【问题标题】:Difficulty in reading values from an array难以从数组中读取值
【发布时间】:2023-03-21 09:10:01
【问题描述】:

我正在编写 C++ 代码,但我正在为一些相当简单的事情苦苦挣扎:

我已经声明了一个数组

uint8_t *received_data 在我的代码中作为全局变量。

然后我在一个函数中分配它的内存:

void advertisementCallback(const Gap::AdvertisementCallbackParams_t *params) {

    if(params->type == 3){
        for(int i = 0; i < params->advertisingDataLen; i++){
            if(params->advertisingData[i] == 0x16){
                if(params->advertisingData[i+1] == 0x34 && params->advertisingData[i+2] == 0x23){
                    received_data_size = params->advertisingDataLen - (i + 3);
                    received_data = new uint8_t[received_data_size];
                    for(int index = i+3; index < params->advertisingDataLen; index++){
                        received_data[index] = params->advertisingData[index];
                        //printf("%02x ", received_data[index]);//params->advertisingData[index]);                       
                        //printf("\r\n");
                    }
                }
            }    
        }  
    }
}

请注意,注释的 printf 正在打印我正确接收的数据。

但是在我的 main 中,当我尝试相同的 printf 时,我大部分时间都会收到垃圾,有时我会在前三个位置收到数组的最后三个元素,然后是垃圾。

我的主要是:

int main(void)
{
    BLE& ble = BLE::Instance(BLE::DEFAULT_INSTANCE);
    ble.init(bleInitComplete);
    bool state = true;
    while(true){
        ble.waitForEvent();
        measurement[2]++;
        printf("In the loop \n");
        for(int i = 0; i < received_data_size; i++){
            printf("%02x ", received_data[i]);//params->advertisingData[index]);                       
            printf("\r\n");
        }
        delete[] received_data;
    }
}

目前的整个代码是:

#include "mbed.h"
#include "ble/BLE.h"

/* Optional: Device Name, add for human read-ability */
const static char     DEVICE_NAME[] = "G4";

uint16_t uuid16_list[]        = {0x2334};

/* You have up to 26 bytes of advertising data to use. */
const static uint8_t AdvData[] = {0x01,0x02,0x03,0x04,0x05};   /* Example of hex data */

uint8_t meas = 0;

uint8_t received_data_size;

static uint8_t *received_data;


uint8_t measurement[] = {0x34,0x23, meas};

/* Optional: Restart advertising when peer disconnects */
void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
{
    BLE::Instance().gap().startAdvertising();
}
/**
 * This function is called when the ble initialization process has failed
 */
void onBleInitError(BLE &ble, ble_error_t error)
{
    /* Avoid compiler warnings */
    (void) ble;
    (void) error;

    /* Initialization error handling should go here */
}    


void advertisementCallback(const Gap::AdvertisementCallbackParams_t *params) {

    if(params->type == 3){
        for(int i = 0; i < params->advertisingDataLen; i++){
            if(params->advertisingData[i] == 0x16){
                if(params->advertisingData[i+1] == 0x34 && params->advertisingData[i+2] == 0x23){
                    received_data_size = params->advertisingDataLen - (i + 3);
                    received_data = new uint8_t[received_data_size];
                    for(int index = i+3; index < params->advertisingDataLen; index++){
                        received_data[index] = params->advertisingData[index];
                        //printf("%02x ", received_data[index]);//params->advertisingData[index]);                       
                        //printf("\r\n");
                    }
                }
            }    
        }  
    }
}

/**
 * Callback triggered when the ble initialization process has finished
 */
void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
{
    BLE&        ble   = params->ble;
    ble_error_t error = params->error;

    if (error != BLE_ERROR_NONE) {
        /* In case of error, forward the error handling to onBleInitError */
        onBleInitError(ble, error);
        return;
    }

    /* Ensure that it is the default instance of BLE */
    if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
        return;
    }

    /* Set device name characteristic data */
    ble.gap().setDeviceName((const uint8_t *) DEVICE_NAME);

    /* Optional: add callback for disconnection */
    ble.gap().onDisconnection(disconnectionCallback);

    /* Sacrifice 3B of 31B to Advertising Flags */
    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE );
    ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);

    /* Sacrifice 2B of 31B to AdvType overhead, rest goes to AdvData array you define */
    //ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, AdvData, sizeof(AdvData));
    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::SERVICE_DATA, measurement, sizeof(measurement));
    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list));


    /* Optional: Add name to device */
    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));

    /* Set advertising interval. Longer interval == longer battery life */
    ble.gap().setAdvertisingInterval(500); /* 100ms */

    /* Start advertising */
    //ble.gap().startAdvertising();

    /*Start Scanning*/
    ble.gap().setScanParams(500 /* scan interval */, 200 /* scan window */);
    ble.gap().startScan(advertisementCallback);
}

int main(void)
{
    BLE& ble = BLE::Instance(BLE::DEFAULT_INSTANCE);
    ble.init(bleInitComplete);
    bool state = true;
    while(true){
        ble.waitForEvent();
        measurement[2]++;
        printf("In the loop \n");
        for(int i = 0; i < received_data_size; i++){
            printf("%02x ", received_data[i]);//params->advertisingData[index]);                       
            printf("\r\n");
        }
        delete[] received_data;
    }
}

BLE 代表蓝牙低功耗。该代码基于 mbed.org 上的示例

我想我错过了一些东西,但我不确定到底是什么。非常感谢您的帮助。

【问题讨论】:

  • [离题],避免使用全局变量。
  • 什么时候调用你的函数?
  • 全局变量会终结你。你已经在这里如履薄冰了。这是一大堆代码,这些神秘变量无处不在。分配的所有权似乎完全是任意的,这会很麻烦。
  • 你的平台是什么?您的回调是如何注册的?什么是BLE?请用答案编辑您的帖子。
  • 作为您帖子的质量检查,请将您发布的代码放入文件并编译。有没有错误?您发布的内容是否足以编译和构建?您是否提供了输入数据?

标签: c++ arrays function


【解决方案1】:

首先,如果不进一步查看代码的其余部分,您的全局接收数据的前三个字节将永远不会被写入。看看你的广告Callback() 的这个特定部分:

for(int index = i+3; index < params->advertisingDataLen; index++){
                    received_data[index] = params->advertisingData[index];

因此,用于写入 received_data 的索引总是从偏移量 3 开始 - 从不小于 - ,而它应该从 0 开始。为此添加一个专用的索引变量。在您的 main() 中,您创建了一个从 0 开始的循环:

for(int i = 0; i < received_data_size; i++){
        printf("%02x ", received_data[i]);

因此,调试输出的前三个字节将始终包含随机数据。

【讨论】:

  • 我也偶然发现了 ble.waitForEvent(); .您的处理程序 AdvertisementCallback() 是异步调用的吗?那么您应该避免将数据写入全局数组,因为您的数据在处理时可能会被覆盖。
  • 您在所有 cmets 中都是正确的。我通过使用全局向量解决了这个问题。在 adsCallback 中访问它,以便将我需要的值传递给它,然后我在我的 main 中访问它,读取这些值然后清除它。
  • 同样事件是异步的,但它很少发生,所以如果代码运行时发生了一些事情,它将被添加到向量的底部,而不影响其余的任务
猜你喜欢
  • 1970-01-01
  • 2020-07-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-11
  • 1970-01-01
相关资源
最近更新 更多