DSP TMS320C6455 芯片支持库CSL API参考
本文翻譯自官方庫《C6455_CSL_APIREFERENCE》。
1 CSL介紹
芯片支持庫由一系列定義良好的API構成,這些API提取出了Soc設備的細節以便用戶可以配置、控制和讀寫外設,而不用擔心寄存器字段級的實現細節。
CSL服務以模塊的形式展現。CSL API遵循統一的風格,統一的跨處理器指令集架構,且獨立于操作系統,提高了可移植性。
2 CSL概要
CSL有2層實現,基本寄存器層和更抽象的函數層。寄存器層包括基本的宏和類型定義。函數層由C函數組成,相對寄存器層更抽象,但同樣實現對底層硬件的控制。
CSL不會管理基礎硬件上的數據移動,這些功能是設備驅動驅動程序要干的事(程序員實現),CSL盡量不去模糊設備驅動程序和CSL服務直接的邊界。
CSL以模塊形式提供服務,每個模塊均有2個抽象層(寄存器層、函數層)。模塊的API是正交的(一個模塊的API不會調用另一個模塊的API),并且不會從內部動態分配內存。這樣對于保持CSL的可擴展性很重要。
3 CSL接口
CSL將每個外設構建一個模塊。
寄存器層頭文件命名:CSLR_.h
函數層頭文件命名:CSL_.h
為了外設的模塊化,CSL提供了一些芯片級的模塊來實現系統和設備級服務。
| CHIP | 包含了通用的設備說明信息,如寄存器ID,字段定義,寄存器讀和寫功能 |
| VERSION | 提供了版本管理,如chip ID和version ID |
| INTC | 中斷模塊提供中斷管理服務和調度,該模塊是一個單獨的模塊 |
4 函數層
CSL提供的函數層是CSL 3.x風格和CSL 2.x風格的混合體。為了將來利用硬件抽象層并保持最大的兼容性,CSL建議用戶使用函數層API。
CSL 3.x在所有模塊中都支持一組核心的函數層API。
| CLS_Init() | 外設初始化函數,可選用,對外設不起作用 |
| CLS_Open() | 返回一個外設實例的句柄 |
| CLS_Close() | 釋放外設實例的句柄 |
| CLS_HwSetup() | 使用傳進去的CSL_HwSetup結構體配置外設所有的寄存器 |
| CLS_GetHwStatus() | 使用CSL_GetHwSetup結構體查詢當前的外設配置 |
| CLS_HwControl() | 通過傳遞的命令參數修改一個或多個參數 |
| CLS_HwSetupRaw() | 用傳進去的Config結構體的寄存器值初始化設備寄存器 |
| CLS_Read() | IO外設的讀數據 |
| CLS_Write() | IO設備的寫數據 |
另外,還有一些為外設實現特殊的API來執行特定的操作。 例如,DMAX模塊的“ CSL_dmaxGetNextFreeParamEntry”API在資源表中搜索下一個空閑參數入口。
該層導出的函數是“運行即完成”,意思是它們不應支持異步行為或延遲完成(個人理解:運行完,對外設的操作也就完成了)。
如果外設能啟動事務并通過指定的CPU中斷在以后的某個時間點判斷其完成的能力,則這個過程應由高級軟件(通常是設備驅動程序)完成,不應在函數層實現。 通常,CSLAPI不執行資源管理或內存分配,這應由應用程序代碼或設備驅動程序管理。
4.1 CSL基本數據類型
| Bool | Unsigned short |
| Int | int |
| Char | char |
| String | char * |
| Ptr | void * |
| Uint32 | unsigned int |
| Uint16 | unsigned short |
| Uint8 | unsigned char |
| Int32 | int |
| Int16 | short |
| Int8 | char |
| CSL_BitMask8 | Uint8 |
| CSL_BitMask16 | Uint16 |
| CSL_BitMask32 | Uint32 |
| CSL_Reg8 | volatile Uint8 |
| CSL_Reg16 | volatile Uint16 |
| CSL_Reg32 | volatile Uint32 |
| CSL_Status | Int16 |
4.2 函數層命名約定
CSL命名分為2種,需聲明的名稱(如函數、常量)及符號常量或宏(通過enum或#define定義),需聲明的名稱要避免用戶重定義,盡快可以#define重定義,但不推薦,因為一旦發生沖突,后果不可預測。
4.2.1 CSL 3.x命名約定
| CSL__ | 指定為#define或枚舉的符號常量。 整個名稱必須使用大寫字母,表示外設名稱,而表示任何名稱,代表指定或定義的項目。 部分可以嵌入一個或多個下劃線,以提高可讀性。 | CSL_INTC_EVENTID_CNT |
| CSL_ | 外設模塊類型。 CSL_前綴將大寫。 模塊名稱字符串大寫,并遵循標題大小寫約定,沒有任何下劃線。大寫字母用于表示新單詞或短語的開頭。 | CSL_TimerObj CSL_IntcEventId CSL_I2cHwSetup CSL_I2cHandle |
4.2.2 CSL 2.x命名約定
| _ | 指定為#define或枚舉的符號常量。 整個名稱必須使用大寫字母,表示外設名稱,而表示任何名稱,代表指定或定義的項目。 部分可以嵌入一個或多個下劃線,以提高可讀性。 | MCBSP_RCV_START |
| _ | 外設模塊類型。 模塊名稱前綴字符串大寫,名稱部分首字母大寫后面小寫,沒有任何下劃線。大寫字母用于表示新單詞或短語的開頭。 | **MCBSP_Obj |
| HPI_Config ** |
4.3 符號常量
| CSL___REGS | 外設模塊第n個實例的基地址,如CSL_TIMER_1_REGS |
| CSL__CHA_REGS | 對支持多通道外設的通道n的硬件基地址 |
4.4 錯誤代碼
CSL 3.x擴展了錯誤處理支持,通過API的返回值和/或傳遞給調用本身的狀態參數來報告API的成功或失敗。
錯誤代碼是16位帶符號的二進制數,可以表示32k個唯一的錯誤。錯誤碼分為1024組,每組大小為32,第一組保留用于CSL通用系統錯誤,第二到最后一組分配到各個模塊之間。
正數為CSL API的正常狀態/成功運行,負數為錯誤狀態。
| CSL_SOK | +1 | 成功 |
| CSL_ESYS_FAIL | -1 | 失敗 |
| CSL_ESYS_INUSE | -2 | 外設資源已被使用 |
| CSL_ESYS_XIO | -3 | 共享IO引腳沖突 |
| CSL_ESYS_OVFL | -4 | CSL系統院溢出 |
| CSL_ESYS_BADHANDLE | -5 | 傳遞給CSL的句柄無效 |
| CSL_ESYS_INVPARAMS | -6 | 無效參數 |
| CSL_ESYS_INVCMD | -7 | 傳遞給CSL的命令無效 |
| CSL_ESYS_INVQUERY | -8 | 傳遞給CSL的查詢無效 |
| CSL_ESYS_NOTSUPPORTED | -9 | CSL不支持的行為 |
5 寄存器層
5.1 寄存器命名規范
| CSL Module Identifiers | CSL__ID,如CSL_TIMER_ID,CLS_MCBSP_ID |
| Peripheral Instance Identifiers | 如果CSL模塊有不止一個實例,則遵循CSL_<NUM>,如CSL_TIMER_1,CSL_MCBSP_1;如果CSL模塊只有一個實例,則遵循CSL,如CSL_EDMA3,CSL_GPIO |
| Peripheral Instance Count Identifiers | CSL__CNT,如CSL_EMIFA_CNT |
| Peripheral Register Identifiers | _,名字使用指定外設實例掩碼 |
| Peripheral Register Continuous Bit-field Identifiers | ,名字為實例相關的。如TIMER_CNTL_CLKEN |
| Peripheral Register Bit_field Sysbols | _,名字是實例相關的,如CMPAC_TX_CONTROL_EN_RESETVAL |
5.2 外設掩碼結構
Soc 外設通常是通過對外設IO地址空間中的一個或多個寄存器進行讀/寫來編程的。 為了干凈直觀地訪問給定外設實例的所有寄存器,CSL實現了一種稱為**寄存器覆蓋結構(我個人理解:翻譯為掩碼比較合適,故都用掩碼來表示)**的技術。 按出現順序用每個寄存器對應的結構成員來定義C數據結構模板,成員類型根據寄存器的寬度確定,并且 引入適當填充來對齊數據結構,以便“ C”對這些寄存器進行正確的尋址。 結構成員與datasheet中的規定得名稱一樣,以簡化編程。 由于C結構格式定義良好,因此可以在IDE監視窗口中查看寄存器,并可以在鍵入時這些寄存器可以智能推測補充完成。
應當注意的是,寄存器掩碼不會實例化,因此也不會占用內存。 這些結構的目的主要是便于使用“ C”指針。
例子:
下表展示了TIMER外設的布局,假設有2個實例,一個地址為0x02940000,并且另一個在地址0x02980000,寄存器掩碼如下:
5.3 寄存器層符號常量
CSL寄存器層文件(cslr_.h)定義每個外設寄存器/位字段的標準符號常量,這些符號常量按照如下約定來定義:
CSL__,(對于SYMBOL定義了可選的符號常量如STOP/START)
其內存映射的外設采用“本地字節序”格式,即可以用于CPU解釋。如果CPU和內存映射的外圍設備之間的字節序不匹配,則必須在應用此文件中顯示的_MASK,_SHIFT等符號之前,在外部進行必要的更正(交換)。
5.4 寄存器宏
| CSL_FMK(field, val) | 創建一個將值(val)移動到指定字段位置的AND掩碼。 |
| CSL_FMKT(field, token) | 與CSL_FMK相同,但允許將預定義的符號標記當值使用。 |
| CSL_FMKR(msb, lsb, val) | 與CSL_FMK相同,但允許原始位位置(msb:lsb)指定位字段。 |
| CSL_FEXT(reg, field) | 評估從指定字段收集的位的算術值。 |
| CSL_FEXTR(reg, msb, lsb) | 與CSL_FEXT相同,但允許原始位位置(msb:lsb)指定位字段。 |
| CSL_FINS(reg, field, val) | 將指定值(val)插入寄存器的指定字段中。 |
| CSL_FINST(reg, field, token) | 與CSL_FINS相同,但允許將預定義的符號標記用作值。 |
| CSL_FINSR(reg, msb, lsb, val) | 與CSL_FINS相同,但允許原始位位置(msb:lsb)指定位字段。 |
6 C++兼容性
CSL函數層大部分是用C實現的,小部分用的匯編(C比較難實現)。此外,API也適當的聲明為可以用C++實現,但不像C++函數,CSL API不支持傳遞默認值。
同樣,在CSL API語義要求用戶指定函數指針的地方,CSL3.x設計不允許用戶輸入C ++函數指針。 要解決以上限制,用戶需要編寫C語言中的封裝函數,以封裝C ++成員函數。該函數可以設計為將類實例作為參數輸入(連同其所需的任何其他參數),并在內部調用適當的類成員函數以實現所需的目標。
7 中斷軟件架構
CSL3.x中的INTC模塊旨在為所有基本的中斷控制器功能提供抽象,例如啟用和禁用中斷,指定響應中斷而調用的用戶功能以及設置所需的硬件屬性。 這些功能并非特定于任何給定的外圍設備。 換句話說,INTC模塊提取處理器提供的通用中斷能力。
注意:CSL 3.0 INTC模塊為一個單獨的塊,作為其余CSL模塊的單獨庫提供。 當使用包含中斷控制器/調度程序支持的嵌入式操作系統時,不要連接INTC庫。 DSP / BIOS用戶應使用DSP / BIOS v5.21或更高版本支持的HWI(硬件中斷)和ECM(事件組合管理器)模塊。
下面以C6482為例介紹CSL INTC功能。
7.1 中斷控制器
下圖顯示了在虛線邊界內的多級中斷控制器。 Level-0控制器是CPU本身的一部分。 此級別為處理器實現主要的中斷向量表。 其余的控制器有助于擴展這些向量,以處理更多的硬件事件。 這些事件,如箭頭所示,可能是通過設備輸入引腳的外部觸發和/或由片上外設的內部斷言。 用cross-hatched boxes表示的外設本身可能是事件控制器(方格),該事件控制器有助于將硬件事件映射到的輸出線來判斷CPU中斷。 每個中斷控制器都將具有可編程控制寄存器,以使能或失能中斷。 控制器還允許用戶將中斷捕獲電路配置為指定的極性,邊沿靈敏度,優先級等。級別0中斷控制器具有選擇器功能,可將給定的CPU中斷向量映射為1 -N輸入硬件事件。 盡管該方案在當今的TI處理器中可用于Level-0,但在技術上也可以在其他級別使用。中斷控制器也可能包含多個邏輯塊。 (請參見圖中的2.0、2.1塊。)中斷控制器Level-0到Level-N的所有塊都是CSL3.x中INTC模塊的一部分(由虛線限制)。 用戶只會看到頂級的INTC抽象。 內部INTC0至INTCn對用戶隱藏。 各個INTC子塊之間的連接應在INTC模塊初始化和調度程序設置期間完成,如本文檔隨后的小節中所述。 重要的是要注意,任何嵌入特定外設(例如C64x EDMA控制器)中的“custom controllers”(請參見圖中的方格框)均不視為INTC功能的一部分。
7.3 INTC模塊初始化
INTC模塊維護一個位掩碼數組,這些掩碼使INTC能夠跟蹤應用程序正在激活或正在使用的中斷。 每個位的位置對應于一個可以由INTC處理的硬件事件。 總數位的位置對應于INTC在任何給定時間可以識別和處理的硬件事件的最大數量。
在level-0處,這對應于CPU主中斷向量。 在其他級別,它對應于控制器中實現的扇入功能和優先級解析。 INTC模塊將為每個硬件事件分配唯一的ID,并了解適用于每個級別的此類ID的范圍(即INTC0至INTCn)。
在CSL初始化階段,將調用INTC模塊初始化函數CSL_intcInit()。這會將全局變量CSL_IntcContext.eventAllocMask []重置為零。 這意味著所有中斷都可使用。 該數組負責解決同一中斷資源上的所有沖突。 每個中斷只能插入一個中斷服務程序。 因此,當在不同事件之間共享同一中斷線時,必須在應用程序中注意事件的同步,并且必須在ISR中識別導致中斷的事件以執行適當的功能。
7.4 中斷調用說明
成功初始化INTC模塊之后(通過CSL_intcInit()),用戶可以選擇通過調用CSL_intcDispatcherInit()來初始化INTC內置調度程序。 為CSL_intcDispatcherInit())傳遞的調度程序記錄參數用作ISR在特定時間點掛接到特定CPU中斷的記錄。 一旦創建了調度程序記錄并對其進行了初始化,CSL_plugEventHandler()將在內部執行將ISR記錄在調度程序記錄中,并在中斷向量表中連接相應的主ISR。
通常,當操作系統(OS)運行時,主中斷向量表在OS Scheduler的控制下。 OS Scheduler將在level-0上鉤上其自己的調度函數。OS端口可以選擇完全取消CSL調度程序,也可以選擇自己所需的級別。 他們可以選擇首先初始化CSL中斷調用器,然后以所需的級別和/或向量槽交換自己的中斷處理程序。 當與CSL一起使用的OS端口使用其自己的調度程序時,CSL_IntcContext.flags必須等于CSL_INTC_CONTEXT_DISABLECOREVECTORWRITES。 CSL調度代碼/數據可能根本不加載,或者為了優化內存占用而被覆蓋。 通常,事件分發記錄構成上下文信息。 該表將保存事件處理程序函數的地址以及指向要作為單獨參數傳遞給事件處理程序的任意數據對象(void *)的指針。
當不使用INTC分派器時,可以使用CSL_intcHookIsr()在中斷向量表中掛鉤正確的提取數據包,從而在發生中斷時將CPU控制引向正確的ISR。
7.4 INTC API調用順序
INTC用戶調用順序如下:
// Initialize other required CSL3.x Peripherals CSL_intcSetVectorPtr(DEST_ADDR); //If relocation of interrupt vector //required. DEST_ADDR is new location CSL_intcInit(); // INTC Module Initialize CSL_intcDispatcherInit(); // Dispatcher Initialize (if reqd.) CSL_intcGlobalDisable(..); // Disable global interrupts. handle = CSL_intcOpen(..); // Ready an interrupt for use CSL_intcHwSetup(handle..); // Setup interrupt attributes CSL_intcPlugEventHandler(..); // Bind the interrupt with the // corresponding ISR. CSL_intcHwControl(handle..); // assorted control, ex: ISR hookup CSL_intcEventEnable(..); // Enables the event of interest. CSL_intcGlobalEnable(..); // Enable global interrupts. : CSL_intcClose(handle); // End of interrupt use // Terminate Program歡迎關注我的公眾號:槑槑的技術棧。前面兩個字念meimei,二聲,哈哈。
總結
以上是生活随笔為你收集整理的DSP TMS320C6455 芯片支持库CSL API参考的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 属性管理器没有Microsoft.Cpp
- 下一篇: 架构 理论 定律 总结