chore: migrate project into clean repository

This commit is contained in:
yuuux
2026-08-13 16:50:52 +08:00
commit d1d25a09e7
27405 changed files with 9422808 additions and 0 deletions

View File

@@ -0,0 +1,10 @@
if (DEFINED CONFIG_IRQ_PROXY)
listenai_library_named(irq_proxy)
listenai_library_sources(
irq_proxy.c
dma_irq_proxy.c
func_proxy.c
)
listenai_include_directories(.)
endif()

View File

@@ -0,0 +1,7 @@
menu "irq proxy configuration"
config IRQ_PROXY
bool "irq proxy support"
default n
endmenu

View File

@@ -0,0 +1,29 @@
#include "dma_irq_proxy.h"
#include "dma.h"
#include "log_print.h"
static void DMA_DrvEvent(uint32_t event_info, uint32_t xfer_bytes, uint32_t usr_param)
{
if ( DMA_EVENT_TRANSFER_COMPLETE & (event_info & 0xFF)) {
irq_proxy_trigger(usr_param);
}
}
int32_t dma_irq_proxy_bind(uint8_t ch, irq_proxy_channel_t channel)
{
uint8_t real_ch;
real_ch = dma_channel_reserve(ch, DMA_DrvEvent, channel, DMA_CACHE_SYNC_AUTO);
if (real_ch == DMA_CHANNEL_ANY) {
CLOGE("[FAILED] NO free CP DMA channel!!");
return -1;
}
return 0;
}
int32_t dma_irq_proxy_register_callback(irq_proxy_channel_t ch, irq_proxy_callback_fn callback)
{
irq_proxy_register_callback(ch, callback);
return 0;
}

View File

@@ -0,0 +1,10 @@
#ifndef DMA_IRQ_PROXY_H
#define DMA_IRQ_PROXY_H
#include <stdint.h>
#include "irq_proxy.h"
int32_t dma_irq_proxy_bind(uint8_t ch, irq_proxy_channel_t channel);
int32_t dma_irq_proxy_register_callback(irq_proxy_channel_t ch, irq_proxy_callback_fn callback);
#endif

View File

