ZYNQ 7000使用AMR CortexA9 CPU,移植freeRTOS之前首先需要了解它的基本結構和配置,側重於一下幾點
· 寄存器分佈
· 中斷配置
· 配套的彙編指令集
· IRAM和DRAM
PS:關於ARM的學習,個人認爲,最好是以項目爲驅動,爲自己設定一個小項目,諸如這裏討論的移植freeRTOS,或是經典的跑馬燈實驗。基於設定的項目,直接去ARM官網上查找相應資料,其中英語可能會成爲較大的阻礙,這就需要好好自己好好提升英語能力了。有人可能覺得百度或者各種中文論壇也不錯,但我這次移植也去用了用,資料較少,而且大部分都相互抄襲,沒有太多影響,作爲入門的科普還行,想要進一步做項目還是得去官網。
硬件架構
ARM Cortex A9爲雙核結構,如下圖所示,之前說的sector即爲下圖中的APU
其中只需要重點關注,
· ZYNQ 7000擁有兩塊ARMCortex A9 CPU,運行主頻可配(我用的666.66667MHz)。
· 每塊CPU都對應有32KB的ICache和DCache,它們共享512KB的L2 Cache和256KB的SRAM。
· 輸入到sector的中斷由GIC模塊管理。
寄存器
ARM Cortex A9 CPU共計有37個寄存器,如下圖所示,
其中
· ARM Cortex A9 CPU有多種運行模式,不同模式下訪問的寄存器是不同的,RTOS的移植只關注其中幾種
· 用戶模式(user mode),正常運行模式,
· 系統模式(system mode),具有系統特權的運行模式
· 中斷模式(IRQ mode),處理中斷的運行模式
· 監督模式(Supervisor mode),OS保護模式,處理系統復位和軟件中斷的模式
· 寄存器分爲通用寄存器和分組寄存器兩類
· R0~R7爲通用寄存器,所有CPU運行模式下,CPU訪問的R0~R7都是同一樣的寄存器,都是R0_user~R7_user
· R8~12在FIQ mode下,爲R8_fiq~R12_fiq;其他模式下爲R8_ user ~R12_ user,由此可見,FIQ的處理是可不需要壓棧和出棧。
· SP和LR,在user mode和system mode下爲SP_user和LP_user,其他模式都爲自己獨有的寄存器SP_xx和LP_x,SP作爲stack pointer register使用,LR用於存放函數調用時子函數執行完成後的指令返回地址。也被記爲R13和R14
· PC爲通用寄存器,存放當前CPU下一步需要從ICache中取出的指令位置,其爲當前執行的指令地址+x(CPU會提前取出多條指令優化排序執行),x爲8(針對ARM指令)或4(針對Thmbr指令),也被記爲R15
· CPSR爲當前CPU狀態寄存器,其是通用寄存器
· SPSR爲CPU狀態保存寄存器,除usermode和system mode外,每種模式都有自己獨立的狀態保存寄存器
彙編指令
ARM Cortex A9 CPU使用的彙編指令集爲ARMv8,可以在其官網上找到相關文檔,或者搜索相關指令,網址是:https://developer.arm.com/。文檔非常冗長,建議是找個現成的彙編小程序,一邊閱讀一邊查指令含義,如此可以很快地掌握常用指令。
ARM指令集大致分爲如下幾類
彙編其中使用的寄存器名如下圖所示(實際上改爲小寫也行)
除此之外,ARM的彙編指令還可以操作協處理器(NEON)的寄存器,它們的名稱如下,
中斷
ARM Cortex A9 CPU可處理的中斷分爲SGI、PPI和SPI三類
· SGI,中斷ID 1~15,爲軟件觸發中斷
· PPI,中斷ID 16~31,爲私有中斷,
· SPI,中斷ID 31~95,爲共享中斷,
它們都由GIC進行管理,我們可以通過對GIC的配置來管理所有的中斷。
BSP
ZYNQ 7000往往使用XILINK的SDK進行開發,其提供了一個名爲BSP的軟件工程用於封裝硬件,可以簡單地理解爲硬件驅動庫。如下圖所示,它向OS和業務代碼提供功能接口。實際上,BSP和OS我們往往將其通稱爲平臺。
XILINX提供的BSP比較龐大,包含了CPU所有相關硬件的驅動程序。這裏我們只關心FreeRTOS的移植中要使用的中斷向量表和定時器。
對於中斷向量表,可以在BPS中找到如下默認設置的中斷向量表_vectors_table,
其中我們需要重點關注78行的SVCHandler和82行的IRQHandler,它們分別對應任務切換的中斷和OS提供給用戶的中斷(包括用於時間片的中斷)。
但是該中斷向量表定義的ISR並不能夠用於支撐freeRTOS,需要進行改寫。
PS:這裏83行和84行的IRQ和FIQ都可用於OS提供給用戶的中斷,它們分別對應CPU的IRQ和FIQ模式,我們暫時只使用IRQ。
附:
中斷向量表的加載在boot過程中完成,其中vector_base爲取值爲_vectors_table的宏
SVC的ISR函數如下
IRQ的ISR函數如下,可見其是不能支持退出中斷後的任務切換,需要進行改寫。