Keil MDK之RTX任务管理 初始化 创建 删除

在Keil 的安装目录下面有个RTX的帮助文档,路径C:\keil\ARM\Hlp 这里面的rlarm.chm手册,详细介绍了RTX的各函数接口等

一、RTX的初始化和启动

1、RTX的初始化函数有三个,可以打开rlarm.chm手册,如下图


这三个函数的解析和使用方法大家可以参考手册,

这里重点介绍下os_sys_init_user函数,其他两个有兴趣的可以自己看看手册

函数原型

void os_sys_init_user (
    void (*task)(void),    /* 任务函数*/
    U8    priority,        /* 任务优先级(1-254) */
    void* stack,           /* 任务栈 */
    U16   size);           /* 任务栈大小 */
函数描述:

该函数用于实现RTX操作系统的初始化和启动任务的创建,并且可以自定义任务栈的大小

第一个参数是启动任务的函数名

第二个参数是任务的优先级  RTX任务的优先级越低数字越小

第三个参数是任务栈地址

第四个参数是任务栈大小

举个列子:

os_sys_init_user(AppTaskStart,            /*任务函数*/
4,                       /*任务优先级*/
&AppTaskStartStk,        /*任务栈*/
sizeof(AppTaskStartStk));/*任务栈大小*/

二、任务的创建

RTX中任务的创建有4个函数,如下图


这里重点解析下os_tsk_create_user函数

函数原型:

OS_TID os_tsk_create_user(
    void (*task)(void),    /*任务函数 */
    U8    priority,        /* 任务优先级 (1-254) */
    void* stk,             /* 任务栈 */
    U16   size );          /*任务栈大小 */
函数描述:

该函数用于实现RTX操作系统的任务创建,并且可以自定义栈的大小

第一个参数创建的任务函数名

第二个参数任务的优先级

第三个参数任务栈的地址

低四个参数任务栈的大小

返回值是任务的ID

举个列子:

HandleTaskLED = os_tsk_create_user(AppTaskLED,            /*任务函数*/
 2,                     /*优先级 注意RTX的数字越小,优先级越低*/
       &AppTaskLEDStk,        /*任务栈起始地址*/
sizeof(AppTaskLEDStk));/*任务栈大小*/

三、RTX中的任务删除

RTX中任务的删除有两个函数,如下图


这里重点解析下os_tsk_delete函数

函数原型:

OS_RESULT os_tsk_delete (
    OS_TID task_id );    /*任务ID */
函数描述:

该函数用于实现RTX操作系统的任务删除

第一个参数是删除任务的ID

返回值:如果任务删除成功,函数返回OS_R_OK,其余所有的情况返回OS_R_NOK

举个列子

if(HandleTaskLED != NULL)
{
if(os_tsk_delete(HandleTaskLED) == OS_R_OK)
{
HandleTaskLED = NULL;
printf("任务AppTaskLED删除成功\r\n");
}
else
{
printf("任务AppTaskLED删除失败\r\n");
}
}

下面就做个实验

实验目的:学习RTX的任务创建和删除

实验内容:

1、k1按键按下,删除任务AppTaskLED

2、k2按键按下,重新创建AppTaskLED

下面是详细的代码

#include "bsp.h" /* 底层硬件驱动 */
#include <RTL.h>




static uint64_t AppTaskLEDStk[256/8];/*任务栈*/
static uint64_t AppTaskStartStk[512/8];/*任务栈*/
static uint64_t AppTaskUserKeyStk[512/8];/**/




/*任务句柄*/
OS_TID HandleTaskLED = NULL;
OS_TID HandleTaskKey = NULL;
/*函数声明*/
static void AppTaskCreate(void);
__task void AppTaskLED(void);
__task void AppTaskStart(void);




