新聞中心

EEPW首頁 > 嵌入式系統 > 設計應用 > IAR STM32 函數和變量的絕對地址定位

IAR STM32 函數和變量的絕對地址定位

作者: 時間:2016-11-10 來源:網絡 收藏
昨天我突然冒出個想法,能否利用函數變量的絕對定位,實現程序的模塊化更新。

也就是說,如果我要改變某個函數,只需要更新flash里面一個局部,也許只需要更新幾百個字節(jié),而無須重新下載整個上百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)跨工程固件更新注意事項:

固件更新區(qū)的絕對定位的函數,不能隨意調用其他庫函數,那些被調用的函數也必須是絕對定位的。否則跨工程更新固件,會導致失敗,因為被調用的函數在不同工程里,動態(tài)連接到的位置不同。

但是這個可以解決:被調用的函數,在兩邊工程都申明的絕對地址,并且在非固件更新區(qū)(就是兩邊工程的固件里,這些被調用函數的位置都一樣,只需要函數名和地址一樣即可,函數內部可以不同)。那么被這些調用的函數內,可以隨意調用其他函數,如printf ,strcpy等庫函數了。

絕對定位的函數,如果要使用常量,那么被使用的常量也必須是絕對定位的。否則跨工程更新固件,會導致失敗。

絕對定位的函數,如果要使用全局變量,那么被使用的常量也必須是絕對定位的。否則跨工程更新固件,會導致失敗。而局部變量則不受此限制。

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

本文引用地址:http://butianyuan.cn/article/201611/317115.htm

###############################################################################
# #
# 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:stm32software4.45.2DebugExesoftware.out #
# Map file =E:stm32software4.45.2DebugListsoftware.map #
# Command line =E:stm32software4.45.2DebugObjmain.o #
# E:stm32software4.45.2DebugObjtest.o -o #
# E:stm32software4.45.2DebugExesoftware.out --map #
# E:stm32software4.45.2DebugListsoftware.map #
# --config E:stm32software4.45.2stm32f10x_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 0xccstartup_M.o [4]
.text ro code0x08004110 0xacexit.o [4]
.text ro code0x0800411a 0xamain.o [1]
.text ro code0x08004124 0x8XShttio.o [3]
.text ro code0x0800412c 0x6exit.o [3]
.text ro code0x08004132 0x4low_level_init.o [3]
.text ro code0x08004136 0x2vector_table_M.o [4]
Initializer bytesro data0x08004138 0x8
- 0x080041400x100

"A2": 0x2
.sendstr ro code0x08017000 0x2main.o [1]
- 0x08017002 0x2

"A4": 0x54
.text ro code0x08018000 0x54test.o [1]
- 0x08018054 0x54

"A3": 0x10
.MYSEG const 0x08018500 0x10test.o [1]
- 0x08018510 0x10

"P2", part 1 of 2: 0x400
CSTACK 0x200000000x400
CSTACK uninit 0x200000000x400
- 0x200004000x400

"P2", part 2 of 2: 0x8
P2 s0 0x20000400 0x8
.data inited 0x20000400 0x8XShttio.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 codero datarw data
------ ---------------------
E:stm32software4.45.2DebugObj: [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 AddressSizeType Object
----- --------------- ------
BusFault_Handler 0x08004137 CodeWkvector_table_M.o [4]
CSTACK$$Base 0x20000000 -- Gb- Linker created -
CSTACK$$Limit 0x20000400 -- Gb- Linker created -
DebugMon_Handler 0x08004137 CodeWkvector_table_M.o [4]
HardFault_Handler 0x08004137 CodeWkvector_table_M.o [4]
MemManage_Handler 0x08004137 CodeWkvector_table_M.o [4]
NMI_Handler 0x08004137 CodeWkvector_table_M.o [4]
PendSV_Handler 0x08004137 CodeWkvector_table_M.o [4]
Region

Table
Base 0x080040c4 -- Gb- Linker created -
Region
Table
Limit0x080040d8 -- Gb- Linker created -
SVC_Handler 0x08004137 CodeWkvector_table_M.o [4]
SysTick_Handler 0x08004137 CodeWkvector_table_M.o [4]
UsageFault_Handler 0x08004137 CodeWkvector_table_M.o [4]
__cmain 0x080040d9 CodeGbcmain.o [4]
__exit 0x080040f10x14CodeGbexit.o [5]
__iar_close_ttio 0x0800409d0x26CodeGbiarttio.o [5]
__iar_copy_init3 0x080040410x30CodeGbcopy_init3.o [4]
__iar_data_init3 0x080040710x2cCodeGbdata_init3.o [4]
__iar_lookup_ttioh 0x08004125 0x8CodeGbXShttio.o [3]
__iar_program_start 0x08004105 CodeGbcstartup_M.o [4]
__iar_ttio_handles 0x20000400 0x8DataLcXShttio.o [3]
__low_level_init 0x08004133 0x4CodeGblow_level_init.o [3]
__vector_table 0x08004000 DataGbvector_table_M.o [4]
_call_main 0x080040e5 CodeGbcmain.o [4]
_exit 0x08004111 CodeGbcexit.o [4]
_main 0x080040eb CodeGbcmain.o [4]
exit 0x0800412d 0x6CodeGbexit.o [3]
f1 0x08018049 0xcCodeGbtest.o [1]
main 0x0800411b 0xaCodeGbmain.o [1]
sendstr 0x08017001 0x2CodeGbmain.o [1]
str1 0x08018500 0x8DataGbtest.o [1]
str2 0x08018508 0x8DataGbtest.o [1]
test 0x080180010x44CodeGbtest.o [1]


[1] = E:stm32software4.45.2DebugObj
[2] = command line
[3] = dl7M_tl_in.a
[4] = rt7M_tl.a
[5] = shb_l.a

378 bytes of readonlycode memory
44 bytes of readonlydata memory
1 032 bytes of readwrite data memory

Errors: none
Warnings: none

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

這是.icf文件

/*###ICF### Section handled by ICF editor, dont touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$configideIcfEditorcortex_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 shortlen) @".sendstr"
{
}

extern void test(void);
extern void main1(void);
int main(void)
{
test();
}

#ifdefUSE_FULL_ASSERT
/**
* @briefReports the name of the source file and the source line number
* where the assert_param error has occurred.
* @paramfile: pointer to the source file name
* @paramline: 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 %drn", 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 sendstr(array1,8);
sendstr(arrayx,8);
}
}

int f1(int a,int b){
if(a>0){
return (a+b)*1;
}
else return 0;
}

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

對于你的第三點,cortex和其他arm處理器都提供了一種特殊的中斷。。。。Software Interrupt (SVC)
你只要把系統服務都通過svc來調用,那么就不需要知道調用的實際地址了。。。
當然你也可以在固定的位置放一個函數指針表來手動做這個,調用系統服務的時候從函數指針表上獲得當前版本的函數的絕對定位



評論


技術專區(qū)

關閉