有了前文对TI-RTOS的认识,包括
1 HWI与SWI的关系与区别,TI-RTOS的介绍 https://blog.csdn.net/Clarence_happy/article/details/89478588
2 TASK机制的介绍,https://blog.csdn.net/Clarence_happy/article/details/89485716
3 信号量机制的介绍 ,https://blog.csdn.net/Clarence_happy/article/details/89491204
现在想综合这些知识,在TI提供的SDK simpleBlePeriphera工程基础上,创建一个全新的任务。
这个任务先假定为一个简单的闪灯任务,LED_TASK
为了测试TASK机制的功能,需要实现
1 LED_TASK 与 BLE_TASK相互独立,且BLE_TASK优先级高,LED_TASK优先级低
2 LED_TASK能与BLE_TASK交互数据,外部通过蓝牙主机发送LED闪烁间隔给到BLE_TASK,BLE_TASK再发送给LED_TASK,实现任务之间的数据相互
////正文
1 simpleBlePeriphera工程
显然,在startup文件夹下包含了main.c函数,main函数中包含了创建BLE任务的函数
SimpleBLEPeripheral_createTask();
void SimpleBLEPeripheral_createTask(void)
{
Task_Params taskParams;// Configure task
Task_Params_init(&taskParams);
taskParams.stack = sbpTaskStack;//可以看出是一个数组的首地址
taskParams.stackSize = SBP_TASK_STACK_SIZE;//堆栈数组的大小
taskParams.priority = SBP_TASK_PRIORITY;//BLE TASK的优先级宏定义Task_construct(&sbpTask, SimpleBLEPeripheral_taskFxn, &taskParams, NULL);
}
首先我们参照创建BLE_TASK的方法,创建自己的任务LED_TASK,创建led_task.c
#include "led_task.h"
#include
#include
#include
#include
#include "periph_led.h"
Semaphore_Handle semLedFicker;
static void BLE_taskFxn(UArg a0, UArg a1){
Semaphore_Params semLedFickerParams;//创建一个信号量的初始化变量
uint32_t timeoutInTicks = 100000;//多久pending一次信号量 100000 * 10us = 1S,也就是任务1S判断一次信号量是否ready
Semaphore_Params_init(&semLedFickerParams);//初始化信号量
semLedFicker = Semaphore_create(0, &semLedFickerParams, NULL); //为全局信号量创建实体,原先也许就是一个指针,现在的确为他动态创建内存。
if(semLedFicker ==NULL){
//创建失败
}else{
//创建成功
}
//初始化设备
for(;;){
//wait 一个信号量
Semaphore_pend(semLedFicker, timeoutInTicks);//第一个参数是信号量,第二个参数是等待时间,如果超过这个时间信号量还未被其他任务POST,那么会自动POST,如果不需要此功能,可以把第二个参数改为BIOS_WAIT_FOREVER
board_led_toogle(_2G_LED);
}
}
#define LED_TASK_PRIORITY 1
#define LED_TASK_STACK_SIZE 512
Task_Struct ledTask;//创建一个生命周期超长的ledTask实例
Char ledTaskStack[LED_TASK_STACK_SIZE];//为LED TASK创建堆栈
void Led_createTask(void){
Task_Params taskParams; // Configure task
Task_Params_init(&taskParams);
taskParams.stack = ledTaskStack;
taskParams.stackSize = LED_TASK_STACK_SIZE;
taskParams.priority = LED_TASK_PRIORITY;
Task_construct(&ledTask, BLE_taskFxn, &taskParams, NULL);//创建实例
}
在配置优先级的时候,咱们让BLE的优先级高,默认的BLE优先级是最低的,咱们把他拉高一级,让LED_TASK作为最低优先级
TI-RTOS中值越大优先级越高
// Task configuration
#define SBP_TASK_PRIORITY 2 //默认是1的
于是咱们把Led_createTask放到SimpleBLEPeripheral_createTask();之后
SimpleBLEPeripheral_createTask();
Led_createTask();
现象是2G灯1S一次闪烁,在BLE任务中并没有POST信号量,但是我在LED TASK中PENDING操作的第二个参数里,摆放的是一个数,而不是BIOS_WAIT_FOREVER,所以,外部信号量如果长时间不POST,任务会自动等待TIMEOUT,POST此信号量。
把参数改为BIOS_WAIT_FOREVER,LED不再闪烁。
实验继续
在BLE_PERIPH的周期函数中放入POST函数,也就是说BLE_TASK任务里,每隔1S ,POST一次LED任务,观察LED灯是否闪烁。
static void SimpleBLEPeripheral_performPeriodicTask(void)
{
Semaphore_post(semLedFicker);
}
现象,LED正常闪烁,证明在BLE_TASK中POST一个BIOS_WAIT_FOREVER的信号量,可以触发任务的执行。
笔者想到,TASK之间共享数据在同一个工程中,可以用最轻便的方法,定义一个全局数组,不同的TASK共同访问这一个数组即可,或者使用操作系统提供的队列,或者邮箱。最困难的问题是如何协调TASK,不要再同一时间访问同一个变量,用信号量完美解决此问题了。
成功的将多个TASK,在信号量的指挥下协调运行。