第8章 硬件抽象层
8.1 硬件抽象层APIs
SYS/BIOS为中断、缓存和定时器提供配置和管理服务。不同于诸如线程等
其它SYS/BIOS服务,此模块直接面向设备硬件方面编程,并组成
Hardware Abstraction Layer (HAL硬件抽象层)包。服务包括使用和禁用中断、中断向量插入、将多个中断复用到单个向量和缓存失效和回写,这些将在本章描述。
注意:在SYS/BIOS应用程序中对中断、缓存、计时器和它们所关联向量的任何配置和操作必须经过SYS/BIOS HAL APIs。在早期的DSP/BIOS版本中,一些HAL服务无法使用,开发者只能使用设备的Chip Support Library (CSL芯片支持库)中的函数。最新的CSL3.0版本被设计为无需在应用程序中使用SYS/BIOS。它们的一些服务并不兼容SYS/BIOS。应避免在同一应用程序中同时使用SYS/BIOS和CSL中断、缓存、定时器函数,因为这种组合会导致复杂的中断相关的调试问题。
HAL APIs分成两个种类:
- 可在所有目标和设备上使用的通用API
- 仅针对特定设备或ISA系列的特定目标/设备APIs
通用API被设计成覆盖绝大多数用例。开发人员关心的是确保不同的TI设备之间的易移植性,最好尽可能多地使用通用API服务。对于通用APIs无法用于指定设备硬件特征的情况,你可以选择使用指定目标/设备APIs,它提供了完整的硬件授权。
本章,对于每个HAL包的功能概述都同时提供对于包的通用API函数的用例。在描述完通用函数、特定目标/设备APIs用例后,还会提供基于'C64x设备的相关内容。对于特定系列或设备的特定目标/设备APIs的完整描述,请查阅API参考文档。8.5节
HAL Package Organization提供通用HAL包概述以及相关的特定目标/设备包,这此可帮助查找恰当的包。
注意:关于使用SYS/BIOS具体硬件的信息,请参考链接:http://processors.wiki.ti.com/index.php/Category:SYSBIOS
8.2 HWI模块
ti.sysbios.hal.Hwi模块提供了一个APIs集合用于管理硬件中断。这些APIs在所有支持的目标和设备上是通用的,为大多数应用程序提供足够的功能。参考
document introducing Hwis进行概览。
8.2.1 为系统中断源关联C函数
为指定系统中断关联用户提供C函数,可以创建一个封闭了相关Hwi模块中断需求信息的Hwi对象。ti.sysbios.hal.Hwi模块支持标准的静态和动态形式的“create”函数。
配置实例:下例使用了默认实例配置参数静态创建了一个将“myIsr” C函数和中断5关联的Hwi对象:
var Hwi = xdc.useModule(
'ti.sysbios.hal.Hwi');
Hwi.create( 5, '&myIsr'); |
#include <ti/sysbios/hal/Hwi.h>
#include <xdc/runtime/Error.h> #include <xdc/runtime/System.h> Hwi_Handle myHwi; Error_Block eb; Error_init(&eb); myHwi = Hwi_create( 5, myIsr, NULL, &eb); if (myHwi == NULL) { System_abort( "Hwi create failed"); } |
当默认实例参数已经满足创建Hwi对象时,使用NULL参数。
8.2.2 Hwi实例配置参数
以下配置参数和它们的默认值由每个Hwi对象定义。有关这些参数和它们的值的详细信息请参考在线文档的ti.sysbios.hal.Hwi module模块。
- “maskSetting”定义了中断调度器是如何管理中断嵌套的
MaskingOption maskSetting = MaskingOption_SELF;
- “arg”参数将在分发器调用时传递给Hwi函数
UArg arg = 0;
- “enabledInt”参数用于在Hwi对象创建时自动使用或禁用中断
Bool enableInt = true;
- “eventId”帮助'C6000设备将中断数与一个外部事件动态关联。默认值-1在它的正常(reset)状态下将eventId与中断数的关联断开(也就是需要非关联状态)。
Int eventId = - 1;
- “priority”参数用于那些支持中断优先设置的体系。默认值-1告诉Hwi模块将中断优先级设置为与设备相应的默认值。
Int priority = - 1;
8.2.3 使用非默认实例配置参数创建一个Hwi对象
基于8.2.1所给定的例子,下例显示如何将中断5和“myIsr” C函数关联,向“myIsr”传递参数“10”,并在创建完毕后禁用中断。
配置实例:
var Hwi = xdc.useModule(
'ti.sysbios.hal.Hwi');
/* initialize hwiParams to default values */ var hwiParams = new Hwi.Params; hwiParams.arg = 10; /* Set myIsr5 argument to 10 */ hwiParams.enableInt = false; /* override default setting */ /* Create a Hwi object for interrupt number 5 * that invokes myIsr5() with argument 10 */ Hwi.create( 5, '&myIsr', hwiParams); |
运行时实例:
#include <ti/sysbios/hal/Hwi.h>
#include <xdc/runtime/Error.h> Hwi_Params hwiParams; Hwi_Handle myHwi; Error_Block eb; /* initialize error block and hwiParams to default values */ Error_init(&eb); Hwi_Params_init(&hwiParams); hwiParams.arg = 10; hwiParams.enableInt = FALSE; myHwi = Hwi_create( 5, myIsr, &hwiParms, &eb); if (myHwi == NULL) { System_abort( "Hwi create failed"); } |
8.2.4 使用和禁用中断
你可用以下Hwi模块APIs来使用及禁用全部或单独的中断:
- UInt Hwi_enable():全局地使用所有中断。返回之前的(使用/禁用)状态。
- UInt Hwi_disable():全局地禁用所有中断。返回之前的(使用/禁用)状态。
- Hwi_restore(UInt key):全局地将中断恢复为之前的(使用/禁用)状态。
- 以下APIs用于使用、禁用及恢复给定“intNum”的特定中断。它们和全局Hwi_enable/disable/restore APIs有相同语义:
— UInt Hwi_enableInterrupt(UInt intNum);— UInt Hwi_disableInterrupt(UInt intNum);— Hwi_restoreInterrupt(UInt key);
- Hwi_clearInterrupt(UInt intNum):从当前等待中断集中清除“intNum”。
在处理关键部分时禁用中段非常有用。
在C6000平台,Hwi_disable()用于在控制状态寄存器(CSR)中清除GIE位。在C2000平台,Hwi_disable()用于在ST1寄存器中设置INTM位。
8.2.5 一个简单的Hwi应用实例
下例创建了两个Hwi对象。一个中断号是5,另一个中断号是6。为了说明目的,一个中断静态创建,另一个动态创建。一个等待中断完成的Idle函数也添加进Idle函数列表。
配置实例:
/* Pull in BIOS module required by ALL BIOS applications */
xdc.useModule( 'ti.sysbios.BIOS'); /* Pull in XDC runtime System module for various APIs used */ xdc.useModule( 'xdc.runtime.System'); /* Get handle to Hwi module for static configuration */ var Hwi = xdc.useModule( 'ti.sysbios.hal.Hwi'); var hwiParams = new Hwi.Params; /* Initialize hwiParams to default values */ hwiParams.arg = 10; /* Set myIsr5 argument */ hwiParams.enableInt = false; /* Keep interrupt 5 disabled until later */ /* Create a Hwi object for interrupt number 5 * that invokes myIsr5() with argument 10 */ Hwi.create( 5, '&myIsr5', hwiParams); /* Add an idle thread 'myIdleFunc' that monitors interrupts. */ var Idle = xdc.useModule(ti.sysbios.knl.Idle); Idle.addFunc( '&myIdleFunc'); |
运行时实例:
#include <xdc/std.h>
#include <xdc/runtime/System.h> #include <xdc/runtime/Error.h> #include <ti/sysbios/hal/Hwi.h> #include <ti/sysbios/BIOS.h> Bool Hwi5 = FALSE; Bool Hwi6 = FALSE; /* Runs when interrupt 5 occurs */ Void myIsr5(UArg arg) { if (arg == 10) { Hwi5 = TRUE; } } /* Runs when interrupt 6 occurs */ Void myIsr6(UArg arg) { if (arg == 12) { Hwi6 = TRUE; } } main( void) { Hwi_Params hwiParams; Hwi_Handle myHwi; Error_Block eb; /* Initialize error block and hwiParams to default values */ Error_init(&eb); Hwi_Params_init(&hwiParams); /* Set myIsr6 parameters */ hwiParams.arg = 12; hwiParams.enableInt = FALSE; /* Create a Hwi object for interrupt number 6 * that invokes myIsr6() with argument 12 */ myHwi = Hwi_create( 6, myIsr6, &hwiParams, &eb); if (myHwi == NULL) { System_abort( "Hwi create failed"); } /* enable both interrupts */ Hwi_enableInterrupt( 5); Hwi_enableInterrupt( 6); BIOS_start(); } /* The Idle thread checks for completion of interrupts 5 & 6 * and exits when they have both completed. */ Void myIdleFunc() { if (Hwi5 && Hwi6) { System_printf( "Both interrupts have occurred!"); System_exit( 0); } } |
这代码太坑爹了,又错了几个地方,我改过来了。这编译器也不靠谱,错误指示天马行空啊!害我又浪费了几个钟。
中断号5、6已被占用。我这块板大于15才能用,改中断号后运行了也没效果,中断没触发,看不到效果。
8.2.6 中断调度器
合并为每个中断执行寄存器保存和恢复的代码,SYS/BIOS提供为中断服务提供了一个中断调度器来自动执行这样的动作。使用Hwi调度器使得ISR函数可用C来编写。
队了保护中断线程上下文之外,SYS/BIOS Hwi调度器还安排以下动作:
在某些平台,如MSP430,不提供Hwi调度器。但所生成的中断存根本质上提供了相同的默认功能。然而生成的中断存根不会自动管理嵌套中断,因为MSP430不支持。
- 在中断处理期间禁用SYS/BIOS Swi和Task调度。
- 在每次中断基础上自动管理嵌套中断。
- 调用任何配置了“begin”的Hwi Hook函数。
- 运行Hwi函数。
- 调用任何配置了“end”的Hwi Hook函数。
- 在处理完中断后,调用Swi和Task调度器以执行Hwi函数内产生的所有Swi和Task操作。
注意:有关使用SYS/BIOS具体硬件的信息,请参考链接http://processors.wiki.ti.com/index.php/Category:SYSBIOS
注意: interrupt 关键字或 INTERRUPT 预编译指令不可用于被Hwi调度器调用的C函数(或中断存根,不提供Hwi调度器的平台,如MSP430)。Hwi调度器和中断存根包含此项功能,使用C修饰符会导致灾难性后果。
使用 interrupt 关键字或 INTERRUPT 预编译指令的函数不能使用Hwi调度器或中断存根,并且不能调用SYS/BIOS APIs。
8.2.7 使用中断调度器保存和恢复寄存器
在准备调用用户Hwi函数时通过调度器保存和恢复寄存器需遵守C编译器文档的寄存器使用约定部分所定义的"saved by caller"或"scratch"寄存器。获取有关寄存器保存和恢复或TMS320函数遵守TI的C运行时模型的更多信息,请参考你的平台的
Optimizing Compiler User's Guide。
8.2.8 特定目标/设备Hwi模块的附加功能
如8.5节所述,ti.sysbios.hal.Hwi模块使用代理委托机制实现。所有 ti.sysbios.hal.Hwi的APIs都会转发给特定目标/设备Hwi模块,从而实现所有ti.sysbios.hal.Hwi所需的APIs。每个这些Hwi模块的实现提供了额外对于系列/设备唯一的APIs和功能性,如果需要可以代替ti.sysbios.hal.Hwi模块。
例如,'C64x特定目标Hwi模块,ti.sysbios.family.c64p.Hwi中,除了ti.sysbios.hal.Hwi模块中定义的,还额外提供了以下APIs:
- Hwi_eventMap(UInt intNum, UInt eventId);
重新将一个外部事件号映射至中断号。
- Bits16 Hwi_enableIER(Bits16 mask);
Bits16 Hwi_disableIER(Bits16 mask);Bits16 Hwi_restoreIER(Bits16 mask);
这三个APIs可以使能、禁用、恢复由“mask”参数所定义的一组中断。这些APIs提供了直接操作'C64x+'s内部IER寄存器的能力。
要能够访问这些额外的APIs,你需要使用'C64x+目标关联的特定目标/设备Hwi模块,而不是sysbios.hal.Hwi模块。
要获取特定目标/设备Hwi模块的参考资料,请阅读ti.sysbios.family.*.Hwi的CDOC文档,如ti.sysbios.family.c28.Hwi。
下例修改自8.2.5节例子的一部分。修改部分用粗体显示。
配置实例:
var Hwi = xdc.useModule(
'ti.sysbios.family.c64p.Hwi');
/* Initialize hwiParams to default values */ var hwiParams = new Hwi.Params; /* Set myIsr5 parameters */ hwiParams.arg = 10; hwiParams.enableInt = false; /* Create a Hwi object for interrupt number 5 * that invokes myIsr5() with argument 10 */ Hwi.create( 5, '&myIsr5', hwiParams); |
运行时实例:
#include <
ti/sysbios/family/c64p/Hwi.h>
#include <xdc/runtime/Error.h> main(Void) { Hwi_Params hwiParams; Hwi_Handle myHwi; Error_Block eb; /* Initialize error block and hwiParams to default values */ Error_init(&eb); Hwi_Params_init(&hwiParams); /* Set myIsr6 parameters */ hwiParams.arg = 12; hwiParams.enableInt = FALSE; /* Create a Hwi object for interrupt number 6 * that invokes myIsr6() with argument 12 */ myHwi = Hwi_create( 6, myIsr6, &hwiParms, &eb); if (myHwi == NULL) { System_abort( "Hwi create failed"); } /* Enable interrupts 5 & 6 simultaneously using the C64x+ * Hwi module Hwi_enableIER() API. */ Hwi_enableIER(0x0060); . . . |
8.3 定时器模块
ti.sysbios.hal.Timer模块提供了使用定时器外设的标准接口。它隐藏了任何定时器外设的特定目标/设备特性。它继承自ti.sysbios.interfaces.ITimer接口。
你可以使用此模块创建一个定时器(也就是标记使用的定时器),并将它配置为当定时器到期时调用tickFxn。仅在定时器外设无需任何自定义配置时使用此模块。
此模块有一个配置参数TimerProxy,由一个特定目标/设备实现默认插入。例如,C64x目标的实现是ti.sysbios.family.c64.Timer。
定时器可被配置为单周期或多周期模式。period可使用数量或微秒指定。定时器中断总是使用Hwi调度器。定时器的tickFxn运行于Hwi线程上下文。定时器模块自动为定时器中断创建一个Hwi实例。
Timer_create() API携带一个timerId参数。timerId由TimerProxy决定,范围从0到特定目标/设备值。timerId仅仅是一个逻辑ID;它与实际定时器外设的关系由TimerProxy控制。
如果你的程序中使用哪个定时器无关紧要,将timerId指定为Timer.ANY(配置文件)或者Timer_ANY(C代码),这意味着使用任何可能的定时器。例如,在配置文件中使用:
Timer.create(
Timer.ANY,
"&myIsr", timerParams);
|
在C代码中使用:
myTimer = Timer_create(
Timer_ANY, myIsr, &timerParams, &eb);
if (myTimer == NULL) { System_abort( "Timer create failed"); } |
timerParams包含几个参数用于配置定时器,例如,timerParams.startMode可被设置为StartMode_AUTO或StartMode_USER。StartMode_AUTO指示静态创建的定时器应在BIOS_start()内开始计时,动态创建的定时器应该在create()时开始计时。StartMode_USER指示在程序使用Timer_start()开始计时。见8.3.1节的例子。
你可以调用Timer_getNumTimers()获取定时器外设的数量。它包含了在用及可用的定时器外设。还可以通过调用Timer_getStatus()来查询定时器状态。
如果你希望使用特定的定时器外设或希望使用自定义定时器配置(设置定时器输出引脚、仿真行为等等),可以使用特定目标/设备定时器模块。例如,ti.sysbios.family.c64.Timer。
定时器模块还允许你为定时器外设指定extFreq(外部频率)属性并为在运行时获取定时器频率提供API。此外部频率仅支持那些定时器频率可与CPU频率分开设置的目标。你可以使用Timer_getFreq()来将定时器中断转换为实时时间。
定时器提供APIs在运行时开始、停止、修改定时器周期。这些APIs有以下副作用:
- Timer_setPeriod()在设置period寄存器时停止定时器。它会重启定时器。
- Timer_stop()停止定时器并禁用定时器中断。
- Timer_start()清除计数器,清除任何等待中断,并在启动定时器之前使能定时器中断。
运行时实例:此C例程创建了一个period为10微秒的定时器。它传递参数1到myIsr函数。它通知定时器模块使用任意可用的定时器外设:
Timer_Params timerParams;
Timer_Handle myTimer; Error_Block eb; Error_init(&eb); Timer_Params_init(&timerParams); timerParams.period = 10; timerParams.periodType = Timer_PeriodType_MICROSECS; timerParams.arg = 1; myTimer = Timer_create(Timer_ANY, myIsr, &timerParams, &eb); if (myTimer == NULL) { System_abort( "Timer create failed"); } |
配置实例:此例静态创建了一个定时器,它和之前的C例程一样。它指定timerId为1:
var timer = xdc.useModule(
'ti.sysbios.hal.Timer');
var timerParams = new Timer.Params(); timerParams.period = 10; timerParams.periodType = Timer.PeriodType_MICROSECS; timerParams.arg = 1; timer.create( 1, '&myIsr', timerParams); |
运行时实例:此C例程在定时器创建时设置了频率。extFreq.hi和extFreq.lo属性设置结构体的高低32bit部分,用于表示以Hz为单位的频率。
Timer_Params timerParams;
Timer_Handle myTimer; Error_Block eb; Error_init(&eb); Timer_Params_init(&timerParams); timerParams.extFreq.lo = 270000000; /* 27 MHz */ timerParams.extFreq.hi = 0; myTimer = Timer_create(Timer_ANY, myIsr, &timerParams, &eb); if (myTimer == NULL) { System_abort( "Timer create failed"); } |
配置实例:以下配置实例为它所创建的定时器指定了一个频率:
var Timer = xdc.useModule(
'ti.sysbios.hal.Timer');
var timerParams = new Timer.Params(); timerParams.extFreq.lo = 270000000; timerParams.extFreq.hi = 0; ... Timer.create( 1, '&myIsr', timerParams); |
运行时实例:此C例程创建了一个定时器,每2毫秒运行一次tickFxn(),使用任意可用的定时器外设。它还创建了一个task,当特定条件发生,更改将定时器的period从2改为4毫秒。tickFxn()打印一个信息显示当前定时器的period:
Timer_Handle timerHandle;
Int main(Void) { Error_Block eb; Timer_Params timerParams; Task_Handle taskHandle; Error_init(&eb); Timer_Params_init(&timerParams); timerParams.period = 2000; /* 2 ms */ timerHandle = Timer_create(Timer_ANY, tickFxn, &timerParams, &eb); if (timerHandle == NULL) { System_abort( "Timer create failed"); } taskHandle = Task_create(masterTask, NULL, &eb); if (taskHandle == NULL) { System_abort( "Task create failed"); } } Void masterTask(UArg arg0 UArg arg1) { ... // Condition detected requiring a change to timer period Timer_stop(timerHandle); Timer_setPeriodMicroSecs( 4000); /* change 2ms to 4ms */ Timer_start(timerHandle); ... } Void tickFxn(UArg arg0) { System_printf( "Current period = %d\n", Timer_getPeriod(timerHandle); } |
8.3.1 特定目标/设备定时器模块
如8.5节所述,ti.sysbios.hal.Timer模块使用了代理委托机制实现。一个单独的特定目标/设置定时器模块提供了对每个系列的支持。例如,ti.sysbios.timers.timer64.Timer模块作为64P系列定时器外设管理器。这些特定目标/设备模块提供了通用ti.sysbios.hal.Timer模块所不支持的额外配置参数和APIs。
ti.sysbios.timers.timer64.Timer模块的配置参数controlInit、globalControlInit和 emuMgtInit用于配置各种定时器属性。此模块有一个Hwi参数结构体作为创建参数的一部分,使得你可以配置定时器关联的Hwi对象。还有一个Timer_reconfig() API让你可以重新配置一个静态创建的定时器。
配置实例:此配置实例指定定时器参数,包括定时器的特定目标/设备参数用于调用它所创建的myTimer:
var Timer = xdc.useModule(
'ti.sysbios.timers.timer64.Timer');
var timerParams = new Timer.Params(); timerParams.period = 2000; //2ms timerParams.arg = 1; timerParams.startMode = Timer.StartMode_USER; timerParams.controlInit.invout = 1; timerParams.globalControlInit.chained = false; timerParams.emuMgtInit.free = false; timerParams.suspSrc = SuspSrc_ARM; Program.global.myTimer = Timer.create( 1, "&myIsr", timerParams); |
运行时实例:此C例程使用myTimer创建之前的配置实例,并重新配置定时器,并先于BIOS_start()在程序的main()函数中使用不同的函数参数和startMode。
#include <ti/sysbios/timers/timer64/Timer.h>
#include <xdc/cfg/global.h> #include <xdc/runtime/Error.h> Void myIsr(UArg arg) { System_printf( "myIsr arg = %d\n", (Int)arg); System_exit( 0); } Int main(Int argc, char *argv[]) { Timer_Params timerParams; Error_Block eb; Error_init(&eb); Timer_Params_init(&timerParams); timerParams.arg = 2; timerParams.startMode = Timer_StartMode_AUTO; Timer_reconfig(myTimer, tickFxn, &timerParams, &eb); if (Error_check(&eb)) { System_abort( "Timer reconfigure failed"); } BIOS_start(); return( 0); } |
8.4 Cache(高速缓存)模块
cache支持提供了API函数用于执行cache行级别或全局的cache一致性操作。cache一致性操作有:
- Invalidate:让有效的cache行变为无效,并丢弃受影响的cache行内容。
- Writeback:在不丢弃原始cache行的情况下将cache行的内容写入低级别存储器,如L2 cache或外部存储器
- Writeback-Invalidation:将cache行的内容写入低级别存储器,并丢弃原始cache行内容。
8.4.1 缓存接口函数
cache接口定义于ti.sysbios.interfaces.ICache。cache接口包含以下函数。这些函数的实现是特定目标/设备的。
- Cache_enable():所有cache可用。
- Cache_disable():所有缓存不可用。
- Cache_inv(blockPtr, byteCnt, type, wait):让指定范围内存无效。当你使cache行无效,它的内容将被丢弃,cache将此行标记为“clean”,以便下次这些地址可读,它是从外部存储器获得的。在此范围内的所有行对所有缓存无效。
- Cache_wb(blockPtr, byteCnt, type, wait):回写指定范围的内存。当你执行一个回写操作,cache行内容被写入低级别存储器。此范围内的所有行在cache内变得有效,此范围内的数据回写至源内存。
- Cache_wbInv(blockPtr, byteCnt, type, wait):让指定范围内存回写并无效。当你执行一个回写,cache行内容被写入低级别内存。当你使一个cache行无效,它的内容被丢弃。所有此范围内的行被回写至源内存,然后它们对所有cache无效。
这些cache APIs操作的地址范围始于blockPtr,并延伸至byteCnt所指定的字节数量。每个缓存所操作的地址范围被量化至整个cache行。
blockPtr所指的地址在non-cache(非高速缓存)存储器时,则有可能被缓存在一个或多个cache或根本不是。如果blockPtr不对应于cache行的起点,则使用cache行的起点。如果byteCnt不等于cache行容量,则byteCnt舍入到下一个相同容量的cache。
type参数是一个Cache_Type类型的位掩码,它允许你为将要执行的动作指定一个或多个cache。
如果wait参数为true,那么此函数等待直到无效操作执行完毕并返回。如果wait参数为false,此函数立即返回。你可以稍后使用Cache_wait()来确保此操作已完成。
- Cache_wait():等待cache的 wb/wbInv/inv 操作完成。cache操作直到整个工作过程的所有缓冲及所有内存写入操作都已落实到源内存后才算真正完成。
如8.5节所述,此模块使用代理委托机制实现。特定目标/设备Cache模块为每个支持的系列单独提供。额外APIs会添加进某一模块。例如,ti.sysbios.family.c64p.Cache模块添加了C64x+ caches的专用APIs。这些扩展功能也有前缀“Cache_”。当前已支持C64x+、C674x和ARM cache。
C64x+特性:此设备的cache为 Level 1 Program (L1P), Level 1 Data (L1D), and Level 2 (L2)。参考TMS320C64x+ DSP Megamodule Reference Guide (SPRU871) 获取更多关于L1P、L1D和L2 caches的信息。
8.5 HAL包组织方案
三个存在于ti.sysbios.hal.package的SYS/BIOS模块:Hwi、Timer和Cache需要特定的目标/设备API实现以获得它们所需的功能。为了让这三个模块提供支持所有系列/设备所需的通用APIs集,SYS/BIOS使用代理委托模块机制。(参阅"RTSC Interface Primer: Lesson 12"了解详细信息)
这三个模块中的每一个都作为相应的特定目标/设备模块实现的代理。在使用中,所有Timer/Hwi/Cache API的调用请求都会转发给相应特定目标/设备模块去实现。
在应用程序构建过程的配置步骤中,ti.sysbios.hal包的代理模块基于用户config.bld文件所指定的当前目标和平台自行定位和绑定到相应的委托模块实现。委托绑定过程是在内部完成的。
注意:有关使用SYS/BIOS特定硬件信息,请参考以下链接:http://processors.wiki.ti.com/index.php/Category:SYSBIOS
下表显示了一些定时器、HWI、缓存代理模块,可以根据应用程序的目标和设备进行选择。定时器、缓存和Hwi所使用的代理模块目标/设备映射,可通过ti.sysbios.hal包的在线帮助进行了解。
![基于TI-RTOS的CC2650DK开发(20)---硬件抽象层 - 阿巴睇 - 阿巴睇的博客](http://img2.ph.126.net/hilHtsKevhmdarfCl9_vGw==/6631916588676216704.jpg)
![基于TI-RTOS的CC2650DK开发(20)---硬件抽象层 - 阿巴睇 - 阿巴睇的博客](http://img1.ph.126.net/Rj1QwH-Pp9cjhh-D7p7Lqg==/6632151884164556833.jpg)
为了让代理委托机制正确运行,代理和委托模块必须通过公共接口规范实现。Timer、Hwi和Cache接口规范存在于ti.sysbios.interfaces,分别为ITimer、IHwi和ICache。这些接口规范定义了一组最小通用接口,相信它可以满足绝大多数应用程序的需求。对于不在这些接口规范中定义的,需要满足特定目标/设备的功能性,相应的定时器、Hwi和Cache委托模块会包含这些定义于接口规范的APIs的扩展。
要访问这些扩展API集,你必须在你的配置文件中直接引用特定目标/设备模块,并在C源文件中包含相应的头文件。