日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

如何使用sct文件、icf文件来定位不同的内存存储变量(cortex-m3平台)keil+iar

發布時間:2023/12/13 综合教程 34 生活家
生活随笔 收集整理的這篇文章主要介紹了 如何使用sct文件、icf文件来定位不同的内存存储变量(cortex-m3平台)keil+iar 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

好久沒寫博客了,快到國慶了,經歷了一些項目和坑,還是要保持記錄的好習慣,好記性不如爛筆頭嘛。
目前使用了cortex-m3內核的兩款單片機:stm32f1和lpc1768的,雖說是cm3內核,但是兩個芯片添加的外設是有區別的,很多外設的使用方式也是各有千秋,st在國內比較火,全國研討會如火如荼,每年都有。lpc1768是屬于NXP半導體,前身是飛利浦半導體,也算是老牌的半導體公司,相比較stm32,國內入門的論壇沒有stm32火爆,但我相信質量過得去。

兩款單片機都是比較老了,stm32f1是2007年發布的,lpc1768是估計2009年左右,具體不清楚,我是看標準庫上是這個日期,因此猜測。
雖然不是老的芯片,但是市場依然有供應。
可以作為arm入門的基礎芯片。

stm32f103zet是512flash,64ksram,而且是連續的sram分布,那么程序上使用基本上不用過多考慮;而lpc1768也是有64ksram的,但是是分為3個區域的,32ksram作為普通的sram,和stm32f1類似,使用無區別,但是另外兩個16kb的內存空間是在另外的地址空間,手冊原文:
The LPC17xx contain a total of 64 kB on-chip static RAM memory. This includes the main 32 kB SRAM, accessible by the CPU and DMA controller on a higher-speed bus, and two additional 16 kB each SRAM blocks situated on a separate slave port on the AHB multilayer matrix.

LPC17xx總共包含64 kB片上靜態RAM存儲器。 其中包括可由高速總線上的CPU和DMA控制器訪問的主32 kB SRAM,以及位于AHB多層矩陣上獨立從端口上的兩個附加16 kB SRAM塊。
總結起來就是,32ksram的起始地址0x1000 0000,大小0x8000=64kb
兩個附加16 kB SRAM塊的起始地址0x2007C000,而且是連續的,下面的計算可見一斑。
hex(0x2007C000+0x8000)= 0x20084000
hex(0x2007C000+0x4000)= 0x20080000
因此在keil設置中,可以設置兩個32kb的內存空間,而且如果使用了分散加載文件,那么兩個附加16 kB內存就可以完全利用起來了,lpc1768這個設計的原因是想兩個內存空間可以再單片機運行的過程中,分別取數據,快加usb和ethernet數據的讀寫,和普通的變量區分開來————論壇大佬解釋的。具體鏈接找不到了。。
如何使用呢?sct文件的使用參考了硬漢論壇的pdf文檔,H7系列的。

這里首先使用stm32來演示下:
; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************

LR_IROM1 0x08000000 0x00080000 { ; load region size_region
ER_IROM1 0x08000000 0x00080000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
.ANY (+XO)
}
RW_IRAM1 0x20000000 0x00008000 { ; RW data
.ANY (+RW +ZI)
}
; RW data - 32KB SRAM
RW_IRAM2 0x20008000 0x00008000 {
*(.RAM_D1)
}
}

我把64kb分成兩個32kb的空間,keil需要設置linker界面,使用自定義的sct文件

ac6.14編譯器實例:

定義全局變量:
__attribute__((section (".RAM_D1"))) uint32_t AXISRAMBuf[10];
__attribute__((section (".RAM_D1"))) uint32_t temp = 0;
下面的語句也是合法的,
uint8_t UART_TX_BUF[10] __attribute__((section(".ARM.__at_0x2000B00A"))); //就是將串口發送的數據定位到RAM中起始地址為0X2000b00A
編譯之后,可以在map文件看到這幾個變量的具體地址
temp 0x20008000 Data 4 main.o(.RAM_D1)
AXISRAMBuf 0x20008004 Data 40 main.o(.RAM_D1)
UART_RX_BUF 0x2000b000 Data 10 main.o(.ARM.__at_0x2000b000)
UART_TX_BUF 0x2000b00a Data 10 main.o(.ARM.__at_0x2000B00A)

