你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

使用USART接口进行STM32F0的在线升级(AN4065)-基于标准库的STM32...

[复制链接]
aimejia 发布时间:2018-5-24 10:18
本帖最后由 aimejia 于 2018-5-24 10:25 编辑

1 前言
       STSW-STM32116是ST官网基于标准库的针对STM32F0的USART进口IAP示例程序,下载链接:https://www.stmcu.org.cn/document/detail/index/id-213120
       工程原本是针对STM32F051,本文将介绍如何移植到STM32F070,并针对移植的过程中的问题逐个处理。

2 KEIL下移植      
      IAP程序一般分为两个,一个是IAP,一个是APP,IAP存放在内置FLASH的0x8000000的起始位置,而APP则存放在离这个位置一定距离的位置,这个距离一定是大于或等于IAP本身所占空间大小,本例子为0x8003000。

      下载资源后,打开STM32F0xx_AN4065_FW_V1.0.0\Project\STM32F0xx_IAP\下的binary_template工程,这个就是APP工程,首先用KEIL打开,修改device为STM32F070,

1.jpg

       并编译,结果发现原始的公式是编译不过的,如下错误信息:
  1. <font face="Tahoma" size="2">[plain] view plain copy
  2. linking...  
  3. .\STM320518_EVAL\STM320518_EVAL.axf: Error: L6971E: system_stm32f0xx.o(.data) type RW incompatible with main.o(.ARM.__AT_0x20000000) type ZI in er RW_IRAM1.  
  4. Not enough information to list image symbols.  
  5. Finished: 1 information, 0 warning and 1 error messages.  
  6. ".\STM320518_EVAL\STM320518_EVAL.axf" - 1 Error(s), 0 Warning(s).  
  7. Target not created.  
  8. Build Time Elapsed:  00:00:08  </font>
复制代码
      从字面上判断为编译system_stm32f0xx.c文件生成的目标文件system_stm32f0xx.o中的数据段(.data)内的RW数据与main.o中的数据在地址0x20000000产生冲突。
   
      仔细查看代码,发现main函数之前这么一段:
  1. <font face="Tahoma" size="2">[cpp] view plain copy
  2. #if   (defined ( __CC_ARM ))  
  3.   __IO uint32_t VectorTable[48] __attribute__((at(0x20000000)));  
  4. #elif (defined (__ICCARM__))  
  5. #pragma location = 0x20000000  
  6.   __no_init __IO uint32_t VectorTable[48];  
  7. #elif defined   (  __GNUC__  )  
  8.   __IO uint32_t VectorTable[48] __attribute__((section(".RAMVectorTable")));  
  9. #elif defined ( __TASKING__ )  
  10.   __IO uint32_t VectorTable[48] __at(0x20000000);  
  11. #endif  </font>
复制代码
      可见代码是要将中断向量表VectorTable强制定义在内存0x20000000上,但是此地址与system_stm32f0xx.c定义的全局变量位置有冲突。于是,需要修改避免冲突。中断向量的地址是固定的,但其他全局变量的地址可以相应地移动下,并且APP的烧录位置为0x8003000,如下图:

2.jpg

       再次编译,错误就会消失了。

       另外需要将main函数内前面几行代码做些修改:
  1. <font face="Tahoma" size="2">[cpp] view plain copy
  2. int main(void)  
  3. {  
  4.   uint32_t i = 0;  
  5.   
  6.   /*!< At this stage the microcontroller clock setting is already configured,  
  7.        this is done through SystemInit() function which is called from startup
  8.        file (startup_stm32f0xx.s) before to branch to application main.
  9.        To reconfigure the default setting of SystemInit() function, refer to
  10.        system_stm32f0xx.c file
  11.      */   
  12.   
  13. /* Relocate by software the vector table to the internal SRAM at 0x20000000 ***/   
  14.   
  15.   /* Copy the vector table from the Flash (mapped at the base of the application
  16.      load address 0x08003000) to the base address of the SRAM at 0x20000000. */  
  17.   for(i = 0; i < 48; i++)  
  18.   {  
  19.     VectorTable[i] = *(__IO uint32_t*)(APPLICATION_ADDRESS + (i<<2));  
  20.   }  
  21.   
  22.   /* Enable the SYSCFG peripheral clock*/  
  23.   //RCC_APB2PeriphResetCmd(RCC_APB2Periph_SYSCFG, ENABLE);   
  24.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);    //需要修改成这样  
  25.   /* Remap SRAM at 0x00000000 */  
  26.   SYSCFG_MemoryRemapConfig(SYSCFG_MemoryRemap_SRAM);  
  27.   
  28. /...  
  29. }  </font>
