新手入门
- 积分
- 6
- 金钱
- 6
- 注册时间
- 2020-8-26
- 在线时间
- 0 小时
|
本帖最后由 aou 于 2020-8-26 09:51 编辑
这两天也遇到一个问题, 用GD32F150 做项目,用到 USB IAP, 不加IAP USB HID 识别正常, 但加了 前面的 IAP 程序,把主程序 向后偏移,就发现 USB 不能正常识别,而且 发现程序 执行速度变慢了,开始怀疑是IAP 跳转的时候,有一些中断没有关,进 入主程序后有可能有没有处理的中断引起的,后来全部关中断,有时可以,有时不行,大概 10次能识别 4次, 调试发现 对比各个寄存器的值都和没有偏移之前的 一样,调了整整一天没有结果,准备放弃,就这样了,感觉无解了。
第二天 换了一个思路,各种百度,到处找看有没有人遇到过同样的问题, 最后搜到一个贴子,才发现,GD32F150 64K flash 前32K FLASH 速度快,后面 32K 速度慢, 我的 IAP 程序大小 17K 主程序 大小 37K 17+37 > 32K 了, 有一些 代码存放的已经大于32K了, 查看了一下 keil 编译后的 MAP ,的确, USB 部分的函数的地址已经在 32K 之后了,终于查到问题了。
接下来 验证一下,是不是这个问题引起的,
测试思路
要把主程序大部分重要代码(尤其是 USB)部分 控制在前 32K 以内, 最简单的办法,就是 把 17K大小的 IAP 移到后面。
启动程序
主程序
IAP 程序
那么方法是 先写一个 引导程序 start 让 mcu 一启动直接跳转到 64-44= 20K 后面的起始地址, nvic_vector_table_set(FLASH_BASE,0xB000); 启动程序大小 800B,分配1K flash, 启动程序跳转 进入 IAP 程序, 然后 IAP 程序处理后,再跳转到 主程序 的起启地址 0x8000400, 然后测试, USB 正常了。
问题是解决了, 但是IAP中 串口接收数据,也想换成 USB 接收接,那么问题 又来了, IAP 放到 后面 32K ,IAP程序中的 USB 又会概率性识别不成功。 怎样再解决这个问题呢?
能不能人为控制 主程序中 USB 代码部分 放到 最终生成的 代码前部?
试一下, 32-17 = 15K, 主程序 有 15K高速 FLASH的空间可以用,只要 把重要的 代码让 MDK 编译的时候,放在前面就行。
想到一个比较简单的方法,用 __attribute__ 给MDK 指定 函数的地址, 但是 函数比较多,还得算每个函数的代码大小, 不然地址有可能会重复,也有可能 中间有间隔, 感觉不太好,
能不能让 MDK 把USB 部分代码 自动放程序的前面呢?查看了一下 MAP文件,发现 MDK 编译的时候, 函数地址好像是 根据 函数首字母排序的, 大写字母在前,小写字母在后, 试了一下,把 usbd_core_init() 改成Usbd_core_init () ,再次编译,果然放到前面了。 然后 把USB部分代码的名字全改了, 再次编译试了一下, 问题 解决了。
之前做过一些开发,经常用到 KEIL ,没想到 KEIL中函数名 ( usbd_core_init() Usbd_core_init () ) 还会对程序结果有影响 写出来给大家分享一下,避免有人后面再遇到同样的问题
问题是解决了 ,后续有没有可能 让 主程序 用 IAP 中的 USB 代码呢? 想法是这样的,在IAP中 做一个数组,把 USB函数地址 全记录下来,启动的时候,把数组的地址 加载到内存中 一起传给 主程序,然后主程序通过从IAP 中传过来的地址调用 USB代码,这样主程序就又会小一些了 这种方法可行吗? 后面有时间了再做测试
|
|