返回类型为struct的函数每次调用时都不返回任何内容
Function having return type of struct return nothing every second time its called
我正在编写一个程序,通过ESP32(Arduino Framework(中的蓝牙接收SSID和密码。函数BTSerialRcvBuffer((等待蓝牙,当它接收到一个字符串时,它通过一个类型为structBuffer_return的变量返回字符串的基地址和大小。该函数返回SSID,但不返回密码。我不知道为什么?我必须为Var.rtn_addr分配内存还是为变量buff1和buff2分配足够的内存?
#include <Arduino.h>
#include <stdlib.h>
#include <BluetoothSerial.h>
#include <WiFi.h>
#define btrcv_buffer_size 256
BluetoothSerial SerialBT;
typedef struct
{
char *rtn_addr;
int buff_len;
} Buffer_return;
Buffer_return* BTSerialRcvBuffer() {
static int i = 0;
static char rcv_buffer[ btrcv_buffer_size ];
static Buffer_return Var;
memset(rcv_buffer,0, btrcv_buffer_size);
while (!SerialBT.available());
delayMicroseconds(500);
while(SerialBT.available()) {
rcv_buffer[i] = SerialBT.read();
i++;
}
rcv_buffer[i-1] = ' ';
rcv_buffer[i-2] = ' ';
SerialBT.flush();
Var.rtn_addr = rcv_buffer; //<------------Do I have to allocate memory for Var.rtn_addr?
Var.buff_len = i-1;
return &Var;
}
void WiFiConfig() {
//WiFi.printDiag(Serial);
Serial.println("Enter SSID");
Buffer_return *buff1 = BTSerialRcvBuffer();
char *ssid = (char*) malloc((buff1->buff_len) * sizeof(char));
strcpy(ssid,buff1->rtn_addr);
Serial.println(ssid);
Serial.println("Enter Password");
Buffer_return *buff2 = BTSerialRcvBuffer();
char *pass = (char*) malloc((buff2->buff_len) * sizeof(char));
strcpy(pass,buff2->rtn_addr);
Serial.println(pass);
//Serial.println(buff2->buff_len);
free(ssid)
free(pass);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Establishing connection to WiFi..");
Serial.printf("Connection status: %dn", WiFi.status());
}
}
void setup() {
Serial.begin(115200);
//WiFi.disconnect(true);
SerialBT.begin("ESP32_INO"); //Bluetooth device name
WiFi.mode(WIFI_STA);
Serial.println("The device started, now you can pair it with bluetooth!");
WiFiConfig();
Serial.println("Connected to network");
Serial.println(WiFi.macAddress());
Serial.println(WiFi.localIP());
}
void loop() {
}
输出:
Enter SSID
Airtel_5G <----- prints fine!
Enter Password
<----- Problem!
Establishing connection to WiFi..
Connection status: 6
Establishing connection to WiFi..
Connection status: 6
Establishing connection to WiFi..
Connection status: 6
代码使用以下序列将输入数据复制到缓冲区。
Buffer_return *buff1 = BTSerialRcvBuffer();
char *ssid = (char*) malloc((buff1->buff_len) * sizeof(char));
strcpy(ssid,buff1->rtn_addr);
回想一下,字符串是以NUL结尾的,所以分配必须包括额外的字节!。malloc调用的简单更新:
char *ssid = (char*) malloc((buff1->buff_len+1) * sizeof(char));
根据@lundin的输入,不建议对Arduino使用malloc。最好使用自动分配。
另请参阅:https://arduino.stackexchange.com/questions/682/is-using-malloc-and-free-a-really-bad-idea-on-arduino
char ssid[buff2->buff_len+1] ;
strcpy(ssid, buff2->rtn_addr) ;
更新1:BTSerialRcvBuffer错误
BTSerialRcvBuffer
对包括i
在内的许多变量使用static。回想一下,静态变量初始化一次(在程序启动时(。建议从i
中删除"static"-以修复初始化,因为不需要使其为静态。
同样,也不清楚为什么rcv_buffer
的最后两个位置被重置为零?
代码中有很多错误的做法和缓慢的函数调用。请记住,这是一个8位MCU,所以速度非常慢。一些需要修复的问题:
- 没有必要每次都将rx缓冲区清零。只需跟踪其中包含有效数据的部分有多大。对256字节的
memset
调用非常昂贵 - 通常的做法是将rx缓冲器加倍,以便一个缓冲器可以同时用于接收,另一个缓冲器用于解码。您不使用中断,所以这可能不是什么问题。256字节是一个很大的RAM,所以如果你需要存储那么多数据,双缓冲可能需要更好的MCU。无论如何,我将在下面使用一个双缓冲区示例来展示如何做到这一点
delayMicroseconds(500);
除了将程序挂起500毫秒外,没有任何意义。把它取下来- 错误:在接收过程中,您不会检查缓冲区是否溢出
#define BT_RXBUF_SIZE 256
const char* BTSerialReceive (size_t* size_rec)
{
static char buf1 [BT_RXBUF_SIZE];
static char buf2 [BT_RXBUF_SIZE];
static char* buf = buf1;
buf = (buf == buf1) ? buf2 : buf1; // swap rx buffers
while (!SerialBT.available())
;
size_t i=0;
for(; SerialBT.available() && i<BT_RXBUF_SIZE; i++)
{
buf[i] = SerialBT.read();
}
buf[i] = ' ';
SerialBT.flush();
*size_rec = i;
return buf;
}
具有双缓冲器的指针交换消除了对缓慢且昂贵的memcpy
/strcpy
的需要。如果您使用UART中断,出于重新进入的原因,您将不得不使用这样的设计。
另一件你必须绝对避免的事情是malloc
。这是缓慢和无意义的,看这个。使用嵌入式系统时,必须始终使用固定长度的缓冲区和确定数量的内存。去掉malloc
意味着您可以去掉链接器脚本中的整个堆段,这将释放大量有价值的RAM。
- 模板化接口 - 创建一个泛型模板类以返回任何容器
- 这是使用回溯的 nqueen 问题,但我使用了动态 2d 数组,我的程序编译良好,但不返回任何输出
- C++ - 声明指向返回任何类型并获取任意数量参数的函数的指针
- 类和构造函数中的函数根本不起作用,并且不返回任何错误
- 为什么套接字中的 recv() 函数不返回任何内容?
- 是否有任何内置的哈希图函数来处理 c++ 中的值输入?
- C++如何使虚拟函数返回任何类型的指针
- 返回类型为struct的函数每次调用时都不返回任何内容
- 此程序不返回任何内容
- 是否有任何内置函数可以检查给定的两个数字在给定整数数组中的顺序是否相同?
- std::ifstream.read() 不会向我的缓冲区返回任何内容
- 为什么即使输入相等,v3 也不会返回任何内容
- glGetBufferSubData() 不返回任何数据?
- stbi_load() 不返回任何内容,但不返回 null
- C++ 中是否有任何内置阶乘函数?
- 如何处理不保证返回任何内容的函数
- C++递归不返回任何内容
- MySQL++ 不返回任何内容
- stbi_load不返回任何值
- 是否有任何内置函数可以告诉编译器分支是否可预测