/*
*********************************************************************************************************
* 函 数 名: main
* 功能说明: c程序入口
* 形    参:无
* 返 回 值: 错误代码(无需处理)
*********************************************************************************************************
*/
int main(void)
{


/*
ST固件库中的启动文件已经执行了 SystemInit() 函数,该函数在 system_stm32f4xx.c 文件,主要功能是
配置CPU系统的时钟,内部Flash访问时序,配置FSMC用于外部SRAM
*/
bsp_Init();/*底层初始化*/
os_sys_init_user(AppTaskStart,            /*任务函数*/
4,                       /*任务优先级*/
&AppTaskStartStk,        /*任务栈*/
sizeof(AppTaskStartStk));/*任务栈大小*/
/* 进入主程序循环体 */
while (1)
{
;
}
}
/*
*********************************************************************************************************
* 函 数 名: AppTaskLED
* 功能说明: LED闪烁的任务
* 形    参:无
* 返 回 值: 无
*********************************************************************************************************
*/
__task void AppTaskLED(void)
{
static uint8_t i = 0;
while(1)
{
if(i % 2 == 0)
{
GPIO_ResetBits(GPIOI,GPIO_Pin_10);/*点亮LED*/
}
else
{
GPIO_SetBits(GPIOI,GPIO_Pin_10);/*熄灭LED*/
}
i++;
os_dly_wait(800);/*系统延时函数 因为时钟节拍为1000 所以这里是延时800ms,也就是使AppTaskLED任务挂起800MS*/
}
}


__task void AppTaskUserKey(void)
{
static uint8_t ucKeyCode  = 0;
while(1)
{
ucKeyCode = bsp_GetKey();/*获取按键按下的键值*/
switch(ucKeyCode)
{
case KEY_DOWN_K1:
printf("K1键按下,删除任务AppTaskLED\r\n");
if(HandleTaskLED != NULL)
{
if(os_tsk_delete(HandleTaskLED) == OS_R_OK)/*删除任务AppTaskLED*/
{
HandleTaskLED = NULL;
printf("任务AppTaskLED删除成功\r\n");
}
else
{
printf("任务AppTaskLED删除失败\r\n");
}
}
break;
case KEY_DOWN_K2:
printf("K2键按下,重新创建任务AppTaskLED\r\n");
if(HandleTaskLED == NULL)
{
HandleTaskLED = os_tsk_create_user(AppTaskLED,         /*任务函数*/
2,                 /*任务优先级*/
AppTaskLEDStk,     /*任务栈*/
sizeof(AppTaskLEDStk));/*任务栈的大小*/
}
break;
default:
break;
}
os_dly_wait(20);
}
}
/*
*********************************************************************************************************
* 函 数 名:AppTaskCreate
* 功能说明: 任务创建
* 形    参:无
* 返 回 值: 无
*********************************************************************************************************
*/
static void AppTaskCreate(void)
{
HandleTaskLED = os_tsk_create_user(AppTaskLED,            /*任务函数*/
2,                     /*优先级 注意RTX的数字越小,优先级越低*/
&AppTaskLEDStk,        /*任务栈起始地址*/
sizeof(AppTaskLEDStk));/*任务栈大小*/
HandleTaskKey = os_tsk_create_user(AppTaskUserKey,
3,
&AppTaskUserKeyStk,
sizeof(AppTaskUserKeyStk));
}
/*
*********************************************************************************************************
* 函 数 名:AppTaskStart
* 功能说明: 开始任务
* 形    参:无
* 返 回 值: 无
*********************************************************************************************************
*/
__task void AppTaskStart(void)
{
AppTaskCreate();/*创建AppTaskLED任务*/
while(1)
{
bsp_KeyScan();/*查询按键是否被按下 并且保存键值*/
os_dly_wait(10);/*系统延时函数*/
}
}


实现结果:

我们可以使用调试,来观察每个任务的运行情况,如下图是刚启动的任务运行情况


可以看到有是那个用户任务。一个是开始任务,一个是按键处理任务,一个是LED闪烁的任务

当我们按下K1的时候,再来看发现LED闪烁的任务没有了,如下图,这就是删除了LED闪烁的任务


按下K1就删除了LED的任务

然后按下k2就可以重新创建任务,调试结果和启动的结果一样,同时我们也可以观察到LED的闪烁情况,按下K1LED停止闪烁,按下k2LED重新闪烁

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

做了不一定能实现但不做一定不会实现

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值