IAR STM32 函数和变量的绝对地址定位
也就是说,如果我要改变某个函数,只需要更新flash里面一个局部,也许只需要更新几百个字节,而无须重新下载整个上百K的程序。
经过查找资料和反复实验,终于实现了,现总结如下:
1) 把函数定位在FLASH高端的指定位置,以后更新,只更新那小块地方就可以了。
方法一:
IAR里面进行函数定位, 必须要在.icf里面,进行定义。
void sendstr(unsigned *buf,unsigned shortlen) @".sendstr"
{
....
}
.icf文件,加入这样一句:
place at address mem:0x08017000 { readonly section .sendstr};
方法二)把要更新的函数,单独放在一个.c文件中,然后再.icf文件里面,对该文件进行定位:
test.c
int f1(int a,int b){
if(a>0){
return (a+b)*1;
}
else return 0;
}
int f2(int a,int b){
if(a>0){
return (a+b)*1;
}
else return 0;
}
那么在 .icf文件中,这样写:
place at address mem:0x08018000 { section .text object test.o };
编译完成后, f1就定位在0x08018000 处了,当然f2也紧跟在f1后面。整个test.c文件的所有函数,都在0x08018000 之后。
如果有多个函数需要单独更新,建议采用第二种方式, 只需要对c文件编译后的地址定位,那么该c文件的所有函数都定位了。
绝对定位的函数,只要指定了地址,那么在flash里面的位置就是固定的。
即使是两个不同的工程,比如第一个工程为实际工程,里面有所有的工程文件,第二个工程为更新专用工程,里面仅仅只有test.c文件,里面的函数是同名的,定位地址与第一个工程也一样。
那么这样编译后,第二个工程里面的固件片断,是可以用来更新一个工程的固件的。
这样还可以派生出一个很怪的用法:
我可以把更新专用工程,公布给别人,他只需要在test.c里面,编写函数的具体内容。 然后一样可以更新产品的固件。
真正的实际工程,是不需要公布的。
以上是对函数的绝对定位处理。
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2)变量定位
变量绝对定位:
__no_init char array1[100]@0x2000B000;
变量绝对定位,无须修改.icf,直接指定
这个array1就定位在RAM中的0x2000B000处
常量绝对定位:
const char str1[8]@".MYSEG"="test11!!";
常量绝对定位,需要改.icf文件:
place at address mem:0x08018500 { readonly section .MYSEG};
------------------------------------------------------------------------------------------------------------------------------------------
3)跨工程固件更新注意事项:
固件更新区的绝对定位的函数,不能随意调用其他库函数,那些被调用的函数也必须是绝对定位的。否则跨工程更新固件,会导致失败,因为被调用的函数在不同工程里,动态连接到的位置不同。
但是这个可以解决:被调用的函数,在两边工程都申明的绝对地址,并且在非固件更新区(就是两边工程的固件里,这些被调用函数的位置都一样,只需要函数名和地址一样即可,函数内部可以不同)。那么被这些调用的函数内,可以随意调用其他函数,如printf ,strcpy等库函数了。
绝对定位的函数,如果要使用常量,那么被使用的常量也必须是绝对定位的。否则跨工程更新固件,会导致失败。
绝对定位的函数,如果要使用全局变量,那么被使用的常量也必须是绝对定位的。否则跨工程更新固件,会导致失败。而局部变量则不受此限制。
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
###############################################################################
# #
# IAR ELF Linker V5.50.0.51878/W32 for ARM 31/May/201212:50:09 #
# Copyright (C) 2007-2010 IAR Systems AB. #
# #
# Output file=E:\stm32\software4.45.2\Debug\Exe\software.out #
# Map file =E:\stm32\software4.45.2\Debug\List\software.map #
# Command line =E:\stm32\software4.45.2\Debug\Obj\main.o #
# E:\stm32\software4.45.2\Debug\Obj\test.o -o #
# E:\stm32\software4.45.2\Debug\Exe\software.out --map #
# E:\stm32\software4.45.2\Debug\List\software.map #
# --config E:\stm32\software4.45.2\stm32f10x_flash.icf #
# --semihosting --entry __iar_program_start #
# #
# #
###############################################################################
*******************************************************************************
*** PLACEMENT SUMMARY
***
"A1":place at 0x08004000 { ro section .intvec };
"A2":place at 0x08017000 { ro section .sendstr };
"A3":place at 0x08018500 { ro section .MYSEG };
"A4":place at 0x08018000 { object test.o section .text };
"P1":place in [from 0x08004000 to 0x08020000] { ro };
"P2":place in [from 0x20000000 to 0x2000bfff] {
rw, block CSTACK, block HEAP };
Section Kind Address SizeObject
------- ---- ------- ----------
"A1": 0x40
.intvec ro code0x08004000 0x40vector_table_M.o [4]
- 0x08004040 0x40
"P1": 0x100
.text ro code0x08004040 0x30copy_init3.o [4]
.text ro code0x08004070 0x2cdata_init3.o [4]
.text ro code0x0800409c 0x28iarttio.o [5]
.iar.init_table const 0x080040c4 0x14- Linker created -
.text ro code0x080040d8 0x16cmain.o [4]
.text ro code0x080040f0 0x14exit.o [5]
.text ro code0x08004104 0xccsta
IARSTM32函数变量绝对地 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)