这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » 软件与操作系统 » 瑞萨已适配的串口驱动(V2版)分析

共3条 1/1 1 跳转至

瑞萨已适配的串口驱动(V2版)分析

助工
2024-12-04 23:11:49     打赏

       瑞萨其实两版串口驱动都已经适配了,但是V1版的驱动的适配是放在drv_sci驱动中,个人理解sci是瑞萨专门的一个总线(个人猜测全名是serial control interface),这种总线可以配置成各类串行通信波形。而drv_sci里面适配了不同功能的驱动,内容会显得相对杂乱,不便于分析,且从分析上看,V2版的驱动框架明显比V1版的驱动框架有优势,因此跳过V1版的驱动框架分析实现V2版的驱动框架更加合适。

由V2版驱动框架整理出来的驱动参考模板

#include <rthw.h>
#include <rtthread.h>
#include <rtdevice.h>

#ifdef RT_USING_SERIAL_V2


struct _uart_config
{
    const char *name;
    // Other uart param
};

struct _uart
{
    struct rt_serial_device serial;
    struct _uart_config config;
};

static struct _uart_config uart_config[] =
{
    // Fill uart param
};

static struct _uart uart_obj[sizeof(uart_config) / sizeof(uart_config[0])] = {0};

static rt_err_t _configure(struct rt_serial_device *serial, struct serial_configure *cfg)
{
    // TODO: uart config
    return RT_EOK;
}

static rt_err_t _control(struct rt_serial_device *serial, int cmd, void *arg)
{

    switch (cmd)
    {
    case RT_DEVICE_CTRL_CLR_INT:
        // TODO: Disable IRQ
        break;

    case RT_DEVICE_CTRL_CONFIG:
        // TODO: Uart config
        break;

    case RT_DEVICE_CHECK_OPTMODE:
        // TODO: Return dma mode or intterupt mode

    case RT_DEVICE_CTRL_CLOSE:
        // uart close
        break;

    }
    return RT_EOK;
}

static int _putc(struct rt_serial_device *serial, char c)
{
    // TODO: process write one byte
    return 1;
}


static int _getc(struct rt_serial_device *serial)
{
    // TODO: Read a Byte from uart register
    // return xxxx();
}

static rt_ssize_t _transmit(struct rt_serial_device     *serial,
                                       rt_uint8_t           *buf,
                                       rt_size_t             size,
                                       rt_uint32_t           tx_flag)
{
    // TODO: Process Tx and Rx function
    // Return value is real read/write data num
    return size;
}

// TODO: Int function that call
//     rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_DMADONE | (recv_len << 8));
//     rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
//     rt_hw_serial_isr(serial, RT_SERIAL_EVENT_TX_DONE);
//     rt_hw_serial_isr(serial, RT_SERIAL_EVENT_TX_DMADONE);

static const struct rt_uart_ops _uart_ops =
{
    .configure = _configure,
    .control = _control,
    .putc = _putc,
    .getc = _getc,
    .transmit = _transmit
};

int rt_hw_usart_init(void)
{
    rt_err_t result = 0;
    rt_size_t obj_num = sizeof(uart_obj) / sizeof(struct _uart);

    for (int i = 0; i < obj_num; i++)
    {
        // TODO: uart config init
        uart_obj[i].serial.ops = &_uart_ops;
        result = rt_hw_serial_register(&uart_obj[i].serial,
                                        uart_obj[i].config->name,
                                        RT_DEVICE_FLAG_RDWR,
                                        NULL);
        RT_ASSERT(result == RT_EOK);
    }

    return result;
}

#endif /* RT_USING_SERIAL_V2 */

适配接口分析

源码路径

bsp\renesas\libraries\HAL_Drivers\drv_usart_v2.c

注册入口

// 此部分由RASC生成,并不需要改动
#if defined(BSP_USING_UART0)
#ifndef UART0_CONFIG
#define UART0_CONFIG                                                \
    {                                                               \
        .name = "uart0",                                            \
        .p_api_ctrl = &g_uart0_ctrl,                                \
        .p_cfg = &g_uart0_cfg,                                      \
    }
#endif /* UART0_CONFIG */
#endif /* BSP_USING_UART0 */

