串口进行STM32F0的IAP移植手记(包括RAM&ROM地址设置)

发布者:温柔之风最新更新时间:2018-04-15 来源: eefocus关键字:串口  STM32F0  IAP移植 手机看文章 扫描二维码
随时随地手机看文章

1 前言

STSW-STM32116是ST官网基于标准库的针对STM32F0的USART进口IAP示例程序,下载链接:http://www.stmcu.org/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. linking...  

  2. .\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.  

  3. Not enough information to list image symbols.  

  4. Finished: 1 information, 0 warning and 1 error messages.  

  5. ".\STM320518_EVAL\STM320518_EVAL.axf" - 1 Error(s), 0 Warning(s).  

  6. Target not created.  

  7. Build Time Elapsed:  00:00:08  

从字面上判断为编译system_stm32f0xx.c文件生成的目标文件system_stm32f0xx.o中的数据段(.data)内的RW数据与main.o中的数据在地址0x20000000产生冲突。

仔细查看代码,发现main函数之前这么一段:

  1. #if   (defined ( __CC_ARM ))  

  2.   __IO uint32_t VectorTable[48] __attribute__((at(0x20000000)));  

  3. #elif (defined (__ICCARM__))  

  4. #pragma location = 0x20000000  

  5.   __no_init __IO uint32_t VectorTable[48];  

  6. #elif defined   (  __GNUC__  )  

  7.   __IO uint32_t VectorTable[48] __attribute__((section(".RAMVectorTable")));  

  8. #elif defined ( __TASKING__ )  

  9.   __IO uint32_t VectorTable[48] __at(0x20000000);  

  10. #endif  

可见代码是要将中断向量表VectorTable强制定义在内存0x20000000上,但是此地址与system_stm32f0xx.c定义的全局变量位置有冲突。于是,需要修改避免冲突。中断向量的地址是固定的,但其他全局变量的地址可以相应地移动下,并且APP的烧录位置为0x8003000,如下图:

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

另外需要将main函数内前面几行代码做些修改:

  1. int main(void)  

  2. {  

  3.   uint32_t i = 0;  

  4.   

  5.   /*!< At this stage the microcontroller clock setting is already configured,  

  6.        this is done through SystemInit() function which is called from startup 

  7.        file (startup_stm32f0xx.s) before to branch to application main. 

  8.        To reconfigure the default setting of SystemInit() function, refer to 

  9.        system_stm32f0xx.c file 

  10.      */   

  11.   

  12. /* Relocate by software the vector table to the internal SRAM at 0x20000000 ***/    

  13.   

  14.   /* Copy the vector table from the Flash (mapped at the base of the application 

  15.      load address 0x08003000) to the base address of the SRAM at 0x20000000. */  

  16.   for(i = 0; i < 48; i++)  

  17.   {  

  18.     VectorTable[i] = *(__IO uint32_t*)(APPLICATION_ADDRESS + (i<<2));  

  19.   }  

  20.   

  21.   /* Enable the SYSCFG peripheral clock*/  

  22.   //RCC_APB2PeriphResetCmd(RCC_APB2Periph_SYSCFG, ENABLE);   

  23.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);    //需要修改成这样  

  24.   /* Remap SRAM at 0x00000000 */  

  25.   SYSCFG_MemoryRemapConfig(SYSCFG_MemoryRemap_SRAM);  

  26.   

  27. /...  

  28. }  

