CC2640R2F BLE5.0 TI-RTOS概述

公司主页 文档归类 淘宝

TI-RTOS概述

TI-RTOS是CC2640R2F设备上低功耗蓝牙项目的运行环境。TI-RTOS内核是传统SYS/BIOS内核的定制版本,是一个具有驱动程序,同步和调度工具的实时抢占式多线程操作系统。

线程模块

TI-RTOS内核管理线程执行的四个不同的任务级别,如图21所示。线程模块列表如下图所示,按照优先级降序排列。

  • 硬件中断
  • 软件中断
  • 任务
  • 后台空闲功能的空闲任务


图21. TI-RTOS执行线程

这一节将要介绍四个执行线程以及整个TI-RTOS中用于消息传递和同步的各种结构。在大多数情况下,TI-RTOS函数在util.c(Util)中已被抽象为更高级别的函数。较低级的TI-RTOS函数在TI-RTOS Kernel API Guide中有描述,你可以在TI-RTOS内核用户指南中查看。本文档还定义了TI-RTOS包含的软件包和模块。

硬件中断(Hwi)

Hwi线程(也称为中断服务程序或ISR)是TI-RTOS应用程序中具有最高优先级的线程。Hwi线程用于执行有严格时间限制的关键任务。它们被触发以响应在实时环境中发生的外部异步事件(中断)。Hwi线程总是运行至完成,但是如果有其他的Hwi中断使能,它也可以暂时地被其他中断触发的Hwi线程抢占,这就是所谓的中断嵌套。有关中断嵌套,向导和功能的具体信息,可以在CC26XX技术参考手册中查看。

一般来说中断服务程序运行时间较短,不影响硬实时系统的要求。另外,由于Hwis总是运行至完成,所以在在其上下文中不会调用阻塞API。

中断的TI-RTOS驱动程序将初始化分配的外设所需的中断。有关详细信息,请参阅外设驱动

注意:
外部资源(External Resources)提供了使用GPIO和Hwis的示例。虽然SDK包含一个外设驱动程序库抽象了对硬件寄存器的访问,但建议使用线程>安全的TI-RTOS驱动程序,如外设驱动中所述。

CC2640R2F的Hwi模块还支持零延迟中断。这些中断不通过TI-RTOS Hwi调度程序,因此比标准中断更灵敏,但是该功能禁止其中断服务程序直接调用任何TI-RTOS内核API。ISR要保护自己的上下文防止它干扰内核的调度程序。

为了能让低功耗蓝牙协议栈满足RF严格的时序要求,所有应用程序定义的Hwis都要以最低优先级执行。TI向系统添加新的Hwis时,建议不要修改默认的Hwi优先级。为了不破坏低功耗蓝牙协议栈中TI-RTOS的严格时序,应用程序中定义了临界段代码。执行临界段代码时中断会被关闭,在临界段代码执行完毕之后才会重新启用中断。

软件中断(Swi)

软件中断线程(Swis)是在Hwi线程和任务线程之间提供的一个额外的优先级。与Hwis由硬件中断触发不同,Swis是通过在程序编写过程中调用某些Swi模块的API来触发中断。由于时间限制,Swis中断服务程序不能作为任务来运行,其截止时间不如硬件中断服务程序那么严格。Swi也总是运行至完成,它允许Hwis将不太重要的中断处理放到较低优先级的线程来处理,从而最小化CPU在中断服务程序中花费的时间。Swis需要足够的空间来保存每个Swi中断优先级的上下文,它的每个线程都使用单独的堆栈。

与Hwis类似,Swis需要保持简短,它不应该包含任何阻塞API的调用。这保证了诸如无线协议栈等高优先级任务能根据需要执行。在Swis中建议发布某些TI-RTOS同步对象,然后把具体处理放在任务上下文中。图22说明了这种用例。

图22. 抢占情景

Swi上下文中常常会由时钟模块调用,对于Swi服务函数,不调用阻塞API,保证较短的执行时间是很重要的。

任务

任务线程的优先级高于空闲任务线程,低于软件中断。任务与软件中断的不同之处在于,任务可以在执行期间等待(阻塞),直到有必要的资源可用。每个任务线程都有一个独立的堆栈。TI-RTOS提供了可用于任务间通信和同步的多种机制。这些包括信号量,事件,消息队列和邮箱。
有关详细信息,可以在本文后面的任务中查看。

空闲任务

