gpt4 book ai didi

c - BGLIB SiliconLabs 代码错误?

转载 作者:行者123 更新时间:2023-11-30 16:36:53 30 4
gpt4 key购买 nike

我正在使用 SiliconLabs 的 BGLIB 静态库通过串行端口与 BLED112 进行通信。为了使用这个库,需要定义两个函数:一个用于发送,另一个用于从串行端口接收字节。所有从串口接收到的数据都可以分为两部分: header 和数据。

按照“thermometer-demo”示例的“main.c”代码,该函数从串行接收数据,首先接收 header 和数据。当收到 header 和数据后,代码通过以下代码解析 header 并初始化 *msg 变量:

unsigned char data[256];
struct ble_header hdr;
int r;

r = uart_rx(sizeof(hdr), (unsigned char *)&hdr, UART_TIMEOUT);
.
.
.
if (hdr.lolen) {
r = uart_rx(hdr.lolen, data, UART_TIMEOUT);
.
.
.

}

const struct ble_msg *msg = ble_get_msg_hdr(hdr);

*msg 变量是一个 ble_msg 结构指针,该结构是这样定义的:

struct ble_msg
{
struct ble_header hdr;
uint32 params;
ble_cmd_handler handler;
};

handler是一个函数指针,在初始化*msg时初始化。解析 header 后,代码调用此函数指针:

用于初始化该函数指针的函数在库中定义为空,如果您想使用其中之一,则需要将其删除并重写。

在“thermometer-demo”示例中,使用 void ble_evt_gap_scan_response(const struct ble_msg_gap_scan_response_evt_t *msg) 函数来接收所有可见设备,并且 ble_msg_gap_scan_response_evt_t 的定义如下:

PACKSTRUCT(struct ble_msg_gap_scan_response_evt_t
{
int8 rssi;
uint8 packet_type;
bd_addr sender;
uint8 address_type;
uint8 bond;
uint8array data;
});

使用uint8array这样定义:

typedef struct
{
uint8 len;
uint8 *data;
}uint8array;

对我来说,存在一个问题:当执行 msg->handler(data) 代码并且调用 ble_evt_gap_scan_response 函数时,会在两者之间执行强制转换数据缓冲区和 ble_msg_gap_scan_response_evt_t 结构体以及 uint8 *data 的内容(在 uint8array 结构体中)使用从 SerialPort 接收的数据进行初始化,然后将指向到不正确的 RAM 位置。

我认为目的是提供一种直接访问数据的方法,但对我来说这不是正确的方法。这是我的错误评估还是 bglib bug?

最佳答案

我已联系 SiliconLabs 支持人员,原始库是正确的,但我的库版本似乎不正确。

就像 SiliconLabs 支持人员建议我的那样(并且像此链接中解释得很好: http://www.drdobbs.com/questions-answers-creating-variable-siz/184403480 ),有 3 种可能的声明:

1°声明:

typedef struct
{
uint8 len;
uint8 data[0];
}uint8array;

我通过以下方式访问数据:

msg->data->data[0]
msg->data->data[1]
msg->data->data[2]
...
msg->data->data[n]

在这种情况下,编译器可能会警告缓冲区索引超出限制。

2°声明:

typedef struct
{
uint8 len;
uint8 data[1000];
}uint8array;

在这种情况下,可以以与前一种相同的方式访问数据,但分配的空间超出了必要的范围(在嵌入式中,有时优化很重要,因为资源有限),或者像前一种一样,您可能会超出缓冲区限制。

3°声明:

typedef struct
{
uint8 len;
uint8 data[];
}uint8array;

此声明的名称是灵活数组成员 ( https://en.wikipedia.org/wiki/Flexible_array_member ),并在 C99 标准中引入。在这种情况下,可以按照与前一种相同的方式访问数据,但编译器可以警告这不是标准声明。此声明与 SiliconLabs 为该库采用的声明相同。

就我而言,我使用的是 VisualStudio,并且采用了第三种解决方案,但编译器向我返回警告 C4200(非标准声明)。我尝试了第一个解决方案,编译器不会向我返回任何警告,但对我来说,代码的清晰度缺失,可能会成为 future 使用的问题。

关于c - BGLIB SiliconLabs 代码错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48259706/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com