打开对应的map文件,有如下内容:

  1. GPIO_PIN                                 0x08003470   Data           8  stm320518_eval.o(.constdata)  

  2.    GPIO_CLK                                 0x08003478   Data          16  stm320518_eval.o(.constdata)  

  3.    BUTTON_PIN                               0x08003488   Data          14  stm320518_eval.o(.constdata)  

  4.    BUTTON_CLK                               0x08003498   Data          28  stm320518_eval.o(.constdata)  

  5.    BUTTON_EXTI_LINE                         0x080034b4   Data          14  stm320518_eval.o(.constdata)  

  6.    BUTTON_PORT_SOURCE                       0x080034c2   Data          14  stm320518_eval.o(.constdata)  

  7.    BUTTON_PIN_SOURCE                        0x080034d0   Data          14  stm320518_eval.o(.constdata)  

  8.    BUTTON_IRQn                              0x080034de   Data          14  stm320518_eval.o(.constdata)  

  9.    COM_USART_CLK                            0x080034ec   Data           4  stm320518_eval.o(.constdata)  

  10.    COM_TX_PORT_CLK                          0x080034f0   Data           4  stm320518_eval.o(.constdata)  

  11.    COM_RX_PORT_CLK                          0x080034f4   Data           4  stm320518_eval.o(.constdata)  

  12.    COM_TX_PIN                               0x080034f8   Data           2  stm320518_eval.o(.constdata)  

  13.    COM_RX_PIN                               0x080034fa   Data           2  stm320518_eval.o(.constdata)  

  14.    COM_TX_PIN_SOURCE                        0x080034fc   Data           2  stm320518_eval.o(.constdata)  

  15.    COM_RX_PIN_SOURCE                        0x080034fe   Data           2  stm320518_eval.o(.constdata)  

  16.    COM_TX_AF                                0x08003500   Data           2  stm320518_eval.o(.constdata)  

  17.    COM_RX_AF                                0x08003502   Data           2  stm320518_eval.o(.constdata)  

  18.    RegionBase                      0x08003504   Number         0  anonTable)  

  19.    RegionLimit                     0x08003524   Number         0  anonTable)  

  20.    VectorTable                              0x20000000   Data         192  main.o(.ARM.__AT_0x20000000)      //向量表位置为0x20000000  

  21.    SystemCoreClock                          0x200000c0   Data           4  system_stm32f0xx.o(.data)         //其他全局变量的起始位置为0x200000C0  

  22.    AHBPrescTable                            0x200000c4   Data          16  system_stm32f0xx.o(.data)  

  23.    GPIO_PORT                                0x200000d4   Data          16  stm320518_eval.o(.data)  

  24.    BUTTON_PORT                              0x200000e4   Data          28  stm320518_eval.o(.data)  

  25.    COM_USART                                0x20000100   Data           4  stm320518_eval.o(.data)  

  26.    COM_TX_PORT                              0x20000104   Data           4  stm320518_eval.o(.data)  

  27.    COM_RX_PORT                              0x20000108   Data           4  stm320518_eval.o(.data)  

  28.    __initial_sp                             0x20000510   Data           0  startup_stm32f0xx.o(STACK)  


如上所述,中断向量表被编译在0x20000000,内存的起始位置,而system_stm32f0xx.c下的全局变量SystemCoreClock被KEIL编译成放在紧挨着的0x200000C0的位置,与预期完全相符。分别将IAP与APP烧录进FLASH,测试可以正常运行。

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


3 IAR下移植

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

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


链接配置:

中断向量表:


内存映射:



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

