0. 前言
最近在自己从0搭建一套系统,用到了电流电压采样,按键,Led,CAN,485,EEPROM,一些GPIO等。系统中使用了RTOS,设计的时候需要考虑各个线程优先级的安排,在优快云上搜索发现这方面的内容很少,于是决定简单写一下自己的思考过程,不一定正确,但是希望抛砖引玉,能够对看到文章的人有所帮助。
可能很多人设计优先级的时候是按照其他例程或者是公司常用惯例来进行设计,大部分情况没有错。但是需求不同,可能原有的设计并不完全适用。我们应该抓住系统实际需求,特别是根据实时性的需求,来考虑各个线程的优先级。
1. 案例分析
以我此次项目为例。该产品功能不太复杂,核心业务功能是通过几个外部信号输入和采样计算的判断,输出一些引脚动作。该过程实时性要求最高,动作一旦触发,整个计算判断的时间不能超过20ms。
首先划分和设计了一下本系统的各个功能模块,如下表所示,系统的线程基本也按照下表划分。
功能模块 | 功能说明 |
采样和数据计算 | 采样电流电压值,并且计算电流电压的有效值,过零点等内容 |
输入信号滤波 | 因为产品应用在一个工业场景,所以引脚输入信号肯定要有一个滤波 |
关键业务任务 | 触发后要求20ms内完成,实时性要求高,动作时需要输入信号和采样信号和CAN数据帧的响应信号作为动作执行依据 |
485通信处理 | 作为从站,响应通讯请求。可实现动作控制,状态查询,参数设置等功能。 |
CAN通信处理 | 作为主站,核心业务动作时,向其他从站发送数据帧,实现动作同步。 |
按键处理 | 可实现单击、双击,长按等按键功能 |
LED灯处理 | 可实现LED暗灭和闪烁功能 |
系统状态机和消息处理 | 维护整个系统的状态机,并且处理各类来自按键, |
数据存储 | 485接收系统参数后,在EEPROM中存储 |
2. 思考过程
设计优先级排列的,优先从核心业务逻辑和功能的实时性要求来考虑,我的思考过程是这样的:
- 关键业务任务:
- 这个是系统的关键业务,实时性要求很高,因此要作为一个抓手优先考虑,假设其优先级设置为X。关键业务的过程中需要采样信号的计算,输入信号和CAN响应作为动作条件。因此这三个任务线程的优先级都应该比关键业务高。
- 采样和数据计算
- OS_TICK的设置为1ms,而实际中由于产品需要电流电压有效值,频率,过零点等计算,需要较高的采样频率。软件中采样周期设置为100us,采样和数据计算直接使用硬件定时器来触发,这样采样频率是稳定的,实时性高,计算精度也高。
- 输入信号滤波:输入信号滤波其实是动作触发的依据,同时也是关键业务中使用到的判断依据,不过精度要求低于采样,没有使用硬件定时器,使用线程中延时,优先级设置可以设置为X-1。(当然也可以使用硬件或者软件定时器触发)
- CAN通信处理:由于CAN也是关键业务中的重要一环,因此优先级也不能低于关键业务。但是由于CAN在业务中只需要确认其他节点的响应,可以在接收中断中实现,因此也不再设计单独的线程。
- 系统状态机和消息处理
- 接下来分析系统状态机和消息处理任务,关键业务是否触发需要在这个任务中根据各类信号综合决定,但是设计优先级肯定低于关键业务。因为关键业务执行的时候,并不希望被打断或者重新触发,因此可以把这个任务优先级设置为X+5。
- 485和按键处理中收到的系统消息的是在系统状态机和消息处理任务中处理,是状态机的处理依据,所以优先级比其要高。但他们本身是一个低频事件,不希望打扰到关键业务的执行,所以就设定比关键业务X+3。
- LED的实时性基本没有要求,仅给用户一个提醒功能,重要性也很低。因此优先级可以最低,设定为X+7。
- 数据存储任务
- 使用外部EEPROM来实现数据存储,I2C总线也有一定的实时性要求。由于是由485触发的事件,因此同样优先级不可能高于关键业务。但是优先级和485处理任务哪个更高呢?应该是数据存储任务更高。可以如此考虑,系统接收到一条485指令后,就开始存储数据,数据存储完成项以后,再进行指令的答复。因此数据存储任务一旦触发,要优先完成。因此数据存储的优先级要比485高。
3. 最终优先级安排(由高到低排列)
优先级 | 任务(线程) |
硬件中断 | 采样和数据计算 |
硬件中断 | CAN通信处理 |
2 | 输入信号滤波 |
5 | 关键业务 |
6 | 数据存储 |
7 | 485处理 |
7 | 按键处理 |
10 | 系统状态机和消息处理 |
12 | LED |