arch_misc.c
2026/7/20大约 3 分钟附录源码附录
arch_misc.c
路径: arch\arm\armv7m\arch_misc.c
功能: ARM Cortex-M 架构相关的杂项工具函数实现。提供 os_ffs(Find First Set,从低位找第一个置 1 的位)、os_fls(Find Last Set,从高位找第一个置 1 的位)和 os_get_current_task_sp(获取当前任务栈指针)三个函数。
核心函数:
| 函数 | 说明 |
|---|---|
os_ffs | 查找最低位 1 的位置(从 1 开始计数,0 返回 0),ARMCC 用汇编 RBIT+CLZ 实现,GCC 用 __builtin_ffs |
os_fls | 查找最高位 1 的位置(从 1 开始计数,32bit 最高位为 32),纯 C 二分查找实现 |
os_get_current_task_sp | 获取当前任务栈指针(PSP),通过 MRS PSP 指令读取 |
关键设计点:
- os_ffs 多编译器支持: ARMCC(
__CC_ARM)使用内联汇编RBIT + CLZ实现高效位反转查找,GCC/Clang 使用内置函数__builtin_ffs - os_fls 纯 C 实现: 使用二分查找法(每次折半检查高位),无需汇编,跨编译器和架构通用
- os_get_current_task_sp: 直接读取 PSP(进程栈指针),用于任务上下文保存和栈检测
/**
***********************************************************************************************************************
* Copyright (c) 2020, China Mobile Communications Group Co.,Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* @file os_arch_misc.c
*
* @brief This file provides misc related functions under the ARMv7-M architecture.
*
* @revision
* Date Author Notes
* 2021-01-12 OneOS Team First version.
***********************************************************************************************************************
*/
#include <oneos_config.h>
#include <os_types.h>
#if defined(__CC_ARM)
/**
* ARMCC 内联汇编实现 os_ffs
* 算法:RBIT(位反转) + CLZ(前导零计数) + 1
* 例:value=0x08 (bit3) → RBIT=0x10000000 → CLZ=0 → +1=1 → 返回 4
*/
__asm int32_t os_ffs(uint32_t value)
{
CMP R0, #0x00 /* 检查是否为 0 */
BEQ exit /* 0 则返回 0 */
RBIT R0, R0 /* 位反转 */
CLZ R0, R0 /* 计算前导零 */
ADDS R0, R0, #0x01 /* 加 1(从 1 开始计数) */
exit
BX LR
}
/**
* 获取当前任务栈指针(PSP = Process Stack Pointer)
*/
__asm void *os_get_current_task_sp(void)
{
MRS R0, PSP /* 读取 PSP 到 R0(返回值) */
BX LR
}
#elif defined(__GNUC__) || defined(__CLANG_ARM)
/**
* GCC/Clang 使用内置函数实现 os_ffs
* __builtin_ffs(0) = 0, __builtin_ffs(1) = 1, __builtin_ffs(8) = 4
*/
int32_t os_ffs(uint32_t value)
{
return __builtin_ffs(value);
}
/**
* 获取当前任务栈指针(PSP)
* 使用内联汇编读取 PSP 寄存器
*/
void *os_get_current_task_sp(void)
{
register void *result;
__asm__ __volatile__(
" MRS %0, PSP\n" /* 读取 PSP */
: "=r"(result)); /* 输出到 result */
return result;
}
#endif
/**
* 查找最高位 1 的位置(Find Last Set)
* 使用二分查找法,逐级检查高位
*
* 例:value=0x80000000 → 返回 32
* value=0x00000001 → 返回 1
* value=0x00000000 → 返回 0
*/
int32_t os_fls(uint32_t value)
{
int32_t pos;
pos = 32;
if (!value)
{
pos = 0;
}
else
{
/* 检查 bit31-bit16 */
if (!(value & 0xFFFF0000U))
{
value <<= 16;
pos -= 16;
}
/* 检查 bit31-bit24 */
if (!(value & 0xFF000000U))
{
value <<= 8;
pos -= 8;
}
/* 检查 bit31-bit28 */
if (!(value & 0xF0000000U))
{
value <<= 4;
pos -= 4;
}
/* 检查 bit31-bit30 */
if (!(value & 0xC0000000U))
{
value <<= 2;
pos -= 2;
}
/* 检查 bit31 */
if (!(value & 0x80000000U))
{
value <<= 1;
pos -= 1;
}
}
return pos;
}