UcOs-III 源码阅读: os_prio.c

//作用:包含用于管理位图表(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
}

posted @ 2024-10-31 16:12  炽杨  阅读(43)  评论(0)    收藏  举报