arm开发tq2440上的c++裸奔程序
AVR實驗做到LCD的時候,就發現proteus上沒有現成合適的顯示模塊,網上找的模塊不是按一般方法封裝的,想來自己還有一塊arm9開發板,大概大三、大四時候買的,已經擱置三年了。畢業這兩年已經從51玩到AVR,雖然大多在proteus上玩,但對如何開發嵌入式有了基本,準確的認識。現在應該可以轉到arm平臺上來了吧?
?
首先是開發工具,走了很大的彎路最終才發現只能用RealViewMDK。放棄IAR是因為IAR無法移植TQ2440中對各段地址的引用,類似 |Image$$RW_RAM1$$ZI$$Limit|,這使得我無法安排各段在內存中的位置。即使硬編碼到代碼中,也無法配置成從NAND flash啟動,IAR的鏈接器太簡陋了。
?
我花了很長時間看TQ2440init.s這個啟動文件,最后還是看了TQ論壇上的一篇文章才真正移植成功的(用Keil MDK開發TQ2440裸機程序入門教程2(移植TQ2440測試程序).doc),這才發現自己移植的是鏈接上出了問題,沒有用--sort=CallTree,map文件中可以看到使用前nand.o在4k外,使用后在4k內,這就是代碼燒到板子上后起不來的根本原因。
?
看了一段時間TQ2440的測試代碼,覺得后面用到具體某個驅動的時候再回來看,現在可以開發裸奔游戲了。第一個問題是我想用c++來開發,全局的方法和更接近底層的方法可以用c來實現,自己寫的c++框架后面的開發可能用得著,用c++語言配合面向對象方式的思考要比用C來的簡單,至少對我這個用java工作的人來說是這樣。目前剛把c代碼轉換成c++代碼,主要還是nand.o的鏈接問題,這回不能用Main函數了,c++編譯器不認識,改回main后會把nand.o擠出4K地址范圍,試了所有的sort方法都不行。網上曾經看到有人說為什么不把nand的代碼直接放到TQ2440init.s中,用--asm編譯出nand.s,再把它整個拷貝到啟動代碼末尾,編譯后nand的代碼就在4K內了。
?
哈哈!有意思的事才剛開始 !!
?
2012.08.19
接下來的問題是不能使用STL中的容器類,會報data abort。原因是沒有初始化c++運行時庫,模仿著MDK中的c++例子,把Main替換成__main,這樣在進main()函數之前會初始化c++必要的庫。還用到了__user_initial_stackheap,stack指針可以配置成功,heap指針沒有配置成功,不過已無大礙。
?
昨天剛解決一個困擾我四五天的,內存相關的data abort問題。描述如下:
有個引擎類的成員是STL容器類,LCD屏幕的初始化也是這個引擎類完成,結果在使用容器類成員的時候,打log發現容器類的數據被破壞了。在類初始化的時候數據還是對的,LCD屏幕初始化完畢后數據就出錯了。從log看到stack指針和我配置的不同,修改啟動代碼后解決,但還是有data abort。最終通過不懈的打log調試,發現是視頻緩沖這個全局數據和容器類對象在RW段上數據發生了覆蓋。所以因初始化順序的不同,會造成顯示異常或容器類數據被破壞。
?
原因找到了,解決方案就很容易想到了,之前試過64M內存可以隨意存取,不用管堆或棧的溢出。所以我把視頻緩沖的地址強制設置到遠離RW段的地方,運行,一切OK啦!
附上源碼:http://files.cnblogs.com/PrajnaKit/BoxPorter.zip
?
2012.08.29
顯示模塊初步完成后,我開始聲音模塊的開發和調試。遇到的問題是真機播放聲音時無法觸發DMA中斷,導致聲音剛播放了一點就停止了,直接下載到內存運行時一點問題也沒有。我排查錯誤花了三四天,結果還是沒找到原因。不過我基本明白了DMA和UDA1341的工作原理,可這個bug過不去的話我的“裸奔游戲”遠景就無法實現了。因為剛剛移植好的TQ2440測試程序播放聲音是沒問題的,那我就一步一步的改,直到聲音無法播放。由于改的匆忙,事后回想整理的時候順序可能有錯誤,不過要點應該都講到了。
?
1.?????? 把源碼移植到Keil中。
2.?????? 首先把Main改成main,啟動文件和主文件需要修改,然后把主文件后綴變成cpp。一些c的函數需要包裹在extern “C”中。
3.?????? 變成cpp后拷貝nand flash的函數RdNF2SDRAM被擠出4K地址范圍,通過集成匯編后的nand.asm到啟動文件解決。
4.?????? 使用scatter文件來配置RW段和ZI段,由于STL容器類對象數據地址不太對的原因,需要把ZI段定義在遠離RW段的地方,否則stl容器對象數據會覆蓋ZI段全局數據。因此也需要修改啟動文件中ZI數據初始化的代碼中ZI段的地址。注意linker頁簽中要去掉"Use memory layout from Target dialog"勾選,不然無法指定ZI段地址。
5.?????? Uart_Printf()方法在使用通配符的時候會出問題(%d, %s, %p…),具體原因沒有深究,不過從現象上看可能是由于沒有鏈接相應的庫,也可能是沒有初始化運行時庫。
6.?????? data或者prefetch abort問題需要實現__user_initial_stackheap()方法,不然堆和棧的地址沒有初始化。啟動文件跳轉地址改為__main。
注意:使用__main()的話,無法使用c++的類,不然無法進入到main函數。
更正:更新的源碼現在使用__main()進行跳轉,這樣運行時庫也就能初始化,同時STL庫也能正常工作。
7.?????? arm和thumb混合模式關閉,需要修改配置頁簽和啟動文件中nand.asm數據段的斷言。
?
啟動文件中增加user棧指針設置,最后還是啟動文件寫的有問題啊。。。終于查出來了,我把棧指針初始化開頭的” bic ?????? r0, r0, #CONTROLMASK”注釋掉了,結果就有data abort。?
源碼已更新,屏幕背景所在的內存區域沒有零初始化,所以背景的顏色是不確定的。
?
?
轉載于:https://www.cnblogs.com/PrajnaKit/archive/2012/08/10/2631182.html
總結
以上是生活随笔為你收集整理的arm开发tq2440上的c++裸奔程序的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: wp7 blogs
- 下一篇: 在Cocos2d中实现能够惯性拖动的选择