#if defined(BSP_USING_UART1)
#ifndef UART1_CONFIG
#define UART1_CONFIG                                                \
    {                                                               \
        .name = "uart1",                                            \
        .p_api_ctrl = &g_uart1_ctrl,                                \
        .p_cfg = &g_uart1_cfg,                                      \
    }
#endif /* UART1_CONFIG */
#endif /* BSP_USING_UART1 */

#if defined(BSP_USING_UART2)
#ifndef UART2_CONFIG
#define UART2_CONFIG                                                \
    {                                                               \
        .name = "uart2",                                            \
        .p_api_ctrl = &g_uart2_ctrl,                                \
        .p_cfg = &g_uart2_cfg,                                      \
    }
#endif /* UART2_CONFIG */
#endif /* BSP_USING_UART2 */

#if defined(BSP_USING_UART3)
#ifndef UART3_CONFIG
#define UART3_CONFIG                                                \
    {                                                               \
        .name = "uart3",                                            \
        .p_api_ctrl = &g_uart3_ctrl,                                \
        .p_cfg = &g_uart3_cfg,                                      \
    }
#endif /* UART3_CONFIG */
#endif /* BSP_USING_UART3 */

#if defined(BSP_USING_UART9)
#ifndef UART9_CONFIG
#define UART9_CONFIG                                                \
    {                                                               \
        .name = "uart9",                                            \
        .p_api_ctrl = &g_uart9_ctrl,                                \
        .p_cfg = &g_uart9_cfg,                                      \
    }
#endif /* UART9_CONFIG */
#endif /* BSP_USING_UART9 */

static struct ra_uart_config uart_config[] =
{
#ifdef BSP_USING_UART0
    UART0_CONFIG,
#endif

#ifdef BSP_USING_UART1
    UART1_CONFIG,
#endif

#ifdef BSP_USING_UART2
    UART2_CONFIG,
#endif

#ifdef BSP_USING_UART3
    UART3_CONFIG,
#endif

#ifdef BSP_USING_UART4
    UART4_CONFIG,
#endif

#ifdef BSP_USING_UART5
    UART5_CONFIG,
#endif

#ifdef BSP_USING_UART6
    UART6_CONFIG,
#endif

#ifdef BSP_USING_UART7
    UART7_CONFIG,
#endif

#ifdef BSP_USING_UART8
    UART8_CONFIG,
#endif

#ifdef BSP_USING_UART9
    UART9_CONFIG,
#endif
};

enum
{
#ifdef BSP_USING_UART0
    UART0_INDEX,
#endif

#ifdef BSP_USING_UART1
    UART1_INDEX,
#endif

#ifdef BSP_USING_UART2
    UART2_INDEX,
#endif

#ifdef BSP_USING_UART3
    UART3_INDEX,
#endif

#ifdef BSP_USING_UART4
    UART4_INDEX,
#endif

#ifdef BSP_USING_UART5
    UART5_INDEX,
#endif

#ifdef BSP_USING_UART6
    UART6_INDEX,
#endif

#ifdef BSP_USING_UART7
    UART7_INDEX,
#endif

#ifdef BSP_USING_UART8
    UART8_INDEX,
#endif

#ifdef BSP_USING_UART9
    UART9_INDEX,
#endif
};

static struct ra_uart uart_obj[sizeof(uart_config) / sizeof(uart_config[0])] = {0};

