os_sem_trace.c 源码
2026/7/20大约 2 分钟源码参考内核IPC Trace调试
os_sem_trace.c — 信号量追踪
源文件路径: kernel/source/os_sem_trace.c
引用章节: 6.5 IPC Trace
核心机制
os_sem_trace 是 IPC Trace 框架在信号量上的具体应用,通过钩子函数记录每次信号量操作(Post/Wait/Timeout 等),支持 Shell 命令查看追踪记录。
完整源码
/**
***********************************************************************************************************************
* Copyright (c) 2022, 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_sem_trace.c
*
* @brief This file implements the semaphore trace functions.
*
* @revision
* Date Author Notes
* 2022-03-22 OneOS team First Version
***********************************************************************************************************************
*/
#include <os_stddef.h>
#include <os_errno.h>
#include <os_types.h>
#include <os_ipc_hook.h>
#include <os_sem.h>
#include <os_ipc_trace.h>
#include <shell.h>
#include <stdlib.h>
#include <os_sem_trace.h>
#ifdef OS_USING_SEM_TRACE
#ifndef OS_SEM_TRACE_NUM
#define OS_SEM_TRACE_NUM 5 /* 最多追踪 5 个信号量 */
#endif
#if defined(OS_USING_SHELL)
#define SEM_TRACE_DESC_NUM 7
static const char *gs_sem_trace_desc[SEM_TRACE_DESC_NUM] = {
"Post(Success)", /* 0 */
"Wait(Success)", /* 1 */
"Wait(Failure)", /* 2 */
"Wait(Blocking)", /* 3 */
"Post(Full)", /* 4 */
"Post(Awaking)", /* 5 */
"Wait(Timeout)" /* 6 */
};
#endif
static os_ipc_trace_t gs_os_sem_trace[OS_SEM_TRACE_NUM];
/* 通用追踪钩子:记录事件到环形缓冲区 */
static void os_sem_trace_hook(os_semaphore_id sem, void *priv, os_ubase_t len)
{
os_ubase_t i = 0;
os_ipc_trace_item_t trace_data;
if (OS_NULL != priv)
trace_data.desc = *(os_ubase_t *)priv;
trace_data.task = os_get_current_task();
trace_data.irq = os_irq_num();
trace_data.irq |= ((os_is_irq_active() ? 1 : 0) << 31);
for (i = 0; i < OS_SEM_TRACE_NUM; i++)
ipc_trace_hook(&gs_os_sem_trace[i], (os_ubase_t)sem, &trace_data);
}
/* Wait 钩子函数 */
void os_sem_wait_success_hook(os_semaphore_id sem) { /* desc=1 */
os_ubase_t desc = 1; os_sem_trace_hook(sem, &desc, sizeof(os_ubase_t)); }
void os_sem_wait_fail_hook(os_semaphore_id sem) { /* desc=2 */
os_ubase_t desc = 2; os_sem_trace_hook(sem, &desc, sizeof(os_ubase_t)); }
void os_sem_wait_block_hook(os_semaphore_id sem) { /* desc=3 */
os_ubase_t desc = 3; os_sem_trace_hook(sem, &desc, sizeof(os_ubase_t)); }
void os_sem_wait_timeout_hook(os_semaphore_id sem) { /* desc=6 */
os_ubase_t desc = 6; os_sem_trace_hook(sem, &desc, sizeof(os_ubase_t)); }
OS_IPC_HOOK_DEFINE(sem, wait, success, os_semaphore_id);
OS_IPC_HOOK_DEFINE(sem, wait, fail, os_semaphore_id);
OS_IPC_HOOK_DEFINE(sem, wait, block, os_semaphore_id);
OS_IPC_HOOK_DEFINE(sem, wait, timeout, os_semaphore_id);
/* Post 钩子函数 */
void os_sem_post_success_hook(os_semaphore_id sem) { /* desc=0 */
os_ubase_t desc = 0; os_sem_trace_hook(sem, &desc, sizeof(os_ubase_t)); }
void os_sem_post_full_hook(os_semaphore_id sem) { /* desc=4 */
os_ubase_t desc = 4; os_sem_trace_hook(sem, &desc, sizeof(os_ubase_t)); }
void os_sem_post_awake_hook(os_semaphore_id sem) { /* desc=5 */
os_ubase_t desc = 5; os_sem_trace_hook(sem, &desc, sizeof(os_ubase_t)); }
OS_IPC_HOOK_DEFINE(sem, post, success, os_semaphore_id);
OS_IPC_HOOK_DEFINE(sem, post, full, os_semaphore_id);
OS_IPC_HOOK_DEFINE(sem, post, wake, os_semaphore_id);
/* 初始化:注册所有钩子 */
os_err_t os_sem_hook_init(void)
{
OS_IPC_HOOK_ADD(sem, wait, success, os_sem_wait_success_hook);
OS_IPC_HOOK_ADD(sem, wait, fail, os_sem_wait_fail_hook);
OS_IPC_HOOK_ADD(sem, wait, block, os_sem_wait_block_hook);
OS_IPC_HOOK_ADD(sem, wait, timeout, os_sem_wait_timeout_hook);
OS_IPC_HOOK_ADD(sem, post, success, os_sem_post_success_hook);
OS_IPC_HOOK_ADD(sem, post, full, os_sem_post_full_hook);
OS_IPC_HOOK_ADD(sem, post, wake, os_sem_post_awake_hook);
return OS_SUCCESS;
}
OS_INIT_CALL(os_sem_hook_init, OS_INIT_LEVEL_POST_KERNEL, OS_INIT_SUBLEVEL_MIDDLE);
/* Shell 命令: sem_trace_add <sem_id> / sem_trace_del <sem_id> / sem_trace_show */
#if defined(OS_USING_SHELL) && defined(OS_USING_SEM_TRACE) && defined(OS_USING_IPC_TRACE)
SH_CMD_EXPORT(sem_trace_add, os_sem_trace_add, "Add sem trace");
SH_CMD_EXPORT(sem_trace_del, os_sem_trace_del, "Del sem trace");
SH_CMD_EXPORT(sem_trace_show, os_sem_trace_show, "Show Sem trace");
#endif
#endif /* OS_USING_SEM_TRACE */Shell 使用示例
> sem_trace_add 0x20001234
Sem trace has been added successfully
> sem_trace_show
Kobj : 0x20001234 | Name : sensor_sem | Current Record:7
Post(Success) - sensor_task(0x20001000)
Wait(Success) - mqtt_task(0x20001080)
Post(Awaking) - sensor_task(0x20001000)
...