0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

rt-thread 驱动篇(四)serialX 多架构适配

出出 来源:出出 作者:出出 2022-06-10 10:21 次阅读

前言

自笔者提出 serialX 串口驱动到今天近半年了,当初只在 STM32F4 NUC970 两个系列芯片上做过理论验证。一个是 ARM CM4 核心架构,一个是 ARM9。这两款芯片能完美实现笔者的需求。

经过这半年的实践考验,笔者还是相信 serialX 的实力的,最近这几天笔者尝试在 N32 AB32 RA6M4 上适配 serialX,下面就向各位汇报一下适配结果。

芯片 STM32F4 NUC970 N32 AB32 RA6M4 GD32F4
架构 CM4 ARM9 CM4 RISC-V CM33 CM4

N32G45

因为这个也是 CM4,和 STM32F4 相较而言,可能差别很小。让笔者感到欣慰的是用`DMA_GetFlagStatus(uart->dma_tx.dma_flag, uart->dma_tx.dma_module) == SET` 代替了 `uart->dmaTxing` 。这是一处小改进。
除此之外,没啥可说的了。

已实现的功能有:

  • 轮询收发
  • 中断收发(可阻塞可非阻塞)
  • DMA 收发(可阻塞可非阻塞)

AB32VG1

这个是 RISC-V 架构的 CPU

从芯片手册我们可以看到,它的串口外设只有“接收一个字节完成”和“发送一个字节完成”两个中断。
在 serialX 的设计构想里,我们希望有个“发送寄存器空”中断。因为这样很容易启动一次中断,在中断里判断是否有数据需要发送,进而启动一次发送过程。
假如没有这个中断,我们必须通过先写一个字节引起一次“发送完成中断”,然后借助这次中断继续判断是否有数据需要发送。在数据所有数据发送完之前,我们还需要有个 flag 标识一下现在处于发送流程中。
因此,serialX 需要进行一些改动:
`_serial_int_tx` 函数

       // TODO: start tx
#if defined (RT_SERIAL_NO_TXEIT)
       if (serial->ops->is_int_txing != RT_NULL && serial->ops->is_int_txing(serial) == RT_FALSE) {
           ch = _serial_fifo_pop_data(tx_fifo);
           serial->ops->start_tx(serial, ch);
       }
#else
       serial->ops->start_tx(serial);
#endif
```
`struct rt_uart_ops`
```
#if defined (RT_SERIAL_NO_TXEIT)
   rt_bool_t (*is_int_txing)(struct rt_serial_device *serial);
   void (*start_tx)(struct rt_serial_device *serial, rt_uint8_t ch);
#else
   void (*start_tx)(struct rt_serial_device *serial);
#endif

因为这些改动,AB32VG1 的底层驱动写法也就不一样了,多了一个判断是否处于发送流程中的 api。start_tx stop_tx 也不仅仅是开关中断那么简单了,需要改变 intTxing 这个 flag 标识发送流程状态。

rt_bool_t ab32_int_txing(struct rt_serial_device *serial)
{
   struct ab32_uart *uart;

   RT_ASSERT(serial != RT_NULL);

   uart = rt_container_of(serial, struct ab32_uart, serial);

   return uart->intTxing;
}

static void ab32_start_tx(struct rt_serial_device *serial, rt_uint8_t ch)
{
   struct ab32_uart *uart;

   RT_ASSERT(serial != RT_NULL);

   uart = rt_container_of(serial, struct ab32_uart, serial);
   uart->intTxing = RT_TRUE;
   hal_uart_control(uart->handle.instance, UART_TXIT_ENABLE, HAL_ENABLE);
   hal_uart_write(uart->handle.instance, ch);
}

static void ab32_stop_tx(struct rt_serial_device *serial)
{
   struct ab32_uart *uart;

   RT_ASSERT(serial != RT_NULL);

   uart = rt_container_of(serial, struct ab32_uart, serial);
   hal_uart_control(uart->handle.instance, UART_TXIT_ENABLE, HAL_DISABLE);
   uart->intTxing = RT_FALSE;
}

为此,我们需要添加个新配置,components/drivers/Kconfig

           config RT_SERIAL_NO_TXEIT
               bool "No TX Empty interrupt"
               default n
               help
                   Useful only if the chip hasn't Transmit Register Empty interrupt
                   Such as: AB32 RA6M4

意思是说,当芯片没有“发送寄存器空中断”支持的时候,我们需要用 `intTxing` 代替实现控制发送过程。

另外,发送寄存器也没有空状态,`putc` 函数倒是可以判断发送完成标志,但是这样就不能在中断里调用 `putc` 了;不加发送完成判断,就不能在轮询发送中调用它。总之,轮询发送和中断发送不用用一样的 `putc` 函数了。

