您尚未登录。

#1 Re: 工业芯 匠芯创 » 串口使用DMA的问题 » 2025-08-06 16:31:06

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

#2 工业芯 匠芯创 » 串口使用DMA的问题 » 2025-08-05 20:27:25

zhdj
回复: 2

各位大侠好,我想使用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;
}

页脚

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

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