那么就是成功的,如果使用AC5編譯器

__attribute__((section (".RAM_D1"))) uint32_t AXISRAMBuf[10];
__attribute__((section (".RAM_D1"))) uint32_t temp = 0;

AXISRAMBuf[0] = 11;
temp= 11;

優化等級-00
AXISRAMBuf    0x20008000 Data 40 main.o(.RAM_D1)
temp        0x20008028 Data 4 main.o(.RAM_D1)
優化等級-03
temp        0x20008000 Data 4 main.o(.RAM_D1)
AXISRAMBuf    0x20008004 Data 40 main.o(.RAM_D1)

優化等級-03
temp只定義,代碼中不試用
AXISRAMBuf   0x20008000 Data 40 main.o(.RAM_D1)

可見,編譯會把代碼中不適用的變量,在linker的時候就,不分配空間了,相當于刪除了這個變量

lpc1768的芯片小技巧:
使用iar編譯器,測試通過,也記錄下:
使用兩個sram的方法參見博客鏈接:
https://blog.csdn.net/liming0931/article/details/108887551

定義變量,int val_addr @0x2007C000;
編譯后map文件如下:
val_addr 0x2007'c000 0x4 Data Gb main.o [1]
成功!

keil平臺下有兩種方法可以將lpc1768的兩個內存使用起來

1、keil選項設置

ac5編譯器定義變量,uint32_t variable2 __attribute__((at(0x2007C42C))); // Place at 0x2007C000(因為lpc1768的庫文件core_cm3.h,不支持ac6,暫時使用ac5)

0x2007C42C這個地址需要查看map文件后在自定義地址,否則就會出現linker警告,比如0x2007C004,

linking...

.KEIL5OUTcheck.axf: Warning: L6918W: Execution region RW_IRAM2 placed at 0x2007c000 needs padding to ensure alignment 4 of main.o(.ARM.__AT_0x2007C004).

為啥呢?

意思是0x2007c000 到0x2007c007的空間沒有使用。定義到0x2007c000鏈接就沒有警告了,因為uart_data_to_linux,uart_data_to_g0這兩個變量占用的空間比較大,linker自動將該變量分配到0x2007c000之后的內存地址中了,但是如果不適用iram2,那么只能分配到iram1中。

2、使用自定義的sct文件

iram2 記得不要打鉤。

然后定義變量:

uint32_t variable2 __attribute__((at(0x2007C050))); // Place at0x2007C050
__attribute__((section(".RAM_D1"))) uint32_t AXISRAMBuf[10];
__attribute__((section(".RAM_D1"))) uint32_t AXISRAMBuf2[10]

map文件如下:具體負

AXISRAMBuf     0x2007c000   Data   40 main.o(.RAM_D1)
AXISRAMBuf2       0x2007c028  Data    40 main.o(.RAM_D1)
variable2        0x2007c050    Data    4 main.o(.ARM.__AT_0x2007C050)

keil的linker模式是優先分配__attribute__((section(".RAM_D1")))這種形式定義的變量,如果使用下面的方式:

uint32_t variable2 __attribute__((at(0x2007C000))); // Place at0x2007C000
__attribute__((section(".RAM_D1"))) uint32_t AXISRAMBuf[10];
__attribute__((section(".RAM_D1"))) uint32_t AXISRAMBuf2[10]

linker報錯,也無法生產map文件

.KEIL5OUTcheck.axf: Error: L6985E: Unable to automatically place AT section main.o(.ARM.__AT_0x2007C000) with required base address 0x2007c000. Please manually place in the scatter file using the --no_autoat option.

--no_autoat具體怎么使用,暫時不了解。

具體的link而使用方法,可以參考arm linker參考文件

總結:

使用__attribute__((at(0x2007C004))); 這種方法需要自己計算內存的地址相對比較麻煩,__attribute__((section(".RAM_D1")))

使用__attribute__((section(".RAM_D1"))) ,省去了手動計算地址的麻煩,相對簡單。ac5,ac6通用的。

總結

以上是生活随笔為你收集整理的如何使用sct文件、icf文件来定位不同的内存存储变量(cortex-m3平台)keil+iar的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。