状态结构定义
定义一个结构体,保存任务状态信息。
状态信息获取
在接口函数中,将任务结构中的一些字段值赋值到结构信息中。
- 无需了解任务详细结构
- 可完整获取同一时刻任务的状态信息
tTask.c
#ifndef __TINYOS_H
#define __TINYOS_H
#include <stdint.h>
#include "tLib.h"
#include "tConfig.h"
#define TINYOS_TASK_STATE_RDY 0 //任务就绪
#define TINYOS_TASK_STATE_DESTORYED (1 << 1) //任务删除状态位
#define TINYOS_TASK_STATE_DELAYED (1 << 2) //任务处于延时状态
#define TINYOS_TASK_SYATE_SUSPEND (1 << 3) //任务挂起状态位
//堆栈单元类型
typedef uint32_t tTaskStack;
/* 任务结构 */
typedef struct _tTask {
uint32_t *stack; //指向堆栈的指针
tNode linkNode; //优先级队列的链接结点
uint32_t delayTicks; //软延时计数器
tNode delayNode; //通用的结点结构
uint32_t prio; //优先级字段
uint32_t state; //任务状态
uint32_t slice; //时间片计数器
uint32_t suspendCount; //任务挂起计数器
void (*clean) (void *param); //清理函数
void *cleanParam; //清理函数参数
uint8_t requestDeleteFlag; //删除请求标记
}tTask;
extern tTask *currentTask;
extern tTask *nextTask;
uint32_t tTaskEnterCritical(void);
void tTaskExitCritical(uint32_t status);
void tTaskSwitch(void); //和CPU相关,写在switch.c
void tTaskRunFirst(void);
void tTaskSchedInit(void);
void tTaskSchedDisable(void);
void tTaskSchedEnable(void);
void tTaskSchedRdy(tTask *task);
void tTaskSchedUnRdy(tTask *task);
void tTaskSchedRemove(tTask *task);
void tTaskSched(void);
void tTimeTaskWait(tTask *task, uint32_t ticks);
void tTimeTaskWakeUp(tTask *task);
void tTimeTaskRemove(tTask *task);
void tTaskSystemTickHandler(void);
void tTaskDelay(uint32_t delay);
/* 任务查询结构 */
typedef struct _tTaskInfo {
uint32_t delayTicks; //延时还剩多少个tick数
uint32_t prio; //优先级
uint32_t state; //状态
uint32_t slice; //还有多少个时间片
uint32_t suspendCount; //挂起次数
}tTaskInfo;
void tTaskInit(tTask *task, void(*entry)(void *), void *param, uint32_t prio, tTaskStack *stack);
void tTaskSuspend(tTask *task);
void tTaskWakeUp(tTask *task);
void tTaskSetCleanCallFunc(tTask *task, void (*clean)(void *param), void *param);
void tTaskForceDelete(tTask *task);
void tTaskRequestDelete(tTask *task);
uint8_t tTaskIsRequestedDelete(void);
void tTaskDeleteSelf(void);
void tTaskGetInfo(tTask *task, tTaskInfo *info);
void tSetSysTickPeriod(uint32_t ms);
void tInitApp(void);
#endif
tinyOS.h
#include "tinyOS.h"
/* 任务初始化函数 */
//参数:tTask结构的指针,任务入口函数的地址,传递给任务的参数地址,堆栈地址
//任务初始运行时,会把栈里的内容依次弹出来,恢复到内核寄存器中。
void tTaskInit(tTask *task, void(*entry)(void *), void *param, uint32_t prio, tTaskStack *stack)
{
//初始化具体的堆栈内容
//传递堆栈的末端地址,内核本身的堆栈增长方式是满递减方式增长的,先进行递减操作
*(--stack) = (unsigned long)(1 << 24); //xPSR,设置T标志位
*(--stack) = (unsigned long)entry; //R15(PC),程序入口函数
*(--stack) = (unsigned long)0x14; //R14(LR),未用
*(--stack) = (unsigned long)0x12; //R12,未用
*(--stack) = (unsigned long)0x3; //R3,未用
*(--stack) = (unsigned long)0x2; //R2,未用
*(--stack) = (unsigned long)0x1; //R1,未用
*(--stack) = (unsigned long)param; //R0,程序的入口参数,函数第一个参数存入R0
*(--stack) = (unsigned long)0x11; //R11,未用
*(--stack) = (unsigned long)0x10; //R10,未用
*(--stack) = (unsigned long)0x9; //R9,未用
*(--stack) = (unsigned long)0x8; //R8,未用
*(--stack) = (unsigned long)0x7; //R7,未用
*(--stack) = (unsigned long)0x6; //R6,未用
*(--stack) = (unsigned long)0x5; //R5,未用
*(--stack) = (unsigned long)0x4; //R4,未用
task->slice = TINYOS_SLICE_MAX; //时间片初始值是最大值
task->stack = stack; //保存最终的值
task->delayTicks = 0; //初始化计数器为0
task->prio = prio; //初始化优先级
task->state = TINYOS_TASK_STATE_RDY; //任务状态初始化为就绪态
task->suspendCount = 0; //任务挂起计数器为0
task->clean = (void (*)(void *))0; //清理函数为空
task->cleanParam = (void *)0; //清理函数参数为空
task->requestDeleteFlag = 0; //删除请求标记为0
tNodeInit(&(task->delayNode)); //延时结点初始化
tNodeInit(&(task->linkNode)); //链接结点初始化
tTaskSchedRdy(task); //链接结点插入就绪表
}
/* 任务挂起函数 */
void tTaskSuspend(tTask *task)
{
uint32_t status = tTaskEnterCritical();
if(!(task->state & TINYOS_TASK_STATE_DELAYED))//任务不在延时状态
{
if(++task->suspendCount <= 1)//对挂起计数器++后,挂起计数器是第一次挂起
{
task->state |= TINYOS_TASK_SYATE_SUSPEND;//任务为挂起态
tTaskSchedUnRdy(task);//将任务从挂起就绪列表中移除
if(task == currentTask)//判断任务是否是当前任务
{
tTaskSched();
}
}
}
tTaskExitCritical(status);
}
/* 任务恢复函数 */
void tTaskWakeUp(tTask *task)
{
uint32_t status = tTaskEnterCritical();
if(task->state & TINYOS_TASK_SYATE_SUSPEND)//任务在挂起状态
{
if(--task->suspendCount == 0)
{
task->state &= ~TINYOS_TASK_SYATE_SUSPEND;//清除挂起态
tTaskSchedRdy(task);//将任务插入就绪列表
tTaskSched();
}
}
tTaskExitCritical(status);
}
/* 资源清理回调函数 */
void tTaskSetCleanCallFunc(tTask *task, void (*clean)(void *param), void *param)
{
task->clean = clean;
task->cleanParam = param;
}
/* 强制删除函数 */
void tTaskForceDelete(tTask *task)
{
uint32_t status = tTaskEnterCritical();
if(task->state & TINYOS_TASK_STATE_DELAYED)//任务处于延时状态
{
tTimeTaskRemove(task);
}
else if(!(task->state & TINYOS_TASK_SYATE_SUSPEND))//任务不处于挂起状态
{
//任务在运行或就绪态
tTaskSchedRemove(task);
}
if(task->clean)
{
task->clean(task->cleanParam);
}
if(currentTask == task)//任务是当前任务
{
tTaskSched();
}
tTaskExitCritical(status);
}
/* 请求删除函数 */
void tTaskRequestDelete(tTask *task)
{
uint32_t status = tTaskEnterCritical();
task->requestDeleteFlag = 1;
tTaskExitCritical(status);
}
/* 检查删除请求函数 */
uint8_t tTaskIsRequestedDelete(void)
{
uint8_t delete;
uint32_t states = tTaskEnterCritical();
delete = currentTask->requestDeleteFlag;
tTaskExitCritical(states);
return delete;
}
/* 删除任务自己函数 */
void tTaskDeleteSelf(void)
{
uint32_t states = tTaskEnterCritical();
//任务处于运行态
tTaskSchedRemove(currentTask);
if(currentTask->clean)
{
currentTask->clean(currentTask->cleanParam);
}
tTaskSched();
tTaskExitCritical(states);
}
/* 任务状态查询函数 */
void tTaskGetInfo(tTask *task, tTaskInfo *info)
{
uint32_t states = tTaskEnterCritical();
info->delayTicks = task->delayTicks;
info->prio = task->prio;
info->slice = task->slice;
info->state = task->state;
info->suspendCount = task->suspendCount;
tTaskExitCritical(states);
}
app.c
#include "tinyOS.h"
//定义任务,分别为它们配备独立的堆栈空间
tTask tTask1;
tTask tTask2;
tTask tTask3;
tTask tTask4;
tTaskStack task1Env[1024];
tTaskStack task2Env[1024];
tTaskStack task3Env[1024];
tTaskStack task4Env[1024];
//定义任务要执行的功能
int task1Flag;
void task1Entry(void *param)
{
tTaskInfo taskInfo;
tSetSysTickPeriod(10);//初始化
for(;;)//任务里是for的死循环
{
tTaskGetInfo(currentTask, &taskInfo);
tTaskGetInfo(&tTask4, &taskInfo);
task1Flag = 0;
tTaskDelay(1);
task1Flag = 1;
tTaskDelay(1);
}
}
int task2Flag;
void task2Entry(void *param)
{
for(;;)
{
task2Flag = 0;
tTaskDelay(1);
task2Flag = 1;
tTaskDelay(1);
}
}
int task3Flag;
void task3Entry(void *param)
{
for(;;)
{
task3Flag = 0;
tTaskDelay(1);
task3Flag = 1;
tTaskDelay(1);
}
}
int task4Flag;
void task4Entry(void *param)
{
for(;;)
{
task4Flag = 0;
tTaskDelay(1);
task4Flag = 1;
tTaskDelay(1);
}
}
/* 应用任务初始化函数 */
void tInitApp(void)
{
//最后一个参数:传堆栈末端地址,因为堆栈是向下生长的,初始堆栈地址是堆栈空间最后一个单元地址的末端
tTaskInit(&tTask1, task1Entry, (void *)0x11111111, 0, &task1Env[1024]);
tTaskInit(&tTask2, task2Entry, (void *)0x22222222, 1, &task2Env[1024]);
tTaskInit(&tTask3, task3Entry, (void *)0x22222222, 0, &task3Env[1024]);
tTaskInit(&tTask4, task4Entry, (void *)0x22222222, 1, &task4Env[1024]);
}