国产精品久久久aaaa,日日干夜夜操天天插,亚洲乱熟女香蕉一区二区三区少妇,99精品国产高清一区二区三区,国产成人精品一区二区色戒,久久久国产精品成人免费,亚洲精品毛片久久久久,99久久婷婷国产综合精品电影,国产一区二区三区任你鲁

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

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

3天內不再提示

基于serialX串口驅動移植freemodbus

冬至子 ? 來源:出出啊 ? 作者:出出啊 ? 2023-10-13 14:54 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

關于 serialX
之前,筆者寫過多篇 serialX 的文章,已經把它的原理和理念完完全全明明白白講了,包括它的優勢以及使用它需要注意的方面和可能遇到的問題。

到目前為止,筆者只介紹了 finsh/msh 使用 serialX ,實現了中斷接收中斷發送模式打開串口設備,這次嘗試讓筆者堅信了即便使用 DMA 收發也能在 finsh 里應付自如。今天我們嘗試一下在 freemodbus 里使用 serialX 。

注:筆者寫過文章,討論在控制臺或者 finsh 里完全的中斷收發或者完全的 DMA 收發會有哪些問題。有興趣的大家可以找找看。

測試環境
筆者手里有一塊兒 NK-980IOT V1.0 的開發板,這是去年 rt-thread 論壇搞的測評活動送的。一方面,它吃灰很久了,另一方面,serialX 的驅動很久沒新增了。趁此機會,筆者把 NUC980 的 serialX 驅動加上,然后在此基礎上調試出 console 和 finsh,最后移植 freemodbus 試試會遇到什么問題。

NUC980 serialX 驅動
之前,筆者介紹 serialX 的時候,曾詳細的講解過 struct rt_uart_ops 接口中的每一個函數的功能。完全按照每一個函數功能定義去做,后面的事情就是水到渠成的。

花了小半天的時間從 drv_uart.c 改成 drv_uartX.c 。

然后使用 serialX 中提供的 測試程序 serialX_test.c 簡單測試了一下,收發回環沒發現嚴重問題(沒有數據丟失,沒有數據錯誤)。

啟用控制臺和 finsh 。改成“中斷收發讀寫”模式,試了幾個命令,打印結果完整。

可以說,驗證了這次寫的驅動還是很不錯的,是成功的。

啟用 freemodbus
env 環境里啟用 freemodbus,打開 modbus master 并添加 master 的測試程序。
使用命令 pkgs --update 下載 freemodbus 源碼。

打開項目后,我們可以看到 “sample_mb_master.c” “port” 開頭的以及幾個 “mb” 開頭的。”sample_mb_master.c” 文件是測試樣例程序,”port” 開頭的文件是 freemodbus 在 rt-thread 系統上的接口,剩余的是 freemodbus 的核心程序。

這里面 “sample_mb_master.c” “portserial_m.c” 這兩個文件是今天我們最關心的。我們可以打開看看這倆文件都做了啥。

“sample_mb_master.c”
這個文件的主要工作是創建了兩個線程。

一個用來循環調用 eMBMasterPoll 函數,這個函數是 freemodbus 工作引擎。不循環執行這個函數 freemodbus 跑不起來。

另一個模式應用層線程,用來發送多寄存器寫請求(在這個樣例程序里只用這個來做演示)。

“portserial_m.c”
這個文件里是串口設備操作相關的。比如初始化、打開、關閉,寫數據到串口設備,從串口設備讀數據等等。

xMBMasterPortSerialInit
筆者第一次打開這個文件,滿眼看到的 serial->config. serial->ops->configure 等操作把我驚呆了。

初始化過程最后創建了子線程 serial_soft_trans_irq ,它的工作就是發送數據。

serial_soft_trans_irq
發送子線程入口函數,這個函數只關心 EVENT_SERIAL_TRANS_START 事件,接收到事件后調用 xMBMasterRTUTransmitFSM 函數,如果數據沒發送完,調用 xMBMasterPortSerialPutByte->xMBMasterPortSerialPutByte 往串口寫 1 個字節數據。循環執行直到把所有需要發送的數據寫完。

