本章介绍一些基本支持特性和配置参数提供APIs 的模块,这些参数用于管理整个应用程序的行为。
6.1应用程序支持和管理模块
SYS/BIOS和XDCtools提供了许多模块,这些模块具有用于支持和管理整个应用程序行为的功能。以下模块提供了属于这一类的APIs和配置设置:
BIOS Module (ti.sysbios.BIOS): 负责SYS/BIOS启动和全局参数维护,6.2.
System (xdc.runtime.System): 提供低级系统服务,6.3.
SysMin (xdc.runtime.SysMin): 系统模块的推荐代理,6.3.1.
SysCallback (xdc.runtime.SysCallback): 自定义系统行为的代理,6.3.2.
Program (xdc.cfg.Program): 作为配置命名空间的根,3.4.
Startup (xdc.runtime.Startup): 管理应用程序启动和初始化,6.5.
Reset (xdc.runtime.Reset): 允许在系统复位后立即运行目标特定的复位功能,6.6.
Error (xdc.runtime.Error): 提供处理错误的机制,6.7.
Text (xdc.runtime.Text): 管理具有公共子字符串的字符串,6.8.
Memory (xdc.runtime.Memory): 管理内存使用,7.
6.2BIOS Module
BIOS模块负责设置供SYS/BIOS使用的全局参数,并执行SYS/BIOS启动顺序。进入BIOS模块的软件包路径为ti.sysbios,SYS/BIOS应用程序应该包含以下#include语句:
#include <ti/sysbios/BIOS.h>
//配置文件
var BIOS = xdc.useModule('ti.sysbios.BIOS');
以下BIOS模块APIs 在SYS/BIOS应用程序中很有用:
BIOS_start():应用程序的main()函数在将控制权交给SYS/BIOS线程调度器之前,必须将这个函数作为要执行的最后一条语句调用。这个调用应该在完成应用程序所需的所有初始化之后执行,此函数执行所有剩余的SYS/BIOS初始化,然后将控制权转移给准备运行的最高优先级的Task。如果未启用Tasks,则控制权直接转移到Idle Loop。BIOS_start()函数不返回。
BIOS_getCpuFreq() :该函数返回CPU频率,以单位为Hz。
BIOS_setCpuFreq():设置CPU频率,以单位为Hz
BIOS_exit():终止一个SYS/BIOS应用程序时调用这个函数。BIOS_exit()调用System_exit()并中止。所有通过System_atexit()或ANSI C标准库atexit()函数绑定的函数被执行。对于SYS/BIOS应用程序,建议调用BIOS_exit()而不是调用System_exit(),因为BIOS_exit()在调用System_exit()之前会执行内部清理。如果应用程序需要终止一个错误条件,它应该调用System_abort()或System_abortSpin()。
BIOS_getThreadType():返回进行此函数调用的线程类型。支持的线程类型有:BIOS_ThreadType_Hwi、BIOS_ThreadType_Swi、BIOS_ThreadType_Task和BIOS_ThreadType_Main。
BIOS模块定义了BIOS_WAIT_FOREVER和BIOS_NO_WAIT常量,它们可以用于带有timeout参数的APIs。
BIOS模块提供了几个控制全局SYS/BIOS行为的配置参数。如BIOS.heapSize和BIOS.heapSection在第7.7.2节中描述。BIOS.libType配置参数选择在构建中使用哪个版本的SYS/BIOS库,并在2.4.5节中描述。通过设置BIOS模块的配置参数,可以减少SYS/BIOS应用程序的大小,具体方法请参见附录C和附录D。
6.3System Module
System模块提供基本的低级系统服务,如字符输出、类打印输出和退出处理。
#include <xdc/runtime/System.h>
// 配置
var System = xdc.useModule('xdc.runtime.System');
系统模块APIs 在SYS/BIOS应用程序中很有用:
System_printf():提供几个类似printf的函数,包括System_putch()、System_sprintf()、System_vprintf()、system_apprintf () (参数类型 IArg)和System_vsnprintf()(使用可变参数列表传递参数,将指定数量的字符打印到字符缓冲区)。
System_abort():当应用程序需要中止异常并返回错误消息时调用此函数。此函数返回描述发生错误的字符串。当调用此函数时将进入System gate,SupportProxy的abort函数被调用,然后调用System.abortFxn。没有通过System_atexit()或ANSI C标准库atexit()函数绑定的退出函数被调用.
System_flush() :函数将任何缓冲的输出字符发送到输出设备,还向IDE发出一个断点。这个调用会暂停目标,调用它会影响实时执行的细节,输出字符的目的地由SupportProxy模块确定。
System_exit():建议SYS/BIOS应用调用BIOS_exit()函数,而不是System_exit()函数。BIOS_exit()函数在调用System_exit()之前执行内部清理。System_exit()可以从Task中调用,但不能从Swi或Hwi中调用。
System_atexit() :调用此函数将退出处理程序添加到调用System_exit()时要执行的函数的内部堆栈中。System.maxAtexitHandlers配置属性可以控制多个退出处理程序,默认为8。
System模块使用一个支持代理模块来实现所需的底层服务。所用的实现由System.SupportProxy配置参数,默认是SysMin模块,还有 SysCallback 模块。
Exit Functions:应用程序在没有错误条件的情况下退出时,System模块调用其标准退出函数,该函数反过来调用ANSI C标准exit()函数。如果希望应用程序无限旋转以便调试应用程序的状态,请在配置中添加以下语句:
System.exitFxn = System.exitSpin;
//System.exitSpin不应被应用程序直接调用
可以使用C代码中的System_atexit()函数在运行时指定多个退出处理程序。自定义退出处理程序的原型是:
typedef Void (*System_AtexitHandler)(Int);
Abort Functions:当应用程序由于错误条件而中止时,System模块调用其标准中止函数,该函数反过来调用ANSI C标准 abort() 函数。如果希望应用程序无限旋转以便调试应用程序的状态,请在配置中添加以下语句:
System.abortFxn = System.abortSpin; // System.abortSpin不应被应用程序直接调用
//自定义中止处理程序的原型是:
typedef Void (*System_AbortFxn)(); //自定义 abort handler 原型
6.3.1SysMin Module
SysMin模块是使用大多数SYS/BIOS示例和模板的SupportProxy模块,这个模块提供了系统支持代理所需功能的实现。包括刷新缓冲字符、输出单个字符以及执行退出和中止操作的函数。
SysMin模块推荐大多数应用程序使用SysMin模块,因为它将字符放入圆形缓冲区中,运行时对象视图(ROV)工具知道如何查找和呈现的。
模块在目标上维护一个内部循环缓冲区来存储“输出”字符。当缓冲区已满时数据将被覆盖。当调用清空缓冲区的函数,使用配置的outputFxn“输出”内部循环缓冲区中的字符。除非提供自定义outputFxn,否则在TI目标上使用TI C Run Time Support库中的HOSTwrite()函数输出字符缓冲区。在非TI目标上使用ANSI C标准库函数fwrite()。
应用程序不应该直接调用SysMin函数,但SysMin模块确实提供了配置参数来控制用于内部存储输出的缓冲区位置和包含该缓冲区的内存部分。配置文件(*.cfg)可以通过如下方式启用该模块:
var SysMin = xdc.useModule('xdc.runtime.SysMin');
6.3.2SysCallback Module
SysCallback模块是SysMin代理模块的替代方案。要求您提供自定义函数来处理abort、exit、flush、put和ready操作。如果需要自定义应用程序的输出行为,请使用此模块。
6.4Program Module
Program模块充当配置命名空间的“根”。它在配置中使用,但不提供任何C api。有关配置命名空间的更多信息,请参见2.3.10节。
配置文件不需要使用useModule()语句来启用该模块。Program模块提供控制运行时内存大小的配置参数。这些包括 Program.stack,控制应用程序堆栈的大小,该堆栈与各个任务使用的堆栈分开。
Program模块还提供了控制自动生成的链接器命令文件内容的配置参数。其中包括 Program.sectMap[] 数组(见第7.3.2节)和Program.sectionsExclude 参数(参见章节7.3.4)。
6.5Startup Module
Startup模块管理在调用C的main()函数之前发生的启动初始化,通常包括设置硬件特定的寄存器,如看门狗计时器、对内存的访问、缓存设置、时钟速度等。除了允许用户添加自定义启动函数的配置参数外,该模块还提供了允许模块自动向启动序列添加初始化函数的服务。配置Startup模块的配置文件(*.cfg)应该启用该模块,如下所示:
var Startup = xdc.useModule('xdc.runtime.Startup');
具体启动顺序请参见TI-RTOS内核设备附录(BIOS_INSTALL_DIR/docs/Device_Addendum.html)
6.6Reset Module
Reset模块允许通过配置 Reset.fxns[] 数组来定义初始复位功能( reset function),在应用程序启动时尽可能早地调用Reset函数,在以用于特定于平台的硬件初始化。
只有特定的目标家庭在运行程序之前执行设备重置。因此并非所有平台都支持复位功能。不要在这个函数中放置你想要移植的代码。相反使用Startup模块来定义跨平台应用程序启动函数。
var Reset = xdc.useModule('xdc.runtime.Reset');
Reset模块允许您配置启动函数数组,它允许您为各种外设的启动活动提供单独的函数。
6.7Error Module
Error模块提供了在程序中引发、检查和处理错误的机制。
Error模块的包路径是xdc.runtime.Error,所以使用Error APIs 的SYS/BIOS应用程序应该包含下面的#include语句:
#include <xdc/runtime/Error.h>
var Error = xdc.useModule('xdc.runtime.Error'); //配置
许多SYS/BIOS api(特别是那些创建对象和分配内存的api)都有一个参数,该参数期望Error_Block。第9.3节描述了错误块和一些管理它们的api,包括Error_init()和Error_check()。
SYS/BIOS应用程序中的错误模块APIs:
Error_init():错误块置于初始状态
Error_check() :如果引发错误返回true
Error_getData() :获取错误的参数列表
Error_getMsg() :获取错误的“printf”格式字符串
Error_print() :使用System_printf()打印错误
Error_raise() :引发错误
调用System_printf()时使用 Error APIs:
System_printf(Error_getMsg(eb), Error_getData(eb)->arg[0], Error_getData(eb)->arg[1]);
if (val % 2) {
Error_raise(eb, Error_E_generic, "Value is not a multiple of 2", 0);
}
使用Error配置SYS/BIOS应用程序如何响应所引发的错误。 Error.policy, Error.policyFxn, and Error.raiseHook 配置参数。
默认情况, Error.policy将错误返回给调用函数(Error_UNWIND),如果 Error.policy 为Error_TERMINATE,则所有引发的错误都是致命的,并且对Error_raise()的调用不会返回给调用者。
默认情况, Error.policyFxn是Error_policyDefault(),它在返回调用者或终止之前处理错误并将其记录下来,具体取决于error .policy。您可以使用Error_policySpin(),它只是无限循环,以最小化目标内存占用。
每当引发错误时指定一个 Error.raiseHook ,即使Error.policy 是TERMINATE。默认情况下,此函数被设置为Error_print(),这会导致错误被格式化并由System_printf()输出。将此配置参数设置为null表示不应调用任何函数钩子。
6.8Text Module
Text模块有效地管理具有公共子字符串的字符串集合。与独立字符串的普通表相比,具有高度通用性的集合存储在更少的空间中。可用于文本字符串压缩表示的总空间限制为64K字符。
为了进一步节省空间,“压缩”的表示甚至不需要加载到目标内存中。默认情况下,文本字符串被装入目标内存。您可以通过设置文本来防止这种情况。如附录D所示,isLoaded配置属性为false。
您可以在运行时使用Text_isLoaded布尔常量来控制传递给System_printf()函数的格式字符串。例如:
if (Text_isLoaded) {
System_asprintf(tempStr, fmt, a1, a2, a3, a4, a5, a6, a7, a8);
}
else {
System_asprintf(tempStr, "{evt: fmt=%p, args=[0x%x, 0x%x ...]}", fmt, a1, a2);
}
Text模块的包路径是xdc.runtime.Text,所以使用Text api和常量的SYS/BIOS应用程序应该包含下面的#include语句:
#include <xdc/runtime/Text.h>
var Text = xdc.useModule('xdc.runtime.Text');