任务
线程和任务其实是一样的,只是名字不同。任务有点像C函数,但是不一样。任务一般是死循环,而且没有返回值。在任务当中可调用函数。
当任务开始运行时,系统会给任务传递一个参数 p_arg,这个参数是void型指针。这个指针是一个通用型指针,可以向任务传递变量地址、数据结构、函数入口等等。有了这个指针就可以创建一些代码完全相同的任务,这些任务仅是参数不同(也就是说,这个任务是通用的)
任务分为两种类型:
- 运行至完成:就是这个任务执行的次数有限,执行完成后就会自动挂起;在ucosIII中,这样的任务运行完成后必须调用OSTaskDel()函数将自己删除。在运行时,创建和删除任务会带来一定的开销,所以这样的任务最好不要太多。频繁的创建和删除任务,存储器会布满碎片,导致有栈空间但是无法使用的现象,通常称作内存泄漏。
- 无限循环:这个任务一直在执行
任务相关资源
- 1、任务代码:这个任务需要做什么
- 2、优先级:该任务的优先级
- 3、CPU寄存器:每个任务都有一套自己的寄存器,认为自己可以独占整个CPU
- 4、任务栈:任务栈永远在RAM中,所有任务栈加起来不可超过MCU的RAM否则就会报错
- 5、任务可访问全局变量
- 6、IO设备:一个任务可访问一或多个输入输出设备
任务优先级分配
用户可自定义最大优先级,在os_cfg.h修改。
- 重要任务的优先级设置高一点
- 一般把执行频繁程度高的任务的优先级设置得比较高
- 一般把控制任务优先级设置得比较高,因为控制任务要求响应速度快
根据实际情况分析
栈空间大小的确定
所有函数嵌套调用对存储器的总需求,加上调用这些函数传递这些参数所需的储存容量,加上嵌套的中断处理函数所需要的用来存储CPU运行环境的存储容量,再加上这些中断处理函数所需要的其他各种存储容量,就是这个任务的最小栈空间。
- 可以一开始给一片很大的空间,然后监测其运行一段时间,所需要的实际空间
- 个人使用一个任务栈空间一般给1K
如果程序的运行结果很奇怪,那就要怀疑栈空间是否太小了
一旦分配了栈空间,就不要释放已分配的空间
任务栈溢出检测
-
具有堆栈溢出的检测的CPU
在创建线程的时候,有一个参数控制块成员StkLimitPrt,设置堆栈是否溢出的限位。如果高于或低于这个值就会产生异常,堆栈溢出限位要设置在堆栈有效区域内,还要留有足够的栈空间让超出堆栈限位时能够处理异常 -
计算空闲堆栈的数量
首先在创建任务时,把栈的空间全部清零
然后让低优先级的任务遍历每个已创建任务的栈空间,计算为0时的数值项的个数,发现第一个不为0时,就停止遍历操作计算堆栈使用量,根据检测结果,给任务调整栈空间大小,分配合理的栈空间,重新编译。UCOSIII提供OSTaskStkChk()函数帮组完成这一计算