ARM官方《CMSIS-RTOS教程》之线程的管理和优先级Thread Management and Priority

来源:互联网 发布:java phantomjs pdf 编辑:程序博客网 时间:2024/05/17 09:00

这篇文章咱也开始尝尝鲜,用Markdown编辑,主要是三个原因:
1. 原来每次写一段都要拖到网页最下面点击保存草稿,这个MD编辑器保存按钮在上面,很方便;
2. MD右侧有预览,不用每次切换到博客刷新去看;
3. 写完一大篇文章已经很累了,还要回头用鼠标挨个搞段落、加粗等等,干脆在写文字的时候顺带完成就省事了,如果不去搞段落别人阅读起来又很头大。
此外在翻译ARM官方文档的时候,我有强烈的感觉作者也是用MD编辑器搞的:)

下面进入正题:

线程的管理和优先级Thread Management and Priority

在创建线程的时候就会给它分配一个优先级。RTOS的调度器靠线程的优先级来决定要调度哪个线程运行。假如同时有几个线程都准备运行,优先级最高的线程就会进入运行状态。如果一个高优先级线程处于准备运行状态,它就会抢占正在运行的低优先级线程。有一点非常重要,高优先级线程占用CPU运行的时候永远不会停止,除非有RTOS API调用来阻塞它,或者有更高优先级的线程来抢占它。线程的优先级在线程结构体中定义,下面列出可用的优先级定义,其中一般默认的优先级是osPriorityNormal。

CMSIS-RTOS Priority Levels osPriorityIdle osPriorityLow osPriorityBelowNormal osPriorityNormal osPriorityAboveNormal osPriorityHigh osPriorityRealTime osPriorityError

一旦线程开始运行,我们就可以使用几个OS系统调用来管理线程。当然也可以通过其他函数或在它自己代码里面提升或者降低它的优先级。

osStatus osThreadSetPriority(threadID, priority);osPriority osThreadGetPriority(threadID);

在创建线程之后,也可以通过它自己或者其他活跃的线程来删除它。再强调一次,我们使用thread ID而不是它的函数名来操作。

osStatus = osThreadTermainate(threadID1);

另外,同优先级线程间的切换有一种特殊情况,就是使用协作(co-operative)切换方式:

osStatus osThreadYield();//切换到另外一个准备运行的线程

练习和管理线程II

在这个练习里我们将看到如何给线程分配不同的优先级,然后如何动态地创建和终结线程。

打开”Ex 2 and 3 Threads”工程(上篇文章已经安装过这个例程了,这里只需要找到并打开–译者注)
把LED线程2的优先级改成AboveNormal:

osThreadDef(led_thread2, osPriorityAboveNormal, 1, 0);osThreadDef(led_thread1, osPriorityNormal, 1, 0);

build编译工程并启动debug仿真。
启动代码全速运行。
打开菜单栏Debug->OS Support->Event Viewer window:
这里写图片描述

从上图我们可以看到thread2一直在运行,而thread1完全没动静。
返回源文件,可以看到led_thread1完全为灰色,表示根本运行不到:
这里写图片描述

出现这个现象的原因就是led_thread1是正常优先级而led_thread2是更高的优先级,所以它把线程1给抢占了。更绝的是它永远不会阻塞,所以它将永远运行,而线程1永远没有机会。
虽然在这个例子中这个问题很容易看出来,但对于刚接触RTOS的新手来说却是普遍会犯的错误。

0 0