Я пытался закодировать строку с помощью библиотеки Nanopb на NodeMCU и опубликовать ее с помощью 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
Кажется, вы переполняете свой стек, т.е. не хватает места, выделенного для локальных переменных. Когда одна из библиотек работает отдельно, места достаточно, но при объединении оно заканчивается.
Простой способ исправить это - изменить эту большую переменную на статическое распределение:
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
.
Привет, @Anuroop Shannu. Какую библиотеку AzureMQTT вы использовали? Ссылались ли вы на AzureIoTHubMQTTClient или AzureIoTProtocol_MQTT? Вы можете получить образцы с этими двумя библиотеками.
Привет, @Michael Xu, MSFT, я использую AzureIoTHubMQTTClient. Как я уже говорил ранее, и Azure, и Nanopb работают нормально по отдельности, то есть я могу опубликовать сообщение и получить его в обозревателе устройства, когда я не использую nanopb.
Пытался перейти на статический, сразу при включении питания выдает ошибку стека (9): LoadStoreAlignment Причина: Загрузить или сохранить по невыровненному адресу. Кроме того, попытался изменить размер стека в cont.h на 16384 с 4096. Затем я получаю фатальное исключение 2 (InstructionRetchErrorCause)