C的一些算法技巧

一 数据分包与位字节计算:

modbus中m个位寄存器需要的字节数计算:

  #define BytesForBitRegs(m)  (total/8 + ((total%8)?1:0))

传输m个字节,每包/帧大小为n,则总共需要的包数

#define PackNum(total,single)  (total/single + ((total%single)?1:0))或

PackNum = (total + (singleNum - 1))/singleNum ;

二 数据字节编码算法COBS,可用于串口通信

以modbus rtu通信为例,一般是3.5字符作为帧间隔区分,而使用COBS就不需要这样了,他是将范围 [0,255] 内的任意字节字符串转换为 [1,255] 范围内的字节。从数据中消除所有0,现在可以使用0来明确标记转换后数据的结束

 

 

 

 

 1 #include <stddef.h>
 2 #include <stdint.h>
 3 #include <assert.h>
 4  
 5 /** COBS encode data to buffer
 6         @param data Pointer to input data to encode
 7         @param length Number of bytes to encode
 8         @param buffer Pointer to encoded output buffer
 9         @return Encoded buffer length in bytes
10         @note Does not output delimiter byte
11 */
12 size_t cobsEncode(const void *data, size_t length, uint8_t *buffer)
13 {
14         assert(data && buffer);
15  
16         uint8_t *encode = buffer; // Encoded byte pointer
17         uint8_t *codep = encode++; // Output code pointer
18         uint8_t code = 1; // Code value
19  
20         for (const uint8_t *byte = (const uint8_t *)data; length--; ++byte)
21         {
22                 if (*byte) // Byte not zero, write it
23                         *encode++ = *byte, ++code;
24  
25                 if (!*byte || code == 0xff) // Input is zero or block completed, restart
26                 {
27                         *codep = code, code = 1, codep = encode;
28                         if (!*byte || length)
29                                 ++encode;
30                 }
31         }
32         *codep = code; // Write final code value
33  
34         return (size_t)(encode - buffer);
35 }
36  
37 /** COBS decode data from buffer
38         @param buffer Pointer to encoded input bytes
39         @param length Number of bytes to decode
40         @param data Pointer to decoded output data
41         @return Number of bytes successfully decoded
42         @note Stops decoding if delimiter byte is found
43 */
44 size_t cobsDecode(const uint8_t *buffer, size_t length, void *data)
45 {
46         assert(buffer && data);
47  
48         const uint8_t *byte = buffer; // Encoded input byte pointer
49         uint8_t *decode = (uint8_t *)data; // Decoded output byte pointer
50  
51         for (uint8_t code = 0xff, block = 0; byte < buffer + length; --block)
52         {
53                 if (block) // Decode block byte
54                         *decode++ = *byte++;
55                 else
56                 {
57                         if (code != 0xff) // Encoded zero, write it
58                                 *decode++ = 0;
59                         block = code = *byte++; // Next block length
60                         if (!code) // Delimiter code found
61                                 break;
62                 }
63         }
64  
65         return (size_t)(decode - (uint8_t *)data);
66 }
View Code

 

posted on 2022-06-02 16:34  杰瑞鼠  阅读(169)  评论(0编辑  收藏  举报