好幾年沒玩S3C2440,從單片機(jī)玩到嵌入式,就記得這個(gè)是我入門嵌入式比較早的一款芯片。
S3C2440是帶MMU的,可以上WinCE/Linux這些操作系統(tǒng),適合做嵌入式開發(fā),做單片機(jī)開發(fā)的話,總感覺有點(diǎn)浪費(fèi),但如果只是玩玩應(yīng)該沒問題。
最近業(yè)余時(shí)間想把S3C2440拿來當(dāng)單片機(jī)玩玩。
廢話少說,直接入主題。
第一步當(dāng)然是創(chuàng)建初始工程。
既然是裸機(jī)實(shí)戰(zhàn),想玩點(diǎn)什么特色,看來匯編是不能少的了。ARM9匯編支持的好一點(diǎn)的當(dāng)然是MDK,IAR的匯編語(yǔ)法和ARM官方的有一些區(qū)別,還是算了。
gcc 語(yǔ)法和ARM官方是差不多,不過編譯出來的代碼質(zhì)量比不過MDK。這里就選用MDK5.1
單片機(jī)的helloworld都是從LED開始,我這里也不例外,就從Led開始,或者說從GPIO開始。
打開MDK5,如果已經(jīng)有工程隨MDK啟動(dòng)時(shí)打開,就先關(guān)閉當(dāng)前已經(jīng)打開的工程。
1.創(chuàng)建新工程,要求選擇芯片型號(hào),直接在搜索框輸入S3C2440A,確認(rèn)。
MDK會(huì)自動(dòng)加入S3C2440.s啟動(dòng)文件,里面用ARM匯編語(yǔ)言編寫的,對(duì)于不太熟悉匯編的童鞋來說,可能看懂還是有點(diǎn)難度。
這里就先不用去看,直接使用它創(chuàng)建完整工程,否者后面編譯鏈接通不過。
到后面如果需要加入一些有趣的功能,再回到這個(gè)文件中修改,或者按需要直接重寫。
2.設(shè)置
1)Target頁(yè),
IRAM1 Start 0x40000000 Size 0x1000
去掉Use Cross-Module Optimization 代碼前期建議不要開優(yōu)化
去掉Use mirolib
2) Output頁(yè)
勾上Create HEX File
3)User頁(yè)
勾上 Run #1
后面填上 fromelf.exe --bin -o @p.bin @p.axf
4)后面 Debug和 Unitiily頁(yè)按仿真器類型修改,其他頁(yè)默認(rèn)不用修改。
3.初始工程當(dāng)然還是先完成main函數(shù),那就先創(chuàng)建個(gè)main.c的文件,編寫基本的main函數(shù)。
int main(void)
{
unsigned int a = 0;
unsigned int b = 1;
while(1){
a = b ;
b = a;
}
return 1;
}
編寫完后,當(dāng)然首先想到的是編譯嘛。沒想到一編譯出來各種各樣奇怪的錯(cuò)誤。
仔細(xì)看信息,發(fā)現(xiàn)不是編譯錯(cuò)誤,而是在鏈接階段出的錯(cuò)誤。
好吧,估計(jì)是分散加載設(shè)置有問題了。
4.編寫分散加載腳本。
點(diǎn)擊options for target,也就是工具欄中的設(shè)置鍵,到Linker一欄,去掉Use Memory Layout from Target Dialog,這樣就可以用
Scatter File,也就是分散加載腳本方式。我個(gè)人的習(xí)慣是喜歡用分散加載腳本,上面點(diǎn)勾選的是簡(jiǎn)單的設(shè)置方式,只能支持比較簡(jiǎn)單的分散加載要求。
復(fù)雜的分散加載,它就做不了了,分散加載腳本是簡(jiǎn)單和復(fù)雜通吃。
去掉勾后,系統(tǒng)默認(rèn)給出早工程文件的同目錄下的同工程名的分散加載腳本名,點(diǎn)擊后面的Edit。
用下面的代碼覆蓋它,保存后,重新全部編譯,通過。
ER_ROM1 0x40000000
{
ER_ROM1 0x40000000
{
*.o (RESET, +First)
*(InRoot$$Sections)
* (+RO)
}
RW_RAM1 0x40000800
{
;S3C2440.o (MyStacks)
.ANY (+RW,+ZI) ; * (+RO)
}
HEAP +0 UNINIT
{
S3C2440.o (Heap)
}
STACK 0x40001000 UNINIT
{
S3C2440.o (STACK)
}
}
那是不是到這里就OK了呢,我也不知道,接下來先仿真下。
2015-2-9
5.仿真測(cè)試
一仿真才知道出了大問題,ARM的體系,系統(tǒng)棧是滿遞減方式的,所以棧頂不能超過0x40001000,棧底就更不能超了
計(jì)算了下棧容量,應(yīng)該是0x488,看了map文件,棧頂?shù)搅?x40001488,所以腳本要看一下
ER_ROM1 0x40000000
{
ER_ROM1 0x40000000
{
*.o (RESET, +First)
*(InRoot$$Sections)
* (+RO)
}
RW_RAM1 0x40000800
{
;S3C2440.o (MyStacks)
.ANY (+RW,+ZI) ; * (+RO)
}
HEAP +0 UNINIT
{
S3C2440.o (Heap)
}
STACK 0x40000B00 UNINIT
{
S3C2440.o (STACK)
}
}
這會(huì)編譯下,仿真能進(jìn)main函數(shù)了,但是卻老會(huì)重啟,另外發(fā)現(xiàn)CPU跑的是自己之前燒寫到nandflash前4KB的程序,說明仿真時(shí)看到的代碼其實(shí)是
steppingstone的代碼,且在仿真時(shí),指向第一條指令的位置是0x00000000,而不是0x40000000,看來仿真時(shí)仿真期沒有讓PC指向0x40000000,所以仿真時(shí)跑的是steppingstone的代碼。
在debug一欄中edit initization file中加上以下代碼,這里只是想讓PC直到0x40000000,把初始化時(shí)鐘,RAM等去掉,以后需要再加。
既然是裸機(jī)實(shí)戰(zhàn),那還是盡量讓代碼來做我們需要的功能,腳本替我們做了初始化工作就沒意思了。當(dāng)然PC的初始化是沒辦法了,只能通過腳本來設(shè)置,畢竟現(xiàn)在在
nandflash前4KB的代碼還不是我們自己的代碼,不能掌控。
FUNC void SetupForStart (void) {
//
PC = 0x40000000;//0x30000000
}
FUNC void Init (void) {
// Clock Setup
// FCLK = 300 MHz, HCLK = 100 MHz, PCLK = 50 MHz
// _WDWORD(0x4C000000, 0x0FFF0FFF); // LOCKTIME
// _WDWORD(0x4C000014, 0x0000000F); // CLKDIVN
// _WDWORD(0x4C000004, 0x00043011); // MPLLCON
// _WDWORD(0x4C000008, 0x00038021); // UPLLCON
// _WDWORD(0x4C00000C, 0x001FFFF0); // CLKCON
}
// Reset chip with watchdog, because nRST line is routed on hardware in a way
// that it can not be pulled low with ULINK
//_WDWORD(0x40000000, 0xEAFFFFFE); // Load RAM addr 0 with branch to itself
CPSR = 0x000000D3; // Disable interrupts
PC = 0x40000000; //0x30000000 // Position PC to start of RAM
//_WDWORD(0x53000000, 0x00000021); // Enable Watchdog
//g, 0 // Wait for Watchdog to reset chip
//Init(); // Initialize memory
LOAD project.axf INCREMENTAL // Download program
SetupForStart(); // Setup for Running
再次仿真,沒有問題了。
好,到此,S3C2440裸機(jī)的第一個(gè)工程已經(jīng)差不多完成了。
在仿照CMSIS編寫了外設(shè)頭文件后,再來操作Led。
這里是借由MKD提供的匯編啟動(dòng)代碼來做的,懂匯編的童鞋可以自己寫一個(gè)匯編啟動(dòng),如果不懂也沒什么,可以照著ARM7的匯編啟動(dòng)代碼寫,例如LPC213x/214x系列的匯編啟動(dòng)代碼。
推薦個(gè)鏈接,對(duì)MDK提供的S3C2440匯編啟動(dòng)代碼的解讀:
http://www.oschina.net/question/565065_115207
上一篇:S3C2440開發(fā)板裸機(jī)程序系列07—NAND FLASH存儲(chǔ)器
下一篇:s3c2440 裸機(jī) 系統(tǒng)時(shí)鐘和定時(shí)器的設(shè)置
推薦閱讀
史海拾趣
設(shè)計(jì)資源 培訓(xùn) 開發(fā)板 精華推薦
- 如何計(jì)算單片機(jī)的波特率
- STM32單片機(jī)優(yōu)先級(jí)的定義
- 如何采用STM32單片機(jī)實(shí)現(xiàn)IAP功能
- STM32單片機(jī)對(duì)NAND Flash的讀寫以及在ASF中的使用
- STM32單片機(jī)SysTick系統(tǒng)滴答功能解析
- STM32單片機(jī)定時(shí)器的時(shí)鐘源設(shè)置
- STM32單片機(jī)PID算法的原則及應(yīng)用方法
- 如何采用STM32單片機(jī)中斷向量控制器NVIC來分配優(yōu)先級(jí)的數(shù)量
- STM32單片機(jī)固件庫(kù)建立工程的方法及步驟
- 中國(guó)研究人員發(fā)明全新動(dòng)作好奇心算法 增強(qiáng)不確定環(huán)境下的自主導(dǎo)航
- 技術(shù)解析|沃爾沃XC70超級(jí)混動(dòng)有什么亮點(diǎn)?
- 小米汽車:磁吸物理按鍵已接入米家,可通過APP操控
- 專家專論 | 顧劍民:L2級(jí)輔助駕駛激光雷達(dá)“價(jià)格歸零”
- 近一個(gè)月投資五家!京東密集落子具身智能機(jī)器人賽道
- 海外動(dòng)力電池裝車量TOP10:3家落榜 一新上榜中企暴增逾10倍
- 吉利汽車:全域AI守護(hù)輔助駕駛安全
- 松下汽車系統(tǒng)與VicOne深化合作 共拓新一代智能座艙系統(tǒng)安全創(chuàng)新
- 汽車MCU的“芯”浪潮
- 具身智能如何大規(guī)模推廣?丨具身智能機(jī)器人高質(zhì)量發(fā)展
- 2021年STM32中國(guó)峰會(huì)暨粉絲狂歡節(jié) 報(bào)名啦!
- 一起哇:基于國(guó)產(chǎn)芯、便攜烙鐵系統(tǒng)IronOS(FreeRTOS)的智能烙鐵
- 【已結(jié)束】直播“戴”“芯”:英飛凌可穿戴設(shè)備保姆級(jí)解決方案
- Fluke高分辨率熱像儀~小細(xì)節(jié)也不放過!免費(fèi)體驗(yàn)報(bào)名中
- 下載有禮!是德科技5G精選解決方案,幫您勘破 5G 迷宮!
- 免費(fèi)申請(qǐng)?jiān)囉脇福祿克Norma6000功率分析儀
- EEWorld下載中心大批技術(shù)資料等你來領(lǐng),還有好禮相助
- 《模擬對(duì)話》50周年大合集(2013-2016)
- 分享、評(píng)論《Vishay光電子博文》盡享精彩好禮!
- TI有獎(jiǎng)直播|使用DLP®微型投影技術(shù)的IoT顯示方案
- 2019年Q2全球智能手表出貨量躍升至1200萬
- Stm32F407時(shí)鐘要更改的幾個(gè)地方
- STM32F407時(shí)鐘設(shè)置
- 瑞薩電子ProPILOT 2.0為您實(shí)現(xiàn)ECU駕駛判斷與控制功能
- 基于STM32F407時(shí)鐘配置學(xué)習(xí)
- MSP430 單芯片實(shí)現(xiàn)低成本、低功耗電感鄰近度感測(cè)
- 用MSP430控制的可調(diào)速風(fēng)扇散熱系統(tǒng)方案
- 基于MSP430與uPD720200的高速溫度采集系統(tǒng)的設(shè)計(jì)
- 基于MSP430和CC3000的無線智能控制系統(tǒng)
- ADI—AD7380系列SAR ADC的片內(nèi)過采樣解析