第一次測試
經過簡單瀏覽后,筆者想盡快運行程序,做進一步觀察。

計算機端,筆者用一個 Qt5 寫的 modbus slave 終端。如果一切順利,NK-980IOT 開發板上發的多寄存器寫請求會對 Qt5 modbus slave 終端里的數據修改,并界面上顯示到數據變化。

很幸運,筆者這一步也很順利。

進一步測試
因為自帶的 master 樣例程序僅僅測試了一個多寄存器寫,而且,我們可以看到原來只對 eMBMasterReqWriteMultipleHoldingRegister 返回錯誤代碼計數,并沒有區分判斷會出現哪種錯誤,我們把這個錯誤碼處理一下

rt_uint32_t err_no = 0, err_reg = 0, err_arg = 0, err_data = 0, err_tout = 0;
switch (error_code) {
case MB_MRE_NO_ERR:
    err_no++;
break;
case MB_MRE_NO_REG:
    err_reg++;
break;
case MB_MRE_ILL_ARG:
    err_arg++;
break;
case MB_MRE_REV_DATA:
    err_data++;
break;
case MB_MRE_TIMEDOUT:
    err_tout++;
break;
default:
    rt_kprintf("n:%d; r:%d; a:%d; d:%d; t:%dn", err_no, err_reg, err_arg, err_data, err_tout);
break;
}

這幾種返回碼,只有 MB_MRE_NO_ERR 是正常和完美的,如果出現其它幾個都是有問題的。

筆者經過關閉 slave 端,可以測試出現 MB_MRE_TIMEDOUT 。但是,經常還會出現 MB_MRE_REV_DATA 這個錯誤!!!

MB_MRE_REV_DATA 錯誤跟蹤
這個錯誤字面含義是,有接收數據,但是接收的數據有異常!我們上面的測試只有一個“多寄存器寫”,master 發寫請求了以后,只有可能收到成功響應(MB_MRE_NO_ERR),或者錯誤響應信息(MB_MRE_NO_REG MB_MRE_ILL_ARG)。不應該會出現 slave 給 master 主動發請求的。

為了觀察 slave 端接收和發送數據,筆者計劃把 slave 端的調試打開,檢查一下它是不是回復響應出現錯誤了。

因為筆者的 slave 端是 Qt 寫的,當前使用的這個 exe 是很久之前用 Qt5.9 版本編譯出來的。筆者需要重新編譯一下這個 exe 程序(現在安裝的版本有 Qt5.12 Qt5.15 兩個)。編譯出來新程序之后,筆者得到如下調試信息(無論是 Qt5.12 還是 Qt5.15),

qt.modbus.lowlevel: (RTU server) Received ADU: "01100000000408000f0049000200003574"
qt.modbus: (RTU server) Request PDU: 0x100000000408000f004900020000
qt.modbus: (RTU server) Response PDU: 0x1000000004
qt.modbus.lowlevel: (RTU server) Response ADU: "011000000004c1ca"
qt.modbus.lowlevel: (RTU server) Received ADU: "011000000004080013004b000200009175"
qt.modbus: (RTU server) Request PDU: 0x1000000004080013004b00020000
qt.modbus: (RTU server) Response PDU: 0x1000000004
qt.modbus.lowlevel: (RTU server) Response ADU: "011000000004c1ca"
qt.modbus.lowlevel: (RTU server) Received ADU: "011000000004080027004d000200006cb6"
qt.modbus: (RTU server) Request PDU: 0x1000000004080027004d00020000
qt.modbus: (RTU server) Response PDU: 0x1000000004
qt.modbus.lowlevel: (RTU server) Response ADU: "011000000004c1ca"

slave 斷得到了完整正確的 ADU,響應的 ADU 也是正常的。接下來再回過頭看看開發板接收響應 ADU 時得到的數據是什么。
在 eMBMasterRTUReceive 函數體內 if 條件語句之前添加一句代碼 od_mem((unsigned int)ucMasterRTURcvBuf, (unsigned int)ucMasterRTURcvBuf + usMasterRcvBufferPos);。這句代碼將在控制臺打印輸出接收到的 ADU 。

