历史上的今天
今天是:2025年04月15日(星期二)
2018年04月15日 | 串口进行STM32F0的IAP移植手记(包括RAM&ROM地址设置)
2018-04-15 来源:eefocus
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,
并编译,结果发现原始的公式是编译不过的,如下错误信息:
linking...
.\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.
Not enough information to list image symbols.
Finished: 1 information, 0 warning and 1 error messages.
".\STM320518_EVAL\STM320518_EVAL.axf" - 1 Error(s), 0 Warning(s).
Target not created.
Build Time Elapsed: 00:00:08
从字面上判断为编译system_stm32f0xx.c文件生成的目标文件system_stm32f0xx.o中的数据段(.data)内的RW数据与main.o中的数据在地址0x20000000产生冲突。
仔细查看代码,发现main函数之前这么一段:
#if (defined ( __CC_ARM ))
__IO uint32_t VectorTable[48] __attribute__((at(0x20000000)));
#elif (defined (__ICCARM__))
#pragma location = 0x20000000
__no_init __IO uint32_t VectorTable[48];
#elif defined ( __GNUC__ )
__IO uint32_t VectorTable[48] __attribute__((section(".RAMVectorTable")));
#elif defined ( __TASKING__ )
__IO uint32_t VectorTable[48] __at(0x20000000);
#endif
可见代码是要将中断向量表VectorTable强制定义在内存0x20000000上,但是此地址与system_stm32f0xx.c定义的全局变量位置有冲突。于是,需要修改避免冲突。中断向量的地址是固定的,但其他全局变量的地址可以相应地移动下,并且APP的烧录位置为0x8003000,如下图:
再次编译,错误就会消失了。
另外需要将main函数内前面几行代码做些修改:
int main(void)
{
uint32_t i = 0;
/*!< At this stage the microcontroller clock setting is already configured,
this is done through SystemInit() function which is called from startup
file (startup_stm32f0xx.s) before to branch to application main.
To reconfigure the default setting of SystemInit() function, refer to
system_stm32f0xx.c file
*/
/* Relocate by software the vector table to the internal SRAM at 0x20000000 ***/
/* Copy the vector table from the Flash (mapped at the base of the application
load address 0x08003000) to the base address of the SRAM at 0x20000000. */
for(i = 0; i < 48; i++)
{
VectorTable[i] = *(__IO uint32_t*)(APPLICATION_ADDRESS + (i<<2));
}
/* Enable the SYSCFG peripheral clock*/
//RCC_APB2PeriphResetCmd(RCC_APB2Periph_SYSCFG, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); //需要修改成这样
/* Remap SRAM at 0x00000000 */
SYSCFG_MemoryRemapConfig(SYSCFG_MemoryRemap_SRAM);
/...
}
打开对应的map文件,有如下内容:
GPIO_PIN 0x08003470 Data 8 stm320518_eval.o(.constdata)
GPIO_CLK 0x08003478 Data 16 stm320518_eval.o(.constdata)
BUTTON_PIN 0x08003488 Data 14 stm320518_eval.o(.constdata)
BUTTON_CLK 0x08003498 Data 28 stm320518_eval.o(.constdata)
BUTTON_EXTI_LINE 0x080034b4 Data 14 stm320518_eval.o(.constdata)
BUTTON_PORT_SOURCE 0x080034c2 Data 14 stm320518_eval.o(.constdata)
BUTTON_PIN_SOURCE 0x080034d0 Data 14 stm320518_eval.o(.constdata)
BUTTON_IRQn 0x080034de Data 14 stm320518_eval.o(.constdata)
COM_USART_CLK 0x080034ec Data 4 stm320518_eval.o(.constdata)
COM_TX_PORT_CLK 0x080034f0 Data 4 stm320518_eval.o(.constdata)
COM_RX_PORT_CLK 0x080034f4 Data 4 stm320518_eval.o(.constdata)
COM_TX_PIN 0x080034f8 Data 2 stm320518_eval.o(.constdata)
COM_RX_PIN 0x080034fa Data 2 stm320518_eval.o(.constdata)
COM_TX_PIN_SOURCE 0x080034fc Data 2 stm320518_eval.o(.constdata)
COM_RX_PIN_SOURCE 0x080034fe Data 2 stm320518_eval.o(.constdata)
COM_TX_AF 0x08003500 Data 2 stm320518_eval.o(.constdata)
COM_RX_AF 0x08003502 Data 2 stm320518_eval.o(.constdata)
RegionBase 0x08003504 Number 0 anonTable)
RegionLimit 0x08003524 Number 0 anonTable)
VectorTable 0x20000000 Data 192 main.o(.ARM.__AT_0x20000000) //向量表位置为0x20000000
SystemCoreClock 0x200000c0 Data 4 system_stm32f0xx.o(.data) //其他全局变量的起始位置为0x200000C0
AHBPrescTable 0x200000c4 Data 16 system_stm32f0xx.o(.data)
GPIO_PORT 0x200000d4 Data 16 stm320518_eval.o(.data)
BUTTON_PORT 0x200000e4 Data 28 stm320518_eval.o(.data)
COM_USART 0x20000100 Data 4 stm320518_eval.o(.data)
COM_TX_PORT 0x20000104 Data 4 stm320518_eval.o(.data)
COM_RX_PORT 0x20000108 Data 4 stm320518_eval.o(.data)
__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文件如下所示:
Entry Address Size Type Object
----- ------- ---- ---- ------
.iar.init_table$$Base 0x080034fc -- Gb - Linker created -
.iar.init_table$$Limit 0x08003510 -- Gb - Linker created -
?main 0x08003511 Code Gb cmain.o [4]
CSTACK$$Base 0x200000d8 -- Gb - Linker created -
CSTACK$$Limit 0x200010d8 -- Gb - Linker created -
Delay 0x080031e3 0x10 Code Gb main.o [1]
GPIO_PIN 0x080035a0 0x8 Data Gb stm320518_eval.o [1]
GPIO_PORT 0x200000c0 0x10 Data Gb stm320518_eval.o [1] //stm320518_eval.c文件内的全局变量GPIO_PORT数组存放在0x200000c0
HardFault_Handler 0x08003573 0x4 Code Gb stm32f0xx_it.o [1]
NMI_Handler 0x08003571 0x2 Code Gb stm32f0xx_it.o [1]
NVIC_SetPriority 0x080030c1 0x84 Code Lc main.o [1]
PendSV_Handler 0x08003579 0x2 Code Gb stm32f0xx_it.o [1]
RCC_APB2PeriphClockCmd 0x08003229 0x20 Code Gb stm32f0xx_rcc.o [1]
RegionBase 0x080034fc -- Gb - Linker created -
RegionLimit 0x08003510 -- Gb - Linker created -
STM_EVAL_LEDToggle 0x08003315 0x26 Code Gb stm320518_eval.o [1]
SVC_Handler 0x08003577 0x2 Code Gb stm32f0xx_it.o [1]
SYSCFG_MemoryRemapConfig
0x0800324d 0x14 Code Gb stm32f0xx_syscfg.o [1]
SetSysClock 0x080033b7 0xbe Code Lc system_stm32f0xx.o [1]
SysTick_Config 0x08003145 0x32 Code Lc main.o [1]
SysTick_Handler 0x0800357b 0x8 Code Gb stm32f0xx_it.o [1]
SystemCoreClock 0x200000d0 0x4 Data Gb system_stm32f0xx.o [1]
SystemInit 0x08003349 0x6e Code Gb system_stm32f0xx.o [1]
TimingDelay 0x200000d4 0x4 Data Lc main.o [1]
TimingDelay_Decrement 0x080031f3 0x16 Code Gb main.o [1]
VectorTable 0x20000000 0xc0 Data Gb main.o [1] //向量表编译位置为0x20000000
__aeabi_idiv0 0x08003345 Code Gb IntDivZer.o [4]
__aeabi_uidiv 0x08003265 Code Gb I32DivModFast.o [4]
__aeabi_uidivmod 0x08003265 Code Gb I32DivModFast.o [4]
__cmain 0x08003511 Code Gb cmain.o [4]
__exit 0x08003545 0x14 Code Gb exit.o [5]
__iar_copy_init3 0x080034a5 0x30 Code Gb copy_init3.o [4]
__iar_data_init3 0x080034d5 0x28 Code Gb data_init.o [4]
__iar_program_start 0x08003595 Code Gb cstartup_M.o [4]
__low_level_init 0x0800352b 0x4 Code Gb low_level_init.o [3]
__vector_table 0x08003000 Data Gb startup_stm32f0xx.o [1]
_call_main 0x0800351d Code Gb cmain.o [4]
_exit 0x08003539 Code Gb cexit.o [4]
_main 0x08003527 Code Gb cmain.o [4]
exit 0x0800352f 0x8 Code Gb exit.o [3]
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要好
上一篇:hex 文件详解 stm32
史海拾趣
|
unsigned char PreA,PreB; sbit Key_UP=P0^0; sbit Key_DW=P0^1; void KeyWheel() { if(PreA!=Key_UP) { PreA=Key_UP; if((Key_UP==1&&Key_DW==0)||(Key_UP==0&&Key_DW==1)) &n ...… 查看全部问答> |
|
http://job.eeworld.net/Jobs/ViewJob/C_dc84d8596c334cd683c646206b657cdb.aspx QQ:13910830 … 查看全部问答> |
|
各位大神,我在使用CC2430进行测试的时候,组网成功,然后通过串口相网关设备发送(读取终端数据)的命令的时候,发现需要很长一段时间(4s左右)网关才能响应我的命令,然后再过1s左右的时间读取终端设备的数据。然后在回传。 请问一下,有没有什 ...… 查看全部问答> |
|
小弟正在学习ucosii,现在需要利用ucosII中内存管理来实现动态分配内存,我看到邵贝贝书中讲到一个内存分配的例子: OS_MEM *CommTxBuf; INT8U CommTxPart[100][32]; CommTxBuf=OSMemCreate(CommTxPart,100,32,&err); 我有些疑问:假设CommTxPa ...… 查看全部问答> |
|
本帖最后由 cl17726 于 2014-3-9 17:58 编辑 这样是提示什么? ERROR: D:\\WINCE600\\PLATFORM\\COMMON\\SRC\\SOC\\COMMON_FSL_V2_PDK1_9\\BOOT\\FMD\\NAND\\.\\nandboot.c line 325: length size(0x23e038c) is differen with expected (0x20000 ...… 查看全部问答> |
|
在开发板上调试好的测距程序,想移到自己焊接的万能板上,单片机没有反映,显示屏只有背光,显然没有被初始化。飞线已经仔细检查过几遍了,应该不存在错误,5V电源及地线都正常,将MPU及显示屏装回到开发板能正常工作。请教各位,在仅仅只有万用表 ...… 查看全部问答> |




