完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
第7章地址ARM DSP源码和库移植方法(IAR8)
本期教程主要讲解ARM官方DSP源码和库的移植以及一些相关知识的介绍。 总结7.1初级重要提示 IAR 请使用 8.30 及以上版本,CMSIS 请使用 5.6.0 及以上版本。 IAR 的工程创建,下载和调试方法,在 V6 用户手册中有详细说明 ? mod=viewthread& tid= 93255 。 7.2 DSP库的下载和说明 下面详细的给大家讲解一下官方DSP库的移植。 7.2.1 DSP库的下载 DSP库是包含在CMSIS软件包(Cortex Microcontroller Software Interface Standard)里面,所以下载DSP库也就是下载CMSIS软件包。这里提供三个可以下载的地方: 方式一:STM32CubeH7软件包里面。 各个版本的CubeH7软件包,都带有CMSIS文件夹,只是版本比较老,不推荐。即使是最新的CubeH7 软件包,包含的CMSIS软件包版本也有点低。 方式二:MDK安装目录(下面是5.6.0版本的路径)。 大家安装了新版MDK后,CMSIS软件包会在存在路径:ARMPACKARMCMSIS5.6.0CMSIS。 如果有更新的版本,推荐大家使用最新版本, 方式三:GitHub。 通过GitHub获取也比较方便。点击就可以下载CMSIS软件包了。 当然,也可以在ARM官网下载,只是这年ARM官网得非常频繁,通过检索功能找资料非常麻烦。所以不推荐大家到ARM官网下载资料了。 7.2.2 DSP的库说明 这里我们以CMSIS V5.6.0为标准进行移植。打开固件库里面的CMSIS文件,可以看到以下几个文件: 其中DSP文件夹是我们需要的: 例子文件夹里面的文件如下,主要是提供了一些例子: 包括文件夹里面是DSP库的头文件: Lib文件夹里面是MDK( ARM),IAR和CGG文件库: Projects这个里面版本的文件如下,提供了三个版本的工程模板,每个模板里面都要把所有源码文件添加进来: 源文件夹中的文件如下,是DSP的源码文件: 7.3 DSP库版本的区别 IAR版本的DSP库如下: arm_cortexM4lf_math.lib Cortex-M4内核,l表示小端格式,f表示带FPU单元,M4仅支持单精度单精度浮点。 arm_cortexM4l_math.lib Cortex-M4内核,l表示小端格式。 arm_cortexM4bf_math.lib Cortex-M4内核,b表示大端格式,f表示带FPU单元,M4仅支持单精度单精度浮点。 arm_cortexM4b_math.lib 皮质-M4内核,B表示大端格式。 STM32F4是M4内核,单精度浮点,一般使用小端格式,所以我们选择库 arm_cortexM4lf_math.lib 7.4 DSP的库几个重要的预定义宏含义 根据用户的使用要求,这几个预定义宏可以添加到IAR的预定义选项中: 这里将这几个预定义宏做个介绍: ARM_MATH_BIG_ENDIAN: 大端格式。 ARM_MATH_MATRIX_CHECK: 检测矩阵的输入输出大小。 ARM_MATH_NEON: ARM_MATH_NEON_EXPERIMENTAL: 这两个暂时用不到,因为M0,M3,M4和M7内核不支持NEON指令,需要等待升级到ARMv8.1-M架构。 ARM_MATH_ROUNDING: 主要用在浮点数转Q32,Q15和Q7,类似四舍五入的处理上,其他函数没时。 ARM_MATH_LOOPUNROLL: 用于4个为一组的小示范处理,重大执行速度。 通过下面的求值函数,可以方便的区别: void arm_abs_f32( const float32_t * pSrc, float32_t * pDst, uint32_t blockSize) { uint32_t blkCnt; /* Loop counter */ #if defined(ARM_MATH_NEON) float32x4_t vec1; float32x4_t res; /* Compute 4 outputs at a time */ blkCnt = blockSize 》》 2U; while (blkCnt 》 0U) { /* C = |A| */ /* Calculate absolute values and then store the results in the destination buffer. */ vec1 = vld1q_f32(pSrc); res = vabsq_f32(vec1); vst1q_f32(pDst, res); /* Increment pointers */ pSrc += 4; pDst += 4; /* Decrement the loop counter */ blkCnt--; } /* Tail */ blkCnt = blockSize & 0x3; #else #if defined (ARM_MATH_LOOPUNROLL) /* Loop unrolling: Compute 4 outputs at a time */ blkCnt = blockSize 》》 2U; while (blkCnt 》 0U) { /* C = |A| */ /* Calculate absolute and store result in destination buffer. */ *pDst++ = fabsf(*pSrc++); *pDst++ = fabsf(*pSrc++); *pDst++ = fabsf(*pSrc++); *pDst++ = fabsf(*pSrc++); /* Decrement loop counter */ blkCnt--; } /* Loop unrolling: Compute remaining outputs */ blkCnt = blockSize % 0x4U; #else /* Initialize blkCnt with number of samples */ blkCnt = blockSize; #endif /* #if defined (ARM_MATH_LOOPUNROLL) */ #endif /* #if defined(ARM_MATH_NEON) */ while (blkCnt 》 0U) { /* C = |A| */ /* Calculate absolute and store result in destination buffer. */ *pDst++ = fabsf(*pSrc++); /* Decrement loop counter */ blkCnt--; } } 7.5 DSP库在IAR上的移植(源码移植方式) 下面我们讲解下如何在IAR上面移植DSP库源码,DSP库的移植相对比较容易。 7.5.1第一步:建立IAR工程并添加DSP库 为了网求方便起见,我们这里不再创建一个MDK工程了,直接以V6开发板中的例子:V6-001_跑马灯例子我们为模板(注意,要使用HAL版本的例子)进行添加培养。打开这个实例并在另外添加演示CMSIS/DSP: 这里不需要添加C文件源,可以添加包含这些C文件的汇总文件,比如BasicMathFunctions.c文件里面的C文件: #include “arm_abs_f32.c” #include “arm_abs_q15.c” #include “arm_abs_q31.c” #include “arm_abs_q7.c” #include “arm_add_f32.c” #include “arm_add_q15.c” #include “arm_add_q31.c” #include “arm_add_q7.c” #include “arm_dot_prod_f32.c” #include “arm_dot_prod_q15.c” #include “arm_dot_prod_q31.c” #include “arm_dot_prod_q7.c” #include “arm_mult_f32.c” #include “arm_mult_q15.c” #include “arm_mult_q31.c” #include “arm_mult_q7.c” #include “arm_negate_f32.c” #include “arm_negate_q15.c” #include “arm_negate_q31.c” #include “arm_negate_q7.c” #include “arm_offset_f32.c” #include “arm_offset_q15.c” #include “arm_offset_q31.c” #include “arm_offset_q7.c” #include “arm_scale_f32.c” #include “arm_scale_q15.c” #include “arm_scale_q31.c” #include “arm_scale_q7.c” #include “arm_shift_q15.c” #include “arm_shift_q31.c” #include “arm_shift_q7.c” #include “arm_sub_f32.c” #include “arm_sub_q15.c” #include “arm_sub_q31.c” #include “arm_sub_q7.c 这样一个,IAR编译后会自动关联,查看源码非方便: 7.5.2这个已经:添加头文件路径 添加DSP所需的头文件路径,头文件路径是在模板工程中添加好的,这里只是跟大家看一下: 这里要注意一点,直接添加路径LibrariesCMSISInclude里面的头文件,而没有添加LibrariesCMSISDSPInclude,这是因为路径LibrariesCMSISInclude里面已经包含了DSP库的头文件。 7.5.3 第三步:添加宏定义 我们这里只能使能一个宏定义ARM_MATH_LOOPUNROLL: 7.5.4 第四步:开启FPU 需要通过MDK开启FPU,由于STM32F4支持单 步精度浮点,这里要开启Sing Precision。7.5.5第五步:添加头文件arm_math.h #DSP库函数的文件得添加包括“arm_math.h”就可以调用DSP库的API了。至此就完成了DSP库的移植。 7.6 DSP库在IAR上的移植(库移植) ) 移植方法与插件7.5小节的相同,仅第1步不同,将源码的添加为库添加: 7.7升级到最新版DSP库方法 由于CMSIS软件实时更新的,这里提供一种升级的简单的方法,按照方法7.1小节的说明下载到最新版的CMSIS软件包,然后直接覆盖DSP工程里面的CMSIS压缩法。 7.8简易DSP库函数验证 这里我们主要运行arm_abs_f32,arm_abs_q31,arm_abs_q15这三个函数,以此来验证我们移植的DSP库是否正确。 配套例子: 本章配套了如下两个例子: V6-200_DSP程序模板(源码方式) V6-201_DSP程序模板(库方式) 实验目的: 1. 学习官方DSP库的移植 实验内容: 1. 按压结果K1, 串口打印函数arm_abs_f32的输出 2. 点击K2,耳机打印功能arm_abs_q31的输出结果 3。按下K3,串口的输出函数arm_abs_q15的输出结果 实验现象: 通过串口上位机软件SecureCRT看打印信息现象如下(分别出现了K1,K2,K3)。本章7.7小节所说的问题。 程序设计: 程序的设计也比较简单,通过按下不同的按键从而打印不同的DSP库函数执行结果,主程序如下: #include ”bsp.h“ /* 底层硬件驱动 */ #include ”arm_math.h“ /* 定义例程名和例程发布日期 */ #define EXAMPLE_NAME ”V7-ARM的DSP移植模板(源码方式)“ #define EXAMPLE_DATE ”2019-07-31“ #define DEMO_VER ”1.0“ static void PrintfLogo(void); static void PrintfHelp(void); /* ********************************************************************************************************* * 函 数 名: main * 功能说明: c程序入口 * 形 参: 无 * 返 回 值: 错误代码(无需处理) ********************************************************************************************************* */ int main(void) { uint8_t ucKeyCode; /* 按键代码 */ float32_t pSrc; float32_t pDst; q31_t pSrc1; q31_t pDst1; q15_t pSrc2; q15_t pDst2; bsp_Init(); /* 硬件初始化 */ PrintfLogo(); /* 打印例程名称和版本等信息 */ PrintfHelp(); /* 打印操作提示 */ bsp_StartAutoTimer(0, 100); /* 启动1个100ms的自动重装的定时器 */ /* 主程序大循环 */ while (1) { /* CPU空闲时执行的函数,在 bsp.c */ bsp_Idle(); /* 判断定时器超时时间 */ if (bsp_CheckTimer(0)) { /* 每隔100ms 进来一次 */ /* 翻转LED2的状态 */ bsp_LedToggle(2); } /* 处理按键事件 */ ucKeyCode = bsp_GetKey(); if (ucKeyCode 》 0) { /* 有键按下 */ switch (ucKeyCode) { case KEY_DOWN_K1: /* K1键按下 */ pSrc -= 1.23f; arm_abs_f32(&pSrc, &pDst, 1); printf(”pDst = %frn“, pDst); break; case KEY_DOWN_K2: /* K2键按下 */ pSrc1 -= 1; arm_abs_q31(&pSrc1, &pDst1, 1); printf(”pDst1 = %drn“, pDst1); break; case KEY_DOWN_K3: /* K3键按下 */ pSrc2 -= 1; arm_abs_q15(&pSrc2, &pDst2, 1); printf(”pDst2 = %drn“, pDst2); break; default: break; } } } } 7.9 总结本期教程主要跟大家介绍了官方库的移植,比较简单的移植也比较简单,建议初学的同学按照这个步骤进行DSP移植。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1817 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1631 浏览 1 评论
1103 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
739 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1692 浏览 2 评论
1951浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
754浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
585浏览 3评论
605浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
568浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-30 08:47 , Processed in 0.742497 second(s), Total 47, Slave 39 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号