筆者看到了很多 “01040004 70F9C1” “01040004 70F9F9” 或者其它數據,但是正確的應該是 “01100000 0004C1CA”,很多次才出現一次正確的。為什么從串口發出去的數據是正確的,能被遠端正常接收,遠端響應回來的數據就出現接收錯誤了?!

為了確定開發板和驅動工作還是正常的,筆者又切換到 serialX 的測試程序,用收發回環測試一遍沒有問題,再測試 freemodbus 接收仍然異常!

修改 xMBMasterPortSerialInit
前邊筆者說過,當看到 serial->config. serial->ops->configure 等操作時驚呆了。這一步,讓上帝的歸上帝吧。

serial_dev = rt_device_find(uart_name);
if(serial_dev == RT_NULL)
{
    /* can not find uart */
    return FALSE;
}
/* set serial configure parameter */
uart_conf.baud_rate = ulBaudRate;
/* set serial configure */
rt_device_control(serial_dev, RT_DEVICE_CTRL_CONFIG, &uart_conf);
/* open serial device */
if (!rt_device_open(serial_dev, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_INT_TX)) {
    rt_device_set_rx_indicate(serial_dev, serial_rx_ind);
} else {
    return FALSE;
}

全局變量 static struct rt_serial_device *serial; 改成 static rt_device_t serial_dev = RT_NULL;。所有使用 serial 這個變量的地方全換成使用 serial_dev 。

這樣修改了以后,一切變得明朗了起來。

總結

除了上面提到的那個問題,筆者還遇到一種情況,slave 端接收串口數據經常出現斷幀,而且字符接收間隔長達 10+ms 。這種情況,當筆者將 rt_device_write(serial_dev, 0, pucByte, 1); 改成 rt_device_write(serial_dev, 0, pucByte, sz); 后得到解決。但是,之后再也沒復現。

得益于 serialX 的框架理念,我們可以從“一個字節一個字節的寫”提升到“寫一批字節”。而且放到發送緩存里的數據,無論使用中斷發送還是 DMA 發送都不會對應用層帶來任何壓力。

另一方面,讀 modbus ADU 的時候,其實也可以“讀一批字節”。不是一個字節中斷,read 一個字節,下一個接收字節中斷,再 read 一個字節…

freemodbus 還有很多可圈可點的地方。但是拿它來驗證 serialX 驅動可能是最簡單的一個了。

