举报
FlashDB的Flash操作接口(如write函数)在默认实现中是同步的,这意味着大量数据写入时会导致系统阻塞。但你可以通过以下方法实现异步操作,避免阻塞:
构建异步框架:
typedef struct {
long offset;
uint8_t *buf; // 需动态分配内存
size_t size;
// 可添加回调函数字段
} flash_operation_t;
// 创建任务队列(线程安全)
static rt_mailbox_t op_mailbox; // RT-Thread示例修改write函数为异步:
static int write_async(long offset, const uint8_t *buf, size_t size) {
// 动态复制数据(避免原buf被修改)
uint8_t *buf_copy = rt_malloc(size);
if (!buf_copy) return -RT_ENOMEM;
memcpy(buf_copy, buf, size);
// 创建操作请求
flash_operation_t op = {
.offset = offset,
.buf = buf_copy,
.size = size
};
// 发送到队列(非阻塞)
if (rt_mb_send(op_mailbox, (rt_ubase_t)&op) != RT_EOK) {
rt_free(buf_copy); // 失败则释放内存
return -RT_ERROR;
}
return RT_EOK; // 立即返回
}后台任务处理实际写入:
static void flash_worker_thread(void *param) {
while (1) {
flash_operation_t *op;
// 阻塞等待任务
rt_mb_recv(op_mailbox, (rt_ubase_t*)&op, RT_WAITING_FOREVER);
// 实际Flash操作(同步)
for (size_t i = 0; i < op->size; i += 4) {
uint32_t data = *((uint32_t*)(op->buf + i));
HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD,
stm32_onchip_flash.addr + op->offset + i,
data);
}
rt_free(op->buf); // 释放内存
// 可添加回调通知完成
}
}初始化异步框架:
void async_flash_init(void) {
// 创建邮箱
op_mailbox = rt_mb_create("flash_mb", 10, RT_IPC_FLAG_FIFO);
// 启动后台线程
rt_thread_t thread = rt_thread_create("flash_worker", flash_worker_thread,
RT_NULL, 2048, 15, 10);
rt_thread_startup(thread);
}数据一致性:
内存管理:
buf_copy,避免原数据被修改。rt_free(op->buf))。错误处理:
flash_worker_thread中检查Flash操作结果(如HAL状态)。线程安全:
性能权衡:
如果不想重构为异步,可优化同步写入:
static int write(long offset, const uint8_t *buf, size_t size) {
for (size_t i = 0; i < size; i += 4) {
// 每次写入4字节
uint32_t data = *((uint32_t*)(buf + i));
HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD,
stm32_onchip_flash.addr + offset + i,
data);
// 每写N次主动让出CPU(需RTOS支持)
if ((i % 128) == 0) rt_thread_yield();
}
return 0;
}根据系统复杂度需求选择合适的方案。异步改造需处理数据生命周期,但能显著提升系统响应能力。
举报
更多回帖