色猫咪av在线网址_91精品国产福利在线观看雪梨还会玩转热点_丁香花的视频免费观看_国产手机在线A∨免费视频_十八禁av无码免费网站APP_综合色一区二区亚洲_日韩精品小电影_漂亮人妻熟睡中被公侵犯_全新成人高清无码片_高级厕所偷窥白领美女嘘嘘

當(dāng)前位置: 首頁(yè) >應(yīng)用方案 >技術(shù)應(yīng)用 >

嵌入式開(kāi)發(fā)遇到數(shù)據(jù)轉(zhuǎn)換解決數(shù)據(jù)流過(guò)大的解決辦法

痛苦!數(shù)據(jù)流過(guò)大?數(shù)據(jù)轉(zhuǎn)換各種組包拆包?指針數(shù)組你試過(guò)沒(méi)!

今天的是干貨,是真的干。作為一個(gè)從業(yè)4年,工齡6年的嵌入式開(kāi)發(fā)程序員,在做通訊設(shè)備領(lǐng)域時(shí)最痛苦的事莫過(guò)于數(shù)據(jù)流過(guò)大問(wèn)題,以及數(shù)據(jù)轉(zhuǎn)換時(shí)各種組包拆包等問(wèn)題,特別是在控制器內(nèi)存資源有限時(shí)。這種問(wèn)題更加突出。

拿以太網(wǎng)+串口傳輸modbus指令舉例:

以太網(wǎng)數(shù)據(jù)收發(fā)時(shí)以太網(wǎng)的協(xié)議棧占用內(nèi)存約20Kbyte,單個(gè)SOCKET傳輸數(shù)據(jù)時(shí)最少預(yù)留了532byte字節(jié)的緩存空間,當(dāng)取出網(wǎng)絡(luò)下傳的數(shù)據(jù)時(shí),需要拆掉網(wǎng)絡(luò)傳輸頭并在末尾增加CRC,串口上行數(shù)據(jù)時(shí),需要增加網(wǎng)絡(luò)傳輸數(shù)據(jù)頭以及去掉末尾CRC值,如果此時(shí)碰到慣用for循環(huán)copy數(shù)據(jù)或者使用memcpy函數(shù)進(jìn)行數(shù)據(jù)組包的大佬,內(nèi)存空間基本就是捉襟見(jiàn)肘。

解決以上問(wèn)題的辦法之一就是使用指針配合數(shù)組進(jìn)行組包與拆包,如下圖;

預(yù)留包頭46字節(jié)

數(shù)據(jù)部分536字節(jié)

末尾預(yù)留10字節(jié)

網(wǎng)絡(luò)端向串口發(fā)送:聲明數(shù)組時(shí)申明比實(shí)際數(shù)據(jù)所需空間更大的數(shù)組unsigned char Buff[592],以及一個(gè)指針unsigned char *datapoint;將datapoint指向Buff[46]的位置,讀入數(shù)據(jù),將數(shù)據(jù)從指針datapoint指向的位置開(kāi)始存入數(shù)組,同時(shí)使用另外的變量unsigned int length存儲(chǔ)當(dāng)次讀入的數(shù)據(jù)的長(zhǎng)度,進(jìn)行數(shù)據(jù)拆包操作時(shí)(去包頭6字節(jié)),直接將指針datapoint指向Buff[52]的位置,隨后將計(jì)算所得CRC2byte)值從Buff[46 + length]位置存入數(shù)組,并得出最終需要傳輸?shù)拈L(zhǎng)度length+2,串口發(fā)送數(shù)據(jù)只需要輸入起始地址datapoint,長(zhǎng)度length,將數(shù)據(jù)存入串口發(fā)送環(huán)形隊(duì)列即可完成發(fā)送。

代碼如下

unsigned char Buff[592];

unsigned char *datapoint;

unsigned int length;

datapoint = & Buff[46];//指針指向數(shù)組中間

net_dataread(datapoint,& length);//讀取數(shù)據(jù),獲得數(shù)據(jù)長(zhǎng)度

CRC(&Buff[46+length],datapoint,& length);//獲取校驗(yàn)值并存入數(shù)組

Uart_send(datapoint,length+2);

串口向網(wǎng)絡(luò)發(fā)送時(shí),數(shù)據(jù)從環(huán)形隊(duì)列讀出,需要加上TCP modbus協(xié)議的包頭部分(6byte),去掉CRC校驗(yàn),同樣聲明數(shù)組以及指針、長(zhǎng)度變量,將datapoint指向Buff[46]的位置,讀入數(shù)據(jù),將數(shù)據(jù)從指針datapoint指向的位置開(kāi)始存入數(shù)組;將指針指向當(dāng)前指向地址的前6個(gè)地址位置存入6字節(jié),然后按照新的datapoint位置,長(zhǎng)度length+4將數(shù)據(jù)從網(wǎng)絡(luò)發(fā)出;

代碼如下

unsigned char Buff[592];

unsigned char *datapoint;

unsigned int length;

datapoint = & Buff[46];//指針指向數(shù)組中間

uart_read(datapoint,& length);//讀取數(shù)據(jù),獲得數(shù)據(jù)長(zhǎng)度

datapoint = datapoint-6;

memcpy(datapoint,包頭暫存數(shù)組首地址,6);

Uart_send(datapoint,length+4);

以上實(shí)例簡(jiǎn)單說(shuō)明了利用指針組包的簡(jiǎn)單應(yīng)用,但是在實(shí)際應(yīng)用中可能由于設(shè)備需要使用多種協(xié)議,組包方式不同,例如包頭之前加入注冊(cè)包等,數(shù)據(jù)實(shí)際讀取完成之后不是直接操作而是直接傳入子函數(shù),進(jìn)行組包與拆包,此時(shí)僅需要傳入datapoint與長(zhǎng)度,進(jìn)子函數(shù),由于datapoint指向的數(shù)組前后均有預(yù)留空間,子函數(shù)內(nèi)依然可以使用指針,且在Buff[]數(shù)組的范圍內(nèi),指針可以前后自由移動(dòng),在不需要進(jìn)行大量數(shù)據(jù)拷貝的前提下完成數(shù)組的拆組包過(guò)程,同時(shí)也避免了反復(fù)拷貝數(shù)據(jù)對(duì)空間的浪費(fèi)。

      以上就是指針的簡(jiǎn)單應(yīng)用之一,指針除了對(duì)數(shù)組,還可以對(duì)函數(shù)操作,結(jié)合結(jié)構(gòu)體,基本上可以在C語(yǔ)言中實(shí)現(xiàn)類(lèi)似C++中類(lèi)功能

今天的分享就到這里啦,EBYTE每一天都致力于更好的助力物聯(lián)化、智能化、自動(dòng)化的發(fā)展,提升資源利用率,更多產(chǎn)品及相關(guān)資料,感興趣的小伙伴可以登錄我們的億佰特官網(wǎng)進(jìn)行了解,也可以直接撥打400電話咨詢技術(shù)專員!


4000-330-990

https://www.wjx.cn/jq/84863372.aspx