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

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

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

rt-thread驅(qū)動(dòng)篇之serialX阻塞超時(shí)返回

冬至子 ? 來(lái)源:出出啊 ? 作者:出出啊 ? 2023-08-28 15:50 ? 次閱讀

前言
盡管仍然很多癡男怨女在 v1 v2 身上跌倒、跌倒、繼續(xù)跌倒,仍然阻止不了他們飛蛾撲火式的被 v1 v2 的缺陷所吸引而殉情。

它一如既往的保持著優(yōu)良的特性,也有可能是很多人沒(méi)發(fā)現(xiàn),主要是接受它的人很少。不過(guò),這不影響今天它帶來(lái)新的特性。

阻塞超時(shí)
我們一直強(qiáng)調(diào),它有與之前非同一般的兩個(gè)概念“阻塞”“非阻塞”。雖然 v2 熱火朝天的提出了這兩個(gè)概念,但是實(shí)現(xiàn)的效果卻不盡人意。

在之前的正式文檔里,我沒(méi)膽量承認(rèn)一個(gè)事實(shí),那就是,阻塞讀在無(wú)數(shù)據(jù)可讀的時(shí)候?qū)⒂肋h(yuǎn)阻塞下去。某些應(yīng)用場(chǎng)景并不希望這樣,我們希望等待某設(shè)備響應(yīng),若干時(shí)間后無(wú)響應(yīng)超時(shí),我們返回繼續(xù)做其它工作,而不是被無(wú)響應(yīng)的設(shè)備永久占用。

給某些論壇提問(wèn)里的解答時(shí),我提到過(guò)幾次 serialX 可以通過(guò)以下技術(shù)手段應(yīng)對(duì)這種場(chǎng)景。

方法一
使用非阻塞模式打開(kāi),超時(shí)讀過(guò)程偽代碼可能如下這樣:

while(timeout > 0) {
read
sleep 1
timeout -= 1
}
if (timeout == 0) {
// timeout here
} else {
// no timeout
}
方法二
使用完成中斷 indicate 回調(diào)函數(shù)發(fā)消息,這也是官方提供的讀串口設(shè)備的“標(biāo)準(zhǔn)”方式

static void serial_thread_entry(void parameter)
{
char ch;
while (1)
{
/
從串口讀取一個(gè)字節(jié)的數(shù)據(jù),沒(méi)有讀取到則等待接收信號(hào)/
while (rt_device_read(serial, -1, &ch, 1) != 1)
{
/
阻塞等待接收信號(hào)量,等到信號(hào)量后再次讀取數(shù)據(jù) */
rt_sem_take(&rx_sem, timeout);
}
...
}
}
注:此段代碼改編自官方文檔

大多數(shù)人第一次使用 rtt 的串口設(shè)備也是用這段代碼測(cè)試的。但是,serialX 不提倡大家使用 indicate 回調(diào)函數(shù)。

serialX 有它自己的特性,它有它自己的優(yōu)美性,那就是盡可能不給應(yīng)用層代碼帶來(lái)麻煩,不要寫(xiě)太復(fù)雜難懂的邏輯,不要給應(yīng)用層引入莫名未知的后果。

我們希望在不影響不改變之前的使用的前提下,rt_device_read 能夠在預(yù)定的時(shí)間內(nèi)超時(shí)返回退出,并不是用于阻塞下去,同時(shí) rt_device_read 返回 -RT_ETIMEOUT 錯(cuò)誤碼。應(yīng)用層可以根據(jù) rt_device_read 返回值

== 0 無(wú)數(shù)據(jù)
0 有數(shù)據(jù)

< 0 有錯(cuò)誤(-RT_ETIMEOUT 超時(shí))
分別處理不同情況。
serialX 的實(shí)現(xiàn)
首先,rtdef.h 添加定義,用于設(shè)備超時(shí)配置

#define RT_DEVICE_CTRL_TIMEOUT 0x30 /**< timeout for blocking */
其次,struct rt_serial_device 添加 rt_tick_t timeout_tick; 變量,設(shè)備超時(shí)時(shí)間 tick 。

然后,rt_serial_control 函數(shù)添加超時(shí)配置宏選項(xiàng)處理

