測(cè)試環(huán)境
開發(fā)板: NK-980IOT V1.0 的開發(fā)板
rt-thread 版本:4.1.1
IDE:keil + env
啟用 posix
首先,啟用 DFS:”RT-Thread Components” -> “DFS: device virtual file system” 。進(jìn)入子菜單,選擇
“Using posix-like functions, open/read/write/close”
“ Using devfs for device objects”
其它項(xiàng)可以取消選擇。
然后進(jìn)入 “RT-Thread Components” -> “C/C++ and POSIX layer” -> “POSIX (Portable Operating System Interface) layer” 子菜單項(xiàng),選擇
“Enable POSIX file system and I/O”
“Enable I/O Multiplexing select() “
“Enable Terminal I/O “
其它項(xiàng)可以取消選擇。
測(cè)試
我們繼續(xù)使用 rt-thread 驅(qū)動(dòng)篇 之 serialX 全網(wǎng)公測(cè) 提供的測(cè)試方案,但是把里面的讀寫 API 改一改,rt_device_open 改成 open,rt_device_read 改成 read,rt_device_write 改成 write,rt_device_close 改成 close。
我們知道, open/read/write/close 分別對(duì)應(yīng)調(diào)用 dfs_file_(open/read/write/close) 進(jìn)而調(diào)用 struct dfs_file_ops 結(jié)構(gòu)體中定義的 open/read/write/close 接口。在串口驅(qū)動(dòng)框架里就是 serial_fops_(open/read/write/close) 等幾個(gè)函數(shù)。
serial_fops_open
需要說明的是,我們只能選擇“中斷”或者“DMA”中的一種模式了。另外,除了 O_RDONLY O_WRONLY O_RDWR 三種讀寫標(biāo)志,還可以支持 O_NONBLOCK ,它等于 RT_DEVICE_OFLAG_NONBLOCKING。
serial_fops_read
原來的實(shí)現(xiàn)有如下一個(gè) while 循環(huán),這個(gè)循環(huán)的本意是:非阻塞模式下,如果沒有 read 到數(shù)據(jù)返回 -EAGAIN 錯(cuò)誤值,告知應(yīng)用層無數(shù)據(jù)并可以再次讀;阻塞模式下,如果沒有 read 到數(shù)據(jù)將等待工作隊(duì)列而掛起線程。
do
{
size = rt_device_read(device, -1, buf, count);
if (size <= 0)
{
if (fd- >flags & O_NONBLOCK)
{
size = -EAGAIN;
break;
}
rt_wqueue_wait(&(device- >wait_queue), 0, RT_WAITING_FOREVER);
}
}while (size <= 0);
這和原來 serialX 的阻塞模式概念是一致的,如此一來,我們發(fā)現(xiàn)阻塞模式時(shí) rt_device_read 先阻塞了,并不會(huì)走到 if 條件語句塊內(nèi)。
flush 概念
大家一定知道,flush 支持是 serialX 獨(dú)有的,v1 v2 沒有這個(gè)。當(dāng)我們開啟 posix 之后,發(fā)現(xiàn) dfs 實(shí)現(xiàn)了一個(gè)函數(shù) fsync ,同時(shí)還有一個(gè) dfs_file_flush 函數(shù),以及 struct dfs_file_ops 也定義了 flush 接口。只是在之前的版本里這個(gè)都沒有實(shí)現(xiàn)。于是,我們對(duì) “serialX.c” 做如下修改
找到 const static struct dfs_file_ops _serial_fops = 變量定義代碼行,將 RT_NULL, /* flush / 修改為 serial_fops_flush, / flush */ 。然后在上面添加 serial_fops_flush 函數(shù)實(shí)現(xiàn):
static int serial_fops_flush(struct dfs_fd *fd)
{
rt_device_t device;
device = (rt_device_t)fd->data;
return rt_device_flush(device);
}
瞧,serialX 的 flush 和 dfs 的 flush 以及 posix 的 fsync 銜接起來了。
select io 復(fù)用
之前設(shè)計(jì)的測(cè)試方案里,只有回環(huán)測(cè)試改動(dòng)比較大。這里我們使用 select 這個(gè)高級(jí)的用法,監(jiān)聽是否有數(shù)據(jù)。
用這種方式,我們可以同時(shí)監(jiān)聽多個(gè)串口設(shè)備了?;蛘哒f,一個(gè)線程“同時(shí)”讀多個(gè)串口設(shè)備。
termios
開啟了 posix ,串口設(shè)備修改波特率、數(shù)據(jù)位等需要使用 termios。這部分的問題留待下一篇 libmodbus 部分詳說。
總結(jié)
啟用了 posix 后我們發(fā)現(xiàn),posix 是在原來的設(shè)備驅(qū)動(dòng)框架基礎(chǔ)上套的一層殼。增加了函數(shù)調(diào)用跳轉(zhuǎn)次數(shù)。如果沒有必要的理由,還是不啟用 posix 了。
-
C++語言
+關(guān)注
關(guān)注
0文章
147瀏覽量
6987 -
Posix
+關(guān)注
關(guān)注
0文章
36瀏覽量
9496 -
RT-Thread
+關(guān)注
關(guān)注
31文章
1285瀏覽量
40081 -
DFS
+關(guān)注
關(guān)注
0文章
26瀏覽量
9162 -
FreeModbus
+關(guān)注
關(guān)注
0文章
16瀏覽量
4466
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論