空闲任务线程在TI-RTOS应用程序中优先级最低,它会执行一个空闲循环。在主函数返回之后,TI-RTOS应用程序会调用每个TI-RTOS模块的启动程序,然后进入空闲循环。每个线程在被再次调用之前都必须等待所有其他线程执行完成。空闲循环在没有更高优先级的任务需要执行的时候会一直执行。只有没有严格截止期限的函数才能在空闲循环中执行。

对于CC2640R2F设备,空闲任务支持电源策略管理器设置为允许的最低功率节省模式。

内核配置

TI-RTOS应用程序可以使用工程中的.cfg文件来配置TI-RTOS内核。在IARCCS工程中,配置文件在应用程序项目工作区中的TOOLS文件夹下。

该配置通过选择性地包括或使用可用于内核的RTSC模块来实现。.cfg中通过调用xdc.useModule()函数来设置TI-RTOS内核用户指南中定义的各种选项来启用一个模块。

注意:
BLE5-Stack中的项目(如simple_peripheral)通常会包含一个app_ble.cfg配置文件。

可以在.cfg文件中配置的一些选项(但不限于这些):

  • 启动选项
  • Hwi,Swi和任务优先级的数量
  • 异常和错误处理
  • 系统刻度的持续时间(TI-RTOS内核中最基本的时间单位)。
  • 定义应用程序的入口点和中断向量
  • TI-RTOS堆和堆栈(不要与其他堆管理器混淆!)
  • 包括预编译的内核和TI-RTOS驱动程序库
  • 系统配置(for System_printf()

一旦.cfg文件发生变动时,您需要重新运行XDCTools的configuro工具。在IAR和CCS提供的示例中这一步作为预构建步骤已经为您提供。

注意:
.cfg的名称并不重要。但是项目只能包含一个.cfg文件。

对于CC2640R2F,TI-RTOS内核存储在ROM中。通常为了节省Flash的访问足迹,.cfg也会包含在内核的ROM模块中,如清单1所示。

清单1. 如何把TI-RTOS内核包含到ROM中

/ * ================ ROM configuration================ * / 
/ * 
*To use BIOS in flash, comment out the code block below.
* / 
if (typeof NO_ROM == 'undefined' ||(typeof NO_ROM != 'undefined' && NO_ROM == 0 ))
{ 
	var ROM = xdc.useModule'ti.sysbios.rom.ROM'); 
	if(program.cpu.deviceName .match(/CC26/)){ 
		ROM.romName = ROM.CC2640R2F; 
	} 
	else if(Program.cpu.deviceName.match(/CC13/)){ 
		ROM.romName = ROM.CC1350;
	} 
}

ROM中的TI-RTOS内核针对性能进行了优化。如果您的应用程序需要额外的工具(通常用于调试),则必须将TI-RTOS内核包含在Flash中,这将增加Flash消耗。下面显示的是在ROM中使用TI-RTOS内核的简要列表。

  • BIOS.assertsEnabled必须设置为false
  • BIOS.logsEnabled必须设置为false
  • BIOS.taskEnabled必须设置为true
  • BIOS.swiEnabled必须设置为true
  • BIOS.runtimeCreatesEnabled 必须设置为true
  • BIOS必须使用该ti.sysbios.gates.GateMutex模块
  • Clock.tickSource必须设置为Clock.TickSource_TIMER
  • Semaphore.supportsPriority一定是false
  • Swi,Task和Hwi hooks不容许
  • Swi,Task和Hwi name instances不容许
  • 任务堆栈检查被禁用
  • Hwi.disablePriority必须设置为0x20
  • Hwi.dispatcherAutoNestingSupport必须设置为true
  • 默认的Heap instance必须设置为ti.sysbios.heaps.HeapMem管理者

有关上述列表外的其他文档,可以在TI-RTOS内核用户指南中查看。

创造与构建

大多数TI-RTOS模块通常都有_create()_construct()APIs用来初始化最初的例程。这两个API之间运行时的主要差异是内存分配和错误处理。
在初始化之前,创建API会从默认的TI-RTOS堆执行内存分配。因此,应用程序必须在继续之前检查有效句​​柄的返回值。

清单2. 创建一个信号量

 1 Semaphore_Handle sem;
 2 Semaphore_Params semParams;
 3 Semaphore_Params_init(&semParams);
 4 sem = Semaphore_create(0,&semParams,NULL);/*Memory allocated in here*/
 5 if (sem == NULL) /* Check if the handle is valid */
 6 {
 7 	System_abort("Semaphore could not be created");
 8 }
 9
10 

构造API提供了一个用于存储实例变量的数据结构。由于内存已被预先分配给实例,构建后不再需要进行错误检查。

清单3. 构造一个信号量

1 Semaphore_Handle  SEM ;
  • 3
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值