static void ra_uart_get_config(void)
{
    struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;

#ifdef BSP_USING_UART0
    uart_obj[UART0_INDEX].serial.config = config;
    uart_obj[UART0_INDEX].uart_dma_flag = 0;

    uart_obj[UART0_INDEX].serial.config.rx_bufsz = BSP_UART0_RX_BUFSIZE;
    uart_obj[UART0_INDEX].serial.config.tx_bufsz = BSP_UART0_TX_BUFSIZE;
#endif

#ifdef BSP_USING_UART1
    uart_obj[UART1_INDEX].serial.config = config;
    uart_obj[UART1_INDEX].uart_dma_flag = 0;

    uart_obj[UART1_INDEX].serial.config.rx_bufsz = BSP_UART1_RX_BUFSIZE;
    uart_obj[UART1_INDEX].serial.config.tx_bufsz = BSP_UART1_TX_BUFSIZE;
#endif

#ifdef BSP_USING_UART2
    uart_obj[UART2_INDEX].serial.config = config;
    uart_obj[UART2_INDEX].uart_dma_flag = 0;

    uart_obj[UART2_INDEX].serial.config.rx_bufsz = BSP_UART2_RX_BUFSIZE;
    uart_obj[UART2_INDEX].serial.config.tx_bufsz = BSP_UART2_TX_BUFSIZE;
#endif

#ifdef BSP_USING_UART3
    uart_obj[UART3_INDEX].serial.config = config;
    uart_obj[UART3_INDEX].uart_dma_flag = 0;

    uart_obj[UART3_INDEX].serial.config.rx_bufsz = BSP_UART3_RX_BUFSIZE;
    uart_obj[UART3_INDEX].serial.config.tx_bufsz = BSP_UART3_TX_BUFSIZE;
#endif

#ifdef BSP_USING_UART4
    uart_obj[UART4_INDEX].serial.config = config;
    uart_obj[UART4_INDEX].uart_dma_flag = 0;

    uart_obj[UART4_INDEX].serial.config.rx_bufsz = BSP_UART4_RX_BUFSIZE;
    uart_obj[UART4_INDEX].serial.config.tx_bufsz = BSP_UART4_TX_BUFSIZE;
#endif

#ifdef BSP_USING_UART5
    uart_obj[UART5_INDEX].serial.config = config;
    uart_obj[UART5_INDEX].uart_dma_flag = 0;

    uart_obj[UART5_INDEX].serial.config.rx_bufsz = BSP_UART5_RX_BUFSIZE;
    uart_obj[UART5_INDEX].serial.config.tx_bufsz = BSP_UART5_TX_BUFSIZE;
#endif

#ifdef BSP_USING_UART6
    uart_obj[UART6_INDEX].serial.config = config;
    uart_obj[UART6_INDEX].uart_dma_flag = 0;

    uart_obj[UART6_INDEX].serial.config.rx_bufsz = BSP_UART6_RX_BUFSIZE;
    uart_obj[UART6_INDEX].serial.config.tx_bufsz = BSP_UART6_TX_BUFSIZE;
#endif

#ifdef BSP_USING_UART7
    uart_obj[UART7_INDEX].serial.config = config;
    uart_obj[UART7_INDEX].uart_dma_flag = 0;

    uart_obj[UART7_INDEX].serial.config.rx_bufsz = BSP_UART7_RX_BUFSIZE;
    uart_obj[UART7_INDEX].serial.config.tx_bufsz = BSP_UART7_TX_BUFSIZE;
#endif

#ifdef BSP_USING_UART8
    uart_obj[UART8_INDEX].serial.config = config;
    uart_obj[UART8_INDEX].uart_dma_flag = 0;

    uart_obj[UART8_INDEX].serial.config.rx_bufsz = BSP_UART8_RX_BUFSIZE;
    uart_obj[UART8_INDEX].serial.config.tx_bufsz = BSP_UART8_TX_BUFSIZE;
#endif

#ifdef BSP_USING_UART9
    uart_obj[UART9_INDEX].serial.config = config;
    uart_obj[UART9_INDEX].uart_dma_flag = 0;

    uart_obj[UART9_INDEX].serial.config.rx_bufsz = BSP_UART9_RX_BUFSIZE;
    uart_obj[UART9_INDEX].serial.config.tx_bufsz = BSP_UART9_TX_BUFSIZE;
#endif
}

// 对接框架层的实现代码
static const struct rt_uart_ops ra_uart_ops =
{
    .configure = ra_uart_configure,
    .control = ra_uart_control,
    .putc = ra_uart_putc,
    .getc = ra_uart_getc,
    .transmit = ra_uart_transmit
};

int rt_hw_usart_init(void)
{
    rt_err_t result = 0;
    rt_size_t obj_num = sizeof(uart_obj) / sizeof(struct ra_uart);

    // uart object默认参数初始化
    ra_uart_get_config();
    for (int i = 0; i < obj_num; i++)
    {
        /* 将uart配置和uart对应的操作函数交由object维护 */
        uart_obj[i].config = &uart_config[i];
        uart_obj[i].serial.ops = &ra_uart_ops;
        /* 向系统注册uart设备 */
        result = rt_hw_serial_register(&uart_obj[i].serial,
                                       uart_obj[i].config->name,
                                       RT_DEVICE_FLAG_RDWR,
                                       NULL);
        RT_ASSERT(result == RT_EOK);
    }

    return result;
}

       注册入口基本上就是照着模板的样子实现的。

