歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Linux下串口操作之數據拼接

Linux串口操作中,特別以非阻塞的方式讀取和發送數據,做好進程之間的同步很重要。有時我們會發現這樣一個問題,在進行read操作時,一次read不能獲得一個完整的數據幀,這就好比你買了一個電腦,送貨的先把顯示器送到你家,再把機箱送到,你會發現還少鍵盤鼠標什麼的,又要過幾天才送,這會讓你急死。很不幸,在串口操作的時候,接受數據很可能就是這樣分批收貨的,但是幸運的是,接受數據的動作很快,別忘了計算機就是靠速度這一點,拋開這個,啥都不是。

很自然的,我們就會進行數據的拼接,將一堆零散的數據拼接成一個個有用的數據幀,哈哈,變廢為寶。說多了讓人很煩,舉個例子吧。

假如我們定義的數據幀是以'$'開頭,以‘#’結尾的。

首先定義了兩個字符數組:

//一個緩沖數組,用來存放每一次讀到的數據
char read_data[256]={0};
//存放一個完整的數據幀,以便處理
char read_buf[256]={0};

再看看憑借數據的函數是怎麼樣實現的:

//得到了一個完整的數據幀
void get_complete_frame()
{
    char read_tmp[256]={0};
    int return_flag=0;
    int i;
    //存放讀取到的字節數
    while(1)
    {
      memset(read_tmp,0,sizeof(read_tmp));
      if(read(fd, read_tmp, sizeof(read_tmp))>0)
      {
        //數據幀的拼接
        printf("read_tmp: %s\n",read_tmp);
        for( i=0;i<strlen(read_tmp);i++)
        {
              if(read_tmp[i]=='$')
              {
                memset(read_data,0,sizeof(read_data));
                char tmp[5]={0};
                tmp[0]=read_tmp[i];
                strcat(read_data,tmp);
              }
              else if(read_tmp[i]=='#')
              {
                char tmp[5]={0};
                tmp[0]=read_tmp[i];
                strcat(read_data,tmp);
                return_flag=1;
                memset(read_buf,0,sizeof(read_buf));
                //遇到幀尾,將read_data幀拷貝到read_buf中,以便處理
                memcpy(read_buf,read_data,sizeof(read_data));
              }
              else
              {
                  char tmp[5]={0};
                tmp[0]=read_tmp[i];
                strcat(read_data,tmp);
              }
        }
        //有了一個完整的數據幀就返回處理
        if(return_flag==1)
            return;
      }
      else//讀不到數據就返回,以便檢查對方是否斷線
        return;
    usleep(100000);
    }
}

從上面的代碼中,我們可以看到,每一次從串口讀取數據,將讀到的數據放在read_tmp中。對這個數組進行逐個地字符分析,遇到幀頭標志就清空緩沖數組read_data中,保證了緩沖數組中的數組都是以‘$’開頭的;如果遇到了幀尾,哈,我們現在遇到有了一個完整的幀啦,可以去處理幀咯,將數據幀拷貝到read_buf中,程序直接對read_buf進行處理,處理之前別忘了幀尾後面的字符是新的一桢的開頭部分,要把它們也保存下來。在程序中我們看到讀不到數據就返回,如果不返回,這個函數就會一直運行,那麼這樣做的效果不就等價於阻塞操作了麼,非阻塞就失去了其意義。

大概就這樣吧。

Copyright © Linux教程網 All Rights Reserved