case RT_DEVICE_CTRL_TIMEOUT:
    rt_tick_t timeout_tick = (rt_tick_t)args;
    serial- >timeout_tick = timeout_tick;
break;

最后,在 serialX.c 文件中所有涉及到阻塞的地方(包括讀寫(xiě),不包含 flush)修改 rt_completion_wait 第二個(gè)參數(shù)為 serial->timeout_tick。并當(dāng) rt_completion_wait 返回 -RT_ETIMEOUT 時(shí)退出當(dāng)前讀寫(xiě)操作返回應(yīng)用層。

注意:特別說(shuō)明,我們希望一個(gè)設(shè)備以阻塞模式打開(kāi)時(shí),默認(rèn)的阻塞超時(shí)時(shí)間是“永久”,所以,每次 rt_device_open 后 serialX 設(shè)定阻塞超時(shí)時(shí)間時(shí)間是 RT_WAITING_FOREVER 。如果需要指定某超時(shí)時(shí)間需要 rt_device_control(serial_dev, RT_DEVICE_CTRL_TIMEOUT, &timeout);

rt_tick_t timeout = 50;
if (rt_device_open(scpi_uart_dev, RT_DEVICE_OFLAG_RDWR
                           | RT_DEVICE_FLAG_INT_RX
                           | RT_DEVICE_FLAG_INT_TX
                           | RT_DEVICE_OFLAG_BLOCKING) != RT_EOK)
{
    rt_kprintf("Open device: %s failedn", UART_DEV_NAME);
    return;
}
rt_device_control(serial_dev, RT_DEVICE_CTRL_TIMEOUT, &timeout);
rt_ssize_t ret = rt_device_read(serial_dev, -1, &recvbuf[0], 128);
if (ret == -RT_ETIMEOUT) {
    rt_device_close(serial_dev);
    return;
} else {
}

這就是今天我們要講的第三種方法,相比前兩種,這種方法更優(yōu)雅些,代碼邏輯也清晰。