uart配置入口

static rt_err_t ra_uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
{
    struct ra_uart *uart;
    RT_ASSERT(serial != RT_NULL);
    RT_ASSERT(cfg != RT_NULL);

    fsp_err_t err = FSP_SUCCESS;

    uart = rt_container_of(serial, struct ra_uart, serial);
    RT_ASSERT(uart != RT_NULL);

#ifdef SOC_SERIES_R7FA8M85
    err = R_SCI_B_UART_Open(uart->config->p_api_ctrl, uart->config->p_cfg);
#else
    err = R_SCI_UART_Open(uart->config->p_api_ctrl, uart->config->p_cfg);
#endif
    if (FSP_SUCCESS != err)
    {
        return -RT_ERROR;
    }

    return RT_EOK;
}

     从配置入口我们可以看出,传入的cfg参数完全没有使用到,而使用到的仅仅是rasc生成的默认配置,也就是说,瑞萨目前适配的框架并不能做到动态设置串口参数的目的,而是直接在调用configure接口时,就已经打开串口了。

uart控制入口

static rt_err_t ra_uart_control(struct rt_serial_device *serial, int cmd, void *arg)
{
    return RT_EOK;
}

     同上,由于目前瑞萨所做的并不是上层应用动态配置串口参数的方法,因此控制接口也一个功能都未实现,直接返回RT_EOK,以免上层不能执行下去。

uart输出字符入口

static int ra_uart_putc(struct rt_serial_device *serial, char c)
{
    struct ra_uart *uart;
    RT_ASSERT(serial != RT_NULL);

    uart = rt_container_of(serial, struct ra_uart, serial);
    RT_ASSERT(uart != RT_NULL);

#ifdef SOC_SERIES_R7FA8M85
    sci_b_uart_instance_ctrl_t *p_ctrl = (sci_b_uart_instance_ctrl_t *)uart->config->p_api_ctrl;
#else
    sci_uart_instance_ctrl_t *p_ctrl = (sci_uart_instance_ctrl_t *)uart->config->p_api_ctrl;
#endif

    p_ctrl->p_reg->TDR = c;

#if defined(SOC_SERIES_R7FA8M85) || defined(SOC_SERIES_R9A07G0)
    while ((p_ctrl->p_reg->CSR_b.TEND) == 0);
#else
    while ((p_ctrl->p_reg->SSR_b.TEND) == 0);
#endif

    return RT_EOK;
}

     轮询发送实现,其实轮询发送实现逻辑很简单,几乎所有方案都是往某个发送寄存器放一个字节的内容,然后等待发送完成标记置位,瑞萨也是这么操作的,只是不知道为何瑞萨这部分的实现并未封装到fsp层,而是直接将寄存器操作放置在驱动适配层。

uart读取字符入口

static int ra_uart_getc(struct rt_serial_device *serial)
{
    return RT_EOK;
}

     此接口在轮询模式下会使用,而瑞萨未实现具体功能,代表目前瑞萨并未适配轮询方式的RX接口t。

uart传输入口

static rt_ssize_t ra_uart_transmit(struct rt_serial_device     *serial,
                                   rt_uint8_t           *buf,
                                   rt_size_t             size,
                                   rt_uint32_t           tx_flag)
{
    struct ra_uart *uart;

    RT_ASSERT(serial != RT_NULL);
    RT_ASSERT(buf != RT_NULL);
    uart = rt_container_of(serial, struct ra_uart, serial);
    RT_ASSERT(uart != RT_NULL);

    ra_uart_control(serial, RT_DEVICE_CTRL_SET_INT, (void *)tx_flag);

    return size;
}

     确切的说,这个函数不应该叫传输函数,因为对接的瑞萨框架的接口上表明了,这个函数实际上仅仅执行了发送功能,而且这个发送还是不带发送完成回调的,这就意味着,在我们使用瑞萨目前的驱动代码时,是默认认为串口数据发送成功的。

uart中断回调处理入口

