IAR之函数和变量的绝对地址定位
IAR之函數(shù)和變量的絕對(duì)地址定位?
轉(zhuǎn)自:http://blog.csdn.net/slj_win/article/details/21516497
?
?昨天我突然冒出個(gè)想法,能否利用函數(shù)和變量的絕對(duì)定位,實(shí)現(xiàn)程序的模塊化更新。
??也就是說,如果我要改變某個(gè)函數(shù),只需要更新flash里面一個(gè)局部,也許只需要更新幾百個(gè)字節(jié),而無須重新下載整個(gè)上百K的程序。
??經(jīng)過查找資料和反復(fù)實(shí)驗(yàn),終于實(shí)現(xiàn)了,現(xiàn)總結(jié)如下:
??1) 把函數(shù)定位在FLASH高端的指定位置,以后更新,只更新那小塊地方就可以了。
??方法一:
? ? IAR里面進(jìn)行函數(shù)定位, 必須要在.icf里面,進(jìn)行定義。
? ?void sendstr(unsigned *buf,unsigned short??len) @".sendstr"
? ?{
? ? ....
? ?}
? ?.icf文件,加入這樣一句:
??place at address mem:0x08017000 { readonly section .sendstr};
??方法二)??把要更新的函數(shù),單獨(dú)放在一個(gè).c文件中,然后再.icf文件里面,對(duì)該文件進(jìn)行定位:
??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 處了,當(dāng)然f2也緊跟在f1后面。整個(gè)test.c文件的所有函數(shù),都在0x08018000 之后。
如果有多個(gè)函數(shù)需要單獨(dú)更新,建議采用第二種方式, 只需要對(duì)c文件編譯后的地址定位,那么該c文件的所有函數(shù)都定位了。
絕對(duì)定位的函數(shù),只要指定了地址,那么在flash里面的位置就是固定的。
即使是兩個(gè)不同的工程,比如第一個(gè)工程為實(shí)際工程,里面有所有的工程文件,??第二個(gè)工程為更新專用工程,里面僅僅只有test.c文件,里面的函數(shù)是同名的,定位地址與第一個(gè)工程也一樣。
那么這樣編譯后,第二個(gè)工程里面的固件片斷,是可以用來更新一個(gè)工程的固件的。
這樣還可以派生出一個(gè)很怪的用法:
我可以把更新專用工程,公布給別人,他只需要在test.c里面,編寫函數(shù)的具體內(nèi)容。 然后一樣可以更新產(chǎn)品的固件。
真正的實(shí)際工程,是不需要公布的。
以上是對(duì)函數(shù)的絕對(duì)定位處理。
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
?
2)變量定位
變量絕對(duì)定位:
__no_init char array1[100]@0x2000B000;
變量絕對(duì)定位,無須修改.icf,直接指定
這個(gè)array1就定位在RAM中的0x2000B000處
常量絕對(duì)定位:
const char str1[8]@".MYSEG"="test11!!";
常量絕對(duì)定位,需要改.icf文件:
place at address mem:0x08018500 { readonly section .MYSEG};
------------------------------------------------------------------------------------------------------------------------------------------
3)跨工程固件更新注意事項(xiàng):
固件更新區(qū)的絕對(duì)定位的函數(shù),不能隨意調(diào)用其他庫函數(shù),那些被調(diào)用的函數(shù)也必須是絕對(duì)定位的。否則跨工程更新固件,會(huì)導(dǎo)致失敗,因?yàn)楸徽{(diào)用的函數(shù)在不同工程里,動(dòng)態(tài)連接到的位置不同。?
但是這個(gè)可以解決:被調(diào)用的函數(shù),在兩邊工程都申明的絕對(duì)地址,并且在非固件更新區(qū)(就是兩邊工程的固件里,這些被調(diào)用函數(shù)的位置都一樣,只需要函數(shù)名和地址一樣即可,函數(shù)內(nèi)部可以不同)。那么被這些調(diào)用的函數(shù)內(nèi),可以隨意調(diào)用其他函數(shù),如printf ,strcpy等庫函數(shù)了。
絕對(duì)定位的函數(shù),如果要使用常量,那么被使用的常量也必須是絕對(duì)定位的。否則跨工程更新固件,會(huì)導(dǎo)致失敗。
絕對(duì)定位的函數(shù),如果要使用全局變量,那么被使用的常量也必須是絕對(duì)定位的。否則跨工程更新固件,會(huì)導(dǎo)致失敗。??而局部變量則不受此限制。
?
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
###############################################################################
#? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ???#
# IAR ELF Linker V5.50.0.51878/W32 for ARM? ?? ?? ?? ???31/May/2012??12: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? ?Size??Object
??-------? ?? ?? ?? ?----? ?? ???-------? ?----??------
"A1":? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ???0x40
??.intvec? ?? ?? ?? ?ro code??0x08004000? ?0x40??vector_table_M.o [4]
? ?? ?? ?? ?? ?? ?? ?? ?? ? - 0x08004040? ?0x40
"P1":? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? 0x100
??.text? ?? ?? ?? ???ro code??0x08004040? ?0x30??copy_init3.o [4]
??.text? ?? ?? ?? ???ro code??0x08004070? ?0x2c??data_init3.o [4]
??.text? ?? ?? ?? ???ro code??0x0800409c? ?0x28??iarttio.o [5]
??.iar.init_table? ? const? ? 0x080040c4? ?0x14??- Linker created -
??.text? ?? ?? ?? ???ro code??0x080040d8? ?0x16??cmain.o [4]
??.text? ?? ?? ?? ???ro code??0x080040f0? ?0x14??exit.o [5]
??.text? ?? ?? ?? ???ro code??0x08004104? ? 0xc??cstartup_M.o [4]
??.text? ?? ?? ?? ???ro code??0x08004110? ? 0xa??cexit.o [4]
??.text? ?? ?? ?? ???ro code??0x0800411a? ? 0xa??main.o [1]
??.text? ?? ?? ?? ???ro code??0x08004124? ? 0x8??XShttio.o [3]
??.text? ?? ?? ?? ???ro code??0x0800412c? ? 0x6??exit.o [3]
??.text? ?? ?? ?? ???ro code??0x08004132? ? 0x4??low_level_init.o [3]
??.text? ?? ?? ?? ???ro code??0x08004136? ? 0x2??vector_table_M.o [4]
??Initializer bytes??ro data??0x08004138? ? 0x8??<for P2 s0>
? ?? ?? ?? ?? ?? ?? ?? ?? ? - 0x08004140??0x100
"A2":? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?0x2
??.sendstr? ?? ?? ???ro code??0x08017000? ? 0x2??main.o [1]
? ?? ?? ?? ?? ?? ?? ?? ?? ? - 0x08017002? ? 0x2
"A4":? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ???0x54
??.text? ?? ?? ?? ???ro code??0x08018000? ?0x54??test.o [1]
? ?? ?? ?? ?? ?? ?? ?? ?? ? - 0x08018054? ?0x54
"A3":? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ???0x10
??.MYSEG? ?? ?? ?? ? const? ? 0x08018500? ?0x10??test.o [1]
? ?? ?? ?? ?? ?? ?? ?? ?? ? - 0x08018510? ?0x10
"P2", part 1 of 2:? ?? ?? ?? ?? ?? ?? ?? ?0x400
??CSTACK? ?? ?? ?? ?? ?? ?? ? 0x20000000??0x400??<Block>
? ? CSTACK? ?? ?? ???uninit? ?0x20000000??0x400??<Block tail>
? ?? ?? ?? ?? ?? ?? ?? ?? ? - 0x20000400??0x400
"P2", part 2 of 2:? ?? ?? ?? ?? ?? ?? ?? ???0x8
??P2 s0? ?? ?? ?? ?? ?? ?? ???0x20000400? ? 0x8??<Init block>
? ? .data? ?? ?? ?? ?inited? ?0x20000400? ? 0x8??XShttio.o [3]
? ?? ?? ?? ?? ?? ?? ?? ?? ? - 0x20000408? ? 0x8
*******************************************************************************
*** INIT TABLE
***
? ?? ?? ? Address? ???Size
? ?? ?? ? -------? ???----
Copy (__iar_copy_init3)
? ? 1 source range, total size 0x8 (100% of destination):
? ?? ?? ? 0x08004138? ?0x8
? ? 1 destination range, total size 0x8:
? ?? ?? ? 0x20000400? ?0x8
*******************************************************************************
*** MODULE SUMMARY
***
? ? Module? ?? ?? ?? ?ro code??ro data??rw data
? ? ------? ?? ?? ?? ?-------??-------??-------
E:\stm32\software4.45.2\Debug\Obj: [1]
? ? main.o? ?? ?? ?? ?? ???12
? ? test.o? ?? ?? ?? ?? ???84? ?? ? 16
? ? -------------------------------------------
? ? Total:? ?? ?? ?? ?? ???96? ?? ? 16
command line: [2]
? ? -------------------------------------------
? ? Total:
dl7M_tl_in.a: [3]
? ? XShttio.o? ?? ?? ?? ?? ?8? ?? ???8? ?? ???8
? ? exit.o? ?? ?? ?? ?? ?? ?6
? ? low_level_init.o? ?? ???4
? ? -------------------------------------------
? ? Total:? ?? ?? ?? ?? ???18? ?? ???8? ?? ???8
rt7M_tl.a: [4]
? ? cexit.o? ?? ?? ?? ?? ? 10
? ? cmain.o? ?? ?? ?? ?? ? 22
? ? copy_init3.o? ?? ?? ???48
? ? cstartup_M.o? ?? ?? ???12
? ? data_init3.o? ?? ?? ???44
? ? vector_table_M.o? ?? ? 66
? ? -------------------------------------------
? ? Total:? ?? ?? ?? ?? ? 202
shb_l.a: [5]
? ? exit.o? ?? ?? ?? ?? ???20
? ? iarttio.o? ?? ?? ?? ???40
? ? -------------------------------------------
? ? Total:? ?? ?? ?? ?? ???60
? ? Gaps? ?? ?? ?? ?? ?? ???2
? ? Linker created? ?? ?? ?? ?? ?? ?20? ? 1 024
-----------------------------------------------
? ? Grand Total:? ?? ?? ? 378? ?? ? 44? ? 1 032
*******************************************************************************
*** ENTRY LIST
***
Entry? ?? ?? ?? ?? ?? ???Address??Size??Type? ?? ?Object
-----? ?? ?? ?? ?? ?? ???-------??----??----? ?? ?------
BusFault_Handler? ?? ?0x08004137? ?? ???Code??Wk??vector_table_M.o [4]
CSTACK$$Base? ?? ?? ? 0x20000000? ?? ?? ?--? ?Gb??- Linker created -
CSTACK$$Limit? ?? ?? ?0x20000400? ?? ?? ?--? ?Gb??- Linker created -
DebugMon_Handler? ?? ?0x08004137? ?? ???Code??Wk??vector_table_M.o [4]
HardFault_Handler? ???0x08004137? ?? ???Code??Wk??vector_table_M.o [4]
MemManage_Handler? ???0x08004137? ?? ???Code??Wk??vector_table_M.o [4]
NMI_Handler? ?? ?? ???0x08004137? ?? ???Code??Wk??vector_table_M.o [4]
PendSV_Handler? ?? ???0x08004137? ?? ???Code??Wk??vector_table_M.o [4]
Region
Base? ?0x080040c4? ?? ?? ?--? ?Gb??- Linker created -
RegionLimit??0x080040d8? ?? ?? ?--? ?Gb??- Linker created -
SVC_Handler? ?? ?? ???0x08004137? ?? ???Code??Wk??vector_table_M.o [4]
SysTick_Handler? ?? ? 0x08004137? ?? ???Code??Wk??vector_table_M.o [4]
UsageFault_Handler? ? 0x08004137? ?? ???Code??Wk??vector_table_M.o [4]
__cmain? ?? ?? ?? ?? ?0x080040d9? ?? ???Code??Gb??cmain.o [4]
__exit? ?? ?? ?? ?? ? 0x080040f1??0x14??Code??Gb??exit.o [5]
__iar_close_ttio? ?? ?0x0800409d??0x26??Code??Gb??iarttio.o [5]
__iar_copy_init3? ?? ?0x08004041??0x30??Code??Gb??copy_init3.o [4]
__iar_data_init3? ?? ?0x08004071??0x2c??Code??Gb??data_init3.o [4]
__iar_lookup_ttioh? ? 0x08004125? ?0x8??Code??Gb??XShttio.o [3]
__iar_program_start? ?0x08004105? ?? ???Code??Gb??cstartup_M.o [4]
__iar_ttio_handles? ? 0x20000400? ?0x8??Data??Lc??XShttio.o [3]
__low_level_init? ?? ?0x08004133? ?0x4??Code??Gb??low_level_init.o [3]
__vector_table? ?? ???0x08004000? ?? ???Data??Gb??vector_table_M.o [4]
_call_main? ?? ?? ?? ?0x080040e5? ?? ???Code??Gb??cmain.o [4]
_exit? ?? ?? ?? ?? ???0x08004111? ?? ???Code??Gb??cexit.o [4]
_main? ?? ?? ?? ?? ???0x080040eb? ?? ???Code??Gb??cmain.o [4]
exit? ?? ?? ?? ?? ?? ?0x0800412d? ?0x6??Code??Gb??exit.o [3]
f1? ?? ?? ?? ?? ?? ???0x08018049? ?0xc??Code??Gb??test.o [1]
main? ?? ?? ?? ?? ?? ?0x0800411b? ?0xa??Code??Gb??main.o [1]
sendstr? ?? ?? ?? ?? ?0x08017001? ?0x2??Code??Gb??main.o [1]
str1? ?? ?? ?? ?? ?? ?0x08018500? ?0x8??Data??Gb??test.o [1]
str2? ?? ?? ?? ?? ?? ?0x08018508? ?0x8??Data??Gb??test.o [1]
test? ?? ?? ?? ?? ?? ?0x08018001??0x44??Code??Gb??test.o [1]
[1] = E:\stm32\software4.45.2\Debug\Obj
[2] = command line
[3] = dl7M_tl_in.a
[4] = rt7M_tl.a
[5] = shb_l.a
? ? 378 bytes of readonly??code memory
? ???44 bytes of readonly??data memory
??1 032 bytes of readwrite data memory
Errors: none
Warnings: none
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
這是.icf文件
/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x08004000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__? ?= 0x08004000;
define symbol __ICFEDIT_region_ROM_end__? ???= 0x08020000;
define symbol __ICFEDIT_region_RAM_start__? ?= 0x20000000;
define symbol __ICFEDIT_region_RAM_end__? ???= 0x2000BFFF;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__? ?= 0x400;
define symbol __ICFEDIT_size_heap__? ???= 0x200;
/**** End of ICF editor section. ###ICF###*/
define memory mem with size = 4G;
define region ROM_region? ?= mem:[from __ICFEDIT_region_ROM_start__? ?to __ICFEDIT_region_ROM_end__];
define region RAM_region? ?= mem:[from __ICFEDIT_region_RAM_start__? ?to __ICFEDIT_region_RAM_end__];
define block CSTACK? ? with alignment = 8, size = __ICFEDIT_size_cstack__? ?{ };
define block HEAP? ?? ?with alignment = 8, size = __ICFEDIT_size_heap__? ???{ };
initialize by copy { readwrite };
do not initialize??{ section .noinit };
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
place at address mem:0x08017000 { readonly section .sendstr};
place at address mem:0x08018500 { readonly section .MYSEG};
place at address mem:0x08018000 { section .text object test.o };
place in ROM_region? ?{ readonly };
place in RAM_region? ?{ readwrite,
? ?? ?? ?? ?? ?? ?? ?? ?block CSTACK, block HEAP };
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
main.c
/* Includes ------------------------------------------------------------------*/
//#include "stm32f10x.h"
#include "string.h"
#include "stdio.h"
void sendstr(unsigned *buf,unsigned short??len) @".sendstr"
{
}
extern void test(void);
extern void main1(void);
int main(void)
{
? ???test();
}
#ifdef??USE_FULL_ASSERT
/**
??* @brief??Reports the name of the source file and the source line number
??*? ?? ?? ?where the assert_param error has occurred.
??* @param??file: pointer to the source file name
??* @param??line: assert_param error line source number
??* @retval None
??*/
void assert_failed(uint8_t* file, uint32_t line)
{?
??/* User can add his own implementation to report the file name and line number,
? ???ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
??/* Infinite loop */
??while (1)
??{
??}
}
#endif
/**
??* @}
??*/
/**
??* @}
??*/
/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
test.c
//__no_init char array1[100]@0x2000B000;
//char array1[100];
const char str1[8]@".MYSEG"="test11!!";
const char str2[8]@".MYSEG"="test66!!";
int f1(int a,int b);
void test(void)// @".test" //MYSEGMENT段可在XCL中開辟
{
? ? char arrayx[150];??
? ? char array1[150];
? ? int i,a,b,c;
? ? for (i=0;i<8;i++){
? ?? ?array1[i]=str1[i];? ?? ?
? ?? ?arrayx[i]=str2[i];? ?? ?
? ? }
? ? a=1;
? ? b=2;
? ? c=f1(a,b);
? ? for (i=0;i<c;i++) {
? ?? ?sendstr(array1,8);? ??
? ?? ?sendstr(arrayx,8);? ??
? ? }
}
int f1(int a,int b){
??if(a>0){
? ?return (a+b)*1;
??}
??else return 0;
}
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
?
對(duì)于你的第三點(diǎn),cortex和其他arm處理器都提供了一種特殊的中斷。。。。Software Interrupt (SVC)
你只要把系統(tǒng)服務(wù)都通過svc來調(diào)用,那么就不需要知道調(diào)用的實(shí)際地址了。。。
當(dāng)然你也可以在固定的位置放一個(gè)函數(shù)指針表來手動(dòng)做這個(gè),調(diào)用系統(tǒng)服務(wù)的時(shí)候從函數(shù)指針表上獲得當(dāng)前版本的函數(shù)的絕對(duì)定位
總結(jié)
以上是生活随笔為你收集整理的IAR之函数和变量的绝对地址定位的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: IAR的const,变量指定绝对地址,函
- 下一篇: MDK:assert_param函数未定