總結(jié)
歡迎大家入坑 serialX。

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

    關(guān)注

    68

    文章

    19376

    瀏覽量

    230441
  • 回調(diào)函數(shù)
    +關(guān)注

    關(guān)注

    0

    文章

    87

    瀏覽量

    11596
  • 串口中斷
    +關(guān)注

    關(guān)注

    0

    文章

    67

    瀏覽量

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

    關(guān)注

    31

    文章

    1300

    瀏覽量

    40264
  • serialX
    +關(guān)注

    關(guān)注

    0

    文章

    7

    瀏覽量

    808
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    RT-Thread記錄(一、版本開(kāi)發(fā)環(huán)境及配合CubeMX)

    RT-Thread 學(xué)習(xí)記錄的第一文章,RT-Thread記錄(一、RT-Thread 版本、RT-Thread Studio開(kāi)發(fā)環(huán)境 及
    的頭像 發(fā)表于 06-20 00:28 ?5300次閱讀
    <b class='flag-5'>RT-Thread</b>記錄(一、版本開(kāi)發(fā)環(huán)境及配合CubeMX)

    rt-thread 驅(qū)動(dòng)(六)serialX弊端及解決方法

    serialX 作為一個(gè)非阻塞串口驅(qū)動(dòng)框架,在遇到一些異常時(shí),需要做一些特殊處理,今天,筆者帶大家來(lái)扒一扒 serialX 使用過(guò)程中需要注意哪些問(wèn)題。
    的頭像 發(fā)表于 06-20 11:43 ?3594次閱讀

    RT-Thread ssd1306驅(qū)動(dòng)

    RT-Thread 驅(qū)動(dòng)ssd1306
    的頭像 發(fā)表于 04-21 10:08 ?26.5w次閱讀
    <b class='flag-5'>RT-Thread</b> ssd1306<b class='flag-5'>驅(qū)動(dòng)</b>

    rt-thread驅(qū)動(dòng)資料下載

    前提下,用 32 位無(wú)符號(hào)整型 timer_cnt,最大可以處理時(shí)間僅有 4294.967295s。精度 PK2、rt-thread驅(qū)動(dòng)serialX全網(wǎng)公測(cè)STM32 中斷模式測(cè)試
    發(fā)表于 03-24 15:37

    RT-Thread系統(tǒng)的信號(hào)如何進(jìn)行管理和使用呢

    進(jìn)入就緒狀態(tài)去處理對(duì)應(yīng)的信號(hào)處于運(yùn)行狀態(tài),系統(tǒng)會(huì)創(chuàng)建新的??臻g去處理對(duì)應(yīng)的信號(hào)管理信號(hào)在 RT-Thread 中,對(duì)信號(hào)的操作包括以下幾種:安裝信號(hào)、阻塞信號(hào)、解除阻塞、信號(hào)發(fā)送、信號(hào)等待。1.安裝
    發(fā)表于 03-31 14:01

    rt-thread驅(qū)動(dòng)serial v1 v2 和 X測(cè)試

    測(cè)試回環(huán)測(cè)試數(shù)據(jù)丟失率其它未測(cè)試項(xiàng):stream 支持,因?yàn)?v1 v2 只有 poll 模式支持, serialX 可以全模式支持,這一項(xiàng)未進(jìn)行對(duì)比。測(cè)試環(huán)境rt-thread
    發(fā)表于 04-14 14:36

    【原創(chuàng)精選】RT-Thread征文精選技術(shù)文章合集

    軟件包)NO2 專(zhuān)欄作者 :出出簡(jiǎn)介:rt-thread 研究。1. rt-thread 驅(qū)動(dòng)rt-thread
    發(fā)表于 07-26 14:56

    測(cè)試serialX的posix支持詳解

    Terminal I/O “其它項(xiàng)可以取消選擇。測(cè)試我們繼續(xù)使用 rt-thread 驅(qū)動(dòng) serialX 全網(wǎng)公測(cè) 提供的測(cè)試方案
    發(fā)表于 02-14 11:29

    RT-Thread編程指南

    RT-Thread編程指南——RT-Thread開(kāi)發(fā)組(2015-03-31)。RT-Thread做為國(guó)內(nèi)有較大影響力的開(kāi)源實(shí)時(shí)操作系統(tǒng),本文是RT-Thread實(shí)時(shí)操作系統(tǒng)的編程指南
    發(fā)表于 11-26 16:06 ?0次下載

    RT-Thread Studio驅(qū)動(dòng)SD卡

    RT-Thread Studio驅(qū)動(dòng)SD卡前言一、創(chuàng)建基本工程1、創(chuàng)建Bootloader2、創(chuàng)建項(xiàng)目工程二、配置RT-Thread Settings三、代碼分析1.引入庫(kù)2.讀入數(shù)據(jù)四、效果驗(yàn)證
    發(fā)表于 12-27 19:13 ?20次下載
    <b class='flag-5'>RT-Thread</b> Studio<b class='flag-5'>驅(qū)動(dòng)</b>SD卡

    rt-thread 驅(qū)動(dòng)(五)serialX 小試牛刀

    終于來(lái)到了 serialX 的實(shí)踐,期待很久了。
    的頭像 發(fā)表于 06-16 11:29 ?4613次閱讀
    <b class='flag-5'>rt-thread</b> <b class='flag-5'>驅(qū)動(dòng)</b><b class='flag-5'>篇</b>(五)<b class='flag-5'>serialX</b> 小試牛刀

    RT-Thread文檔_RT-Thread 簡(jiǎn)介

    RT-Thread文檔_RT-Thread 簡(jiǎn)介
    發(fā)表于 02-22 18:22 ?5次下載
    <b class='flag-5'>RT-Thread</b>文檔_<b class='flag-5'>RT-Thread</b> 簡(jiǎn)介

    RT-Thread文檔_RT-Thread SMP 介紹與移植

    RT-Thread文檔_RT-Thread SMP 介紹與移植
    發(fā)表于 02-22 18:31 ?9次下載
    <b class='flag-5'>RT-Thread</b>文檔_<b class='flag-5'>RT-Thread</b> SMP 介紹與移植

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

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

    【S32K146 RT-Thread 使用SFUD組件驅(qū)動(dòng)spi flash

    【S32K146 RT-Thread 使用SFUD組件驅(qū)動(dòng)spi flash
    的頭像 發(fā)表于 11-21 01:05 ?357次閱讀
    【S32K146 <b class='flag-5'>RT-Thread</b>】<b class='flag-5'>之</b> 使用SFUD組件<b class='flag-5'>驅(qū)動(dòng)</b>spi flash