rk2118之UART DMA调试

一. 软件需求

1、RK2118需要与bt实现uart通信
2、实现自定义通信协议。

二. UART DMA软件实现

2.1 软件框架介绍

串口框架:

components/drivers/include/drivers/serial.h
components/drivers/serial/serial.c 设备驱动
components/libc/termios/posix_termios.c 类似linux的tty配置
components/libc/termios/posix_termios.h

串口驱动适配层:
bsp/rockchip-pisces/drivers/drv_uart.c
bsp/rockchip-pisces/drivers/drv_uart.h

串口测试命令,串口用户程序完全可以参照以下驱动:
bsp/rockchip-common/tests/termios_test.c

2.2 uart dma代码路径

Rk2118/Components/hifi4/rtt/app/rkplayer/userial_dma_app.c

2.2.1 DMA设备创建以及初始化

int  uart_dma_device_init()
{
    char uart_name[RT_NAME_MAX];
    rt_strncpy(uart_name, DMA_UART_NAME, RT_NAME_MAX);
    serial = rt_device_find(uart_name);
    if (!serial){
        rt_kprintf("find %s failed!\n", uart_name);
        return -RT_ERROR;
    }else {
        RC_LOGD("find %s ok!\n", uart_name);
    }
    rt_device_open(serial, RT_DEVICE_FLAG_DMA_RX);
    rt_device_set_rx_indicate(serial, uart_input);
    return 0;
}

2.2.2 DMA线程创建(创建消息队列,阻塞等待rx消息)

int uart_dma_app_init()
{
    rt_err_t ret = RT_EOK;
    static char msg_pool[256];
    rt_mq_init(&rx_mq, "rx_mq",msg_pool,sizeof(struct rx_msg),sizeof(msg_pool),RT_IPC_FLAG_FIFO);
    int rets = uart_dma_device_init();
    if (rets < 0){
        return RT_ERROR;
    }
    RC_LOGD(" dma_serial thread create \n");
    rt_thread_t thread = rt_thread_create("dma_serial", serial_thread_entry, RT_NULL, 1024, 21, 10);
    if (thread != RT_NULL){
        rt_thread_startup(thread);
    }
    else{
        ret = RT_ERROR;
    }
    return ret;
}

2.2.3 阻塞等待线程实现

static void serial_thread_entry(void *parameter)
	{
	    struct rx_msg msg;
	    rt_err_t result;
	    rt_uint32_t rx_length;
	    static char rx_buffer[RT_SERIAL_RB_BUFSZ + 1];
	    rt_kprintf(" serial_thread_entry   \n");
	    while (1)
	    {
	        rt_memset(&msg, 0, sizeof(msg));
	        rt_memset(rx_buffer, 0, sizeof(rx_buffer));
	        result = rt_mq_recv(&rx_mq, &msg, sizeof(msg), RT_WAITING_FOREVER);
	        rt_kprintf(" recv message value  = %d  msg.size = %d\n",msg.value,msg.size);
	        if (result == RT_EOK)
	        {
	            rx_length = rt_device_read(msg.dev, 0, rx_buffer, msg.size);
	            rx_buffer[rx_length] = '\0';
	            rt_device_write(serial, 0, rx_buffer, rx_length);
	            RC_LOGI(" %s\n",rx_buffer);
	            RC_LOGI(" %d %d %d \n",rx_buffer[0],rx_buffer[1],rx_buffer[2]);
	        }
	    }
	}

2.2.4 Send函数实现

void uart_send_data(uint8_t *data, uint32_t len)
		{
		    if (!serial) {
		        return ;
		    }
		    rt_device_write(serial, 0, data, len);
		    uart_dma_data_dump(data,len);
		}

三、rkplayer app流程介绍

1、IN1IT_APP_EXPORT(rkplayer_init);/注册app线程到init函数/
在这里插入图片描述

2、g_app_info.main_mq = rt_mq_create(“main”, sizeof(struct app_msg), 10, RT_IPC_FLAG_FIFO);/主消息队列/