@@ -0,0 +1,266 @@
#include <string.h>
#include "func_proxy.h"
#include "irq_proxy.h"
#include "log_print.h"
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
// #define LOG_DBG(format, ...) CLOGD(format, ##__VA_ARGS__)
// #define LOG_INF(format, ...) CLOGI(format, ##__VA_ARGS__)
// #define LOG_ERR(format, ...) CLOGE(format, ##__VA_ARGS__)
#define LOG_DBG(format, ...)
#define LOG_INF(format, ...)
#define LOG_ERR(format, ...)
#define FUNC_PROXY_TASK_STACK_SIZE 2048
#define FUNC_PROXY_TASK_PRIORITY configMAX_PRIORITIES - 1
#define FUNC_PROXY_QUEUE_LENGTH 5
#define MAX_FUNC_NAME_LEN 32
#define MAX_FUNC_NUM 16
#define MAX_DATA_SIZE 1024
// 共享内存结构体定义
struct func_proxy_shared_data {
char func_name[MAX_FUNC_NAME_LEN]; // 函数名称
uint8_t data_buf[MAX_DATA_SIZE]; // 数据缓冲区
size_t in_size; // 输入数据大小
size_t out_size; // 输出数据大小
uint32_t call_flag; // 调用标志0=空闲1=请求调用2=调用完成
int32_t result; // 调用结果
uint32_t reserve0;
uint32_t reserve1;
};
// 共享内存基地址与irq_proxy.c中定义相同
// #define MEM_SHARED_BASE 0x2001F000
// // 获取共享内存中的函数代理数据结构
// #define func_proxy_shared ((volatile struct func_proxy_shared_data *)(MEM_SHARED_BASE + sizeof(uint32_t) + sizeof(uint32_t)))
struct func_proxy_shared_data share_data __attribute__((section(".ipc.func_proxy"))) = {0};
volatile struct func_proxy_shared_data * func_proxy_shared = &share_data;
// 函数注册表项
struct func_entry {
char name[MAX_FUNC_NAME_LEN];
func_proxy_handler_t handler;
};
// 函数注册表
static struct func_entry g_func_table[MAX_FUNC_NUM];
static int g_func_count = 0;
// AP执行完成信号量
static SemaphoreHandle_t g_exec_complete_sem;
// 查找函数
static func_proxy_handler_t find_func(const char *name)
{
for (int i = 0; i < g_func_count; i++) {
if (strcmp(g_func_table[i].name, name) == 0) {
return g_func_table[i].handler;
}
}
return NULL;
}
// AP核注册函数处理回调
int32_t func_proxy_register(const char *name, func_proxy_handler_t handler)
{
if (g_func_count >= MAX_FUNC_NUM || strlen(name) >= MAX_FUNC_NAME_LEN) {
return -1;
}
// 检查是否已经注册
if (find_func(name) != NULL) {
return -2;
}
strcpy(g_func_table[g_func_count].name, name);
g_func_table[g_func_count].handler = handler;
g_func_count++;
return 0;
}
// CP核调用AP核函数
int32_t func_proxy_call(const char *name, func_proxy_data_t *in, func_proxy_data_t *out)
{
LOG_INF("[PROXY] Call start: %s", name);
if (strlen(name) >= MAX_FUNC_NAME_LEN) {
LOG_ERR("[PROXY] Function name too long");
return -1;
}
if (in && in->size > MAX_DATA_SIZE) {
return -2;
}
// 等待之前的调用完成
uint32_t wait_count = 0;
while (func_proxy_shared->call_flag != 0) {
wait_count++;
if (wait_count % 1000000 == 0) {
LOG_ERR("[PROXY] Waiting for previous call to complete, flag=%d", func_proxy_shared->call_flag);
}
}
LOG_INF("[PROXY] Previous call completed");
// 设置函数名和输入数据
strcpy((char *)func_proxy_shared->func_name, name);
LOG_INF("[PROXY] Function name set: %s", func_proxy_shared->func_name);
if (in && in->data && in->size > 0) {
memcpy((void *)func_proxy_shared->data_buf, in->data, in->size);
func_proxy_shared->in_size = in->size;
LOG_INF("[PROXY] Input data copied, size: %d", in->size);
} else {
func_proxy_shared->in_size = 0;
LOG_INF("[PROXY] No input data");
}
// 设置期望的输出数据大小
func_proxy_shared->out_size = out ? out->size : 0;
// 设置调用标志
func_proxy_shared->call_flag = 1;
// 通知AP核执行函数
LOG_INF("[PROXY] Triggering AP execution");
irq_proxy_trigger(IRQ_PROXY_CHAN_FUNC_REQUEST);
// 等待AP核执行完成
LOG_INF("[PROXY] Waiting for AP execution");
if (xSemaphoreTake(g_exec_complete_sem, portMAX_DELAY) != pdTRUE) {
LOG_ERR("[PROXY] Failed to take completion semaphore");
return -1;
}
LOG_INF("[PROXY] AP execution completed");
// 获取输出数据
if (out && out->data && func_proxy_shared->out_size > 0) {
size_t copy_size = func_proxy_shared->out_size;
if (copy_size > out->size) {
copy_size = out->size;
}
memcpy(out->data, (const void *)func_proxy_shared->data_buf, copy_size);
out->size = copy_size;
}
// 获取调用结果
int32_t result = func_proxy_shared->result;
// 清除标志
func_proxy_shared->call_flag = 0;
return result;
}
// 函数代理任务句柄
static TaskHandle_t func_proxy_task_handle;
// 函数代理任务
static void func_proxy_task(void *arg)
{
while (1) {
// 等待通知
uint32_t notification;
if (xTaskNotifyWait(0, UINT32_MAX, &notification, portMAX_DELAY) == pdTRUE) {
LOG_INF("[PROXY] Notified handler task");
// 检查调用标志
if (func_proxy_shared->call_flag != 1) {
continue;
}
// 查找函数
func_proxy_handler_t handler = find_func((const char *)func_proxy_shared->func_name);
if (!handler) {
LOG_ERR("[PROXY-AP] Handler not found for: %s", func_proxy_shared->func_name);
func_proxy_shared->result = -1;
func_proxy_shared->out_size = 0;
} else {
// 准备输入输出数据
func_proxy_data_t in = {
.data = func_proxy_shared->in_size > 0 ? (void *)func_proxy_shared->data_buf : NULL,
.size = func_proxy_shared->in_size
};
func_proxy_data_t out = {
.data = (void *)func_proxy_shared->data_buf,
.size = func_proxy_shared->out_size
};
LOG_INF("[PROXY] Calling handler: %s", func_proxy_shared->func_name);
// 执行函数
func_proxy_shared->result = handler(&in, &out);
func_proxy_shared->out_size = out.size;
}
LOG_INF("[PROXY] before IRQ_PROXY_CHAN_FUNC_COMPLETE");
// 设置完成标志
func_proxy_shared->call_flag = 2;
// 通知CP核完成
irq_proxy_trigger(IRQ_PROXY_CHAN_FUNC_COMPLETE);
LOG_INF("[PROXY] IRQ_PROXY_CHAN_FUNC_COMPLETE");
}
}
}
// AP核函数调用中断处理
static int32_t func_proxy_complete_handler(void)
{
// 释放执行完成信号量
BaseType_t need_yield = pdFALSE;
xSemaphoreGiveFromISR(g_exec_complete_sem, &need_yield);
portYIELD_FROM_ISR(need_yield);
return 0;
}
static int32_t func_proxy_handler(void)
{
// 发送通知给处理任务
BaseType_t need_yield = pdFALSE;
xTaskNotifyFromISR(func_proxy_task_handle, 1, eSetBits, &need_yield);
portYIELD_FROM_ISR(need_yield);
return 0;
}
void func_proxy_init(void)
{
// 创建执行完成信号量
g_exec_complete_sem = xSemaphoreCreateBinary();
if (g_exec_complete_sem == NULL) {
LOG_ERR("[PROXY] Failed to create completion semaphore");
return;
}
LOG_INF("[PROXY] Initializing function proxy");
// 初始化函数表
memset(g_func_table, 0, sizeof(g_func_table));
g_func_count = 0;
// 初始化共享内存
volatile struct func_proxy_shared_data *shared = func_proxy_shared;
memset((void *)shared, 0, sizeof(struct func_proxy_shared_data));
LOG_INF("[PROXY] Shared memory initialized at %p", (void *)shared);
// 注册AP执行完成中断处理函数
irq_proxy_register_callback(IRQ_PROXY_CHAN_FUNC_COMPLETE, func_proxy_complete_handler);
// 创建函数代理任务
BaseType_t ret = xTaskCreate(func_proxy_task,
"func_proxy",
FUNC_PROXY_TASK_STACK_SIZE,
NULL,
FUNC_PROXY_TASK_PRIORITY,
&func_proxy_task_handle);
if (ret != pdPASS) {
LOG_ERR("[PROXY] Failed to create function proxy task");
return;
}
LOG_INF("[PROXY] Function proxy task created");
// 注册函数调用处理回调
irq_proxy_register_callback(IRQ_PROXY_CHAN_FUNC_REQUEST, func_proxy_handler);
LOG_INF("[PROXY] Function proxy initialized");
}

View File

@@ -0,0 +1,49 @@
#ifndef FUNC_PROXY_H
#define FUNC_PROXY_H
#include <stdint.h>
#include <stddef.h>
#include "irq_proxy.h"
// 使用irq_proxy.h中定义的通道
#define IRQ_PROXY_CHAN_FUNC_PROXY IRQ_PROXY_CHAN_FUNC_REQUEST
/**
* 函数代理数据结构
*/
typedef struct {
void *data; // 数据指针
size_t size; // 数据大小
} func_proxy_data_t;
/**
* 函数代理处理函数
* @param in: 输入数据
* @param out: 输出数据
* @return: 0成功其他值失败
*/
typedef int32_t (*func_proxy_handler_t)(func_proxy_data_t *in, func_proxy_data_t *out);
/**
* AP核注册函数处理回调
* @param name: 函数名称,必须是全局唯一的
* @param handler: 函数处理回调
* @return: 0成功其他值失败
*/
int32_t func_proxy_register(const char *name, func_proxy_handler_t handler);
/**
* CP核调用AP核函数
* @param name: 函数名称
* @param in: 输入数据
* @param out: 输出数据
* @return: 0成功其他值失败
*/
int32_t func_proxy_call(const char *name, func_proxy_data_t *in, func_proxy_data_t *out);
/**
* 初始化函数代理
*/
void func_proxy_init(void);
#endif /* FUNC_PROXY_H */

View File

@@ -0,0 +1,137 @@
#include "irq_proxy.h"
#include "Driver_MBX.h"
#include <string.h>
#include "log_print.h"
#define IRQ_PROXY_MBX_DEV NULL
#define IRQ_PROXY_MAX_CHANNELS 8
#define IRQ_PROXY_OFFSET 24
#define MEM_SHARED_BASE 0x20040000
#define MEM_SHARED_SIZE 0x1000
// 共享内存结构体定义
struct ap_cp_shared_struct {
uint32_t irq_status;
uint8_t shared_data[MEM_SHARED_SIZE];
uint32_t ack_flag;
};
#define ap_cp_shared ((volatile struct ap_cp_shared_struct *)MEM_SHARED_BASE)
static irq_proxy_device_t g_irq_proxy_devices[IRQ_PROXY_MAX_CHANNELS];
static inline uint32_t co_clz(uint32_t val)
{
uint32_t tmp;
uint32_t shift = 0;
if (val == 0)
{
return 32;
}
tmp = val >> 16;
if (tmp)
{
shift = 16;
val = tmp;
}
tmp = val >> 8;
if (tmp)
{
shift += 8;
val = tmp;
}
tmp = val >> 4;
if (tmp)
{
shift += 4;
val = tmp;
}
tmp = val >> 2;
if (tmp)
{
shift += 2;
val = tmp;
}
tmp = val >> 1;
if (tmp)
{
shift += 1;
}
return (31 - shift);
}
/**
* @brief IRQ代理中断处理函数
* @param event 事件类型
* @param param 通道号
* @return 成功返回0,失败返回负值
*/
static int8_t irq_proxy_handler(uint32_t event, uint32_t param)
{
while (param) {
uint32_t highest_bit = 31 - co_clz(param);
irq_proxy_channel_t channel = highest_bit - IRQ_PROXY_OFFSET;
// 处理当前通道
if (channel < IRQ_PROXY_MAX_CHANNELS) {
irq_proxy_device_t *dev = &g_irq_proxy_devices[channel];
if (dev->callback) {
dev->callback();
}
}
// 清除已处理的bit
param &= ~(1U << highest_bit);
}
return 0;
}
/**
* @brief 初始化IRQ代理
*/
void irq_proxy_init(void)
{
memset(g_irq_proxy_devices, 0, sizeof(g_irq_proxy_devices));
MBX3_Initialize(IRQ_PROXY_MBX_DEV, irq_proxy_handler);
}
/**
* @brief 注册回调函数
* @param channel 通道号
* @param callback 回调函数
* @return 成功返回0,失败返回负值
*/
int32_t irq_proxy_register_callback(irq_proxy_channel_t channel, irq_proxy_callback_fn callback)
{
if (channel >= IRQ_PROXY_MAX_CHANNELS || !callback) {
return -1;
}
g_irq_proxy_devices[channel].callback = callback;
return 0;
}
/**
* @brief 触发指定通道
* @param channel 通道号
* @return 成功返回0,失败返回负值
*/
int32_t irq_proxy_trigger(irq_proxy_channel_t channel)
{
// 参数检查
if (channel >= IRQ_PROXY_MAX_CHANNELS) {
return -1;
}
return MBX_Trigger(IRQ_PROXY_MBX_DEV, channel + IRQ_PROXY_OFFSET);
}

View File

@@ -0,0 +1,25 @@
#ifndef IRQ_PROXY_H
#define IRQ_PROXY_H
#include <stdint.h>
typedef enum {
IRQ_PROXY_CHAN_ROTATE_DMA = 0,
IRQ_PROXY_CHAN_FUNC_REQUEST, // CP请求AP执行函数
IRQ_PROXY_CHAN_FUNC_COMPLETE, // AP通知CP函数执行完成
IRQ_PROXY_CHAN_LVGL_BLEND_DMA, // LVGL blend 用到CPDMA
IRQ_PROXY_CHAN_MAX
} irq_proxy_channel_t;
typedef int32_t (*irq_proxy_callback_fn)(void);
typedef struct {
irq_proxy_callback_fn callback;
} irq_proxy_device_t;
void irq_proxy_init(void);
int32_t irq_proxy_register_callback(irq_proxy_channel_t channel,
irq_proxy_callback_fn callback);
int32_t irq_proxy_trigger(irq_proxy_channel_t channel);
#endif /* IRQ_PROXY_H */