当前位置: 首页 > 工具软件 > nanopb > 使用案例 >

基于RT1052 Aworks nanopb string 类型动态长度使用方式(二十六)

卞博简
2023-12-01

本文主要是通过迁移的思维,记录本人初次使用周立功的Aworks框架进行开发

本文在Aworks上使用nanopb库对string类型字段进行封包及解包测试。
参考链接封包及解包原理:https://www.cnblogs.com/silvermagic/p/9087593.html

1. 定义string消息协议

message LaneStatus {
   bool showLane = 1; 
   string laneBackInfo = 2;
   string laneSelectInfo = 3; 
}

使用如下命令进行编译

..\..\generator-bin\protoc --nanopb_out=. simple.proto

最终生成的结构体

/* Struct definitions */
typedef struct _LaneStatus { 
    bool showLane; /* true:显示/ false:隐藏 */
    pb_callback_t laneBackInfo; /* 车道背景信息 */
    pb_callback_t laneSelectInfo; /* 车道前景信息 */
} LaneStatus;

2.测试代码

#include <stdio.h>
#include <pb_encode.h>
#include <pb_decode.h>
#include <string.h>
#include "BleMessage2.pb.h"
#include "aw_vdebug.h"


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pb_decode.h>


#define TEST(x) if (!(x)) { \
    aw_kprintf("Test %s failed (in field %d).\n", #x, field->tag); \
    return false; \
    }

static bool write_string(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
{
    return pb_encode_tag_for_field(stream, field) &&
           pb_encode_string(stream, *arg, strlen(*arg));
}

static bool read_string(pb_istream_t *stream, const pb_field_t *field, void **arg)
{
    uint8_t buf[128] = {0};
    size_t len = stream->bytes_left;

    if (len > sizeof(buf) - 1 || !pb_read(stream, buf, len))
        return false;
    
	strncpy(*arg,(char *)buf,strlen(buf));
    //TEST(strcmp((char*)buf, *arg) == 0);
    return true;
}


int lanestatus_test_main()
{
    /* This is the buffer where we will store our message. */

    uint8_t buffer[128] = {0};
    size_t message_length = 0;
 
     bool status;
    {
        com_bst_modules_iot_proto_LaneStatus sign = com_bst_modules_iot_proto_LaneStatus_init_zero;
        sign.laneBackInfo.funcs.encode = write_string;
        sign.laneBackInfo.arg = &"laneBackInfo";
        sign.laneSelectInfo.funcs.encode = write_string;
        sign.laneSelectInfo.arg = &"laneSelectInfo";
        sign.showLane = true;
        pb_ostream_t stream  = pb_ostream_from_buffer(buffer, sizeof(buffer));
        status = pb_encode(&stream, com_bst_modules_iot_proto_LaneStatus_fields, &sign);
        message_length = stream.bytes_written;
        /* Then just check for any errors.. */
        if (!status)   {
            aw_kprintf("Encoding failed: %s\n", PB_GET_ERROR(&stream));
            return 1;
        }
				aw_kprintf("message_length: %d\n", message_length);
    }
    
    {
		char laneBackInfo_tmp[128]={0};
		char laneSelectInfo_tmp[128]={0};
        /* Allocate space for the decoded message. */
        com_bst_modules_iot_proto_LaneStatus message = com_bst_modules_iot_proto_LaneStatus_init_zero;
        message.laneBackInfo.funcs.decode = read_string;
        message.laneBackInfo.arg = &laneBackInfo_tmp;
        message.laneSelectInfo.funcs.decode = read_string;
        message.laneSelectInfo.arg = &laneSelectInfo_tmp;	

        /* Create a stream that reads from the buffer. */
        pb_istream_t stream = pb_istream_from_buffer(buffer, message_length);
        
        /* Now we are ready to decode the message. */
        status = pb_decode(&stream, com_bst_modules_iot_proto_LaneStatus_fields, &message);
        
        /* Check for errors... */
        if (!status)
        {
            aw_kprintf("Decoding failed: %s\n", PB_GET_ERROR(&stream));
            return 1;
        }
        
        /* Print the data contained in the message. */
        aw_kprintf("Your showLane = %d!\n", message.showLane);   				     
        aw_kprintf("Your laneBackInfo = %s!\n", laneBackInfo_tmp);
        aw_kprintf("Your laneSelectInfo = %s!\n", laneSelectInfo_tmp); 
				
		aw_kprintf("Your laneBackInfo = %s!\n", message.laneBackInfo.arg);
        aw_kprintf("Your laneSelectInfo = %s!\n", message.laneSelectInfo.arg); 

    }
}

3. 验证

AWorks for i.MX RT1050, build Mar  1 2022

AWorks SDK Version is 2.1.2 <2020-09-30>  
current time: 1970-01-01 07:36:47

Appl|AWorks->>> ication Start. 
message_length: 32
Your showLane = 1!
Your laneBackInfo = laneBackInfo!
Your laneSelectInfo = laneSelectInfo!
Your laneBackInfo = laneBackInfo!
Your laneSelectInfo = laneSelectInfo!

4. 总结

动态长度在封包及解包时,需要注册encode及decode函数,并且需要传递缓冲区。
动态长度也有一个弊端,比如Java开发者就不需要考虑长度,但是C语言开发者就需要考虑,最好的方式就是在双方约定最大长度大小。

 类似资料: