找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3795|回复: 1
打印 上一主题 下一主题
收起左侧

IAR STM32 函数和变量的绝对地址定位

[复制链接]
跳转到指定楼层
楼主
ID:262 发表于 2016-3-11 23:26 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
昨天我突然冒出个想法,能否利用函数和变量的绝对定位,实现程序的模块化更新。


也就是说,如果我要改变某个函数,只需要更新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等库函数了。


绝对定位的函数,如果要使用常量,那么被使用的常量也必须是绝对定位的。否则跨工程更新固件,会导致失败。


绝对定位的函数,如果要使用全局变量,那么被使用的常量也必须是绝对定位的。否则跨工程更新固件,会导致失败。 而局部变量则不受此限制。

  1. ###############################################################################
  2. #                                                                             #
  3. # IAR ELF Linker V5.50.0.51878/W32 for ARM              31/May/2012  12:50:09 #
  4. # Copyright (C) 2007-2010 IAR Systems AB.                                     #
  5. #                                                                             #
  6. #    Output file  =  E:\stm32\software4.45.2\Debug\Exe\software.out           #
  7. #    Map file     =  E:\stm32\software4.45.2\Debug\List\software.map          #
  8. #    Command line =  E:\stm32\software4.45.2\Debug\Obj\main.o                 #
  9. #                    E:\stm32\software4.45.2\Debug\Obj\test.o -o              #
  10. #                    E:\stm32\software4.45.2\Debug\Exe\software.out --map     #
  11. #                    E:\stm32\software4.45.2\Debug\List\software.map          #
  12. #                    --config E:\stm32\software4.45.2\stm32f10x_flash.icf     #
  13. #                    --semihosting --entry __iar_program_start                #
  14. #                                                                             #
  15. #                                                                             #
  16. ###############################################################################

  17. *******************************************************************************
  18. *** PLACEMENT SUMMARY
  19. ***

  20. "A1":  place at 0x08004000 { ro section .intvec };
  21. "A2":  place at 0x08017000 { ro section .sendstr };
  22. "A3":  place at 0x08018500 { ro section .MYSEG };
  23. "A4":  place at 0x08018000 { object test.o section .text };
  24. "P1":  place in [from 0x08004000 to 0x08020000] { ro };
  25. "P2":  place in [from 0x20000000 to 0x2000bfff] {
  26.           rw, block CSTACK, block HEAP };

  27.   Section            Kind        Address   Size  Object
  28.   -------            ----        -------   ----  ------
  29. "A1":                                      0x40
  30.   .intvec            ro code  0x08004000   0x40  vector_table_M.o [4]
  31.                             - 0x08004040   0x40

  32. "P1":                                     0x100
  33.   .text              ro code  0x08004040   0x30  copy_init3.o [4]
  34.   .text              ro code  0x08004070   0x2c  data_init3.o [4]
  35.   .text              ro code  0x0800409c   0x28  iarttio.o [5]
  36.   .iar.init_table    const    0x080040c4   0x14  - Linker created -
  37.   .text              ro code  0x080040d8   0x16  cmain.o [4]
  38.   .text              ro code  0x080040f0   0x14  exit.o [5]
  39.   .text              ro code  0x08004104    0xc  cstartup_M.o [4]
  40.   .text              ro code  0x08004110    0xa  cexit.o [4]
  41.   .text              ro code  0x0800411a    0xa  main.o [1]
  42.   .text              ro code  0x08004124    0x8  XShttio.o [3]
  43.   .text              ro code  0x0800412c    0x6  exit.o [3]
  44.   .text              ro code  0x08004132    0x4  low_level_init.o [3]
  45.   .text              ro code  0x08004136    0x2  vector_table_M.o [4]
  46.   Initializer bytes  ro data  0x08004138    0x8  
  47.                             - 0x08004140  0x100

  48. "A2":                                       0x2
  49.   .sendstr           ro code  0x08017000    0x2  main.o [1]
  50.                             - 0x08017002    0x2

  51. "A4":                                      0x54
  52.   .text              ro code  0x08018000   0x54  test.o [1]
  53.                             - 0x08018054   0x54

  54. "A3":                                      0x10
  55.   .MYSEG             const    0x08018500   0x10  test.o [1]
  56.                             - 0x08018510   0x10

  57. "P2", part 1 of 2:                        0x400
  58.   CSTACK                      0x20000000  0x400  
  59.     CSTACK           uninit   0x20000000  0x400  
  60.                             - 0x20000400  0x400

  61. "P2", part 2 of 2:                          0x8
  62.   P2 s0                       0x20000400    0x8  
  63.     .data            inited   0x20000400    0x8  XShttio.o [3]
  64.                             - 0x20000408    0x8


  65. *******************************************************************************
  66. *** INIT TABLE
  67. ***

  68.           Address     Size
  69.           -------     ----
  70. Copy (__iar_copy_init3)
  71.     1 source range, total size 0x8 (100% of destination):
  72.           0x08004138   0x8
  73.     1 destination range, total size 0x8:
  74.           0x20000400   0x8


  75. *******************************************************************************
  76. *** MODULE SUMMARY
  77. ***

  78.     Module            ro code  ro data  rw data
  79.     ------            -------  -------  -------
  80. E:\stm32\software4.45.2\Debug\Obj: [1]
  81.     main.o                 12
  82.     test.o                 84       16
  83.     -------------------------------------------
  84.     Total:                 96       16

  85. command line: [2]
  86.     -------------------------------------------
  87.     Total:

  88. dl7M_tl_in.a: [3]
  89.     XShttio.o               8        8        8
  90.     exit.o                  6
  91.     low_level_init.o        4
  92.     -------------------------------------------
  93.     Total:                 18        8        8

  94. rt7M_tl.a: [4]
  95.     cexit.o                10
  96.     cmain.o                22
  97.     copy_init3.o           48
  98.     cstartup_M.o           12
  99.     data_init3.o           44
  100.     vector_table_M.o       66
  101.     -------------------------------------------
  102.     Total:                202

  103. shb_l.a: [5]
  104.     exit.o                 20
  105.     iarttio.o              40
  106.     -------------------------------------------
  107.     Total:                 60

  108.     Gaps                    2
  109.     Linker created                  20    1 024
  110. -----------------------------------------------
  111.     Grand Total:          378       44    1 032


  112. *******************************************************************************
  113. *** ENTRY LIST
  114. ***

  115. Entry                    Address  Size  Type      Object
  116. -----                    -------  ----  ----      ------
  117. BusFault_Handler      0x08004137        Code  Wk  vector_table_M.o [4]
  118. CSTACK$Base          0x20000000         --   Gb  - Linker created -
  119. CSTACK$Limit         0x20000400         --   Gb  - Linker created -
  120. DebugMon_Handler      0x08004137        Code  Wk  vector_table_M.o [4]
  121. HardFault_Handler     0x08004137        Code  Wk  vector_table_M.o [4]
  122. MemManage_Handler     0x08004137        Code  Wk  vector_table_M.o [4]
  123. NMI_Handler           0x08004137        Code  Wk  vector_table_M.o [4]
  124. PendSV_Handler        0x08004137        Code  Wk  vector_table_M.o [4]
  125. Region

  126. Table
  127. Base   0x080040c4         --   Gb  - Linker created -
  128. Region
  129. Table
  130. Limit  0x080040d8         --   Gb  - Linker created -
  131. SVC_Handler           0x08004137        Code  Wk  vector_table_M.o [4]
  132. SysTick_Handler       0x08004137        Code  Wk  vector_table_M.o [4]
  133. UsageFault_Handler    0x08004137        Code  Wk  vector_table_M.o [4]
  134. __cmain               0x080040d9        Code  Gb  cmain.o [4]
  135. __exit                0x080040f1  0x14  Code  Gb  exit.o [5]
  136. __iar_close_ttio      0x0800409d  0x26  Code  Gb  iarttio.o [5]
  137. __iar_copy_init3      0x08004041  0x30  Code  Gb  copy_init3.o [4]
  138. __iar_data_init3      0x08004071  0x2c  Code  Gb  data_init3.o [4]
  139. __iar_lookup_ttioh    0x08004125   0x8  Code  Gb  XShttio.o [3]
  140. __iar_program_start   0x08004105        Code  Gb  cstartup_M.o [4]
  141. __iar_ttio_handles    0x20000400   0x8  Data  Lc  XShttio.o [3]
  142. __low_level_init      0x08004133   0x4  Code  Gb  low_level_init.o [3]
  143. __vector_table        0x08004000        Data  Gb  vector_table_M.o [4]
  144. _call_main            0x080040e5        Code  Gb  cmain.o [4]
  145. _exit                 0x08004111        Code  Gb  cexit.o [4]
  146. _main                 0x080040eb        Code  Gb  cmain.o [4]
  147. exit                  0x0800412d   0x6  Code  Gb  exit.o [3]
  148. f1                    0x08018049   0xc  Code  Gb  test.o [1]
  149. main                  0x0800411b   0xa  Code  Gb  main.o [1]
  150. sendstr               0x08017001   0x2  Code  Gb  main.o [1]
  151. str1                  0x08018500   0x8  Data  Gb  test.o [1]
  152. str2                  0x08018508   0x8  Data  Gb  test.o [1]
  153. test                  0x08018001  0x44  Code  Gb  test.o [1]


  154. [1] = E:\stm32\software4.45.2\Debug\Obj
  155. [2] = command line
  156. [3] = dl7M_tl_in.a
  157. [4] = rt7M_tl.a
  158. [5] = shb_l.a

  159.     378 bytes of readonly  code memory
  160.      44 bytes of readonly  data memory
  161.   1 032 bytes of readwrite data memory

  162. Errors: none
  163. Warnings: none
  164. ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

  165. 这是.icf文件

  166. define symbol __ICFEDIT_intvec_start__ = 0x08004000;
  167. define symbol __ICFEDIT_region_ROM_start__   = 0x08004000;
  168. define symbol __ICFEDIT_region_ROM_end__     = 0x08020000;
  169. define symbol __ICFEDIT_region_RAM_start__   = 0x20000000;
  170. define symbol __ICFEDIT_region_RAM_end__     = 0x2000BFFF;
  171. define symbol __ICFEDIT_size_cstack__   = 0x400;
  172. define symbol __ICFEDIT_size_heap__     = 0x200;


  173. define memory mem with size = 4G;
  174. define region ROM_region   = mem:[from __ICFEDIT_region_ROM_start__   to __ICFEDIT_region_ROM_end__];
  175. define region RAM_region   = mem:[from __ICFEDIT_region_RAM_start__   to __ICFEDIT_region_RAM_end__];

  176. define block CSTACK    with alignment = 8, size = __ICFEDIT_size_cstack__   { };
  177. define block HEAP      with alignment = 8, size = __ICFEDIT_size_heap__     { };

  178. initialize by copy { readwrite };
  179. do not initialize  { section .noinit };

  180. place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };

  181. place at address mem:0x08017000 { readonly section .sendstr};
  182. place at address mem:0x08018500 { readonly section .MYSEG};

  183. place at address mem:0x08018000 { section .text object test.o };

  184. place in ROM_region   { readonly };
  185. place in RAM_region   { readwrite,
  186.                         block CSTACK, block HEAP };

  187. -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

  188. main.c

  189. //#include "stm32f10x.h"
  190. #include "string.h"
  191. #include "stdio.h"

  192. void sendstr(unsigned *buf,unsigned short  len) @".sendstr"
  193. {
  194. }

  195. extern void test(void);
  196. extern void main1(void);
  197. int main(void)
  198. {
  199.      test();
  200. }

  201. #ifdef  USE_FULL_ASSERT
  202. void assert_failed(uint8_t* file, uint32_t line)
  203. {



  204.   while (1)
  205.   {
  206.   }
  207. }
  208. #endif




  209. -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

  210. test.c

  211. //__no_init char array1[100]@0x2000B000;

  212. //char array1[100];

  213. const char str1[8]@".MYSEG"="test11!!";
  214. const char str2[8]@".MYSEG"="test66!!";


  215. int f1(int a,int b);
  216. void test(void)// @".test" //MYSEGMENT段可在XCL中开辟
  217. {
  218.     char arrayx[150];  
  219.     char array1[150];
  220.     int i,a,b,c;
  221.     for (i=0;i<8;i++){
  222.       array1[i]=str1[i];      
  223.       arrayx[i]=str2[i];      
  224.     }
  225.     a=1;
  226.     b=2;
  227.     c=f1(a,b);
  228.     for (i=0;i
  229.       sendstr(array1,8);   
  230.       sendstr(arrayx,8);   
  231.     }
  232. }

  233. int f1(int a,int b){
  234.   if(a>0){
  235.    return (a+b)*1;
  236.   }
  237.   else return 0;
  238. }
复制代码


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:262 发表于 2016-3-11 23:26 | 只看该作者
51黑有你更精彩!!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表