Files
arcs/arcs-sdk/drivers/lisa_device/lisa_device.c
2026-08-13 16:50:52 +08:00

268 lines
6.5 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* Copyright (c) 2025, LISTENAI
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file lisa_device.c
* @brief LISA 设备框架 - 设备管理核心实现
*/
#include "lisa_device.h"
#include <lisa_mutex.h>
#include <lisa_time.h>
#include <string.h>
#define LOG_TAG "lisa_device"
#include <lisa_log.h>
/* ===== 链接器符号声明 ===== */
extern lisa_device_registry_entry_t __lisa_device_registry_start[];
extern lisa_device_registry_entry_t __lisa_device_registry_end[];
/* ===== 全局变量 ===== */
static lisa_device_t *device_list_head = NULL;
static uint32_t device_count = 0;
static bool manager_initialized = false;
static lisa_mutex_t *device_mutex = NULL;
/* ===== 内部辅助函数 ===== */
/**
* @brief 验证设备指针有效性
*/
static inline bool is_device_valid(const lisa_device_t *dev)
{
return (dev != NULL && dev->name != NULL);
}
/**
* @brief 内部设备查找函数 (不增加引用计数)
* @note 仅供内部使用
*/
static lisa_device_t *find_device_by_name(const char *name)
{
if (!name) {
return NULL;
}
if (device_mutex) {
lisa_mutex_lock(device_mutex, LISA_WAIT_FOREVER);
}
lisa_device_t *dev = device_list_head;
while (dev) {
if (strcmp(dev->name, name) == 0) {
if (device_mutex) {
lisa_mutex_unlock(device_mutex);
}
return dev;
}
dev = dev->next;
}
if (device_mutex) {
lisa_mutex_unlock(device_mutex);
}
return NULL;
}
/**
* @brief 内部设备注册函数
* @note 仅在 lisa_device_init 中使用
*/
static int register_device_internal(lisa_device_t *device)
{
if (!is_device_valid(device)) {
return LISA_DEVICE_ERR_INVALID;
}
/* 检查是否已存在 */
if (find_device_by_name(device->name)) {
return LISA_DEVICE_ERR_EXISTS;
}
/* 添加到链表头 */
device->next = device_list_head;
device_list_head = device;
device_count++;
/* 初始化设备状态 */
device->state = LISA_DEVICE_STATE_UNINITIALIZED;
memset(&device->stats, 0, sizeof(device->stats));
return LISA_DEVICE_OK;
}
/* ========================================================================
* 设备管理接口实现
* ======================================================================== */
int lisa_device_init(void)
{
if (manager_initialized) {
return device_count;
}
/* 初始化锁 */
device_mutex = lisa_mutex_create();
if (device_mutex == NULL) {
LISA_LOGE(LOG_TAG, "Failed to create mutex");
return -1;
}
lisa_device_registry_entry_t *entry_start = __lisa_device_registry_start;
lisa_device_registry_entry_t *entry_end = __lisa_device_registry_end;
/* 计算设备数量 */
size_t count = entry_end - entry_start;
if (count == 0) {
manager_initialized = true;
return 0;
}
/* 注册所有设备 */
int registered = 0;
for (size_t i = 0; i < count; i++) {
lisa_device_registry_entry_t *entry = &entry_start[i];
if (!entry->device) {
continue;
}
/* 初始化函数必须存在 */
if (!entry->init_fn) {
/* 没有初始化函数,不符合规范,跳过 */
continue;
}
/* 先注册设备到管理器(状态为 UNINITIALIZED */
if (register_device_internal(entry->device) != LISA_DEVICE_OK) {
continue;
}
/* 记录初始化开始时间 */
uint64_t start_time = lisa_os_get_tick_ms();
/* 调用初始化函数 */
int init_ret = entry->init_fn();
/* 记录初始化结束时间和耗时 */
uint64_t end_time = lisa_os_get_tick_ms();
entry->device->stats.init_timestamp = (uint32_t)end_time;
entry->device->stats.init_time = (uint32_t)(end_time - start_time);
/* 记录初始化返回值到统计信息 */
entry->device->stats.init_result = init_ret;
/* 根据返回值设置状态 */
if (init_ret == 0) {
/* 初始化成功 */
entry->device->state = LISA_DEVICE_STATE_INITIALIZED;
} else {
/* 初始化失败,标记为错误状态 */
entry->device->state = LISA_DEVICE_STATE_ERROR;
}
registered++;
}
manager_initialized = true;
return registered;
}
lisa_device_t *lisa_device_get(const char *name)
{
lisa_device_t *dev = find_device_by_name(name);
/* 统计引用次数:每次成功获取设备时,引用计数 +1 */
if (dev) {
if (device_mutex) {
lisa_mutex_lock(device_mutex, LISA_WAIT_FOREVER);
}
dev->stats.ref_count++;
if (device_mutex) {
lisa_mutex_unlock(device_mutex);
}
}
return dev;
}
bool lisa_device_ready(const lisa_device_t *dev)
{
if (dev == NULL) {
/* 设备指针无效 */
return false;
}
if (dev->state != LISA_DEVICE_STATE_INITIALIZED) {
/* 设备未就绪(未初始化或处于错误状态) */
return false;
}
return true;
}
/* ========================================================================
* 查询接口实现
* ======================================================================== */
uint32_t lisa_device_get_count(void)
{
return device_count;
}
void lisa_device_get_stats(const lisa_device_t *dev, lisa_device_stats_t *stats)
{
if (!is_device_valid(dev) || !stats) {
return;
}
memcpy(stats, &dev->stats, sizeof(lisa_device_stats_t));
}
void lisa_device_reset_stats(lisa_device_t *dev)
{
if (!is_device_valid(dev)) {
return;
}
memset(&dev->stats, 0, sizeof(lisa_device_stats_t));
}
/* ========================================================================
* 遍历接口实现
* ======================================================================== */
int lisa_device_foreach(lisa_device_iterator_cb callback, void *user_data)
{
if (!callback) {
return LISA_DEVICE_ERR_INVALID;
}
if (device_mutex) {
lisa_mutex_lock(device_mutex, LISA_WAIT_FOREVER);
}
lisa_device_t *dev = device_list_head;
int count = 0;
while (dev && callback) {
count++; /* 先计数当前设备 */
int ret = callback(dev, user_data);
if (ret != 0) {
break; /* 回调返回非0停止遍历 */
}
dev = dev->next;
}
if (device_mutex) {
lisa_mutex_unlock(device_mutex);
}
return count;
}