由於Rigel的成本問題,其flash有512K,而SDRam只有2M. 要將code壓縮在這樣的空間包括兩個工作:
- 二進制<512 K
- SDRam必須小於2M,越小越好
採用工具,將SDRam刷爲特殊的值,將當前的bin運行在FPGA之上,運行一段時間後,將SDRam dump出來檢查其佔用的SDRam空間是否足夠小。
佔用的空間如下:
512k bin flash
2M .BSS/.Rodata SDRam
.text SDRam
.data SDRam
stack SDRam
system pool SDRam
hd pool SDRam
在代碼中的嵌套,rodata等進行refactor的同時,主要想利用Flash的空餘空間。做一個搬家的工作。
也就是說想讓部分代碼在flash上運行,這樣就可以減少.text和data段的大小。但是由於flash爲串行接口,難以實現同步,也就是說如果線程調度(從flash讀取指令)和Application向flash寫之間,無法進行同步(向flash寫一些用戶信息,頻道號等用戶數據)。在系統中可以通過互斥鎖的方式實現flash的串行訪問,但是cpu調度指令無法受控。所以要在flash上運行程序必須有嚴格的要求:單線程,無進程調度。所以,可以認爲在OS啓動之前的很多工作,都可以在Flash上工作。
但是這些函數可能有的在OS啓動前被調用,有的在OS後備調用。所以必須將這種情況的函數都放到SDRAM中,而僅在OS啓動前調用的函數放在FLASH中。
所以首要任務,找出這些函數,並將其打上__attribute__((section (".flashtext")))標籤,而在ld腳本中,將.flashext代碼都放在flash中。
同時Flash的函數可以調用SDRam的函數,而SDRam內的函數不能調用Flash的函數(相當於取值操作)。所以只要被SDRam裏的函數調用了的函數,其類型一定是SDRam。而Flash中的函數可以調用Flash函數,也可以調用SDRam函數。
這樣可以認爲可以在dump的ASM中查找被調用SDRam函數調用次數是0的函數,這些函數有可能可以放在Flash中。
檢查這些函數,看看能否放在Flash中。
但是這樣有個問題,由於MIPS指令長度的限制,從FLash跳到ROm中要使用長跳轉方式,也就是說不能直接jlr address了事,所以,代碼中需要確定哪些函數是從Flash跳過來的,並將其函數聲明中,設定__attribute__((longcall))標籤,以此來完成編譯器的長跳轉。