3、uart_dma_app_init();/dma线程创建/

4、rt_mq_recv(g_app_info.main_mq, (void *)&rcv_msg, sizeof(struct app_msg), RT_WAITING_FOREVER);/阻塞式等待消息/

5、消息的分类转发到其他线程
for (int i = TYPE_PLAY; i < TYPE_REMOTE_CTL; i++) {
if (rcv_msg.msg_falg & (1<<i)) {
send_msg.press = rcv_msg.press;
send_msg.type = i;
rt_mq_send(g_app_info.msg_mq[i], (void *)&send_msg, sizeof(struct app_msg));
}
}

3.1按键下发流程

1、key_app线程等待adc按键消息

在这里插入图片描述

2、adc检测到不同的按键电压发送消息到主线程
在这里插入图片描述

3、主线程根据不同的按键消息实现对应功能
在这里插入图片描述

四、UART自定义协议

4.1、协议自定义格式

4.2 代码实现命令打包

4.2.1、命令打包函数

static uint8_t user_build_cmd(uint8_t opcode, uint8_t subcommand, uint8_t *src, uint8_t srclen, uint8_t *dst, uint8_t dstlen) {
uint8_t i = 0;
RT_ASSERT(dstlen >= (/HEAD/ 4 + srclen + 1/CHECKSUM_LEN/));
dst[i++] = 0x28; /start/
dst[i++] = 4 + srclen + 1; /len/
dst[i++] = opcode; /func/
dst[i++] = subcommand; /sub/
memcpy(&dst[i], src, srclen); /data/
i = i+ srclen;
dst[i] = calculate_checksum(dst, i);/crc/
return i;
}

4.2.2、校验函数

static uint8_t calculate_checksum(uint8_t *buf, uint8_t len)
	{
	    uint8_t sum;
	    for(sum = 0; len > 0; len--)
	        sum += *buf++;
	    rt_kprintf("debug: sum = %d \n ",sum&0xff);
	    return sum&0xff;
	}

4.2.3、功能函数实现

在这里插入图片描述

五、UART DEBUG

5.1 menuconfig配置

通过menuconfig打开串口配置,同时会生成/dev/uart0…3设备。

RT-Thread rockchip RKxxxx drivers —>
[] Enable UART
[
] Enable UART0
[ ] Enable UART1
[*] Enable UART2

5.2 、uart test功能

RT-Thread Components —>
[] DFS: device virtual file system —>
[
] Using devfs for device objects
C/C++ and POSIX layer —>
POSIX (Portable Operating System Interface) layer —>
[] Enable POSIX file system and I/O
[
] Enable I/O Multiplexing select() <sys/select.h>
[*] Enable Terminal I/O <termios.h>

RT-Thread bsp test case —>
RT-Thread Common Test case —>
[] Enable BSP Common TEST
[
] Enable BSP Common UART TEST

串口测试命令:
receive data:
termtest r /dev/uart4 115200
send data:
termtest s /dev/uart4 115200
receive then send:
termtest t /dev/uart4 115200
externel loopback:
termtest l /dev/uart4 115200

5.3 、uart send test

void uart_send_msg_test()
	{
	    struct rx_msg msg;
	    rt_err_t result;
	    msg.dev = serial;
	    msg.value = 12;
	    msg.size = 1;
	    rt_kprintf("send message  \n");
	    result = rt_mq_send(&rx_mq, &msg, sizeof(msg));
	    if ( result == -RT_EFULL){
	        rt_kprintf("message queue full!\n");
	    }
	}

测试实例:
1、由于硬件环境限制;目前采用audio debug uart 作为调试口(uart2)

2、测试目前使用的是V+和V-按键操作如下:
/* 把相关测试函数放到按键下,接出对应uart口可以看到测试收发正常**/
在这里插入图片描述

Debug:uart0发送端打印如下:
在这里插入图片描述

Uart2接收端打印如下:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值