ADS1.2進行ARM嵌入式軟件開發

 
使用ADS開發嵌入式程序,需要考慮如下:
1.與硬件相關的C語言庫函數的使用
2.某些C語言庫函數使用了調試環境的資源,要把這些使用的資源重定向到目標系統中的硬件上來
3.可執行映像文件的存儲器映射必須根據目標硬件的存儲器分佈進行裁減
4.在主程序執行前,嵌入式運用程序必須先完成系統的初始化。一個完整的初始化包括用戶的啓動代碼和ADS中C庫函數的初始化過程。
 
ADS1.2 C語言庫函數->Semihosting

ADSC語言函數庫中,某些ANSIC的功能是由主機的調試環境來提供的,這套機制有一個專門術語叫SemihostingSemihosting通過一組軟件中斷(SWI)指令來實現。當一個Semihosting軟中斷被執行時,調試系統先識別這個SWI請求,然後掛起正在運行的程序,調用Semihosting的服務,完成後再恢復原來的程序執行。因此,主機執行的任務對於程序來說是透明的

  

C語言庫函數結構

從概念上來講,C語言庫函數可以被分成兩部分,一是ANSIC語言規範本身的一部分,一是隻受某一特定ANSIC層次支持的函數,如圖2所示。其中一些ANSIC的功能是由主機調試環境調用驅動程序級的函數完成的。例如,ADS的庫函數printf()把輸出信息輸出到調試器的控制檯窗口,這個功能通過調用__sys_write()實現,__sys_write()執行了一個把字符串輸出到主機控制檯的Semihosting軟中斷服務程序

 

缺省的存儲器映射

         如果用戶在程序編譯時沒有提供指定映象的存儲器分佈,ADS將爲生成的目標代碼和數據分配一個缺省的存儲器映射圖。

目標映象被連接到0x8000處,存儲和執行區域都位於該地址空間。從前至後,依次爲RO(只讀)RW(讀寫)ZI(零初始化)部分。在ZI部分之上爲HEAP,故HEAP的確切地址在連接時才能確定。但是STACK的基地址是在運用程序啓動時由Semihosting操作提供。ARMulator返回配置文件peripherals.ami中的設置值,缺省爲0x08000000Multi-ICE返回的是調試器內部變量top_of_memory的值,缺省爲0x00080000

連接器佈局規則

 

映象按屬性以RO-RW-ZI次序進行排列,同一種屬性裏代碼優於數據。連接器將輸入段根據名字的字母順序進行排列,輸入段的名字與彙編代碼裏塊名字指示一致(彙編程序中使用AREA關鍵字)。在輸入段中,不同對象的代碼和數據放置次序與在連接器命令行中指定對象次序一致。如果需要靈活分配,則需要控制代碼和數據佈局的機制Scatterloading。
啓動運用程序
 
大多數嵌入式系統進入應用程序之前有一個初始化過程,該過程完成系統的初始化和啓動。初始化中__main負責設置運行映象存儲器設置,__rt_entry負責庫函數的初始化。__main完成代碼和數據的複製,並將ZI數據區清零。接着__main進入__rt_entry,進行STACKHEAP初始化,最後__rt_entry跳進應用程序的入口main()。函數main()存在於工程時,連接器會將__main__rt_entry中初始化代碼連接進來。否則就不連接這些初始化代碼。缺省狀態下C庫函數用Semihosting機制來實現設備驅動的功能。但是一個真正的嵌入式系統,要使用具體的外設或硬件獨立於主機環境運行。
C庫函數重定向
 
用戶可定義自己的C語言庫函數,鏈接器在連接時自動使用這些新的功能函數,此過程叫重定向C語言庫函數。舉例來說,用戶有一個I/O設備(如UART)。本來庫函數fputc()是把字符輸出到調試器控制窗口中去的,但用戶把輸出設備改成了UART端口,這樣一來,所有基於fputc()函數的printf()系列函數輸出都被重定向到UART端口上去了。
下面是實現fputc()重定向的一個例子:
extern void sendchar(char*ch);
int fputc(int ch,FILE *f)

     
/*e.g.write a character to an UART*/
   
char tempch=ch;
   sendchar(
&tempch);
   
return ch;

這個例子簡單地將輸入字符重新定向到另一個函數sendchar(),sendchar()假定是一個另外定義的串口輸出函數。在這裏,fputc()就好像目標硬件和標準C庫函數之間的抽象層。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章