linux串口通信协议编程详解

linux串口通信协议编程详解:

1.串口通信协议拟定;

2.通信校验--CRC;

3.Linux多线程编程;

1.串口通信协议;

1.1协议拟定:

项目

长度

定义

备注

帧头(head)

1

0xf4

恒不变

流水号(serial _num)

2

消息的流水号

累加(先低8位后高8位

长度

1

Length

帧总长(含前3字节,最大255)

属性

2

设备通信类型或数据类型、数据加密、校验方式、是否分包、数据类型、数据发送方式

低位对齐

数据包

PackageLength=Length-7

Package

承载的数据

校验

2

CRC16

使用CRC16算法对前面所有内容进行

帧尾

1

0x4f

恒不变

示例数据:

0xf4,0x00,0x17,0x03,0x00,0x11,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x78,0x67,0x4f

黑色部分为桢头

蓝色部分为流水号

紫色部分为长度

灰色部分是属性

红色部分为数据(可以将你们的数据放在此部分,长度最大64字节)

金色部分为校验(CRC16,具体算法参考后面提供的代码)

棕色部分尾帧尾

协议的初始化关于head(标示头)、serial_num(流水号)、length(数据长度)、properity(属性)、CRC(校验码)和tail(标示尾);

属性里包括:

5

4

3

2

1

0

定义通信的属性 比如设备类型

 

数据加密类型

校验方式

00 -> 

01 -> D5

10 -> 

11 -> others

00 - none

 

00 -> none

01 -> CRC

10 -> 

11 -> 

默认00 01 00 01 (low 8 bit)

15

14

13

12

11

10

9

8

7

6

是否采用分包

分包总长(0标示未分包 其他他数据标示包总长)

子包ID

(总共分为9包)

协议类型ID

000 - 111

000 - 111

0000 -> 1111


1.2系统框架图

发送端主要完成数据组包,转义和发送,组包需要设置数据长度、数据是否加密、使用什么样的校验方式、发送的类型、是否需要分包、设置分包ID

从缓存区读取数据并解析,拿到一包数据之后:

1.通过CRC校验判断数据是否有错,如果出错返回流水号(分包的话还要返回子包ID);

2.通过分析属性里的各个参数判断是否分包、数据类型、是否加密等属性然后解析出发送端数据;

1.3重点简介

接收端的处理:

1.在接收端设置一个缓存区,将从发送端的数据存放在缓存区内,接受的策略是当read函数返回的值为0时处理和当缓存区存满的时候处理,当缓存区满了的时候我们就从头开始继续写,覆盖原来的数据;

2.如何从读到的数据中分离出每包数据,通过我们设计的标示头和尾,当读到一个头这是头标记置为1,如果有连续的头,就舍弃前面的,当读到尾标识的时候,判断前面的头标记是否为1,若为1则说明找到了完整的一包数据,若果不为1直接舍弃。

数据分包处理:

1.发送端:当需要发送的数据大于协议拟定的长度的时候我们就需要进行分包操作,在属性里定义了分包总长和子包ID,方便我们在解析端进行接收和重组;

2.接收端:我们通过判断包总长确定接收的数据是否分包,因为分包的时候都是在数据满足协议数据最大长度的时候才进行分包,所以,在接收端的缓存我们可以通过子包ID来判断包的顺序和应该写入的位置,再出现丢包的时候,我们通过设置时间间隔判断是否丢包,每次接收到子包数据这时会获取系统的当前时间,当下次再接收到这个数据的时候进行判断,如果间隔大于一个阈值(自己设定)我们可以判定接受的数据出错,将原来的数据全部丢掉,重新接收。

2.CRC校验算法

    关于错误校验常用三种就是奇偶校验、累加和校验和CRC校验;前两种校验方法相信大家有有所了解,所以这里重点介绍一下CRC算法;

    CRC(循环冗余校验码):CRC 算法的基本思想是将传输的数据当做一个位数很长的数。将这个数除以另一个数。得到的余数作为校验数据附加到原数据后面。传输的时候将传输的数据和校验数据一块发送这个,在接收端我们利用接收到的数据利用“模二除法”除以利用的多项式,如果余数为0说明传输过程中没有差错,如果不为0表明传输过程中有错误。

step1:确认使用的多项式,通常我们会采用固定的多项式,常见的几种生成多项式如:

CRC8=X8+X5+X4+X0

CRC-CCITT=X16+X12+X5+X0

CRC16=X16+X15+X2+X0

CRC12=X12+X11+X3+X2+X0

CRC32=X32+X26+X23+X22+X16+X12+X11+X10+X8+X7+X5+X4+X2+X1+X0

生成多项式确定之后我们就可以进行算法编程: 从前面的介绍我们知道CRC校验核心就是实现无借位的除法运算(即模二除法)。下面还是通过一个例子来说明如何实现CRC校验。

假设我们的生成多项式为:100110001(简记为0x31),也就是CRC-8

则计算步骤如下:

(1)      将CRC寄存器(8-bits,比生成多项式少1bit)赋初值0

(2)      在待传输信息流后面加入8个0

(3)      While (数据未处理完)

(4)      Begin

(5)          If (CRC寄存器首位是1)

(6)              reg = reg XOR 0x31

(7)          CRC寄存器左移一位,读入一个新的数据于CRC寄存器的0 bit的位置。

(8)      End

(9)      CRC寄存器就是我们所要求的余数。

实际上,真正的CRC 计算通常与上面描述的还有些出入。这是因为这种最基本的CRC除法有个很明显的缺陷,就是数据流的开头添加一些0并不影响最后校验字的结果。这个问题很让人恼火啊,因此真正应用的CRC 算法基本都在原始的CRC算法的基础上做了些小的改动。

所谓的改动,也就是增加了两个概念,第一个是“余数初始值”,第二个是“结果异或值”。

所谓的“余数初始值”就是在计算CRC值的开始,给CRC寄存器一个初始值。“结果异或值”是在其余计算完成后将CRC寄存器的值在与这个值进行一下异或操作作为最后的校验值。

常见的三种CRC 标准用到个各个参数如下表。

 

CCITT

CRC16

CRC32

校验和位宽W

16

16

32

生成多项式

x16+x12+x5+1

x16+x15+x2+1

x32+x26+x23+x22+x16+

x12+x11+x10+x8+x7+x5+

x4+x2+x1+1

除数(多项式)

0x1021

0x8005

0x04C11DB7

余数初始值

0xFFFF

0x0000

0xFFFFFFFF

结果异或值

0x0000

0x0000

0xFFFFFFFF

 

加入这些变形后,常见的算法描述形式就成了这个样子了:

(1)      设置CRC寄存器,并给其赋值为“余数初始值”。

(2)      将数据的第一个8-bit字符与CRC寄存器进行异或,并把结果存入CRC寄存器。

(3)      CRC寄存器向右移一位,MSB补零,移出并检查LSB。

(4)      如果LSB为0,重复第三步;若LSB为1,CRC寄存器与0x31相异或。

(5)      重复第3与第4步直到8次移位全部完成。此时一个8-bit数据处理完毕。

(6)      重复第2至第5步直到所有数据全部处理完成。

(7)      最终CRC寄存器的内容与“结果异或值”进行或非操作后即为CRC值。

(代码实现)

  1. U16 crc16_check(U8 *data_ptr, U8 data_length)  
  2. {  
  3.     /*polynomial*/  
  4.     U16 crc_gen = 0xa001;  
  5.     U16 crc;  
  6.     U8 i, j;  
  7.   
  8.   
  9.     /*init value of crc*/  
  10.     crc = 0xffff;  
  11.     if (data_length != 0)  
  12.     {  
  13.         for (i = 0; i < data_length; i++)  
  14.         {  
  15.             crc ^= (U16)(data_ptr[i]);  
  16.             for (j = 0; j < 8; j++)  
  17.             {  
  18.                 if ((crc & 0x01)  == 0x01)     
  19.                 {  
  20.                     crc >>= 1;      
  21.                     crc ^= crc_gen;  
  22.                 }  
  23.                 else  
  24.                 {  
  25.                     crc >>= 1;  
  26.                 }  
  27.             }/*end for*/  
  28.         }/*end for*/  
  29.     }/*end if*/  
  30.     return crc;  
  31. }  

3.Linux多线程编程;

在任务实现的时候,我们通过多线程实现数据的接受和任务的执行,线程之间通过消息队列来进行通信;在接收端我们创建一个线程用于接收数据和预处理,这里的预处理主要是从接收得到的数据中解析出整包的数据并完成校验,确定得到一包正确的数据,然后将这个数据放在消息队列里;这个时候我们的接受线程就可以不断的接受和往消息队列里发送数据,在任务执行段再创建一个线程,用于任务处理,这里面主要实现的是从消息队列里面读取数据并解析。在消息队列创建的时候出现了一个消息队列ID为0的现象,不知道是什么原因。

这个实现的源代码如下:


  1. /************************************************************************* 
  2.     > Copyright (C), 2014,  
  3.     > File Name: scom_protocal.h 
  4.     > Author: xhniu   
  5.     > Mail:  
  6.     > Created Time: Fri 22 Aug 2014 04:45:03 PM CST 
  7.     > Description:  define the scom protocal,realize the data send/recv  
  8.                     escape_character/anti_escape_character data_process 
  9.                     multi thread program and inter thread communication with 
  10.                     message queue; 
  11.     > Version: V0.1  
  12.     > Function List: 
  13.         1.U8 serialport_init(INT8 port_fd, U32 baud_rate, 
  14.         2.U8 data_bits, U8 parity, U8 stop_bit); 
  15.         3.void scom_protocal_init(scom_protocal *protocal_info_ptr); 
  16.         4.INT8 open_port(void); 
  17.         5.U16 crc16_check(U8 *data_ptr, U8 data_length); 
  18.         6.U8 escape_character(U8 *package_data_ptr, U8 data_length,  
  19.                 U8 *buffer_ptr); 
  20.         7.U8 anti_escape_character(U8 *buffer_ptr, U8 *package_data_ptr, 
  21.                 U8 data_length); 
  22.         8.void  *tsk_run(INT8 *param_ptr); 
  23.         9.U8 data_process(U8 *data_proc_ptr, U8 data_start_pos, 
  24.                 U8 data_end_pos); 
  25.         10.U8 data_package(scom_protocal *protocal_info_ptr, 
  26.                 U8 *package_data_ptr, U8 data_length); 
  27.         11.U8 data_send(INT8 port_fd, scom_protocal *protocal_info_ptr, 
  28.                 U8 *data_send_ptr, U8 data_send_length); 
  29.         12.void *data_recv(recv_param *data_recv_info_ptr); 
  30.         13.U8 close_port(INT8 port_fd); 
  31.     > History: <author>  <date>    <version>     <desc> 
  32.                xhniu     14.09.12  V0.1          Completion of  
  33.                                                  multi-threaded programming 
  34.                xhniu     14.09.14  V0.1          add the msg_que  
  35.                xhniu     16.09.14  V0.1          add the tsk delete function 
  36.                                                  and free the system resource 
  37.                xhniu     18.09.14  V0.1            
  38.     > Others: naming rules is UNIX 
  39.               m_ member variable g_ globe variable 
  40.  ************************************************************************/  
  41. #include<stdlib.h>  
  42. #include<math.h>  
  43. #include<stdio.h>  
  44. #include<fcntl.h>          /*File control*/  
  45. #include<unistd.h>         /**/  
  46. #include<errno.h>  
  47. #include<string.h>  
  48. #include<termio.h>         /*provide the common interface*/  
  49. #include<sys/types.h>  
  50. #include<sys/stat.h>  
  51. #include<pthread.h>  
  52. #include<sys/ipc.h>  
  53. #include<sys/msg.h>  
  54. /* To prevent repeated variables defined */  
  55. #ifndef _SCOM_PROTOCAL_H_  
  56. #define _SCOM_PROTOCAL_H_  
  57.   
  58. typedef unsigned char U8;  
  59. typedef unsigned short U16;  
  60. typedef unsigned long U32;  
  61. typedef signed char INT8;  
  62. typedef unsigned int UINT16;  
  63. typedef signed int INT16;  
  64.   
  65. /* 
  66.  * define the macro to set the  
  67.  * init_value of the property 
  68.  */  
  69. #define PROPERTY_INIT 0x11  
  70. #define PROPERTY_0x01 0x51  
  71. #define PROPERTY_0x02 0x91  
  72. #define PROPERTY_0x03 0xd1  
  73. #define PROPERTY_0x04 0x111  
  74. #define PROPERTY_0x05 0x151  
  75. #define PROPERTY_OTHER 0x155  
  76.   
  77. #ifndef NULL  
  78. #define NULL ((void*) 0)  
  79. #endif  
  80.   
  81. #define DEBUG 1  
  82.   
  83. #ifdef DEBUG      
  84. #else  
  85. #endif  
  86.   
  87. #define HEAD 0xf4  
  88. #define TAIL 0x4f  
  89.   
  90. #define FALSE -1  
  91. #define TRUE 0  
  92. /*define the device port*/  
  93. #if 1  
  94. #define DEV_PORT "/dev/pts/4"  
  95. #else  
  96. #define DEV_PORT "/dev/ttyAMA2"  
  97. #endif  
  98. /*define the flag to cancel the thread*/  
  99. U8 g_exit_flag = 0;  
  100.   
  101. #define DATA_LENGTH_MAX 8  
  102. #define PROTOCAL_LENGTH 9  
  103. #define BUFFER_SIZE 72  
  104. #define BAUDRATE 115200  
  105. /* */  
  106. #endif  
  107.   
  108. #define MSG_QUE_KEY 1024  
  109. /*define the struct of the mes_que*/  
  110. #define MSG_TYPE 17  
  111.   
  112. typedef struct  
  113. {  
  114.     INT8 msg_type;  
  115.     U8 msg_len;  
  116.     /*exclude the head and tail*/  
  117.     U8 msg_buf[DATA_LENGTH_MAX + PROTOCAL_LENGTH - 2];  
  118. }msg_que;  
  119.   
  120. typedef struct   
  121. {  
  122.     INT8 port_fd;  
  123.     U8 buf[BUFFER_SIZE];  
  124. }recv_param;  
  125. #if 0  
  126. typedef struct  
  127. {  
  128.     U8 package_data_length;  
  129.     /*exclude the head and tail*/  
  130.     U8 buf[DATA_LENGTH_MAX + PROTOCAL_LENGTH - 2];  
  131. }tsk_param;  
  132. #endif  
  133.   
  134. /*self define the protocal of the serial com*/  
  135. typedef struct  
  136. {  
  137.     U8 head[1];  
  138.     U16 serial_num;  
  139.     U8 length[1];  /*data_length + PROTOCAL_LENGTH*/  
  140.     U16 property;       
  141.     U8 package_data[DATA_LENGTH_MAX];  
  142.     U16 crc_check;  
  143.     U8 tail[1];  
  144. }scom_protocal;  
  145.   
  146. /*function declaration*/  
  147. U8 serialport_init(INT8 port_fd, U32 baud_rate,  
  148.         U8 data_bits, U8 parity, U8 stop_bit);  
  149. void scom_protocal_init(scom_protocal *protocal_info_ptr);  
  150. INT8 open_port(void);  
  151. U16 crc16_check(U8 *data_ptr, U8 data_length);  
  152. U8 escape_character(U8 *package_data_ptr, U8 data_length,   
  153.         U8 *buffer_ptr);  
  154. U8 anti_escape_character(U8 *buffer_ptr, U8 *package_data_ptr,  
  155.         U8 data_length);  
  156. void  *tsk_run(INT8 *param_ptr);  
  157. U8 data_process(U8 *data_proc_ptr, U8 data_start_pos,  
  158.         U8 data_end_pos);  
  159. U8 data_package(scom_protocal *protocal_info_ptr,  
  160.         U8 *package_data_ptr, U8 data_length);  
  161. U8 data_send(INT8 port_fd, scom_protocal *protocal_info_ptr,  
  162.         U8 *data_send_ptr, U8 data_send_length);  
  163. void *data_recv(recv_param *data_recv_info_ptr);  
  164. U8 close_port(INT8 port_fd);  
  165. /************************************************* 
  166.  * Function: void serialport_init() 
  167.  * Description: init the serialport 
  168.  * Calls: none 
  169.  * Called By: main 
  170.  * Input: port_fd baud_rate data_bits parity stop_bit 
  171.  * Output: print the error info 
  172.  * Return: none 
  173.  * Author: xhniu 
  174.  * History: <author> <date>  <desc> 
  175.  * 
  176.  * Others: none 
  177. *************************************************/  
  178. U8 serialport_init(INT8 port_fd, U32 baud_rate,  
  179.         U8 data_bits, U8 parity, U8 stop_bit)  
  180. {  
  181.     struct termios newtio, oldtio;  
  182.   
  183.     /*save the primary params of the serial port stop_bit*/  
  184.     if (tcgetattr(port_fd, &oldtio )!= 0)  
  185.     {  
  186.         perror("setup serial failed!!!\n");  
  187.         return -1;  
  188.     }  
  189.   
  190.     bzero(&newtio, sizeof(newtio));  
  191.     /*set the data_bits stop_bit parity*/  
  192.     newtio.c_cflag |= CLOCAL | CREAD;  
  193.     newtio.c_cflag &= ~CSIZE;  
  194.   
  195.     switch (data_bits)  
  196.     {  
  197.         case 7:  
  198.             newtio.c_cflag |= CS7;  
  199.             break;  
  200.         case 8:  
  201.             newtio.c_cflag |= CS8;  
  202.             break;  
  203.         default:  
  204.             break;  
  205.     }  
  206.       
  207.     switch (parity)  
  208.     {  
  209.         case 'O':/*odd number*/  
  210.             newtio.c_cflag |= PARENB;  
  211.             newtio.c_cflag |= PARODD;  
  212.             newtio.c_iflag |= (INPCK | ISTRIP);  
  213.             break;  
  214.         case 'E':/*even number*/  
  215.             newtio.c_iflag |= (INPCK | ISTRIP);  
  216.             newtio.c_cflag |= PARENB;  
  217.             newtio.c_cflag &= ~PARODD;  
  218.             break;  
  219.         case 'N':  
  220.             newtio.c_cflag &= ~PARENB;  
  221.             break;  
  222.         default:  
  223.             break;  
  224.     }  
  225.   
  226.     switch (baud_rate)  
  227.     {  
  228.         case 9600:  
  229.             cfsetispeed(&newtio, B9600);  
  230.             cfsetospeed(&newtio, B9600);  
  231.             break;  
  232.         case 115200:  
  233.             cfsetispeed(&newtio, B115200);  
  234.             cfsetospeed(&newtio, B115200);  
  235.             break;  
  236.         default:  
  237.             break;  
  238.     }  
  239.   
  240.     if (1 == stop_bit)  
  241.     {  
  242.         newtio.c_cflag &= ~CSTOPB;  
  243.     }  
  244.     else if (2 == stop_bit)  
  245.     {  
  246.         newtio.c_cflag |= CSTOPB;  
  247.     }  
  248.   
  249.     /*active the newtio*/  
  250.     if ((tcsetattr(port_fd, TCSANOW, &newtio)) != 0)  
  251.     {  
  252.         perror("serial port set error!!!\n");  
  253.         return -1;  
  254.     }  
  255.   
  256.     printf("serial port set done!!!\n");  
  257.     return 0;  
  258. }  
  259. /************************************************* 
  260.  * Function: scom_protocal_init() 
  261.  * Description: init the params of the protocal 
  262.  * Calls: none 
  263.  * Called By: none 
  264.  * Input: the struct of the scom_protocal 
  265.  * Output: none 
  266.  * Return: none 
  267.  * Author: xhniu 
  268.  * History: <author> <date>  <desc> 
  269.  * Others: none 
  270. *************************************************/  
  271. void scom_protocal_init(scom_protocal *protocal_info_ptr)  
  272. {  
  273.     protocal_info_ptr->head[0] = HEAD;  
  274.     protocal_info_ptr->serial_num = 0x0000;  
  275.     /*init length is data_length + PROTOCAL_LENGTH*/  
  276.     protocal_info_ptr->length[0] = 0x11;  
  277.     protocal_info_ptr->property = PROPERTY_INIT;  
  278.   
  279.     memset(protocal_info_ptr->package_data, 0, sizeof(U8) * 8);  
  280.   
  281.     protocal_info_ptr->crc_check = 0x0000;  
  282.     protocal_info_ptr->tail[0] = 0x4f;  
  283. }  
  284. /************************************************* 
  285.  * Function: open_port() 
  286.  * Description: open the DEV_PORT 
  287.  * Calls: none 
  288.  * Called By: none 
  289.  * Input: none 
  290.  * Output: none 
  291.  * Return: port_fd 
  292.  * Author: xhniu 
  293.  * History: <author> <date>  <desc> 
  294.  * Others: none 
  295. *************************************************/  
  296. INT8 open_port(void)  
  297. {  
  298.     INT8 port_fd;  
  299.       
  300.     /* */  
  301.     port_fd = open(DEV_PORT,   
  302.             O_RDWR | O_NOCTTY | O_NONBLOCK);  
  303.     if (-1 == port_fd)  
  304.     {  
  305.         perror("open the serial port failed!!!\n");  
  306.         return -1;  
  307.     }  
  308.       
  309.     /*set the serial port is block and waitting*/  
  310.     if (fcntl(port_fd, F_SETFL, 0) < 0)  
  311.     {  
  312.         printf("fcntl failed!\n");  
  313.     }  
  314.     else  
  315.     {  
  316.         printf("fcntl = %d \n", fcntl(port_fd, F_SETFL, 0));  
  317.     }/*end if*/  
  318.   
  319.     return port_fd;  
  320. }  
  321.   
  322. /************************************************* 
  323.  * Function: crc16_check() 
  324.  * Description: genetrate the check data 
  325.  * Calls: none 
  326.  * Called By: data_package() 
  327.  * Input: data need check and length of data 
  328.  * Output: none 
  329.  * Return: crc check data 
  330.  * Author: xhniu 
  331.  * History: <author> <date>  <desc> 
  332.  * Others: none 
  333. *************************************************/  
  334. U16 crc16_check(U8 *data_ptr, U8 data_length)  
  335. {  
  336.     /*polynomial*/  
  337.     U16 crc_gen = 0xa001;  
  338.     U16 crc;  
  339.     U8 i, j;  
  340.   
  341.     /*init value of crc*/  
  342.     crc = 0xffff;  
  343.     if (data_length != 0)  
  344.     {  
  345.         for (i = 0; i < data_length; i++)  
  346.         {  
  347.             crc ^= (U16)(data_ptr[i]);  
  348.             for (j = 0; j < 8; j++)  
  349.             {  
  350.                 if ((crc & 0x01)  == 0x01)     
  351.                 {  
  352.                     crc >>= 1;      
  353.                     crc ^= crc_gen;  
  354.                 }  
  355.                 else  
  356.                 {  
  357.                     crc >>= 1;  
  358.                 }  
  359.             }/*end for*/  
  360.         }/*end for*/  
  361.     }/*end if*/  
  362.     return crc;  
  363. }  
  364.   
  365. /************************************************* 
  366.  * Function: escape_character() 
  367.  * Description: f4 -- ff 01, ff -- ff 02, 4f -- ff 03 
  368.  * Calls: none 
  369.  * Called By: data_send 
  370.  * Input: package_data, data_length, buffer 
  371.  * Output: none 
  372.  * Return: TRUE or FALSE 
  373.  * Author: xhniu 
  374.  * History: <author> <date>  <desc> 
  375.  * Others: none 
  376. *************************************************/  
  377. U8 escape_character(U8 *package_data_ptr, U8 data_length, U8 *buffer)  
  378. {  
  379.     if ((NULL == package_data_ptr) | (0 == data_length))  
  380.     {  
  381.         printf("input error!!!\n");  
  382.         return FALSE;  
  383.     }  
  384.   
  385.     U8 count = 1;  
  386.   
  387.     buffer[0] = package_data_ptr[0];  
  388.     buffer++;  
  389.     /*except the head and the tail*/  
  390.     for (; count < (data_length -1); count++)  
  391.     {  
  392.         if (0xf4 == package_data_ptr[count])  
  393.         {  
  394.             *buffer++ = 0xff;  
  395.             *buffer++ = 0x01;  
  396.         }  
  397.         else if (0xff == package_data_ptr[count])  
  398.         {  
  399.             *buffer++ = 0xff;  
  400.             *buffer++ = 0x02;  
  401.         }  
  402.         else if (0x4f == package_data_ptr[count])  
  403.         {  
  404.             *buffer++ = 0xff;  
  405.             *buffer++ = 0x03;  
  406.         }  
  407.         else  
  408.         {  
  409.             *buffer++ = package_data_ptr[count];  
  410.         }/*end if*/  
  411.     }/*end for*/  
  412.     *buffer++ = 0x4f;  
  413.     *buffer = '\0';  
  414.   
  415.     return TRUE;  
  416. }  
  417. /************************************************* 
  418.  * Function: anti_escape_character() 
  419.  * Description: ff 01 -- f4, ff 02 -- ff, ff 03 -- 4f 
  420.  * Calls: none 
  421.  * Called By:  
  422.  * Input: buffer, package_data, data_length 
  423.  * Output:  
  424.  * Return:  
  425.  * Author: xhniu 
  426.  * History: <author> <date>  <desc> 
  427.  * Others: none 
  428. *************************************************/  
  429. U8 anti_escape_character(U8 *buffer_ptr, U8 *package_data_ptr,  
  430.         U8 data_length)  
  431. {  
  432.     if ((NULL == package_data_ptr) | (0 == data_length))  
  433.     {  
  434.         printf("input data error!\n");  
  435.         return FALSE;  
  436.     }  
  437.   
  438.     U8 flag = 0;  
  439.     U8 count = 0;  
  440.   
  441.     package_data_ptr[0] = buffer_ptr[0];  
  442.     package_data_ptr++;  
  443.     buffer_ptr++;  
  444.     /*exclude the tail 0x4f*/  
  445.     while (TAIL != *buffer_ptr)  
  446.     {  
  447.         if (0xff == *buffer_ptr)  
  448.         {  
  449.             flag = 1;  
  450.             buffer_ptr++;  
  451.   
  452.             if ((0x01 == *buffer_ptr) && (1 == flag))  
  453.             {  
  454.                 *package_data_ptr++ = 0xf4;  
  455.             }  
  456.             else if ((0x02 == *buffer_ptr) && (1 == flag))  
  457.             {  
  458.                 *package_data_ptr++ = 0xff;  
  459.             }  
  460.             else if ((0x03 == *buffer_ptr) && (1 == flag))  
  461.             {  
  462.                 *package_data_ptr++ = 0x4f;  
  463.             }  
  464.             else if (1 == flag)  
  465.             {  
  466.                 *package_data_ptr++ =  0xff;    
  467.                 *package_data_ptr++ = *buffer_ptr++;  
  468.             }  
  469.             buffer_ptr++;  
  470.         }  
  471.         else  
  472.         {  
  473.             *package_data_ptr++ = *buffer_ptr++;  
  474.             flag = 0;  
  475.         }/*end if*/  
  476.   
  477.     }/*end while*/  
  478.   
  479.     return TRUE;  
  480. }  
  481.   
  482. /************************************************* 
  483.  * Function: tsk_run() 
  484.  * Description:  receive a package data and execute a tsk 
  485.  * Calls: none 
  486.  * Called By: data_recv() 
  487.  * Input: data_proc_ptr 
  488.  * Output: none 
  489.  * Return:  
  490.  * Author: xhniu 
  491.  * History: <author> <date>  <desc> 
  492.  * Others: none 
  493. ************************************************/  
  494. void  *tsk_run(INT8 *param_ptr)  
  495. {  
  496.     INT8 port_fd = *param_ptr;  
  497.     U8 *exit_ptr = "exit";  
  498. #if DEBUG  
  499.     printf("in tsk_run,port_fd is %4d\n", port_fd);  
  500. #endif  
  501.     /*use to data send*/  
  502.     scom_protocal scom_protocal_info;  
  503.     memset(&scom_protocal_info, 0, sizeof(scom_protocal_info));  
  504.     scom_protocal_init(&scom_protocal_info);  
  505.     U8 data_send_length = 0;  
  506.     U8 data_send_array[32] = {0};  
  507.     U8 num = 0;  
  508.     /*use to data proc*/  
  509.     U8 package_data_ptr[DATA_LENGTH_MAX + PROTOCAL_LENGTH - 2] = {0};  
  510.     U8 data_ptr[DATA_LENGTH_MAX] = {0};  
  511.     U8 package_data_length = 0;  
  512.     /*define the var to recv msg form msg_que*/  
  513.     INT16 msg_que_id;  
  514.     INT8 ret;  
  515.     msg_que msg_que_info;  
  516.     memset(&msg_que_info, 0, sizeof(msg_que_info));  
  517.     /*proc the sub package*/  
  518.     U8 sub_package_num = 0;  
  519.     U8 sub_package_flag = 0;  
  520.     U8 sub_package_ID = 0;  
  521.     U8 sub_package_count = 0;  
  522.     U8 sub_package_buf[DATA_LENGTH_MAX * 8] = {0};  
  523.     INT16 cur_time = 0;  
  524.     INT16 last_time = 0;  
  525.   
  526.     while (1)  
  527.     {  
  528.         /*judge the exit flag*/  
  529.         if(1 == g_exit_flag)  
  530.         {     
  531.             printf("int tsk_run,g_exit_flag is:%4d\n", g_exit_flag);  
  532.             break;  
  533.         }  
  534.   
  535.         /*check the msg que is exist*/  
  536.         msg_que_id = msgget(MSG_QUE_KEY, IPC_EXCL);  
  537.         if (msg_que_id <= 0)  
  538.         {  
  539.             printf("msg que is not exist!\n");  
  540.             sleep(1);  
  541.             continue;  
  542.         }  
  543.         else  
  544.         {  
  545.             printf("\nin tsk_run,msg_que_id is %4d\n", msg_que_id);  
  546.         }  
  547.         /*start to recv data from the msg que*/  
  548.         ret = msgrcv(msg_que_id, &msg_que_info, sizeof(msg_que_info), 0, 0);  
  549.         if (ret < 0)  
  550.         {  
  551.             printf("recv data from the msg que failed!\n");  
  552.             continue;  
  553.         }  
  554.         else  
  555.         {  
  556.             printf("recv data from the msg que success!\n");  
  557.         }/*end if*/  
  558.   
  559.         /*get the cur time*/  
  560.         if (0 != last_time)  
  561.         {  
  562.             printf("*****last_time is %4d*****\n", last_time);  
  563.             cur_time = time((time_t*)NULL);  
  564.             printf("cur_time is :%4d\n", cur_time);  
  565.             if (cur_time - last_time > 10)  
  566.             {  
  567.                 printf("cannot get the  complete package_data!!!\n");  
  568.                 memset(sub_package_buf, 0, DATA_LENGTH_MAX * 8);  
  569.                 sub_package_count = 0;  
  570.                 last_time = 0;  
  571.                 continue;  
  572.             }  
  573.         }/*end if*/  
  574.   
  575.         package_data_length = msg_que_info.msg_len;  
  576.         memcpy(package_data_ptr, msg_que_info.msg_buf, msg_que_info.msg_len);  
  577. #if DEBUG  
  578.         printf("package_data_length is %4d\n", package_data_length);  
  579.         U8 i = 0;  
  580.         while (i < package_data_length)  
  581.         {  
  582.             printf("%02x ", package_data_ptr[i++]);  
  583.         }  
  584.         printf("\n");  
  585. #endif  
  586.         U16 property = 0;  
  587.         property = package_data_ptr[4];  
  588.         property = property << 8;  
  589.         property = (property | package_data_ptr[3]);  
  590. #if DEBUG  
  591.         printf("property is:%04x\n", property);  
  592. #endif  
  593.         /*judging whethre the data sub*/  
  594.         sub_package_num = (property >> 13);  
  595.         sub_package_ID = (property >> 10);  
  596.         sub_package_ID &= 0x07;  
  597.         printf("the sub_package_ID is %4d\n", sub_package_ID);  
  598.   
  599.         if (0 != sub_package_num)  
  600.         {  
  601.             sub_package_flag = 1;  
  602.             sub_package_count++;  
  603.             memcpy(&sub_package_buf[ sub_package_ID * DATA_LENGTH_MAX],  
  604.                         &package_data_ptr[5],package_data_ptr[2] - PROTOCAL_LENGTH);  
  605.             printf("sub_package_count is %4d subpackage_num is %4d\n", sub_package_count, sub_package_num);  
  606.             /*recv the complete package*/  
  607.             if(sub_package_count == (sub_package_num + 1))  
  608.             {  
  609. #if DEBUG  
  610.                 U8 i = 0;   
  611.                 for (; i < 28; i++)  
  612.                 {  
  613.                     printf("%c",sub_package_buf[i]);  
  614.                 }  
  615.                 printf("\n");  
  616. #endif  
  617.                 system(sub_package_buf);  
  618.                 memset(sub_package_buf, 0, DATA_LENGTH_MAX * 8);  
  619.                 sub_package_count = 0;  
  620.                 last_time = 0;  
  621.                 continue;  
  622.             }  
  623.             else  
  624.             {  
  625.                 last_time = time((time_t*)NULL);  
  626.                 printf("last_time is:%4d\n",last_time);  
  627.             }/*end if*/  
  628.             continue;  
  629.         }/*end if*/  
  630.   
  631.         memcpy(data_ptr, &package_data_ptr[5], package_data_ptr[2] - PROTOCAL_LENGTH);  
  632.         property &= 0x3ff;  
  633.         switch (property)  
  634.         {  
  635.             case PROPERTY_INIT:  
  636.                    {  
  637.                        printf("The receive cmd is linux system cmd:%s\n", data_ptr);  
  638.                          
  639.                        if (0 == strcmp(exit_ptr, data_ptr))  
  640.                        {  
  641.                            g_exit_flag = 1;  
  642.                        }  
  643.                        else  
  644.                        {  
  645.                            system(data_ptr);  
  646.                        }  
  647.                        break;  
  648.                    }  
  649.             case PROPERTY_0x01:  
  650.                    {   
  651. #if DEBUG  
  652.                        printf("The receive cmd is get the GPS data:\n");  
  653. #endif                        
  654.                        printf("GPS:longitude :%04x, latitude :%04x, height :%04x, time :%04x\n",  
  655.                                0xf101,0xf202, 0xf123, 0xffff);  
  656.   
  657.                        num = 0;  
  658.                        data_send_array[num++] = 0x01;   
  659.                        data_send_array[num++] = 0xf1;   
  660.                        data_send_array[num++] = 0x02;   
  661.                        data_send_array[num++] = 0xf2;   
  662.                        data_send_array[num++] = 0x23;   
  663.                        data_send_array[num++] = 0xf1;   
  664.                        data_send_array[num++] = 0xff;   
  665.                        data_send_array[num++] = 0xff;   
  666.                        scom_protocal_info.property = PROPERTY_0x01;  
  667.                        data_send(port_fd, &scom_protocal_info, data_send_array, 8);  
  668.                        break;  
  669.                     }  
  670.             case PROPERTY_0x02:  
  671.                    {  
  672.                        printf("The receive cmd is get the gyroscope data:\n");  
  673.                        printf("gyroscope:\ncabrage:%04x, yaw:%04x, roll;%04x\n",   
  674.                                0xf1f2, 0xf3f4, 0xf5f6);  
  675.                        num = 0;  
  676.                        data_send_array[num++] = 0xf2;   
  677.                        data_send_array[num++] = 0xf1;   
  678.                        data_send_array[num++] = 0xf4;   
  679.                        data_send_array[num++] = 0xf3;   
  680.                        data_send_array[num++] = 0xf6;   
  681.                        data_send_array[num++] = 0xf5;  
  682.   
  683.                        scom_protocal_info.property = PROPERTY_0x02;  
  684.                        data_send(port_fd, &scom_protocal_info, data_send_array, num);  
  685.                        break;  
  686.                    }  
  687.             case PROPERTY_0x03:  
  688.                    {   
  689.                        printf("The receive cm d is get the accelerometer data:\n");  
  690.                        printf("accelerometer:\nX:%04x, Y:%04x, Z:%04x\n",   
  691.                                0x0102, 0x0304, 0x0506);  
  692.                        num = 0;  
  693.                        data_send_array[num++] = 0x02;   
  694.                        data_send_array[num++] = 0x01;   
  695.                        data_send_array[num++] = 0x04;   
  696.                        data_send_array[num++] = 0x03;   
  697.                        data_send_array[num++] = 0x06;   
  698.                        data_send_array[num++] = 0x05;  
  699.   
  700.                        scom_protocal_info.property = PROPERTY_0x03;  
  701.                        data_send(port_fd, &scom_protocal_info, data_send_array, num);  
  702.                        break;  
  703.                    }  
  704.             case PROPERTY_0x04:  
  705.                    {   
  706.                        printf("The receive cmd is get th e target info:\n");  
  707.   
  708.                        num = 0;  
  709.                        data_send_array[num++] = 0x01;   
  710.                        data_send_array[num++] = 0x34;   
  711.                        data_send_array[num++] = 0x12;   
  712.                        data_send_array[num++] = 0x21;   
  713.                        data_send_array[num++] = 0x43;   
  714.                        data_send_array[num++] = 0x02;   
  715.                        data_send_array[num++] = 0x78;   
  716.                        data_send_array[num++] = 0x56;   
  717.                        data_send_array[num++] = 0x65;   
  718.                        data_send_array[num++] = 0x87;   
  719.                        data_send_array[num++] = 0x03;   
  720.                        data_send_array[num++] = 0x14;  
  721.                        data_send_array[num++] = 0x23;   
  722.                        data_send_array[num++] = 0x21;   
  723.                        data_send_array[num++] = 0x34;   
  724.   
  725.                        scom_protocal_info.property = PROPERTY_0x04;  
  726.                        data_send(port_fd, &scom_protocal_info, data_send_array, num);  
  727.                        break;  
  728.                    }  
  729.             case PROPERTY_0x05:  
  730.                    {   
  731.                        printf("the cmd  is get the D5 info:\n");  
  732.   
  733.                        num = 0;  
  734.                        data_send_array[num++] = 0x01;   
  735.                        data_send_array[num++] = 0x34;   
  736.                        data_send_array[num++] = 0x12;   
  737.                        data_send_array[num++] = 0x21;   
  738.                        data_send_array[num++] = 0x43;   
  739.                        data_send_array[num++] = 0x02;   
  740.                        data_send_array[num++] = 0x78;   
  741.                        data_send_array[num++] = 0x56;   
  742.                        data_send_array[num++] = 0x65;   
  743.                        data_send_array[num++] = 0x87;   
  744.                        data_send_array[num++] = 0x03;   
  745.                        data_send_array[num++] = 0x14;  
  746.                        data_send_array[num++] = 0x23;   
  747.                        data_send_array[num++] = 0x21;   
  748.                        break;  
  749.                    }  
  750.             default:  
  751.                    {  
  752.                        printf("cannot discrimate the cmd:\n");  
  753.   
  754.                        U8 i = 0;  
  755.                        for (; i < package_data_ptr[2] - PROTOCAL_LENGTH; i++)  
  756.                        {  
  757.                             printf("%02x ", data_ptr[i]);  
  758.                        }  
  759.                        printf("\n");  
  760.                        break;  
  761.                    }  
  762.         }/*end switch*/  
  763.     }/*end ehile*/  
  764. }  
  765.   
  766. /************************************************* 
  767.  * Function: data_process() 
  768.  * Description:  process the data form the bufer_recv 
  769.  * Calls: none 
  770.  * Called By: data_recv() 
  771.  * Input: data_proc_ptr 
  772.  * Output: none 
  773.  * Return:  
  774.  * Author: xhniu 
  775.  * History: <author> <date>  <desc> 
  776.  * Others: none 
  777. ************************************************/  
  778. U8 data_process(U8 *data_proc_ptr,  
  779.         U8 data_start_pos,  
  780.         U8 data_end_pos)  
  781. {  
  782.     if ((NULL == data_proc_ptr) || (data_start_pos >= data_end_pos))  
  783.     {  
  784.         printf("input data error!\n");  
  785.         return 0;  
  786.     }  
  787.   
  788.     /*use msg_que to do the ipc*/  
  789.     msg_que msg_que_info;  
  790.     INT8 ret = 0;  
  791.     INT16 msg_que_id;  
  792.     memset(&msg_que_info, 0, sizeof(msg_que_info));  
  793.     msg_que_id = msgget((key_t)MSG_QUE_KEY, IPC_EXCL);  
  794. #if DEBUG  
  795.     printf("the msg_que_id is:%4d\n", msg_que_id);  
  796. #endif  
  797.   
  798.     /*process data buffer*/  
  799.     U8 buffer[(DATA_LENGTH_MAX + PROTOCAL_LENGTH) * 2  - 2] = {0};  
  800.     U8 package_data[(DATA_LENGTH_MAX + PROTOCAL_LENGTH) * 2] = {0};  
  801.   
  802.     /*   */  
  803.     U8 head_flag = 0;  
  804.     U8 tail_flag = 0;  
  805.     U8 pos = 0;  
  806.     U8 package_data_length = 0;  
  807.   
  808.     for (; data_start_pos < data_end_pos; data_start_pos++)  
  809.     {  
  810.         /*find the head */  
  811.         if ((HEAD == data_proc_ptr[data_start_pos])  
  812.                 && (0 == head_flag))  
  813.         {  
  814.             head_flag = 1;  
  815.             pos = data_start_pos;  
  816.             continue;  
  817.         }  
  818.         /*avoid the double head or triple head*/  
  819.         if ((HEAD == data_proc_ptr[data_start_pos])  
  820.                 && (1 == head_flag))  
  821.         {  
  822.             pos = data_start_pos;  
  823.         }  
  824.   
  825.         if ((TAIL == data_proc_ptr[data_start_pos])  
  826.                 && (0 == tail_flag))  
  827.         {  
  828.             if(1 == head_flag)  
  829.             {  
  830.                 tail_flag = 1;  
  831.             }  
  832.             else  
  833.             {  
  834.                 tail_flag = 0;  
  835.             }  
  836.         }     
  837.           
  838.         /*process a packaged data*/  
  839.         if ((1 == head_flag) && (1 == tail_flag))  
  840.         {  
  841.             printf("data_start_pos is %2d, pos is %2d ", data_start_pos, pos);  
  842.             memset(buffer, 0x00, (DATA_LENGTH_MAX + PROTOCAL_LENGTH) * 2 - 2);  
  843.             memcpy(buffer, &data_proc_ptr[pos],   
  844.                     (data_start_pos - pos + 1));  
  845.   
  846.             /*anti escape character*/  
  847.             printf("\nanti escape character! data_start_pos is %4d pos is %4d\n",  
  848.                     data_start_pos, pos);  
  849.             memset(package_data, 0x00,   
  850.                     (DATA_LENGTH_MAX + PROTOCAL_LENGTH) * 2);  
  851.             anti_escape_character(buffer, package_data,  
  852.                     (data_start_pos - pos + 1));  
  853.   
  854.             /*data length exclude head and tail*/  
  855. #if DEBUG  
  856.             printf("data length is: package[3] = %2d\n", package_data[3] - 2);  
  857. #endif  
  858.             package_data_length = package_data[3] - 2;  
  859.             printf("crc16_check is 0x%04x\n",  
  860.                     crc16_check(&package_data[1], package_data_length));  
  861.             if (0x00 == crc16_check(&package_data[1], package_data_length))  
  862.             {  
  863.                 printf("crc16_check success!\n");  
  864.             }  
  865.             else  
  866.             {  
  867.                 printf("crc16_ check error!\n");  
  868.                 /* 
  869.                  * theoretically,it will return the serial_num 
  870.                  * and the sub_package_ID  
  871.                  */  
  872.                 return 0;  
  873.             }  
  874.             /*get a complete package data and send it to the msg_que*/  
  875.             msg_que_info.msg_type = MSG_TYPE;  
  876.             msg_que_info.msg_len = package_data_length;  
  877. #if DEBUG  
  878.             printf("msg_que_info.msg_len is %4d\n",   
  879.                     msg_que_info.msg_len);  
  880. #endif  
  881.             memcpy(&(msg_que_info.msg_buf), &package_data[1],  
  882.                     package_data_length);  
  883.             /*send the msg*/  
  884.             ret = msgsnd(msg_que_id, &msg_que_info, package_data_length, IPC_NOWAIT);  
  885.             if (ret < 0)  
  886.             {  
  887.                 printf("msg send failed!\n");  
  888.                 return 0;  
  889.             }  
  890.             else   
  891.             {  
  892.                 printf("send msg success! ret is %4d\n", ret);  
  893.                 sleep(2);  
  894.             }  
  895.               
  896.             head_flag = 0;  
  897.             tail_flag = 0;  
  898.             pos = 0;  
  899.         }  
  900.     }  
  901. #if 0  
  902.     printf("\nreturn data is: %4d\n", pos);  
  903. #endif  
  904.     return pos;  
  905. }  
  906. /************************************************* 
  907.  * Function: data_package() 
  908.  * Description: package the data with the scom_protocal 
  909.  * Calls:  
  910.  * Called By: data_send 
  911.  * Input: protocal_info_ptr, package_data, data_length 
  912.  * Output:  
  913.  * Return: TRUE/FALSE 
  914.  * Author: xhniu 
  915.  * History: <author> <date>  <desc> 
  916.  * Others: none 
  917. *************************************************/  
  918. U8 data_package(scom_protocal *protocal_info_ptr,  
  919.         U8 *package_data_ptr, U8 data_length)  
  920. {  
  921.     /*decide whether need subpackage*/  
  922.     if (data_length > DATA_LENGTH_MAX)  
  923.     {  
  924.         printf("input valid!!!\n");  
  925.         return -1;  
  926.     }  
  927.       
  928.     U8 len = 0;  
  929.   
  930.     package_data_ptr[0] = protocal_info_ptr->head[0];  
  931.     /*U16 to U8 low 8 bit*/  
  932.     package_data_ptr[1] = (U8)(protocal_info_ptr->serial_num);  
  933.     package_data_ptr[2] = (U8)((protocal_info_ptr->serial_num)  
  934.             >> 8);  
  935.   
  936.     package_data_ptr[3] = data_length + PROTOCAL_LENGTH;  
  937.       
  938.     /*U16 to U8 low 8 bit*/  
  939.     package_data_ptr[4] = (U8)(protocal_info_ptr->property);  
  940.     /*high 8 bit*/  
  941.     package_data_ptr[5] = (U8)((protocal_info_ptr->property)  
  942.             >> 8);  
  943.       
  944.     for (; len < data_length; len++)  
  945.     {  
  946.         package_data_ptr[len + 6] =   
  947.             protocal_info_ptr->package_data[len];  
  948.     }  
  949.     /* 
  950.      *generate the CRC16 check data 
  951.      * U16 to U8 
  952.      */  
  953.     U16 check_code;  
  954.     /*data_length + property(2 byte) + length(1 byte) +  
  955.      * serial_num(2 byte) 
  956.      */  
  957.     U8 *ptr = malloc(sizeof(U8) * (data_length + 5));  
  958.     memcpy(ptr, package_data_ptr + 1, data_length + 5);  
  959.     check_code = crc16_check(ptr, data_length + 5);  
  960.     /*free the ptr*/  
  961.     free(ptr);  
  962.     ptr = NULL;  
  963.   
  964.     /*low 8 bit*/  
  965.     package_data_ptr[len + 6] = (U8)(check_code);  
  966.     /*high 8 bie*/  
  967.     package_data_ptr[len + 7] = (U8)(check_code >> 8);  
  968.     package_data_ptr[len + 8] = protocal_info_ptr->tail[0];  
  969.       
  970.     return TRUE;  
  971. }  
  972. /************************************************* 
  973.  * Function: data_send() 
  974.  * Description: read the data and  
  975.  * Calls: none 
  976.  * Called By: none 
  977.  * Input: none 
  978.  * Output: none 
  979.  * Return:  
  980.  * Author: xhniu 
  981.  * History: <author> <date>  <desc> 
  982.  * Others: none 
  983. *************************************************/  
  984. U8 data_send(INT8 port_fd, scom_protocal *protocal_info_ptr,  
  985.         U8 *data_send_ptr, U8 data_send_length)  
  986. {  
  987.     if (NULL == data_send_ptr)  
  988.     {  
  989.         printf("input data error!!!\n");  
  990.         return FALSE;  
  991.     }  
  992.   
  993.     /*number of the char need escape*/  
  994.     U8 num_escape_char = 0;  
  995.     U8 num_escape_char_temp = 0;  
  996.       
  997.     U8 *package_data = NULL;  
  998.     U8 *escape_char_ptr = NULL;  
  999.   
  1000.     /*when send new data, the serial num will plus 1*/  
  1001.     (protocal_info_ptr->serial_num)++;  
  1002.       
  1003.     if (data_send_length > DATA_LENGTH_MAX)  
  1004.     {  
  1005.         /*need the subpackage calculate the sun_package_num 
  1006.          * set the flag of the subpackage*/  
  1007.         int sub_package_num = 0, count = 0;  
  1008.         if (0 != data_send_length % DATA_LENGTH_MAX)  
  1009.         {  
  1010.             sub_package_num = (data_send_length / DATA_LENGTH_MAX) + 1;  
  1011.         }  
  1012.         else  
  1013.         {  
  1014.             sub_package_num = (data_send_length / DATA_LENGTH_MAX);  
  1015.         }  
  1016.   
  1017.         /*3 byte of the sub_package_num the data area is  
  1018.          *1 ~ 7 
  1019.          */  
  1020.         if (sub_package_num > 8)  
  1021.         {  
  1022.             return FALSE;  
  1023.         }  
  1024.         protocal_info_ptr->property &= 0x1fff;  
  1025.         protocal_info_ptr->property |= ((sub_package_num - 1) << 13);  
  1026. #if DEBUG  
  1027.         printf("sub_package_num is:%4x\n",sub_package_num);  
  1028. #endif  
  1029.         /* 
  1030.          * sub_package_num - 1  
  1031.          * the length of the last sub_package is not sure 
  1032.          */  
  1033.         for (; count < (sub_package_num - 1); count++)  
  1034.         {  
  1035.             /*set the length of the protcal_info_ptr->length[0]*/  
  1036.             protocal_info_ptr->length[0] =   
  1037.                 DATA_LENGTH_MAX + PROTOCAL_LENGTH;  
  1038.             /*set the ID of the subpackage*/  
  1039.             protocal_info_ptr->property &= 0xe3ff;  
  1040.             protocal_info_ptr->property |= (count << 10);  
  1041.               
  1042.             memcpy(protocal_info_ptr->package_data,   
  1043.                     (data_send_ptr + count * DATA_LENGTH_MAX ),  
  1044.                     DATA_LENGTH_MAX);  
  1045. #if 0  
  1046.             U8 m = 0;  
  1047.             for (; m < protocal_info_ptr->length[0]; m++)  
  1048.             {  
  1049.                 printf("%02x ", protocal_info_ptr->package_data[m]);  
  1050.             }  
  1051.             printf("\n");  
  1052. #endif    
  1053.             /*malloc a mem to restore the packaged data  
  1054.              *plus the head(1),tail(1),length(1),property(2),crc(2),serial_num(2), 
  1055.              */  
  1056.             package_data = (U8 *)malloc(sizeof(U8) *   
  1057.                     (DATA_LENGTH_MAX + PROTOCAL_LENGTH));  
  1058.             if (NULL == package_data)  
  1059.             {  
  1060.                 printf("malloc failed\n");  
  1061.                 return FALSE;  
  1062.             }  
  1063.               
  1064.             data_package(protocal_info_ptr, package_data,  
  1065.                     DATA_LENGTH_MAX);  
  1066. #if DEBUG  
  1067.             U8 m = 0;  
  1068.             for (; m < 17; m++)  
  1069.             {  
  1070.                 printf("%02x ", package_data[m]);  
  1071.             }  
  1072.             printf("\n");  
  1073. #endif  
  1074.             /* malloc a buffer use to send data 
  1075.              * character transfer 
  1076.              */  
  1077.             num_escape_char = 0;  
  1078.             num_escape_char_temp = 0;  
  1079.             /*count the num of the 0xff 0xf4 0x4f except tail and head*/  
  1080.             num_escape_char_temp = protocal_info_ptr->length[0] - 2;  
  1081.           
  1082.             while ((num_escape_char_temp--) > 1)  
  1083.             {  
  1084.                 if ((0xff == package_data[num_escape_char_temp])  
  1085.                         | (0xf4 == package_data[num_escape_char_temp])  
  1086.                         | (0x4f == package_data[num_escape_char_temp]))  
  1087.                 {  
  1088.                     num_escape_char++;  
  1089.                 }  
  1090.             }  
  1091. #if DEBUG  
  1092.             printf("num_escape_char is %4d\n", num_escape_char);  
  1093. #endif  
  1094.             if(0 == num_escape_char)  
  1095.             {  
  1096.                 /*no escape characters send data diretly*/  
  1097.                 if (write(port_fd, package_data,   
  1098.                         (protocal_info_ptr->length[0])) < 0)  
  1099.                 {  
  1100.                     printf("write data error! \n");  
  1101.                     return FALSE;  
  1102.                 }  
  1103.                 else  
  1104.                 {  
  1105.                     printf("write data success!\n");  
  1106.                 }  
  1107.             }  
  1108.             else  
  1109.             {  
  1110.                 escape_char_ptr = (U8 *)malloc(sizeof(U8)     
  1111.                         * (protocal_info_ptr->length[0] + num_escape_char));   
  1112. #if DEBUG  
  1113.                 printf("%4d \n", protocal_info_ptr->length[0]);  
  1114. #endif  
  1115.                 escape_character(package_data,   
  1116.                         protocal_info_ptr->length[0], escape_char_ptr);  
  1117. #if DEBUG  
  1118.                 U8 k = 0;  
  1119.                 for (; k < protocal_info_ptr->length[0]  
  1120.                         + num_escape_char; k++)  
  1121.                 {  
  1122.                     printf("%04x ", escape_char_ptr[k]);  
  1123.                 }  
  1124. #endif  
  1125.                 /*send data*/  
  1126.                 if (write(port_fd, escape_char_ptr,   
  1127.                         (protocal_info_ptr->length[0] + num_escape_char)) < 0)  
  1128.                 {  
  1129.                     printf("write data error! \n");  
  1130.                     return FALSE;  
  1131.                 }  
  1132.                 else  
  1133.                 {  
  1134.                     printf("write data success!\n");  
  1135.                 }  
  1136.                   
  1137.                 /*free the memory*/  
  1138.                 free(escape_char_ptr);  
  1139.                 escape_char_ptr = NULL;  
  1140.             }  
  1141.   
  1142.             free(package_data);  
  1143.             package_data = NULL;  
  1144.   
  1145.         }/*end for*/  
  1146.         if (data_send_length - count * DATA_LENGTH_MAX > 0)  
  1147.         {  
  1148.             protocal_info_ptr->length[0] = data_send_length  
  1149.                 - count * DATA_LENGTH_MAX + PROTOCAL_LENGTH;   
  1150.   
  1151.             protocal_info_ptr->property &= 0xe3ff;  
  1152.             protocal_info_ptr->property |= (count << 10);  
  1153.             memcpy(protocal_info_ptr->package_data,  
  1154.                     (data_send_ptr + count * DATA_LENGTH_MAX),   
  1155.                     (data_send_length - count * DATA_LENGTH_MAX));  
  1156.             /*malloc a mem to restore the packaged data*/  
  1157.             package_data = (U8 *)malloc(sizeof(U8) * (data_send_length  
  1158.                         - count * DATA_LENGTH_MAX + PROTOCAL_LENGTH));  
  1159.             if (NULL == package_data)  
  1160.             {  
  1161.                 printf("malloc failed \n");  
  1162.             }  
  1163. #if DEBUG  
  1164.             printf("the rest data length is %4d\n",   
  1165.                     data_send_length - count * DATA_LENGTH_MAX );  
  1166. #endif  
  1167.   
  1168.             data_package(protocal_info_ptr, package_data,   
  1169.                     data_send_length - count * DATA_LENGTH_MAX);  
  1170. #if DEBUG  
  1171.             U8 n = 0;  
  1172.             for (; n < protocal_info_ptr->length[0]; n++)  
  1173.             {  
  1174.                 printf("%02x ", package_data[n]);  
  1175.             }  
  1176.             printf("\n");  
  1177. #endif  
  1178.             /* malloc a buffer use to send data 
  1179.              * character transfer 
  1180.              */  
  1181.             num_escape_char = 0;  
  1182.             num_escape_char_temp = 0;  
  1183.             /*count the num of the 0xff 0xf4 0x4f except tail and head*/  
  1184.             num_escape_char_temp = protocal_info_ptr->length[0] - 2;  
  1185.           
  1186.             while ((num_escape_char_temp--) > 1)  
  1187.             {  
  1188.                 if ((0xff ==  package_data[num_escape_char_temp])  
  1189.                         | (0xf4 == package_data[num_escape_char_temp])  
  1190.                         | (0x4f == package_data[num_escape_char_temp]))  
  1191.                 {  
  1192.                     num_escape_char++;  
  1193.                 }  
  1194.             }  
  1195. #if DEBUG  
  1196.             printf("num_escape_char is %4d\n", num_escape_char);  
  1197. #endif  
  1198.             if(0 == num_escape_char)  
  1199.             {  
  1200.                 /*no escape characters send data diretly*/    
  1201.                 if (write(port_fd, package_data,   
  1202.                         (protocal_info_ptr->length[0])) < 0)  
  1203.                 {  
  1204.                     printf("write data error! \n");  
  1205.                     return FALSE;  
  1206.                 }  
  1207.                 else  
  1208.                 {  
  1209.                     printf("write data success!\n");  
  1210.                 }  
  1211.             }  
  1212.             else  
  1213.             {  
  1214.                 escape_char_ptr = (U8 *)malloc(sizeof(U8)     
  1215.                         * (protocal_info_ptr->length[0] + num_escape_char));   
  1216. #if DEBUG  
  1217.                 printf("%4d \n", protocal_info_ptr->length[0]);  
  1218. #endif  
  1219.                 escape_character(package_data,   
  1220.                         protocal_info_ptr->length[0], escape_char_ptr);  
  1221. #if DEBUG  
  1222.                 U8 k = 0;  
  1223.                 for (; k < protocal_info_ptr->length[0]  
  1224.                         + num_escape_char; k++)  
  1225.                 {  
  1226.                     printf("%04x ", escape_char_ptr[k]);  
  1227.                 }  
  1228. #endif  
  1229.             /*send data*/  
  1230. #if 1             
  1231.                 if (write(port_fd, escape_char_ptr,   
  1232.                         (protocal_info_ptr->length[0] + num_escape_char)) < 0)  
  1233.                 {  
  1234.                     printf("write data error!\n");  
  1235.                     return FALSE;  
  1236.                 }  
  1237. #endif  
  1238.                 free(escape_char_ptr);  
  1239.                 escape_char_ptr = NULL;  
  1240.                 /*send data*/  
  1241.             }  
  1242.   
  1243.             /*free the memory*/  
  1244.             free(package_data);  
  1245.             package_data = NULL;  
  1246.           
  1247.             return TRUE;  
  1248.             /**/  
  1249.         }  
  1250.         else/* data_send_length - count * DATA_LENGTH_MAX = 0 */  
  1251.         {  
  1252.             return TRUE;  
  1253.         }/*end if*/  
  1254.     }  
  1255.     else /*data_send_length <= DATA_LENGTH_MAX no subpackage*/  
  1256.     {  
  1257.         /*set the length of tht protocal_info_ptr->length[0]*/  
  1258.         protocal_info_ptr->length[0] = data_send_length + PROTOCAL_LENGTH;  
  1259.   
  1260.         memcpy(protocal_info_ptr->package_data, data_send_ptr, data_send_length);  
  1261.         /*malloc a mem to restore the packaged data*/  
  1262.         package_data = (U8 *)malloc(sizeof(U8)  
  1263.                 * (data_send_length + PROTOCAL_LENGTH));  
  1264. #if DEBUG  
  1265.         printf("data_send_length is %4d\n", data_send_length);  
  1266. #endif  
  1267.         if (NULL == package_data)  
  1268.         {  
  1269.             printf("malloc failed!!!\n");  
  1270.             return FALSE;  
  1271.         }  
  1272. #if DEBUG  
  1273.         printf("data_send_length + PROTOCAL_LENGTH is %4d \n",  
  1274.                 data_send_length + PROTOCAL_LENGTH);  
  1275. #endif  
  1276.         data_package(protocal_info_ptr, package_data, data_send_length);  
  1277.           
  1278. #if DEBUG  
  1279.         printf("protocal_info_ptr_length[0] is %4d \n", protocal_info_ptr->length[0]);  
  1280.         U8 j = 0;  
  1281.         for (; j < data_send_length + PROTOCAL_LENGTH; j++)  
  1282.         {  
  1283.             printf("%02x ", package_data[j]);  
  1284.         }  
  1285.         printf("\n");  
  1286. #endif  
  1287.         /* malloc a buffer use to send data 
  1288.          * character transfer 
  1289.          */  
  1290.         U8 num_escape_char = 0;  
  1291.         U8 num_escape_char_temp = 0;  
  1292.         /*count the num of the 0xff 0xf4 0x4f except tail and head*/  
  1293.         num_escape_char_temp = protocal_info_ptr->length[0] - 2;  
  1294. #if 0  
  1295.         printf("%4d\n", num_escape_char_temp);  
  1296. #endif  
  1297.         while ((num_escape_char_temp--) > 1)  
  1298.         {  
  1299.             if ((0xff == package_data[num_escape_char_temp])  
  1300.                     | (0xf4 == package_data[num_escape_char_temp])  
  1301.                     | (0x4f == package_data[num_escape_char_temp]))  
  1302.             {  
  1303.                 num_escape_char++;  
  1304.             }/*end if*/  
  1305.         }/*end while*/  
  1306. #if DEBUG  
  1307.         printf("num_escape_char is %4d\n", num_escape_char);  
  1308. #endif  
  1309.         if(0 == num_escape_char)  
  1310.         {  
  1311.             /*no escape characters send data diretly*/  
  1312.             if (write(port_fd, package_data,  
  1313.                         protocal_info_ptr->length[0]) < 0)  
  1314.             {  
  1315.                 printf("write data error!!!\n");  
  1316.                 return FALSE;   
  1317.             }  
  1318.             else  
  1319.             {  
  1320.                 printf("write to port_fd data success!\n");  
  1321.             }  
  1322.   
  1323.             /*free the malloc*/  
  1324.             free(package_data);  
  1325.             package_data = NULL;  
  1326.         }/*end if*/  
  1327.         else  
  1328.         {  
  1329.             escape_char_ptr = (U8 *)malloc(sizeof(U8)     
  1330.                     * (protocal_info_ptr->length[0] + num_escape_char));   
  1331. #if DEBUG  
  1332.             printf("%4d \n", protocal_info_ptr->length[0]);  
  1333. #endif  
  1334.             escape_character(package_data,   
  1335.                     protocal_info_ptr->length[0], escape_char_ptr);  
  1336. #if DEBUG  
  1337.             U8 k = 0;  
  1338.             for (; k < protocal_info_ptr->length[0]  
  1339.                     + num_escape_char; k++)  
  1340.             {  
  1341.                 printf("%04x ", escape_char_ptr[k]);  
  1342.             }  
  1343.             printf("\nport_fd is %4d\n", port_fd);  
  1344. #endif  
  1345.             /*send data*/  
  1346.             INT8 res = 0;  
  1347. #if 1         
  1348.             printf("writing data......\n");  
  1349.             /*escape_char_ptr */  
  1350.             res = write(port_fd, escape_char_ptr,  
  1351.                         (protocal_info_ptr->length[0] + num_escape_char));  
  1352. #if DEBUG  
  1353.             printf("res is %2d\n", res);  
  1354. #endif  
  1355.             if (res < 0)  
  1356.             {  
  1357.                 printf("write data error!\n");  
  1358.                 return FALSE;  
  1359.             }  
  1360.             printf("write data end!!!\n");  
  1361. #endif  
  1362.             free(escape_char_ptr);  
  1363.             escape_char_ptr = NULL;  
  1364.         }/*end else*/  
  1365.           
  1366.         /*free the memory*/  
  1367.         free(package_data);  
  1368.         package_data = NULL;  
  1369.     }/*end else*/  
  1370.   
  1371.     return TRUE;  
  1372. }  
  1373. /************************************************* 
  1374.  * Function: data_recv() 
  1375.  * Description:  the data and  
  1376.  * Calls: none 
  1377.  * Called By: none 
  1378.  * Input: none 
  1379.  * Output: none 
  1380.  * Return:  
  1381.  * Author: xhniu 
  1382.  * History: <author> <date>  <desc> 
  1383.  * Others: none 
  1384. ************************************************/  
  1385. void *data_recv(recv_param *data_recv_info_ptr)  
  1386. {  
  1387.     INT8 port_fd = data_recv_info_ptr->port_fd;  
  1388.     U8 *data_recv_buf_ptr = data_recv_info_ptr->buf;  
  1389. #if DEBUG  
  1390.     printf("port_fd is %4d\n", data_recv_info_ptr->port_fd);  
  1391. #endif  
  1392.     U8 pos = 0;   
  1393.     U8 len = 0;  
  1394.     U8 data_proc_pos = 0;  
  1395.     U8 data_start_pos = 0;  
  1396.     U8 data_new_flag = 0;  
  1397. #if DEBUG  
  1398.     printf("start to read data!\n");  
  1399. #endif  
  1400.     while(1)  
  1401.     {  
  1402.         /*judge the exit flag*/  
  1403.         if (1 == g_exit_flag)  
  1404.         {  
  1405.             printf("in data_recv thread,g_exit_flag%4d\n", g_exit_flag);  
  1406.             break;  
  1407.         }  
  1408.         sleep(1);  
  1409. #if DEBUG  
  1410.         printf("pos is %4dlen is %4d\n", pos, len);  
  1411. #endif  
  1412.         len = read(port_fd, &data_recv_buf_ptr[pos], (BUFFER_SIZE - pos));  
  1413.         printf("len is %4d\n", len);  
  1414.         if (len > 0)  
  1415.         {  
  1416.             printf("len is %4d ", len);  
  1417.             pos += len;  
  1418.             data_new_flag = 1;  
  1419.             continue;  
  1420.         }  
  1421.         else if (0 == data_new_flag && 0 == len)  
  1422.         {  
  1423.             printf("no new data come......\n");  
  1424.             continue;  
  1425.         }/*end if*/  
  1426.   
  1427.         /* receiving data */  
  1428.         if ((0 == len) && (pos < BUFFER_SIZE) &&(1 == data_new_flag))  
  1429.         {  
  1430.             /*start to process data*/  
  1431. #if DEBUG  
  1432.             printf("data_start_pos is%2d pos is %3d\n", data_start_pos, pos);  
  1433. #endif  
  1434.             data_proc_pos = data_process(data_recv_buf_ptr, data_start_pos, pos);  
  1435.             if (data_proc_pos > 0)  
  1436.             {  
  1437.                 data_start_pos = data_proc_pos;  
  1438.             }  
  1439.             else  
  1440.             {  
  1441.                 data_start_pos = pos;  
  1442.             }  
  1443.             printf("data_proc_pos is %3d\n", data_proc_pos);  
  1444.             data_new_flag = 0;  
  1445.         }  
  1446.           
  1447.         if (BUFFER_SIZE == pos)  
  1448.         {  
  1449. #if DEBUG  
  1450.             printf("stop recv data, data_start_pos is %2d pos is %4d\n",  
  1451.                     data_start_pos, pos);  
  1452. #endif  
  1453.             data_proc_pos = data_process(data_recv_buf_ptr, data_start_pos, pos);  
  1454.   
  1455.             printf("data_proc_pos is %4d\n", data_proc_pos);  
  1456.   
  1457.             memcpy(&data_recv_buf_ptr[0], &data_recv_buf_ptr[data_proc_pos],   
  1458.                     (BUFFER_SIZE - data_proc_pos));  
  1459.   
  1460.             pos = (BUFFER_SIZE - data_proc_pos);  
  1461.             data_start_pos = 0;  
  1462.         }/*end if*/  
  1463.           
  1464.     }/*end while*/  
  1465. }/*end function*/  
  1466. /************************************************* 
  1467.  * Function: tsk_thread_create() 
  1468.  * Description:  create a thread for a tsk 
  1469.  * Calls: main 
  1470.  * Called By: pthread_create 
  1471.  * Input: task  
  1472.  * Output: error infomation 
  1473.  * Return: TURE?FALSE 
  1474.  * Author: xhniu 
  1475.  * History: <author> <date>  <desc> 
  1476.  * Others:  
  1477. ************************************************/  
  1478. pthread_t tsk_thread_create(void *(*start_routine)(void *),void *arg)  
  1479. {  
  1480.     INT8 ret = 0;  
  1481.     /*create a msg_que*/  
  1482.     msg_que msg_que_info;  
  1483.     INT16 msg_que_id;  
  1484.     key_t key;  
  1485.     key = (key_t)MSG_QUE_KEY;  
  1486.     /*judge the msg que is exist*/  
  1487.     msg_que_id = msgget(MSG_QUE_KEY, IPC_EXCL);  
  1488. #if 1  
  1489.     printf("%4d\n", msg_que_id);  
  1490. #endif  
  1491.     if (msg_que_id <= 0)  
  1492.     {  
  1493.         /*create the msg_que*/  
  1494.         printf("the msg que is not exist!\n");  
  1495.         msg_que_id = msgget(key, IPC_CREAT | 0666);   
  1496.         if (msg_que_id < 0)  
  1497.         {  
  1498.             printf("create the msg que failed!\n");  
  1499.             return FALSE;  
  1500.         }  
  1501.         else  
  1502.         {  
  1503.             printf("create the msg que success,and the msg_que_id is:%4d\n",   
  1504.                     msg_que_id);  
  1505.         }  
  1506.     }  
  1507.     else  
  1508.     {  
  1509.         printf("the msg_que is exist the msg_que_id is:%4d\n", msg_que_id);  
  1510.     }/*end if*/  
  1511.     pthread_t thread_id;  
  1512.   
  1513.     ret = pthread_create(&thread_id, NULL, (void *)*start_routine, arg);  
  1514.     if (FALSE == ret)  
  1515.     {  
  1516.         perror("cannot create a tsk!!!\n");  
  1517.         return FALSE;  
  1518.     }  
  1519.     else  
  1520.     {  
  1521.         printf("new tsk create success! thread_id is %4d\n", (U16)thread_id);  
  1522.     }  
  1523.   
  1524.     return thread_id;  
  1525. }  
  1526. /************************************************* 
  1527.  * Function: tsk_thread_delete() 
  1528.  * Description:  delete a thread 
  1529.  * Calls: main 
  1530.  * Called By: pthread_exit() 
  1531.  * Input:  
  1532.  * Output: none 
  1533.  * Return:  
  1534.  * Author: xhniu 
  1535.  * History: <author> <date>  <desc> 
  1536.  * Others: none 
  1537. ************************************************/  
  1538. U8 tsk_thread_delete(void)  
  1539. {  
  1540.     /*free the related system resource*/  
  1541.     INT16 msg_que_id = 0;  
  1542.     msg_que_id = msgget(MSG_QUE_KEY, IPC_EXCL);  
  1543.     if (msg_que_id < 0)  
  1544.     {  
  1545.         printf("msg que is not exist!\n");  
  1546.         return TRUE;  
  1547.     }  
  1548.     else   
  1549.     {  
  1550.         if(msgctl(msg_que_id, IPC_RMID, 0) < 0)  
  1551.         {  
  1552.             printf("delete msg_que failed!\n");  
  1553.             return FALSE;  
  1554.         }  
  1555.         else  
  1556.         {  
  1557.             printf("delete msg_que: %4d success\n",msg_que_id);  
  1558.             return TRUE;  
  1559.         }/*end if*/  
  1560.     }/*end if*/  
  1561. }  
  1562. /************************************************* 
  1563.  * Function: close_port(INT8 port_fd) 
  1564.  * Description:  close the serial port 
  1565.  * Calls: none 
  1566.  * Called By: main 
  1567.  * Input: port_fd 
  1568.  * Output: none 
  1569.  * Return: TURE/FALSE 
  1570.  * Author: xhniu 
  1571.  * History: <author> <date>  <desc> 
  1572.  * Others: none 
  1573. ************************************************/  
  1574. U8 close_port(INT8 port_fd)  
  1575. {  
  1576.     if (close(port_fd) < 0)  
  1577.     {  
  1578.         printf("close the serial port failed!\n");  
  1579.         return FALSE;  
  1580.     }  
  1581.     else  
  1582.     {  
  1583.         printf("close the serial port success\n");  
  1584.         return TRUE;  
  1585.     }/*end if*/  

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值