复制代码
      打开对应的map文件,有如下内容:
  1. <font face="Tahoma" size="2">[plain] view plain copy
  2. GPIO_PIN                                 0x08003470   Data           8  stm320518_eval.o(.constdata)  
  3.    GPIO_CLK                                 0x08003478   Data          16  stm320518_eval.o(.constdata)  
  4.    BUTTON_PIN                               0x08003488   Data          14  stm320518_eval.o(.constdata)  
  5.    BUTTON_CLK                               0x08003498   Data          28  stm320518_eval.o(.constdata)  
  6.    BUTTON_EXTI_LINE                         0x080034b4   Data          14  stm320518_eval.o(.constdata)  
  7.    BUTTON_PORT_SOURCE                       0x080034c2   Data          14  stm320518_eval.o(.constdata)  
  8.    BUTTON_PIN_SOURCE                        0x080034d0   Data          14  stm320518_eval.o(.constdata)  
  9.    BUTTON_IRQn                              0x080034de   Data          14  stm320518_eval.o(.constdata)  
  10.    COM_USART_CLK                            0x080034ec   Data           4  stm320518_eval.o(.constdata)  
  11.    COM_TX_PORT_CLK                          0x080034f0   Data           4  stm320518_eval.o(.constdata)  
  12.    COM_RX_PORT_CLK                          0x080034f4   Data           4  stm320518_eval.o(.constdata)  
  13.    COM_TX_PIN                               0x080034f8   Data           2  stm320518_eval.o(.constdata)  
  14.    COM_RX_PIN                               0x080034fa   Data           2  stm320518_eval.o(.constdata)  
  15.    COM_TX_PIN_SOURCE                        0x080034fc   Data           2  stm320518_eval.o(.constdata)  
  16.    COM_RX_PIN_SOURCE                        0x080034fe   Data           2  stm320518_eval.o(.constdata)  
  17.    COM_TX_AF                                0x08003500   Data           2  stm320518_eval.o(.constdata)  
  18.    COM_RX_AF                                0x08003502   Data           2  stm320518_eval.o(.constdata)  
  19.    Region
  20. Table
  21. Base                      0x08003504   Number         0  anon
  22. obj.o(Region
  23. Table)  
  24.    Region
  25. Table
  26. Limit                     0x08003524   Number         0  anon
  27. obj.o(Region
  28. Table)  
  29.    VectorTable                              0x20000000   Data         192  main.o(.ARM.__AT_0x20000000)      //向量表位置为0x20000000  
  30.    SystemCoreClock                          0x200000c0   Data           4  system_stm32f0xx.o(.data)         //其他全局变量的起始位置为0x200000C0  
  31.    AHBPrescTable                            0x200000c4   Data          16  system_stm32f0xx.o(.data)  
  32.    GPIO_PORT                                0x200000d4   Data          16  stm320518_eval.o(.data)  
  33.    BUTTON_PORT                              0x200000e4   Data          28  stm320518_eval.o(.data)  
  34.    COM_USART                                0x20000100   Data           4  stm320518_eval.o(.data)  
  35.    COM_TX_PORT                              0x20000104   Data           4  stm320518_eval.o(.data)  
  36.    COM_RX_PORT                              0x20000108   Data           4  stm320518_eval.o(.data)  
  37.    __initial_sp                             0x20000510   Data           0  startup_stm32f0xx.o(STACK)  </font>
复制代码
      如上所述,中断向量表被编译在0x20000000,内存的起始位置,而system_stm32f0xx.c下的全局变量SystemCoreClock被KEIL编译成放在紧挨着的0x200000C0的位置,与预期完全相符。分别将IAP与APP烧录进FLASH,测试可以正常运行。

      注:在KEIL下,必须存在IAP才能调试APP!,这点是与IAR不同的。

3 IAR下移植
     在IAR下的IAP没有什么特殊的,主要还是看APP的配置。

     使用IAR打开APP工程,修改device为STM32F070:

3.jpg

     链接配置:

     中断向量表:

4.jpg


     内存映射:

