|
昨天我突然冒出個想法,能否利用函數和變量的絕對定位,實現程序的模塊化更新。
也就是說,如果我要改變某個函數,只需要更新flash里面一個局部,也許只需要更新幾百個字節,而無須重新下載整個上百K的程序。
經過查找資料和反復實驗,終于實現了,現總結如下:
1)把函數定位在FLASH高端的指定位置,以后更新,只更新那小塊地方就可以了。
方法一:
IAR里面進行函數定位,必須要在.icf里面,進行定義。
void sendstr(unsigned*buf,unsigned short len)@".sendstr"
{
....
}
.icf文件,加入這樣一句:
place at address mem:0x08017000 { readonlysection .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/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
- - 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
- CSTACK uninit 0x20000000 0x400
- - 0x20000400 0x400
- "P2", part 2 of 2: 0x8
- P2 s0 0x20000400 0x8
- .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
- Table
- Base 0x080040c4 -- Gb - Linker created -
- Region
- Table
- Limit 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文件
- define symbol __ICFEDIT_intvec_start__ = 0x08004000;
- 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;
- define symbol __ICFEDIT_size_cstack__ = 0x400;
- define symbol __ICFEDIT_size_heap__ = 0x200;
- 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
- //#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
- void assert_failed(uint8_t* file, uint32_t line)
- {
-
-
- while (1)
- {
- }
- }
- #endif
- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- 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;
- }
復制代碼
|
|