抢占式调度一般是基于优先级(priority)的调度。《FreeRTOS的任务调度算法优化实现》这篇文章中提到FreeRTOS是通过循环遍历的方法查找最高优先级任务,而Ucos采用的是位图(bitmap)算法查找最高优先级任务。调度器是RTOS的核心模块运行频繁,因此其代码设计上要运行速度快开销少才能满足RTOS的实时性要求。
位图(bitmap)的优先级算法时间复杂度为O(1),无论系统中有多少优先级和多少个任务,都可以在恒定的时间内找到最高优先级的任务。参考《FreeRTOS的任务调度算法优化实现》和《uCos中的任务机制和优先级位图算法》这两篇文章来实现一个支持256个优先级任务调度的位图算法。
一、位图算法设计
通过宏OS_TASK_MAX_PRIORITIES来配置系统可支持的最大优先级数量,优先级数值越小,优先级数值越高,即0的优先级最高,255的优先级最低。
#define OS_TASK_MAX_PRIORITIES 255 //Max value is 255
STM32是32位的单片机,一个int型数据由32个bit组成,因此存储256个数据需要(256/32)个int数据,位图结构体设计如下,用bitLevel中bit的位置来标识mapTbl数组中非零元素的位置。
#define OS_BIT_MAP_TBL_SIZE ((OS_TASK_MAX_PRIORITIES >> 5) + 1)
typedef struct STRUCT_BIT_MAP
{
UINT32 mapTbl[OS_BIT_MAP_TBL_SIZE];
UINT8 bitLevel;
}BitMap,*BitMapPtr;
位图初始化函数如下
/**********************************************************************************************
* @brief
*
* @param None
* @retval None
**********************************************************************************************/
void BitMapInit(BitMapPtr pBitMap)
{
for(UINT8 i = 0; i < OS_BIT_MAP_TBL_SIZE; i++)
{
pBitMap->mapTbl[i] = 0;
}
pBitMap->bitLevel = 0;
}
位图置位函数中bitLevel变量置位规则如下:0-31的优先级被置位即mapTbl数组的第一个元素不为0,则bitLevel的bit0被置位;32-64的优先级被置位即mapTbl数组的第二个元素不为0,则bitLevel的bit1被置位;其余优先级设置时以此类推。
/**********************************************************************************************
* @brief
*