2

我一直在尝试使用NodeMCU上的 Nanopb 库对字符串进行编码,并使用AzureMQTT发布它。

在单独测试时,Nanopb 和 Azure 都可以正常工作。但是,将两者集成在一个草图中会给我带来错误。

      void loop(){
      uint8_t sMsg[512];
      gestures data;
      char *msg = "aaaaaaaaaaaaaaaaaaaaaaaaa";
      strcpy(data.values,msg);
      Serial.println("done with strcpy");
      pb_ostream_t buffer = pb_ostream_from_buffer(sMsg, sizeof(sMsg));
      if (!(pb_encode(&buffer, gestures_fields, &data))) {
          Serial.println(F("Encoding failed"));
          Serial.println(PB_GET_ERROR(&buffer));
          return;
       }
       else
       {
          Serial.println("enterd else");
          Serial.println((char*)sMsg);
          client.run();
          if (client.connected()) {
         Serial.println("connected");           
         String payload = "{\"DeviceId\":\"" + String(DEVICE_ID) + "\", \"data\":" + (char*)sMsg + "}";
        Serial.println(payload);
        client.sendEvent(payload);
         Serial.println("Published message!");

   }
 }
 Serial.println("Done with loop");
 }

串口输出如下:

entered if
done with strcpy
enterd else

aaaaaaaaaaaaaaaaaaaaaaaaa?z[@t/⸮?⸮⸮⸮?⸮⸮⸮?⸮⸮⸮?⸮+⸮?⸮⸮⸮?$⸮?
Done with loop

如果观察到,client.connected()则返回 false,因此,消息不会被发布。

此外,有时会client.run()出现堆栈错误:

Fatal exception 28(LoadProhibitedCause):
epc1=0x401016dc, epc2=0x00000000, epc3=0x00000000, excvaddr=0x02786a4c, 
depc=0x00000000

Exception (28):
epc1=0x401016dc epc2=0x00000000 epc3=0x00000000 excvaddr=0x02786a4c 
depc=0x00000000

ctx: sys 
sp: 3ffffcf0 end: 3fffffb0 offset: 01a0

>>>stack>>>
3ffffe90:  3fff0010 3fff242c 00000000 40216af4  
3ffffea0:  00000000 005e5dbc 40216b4b 3fff242c  
3ffffeb0:  3fff2414 ffffffbc 00000000 ffffffff  
3ffffec0:  02786a30 00000000 4020c087 00000026  
3ffffed0:  ffffffff 00000000 3ffeaf61 00000130  
3ffffee0:  4020c0da 3fff2d2c 3ffef1cc 3ffef4cc  
3ffffef0:  00000000 00000000 4010195b 3fff2d2c  
3fffff00:  000000c0 00000000 00000064 3fff2d94  
3fffff10:  4020b4e0 3fff2d2c 3fff2d6c 401070bc  
3fffff20:  00000009 4021007c 3ffef848 40234b25  
3fffff30:  3fff1f34 3fff1f30 005e5dcb 4010610e  
3fffff40:  402164be 3ffee878 3ffee878 40234d6d  
3fffff50:  401060f4 00000000 00000000 0000001c  
3fffff60:  4021fdb4 3ffeffe8 0000001b 4021fdc1  
3fffff70:  3ffef858 3fff0010 027982a2 60000600  
3fffff80:  4021fe06 3fffdab0 00000000 3fffdcb0  
3fffff90:  3fff0020 3fffdab0 00000000 40208993  
3fffffa0:  40000f49 40000f49 3fffdab0 40000f49  
<<<stack<<<

解码堆栈跟踪给出:

Exception 28: LoadProhibited: A load referenced a page mapped with an 
attribute that does not permit loads
Decoding 22 results
0x401016dc: ppEnqueueRxq at ?? line ?
0x401016dc: ppEnqueueRxq at ?? line ?
0x40216af4: ieee80211_parse_wmeparams at ?? line ?
0x40216b4b: ieee80211_parse_wmeparams at ?? line ?
0x4020c087: pp_attach at ?? line ?
0x4020c0da: pp_attach at ?? line ?
0x4010195b: ppCalFrameTimes at ?? line ?
0x4020b4e0: ppCheckTxIdle at ?? line ?
0x401070bc: pvPortMalloc at         

C:\Users\Violet\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/heap.c 第 13 行

0x4021007c: ieee80211_getmgtframe at ?? line ?
0x40234b25: udp_input at 
/Users/igrokhotkov/espressif/arduino/tools/sdk/lwip/src/core/udp.c line 106 
(discriminator 1)
0x4010610e: igmp_timer at 
/Users/igrokhotkov/espressif/arduino/tools/sdk/lwip/src/core/timers.c line 
222
0x402164be: sta_input at ?? line ?
0x40234d6d: udp_bind at 
/Users/igrokhotkov/espressif/arduino/tools/sdk/lwip/src/core/udp.c line 787
0x401060f4: igmp_timer at 
/Users/igrokhotkov/espressif/arduino/tools/sdk/lwip/src/core/timers.c line 217
0x4021fdb4: system_get_os_print at ?? line ?
0x4021fdc1: system_pp_recycle_rx_pkt at ?? line ?
0x4021fe06: system_restart_hook at ?? line ?
0x40208993: std::_Function_base::_Base_manager ::_M_manager(std::_Any_data&, 
std::_Any_data const&, std::_Manager_operation) at 

c:\users\violet\documents\arduinodata\packages\esp8266\tools\xtensa-lx106- 
elf-gcc\1.20.0-26-gb404fb9-2\xtensa-lx106-elf\include\c++\4.8.2/functional 
line 1934
4

1 回答 1

0

看来您可能溢出了堆栈,即为局部变量分配的空间不足。当任何一个库单独运行时,都有足够的空间,但当组合起来时,它就会用完。

解决此问题的一种简单方法是将这个大变量更改为静态分配:

uint8_t sMsg[512];        // Allocated on stack area
static uint8_t sMsg[512]; // Allocated separately

static 的作用是在程序的整个过程中为变量保留一个部分,而不是试图将它放在堆栈的小动态区域中。

也可以增加堆栈大小。在 Arduino ESP8266 SDK 上,这似乎是通过修改CONT_STACKSIZE.cores/esp8266/cont.h

于 2018-05-12T05:24:00.140 回答