0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

rt-thread 驅(qū)動篇(四)serialX 多架構(gòu)適配

出出 ? 來源:出出 ? 作者:出出 ? 2022-06-10 10:21 ? 次閱讀

前言

自筆者提出 serialX 串口驅(qū)動到今天近半年了,當(dāng)初只在 STM32F4 NUC970 兩個系列芯片上做過理論驗證。一個是 ARM CM4 核心架構(gòu),一個是 ARM9。這兩款芯片能完美實現(xiàn)筆者的需求。

經(jīng)過這半年的實踐考驗,筆者還是相信 serialX 的實力的,最近這幾天筆者嘗試在 N32 AB32 RA6M4 上適配 serialX,下面就向各位匯報一下適配結(jié)果。

芯片 STM32F4 NUC970 N32 AB32 RA6M4 GD32F4
架構(gòu) 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` 。這是一處小改進。
除此之外,沒啥可說的了。

已實現(xiàn)的功能有:

  • 輪詢收發(fā)
  • 中斷收發(fā)(可阻塞可非阻塞)
  • DMA 收發(fā)(可阻塞可非阻塞)

AB32VG1

這個是 RISC-V 架構(gòu)的 CPU。

從芯片手冊我們可以看到,它的串口外設(shè)只有“接收一個字節(jié)完成”和“發(fā)送一個字節(jié)完成”兩個中斷。
在 serialX 的設(shè)計構(gòu)想里,我們希望有個“發(fā)送寄存器空”中斷。因為這樣很容易啟動一次中斷,在中斷里判斷是否有數(shù)據(jù)需要發(fā)送,進而啟動一次發(fā)送過程。
假如沒有這個中斷,我們必須通過先寫一個字節(jié)引起一次“發(fā)送完成中斷”,然后借助這次中斷繼續(xù)判斷是否有數(shù)據(jù)需要發(fā)送。在數(shù)據(jù)所有數(shù)據(jù)發(fā)送完之前,我們還需要有個 flag 標(biāo)識一下現(xiàn)在處于發(fā)送流程中。
因此,serialX 需要進行一些改動:
`_serial_int_tx` 函數(shù)

       // 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 的底層驅(qū)動寫法也就不一樣了,多了一個判斷是否處于發(fā)送流程中的 api。start_tx stop_tx 也不僅僅是開關(guān)中斷那么簡單了,需要改變 intTxing 這個 flag 標(biāo)識發(fā)送流程狀態(tài)。

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

意思是說,當(dāng)芯片沒有“發(fā)送寄存器空中斷”支持的時候,我們需要用 `intTxing` 代替實現(xiàn)控制發(fā)送過程。

另外,發(fā)送寄存器也沒有空狀態(tài),`putc` 函數(shù)倒是可以判斷發(fā)送完成標(biāo)志,但是這樣就不能在中斷里調(diào)用 `putc` 了;不加發(fā)送完成判斷,就不能在輪詢發(fā)送中調(diào)用它。總之,輪詢發(fā)送和中斷發(fā)送不用用一樣的 `putc` 函數(shù)了。

已實現(xiàn)的功能有:

  • 中斷收發(fā)(可阻塞可非阻塞)


RA6M4

RA6M4 是一款 CM33 核 ARM 芯片,本以為它比 CM4 高級可以很容易實現(xiàn) CM4 上實現(xiàn)的操作。

但是,筆者也沒有從手冊中找到“發(fā)送寄存器空中斷”。所以 RA6M4 和 AB32VG1 有一樣的補救處理。
但是,筆者還發(fā)現(xiàn)另外一個問題,**如果是中斷發(fā)送,每次寫完 TDR 寄存器后,必須重新使能發(fā)送中斷**。不這樣做,就不會出現(xiàn)發(fā)送完成中斷。

雖然如此,連續(xù)發(fā)送多個字節(jié)仍然會出現(xiàn)發(fā)送中斷不觸發(fā)(或丟失)的情況,導(dǎo)致發(fā)送功能完全癱瘓(這也是 `intTxing` 引入的隱患)。

已實現(xiàn)的功能有:

  • 中斷接收(可阻塞可非阻塞)
  • 中斷發(fā)送(未完),暫時可以用輪詢發(fā)送代替

多說兩句,RA6M4 的 SCI 好像可以啟用 FIFO ,這樣一來串口收發(fā)寄存器就是帶 FIFO 的。遺憾的是筆者不會用啊,有會用的大佬可以嘗試移植一下,用 FIFO 了就相當(dāng)于用 DMA 了。

GD32F4

這個也可以做到和 STM32F4 一樣的程度,DMA 沒有發(fā)送標(biāo)志,只能繼續(xù)用 `dmaTxing` 。

已實現(xiàn)的功能有:

  • 輪詢收發(fā)
  • 中斷收發(fā)(可阻塞可非阻塞)
  • DMA收發(fā)(可阻塞可非阻塞)

注:只分配了 UART0 的 DMA 通道,如果其它的也需要開啟 DMA 請自行修改 `struct gd32_uart uarts` 數(shù)組變量分配 DMA 通道。

注:還有一點,rt-studio 里下載的 GD32F4 firmware 庫版本是很多年前的,現(xiàn)在已經(jīng)改動過好幾次了。筆者使用的 `gd32f4xx_usart.h` 版本是 “2020-09-30, V2.1.0, firmware for GD32F4xx” 。如有編譯錯誤請升級 firmware 庫。

結(jié)束語

關(guān)于 serialX 理論的部分,之前的文章已經(jīng)說的夠多了。這次是想在多種平臺上用實踐檢驗一下 serialX 理論的可行性。經(jīng)過這幾天的投入,最終多多少少有些收獲,還是很欣慰的。

匯總一下,目前可以適配的芯片包括如下幾類
1. 沒有 DMA ,只有串口接收發(fā)送中斷
2. 沒有“發(fā)送寄存器空”狀態(tài)或沒有“發(fā)送寄存器空”中斷
3. 帶接收 IDLE 檢測,帶“發(fā)送寄存器空”中斷
4. 帶 DMA ,并且至少有 DMA 半傳輸中斷和全傳輸中斷
5. 串口外設(shè)自帶收發(fā) FIFO (可認為是 DMA ,但是比 DMA 使用更簡單)

在此,特別感謝[嚜軒公告](https://club.rt-thread.org/u/7c37fff6229d1ccd)支援的開發(fā)板,最終完成了 serialX 在這些平臺上的實現(xiàn)。

下期預(yù)告,我們來扒一扒 serialX 的缺陷,對,它的缺陷。準(zhǔn)確的講是在 RTOS 上引入的坑有哪些以及怎么避免。

附 [serialX](https://gitee.com/thewon/serialX) 倉庫地址,感興趣的可以下載最新版 serialX 源碼。本文提到的幾種芯片的驅(qū)動也都已提交。

審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • ARM
    ARM
    +關(guān)注

    關(guān)注

    134

    文章

    9008

    瀏覽量

    366066
  • N32
    N32
    +關(guān)注

    關(guān)注

    0

    文章

    18

    瀏覽量

    7181
  • STM32F4
    +關(guān)注

    關(guān)注

    3

    文章

    194

    瀏覽量

    27950
  • RT-Thread
    +關(guān)注

    關(guān)注

    31

    文章

    1249

    瀏覽量

    39726
  • serialX
    +關(guān)注

    關(guān)注

    0

    文章

    7

    瀏覽量

    800
收藏 人收藏

    評論

    相關(guān)推薦

    2024 RT-Thread全球巡回 線下培訓(xùn)火熱來襲!

    親愛的RT-Thread社區(qū)成員們:我們非常高興地宣布,2024年RT-Thread全球開發(fā)者線下培訓(xùn)即將拉開帷幕!24年全球巡回培訓(xùn)將覆蓋超10座城市及國家,為開發(fā)者提供一個深入學(xué)習(xí)RT-Thread嵌入式開發(fā)的絕佳機會。
    的頭像 發(fā)表于 08-07 08:35 ?694次閱讀
    2024 <b class='flag-5'>RT-Thread</b>全球巡回 線下培訓(xùn)火熱來襲!

    【好書推薦】RT-Thread設(shè)備驅(qū)動開發(fā)指南

    近年來國內(nèi)芯片產(chǎn)業(yè)和物聯(lián)網(wǎng)產(chǎn)業(yè)的快速崛起,行業(yè)發(fā)展迫切需要更多人才,尤其需要掌握嵌入式操作系統(tǒng)等底層技術(shù)的人才。隨著RT-Thread被更廣泛地應(yīng)用于行業(yè)中,開發(fā)者對嵌入式驅(qū)動開發(fā)的需求越來越
    的頭像 發(fā)表于 08-01 08:35 ?410次閱讀
    【好書推薦】<b class='flag-5'>RT-Thread</b>設(shè)備<b class='flag-5'>驅(qū)動</b>開發(fā)指南

    6月6日杭州站RT-Thread線下workshop,探索RT-Thread混合部署新模式!

    6月6日下午我們將在杭州舉辦RT-Thread混合部署線下workshop,在瑞芯微RK3568平臺上實現(xiàn)同時運行RT-Thread和linux,本次workshop邀請到RT-Thread資深
    的頭像 發(fā)表于 05-28 08:35 ?349次閱讀
    6月6日杭州站<b class='flag-5'>RT-Thread</b>線下workshop,探索<b class='flag-5'>RT-Thread</b>混合部署新模式!

    2024 RT-Thread 全球技術(shù)大會演講議程發(fā)布!

    創(chuàng)造價值!2023RT-Thread全球技術(shù)大會匯集了人工智能、RISC-V、嵌入式、物聯(lián)網(wǎng)、安全、應(yīng)用、開發(fā)環(huán)境和工具等領(lǐng)域的行業(yè)專家和RT-Thread社區(qū)工
    的頭像 發(fā)表于 05-16 08:34 ?419次閱讀
    2024 <b class='flag-5'>RT-Thread</b> 全球技術(shù)大會演講議程發(fā)布!

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

    4月25日,下午我們將在北京舉辦RT-Thread混合部署線下workshop,在瑞芯微RK3568平臺上實現(xiàn)同時運行RT-Thread和linux,本次workshop邀請到RT-Thread資深
    的頭像 發(fā)表于 04-16 08:35 ?351次閱讀
    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平臺上實現(xiàn)同時運行RT-Thread和linux,本次workshop邀請到RT-Thread資深嵌入式軟件工程師農(nóng)曉明老師為您講
    的頭像 發(fā)表于 03-27 11:36 ?706次閱讀
    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平臺上實現(xiàn)同時運行RT-Thread和linux,本次workshop邀請到RT-Thread資深
    的頭像 發(fā)表于 03-27 08:34 ?435次閱讀
    4月10日深圳場<b class='flag-5'>RT-Thread</b>線下workshop,探索<b class='flag-5'>RT-Thread</b>混合部署新模式!

    就在本周!探索RT-Thread混合部署新模式!

    3月21日(本周)我們將在上海張江舉辦RT-Thread混合部署線下workshop,在瑞芯微RK3568平臺上的實現(xiàn)同時運行RT-Thread和linux,本次培訓(xùn)邀請到RT-Thread
    的頭像 發(fā)表于 03-20 08:34 ?451次閱讀
    就在本周<b class='flag-5'>四</b>!探索<b class='flag-5'>RT-Thread</b>混合部署新模式!

    恩智浦半導(dǎo)體正式加入RT-Thread全球合作伙伴計劃!

    前不久,恩智浦半導(dǎo)體正式加入RT-Thread全球合作伙伴計劃,成為RT-Thread高級會員合作伙伴。同時,RT-Thread現(xiàn)已成為恩智浦注冊合作伙伴(RT-Thread| 簡介合
    的頭像 發(fā)表于 03-14 10:40 ?519次閱讀
    恩智浦半導(dǎo)體正式加入<b class='flag-5'>RT-Thread</b>全球合作伙伴計劃!

    RT-Thread驅(qū)動開發(fā)指南進階-動手驅(qū)動先楫未適配的外設(shè)LCD

    經(jīng)過上一的《《RT-Thread設(shè)備驅(qū)動開發(fā)指南》基礎(chǔ)--以先楫bsp的hwtimer設(shè)備為例》闡述,可以大致了解到RT-thread設(shè)
    的頭像 發(fā)表于 02-25 11:04 ?2089次閱讀
    <b class='flag-5'>RT-Thread</b><b class='flag-5'>驅(qū)動</b>開發(fā)指南進階<b class='flag-5'>篇</b>-動手<b class='flag-5'>驅(qū)動</b>先楫未<b class='flag-5'>適配</b>的外設(shè)LCD

    RT-Thread設(shè)備驅(qū)動開發(fā)指南》基礎(chǔ)--以先楫bsp的hwtimer設(shè)備為例

    一、概述(一)RT-Thread設(shè)備驅(qū)動RT-Thread設(shè)備驅(qū)動開發(fā)指南》書籍是RT-thread官方出品撰寫,系統(tǒng)講解
    的頭像 發(fā)表于 02-24 08:16 ?1184次閱讀
    《<b class='flag-5'>RT-Thread</b>設(shè)備<b class='flag-5'>驅(qū)動</b>開發(fā)指南》基礎(chǔ)<b class='flag-5'>篇</b>--以先楫bsp的hwtimer設(shè)備為例

    RT-Thread設(shè)備驅(qū)動開發(fā)指南基礎(chǔ)—以先楫bsp的hwtimer設(shè)備為例

    RT-Thread設(shè)備驅(qū)動開發(fā)指南》書籍是RT-thread官方出品撰寫,系統(tǒng)講解RT-thread IO設(shè)備驅(qū)動開發(fā)方法,從三方面進行講解
    的頭像 發(fā)表于 02-20 16:01 ?1505次閱讀
    <b class='flag-5'>RT-Thread</b>設(shè)備<b class='flag-5'>驅(qū)動</b>開發(fā)指南基礎(chǔ)<b class='flag-5'>篇</b>—以先楫bsp的hwtimer設(shè)備為例

    BL808 RT-Thread Wi-Fi驅(qū)動適配

    BL808 WiFi 屬于 SOC 單芯片型無線 MCU,片上集成 WiFi 功能,移植 RT-Thread 過程中,需要使用 RT-Thread wlan 框架。
    的頭像 發(fā)表于 12-04 11:38 ?779次閱讀

    BL808 RT-Thread Wi-Fi 驅(qū)動適配

    BL808 WiFi 屬于 SOC 單芯片型無線 MCU,片上集成 WiFi 功能,移植 RT-Thread 過程中,需要使用 RT-Thread wlan 框架。 RT-Thread wlan
    的頭像 發(fā)表于 12-02 11:06 ?1286次閱讀
    BL808 <b class='flag-5'>RT-Thread</b> Wi-Fi <b class='flag-5'>驅(qū)動</b><b class='flag-5'>適配</b>

    RT-Thread qemu mps2-an385 bsp移植制作 :系統(tǒng)運行

    前面已經(jīng)讓 RT-Thread 進入了 entry 入口函數(shù),并且 調(diào)整 鏈接腳本,自動初始化與 MSH shell 的符號已經(jīng)預(yù)留, 進入了 RT-Thread 的初始化流
    的頭像 發(fā)表于 11-14 12:27 ?718次閱讀
    <b class='flag-5'>RT-Thread</b> qemu mps2-an385 bsp移植制作 :系統(tǒng)運行<b class='flag-5'>篇</b>