编译后,打开对应的map文件如下所示:


  1. Entry                      Address  Size  Type      Object  

  2. -----                      -------  ----  ----      ------  

  3. .iar.init_table$$Base   0x080034fc         --   Gb  - Linker created -  

  4. .iar.init_table$$Limit  0x08003510         --   Gb  - Linker created -  

  5. ?main                   0x08003511        Code  Gb  cmain.o [4]  

  6. CSTACK$$Base            0x200000d8         --   Gb  - Linker created -  

  7. CSTACK$$Limit           0x200010d8         --   Gb  - Linker created -  

  8. Delay                   0x080031e3  0x10  Code  Gb  main.o [1]  

  9. GPIO_PIN                0x080035a0   0x8  Data  Gb  stm320518_eval.o [1]  

  10. GPIO_PORT               0x200000c0  0x10  Data  Gb  stm320518_eval.o [1]           //stm320518_eval.c文件内的全局变量GPIO_PORT数组存放在0x200000c0  

  11. HardFault_Handler       0x08003573   0x4  Code  Gb  stm32f0xx_it.o [1]  

  12. NMI_Handler             0x08003571   0x2  Code  Gb  stm32f0xx_it.o [1]  

  13. NVIC_SetPriority        0x080030c1  0x84  Code  Lc  main.o [1]  

  14. PendSV_Handler          0x08003579   0x2  Code  Gb  stm32f0xx_it.o [1]  

  15. RCC_APB2PeriphClockCmd  0x08003229  0x20  Code  Gb  stm32f0xx_rcc.o [1]  

  16. RegionBase     0x080034fc         --   Gb  - Linker created -  

  17. RegionLimit    0x08003510         --   Gb  - Linker created -  

  18. STM_EVAL_LEDToggle      0x08003315  0x26  Code  Gb  stm320518_eval.o [1]  

  19. SVC_Handler             0x08003577   0x2  Code  Gb  stm32f0xx_it.o [1]  

  20. SYSCFG_MemoryRemapConfig  

  21.                         0x0800324d  0x14  Code  Gb  stm32f0xx_syscfg.o [1]  

  22. SetSysClock             0x080033b7  0xbe  Code  Lc  system_stm32f0xx.o [1]  

  23. SysTick_Config          0x08003145  0x32  Code  Lc  main.o [1]  

  24. SysTick_Handler         0x0800357b   0x8  Code  Gb  stm32f0xx_it.o [1]  

  25. SystemCoreClock         0x200000d0   0x4  Data  Gb  system_stm32f0xx.o [1]  

  26. SystemInit              0x08003349  0x6e  Code  Gb  system_stm32f0xx.o [1]  

  27. TimingDelay             0x200000d4   0x4  Data  Lc  main.o [1]  

  28. TimingDelay_Decrement   0x080031f3  0x16  Code  Gb  main.o [1]  

  29. VectorTable             0x20000000  0xc0  Data  Gb  main.o [1]           //向量表编译位置为0x20000000  

  30. __aeabi_idiv0           0x08003345        Code  Gb  IntDivZer.o [4]  

  31. __aeabi_uidiv           0x08003265        Code  Gb  I32DivModFast.o [4]  

  32. __aeabi_uidivmod        0x08003265        Code  Gb  I32DivModFast.o [4]  

  33. __cmain                 0x08003511        Code  Gb  cmain.o [4]  

  34. __exit                  0x08003545  0x14  Code  Gb  exit.o [5]  

  35. __iar_copy_init3        0x080034a5  0x30  Code  Gb  copy_init3.o [4]  

  36. __iar_data_init3        0x080034d5  0x28  Code  Gb  data_init.o [4]  

  37. __iar_program_start     0x08003595        Code  Gb  cstartup_M.o [4]  

  38. __low_level_init        0x0800352b   0x4  Code  Gb  low_level_init.o [3]  

  39. __vector_table          0x08003000        Data  Gb  startup_stm32f0xx.o [1]  

  40. _call_main              0x0800351d        Code  Gb  cmain.o [4]  

  41. _exit                   0x08003539        Code  Gb  cexit.o [4]  

  42. _main                   0x08003527        Code  Gb  cmain.o [4]  

  43. exit                    0x0800352f   0x8  Code  Gb  exit.o [3]  

  44. main                    0x08003177  0x6c  Code  Gb  main.o [1]  


如上所示,在IAR编译下,中断向量表被编译在0x20000000,内存的起始位置,而stm320518_eval.c下的全局变量GPIO_PORT被IAR编译成放在紧挨着的0x200000C0的位置。分别将IAP与APP烧录进FLASH,测试可以正常运行。



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


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


关键字:串口  STM32F0  IAP移植 引用地址:串口进行STM32F0的IAP移植手记(包括RAM&ROM地址设置)

上一篇:hex 文件详解 stm32
下一篇:STM32F030 ADC1的DMA采样问题

推荐阅读最新更新时间:2024-03-16 16:00

