首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

PIC 單片機鏈接腳本文件 (.lkr) 詳解:內存區域與段分配

     編輯:關於C語言

.lkr 文件核心作用

鏈接器腳本定義目標 MCU 的**內存架構映射**,指導鏈接器將代碼段放入 ROM、數據段放入 RAM,保護特殊區域 (向量表、配置字等) 不被誤用。

18F4620.lkr 逐段解析

搜索路徑與輸入文件

LIBPATH .                    // 當前目錄搜索庫/目標文件
FILES c018i.o                // 啟動代碼
FILES clib.lib               // C 標準庫
FILES p18f4620.lib           // 器件專用庫

代碼區域定義 (CODEPAGE)

CODEPAGE NAME=vectors START=0x0000 END=0x0029 PROTECTED   // 復位/中斷向量表
CODEPAGE NAME=page    START=0x002A END=0xFFFF             // 用戶程序空間
CODEPAGE NAME=idlocs  START=0x200000 END=0x200007 PROTECTED // ID 地址
CODEPAGE NAME=config  START=0x300000 END=0x30000D PROTECTED // 配置字
CODEPAGE NAME=devid   START=0x3FFFFE END=0x3FFFFF PROTECTED // 器件 ID
CODEPAGE NAME=eedata  START=0xF00000 END=0xF003FF PROTECTED // EEPROM 數據
  • PROTECTED:鏈接器不會自動將普通代數據放入此區域,除非顯式指定 (SECTION 指令或絕對地址)
  • 地址空間分離:程序空間 (0x0000-0xFFFF)、配置空間 (0x300000+)、EEPROM (0xF00000+)

數據區域定義 (DATABANK / ACCESSBANK)

ACCESSBANK NAME=accessram START=0x000 END=0x07F   // Bank 0 低 128 字節 (快速訪問)
DATABANK NAME=gpr0      START=0x080 END=0x0FF   // Bank 0 通用寄存器
DATABANK NAME=gpr1      START=0x100 END=0x1FF   // Bank 1
...                                               // gpr2 ~ gpr14
DATABANK NAME=gpr15     START=0xF00 END=0xF7F   // Bank 15 通用寄存器
ACCESSBANK NAME=accesssfr START=0xF80 END=0xFFF PROTECTED // Bank 15 SFR 區
  • ACCESSBANK:無需切換銀行即可訪問 (BANKSEL 無關),適合高頻變量
  • DATABANK:需通過 BSR (Bank Select Register) 切換銀行訪問
  • PIC18 共 16 個 Bank (0-15),每 Bank 256 字節

邏輯段映射 (SECTION)

SECTION NAME=CONFIG ROM=config   // 將名為 CONFIG 的代碼段放入 config 區域

STACK SIZE=0x100 RAM=gpr14       // 軟件堆棧大小 256 字節,放入 Bank 14
  • 源碼中用 #pragma section NAME 關聯邏輯段
  • 堆棧配置僅 MPLAB C18 需要,其他編譯器可能不同

關鍵概念總結

指令用途
LIBPATH庫/目標文件搜索路徑
FILES指定參與鏈接的輸入文件
CODEPAGE定義程序內存區域 (ROM/EEPROM/配置空間)
DATABANK定義數據內存區域 (RAM Bank)
ACCESSBANK定義無需切銀行的快速訪問區域
SECTION將邏輯代碼/數據段映射到物理區域
STACK指定軟件堆棧大小及存放位置
PROTECTED保護區域不被自動分配

實踐建議

  1. **修改 .lkr 需極謹慎**:錯誤的區域定義會導致代碼覆蓋向量表、配置字損壞、堆棧溢出等致命錯誤
  2. **自定義段放置**:如需將特定數據放入 EEPROM,定義 CODEPAGE NAME=my_eedata ROM=eedata,源碼用 #pragma section NAME=my_eedata
  3. **堆棧大小評估**:根據中斷嵌套深度、函數調用鏈、局部變量大小預留充足空間,建議留 30%+ 余量
  4. **Bank 切換優化**:高頻全局變量放入 accessram,減少 BANKSEL 指令開銷
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved