//作用:包含用于管理位图表(bitmap table)的代码,该位图表用于跟踪哪些任务已准备好运行,请参阅“就绪列表”。 如果使用的CPU提供位清除、置1和测试指令以及计数前导零指令,则可以用汇编 源文件等效替代该文件,以提高性能;
/*
*********************************************************************************************************
* uC/OS-III
* The Real-Time Kernel
*
* Copyright 2009-2022 Silicon Laboratories Inc. www.silabs.com
*
* SPDX-License-Identifier: APACHE-2.0
*
* This software is subject to an open source license and is distributed by
* Silicon Laboratories Inc. pursuant to the terms of the Apache License,
* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
*
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* 优先级管理
*
* 文件 : os_prio.c
* 版本 : V3.08.02
*********************************************************************************************************
*/
#define MICRIUM_SOURCE
#include "os.h"
#ifdef VSC_INCLUDE_SOURCE_FILE_NAMES
const CPU_CHAR *os_prio__c = "$Id: $";
#endif
/*
************************************************************************************************************************
* 初始化优先级列表
*
* 描述: 此函数由 uC/OS-III 调用,用于初始化就绪优先级列表。
*
* 参数: 无
*
* 返回值: 无
*
* 注意: 此函数是 uC/OS-III 的内部函数,您的应用程序不应调用它。
************************************************************************************************************************
*/
void OS_PrioInit(void)
{
CPU_DATA i;
/* 清除位图表 ... 没有任务就绪 */
for (i = 0u; i < OS_PRIO_TBL_SIZE; i++) {
OSPrioTbl[i] = 0u;
}
#if (OS_CFG_TASK_IDLE_EN == 0u)
OS_PrioInsert((OS_PRIO)(OS_CFG_PRIO_MAX - 1u)); /* 插入本应是空闲任务的优先级 */
#endif
}
/*
************************************************************************************************************************
* 获取最高优先级等待任务
*
* 描述: 此函数由其他 uC/OS-III 服务调用,用于确定等待事件的最高优先级任务。
*
* 参数: 无
*
* 返回值: 等待事件的最高优先级任务的优先级
*
* 注意: 1) 此函数是 uC/OS-III 的内部函数,您的应用程序不得调用它。
************************************************************************************************************************
*/
OS_PRIO OS_PrioGetHighest(void)
{
#if (OS_CFG_PRIO_MAX <= (CPU_CFG_DATA_SIZE * 8u)) /* 优化适用于少于一个字长的优先级数量 */
return ((OS_PRIO)CPU_CntLeadZeros(OSPrioTbl[0]));
#elif (OS_CFG_PRIO_MAX <= (2u * (CPU_CFG_DATA_SIZE * 8u))) /* 优化适用于两个字长的优先级数量 */
if (OSPrioTbl[0] == 0u) {
return ((OS_PRIO)((OS_PRIO)CPU_CntLeadZeros(OSPrioTbl[1]) + (CPU_CFG_DATA_SIZE * 8u)));
} else {
return ((OS_PRIO)((OS_PRIO)CPU_CntLeadZeros(OSPrioTbl[0])));
}
#else
CPU_DATA *p_tbl;
OS_PRIO prio;
prio = 0u;
p_tbl = &OSPrioTbl[0];
while (*p_tbl == 0u) { /* 在位图表中查找最高优先级 */
prio = (OS_PRIO)(prio + (CPU_CFG_DATA_SIZE * 8u)); /* 计算每个 CPU_DATA 入口的步长 */
p_tbl++;
}
prio += (OS_PRIO)CPU_CntLeadZeros(*p_tbl); /* 查找入口中第一个设置的位的位置 */
return (prio);
#endif
}
/*
************************************************************************************************************************
* 插入优先级
*
* 描述: 此函数用于在优先级表中插入一个优先级。
*
* 参数: prio 要插入的优先级
*
* 返回值: 无
*
* 注意: 1) 此函数是 uC/OS-III 的内部函数,您的应用程序不得调用它。
************************************************************************************************************************
*/
void OS_PrioInsert(OS_PRIO prio)
{
#if (OS_CFG_PRIO_MAX <= (CPU_CFG_DATA_SIZE * 8u)) /* 优化适用于少于一个字长的优先级数量 */
OSPrioTbl[0] |= (CPU_DATA)1u << (((CPU_CFG_DATA_SIZE * 8u) - 1u) - prio);
#elif (OS_CFG_PRIO_MAX <= (2u * (CPU_CFG_DATA_SIZE * 8u))) /* 优化适用于两个字长的优先级数量 */
if (prio < (CPU_CFG_DATA_SIZE * 8u)) {
OSPrioTbl[0] |= (CPU_DATA)1u << (((CPU_CFG_DATA_SIZE * 8u) - 1u) - prio);
} else {
OSPrioTbl[1] |= (CPU_DATA)1u << (((CPU_CFG_DATA_SIZE * 8u) - 1u) - (prio - (CPU_CFG_DATA_SIZE * 8u)));
}
#else
CPU_DATA bit_nbr;
OS_PRIO ix;
ix = (OS_PRIO)(prio / (CPU_CFG_DATA_SIZE * 8u));
bit_nbr = (CPU_DATA)prio & ((CPU_CFG_DATA_SIZE * 8u) - 1u);
OSPrioTbl[ix] |= (CPU_DATA)1u << (((CPU_CFG_DATA_SIZE * 8u) - 1u) - bit_nbr);
#endif
}
/*
************************************************************************************************************************
* 移除优先级
*
* 描述: 此函数用于从优先级表中移除一个优先级。
*
* 参数: prio 要移除的优先级
*
* 返回值: 无
*
* 注意: 1) 此函数是 uC/OS-III 的内部函数,您的应用程序不得调用它。
************************************************************************************************************************
*/
void OS_PrioRemove(OS_PRIO prio)
{
#if (OS_CFG_PRIO_MAX <= (CPU_CFG_DATA_SIZE * 8u)) /* 优化适用于少于一个字长的优先级数量 */
OSPrioTbl[0] &= ~((CPU_DATA)1u << (((CPU_CFG_DATA_SIZE * 8u) - 1u) - prio));
#elif (OS_CFG_PRIO_MAX <= (2u * (CPU_CFG_DATA_SIZE * 8u))) /* 优化适用于两个字长的优先级数量 */
if (prio < (CPU_CFG_DATA_SIZE * 8u)) {
OSPrioTbl[0] &= ~((CPU_DATA)1u << (((CPU_CFG_DATA_SIZE * 8u) - 1u) - prio));
} else {
OSPrioTbl[1] &= ~((CPU_DATA)1u << (((CPU_CFG_DATA_SIZE * 8u) - 1u) - (prio - (CPU_CFG_DATA_SIZE * 8u))));
}
#else
CPU_DATA bit_nbr;
OS_PRIO ix;
ix = (OS_PRIO)(prio / (CPU_CFG_DATA_SIZE * 8u));
bit_nbr = (CPU_DATA)prio & ((CPU_CFG_DATA_SIZE * 8u) - 1u);
OSPrioTbl[ix] &= ~((CPU_DATA)1u << (((CPU_CFG_DATA_SIZE * 8u) - 1u) - bit_nbr));
#endif
}