#ifdef BSP_USING_UART0
void user_uart0_callback(uart_callback_args_t *p_args)
{
    rt_interrupt_enter();

    struct rt_serial_device *serial = &uart_obj[UART0_INDEX].serial;
    RT_ASSERT(serial != RT_NULL);

    if (UART_EVENT_RX_CHAR == p_args->event)
    {
        struct rt_serial_rx_fifo *rx_fifo;
        rx_fifo = (struct rt_serial_rx_fifo *) serial->serial_rx;
        RT_ASSERT(rx_fifo != RT_NULL);

        rt_ringbuffer_putchar(&(rx_fifo->rb), (rt_uint8_t)p_args->data);

        rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
    }

    rt_interrupt_leave();
}
#endif

#ifdef BSP_USING_UART1
void user_uart1_callback(uart_callback_args_t *p_args)
{
    rt_interrupt_enter();

    struct rt_serial_device *serial = &uart_obj[UART1_INDEX].serial;
    RT_ASSERT(serial != RT_NULL);

    if (UART_EVENT_RX_CHAR == p_args->event)
    {
        struct rt_serial_rx_fifo *rx_fifo;
        rx_fifo = (struct rt_serial_rx_fifo *) serial->serial_rx;
        RT_ASSERT(rx_fifo != RT_NULL);

        rt_ringbuffer_putchar(&(rx_fifo->rb), (rt_uint8_t)p_args->data);

        rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
    }

    rt_interrupt_leave();
}
#endif

#ifdef BSP_USING_UART2
void user_uart2_callback(uart_callback_args_t *p_args)
{
    rt_interrupt_enter();

    struct rt_serial_device *serial = &uart_obj[UART2_INDEX].serial;
    RT_ASSERT(serial != RT_NULL);

    if (UART_EVENT_RX_CHAR == p_args->event)
    {
        struct rt_serial_rx_fifo *rx_fifo;
        rx_fifo = (struct rt_serial_rx_fifo *) serial->serial_rx;
        RT_ASSERT(rx_fifo != RT_NULL);

        rt_ringbuffer_putchar(&(rx_fifo->rb), (rt_uint8_t)p_args->data);

        rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
    }

    rt_interrupt_leave();
}
#endif

#ifdef BSP_USING_UART3
void user_uart3_callback(uart_callback_args_t *p_args)
{
    rt_interrupt_enter();

    struct rt_serial_device *serial = &uart_obj[UART3_INDEX].serial;
    RT_ASSERT(serial != RT_NULL);

    if (UART_EVENT_RX_CHAR == p_args->event)
    {
        struct rt_serial_rx_fifo *rx_fifo;
        rx_fifo = (struct rt_serial_rx_fifo *) serial->serial_rx;
        RT_ASSERT(rx_fifo != RT_NULL);

        rt_ringbuffer_putchar(&(rx_fifo->rb), (rt_uint8_t)p_args->data);

        rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
    }

    rt_interrupt_leave();
}
#endif

#ifdef BSP_USING_UART4
void user_uart4_callback(uart_callback_args_t *p_args)
{
    rt_interrupt_enter();

    struct rt_serial_device *serial = &uart_obj[UART4_INDEX].serial;
    RT_ASSERT(serial != RT_NULL);

    if (UART_EVENT_RX_CHAR == p_args->event)
    {
        struct rt_serial_rx_fifo *rx_fifo;
        rx_fifo = (struct rt_serial_rx_fifo *) serial->serial_rx;
        RT_ASSERT(rx_fifo != RT_NULL);

        rt_ringbuffer_putchar(&(rx_fifo->rb), (rt_uint8_t)p_args->data);

        rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
    }

    rt_interrupt_leave();
}
#endif

#ifdef BSP_USING_UART5
void user_uart5_callback(uart_callback_args_t *p_args)
{
    rt_interrupt_enter();

    struct rt_serial_device *serial = &uart_obj[UART5_INDEX].serial;
    RT_ASSERT(serial != RT_NULL);

    if (UART_EVENT_RX_CHAR == p_args->event)
    {
        struct rt_serial_rx_fifo *rx_fifo;
        rx_fifo = (struct rt_serial_rx_fifo *) serial->serial_rx;
        RT_ASSERT(rx_fifo != RT_NULL);

        rt_ringbuffer_putchar(&(rx_fifo->rb), (rt_uint8_t)p_args->data);

        rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
    }

    rt_interrupt_leave();
}
#endif