最后,筆者把修改過后的 ‘portserial_m.c’ 文件上傳上來,但是請大家注意,不止這一個文件需要修改,但是其它修改都是因為這個文件引起的。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 寄存器
    +關注

    關注

    31

    文章

    5608

    瀏覽量

    129957
  • 緩存器
    +關注

    關注

    0

    文章

    63

    瀏覽量

    12064
  • 串口驅動
    +關注

    關注

    2

    文章

    86

    瀏覽量

    19410
  • FreeModbus
    +關注

    關注

    0

    文章

    17

    瀏覽量

    5077
  • serialX
    +關注

    關注

    0

    文章

    7

    瀏覽量

    875
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    STM32驅動串口屏,STM32F103C8T6串口發送指令控制HMI串口

    串口串口屏是一個集成了單片機的屏幕模塊,采用的是TTL串口協議,可以直接通過對應指令控制屏幕, 本文采用的串口屏是陶晶馳T0系列的基本型,目的是通過單片機的
    的頭像 發表于 02-10 17:07 ?137次閱讀
    STM32<b class='flag-5'>驅動</b><b class='flag-5'>串口</b>屏,STM32F103C8T6<b class='flag-5'>串口</b>發送指令控制HMI<b class='flag-5'>串口</b>屏

    迅為驅動開發實戰:iTOP-RK3568開發板eDP屏幕移植全攻略

    迅為驅動開發實戰:iTOP-RK3568開發板eDP屏幕移植全攻略
    的頭像 發表于 12-30 15:42 ?892次閱讀
    迅為<b class='flag-5'>驅動</b>開發實戰:iTOP-RK3568開發板eDP屏幕<b class='flag-5'>移植</b>全攻略

    串口調試步驟(適合免驅動的232串口設備)

    基礎環境:麒麟系統,最好能聯網以便于更新插件 將串口設備插入主板卡槽 進入命令行 bash dmesg | grep tty 查看新增的串口是否識別,如果識別回新增幾個串口 sudo su 輸入用戶
    的頭像 發表于 12-17 17:23 ?1445次閱讀
    <b class='flag-5'>串口</b>調試步驟(適合免<b class='flag-5'>驅動</b>的232<b class='flag-5'>串口</b>設備)

    串口發送數據的過程中,會中間停幾毫秒,為什么?

    串口發送數據的過程中,會中間停幾毫秒,導致PLC觸發了MODBUS的T3.5,數據接收不對, 1、一開始用的是freemodbus,查看后發現是輪詢發送,后來改為不用freemodbus,直接發
    發表于 09-29 07:51

    移植rtthread_NANO之后SPI通訊不了怎么解決?

    1、我的裸板程序是一個SPI例程,沒有移植rtthread_NANO之前SPI值正常的; 2、按照官方MDK的方法移植了rtthread_NANO之后,什么都沒有增加,就是移植完了就不正常; 3
    發表于 09-11 06:46

    STM32H743以太網驅動移植異常怎么解決?

    單片機:STM32H743II PHY:LAN8720 開發環境:Keil 移植以太網驅動時,遇到異常。 使用的drv_eth.c drv_eth.h的版本信息如下圖所示, 編譯運行之后,顯示的異常如下圖所示, 使用ifconfig,打印信息如下圖所示, 麻煩給看下
    發表于 09-10 07:52

    msh突然無法使用,不顯示是怎么回事?

    基于rtt nano移植了agile_modbus_rtu的從機與freemodbus的tcp程序,在修改 #define FINSH_THREAD_STACK_SIZE 4096前大小為1024
    發表于 09-02 08:13

    如何將 FreeMODBUS 從屬 RTU 模式移植到 M032 系列微控制器?

    如何將 FreeMODBUS 從屬 RTU 模式移植到 M032 系列微控制器
    發表于 08-19 07:20

    RT-Thread Nano硬核移植指南:手把手實現VGLite圖形驅動適配 | 技術集結

    VGLite是NXP提供的輕量級2D圖形API,本文將手把手帶你實現VGLite圖形驅動適配RT-Thread。文章分為上、下兩篇,將手把手教您移植。上篇對RT-ThreadNano內核與Finsh組件進行移植,下篇則教您改寫S
    的頭像 發表于 07-17 14:40 ?3386次閱讀
    RT-Thread Nano硬核<b class='flag-5'>移植</b>指南:手把手實現VGLite圖形<b class='flag-5'>驅動</b>適配 | 技術集結

    【微五科技CF5010RBT60開發板試用體驗】基于FIFO的串口驅動移植xprintf實現標準輸入輸出與shell實現

    本文分享基于FIFO實現串口驅動,方便提供好用的串口收發接口,并基于串口驅動移植xprintf實
    發表于 06-27 22:37

    STM32G431移植FreeModbus

    STM32G431移植FreeModbus 的代碼已通過驗證,在WeActStudio的STM32G431CoreBoard上進行多次測試,均可正常讀取寄存器數值。STM32G431CoreBoard可在我上傳的相關文件下載。
    發表于 04-19 16:50 ?2次下載

    PL2303串口驅動

    PL2303串口驅動
    發表于 04-09 16:02 ?4次下載

    PL2303串口驅動win10版本用

    PL2303串口驅動win10版本用
    發表于 04-09 16:02 ?1次下載

    cp2102串口驅動

    cp2102串口驅動
    發表于 04-09 16:01 ?10次下載

    移植LWIP+FREERTOS時遇到的問題怎么解決?

    固件庫,移植成功,并且跑了幾個串口通信的任務,測試大概兩三天的樣子,并沒有出現問題。 2:移植LWIP1.4.1 (從ST官網下載的那個網頁的例程,修改引腳定義后跑在板子上沒問題,確認硬件沒問題) 3
    發表于 03-11 06:48