页次: 1
各位大侠好,我想使用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