在CYW20829上同时使用全双工UART(用于日志输出)和I2C Master时,添加UART接收回显功能后导致日志输出异常,可能是由于阻塞式读取占用CPU资源或中断冲突所致。以下是解决步骤和代码修改建议:
问题:cyhal_uart_getc(&cy_retarget_io_uart_obj, &read_data, 0)使用非阻塞模式(超时=0),但频繁轮询可能导致CPU负载过高,影响其他任务(如I2C通信)。
改进:改用事件驱动接收(中断回调),避免轮询占用资源:
// 注册回调函数
cyhal_uart_register_callback(&cy_retarget_io_uart_obj, uart_rx_handler, NULL);
cyhal_uart_enable_event(&cy_retarget_io_uart_obj, CYHAL_UART_IRQ_RX_NOT_EMPTY, CYHAL_ISR_PRIORITY_DEFAULT, true); // 中断回调处理接收
void uart_rx_handler(void *arg, cyhal_uart_event_t const *event)
{
if (event->event_type & CYHAL_UART_IRQ_RX_NOT_EMPTY) {
uint8_t data;
if (CY_RSLT_SUCCESS == cyhal_uart_getc(&cy_retarget_io_uart_obj, &data, 0)) {
// 回显字符(非阻塞方式)
cyhal_uart_putc(&cy_retarget_io_uart_obj, data);
// 其他处理逻辑
}
}
}cyhal_uart_putc()回显可能阻塞日志输出。方案:将回显数据存入队列,在后台(如主循环)发送:
QueueHandle_t uart_tx_queue; // FreeRTOS队列
// 在回调中入队数据
if (xQueueSendFromISR(uart_tx_queue, &data, pdFALSE) != pdTRUE) {
// 队列满时丢弃数据(或扩展队列)
}
// 主循环中发送数据
void task_uart_tx(void *arg) {
uint8_t data;
while (1) {
if (xQueueReceive(uart_tx_queue, &data, portMAX_DELAY)) {
cyhal_uart_putc(&cy_retarget_io_uart_obj, data);
}
}
} // UART中断优先级设为高(数值越低优先级越高)
cyhal_uart_set_irq_priority(&cy_retarget_io_uart_obj, CYHAL_ISR_PRIORITY_HIGH);
// I2C中断优先级设为中/低
cyhal_i2c_set_irq_priority(&i2c_master, CYHAL_ISR_PRIORITY_MEDIUM);如果使用DMA进行UART/I2C传输:
初始化时手动分配资源:
// 分配UART的DMA通道
cyhal_dma_t uart_dma;
cyhal_dma_init(&uart_dma, CYHAL_DMA_CHANNEL_0);
cyhal_uart_configure_dma(&cy_retarget_io_uart_obj, &uart_dma, &uart_dma);
// I2C使用另一通道
cyhal_dma_t i2c_dma;
cyhal_dma_init(&i2c_dma, CYHAL_DMA_CHANNEL_1);这样确保:
通过以上步骤,应能解决UART日志异常和I2C工作冲突问题。
举报
更多回帖