1. 程式人生 > >IAR STM32 函式和變數的絕對地址定位

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

 昨天我突然冒出個想法,能否利用函式和變數的絕對定位,實現程式的模組化更新。

  也就是說,如果我要改變某個函式,只需要更新flash裡面一個區域性,也許只需要更新幾百個位元組,而無須重新下載整個上百K的程式。

  經過查詢資料和反覆實驗,終於實現了,現總結如下:

  1) 把函式定位在FLASH高階的指定位置,以後更新,只更新那小塊地方就可以了。

  方法一:

    IAR裡面進行函式定位, 必須要在.icf裡面,進行定義。

   void sendstr(unsigned *buf,unsigned short  len) @".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)跨工程韌體更新注意事項:

韌體更新區的絕對定位的函式,不能隨意呼叫其他庫函式,那些被呼叫的函式也必須是絕對定位的。否則跨工程更新韌體,會導致失敗,因為被呼叫的函式在不同工程裡,動態連線到的位置不同。 

但是這個可以解決:被呼叫的函式,在兩邊工程都申明的絕對地址,並且在非韌體更新區(就是兩邊工程的韌體裡,這些被呼叫函式的位置都一樣,只需要函式名和地址一樣即可,函式內部可以不同)。那麼被這些呼叫的函式內,可以隨意呼叫其他函式,如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  <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
-----                    -------  ----  ----      ------

相關推薦

IAR STM32 函式變數絕對地址定位

 昨天我突然冒出個想法,能否利用函式和變數的絕對定位,實現程式的模組化更新。  也就是說,如果我要改變某個函式,只需要更新flash裡面一個區域性,也許只需要更新幾百個位元組,而無須重新下載整個上百K的程式。  經過查詢資料和反覆實驗,終於實現了,現總結如下:  1) 把函

6函式變數

函式定義 def 函式名(引數1,引數2.....): 函式體   用return 返回值 函式內return後面的程式碼不再執行   用來確定傳入引數型別 a = 1 isinstance(a,(int,floa

Unity3D - 常用函式變數

最近在學習Unity Shader,寫Shader的時候總是忘記Unity為我們提供的函式、變數怎麼寫的,這裡整理一下,方便自己查閱,也提供給網友,學習Shader不易。 1、函式 float3 WorldSpaceViewDir(float4 v) //輸入一個模型空間中的頂點位置,返回世界

棧區返回變數的值變數地址區別

 int fun()     {         int a = 10;         return a;    &n

《笨方法學 Python 3》19.函式變數

#def定義一個變數,cheese乳酪, crackers餅乾 def cheese_and_crackers(cheese_count, boxes_of_crackers): print(f"You have {cheese_count} cheeses!") print(f"You have {bo

《Learn python3 the hard way》ex19 函式變數

def cheese_and_crackers(cheese_count, boxes_of_crackers): # 定義一個有兩個引數的函式 print(f"You have {cheese_count} cheeses!") print(f

建構函式、解構函式變數的生存期

//referred from Wei Guo, Peking University #include<iostream> using namespace std; class Demo{ int id; public: Demo(int i)

jmeter函式變數(一)

概述 對jmeter函式進行一次全面複習,依據是官網的文件版本3.2。本來想一篇寫完的,中間做專案和一些雜事拖了2個禮拜,再回來寫的時候發現太長了~還是分開寫比較妥當。先放出一部分吧。 函式和變數 JMeter函式是一種特殊的值,可以在測試樹中填充任何

jmeter函式變數(二)

__javaScript 函式__javaScript可以用來執行JavaScript程式碼片段(非Java),並返回結果值。JMeter的__javaScript函式會呼叫標準的javascript直譯器。JavaScript會作為指令碼語言使用,因

python中那些雙下劃線開頭得函式變數

Python 用下劃線作為變數字首和字尾指定特殊變數 _xxx 不能用’from module import *’匯入 __xxx__ 系統定義名字 __xxx 類中的私有變數名 核心風格:避免用下劃線作為變數名的開始。 因為下劃線對直譯器有特殊的意義,而且是內建識別符號所使用的符號,我們建議程式設計師避

在vim中使用cscope查詢呼叫、定義函式變數的地方

在vim中用了一陣子ctags,確實美中不足。ctags只能根據呼叫函式的地方查詢定義該函式的地方,不能根據定義函式的地方查詢都有哪些地方呼叫了 該函式。於是又學習了cscope。Cscope在主頁上說它具有毋庸置疑的UNIX血統,早在PDP-11的時代就已經在貝爾實驗室開發出來了。我的 Linux是S

KEIL C51之絕對地址定位

微控制器空間分配看*.M51檔案,ARM,DSP空間分配看*.map檔案 1、函式定位: 假如要把C原始檔 tools.c 中的函式 int BIN2HEX(int xx) {     ... } 放在CODE MEMORY的0x1000處,先編譯該工程,然後開啟該工程的

static函式變數

轉自:http://hi.baidu.com/jwjin/blog/item/037fe544bd8fd683b3b7dc3b.html 用static宣告的變數在C語言中有兩方面的特徵:1)變數會被放在程式的全域性儲存區中,這樣可以在下一次呼叫的時候還可以保持原來的賦值。

vc 子視窗怎麼呼叫父視窗的函式變數

1. 首先要在父視窗中定義成public的變數與函式2. 通過指標指向父視窗3. 再進行呼叫 .如 CxxxDlg *pDlg=(CxxxDlg *)AfxGetMainWnd(); 或CxxxDlg

C++ 相同作用域的函式變數不可同名

C++ 全域性函式與全域性變數不可同名 C++中相同作用域的函式和變數不可同名 // 編譯報錯 int a = 10; void a(){ // some code} 某日,在Chrom

解決zend studio程式碼無法自動提示以及程式碼跟蹤函式變數的問題

zend studio這工具會突然抽風,所有函式方法不能自動提示。下面是一些penngo用過的、收集整理的解決方法。 方法1、在不提示的專案上滑鼠右鍵,開啟選單,選擇Build Path->Configure Build Path,在彈出視窗中選擇PHP Build

51微控制器中將變數、陣列、函式設定在固定位置,定位絕對地址

一、不帶初值的變數或陣列 直接使用_at_ 關鍵字加上地址就行。 如:  unsigned char idata myvar _at_ 0x40;  unsigned char code myvar[10] _at_ 0x40; _at_ 關鍵字

51微控制器中怎麼將函式或者變數定位到指定地址,非常有用

問:C51 怎樣將1個子程式段定位在1個固定的地址位置?        以下2問題均要用C51解決 1。 怎樣將1個子程式段定位在1個固定的地址位置?     例如將 INT BCD2HEX(INT XX)定位在1000H 2。 HOW在EEPROM 中固定的位置存放1字串

Excel的vlookup函式進行資料合併絕對地址

內容如圖所示,[img]http://dl.iteye.com/upload/picture/pic/120140/07cae8b7-3ddb-35d3-8af5-a05f473f9c1a.jpg[/img]現在想把下面那個表裡的卡號按照學號填充到上面那個表的後面,這種情況用

js 函式宣告提升變數提升

1. 函式宣告提升 func() function func () { } 上例不會報錯,正是因為 ‘函式宣告提升’,即將函式宣告提升(整體)到作用域頂部(注意是函式宣告,不包括函式表示式),實際提升後結果同下: // 函式宣告提升 function func () { } func()