linux串口通信协议编程详解

来源:互联网 发布:六宫格切图软件 编辑:程序博客网 时间:2024/06/05 02:44

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值。

(代码实现)

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

3.Linux多线程编程;

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

这个实现的源代码如下:


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

转:http://blog.csdn.net/niuxuheng/article/details/39345241

0 0
原创粉丝点击