您尚未登录。

楼主 # 2025-08-05 20:27:25

zhdj
会员
注册时间: 2025-08-05
已发帖子: 2
积分: 17

串口使用DMA的问题

各位大侠好,我想使用DMA进行串口数据的收发,但一发送就死机,异常7。中断收发正常,请帮忙看一下我的问题出在哪里?
我使用的是DS133CBS,LUBAN-LITE
Board option中 UART2已经打开DMA。rt thread中串口驱动也已经打开DMA。下面是程序

/ UART2 DMA Test Variables /
static rt_device_t uart2_device = RT_NULL;
static rt_thread_t uart2_test_thread = RT_NULL;
static rt_uint8_t uart2_rx_buffer[256];
static rt_uint8_t uart2_tx_buffer[256] __attribute__((aligned(32)));
static rt_uint32_t uart2_test_counter = 0;

/ UART2 接收回调函数 /
static rt_err_t uart2_rx_callback(rt_device_t dev, rt_size_t size)
{
if (size > 0) {
rt_kprintf("[UART2-DMA] RX: %d bytes\n", size);

rt_size_t read_size = rt_device_read(dev, 0, uart2_rx_buffer, size);
if (read_size > 0) {
uart2_rx_buffer[read_size] = '\0';
rt_kprintf("[UART2-DMA] Data: \"%s\"\n", uart2_rx_buffer);
}
}
return RT_EOK;
}

/ UART2 DMA安全发送 /
static rt_err_t uart2_dma_send(const char *data, rt_size_t len)
{
if (!uart2_device || !data || len == 0) return -RT_EINVAL;

if (len > 255) len = 255;
memcpy(uart2_tx_buffer, data, len);

#if defined(RT_USING_CACHE)
rt_hw_cpu_dcache_clean(uart2_tx_buffer, len);
#endif

rt_size_t written = rt_device_write(uart2_device, 0, uart2_tx_buffer, len);
return (written > 0) ? RT_EOK : -RT_ERROR;
}

/ UART2 测试线程 /
static void uart2_test_thread_entry(void *parameter)
{
rt_kprintf("[UART2-DMA] Test thread started\n");

while (1) {
char test_data[64];
rt_snprintf(test_data, sizeof(test_data), "TEST_%04d_DMA_OK\r\n", uart2_test_counter++);

rt_kprintf("[UART2-DMA] Sending: %s", test_data);
uart2_dma_send(test_data, strlen(test_data));

if (uart2_test_counter % 10 == 0) {
rt_uint16_t flag = uart2_device->flag;
rt_kprintf("[UART2-DMA] Status - DMA_TX:%s DMA_RX:%s\n",
(flag & RT_DEVICE_FLAG_DMA_TX) ? "ON" : "OFF",
(flag & RT_DEVICE_FLAG_DMA_RX) ? "ON" : "OFF");
}

rt_thread_mdelay(1000);
}
}

/ 初始化UART2 DMA测试 /
static rt_err_t uart2_dma_test_init(void)
{
rt_kprintf("\n=== UART2 DMA Test Starting ===\n");

/ 查找UART2设备 /
uart2_device = rt_device_find("uart2");
if (!uart2_device) {
rt_kprintf("[UART2-DMA] ERROR: uart2 device not found\n");
return -RT_ERROR;
}

/ 配置串口 /
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
config.baud_rate = BAUD_RATE_921600;
config.data_bits = DATA_BITS_8;
config.stop_bits = STOP_BITS_1;
config.parity = PARITY_NONE;

rt_err_t result = rt_device_control(uart2_device, RT_DEVICE_CTRL_CONFIG, &config);
if (result != RT_EOK) {
rt_kprintf("[UART2-DMA] Config failed: %d\n", result);
return result;
}

/ 尝试DMA模式 /
rt_kprintf("[UART2-DMA] Trying DMA mode...\n");
result = rt_device_open(uart2_device, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_DMA_TX | RT_DEVICE_FLAG_DMA_RX);

if (result != RT_EOK) {
rt_kprintf("[UART2-DMA] DMA failed, using interrupt mode\n");
result = rt_device_open(uart2_device, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
if (result != RT_EOK) {
rt_kprintf("[UART2-DMA] Open failed: %d\n", result);
return result;
}
} else {
rt_kprintf("[UART2-DMA] DMA mode enabled!\n");
}

/ 显示设备状态 /
rt_kprintf("[UART2-DMA] Device flags: 0x%04X\n", uart2_device->flag);
rt_kprintf("[UART2-DMA] DMA TX: %s\n", (uart2_device->flag & RT_DEVICE_FLAG_DMA_TX) ? "ON" : "OFF");
rt_kprintf("[UART2-DMA] DMA RX: %s\n", (uart2_device->flag & RT_DEVICE_FLAG_DMA_RX) ? "ON" : "OFF");

/ 设置接收回调 /
rt_device_set_rx_indicate(uart2_device, uart2_rx_callback);

/ 创建测试线程 /
uart2_test_thread = rt_thread_create("uart2_test",
uart2_test_thread_entry,
RT_NULL,
2048,
20,
10);

if (!uart2_test_thread) {
rt_kprintf("[UART2-DMA] Thread creation failed\n");
rt_device_close(uart2_device);
return -RT_ERROR;
}

rt_thread_startup(uart2_test_thread);
rt_kprintf("[UART2-DMA] Test started successfully!\n");
rt_kprintf("===============================\n");

return RT_EOK;
}

离线

#1 2025-08-06 14:39:52

AICxia
会员
注册时间: 2024-08-12
已发帖子: 93
积分: 214

Re: 串口使用DMA的问题

RT_SERIAL_CONFIG_DEFAULT会将所有的参数重新置回默认值,默认是中断打开,然后open的时候又用了dma打开,所以返回错误了
这个是default,相当于之前配置的参数无效了

可以参考这个写https://gitee.com/artinchip/luban-lite/blob/master/bsp/examples/test-uart/test_uart.c

离线

楼主 #2 2025-08-06 16:31:06

zhdj
会员
注册时间: 2025-08-05
已发帖子: 2
积分: 17

Re: 串口使用DMA的问题

把例程中的打开方式改为DMA,测试通过。非常感谢。

离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn


东莞哇酷科技有限公司开发