89C52串口通信
#include reg52.h unsigned char flag,a; void main() { TMOD=0x20;//设置定时器1为工作方式2 TH1=0xfd; // TL1=0xfd; //用T1定时器设置波特率 TR1=1; //定时器1工作 REN=1; //串口允许接收 SM0=0; // SM1=1; //串行口工作方式1 EA=1; //CPU中断允许 ES=1; //串行口中断允许 while(1) { if(flag==1) //中断法串口通信 { ES=0; //单片机向PC发数据时应
[单片机]
51单片机IO口模拟串口通讯C源程
51 IO口模拟串口通讯C源程 #include reg51.h sbit BT_SND =P1^0; sbit BT_REC =P1^1; #define MODE_QUICK #define F_TM F0 #define TIMER0_ENABLE TL0=TH0; TR0=1; #define TIMER0_DISABLE TR0=0; sbit ACC0= ACC^0; sbit ACC1= ACC^1; sbit ACC2= ACC^2; sbit ACC3= ACC^3; sbit ACC4= ACC^4; sbit ACC5= ACC^5; sbit ACC6= ACC^6; sbit ACC7= ACC^
[单片机]
【单片机】【学习日志】51单片机学习日志[Day4、2022.1.12]
第一部分_串口 一、基础知识 串口是一种应用十分广泛的通讯接口,串口成本低、容易使用、通信线路简单,可实现两个设备的互相通信。 单片机的串口可以使单片机与单片机、单片机与电脑、单片机与各式各样的模块互相通信,极大的扩展了单片机的应用范围,增强了单片机系统的硬件实力。 51单片机内部自带UART(Universal Asynchronous Receiver Transmitter,通用异步收发器)可实现单片机的串口通信。 第一个 USB转换工具 相当于 第二个 陀螺仪模块,加速度传感器 第三个 蓝牙串口 小贴士: VGA接口,相比于 串口的接口(两排) 它有三排插、孔。【用于视频传输、电脑外接显示器】 二、硬件
[单片机]
【单片机】【学习日志】51单片机学习日志[Day4、2022.1.12]
STM32串口波特率大小计算案例
波特率的计算 STM32下的波特率和串口外设时钟息息相关,USART 1的时钟来源于APB2,USART 2-5的时钟来源于APB1。在STM32中,有个波特率寄存器USART_BRR,如下: STM32串口波特率通过USART_BRR进行设置,STM32的波特率寄存器支持分数设置,以提高精确度。USART_BRR的前4位用于表示小数,后12位用于表示整数。但是它还不是我们想要设置的波特率,想要设置我们串口的波特率大小还需要进行计算。其实有关波特率的计算是下面这一条表达式: 从上面的表达式,我们引入了一个新量USARTDIV,它表示对串口的时钟源fck进行分频。假设我们已知道了波特率和fck时钟频率的大小,那么通过上式便可
[单片机]
STM32<font color='red'>串口</font>波特率大小计算案例
基于stm8s103k3单片机串口UART的正确使用分享
最近开始使用stm8s103k3单片机了。据说很好,确实不错。前几天已经试过了GPIO,Timer2,ADC的功能,都比较容易,唯独串口UART使用,破费周折,写出来,供大家借鉴。 我使用的是stm8s103k3,32脚单片机,这个使用手册上说了UART1,UART2,UART3。但是引脚的功能图上只有UART1,并且你打开stm8s103k.h的头文件,里面也只有UART1寄存器的定义说明。所以我认为只有UART1。既然有这个功能,那就用吧,我以为直接可以连接到电脑的串口(COM1),就可以使用了,其实不可以。单片机即使写着提供UART通讯功能,也要连接MAX232转接芯片,我就在这里耽误了许多时间。 1、使用stm8s
[单片机]
基于stm8s103k3单片机<font color='red'>串口</font>UART的正确使用分享
STM32+FreeRTOS+CUBEMX_学习笔记(五)HAL串口终极总结
前言: 在写这篇文章的过程中,我参考了很多的博文。这些博文给了我很多帮助,但是不得不说,网上的博文终究是层次不齐的。当遇到一些关于原理的地方,还是官方文档比较靠谱。毕竟官方要保证这些文档的可靠性。 如果只是想找对应的方式,直接看目录到对应的地方就可以啦 注意,源码库在最后。 目的: 学习HAL库串口操作函数 实现串口的中断收发定长数据 实现串口的帧头帧尾判断收发不定长数据 实现串口的空闲中断收发不定长数据 实现串口的DMA收发不定长数据 环境和平台: keil5 cubemx stm32c8t6 一、HAL库的串口函数学习: 1.1、hal库: HAL库是ST新推出的官方库,该库同图形化开发工具CUBEMX可以结合
[单片机]
STM32+FreeRTOS+CUBEMX_学习笔记(五)HAL<font color='red'>串口</font>终极总结
tiny4412开发板的串口介绍与操作
UART原理说明: 通用异步收发器简称UART,即 Universal Asynchronous Receiver Transmitter ,它用来传输串行数据:发送数据时,CPU将并行数据写入UART,UART按照一定的格式在一根电线上串行发出;接收数据时,UART检测另一根电线上的信号,将串行收集放在缓冲区中,CPU即可读取UART获得这些数据。UART之间以全双工方式传输数据,最精简的连线方法只有三根电线:TxD用于发送数据,RxD用于接收数据,Gnd用于给双方提供参考电平,连线如图1所示: 图1. UART连线图 UART使用标准的TTL/CMOS逻辑电平(0~5V、0~3.3V、0~2.5V或0~1.8V四种
[单片机]
tiny4412开发板的<font color='red'>串口</font>介绍与操作
STC15F2K60S2串口通信程序
//**********************************************//STC15F2K60S2串口通信程序,将串口接受到的数据从串口发出去//采用22.1184M晶振,波特率115200//为方便大家调试,特附该程序的项目工程文件下载地址,下载打开即可调试下载到单片机////*********************************************#include stc15fxxxx.h //调用stc15f系列头文件,下载地址: http://pan.baidu.com/s/1eRUbjLS/*************常量定义****************/#define M
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved