本文主要是介绍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提供了一些芯片级的模块来实现系统和设备级服务。
Module | Description |
---|---|
CHIP | 包含了通用的设备说明信息,如寄存器ID,字段定义,寄存器读和写功能 |
VERSION | 提供了版本管理,如chip ID和version ID |
INTC | 中断模块提供中断管理服务和调度,该模块是一个单独的模块 |
4 函数层
CSL提供的函数层是CSL 3.x风格和CSL 2.x风格的混合体。为了将来利用硬件抽象层并保持最大的兼容性,CSL建议用户使用函数层API。
CSL 3.x在所有模块中都支持一组核心的函数层API。
API | Description |
---|---|
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基本数据类型
type | Defined as. |
---|---|
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命名约定
Format | Namespace | Type |
---|---|---|
CSL__ | 指定为#define或枚举的符号常量。 整个名称必须使用大写字母,表示外设名称,而表示任何名称,代表指定或定义的项目。 部分可以嵌入一个或多个下划线,以提高可读性。 | CSL_INTC_EVENTID_CNT |
CSL_ | 外设模块类型。 CSL_前缀将大写。 模块名称字符串大写,并遵循标题大小写约定,没有任何下划线。大写字母用于表示新单词或短语的开头。 | CSL_TimerObj CSL_IntcEventId CSL_I2cHwSetup CSL_I2cHandle |
4.2.2 CSL 2.x命名约定
Format | Namespace | Type |
---|---|---|
_ | 指定为#define或枚举的符号常量。 整个名称必须使用大写字母,表示外设名称,而表示任何名称,代表指定或定义的项目。 部分可以嵌入一个或多个下划线,以提高可读性。 | MCBSP_RCV_START |
_ | 外设模块类型。 模块名称前缀字符串大写,名称部分首字母大写后面小写,没有任何下划线。大写字母用于表示新单词或短语的开头。 | **MCBSP_Obj |
HPI_Config ** |
4.3 符号常量
Name | Description |
---|---|
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的正常状态/成功运行,负数为错误状态。
Error Code | Number | Description |
---|---|---|
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 寄存器命名规范
Convention | Description |
---|---|
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,寄存器掩码如下:
typedef struct{/*Timer Control Register*/Uint32 CTL;/*Timer Period Register*/Uint32 PRD;/*Timer Counter Register*/Uint32 CNT;
}CSL_TimerRegs;
typedef volatile CSl_TimerReg *CSL_TimerReg_Ovly;
5.3 寄存器层符号常量
CSL寄存器层文件(cslr_.h)定义每个外设寄存器/位字段的标准符号常量,这些符号常量按照如下约定来定义:
CSL__,(对于SYMBOL定义了可选的符号常量如STOP/START)
其内存映射的外设采用“本地字节序”格式,即可以用于CPU解释。如果CPU和内存映射的外围设备之间的字节序不匹配,则必须在应用此文件中显示的_MASK,_SHIFT等符号之前,在外部进行必要的更正(交换)。
5.4 寄存器宏
Service | Description |
---|---|
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参考的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!