<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > IAR STM32 函數(shù)和變量的絕對(duì)地址定位

          IAR STM32 函數(shù)和變量的絕對(duì)地址定位

          作者: 時(shí)間:2016-11-10 來源:網(wǎng)絡(luò) 收藏
          昨天我突然冒出個(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 shortlen) @".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)致失敗。而局部變量則不受此限制。

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

          本文引用地址:http://www.ex-cimer.com/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;
          }

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

          對(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ì)定位



          評(píng)論


          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();