#ifdef BSP_USING_UART6
void user_uart6_callback(uart_callback_args_t *p_args)
{
    rt_interrupt_enter();

    struct rt_serial_device *serial = &uart_obj[UART6_INDEX].serial;
    RT_ASSERT(serial != RT_NULL);

    if (UART_EVENT_RX_CHAR == p_args->event)
    {
        struct rt_serial_rx_fifo *rx_fifo;
        rx_fifo = (struct rt_serial_rx_fifo *) serial->serial_rx;
        RT_ASSERT(rx_fifo != RT_NULL);

        rt_ringbuffer_putchar(&(rx_fifo->rb), (rt_uint8_t)p_args->data);

        rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
    }

    rt_interrupt_leave();
}
#endif

#ifdef BSP_USING_UART7
void user_uart7_callback(uart_callback_args_t *p_args)
{
    rt_interrupt_enter();

    struct rt_serial_device *serial = &uart_obj[UART7_INDEX].serial;
    RT_ASSERT(serial != RT_NULL);

    if (UART_EVENT_RX_CHAR == p_args->event)
    {
        struct rt_serial_rx_fifo *rx_fifo;
        rx_fifo = (struct rt_serial_rx_fifo *) serial->serial_rx;
        RT_ASSERT(rx_fifo != RT_NULL);

        rt_ringbuffer_putchar(&(rx_fifo->rb), (rt_uint8_t)p_args->data);

        rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
    }

    rt_interrupt_leave();
}
#endif

#ifdef BSP_USING_UART8
void user_uart8_callback(uart_callback_args_t *p_args)
{
    rt_interrupt_enter();

    struct rt_serial_device *serial = &uart_obj[UART8_INDEX].serial;
    RT_ASSERT(serial != RT_NULL);

    if (UART_EVENT_RX_CHAR == p_args->event)
    {
        struct rt_serial_rx_fifo *rx_fifo;
        rx_fifo = (struct rt_serial_rx_fifo *) serial->serial_rx;
        RT_ASSERT(rx_fifo != RT_NULL);

        rt_ringbuffer_putchar(&(rx_fifo->rb), (rt_uint8_t)p_args->data);

        rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
    }

    rt_interrupt_leave();
}
#endif

#ifdef BSP_USING_UART9
void user_uart9_callback(uart_callback_args_t *p_args)
{
    rt_interrupt_enter();

    struct rt_serial_device *serial = &uart_obj[UART9_INDEX].serial;
    RT_ASSERT(serial != RT_NULL);

    if (UART_EVENT_RX_CHAR == p_args->event)
    {
        struct rt_serial_rx_fifo *rx_fifo;
        rx_fifo = (struct rt_serial_rx_fifo *) serial->serial_rx;
        RT_ASSERT(rx_fifo != RT_NULL);

        rt_ringbuffer_putchar(&(rx_fifo->rb), (rt_uint8_t)p_args->data);

        rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
    }

    rt_interrupt_leave();
}
#endif

     乍一看,会觉得代码非常多,但实际上看每个宏包裹的内容,会发现,实际上实现长一个样,这么写纯粹的让人误解,还不如把实现统一写成一个宏或者一个函数来降低阅读难度。从这中断回调处理,我们可以发现,瑞萨仅仅做了接收数据的中断回调处理,而发送数据的中断回调,瑞萨并未添加,若需要,则需要自行添加。

总结

      通过对瑞萨适配的V2版串口驱动的分析,我们会发现,瑞萨仅仅适配了中断方式通信的串口,如果要使用轮询或DMA方式工作,还需要自行添加对应实现(轮询方式发送接口已经实现,但未实现轮询接收),否则在驱动这一层就会走不通。

      另外,目前瑞萨适配的版本,并不支持动态配置串口参数,也就是说,RASC配置的默认参数是什么,那最后使用时就是什么。




关键词: 瑞萨     适配     串口     serial     驱动     分析     v2    

专家
2024-12-05 08:17:19     打赏
2楼

感谢分享


工程师
2024-12-05 10:54:42     打赏
3楼

赞赞赞


共3条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]