已实现的功能有:

  • 中断收发(可阻塞可非阻塞)


RA6M4

RA6M4 是一款 CM33 核 ARM 芯片,本以为它比 CM4 高级可以很容易实现 CM4 上实现的操作。

但是,笔者也没有从手册中找到“发送寄存器空中断”。所以 RA6M4 和 AB32VG1 有一样的补救处理。
但是,笔者还发现另外一个问题,**如果是中断发送,每次写完 TDR 寄存器后,必须重新使能发送中断**。不这样做,就不会出现发送完成中断。

虽然如此,连续发送多个字节仍然会出现发送中断不触发(或丢失)的情况,导致发送功能完全瘫痪(这也是 `intTxing` 引入的隐患)。

已实现的功能有:

  • 中断接收(可阻塞可非阻塞)
  • 中断发送(未完),暂时可以用轮询发送代替

多说两句,RA6M4 的 SCI 好像可以启用 FIFO ,这样一来串口收发寄存器就是带 FIFO 的。遗憾的是笔者不会用啊,有会用的大佬可以尝试移植一下,用 FIFO 了就相当于用 DMA 了。

GD32F4

这个也可以做到和 STM32F4 一样的程度,DMA 没有发送标志,只能继续用 `dmaTxing` 。

已实现的功能有:

  • 轮询收发
  • 中断收发(可阻塞可非阻塞)
  • DMA收发(可阻塞可非阻塞)

注:只分配了 UART0 的 DMA 通道,如果其它的也需要开启 DMA 请自行修改 `struct gd32_uart uarts` 数组变量分配 DMA 通道。

注:还有一点,rt-studio 里下载的 GD32F4 firmware 库版本是很多年前的,现在已经改动过好几次了。笔者使用的 `gd32f4xx_usart.h` 版本是 “2020-09-30, V2.1.0, firmware for GD32F4xx” 。如有编译错误请升级 firmware 库。

结束语

关于 serialX 理论的部分,之前的文章已经说的够多了。这次是想在多种平台上用实践检验一下 serialX 理论的可行性。经过这几天的投入,最终多多少少有些收获,还是很欣慰的。

汇总一下,目前可以适配的芯片包括如下几类
1. 没有 DMA ,只有串口接收发送中断
2. 没有“发送寄存器空”状态或没有“发送寄存器空”中断
3. 带接收 IDLE 检测,带“发送寄存器空”中断
4. 带 DMA ,并且至少有 DMA 半传输中断和全传输中断
5. 串口外设自带收发 FIFO (可认为是 DMA ,但是比 DMA 使用更简单)

