在上一篇文章中,Valter Minute 討論了總體架構以及非對稱(也稱為異構)多核 SoC 的優勢。對于次要 Cortex-M4 內核的操作平臺有多種選擇:Valter 文章中討論的示例使用 eCos RTOS,飛思卡爾推廣自己的 RTOS MQX。
然而,根據應用程序的不同,人們甚至可能更喜歡裸機解決方案,例如移植舊版固件或為了其簡單性。但是,也有缺點,最突出的是缺少外圍設備的驅動程序。本文展示了為 Vybrid 的 Cortex-M4 內核創建定制的裸機固件時的一些技術缺陷。
作為一個示例環境,我決定為開源固件庫 libopencm3 貢獻 Vybrid 支持。該庫在 LGPL 版本 3 下獲得許可,因此明確允許將封閉源應用程序與該庫鏈接。盡管它的名字,這個庫也支持各種 Cortex-M4 微控制器,因此它非常適合 Vybrid 的 Cortex-M4 內核。使用該庫,我們可以利用對 Cortex-M4 內核外設的支持,例如系統滴答定時器或嵌套中斷控制器。有人可能會爭辯說,使用庫并不是真正的裸機,但是由于庫的幾乎所有組件都是完全可選的,因此與使用完整的 RTOS 相比,它更接近于裸機。
該代碼尚未合并到上游項目中,但已經可以從 Github 獲得(切換到 fsl-vf6xx 分支):https ://github.com/falstaff84/libopencm3和https://github.com/falstaff84/libopencm3-examples 。 此處的詳細構建說明:http: //falstaff.agner.ch/2014/07/10/libopencm3-bare-metal-vybrid-examples/
內存和閃存
標準微控制器和 Vybrid 的 Cortex-M4 之間的第一個也是最顯著的區別是不同的內存和閃存架構。在微控制器上,非易失性存儲器通??稍诳刂破鞯木€性地址空間中訪問,從而允許它執行就地固件 (XIP)。在 Vybrid 上,非易失性內存通常不會以允許其就地執行的方式實現。相反,固件由主操作系統(例如 Linux)從存儲介質(例如 NAND 閃存)加載到 RAM 中,隨后由 Cortex-M4 內核執行。
有不少于三種內存類型可供運行:緊密耦合內存、片上內存 (OC-RAM/SRAM) 和外部 (DDR) 內存。緊密耦合內存 (TCM) 是可用的最快內存,因為它直接連接到 Cortex-M4 內核。但是,可用的內存量也非常有限。片上存儲器 SRAM 是一種流行的選擇,因為它在尺寸和速度方面提供了良好的折衷。飛思卡爾提供了一份詳盡的文檔,討論了可用內存類型的速度和建議(請參閱 AN4947,了解 Vybrid 架構)。
另一方面是 Cortex-M4 的哈佛式架構,它由兩條總線組成,一條用于數據,一條用于指令。為了確保硬件相應地使用這兩條總線,內存映射提供別名以使用兩條總線訪問相同的內存位置:
OC-RAM Code-Bus: 0x1f000000-0x1f03ffff
OC-RAM System-Bus: 0x3f000000-0x3f03ffff
為獲得最佳性能,應在鏈接器文件的內存描述中考慮到這一點;libopencm3 庫定義了兩個內存區域,代碼總線 (pc_ram) 和系統總線 (ps_ram)。在以下示例中,可用內存被分成兩半,每個部分有 256K 的 RAM。由于地址是整個內存范圍的別名,因此可以根據項目需要自由調整這兩個部分的大小。
鏈接器控制文件片段:examples/vf6xx/colibri-vf61/colibri-vf61.ld
MEMORY
{
pc_ram (rwx) : ORIGIN = 0x1f000000, LENGTH = 256K
ps_ram (rwx) : ORIGIN = 0x3f040000, LENGTH = 256K
}
在節部分,我們需要將代碼節(文本)和數據節(例如 bss)的位置分配給這兩個內存區域。
鏈接器控制文件片段:lib/vf6xx/libopencm3_vf6xx.ld
SECTIONS
{
.text : {
*(.vectors) /* Vector table */
。 = ALIGN(0x400);
*(.text.reset_handler) /* Force reset handler at start */
*(.text*) /* Program code */
。 = ALIGN(4);
} 》pc_ram
。..
.bss : {
*(.bss*) /* Read-write zero initialized data */
*(COMMON)
。 = ALIGN(4);
_ebss = 。;
} 》ps_ram
。..
}
向量表和入口地址
另一個重要方面是向量(中斷)表。在 Cortex-M4 上,向量表0x00000000在復位時讀取。在微控制器上,這通常位于非易失性存儲器中。在 Vybrid 上,Cortex-M4 內核最初是關閉的。在固件的初始化代碼中,我們可以使用向量表偏移寄存器 (VTOR) 來定義向量表的自定義位置。在上面的鏈接器文件中,向量表明確放置在固件的開頭。lib/vf6xx/vector_chipset.c 中的初始化代碼確保在啟動時設置 VTOR 寄存器。
對于 Cortex-M4 微控制器,入口點(也稱為復位向量)是向量表的一部分。這引入了對 Vybrid 的循環依賴,因為我們從固件代碼中初始化向量表(無法從 Cortex-A5 內核訪問 VTOR 寄存器)。為了解決這個難題,輔助內核的入口點(“復位向量”)由系統復位控制器 (SRC) 模塊的寄存器在外部定義。對于飛思卡爾的啟動實用程序“mqxboot”,在 Cortex-A5 內核上運行的 mcc 內核模塊中的啟動實現可確保相應地設置此寄存器。用戶需要將入口點作為參數傳遞給“mqxboot”。注意:地址需要將位 0 設置為 1,以告訴 CPU 目標是 Thumb 代碼(另請參閱參考手冊的“運行輔助內核”一章)。
例如,要將固件 demo.bin 加載到 SRAM 并在輔助內核上啟動它,可以在主內核上運行的 Linux 上使用 mqxboot:
mqxboot
mqxboot demo.bin 0x3f000000 0x1f000401
加載地址需要可從 Cortex-A5 訪問。在本例中,這是 SRAM 的開始。但是,入口點地址是僅適用于 Cortex-M4 內核的代碼總線別名。
由于 Cortex-M4 在源自 Cortex-A5 內核時鐘的系統時鐘上運行,因此從 Cortex-M4 側更改時鐘并不是一個好主意。然而,為了計算時序,讀取時鐘寄存器以獲得當前速度是必要的。在libopencm3中,計算邏輯在lib/vf6xx/ccm.c下實現。主要時鐘是 ARM 內核時鐘 (ccm_core_clk)、平臺總線時鐘(也是 Cortex-M4 內核時鐘 (ccm_platform_bus_clk) 以及 IPS(外設)時鐘 (ccm_ipg_bus_clk))。
溝通
另一方面是與運行在 Cortex-A5 上的主操作系統進行通信的通信基礎設施。libopencm3 實現目前不支持通信??赡茏詈唵蔚耐ㄐ艑崿F是定義一個可以從雙方訪問的共享內存區域(考慮使用使用獨占加載/存儲指令 LDREX/STREX 的同步機制)。更復雜一點的是 MQX RTOS 的多核通信 (MCC) 組件的實現。該組件利用硬件信號量模塊 (SEMA4) 以及四個 CPU 到 CPU 中斷之一在有新消息可用時通知另一個 CPU。可以下載最近的 MQX 版本(4.0.2 及更高版本)以獲取 MCC 的源代碼(驗證許可證是否涵蓋您的用例)。
結論
在 Vybrid 上移植或實現裸機固件是可能的,而且不是很復雜。畢竟,Vybrid 內部的 Cortex-M4 仍然是執行 ARMv7-M 架構的 Cortex-M4 內核。除了外圍驅動程序,鏈接器文件以及初始設置代碼需要一些特殊考慮。
作者:Stefan Agner, Toradex
審核編輯:郭婷
-
微控制器
+關注
關注
48文章
7566瀏覽量
151614 -
控制器
+關注
關注
112文章
16396瀏覽量
178512 -
寄存器
+關注
關注
31文章
5357瀏覽量
120632
發布評論請先 登錄
相關推薦
評論