完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
|
|
相关推荐
|
|
|
在RTOS下,上面两个截图中设置的栈大小有了一个新的名字叫系统栈空间,而任务栈是不使用这里的空间的。任务栈不使用这里的栈空间,哪里使用这里的栈空间呢?答案就在中断函数和中断嵌套。
对于这个问题,简单的描述如下,更详细的内容待我们讲解RTX任务切换和双堆栈指针时再细说(此章节在后期RTX教程升级版本时再配套)。 u 由于Cortex-M3和M4内核具有双堆栈指针,MSP主堆栈指针和PSP进程堆栈指针,或者叫PSP任务堆栈指针也是可以的。在RTX操作系统中,主堆栈指针MSP是给系统栈空间使用的,进程堆栈指针PSP是给任务栈使用的。也就是说,在RTX任务中,所有栈空间的使用都是通过PSP指针进行指向的。一旦进入了中断函数已经可能发生的中断嵌套都是用的MSP指针。这个知识点要记住他,当前可以不知道这是为什么,但是一定要记住。 u 实际应用中系统栈空间分配多大,主要是看可能发生的中断嵌套层数,下面我们就按照最坏执行情况进行考虑,所有的寄存器都需要入栈,此时分为两种情况: l 64字节 对于Cortex-M3内核和未使用FPU(浮点运算单元)功能的Cortex-M4内核在发生中断时需要将16个通用寄存器全部入栈,每个寄存器占用4个字节,也就是16*4 = 64字节的空间。 可能发生几次中断嵌套就是要64乘以几即可。当然,这种是最坏执行情况,也就是所有的寄存器都入栈。 (注:任务执行的过程中发生中断的话,有8个寄存器是自动入栈的,这个栈是任务栈,进入中断以后其余寄存器入栈以及发生中断嵌套都是用的系统栈)。 l 200字节 对于具有FPU(浮点运算单元)功能的Cortex-M4内核,如果在任务中进行了浮点运算,那么在发生中断的时候除了16个通用寄存器需要入栈,还有34个浮点寄存器也是要入栈的,也就是(16+34)*4 = 200字节的空间。当然,这种是最坏执行情况,也就是所有的寄存器都入栈。 (注:任务执行的过程中发送中断的话,有8个通用寄存器和18个浮点寄存器是自动入栈的,这个栈是任务栈,进入中断以后其余通用寄存器和浮点寄存器入栈以及发生中断嵌套都是用的系统栈。)。 |
|
|
|
|
|
|
|
|
7.7 RTX初始化和启动
使用如下3个函数可以实现RTX的初始化: u os_sys_init() u os_sys_init_prio() u os_sys_init_user() 关于这3个函数的讲解及其使用方法可以看教程第3章3.3小节里面说的参考资料rlarm.chm文件 |
|
|
|
|
|
|
|
|
这里我们重点的说一下函数os_sys_init_user函数,因为从本章节开始所有的例子都是用的这个函数作为RTX的初始化。
函数原型: 复制代码 void os_sys_init_user ( void (*task)(void), /* 任务函数 */ U8 priority, /* 任务优先级 (1-254) */ void* stack, /* 任务栈 */ U16 size); /* 任务栈大小,单位字节*/ 函数描述: 函数os_sys_init_user用于实现RTX操作系统的初始化和启动任务的创建,并且使用这个函数做初始化还可以自定义任务栈的大小。 u 第1个参数填启动任务的函数名。 u 第2个参数是任务的优先级设置,用户可以设置的任务优先级范围是1-254。优先级0用于空闲任务,如果用户将这个参数设置为0的话,RTX系统会将其更改为1。优先级255被保留用于最重要的任务。 u 第3个参数是任务栈地址。 u 第4个参数是任务栈大小。 |
|
|
|
|
|
|
|
|
使用这个函数要注意以下几个问题
1. 必须在main函数中调用os_sys_init_user。 2. 任务栈空间必须8字节对齐,可以将任务栈数组定义成uint64_t类型即可。 3. 优先级255代表更重要的任务。 4. 对于RTX操作系统来说,优先级参数中数值越小优先级越低,也就是说空闲任务的优先级是最低的,因为它的优先级数值是0 使用举例: 复制代码 int main (void) { /* RTX初始化并创建启动任务 */ os_sys_init_user (AppTaskStart, /* 任务函数 */ 4, /* 任务优先级 */ &AppTaskStartStk, /* 任务栈 */ sizeof(AppTaskStartStk)); /* 任务栈大小,单位字节数 */ while(1); } |
|
|
|
|
|
|
|
|
7.8 任务创建
使用如下4个函数可以实现RTX的任务创建: u os_tsk_create u os_tsk_create_ex u os_tsk_create_user u os_tsk_create_user_ex 关于这4个函数的讲解及其使用方法可以看教程第3章3.3小节里面说的参考资料rlarm.chm文件 |
|
|
|
|
|
|
|
|
这里我们重点的说一下函数os_tsk_create_user函数,因为从本章节开始所有的例子都是用的这个函数作为RTX的任务创建。
函数原型: 复制代码 OS_TID os_tsk_create_user( void (*task)(void), /* 任务函数 */ U8 priority, /* 任务优先级 (1-254) */ void* stk, /* 任务栈*/ U16 size ); /* 任务栈大小*/ 函数描述: 函数os_tsk_create_use用于实现RTX操作系统的任务创建,并且还可以自定义任务栈的大小。 u 第1个参数填创建任务的函数名。 u 第2个参数是任务的优先级设置,用户可以设置的任务优先级范围是1-254。优先级0用于空闲任务,如果用户将这个参数设置为0的话,RTX系统会将其更改为1。优先级255被保留用于更重要的任务。如果新创建的任务优先级比当前正在执行任务的优先级高,那么就会立即切换到高优先级任务去执行。 u 第3个参数是任务栈地址。 u 第4个参数是任务栈大小。 u 函数的返回值是任务的ID,使用ID号可以区分不同的任务。 |
|
|
|
|
|
|
|
|
使用这个函数要注意以下问题
1. 任务栈空间必须8字节对齐,可以将任务栈数组定义成uint64_t类型即可。 使用举例: 复制代码 /* ********************************************************************************************************** 变量 ********************************************************************************************************** */ static uint64_t AppTaskUserIFStk[512/8]; /* 任务栈 */ /* 任务句柄 */ OS_TID HandleTaskUserIF = NULL; /* ********************************************************************************************************* * 函 数 名: AppTaskCreate * 功能说明: 创建应用任务 * 形 参: 无 * 返 回 值: 无 ********************************************************************************************************* */ static void AppTaskCreate (void) { HandleTaskUserIF = os_tsk_create_user(AppTaskUserIF, /* 任务函数 */ 1, /* 任务优先级 */ &AppTaskUserIFStk, /* 任务栈 */ sizeof(AppTaskUserIFStk)); /* 任务栈大小,单位字节数 */ } |
|
|
|
|
|
|
|
|
7.9 任务删除
使用如下2个函数可以实现RTX的任务删除: u os_tsk_delete u os_tsk_delete_self 关于这2个函数的讲解及其使用方法可以看教程第3章3.3小节里面说的参考资料rlarm.chm文件 |
|
|
|
|
|
|
|
|
这里重点的说一下函数os_tsk_delete,因为从本章节开始所有的例子都是用的这个函数作为RTX的任务删除。
函数原型: 复制代码 OS_RESULT os_tsk_delete ( OS_TID task_id ); /* 任务ID */ 函数描述: 函数os_tsk_create_use用于实现RTX操作系统的任务删除 u 第1个参数填要删除任务的ID。 u 如果任务删除成功,函数返回OS_R_OK,其余所有情况返回OS_R_NOK,比如所写的任务ID不存在。 使用这个函数要注意以下问题: 1. 如果用往此函数里面填的任务ID是0的话,那么删除的就是当前正在执行的任务,此任务被删除后,RTX会切换到任务就绪列表里面下一个要执行的高优先级任务。 使用举例: 复制代码 /* ********************************************************************************************************** 变量 ********************************************************************************************************** */ static uint64_t AppTaskUserIFStk[512/8]; /* 任务栈 */ /* 任务句柄 */ OS_TID HandleTaskUserIF = NULL; /* ********************************************************************************************************* * 函 数 名: AppTaskDelete * 功能说明: 任务删除 * 形 参: 无 * 返 回 值: 无 ********************************************************************************************************* */ static void AppTaskDelete (void) { HandleTaskUserIF = os_tsk_create_user(AppTaskUserIF, /* 任务函数 */ 1, /* 任务优先级 */ &AppTaskUserIFStk, /* 任务栈 */ sizeof(AppTaskUserIFStk)); /* 任务栈大小,单位字节数 */ if(HandleTaskUserIF!= NULL) { if(os_tsk_delete(HandleTaskUserIF) == OS_R_OK) { HandleTaskLED = NULL; printf("任务AppTaskUser删除成功rn"); } else { printf("任务AppTaskUser删除失败rn"); } } } |
|
|
|
|
|
|
|
|
7.10 空闲任务
几乎所有的小型 RTOS 中都会有一个空闲任务,空闲任务应该属于系统任务,是必须要执行的,用户程序不能将其关闭。不光小型系统中有空闲任务,大型的系统里面也有的,比如WIN7,下面的截图就是 WIN7中的空闲进程。 |
|
|
|
|
|
|
|
|
空闲任务主要有以下几个作用:
u 用户不能让系统一直在执行各个应用任务,这样的话系统利用率就是 100%,系统就会一直的超负荷运行,所以空闲任务很有必要。 u 为了更好的实现低功耗,空闲任务也很有必要,用户可以在空闲任务中实现睡眠,停机等低功耗措施。 RTX操作系统的空闲任务在文件RTX_Conf_CM.c文件里面,源代码如下: 复制代码 /*--------------------------- os_idle_demon ---------------------------------*/ __task void os_idle_demon (void) { /* The idle demon is a system task, running when no other task is ready */ /* to run. The 'os_xxx' function calls are not allowed from this task. */ for (;;) { /* HERE: include optional user code to be executed when no task runs.*/ } } |
|
|
|
|
|
|
|
|
7.11 实验例程说明
7.11.1 STM32F103开发板实验 配套例子: V4-402_RTX实验_任务创建和删除 实验目的: 1. 学习RTX的任务创建和删除。 实验内容: 1. K1按键按下,串口打印。 2. K2按键按下,删除任务AppTaskLED。 3. K3按键按下,重新创建任务AppTaskLED。 4. 各个任务实现的功能如下: AppTaskUserIF任务 :按键消息处理。 AppTaskLED任务 :LED闪烁。 AppTaskMsgPro任务 :消息处理,这里是用作LED闪烁。 AppTaskStart任务 :启动任务,也是最高优先级任务,这里实现按键扫描。 |
|
|
|
|
|
|
|
|
Task Configuration
l Number of concurrent running tasks 允许创建4个任务,实际创建了如下四个任务 AppTaskUserIF任务 :按键消息处理。 AppTaskLED任务 :LED闪烁。 AppTaskMsgPro任务 :消息处理,这里是用作LED闪烁。 AppTaskStart任务 :启动任务,也是最高优先级任务,这里实现按键扫描。 l Number of tasks with user-provided stack 创建的4个任务都是采用自定义堆栈方式。 RTX任务调试信息: |
|
|
|
|
|
|
|
|
程序设计:
u 任务栈大小分配: staticuint64_t AppTaskUserIFStk[512/8]; /* 任务栈 */ staticuint64_t AppTaskLEDStk[256/8]; /* 任务栈 */ staticuint64_t AppTaskMsgProStk[512/8]; /* 任务栈 */ staticuint64_t AppTaskStartStk[512/8]; /* 任务栈 */ 将任务栈定义成uint64_t类型可以保证任务栈是8字节对齐的,8字节对齐的含义就是数组的首地址对8求余等于0。如果不做8字节对齐的话,部分C语言库函数,浮点运算和uint64_t类型数据运算会出问题。 u 系统栈大小分配: |
|
|
|
|
|
|
|
|
RTX初始化:
复制代码 /* ********************************************************************************************************* * 函 数 名: main * 功能说明: 标准c程序入口。 * 形 参: 无 * 返 回 值: 无 ********************************************************************************************************* */ int main (void) { /* 初始化外设 */ bsp_Init(); /* 创建启动任务 */ os_sys_init_user (AppTaskStart, /* 任务函数 */ 4, /* 任务优先级 */ &AppTaskStartStk, /* 任务栈 */ sizeof(AppTaskStartStk)); /* 任务栈大小,单位字节数 */ while(1); } |
|
|
|
|
|
|
|
|
RTX任务创建:
复制代码 /* ********************************************************************************************************* * 函 数 名: AppTaskCreate * 功能说明: 创建应用任务 * 形 参: 无 * 返 回 值: 无 ********************************************************************************************************* */ static void AppTaskCreate (void) { HandleTaskUserIF = os_tsk_create_user(AppTaskUserIF, /* 任务函数 */ 1, /* 任务优先级 */ &AppTaskUserIFStk, /* 任务栈 */ sizeof(AppTaskUserIFStk)); /* 任务栈大小,单位字节数 */ HandleTaskLED = os_tsk_create_user(AppTaskLED, /* 任务函数 */ 2, /* 任务优先级 */ &AppTaskLEDStk, /* 任务栈 */ sizeof(AppTaskLEDStk)); /* 任务栈大小,单位字节数 */ HandleTaskMsgPro = os_tsk_create_user(AppTaskMsgPro, /* 任务函数 */ 3, /* 任务优先级 */ &AppTaskMsgProStk, /* 任务栈 */ sizeof(AppTaskMsgProStk)); /* 任务栈大小,单位字节数 */ } |
|
|
|
|
|
|
|
435 浏览 0 评论
464 浏览 0 评论
450 浏览 0 评论
806 浏览 0 评论
RT-Thread与英飞凌(infineon)合作得板子PSOC 6 板子学习
748 浏览 0 评论
【youyeetoo X1 windows 开发板体验】少儿AI智能STEAM积木平台
17012 浏览 31 评论
/9
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-12-12 08:03 , Processed in 1.046728 second(s), Total 72, Slave 64 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191

淘帖