在此,特别感谢[嚜軒公告](https://club.rt-thread.org/u/7c37fff6229d1ccd)支援的开发板,最终完成了 serialX 在这些平台上的实现。

下期预告,我们来扒一扒 serialX 的缺陷,对,它的缺陷。准确的讲是在 RTOS 上引入的坑有哪些以及怎么避免。

附 [serialX](https://gitee.com/thewon/serialX) 仓库地址,感兴趣的可以下载最新版 serialX 源码。本文提到的几种芯片的驱动也都已提交。

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • ARM
    ARM
    +关注

    关注

    134

    文章

    8648

    浏览量

    361757
  • N32
    N32
    +关注

    关注

    0

    文章

    18

    浏览量

    7113
  • STM32F4
    +关注

    关注

    3

    文章

    192

    浏览量

    27675
  • RT-Thread
    +关注

    关注

    31

    文章

    1148

    浏览量

    38867
  • serialX
    +关注

    关注

    0

    文章

    7

    浏览量

    786
收藏 人收藏

    评论

    相关推荐

    4月25日北京站RT-Thread线下workshop,探索RT-Thread混合部署新模式

    4月25日,下午我们将在北京举办RT-Thread混合部署线下workshop,在瑞芯微RK3568平台上实现同时运行RT-Thread和linux,本次workshop邀请到RT-Thread资深
    的头像 发表于 04-16 08:35 85次阅读
    4月25日北京站<b class='flag-5'>RT-Thread</b>线下workshop,探索<b class='flag-5'>RT-Thread</b>混合部署新模式

    4月10日深圳场RT-Thread线下workshop,探索RT-Thread混合部署新模式!

    4月10日我们将在深圳福田举办RT-Thread混合部署线下workshop,在瑞芯微RK3568平台上实现同时运行RT-Thread和linux,本次workshop邀请到RT-Thread资深嵌入式软件工程师农晓明老师为您讲
    的头像 发表于 03-27 11:36 417次阅读
    4月10日深圳场<b class='flag-5'>RT-Thread</b>线下workshop,探索<b class='flag-5'>RT-Thread</b>混合部署新模式!

    4月10日深圳场RT-Thread线下workshop,探索RT-Thread混合部署新模式!

    4月10日我们将在深圳福田举办RT-Thread混合部署线下workshop,在瑞芯微RK3568平台上实现同时运行RT-Thread和linux,本次workshop邀请到RT-Thread资深
    的头像 发表于 03-27 08:34 145次阅读
    4月10日深圳场<b class='flag-5'>RT-Thread</b>线下workshop,探索<b class='flag-5'>RT-Thread</b>混合部署新模式!

    RT-Thread设备驱动开发指南基础篇—以先楫bsp的hwtimer设备为例

    RT-Thread设备驱动开发指南》书籍是RT-thread官方出品撰写,系统讲解RT-thread IO设备驱动开发方法,从三方面进行讲解
    的头像 发表于 02-20 16:01 821次阅读
    <b class='flag-5'>RT-Thread</b>设备<b class='flag-5'>驱动</b>开发指南基础篇—以先楫bsp的hwtimer设备为例

    BL808 RT-Thread Wi-Fi驱动适配

    BL808 WiFi 属于 SOC 单芯片型无线 MCU,片上集成 WiFi 功能,移植 RT-Thread 过程中,需要使用 RT-Thread wlan 框架。
    的头像 发表于 12-04 11:38 410次阅读

    基于rt-thread的socket通信设计

    最近再研究 rt-thread 的通信 ,想设计出 eps8266(多个) rt-thread(作为中控) 服务器的通信框架,使用的开发板是 潘多拉
    的头像 发表于 10-13 15:02 677次阅读
    基于<b class='flag-5'>rt-thread</b>的socket通信设计

    试用RT-Thread Studio(VSCode)

    想尝试RT-Thread studio (VSCode),先下载安装VSCode,再搜索RT-Thread
    的头像 发表于 10-12 10:58 569次阅读
    试用<b class='flag-5'>RT-Thread</b> Studio(VSCode)

    RT-Thread v5.0.2 发布

    RT-Thread 代码仓库地址: ●  https://github.com/RT-Thread/rt-thread RT-Thread 5.0.2 版本发布日志详情: ●  htt
    的头像 发表于 10-10 18:45 774次阅读
    <b class='flag-5'>RT-Thread</b> v5.0.2 发布

    RT-Thread Studio上配置rtthread CANFD驱动来控制M3508电机

    本文旨在RT-Thread Studio上配置rtthread CANFD驱动来控制M3508电机,不涉及任何原理 开发环境:RT-Thread Studio v2.2.6
    发表于 10-08 11:44 554次阅读
    在<b class='flag-5'>RT-Thread</b> Studio上配置rtthread CANFD<b class='flag-5'>驱动</b>来控制M3508电机

    基于 RT-Thread 的 RoboMaster 电控框架(一)

    由于 RT-Thread 稳定高效的内核,丰富的文档教程,积极活跃的社区氛围,以及设备驱动框架、Kconfig、Scons、日志系统、海量的软件包……很难不选择 RT-Thread 进行项目开发
    的头像 发表于 09-19 19:55 415次阅读

    基于RT-Thread的RoboMaster电控框架设计

    由于 RT-Thread 稳定高效的内核,丰富的文档教程,积极活跃的社区氛围,以及设备驱动框架、Kconfig、Scons、日志系统、海量的软件包……很难不选择 RT-Thread 进行项目开发。
    发表于 09-06 15:21 408次阅读

    RT-Thread BSP v1.2.0 发布啦

    有哪些更新、如何安装及创建项目...下面我们一起来看看吧。1主要功能●常用驱动提供了基于RT-Thread驱动框架的适配●提供了如下通用功能的示例:blink_ledca
    的头像 发表于 08-15 10:02 413次阅读
    <b class='flag-5'>RT-Thread</b> BSP v1.2.0 发布啦

    请教一下bsp如何适配RT-Thread上呢?

    CPU 部分已经适配好了,也就是通过 使能 ARCH_ARM_CORTEX_M3 ,来使能 rt-thread/libcpu/arm/cortex-m3,这部分不需要改动
    的头像 发表于 08-01 16:10 612次阅读
    请教一下bsp如何<b class='flag-5'>适配</b>到<b class='flag-5'>RT-Thread</b>上呢?

    教你手上没有开发板如何跑RT-THREAD STM32应用?

    首先打开 RT-Thread Studio,新建RT-Thread
    的头像 发表于 07-18 16:09 1050次阅读
    教你手上没有开发板如何跑<b class='flag-5'>RT-THREAD</b> STM32应用?

    基于RT-Thread Studio学习

    前期准备:从官网下载 RT-Thread Studio,弄个账号登陆,开启rt-thread学习之旅。
    的头像 发表于 05-15 11:00 2576次阅读
    基于<b class='flag-5'>RT-Thread</b> Studio学习