5.jpg

       如上,APP存放在FLASH的位置0x8003000,内存还是设置为:0x20000000.

       编译后,打开对应的map文件如下所示:
  1. <font face="Tahoma" size="2">[plain] view plain copy
  2. Entry                      Address  Size  Type      Object  
  3. -----                      -------  ----  ----      ------  
  4. .iar.init_table$Base   0x080034fc         --   Gb  - Linker created -  
  5. .iar.init_table$Limit  0x08003510         --   Gb  - Linker created -  
  6. ?main                   0x08003511        Code  Gb  cmain.o [4]  
  7. CSTACK$Base            0x200000d8         --   Gb  - Linker created -  
  8. CSTACK$Limit           0x200010d8         --   Gb  - Linker created -  
  9. Delay                   0x080031e3  0x10  Code  Gb  main.o [1]  
  10. GPIO_PIN                0x080035a0   0x8  Data  Gb  stm320518_eval.o [1]  
  11. GPIO_PORT               0x200000c0  0x10  Data  Gb  stm320518_eval.o [1]           //stm320518_eval.c文件内的全局变量GPIO_PORT数组存放在0x200000c0  
  12. HardFault_Handler       0x08003573   0x4  Code  Gb  stm32f0xx_it.o [1]  
  13. NMI_Handler             0x08003571   0x2  Code  Gb  stm32f0xx_it.o [1]  
  14. NVIC_SetPriority        0x080030c1  0x84  Code  Lc  main.o [1]  
  15. PendSV_Handler          0x08003579   0x2  Code  Gb  stm32f0xx_it.o [1]  
  16. RCC_APB2PeriphClockCmd  0x08003229  0x20  Code  Gb  stm32f0xx_rcc.o [1]  
  17. Region
  18. Table
  19. Base     0x080034fc         --   Gb  - Linker created -  
  20. Region
  21. Table
  22. Limit    0x08003510         --   Gb  - Linker created -  
  23. STM_EVAL_LEDToggle      0x08003315  0x26  Code  Gb  stm320518_eval.o [1]  
  24. SVC_Handler             0x08003577   0x2  Code  Gb  stm32f0xx_it.o [1]  
  25. SYSCFG_MemoryRemapConfig  
  26.                         0x0800324d  0x14  Code  Gb  stm32f0xx_syscfg.o [1]  
  27. SetSysClock             0x080033b7  0xbe  Code  Lc  system_stm32f0xx.o [1]  
  28. SysTick_Config          0x08003145  0x32  Code  Lc  main.o [1]  
  29. SysTick_Handler         0x0800357b   0x8  Code  Gb  stm32f0xx_it.o [1]  
  30. SystemCoreClock         0x200000d0   0x4  Data  Gb  system_stm32f0xx.o [1]  
  31. SystemInit              0x08003349  0x6e  Code  Gb  system_stm32f0xx.o [1]  
  32. TimingDelay             0x200000d4   0x4  Data  Lc  main.o [1]  
  33. TimingDelay_Decrement   0x080031f3  0x16  Code  Gb  main.o [1]  
  34. VectorTable             0x20000000  0xc0  Data  Gb  main.o [1]           //向量表编译位置为0x20000000  
  35. __aeabi_idiv0           0x08003345        Code  Gb  IntDivZer.o [4]  
  36. __aeabi_uidiv           0x08003265        Code  Gb  I32DivModFast.o [4]  
  37. __aeabi_uidivmod        0x08003265        Code  Gb  I32DivModFast.o [4]  
  38. __cmain                 0x08003511        Code  Gb  cmain.o [4]  
  39. __exit                  0x08003545  0x14  Code  Gb  exit.o [5]  
  40. __iar_copy_init3        0x080034a5  0x30  Code  Gb  copy_init3.o [4]  
  41. __iar_data_init3        0x080034d5  0x28  Code  Gb  data_init.o [4]  
  42. __iar_program_start     0x08003595        Code  Gb  cstartup_M.o [4]  
  43. __low_level_init        0x0800352b   0x4  Code  Gb  low_level_init.o [3]  
  44. __vector_table          0x08003000        Data  Gb  startup_stm32f0xx.o [1]  
  45. _call_main              0x0800351d        Code  Gb  cmain.o [4]  
  46. _exit                   0x08003539        Code  Gb  cexit.o [4]  
  47. _main                   0x08003527        Code  Gb  cmain.o [4]  
  48. exit                    0x0800352f   0x8  Code  Gb  exit.o [3]  
  49. main                    0x08003177  0x6c  Code  Gb  main.o [1]  </font>
复制代码
       如上所示,在IAR编译下,中断向量表被编译在0x20000000,内存的起始位置,而stm320518_eval.c下的全局变量GPIO_PORT被IAR编译成放在紧挨着的0x200000C0的位置。分别将IAP与APP烧录进FLASH,测试可以正常运行。

       注:从IAR工程的链接配置来看,并没有像KEIL那样配置RAM位置为:0x2000000,编译后的结果向量表也不会与其他全局变量相冲突,可见IAR编译器已经自动计算并避免这种冲突,不像KEIL那样会出现链接错误,以此来提示用户。

       另外:在IAR下,在不存在IAP的情况下也是可以调试APP的,这点是KEIL所不具备的功能,看样子,IAR在细节的处理上比KEIL要好。


转载自FD

收藏 2 评论0 发布时间:2018-5-24 10:18

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版