I would like to create a Arduino library for an ESP8266or ESP32 microcontroller. I wrote a test library which running on an Arduino Nano board with no problem. Here the library cpp file:
#include "Test.h"
Test::Test(){
}
uint32_t Test::libTest(strcttest* t){
uint32_t w;
w = t->a;
return w;
}
Here's the the header file :
#include <Arduino.h>
typedef struct {
uint32_t a;
uint32_t b;
}strcttest;
class Test
{
public:
Test();
uint32_t libTest(strcttest* t);
private:
};
And last but not least the Arduino ino file:
#include <Test.h>
//Instante Test
Test t;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
Serial.println("Start");
}
void loop() {
// put your main code here, to run repeatedly:
//Create structure
strcttest *tt;
tt->a=1;
tt->b=2;
//Output result
Serial.println (t.libTest(tt));
delay(1000);
}
Every compile fine with an Arduino Nano board as well as with ESP8266/ESP32 boards. When I run it on the Nano Board i get the expected result:
Start
1
1
1
1
1
1
1
1
1
...
When I run it on the ESP8266 board I get the following crash result:
l*⸮⸮⸮⸮CI>⸮⸮⸮HB⸮⸮Start
Exception (28):
epc1=0x402024f8 epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000000 depc=0x00000000
ctx: cont
sp: 3ffef7d0 end: 3ffef9a0 offset: 01a0
>>>stack>>>
3ffef970: feefeffe 00000000 3ffee950 40201eb4
3ffef980: feefeffe feefeffe 3ffee96c 40202340
3ffef990: feefeffe feefeffe 3ffee980 40100108
<<<stack<<<
7!a!*6⸮⸮⸮Start
Exception (28):
epc1=0x402024f8 epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000000 depc=0x00000000
ctx: cont
sp: 3ffef7d0 end: 3ffef9a0 offset: 01a0
>>>stack>>>
3ffef970: feefeffe 00000000 3ffee950 40201eb4
3ffef980: feefeffe feefeffe 3ffee96c 40202340
3ffef990: feefeffe feefeffe 3ffee980 40100108
<<<stack<<<
ĜBs⸮`⸮"⸮⸮Start
...
And last but not least on the ESP Development board I receive:
i%M/⸮`⸮i%M7
⸮⸮%Q=qU=\Md⸮aGd<$⸮Start
Guru Meditation Error of type LoadProhibited occurred on core 1. Exception was unhandled.
Register dump:
PC : 0x400dde93 PS : 0x00060030 A0 : 0x800d0570 A1 : 0x3ffc7390
A2 : 0x3ffc1c30 A3 : 0x00000000 A4 : 0x0800001c A5 : 0xffffffff
A6 : 0xffffffff A7 : 0x00060d23 A8 : 0x800832e9 A9 : 0x3ffc7380
A10 : 0x00000003 A11 : 0x00060023 A12 : 0x00060020 A13 : 0x00000003
A14 : 0x00000001 A15 : 0x00000000 SAR : 0x0000001f EXCCAUSE: 0x0000001c
EXCVADDR: 0x00000000 LBEG : 0x400014fd LEND : 0x4000150d LCOUNT : 0xffffffff
Backtrace: 0x400dde93:0x3ffc7390 0x400d0570:0x3ffc73b0 0x400d79b0:0x3ffc73d0
CPU halted.
So my question is: What I am doing wrong. What do i miss. What I haven't understood with Arduino IDE, cpp, pointers, etc.
Sorry I forgot: I use Arduino IDE 1.8.2
strcttest *tt; is your problem. You're not allocating memory for and creating an object of type strcttest - you're merely allocating memory for a pointer to an object of that type. Basically, the code should crash everywhere when your code gets to the line tt->a=1; The fact that it doesn't when run on the Nano is basically dumb luck..
Think of the case where you have a char* variable and then try to copy a string to it - it will crash too, since you dont have any storage space for the string itself - you only have a few bytes allocated that store the address of the string.
The following is a more reasonable implementation of your void loop() function:
void loop() {
// put your main code here, to run repeatedly:
//Create structure
strcttest tt;
tt.a=1;
tt.b=2;
//Output result
Serial.println (t.libTest(&tt));
delay(1000);
}
Another (slower, due to use of new and delete) implementation may look like this:
void loop() {
// put your main code here, to run repeatedly:
//Create structure
strcttest *tt = new strcttest;
tt->a=1;
tt->b=2;
//Output result
Serial.println (t.libTest(tt));
delete tt;
delay(1000);
}
For ESP32 and ESP8266, have a excellent tool to help in crashes situations,
like that You report.
This integrates to Arduino IDE
See it in: https://github.com/me-no-dev/EspExceptionDecoder
Related
I am trying to figure out why this error is popping up in the serial monitor. I tried to figure out which area of the code is the problem. I am pretty sure that it is this one, because if I remove it the code runs. There are some more ModeClasses but they are almost the same. The only difference is the run function. But I don't think that this is the problem. Display class and Clock class I tried individually and they worked.
That's the error message:
//error message
Backtrace:0x40086071:0x3ffb27700x400d215d:0x3ffb2780 0x400d1262:0x3ffb27a0 0x400d12ef:0x3ffb27c0 0x400d13fe:0x3ffb2800 0x400d4019:0x3ffb2820
ELF file SHA256: 0000000000000000
Rebooting...
*!��␄Z�*␁����M�␎�Guru Meditation Error: Core 1 panic'ed (StoreProhibited). Exception was unhandled.
Core 1 register dump:
PC : 0x40086074 PS : 0x00060b30 A0 : 0x800d2160 A1 : 0x3ffb2770
A2 : 0x00000000 A3 : 0x00000000 A4 : 0x00000400 A5 : 0x00000000
A6 : 0x00ff0000 A7 : 0x00000040 A8 : 0x800d2dd4 A9 : 0x3ffb2740
A10 : 0x3ffb27d5 A11 : 0x00000000 A12 : 0x0000000a A13 : 0x00000001
A14 : 0x00060320 A15 : 0x00000001 SAR : 0x00000002 EXCCAUSE: 0x0000001d
EXCVADDR: 0x00000000 LBEG : 0x40086074 LEND : 0x4008607f LCOUNT : 0x0000003f
// thats the ModeClock.h file
#ifndef MODE_CLOCK_H
#define MODE_CLOCK_H
#include <Arduino.h>
#include "Mode.h"
#include "Clock.h"
#include "Display.h"
class ModeClock : public Mode
{
private:
Clock clock;
Display display;
public:
ModeClock(Clock c, Display d)
{
clock = c;
display = d;
}
void run() override;
};
#endif
Here is the .cpp file for the .h file
#include "ModeDate.h"
void ModeDate::run()
{
display.displayText(clock.getClockDate());
Serial.print(clock.getClockDate());
}
And here also the class Mode that is getting inherited by.
#define MODE_H
#ifdef MODE_H
class Mode
{
private:
/* data */
public:
void virtual run() = 0;
};
#endif
I read that it could come from trying to access an invalid memory address. That could happen if you use a pointer wrong. But I'm not using any pointer. Please help me I don't know how to get on with it! I'm really thankful for every tip.
VSCode, PlatformIO
ESP8266 nodeMCU v3.0
PIO`s INCBIN lib https://github.com/AlexIII/incbin-arduino?utm_source=platformio&utm_medium=piohome
I load by INCBIN lib one file to ESP8266.
I try to print first datum.
#include "Arduino.h"
#include "incbin.h"
INCBIN(my, "path/to/file.someExtension");
void setup()
{
Serial.begin(9600);
Serial.println();
Serial.println(*gmyData)
}
void loop(){}
monitor out
Exception (3):
epc1=0x40201098 epc2=0x00000000 epc3=0x00000000 excvaddr=0x40238b14 depc=0x00000000
LoadStoreError: Processor internal physical address or data error during load or store
epc1=0x40201098 in setup at ??:?
excvaddr=0x40238b14 in ethernet_input at ??:?
>>>stack>>>
ctx: cont
sp: 3ffffe00 end: 3fffffc0 offset: 0190
3fffff90: 3fffdad0 00000000 3ffee534 40201093
3fffffa0: feefeffe feefeffe 3ffee66c 40201e00
3fffffb0: feefeffe feefeffe 3ffe85d8 40100cc1
<<<stack<<<
0x40201093 in setup at ??:?
0x40201e00 in loop_wrapper() at core_esp8266_main.cpp:?
0x40100cc1 in cont_wrapper at ??:?
This also throws error.
uint8_t datum = *gmyData;
Serial.println(datum);
edit
Tests show that Serial.println() is not guilty. It's all about incbin'd var access.
test, which throws aforementioned exception:
int i;
if (*gmyData > 0)
i = 1;
else
i = 2;
Serial.println(i);
File is a "primary" certificate gtsltsr.crt from point 1.b from https://cloud.google.com/iot/docs/how-tos/mqtt-bridge#using_a_long-term_mqtt_domain
I tried to read first byte in main code sample just to check correctness.
I'm getting this error, when trying to use Wifi + DallasTemperature && OneWire on my esp32. Temperature sensor is Gravity DS18B20.
When I don't use Wifi it works fine.
This is an error code
09:41:17.049 -> Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled.
09:41:17.082 ->
09:41:17.082 -> Core 1 register dump:
09:41:17.082 -> PC : 0x400d3b40 PS : 0x00060433 A0 : 0x800d4488 A1 : 0x3ffb2710
09:41:17.082 -> A2 : 0x3f40af28 A3 : 0x0000001c A4 : 0x0a4c4c55 A5 : 0x3ff49000
09:41:17.082 -> A6 : 0x00000020 A7 : 0x00000000 A8 : 0x800d3b15 A9 : 0x3ffb26d0
09:41:17.082 -> A10 : 0x00060420 A11 : 0x3ffc2cac A12 : 0x3ffc2ca4 A13 : 0xb33fffff
09:41:17.082 -> A14 : 0x00000001 A15 : 0x00000001 SAR : 0x00000020 EXCCAUSE: 0x0000001c
09:41:17.115 -> EXCVADDR: 0x0a4c4c55 LBEG : 0x400df328 LEND : 0x400df332 LCOUNT : 0x00000000
09:41:17.115 ->
09:41:17.115 ->
09:41:17.115 -> Backtrace:0x400d3b3d:0x3ffb27100x400d4485:0x3ffb2750 0x400d476c:0x3ffb2780 0x400d2782:0x3ffb27b0 0x400d53b7:0x3ffb2820
Here I have it decoded
Decoding 5 results
0x400d3b3d: OneWire::reset() at /home/suomi/Arduino/libraries/OneWire/util/OneWire_direct_gpio.h line 165
: (inlined by) OneWire::reset() at /home/suomi/Arduino/libraries/OneWire/OneWire.cpp line 172
0x400d4485: OneWire::search(unsigned char*, bool) at /home/suomi/Arduino/libraries/OneWire/OneWire.cpp line 388
0x400d476c: DallasTemperature::begin() at /home/suomi/Arduino/libraries/DallasTemperature/DallasTemperature.cpp line 113
0x400d2782: setup() at /home/suomi/Arduino/sketch_sep18a/sketch_sep18a.ino line 53
0x400d53b7: loopTask(void*) at /home/suomi/.arduino15/packages/esp32/hardware/esp32/2.0.0/cores/esp32/main.cpp line 38
also with backtracked lines in the files mentioned above
1. ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_io_desc[pin].mux);
2. DIRECT_MODE_INPUT(reg, mask);
3.if (!reset()) {
4.while (_wire->search(deviceAddress)) {
5.sensors.begin();
6.void loopTask(void *pvParameters)
{
setup();
And my executed code
#include <OneWire.h>
#include <DallasTemperature.h>
#include <WiFi.h>
// Wifi Settings
#define WIFI_NETWORK "name"
#define WIFI_PASSWORD "pass"
#define WIFI_TIMOUT_MS 20000
const int oneWireBus = 32;
OneWire oneWire(oneWireBus);
DallasTemperature sensors(&oneWire);
int status;
int connectToWiFi() {
Serial.println(" ");
Serial.print("Connencting to WiFi");
Serial.print(" ");
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_NETWORK, WIFI_PASSWORD);
unsigned long startAttemptTime = millis();
while(WiFi.status() != WL_CONNECTED && millis() - startAttemptTime < WIFI_TIMOUT_MS) {
Serial.print(".");
delay(700);
}
if (WiFi.status() != WL_CONNECTED) {
Serial.println("Failed connect to WiFi!");
return 0;
}
else {
Serial.print("Connected to WiFi");
Serial.println(WIFI_NETWORK);
Serial.println(WiFi.localIP());
return 1;
}
}
void setup() {
status = connectToWiFi();
Serial.begin(115200);
sensors.begin();
void loop() {
}
I'm not very good in c++, could someone please help me? LoadProhibited: It looks like it trying to access a memory that it shouldn't?
It's been a long time since I used Arduino libs on ESP32. Maybe Serial.begin() should be called before connectToWifi() because you call Serial methods before initializing it.
I am using Bluetooth and receiving a CSS gradient string like this:
(90deg, rgba(66, 68, 90, 1) 0%,rgba(72, 79, 164, 1) 100%)
I am using regex to pull out the "90" for the angle:
regex r_dir("([0-9]{2,3}deg)");
smatch m_dir;
regex_search(data, m_dir, r_dir);
string temp = m_dir[0].str();
int dir = atoi(temp.replace(temp.find("deg"), 3, "").c_str());
This works fine and I am able to get "90". I also need to pull out the colours (and their percentage). Unfortunately there is not built in function to return all matches in a string so I used an example I found online:
regex r_col("(rgba\\(([0-9]{1,3}(, |,|)){4}\\) [0-9]{1,3}%)");
sregex_iterator iter(data.begin(), data.end(), r_col);
sregex_iterator end;
while(iter != end)
{
Serial.println("fff");
for(unsigned i = 0; i < iter->size(); ++i)
{
Serial.println( (*iter)[i].str().c_str());
}
//Serial.println((*iter)[0].str().c_str());
++iter;
}
However not only does this not work, but it causes a crash on my ESP:
Guru Meditation Error: Core 0 panic'ed (Unhandled debug exception)
Debug exception reason: Stack canary watchpoint triggered (Btc_task)
Core 0 register dump:
PC : 0x400d38af PS : 0x00060e36 A0 : 0x800d399d A1 : 0x3ffcd5f0
A2 : 0x3ffcf110 A3 : 0x00000001 A4 : 0x3ffe1218 A5 : 0x3ffe53f4
A6 : 0x3ffc5868 A7 : 0x3ffe0e5f A8 : 0x3ffe0e5e A9 : 0x3f401aa4
A10 : 0x3ffcf110 A11 : 0x00000001 A12 : 0x0000007f A13 : 0x3ffe5354
A14 : 0x3ffc5868 A15 : 0x00000000 SAR : 0x00000010 EXCCAUSE: 0x00000001
EXCVADDR: 0x00000000 LBEG : 0x400014fd LEND : 0x4000150d LCOUNT : 0xffffffff
Backtrace: 0x400d38af:0x3ffcd5f0 0x400d399a:0x3ffcd660 0x400d399a:0x3ffcd6d0 0x400d3b6d:0x3ffcd740 0x400d3856:0x3ffcd760 0x400d399a:0x3ffcd7d0 0x400d3b6d:0x3ffcd840 0x400d3856:0x3ffcd860 0x400d399a:0x3ffcd8d0 0x400d399a:0x3ffcd940 0x400d399a:0x3ffcd9b0 0x400d38cd:0x3ffcda20 0x400d38cd:0x3ffcda90 0x400d3ac1:0x3ffcdb00 0x400d3899:0x3ffcdb70 0x400d3ac1:0x3ffcdbe0 0x400d399a:0x3ffcdc50 0x400d3899:0x3ffcdcc0 0x400d38cd:0x3ffcdd30 0x400d38cd:0x3ffcdda0 0x400d399a:0x3ffcde10 0x400d399a:0x3ffcde80 0x400d3a69:0x3ffcdef0 0x400d3a69:0x3ffcdf60 0x400d3899:0x3ffcdfd0 0x400d399a:0x3ffce040 0x400d3b6d:0x3ffce0b0 0x400d3856:0x3ffce0d0 0x400d399a:0x3ffce140 0x400d3b6d:0x3ffce1b0 0x400d3856:0x3ffce1d0 0x400d399a:0x3ffce240 0x400d3899:0x3ffce2b0 0x400d38cd:0x3ffce320 0x400d38cd:0x3ffce390 0x400d399a:0x3ffce400 0x400d399a:0x3ffce470 0x400d3a69:0x3ffce4e0 0x400d3a69:0x3ffce550 0x400d3899:0x3ffce5c0 0x400d3ac1:0x3ffce630 0x400d399a:0x3ffce6a0 0x400d3b6d:0x3ffce710 0x400d3856:0x3ffce730 0x400d399a:0x3ffce7a0 0x400d3899:0x3ffce810 0x400d38cd:0x3ffce880 0x400d38cd:0x3ffce8f0 0x400d399a:0x3ffce960 0x400d399a:0x3ffce9d0 0x400d3a69:0x3ffcea40
Rebooting...
ets Jun 8 2016 00:22:57
rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0018,len:4
load:0x3fff001c,len:1044
load:0x40078000,len:8896
load:0x40080400,len:5828
entry 0x400806ac
This is caused by (*iter)[i] although I don't know why. I found this GitHub issue on it but that's about it.
I've tried Regexp, specifically the example on iterating over a string. The example caused my ESP to crash however this example I found on an SO post causes no crash it just finds no matches:
ms.Target ((char *)data.c_str());
unsigned int count = ms.MatchCount ("(rgba\\(([0-9]{1,3}(, |,|)){4}\\) [0-9]{1,3}%)");
Serial.print ("Found ");
Serial.print (count);
Serial.println (" matches.");
for (int j = 0; j < count; j++)
{
Serial.print ("Capture number: ");
Serial.println (j, DEC);
Serial.print ("Text: '");
Serial.print (ms.GetCapture ((char *)data.c_str(), j));
Serial.println ("'");
}
with the output being:
Found 0 matches.
Does anyone know to match all occurrences on an ESP?
When using prototyping boards there is a through back of limited memory, moreover C is also limited to core dependencies.
I've fire up my NodeMcu board with ESP32 to test your approach.
Just use a simpler way of substring() to take directly the value from your string.
Instead of using regex use the following substring() -once your css doesn't change its key attributes but only values-. Then you can store the result inside variables and make your logic.
#include <iostream> // std::cout
int main ()
{
std::string css ("(90deg, rgba(66, 68, 90, 1) 0%,rgba(72, 79, 164, 1) 100%)");
std::cout << "DEG: " << css.substr(1,2) << '\n';
return 0;
}
Give it a try!
I am using the ESP32 DevKitC-v1 (clone) with FreeRTOS and attempting to write bytes to the serial port.
My code (below) causes the following exception:
Guru Meditation Error: Core 0 panic'ed (LoadProhibited). Exception was unhandled.
Core 0 register dump:
PC : 0x400ea8fe PS : 0x00060730 A0 : 0x800eb825 A1 : 0x3ffdfdf0
A2 : 0x00000001 A3 : 0x00000055 A4 : 0x00000001 A5 : 0x00000000
A6 : 0x00000002 A7 : 0xff000000 A8 : 0x00000000 A9 : 0x60010000
A10 : 0x00000055 A11 : 0x00000001 A12 : 0x3ffdfd54 A13 : 0x3ffd1068
A14 : 0x00000000 A15 : 0x00000000 SAR : 0x00000004 EXCCAUSE: 0x0000001c
EXCVADDR: 0x00000055 LBEG : 0x400014fd LEND : 0x4000150d LCOUNT : 0xffffffff
Backtrace: 0x400ea8fe:0x3ffdfdf0 0x400eb822:0x3ffdfe10 0x400ebf0d:0x3ffdfe50 0x400e1511:0x3ffdfe80
Rebooting...
ets Jun 8 2016 00:22:57
rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0018,len:4
load:0x3fff001c,len:6372
load:0x40078000,len:11276
load:0x40080000,len:6084
entry 0x4008032c
I have been able to find limited information regarding FreeRTOS and UART operations, I apologise in advance however if I have missed something obvious. I have been trying to self resolve the issue for about 3 days now.
My code:
#define ECHO_TEST_TXD (GPIO_NUM_17)
#define ECHO_TEST_RXD (GPIO_NUM_16)
#define ECHO_TEST_RTS (UART_PIN_NO_CHANGE)
#define ECHO_TEST_CTS (UART_PIN_NO_CHANGE)
static void prvSerialRelayMQTTCommand()
{
const TickType_t xFiveSeconds = pdMS_TO_TICKS( 5000UL );
/* Configure parameters of an UART driver,
* communication pins and install the driver */
uart_config_t uart_config = {
.baud_rate = 9600,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE
};
uart_param_config(UART_NUM_2, &uart_config);
uart_set_pin(UART_NUM_2, ECHO_TEST_TXD, ECHO_TEST_RXD, ECHO_TEST_RTS, ECHO_TEST_CTS);
uart_driver_install(UART_NUM_2, BUF_SIZE * 2, 0, 0, NULL, 0);
while (1) {
uart_write_bytes(UART_NUM_2, 0b00000000, 1);
vTaskDelay(xFiveSeconds);
uart_write_bytes(UART_NUM_2, 0b00000001, 1);
vTaskDelay(xFiveSeconds);
uart_write_bytes(UART_NUM_2, 0b00000011, 1);
vTaskDelay(xFiveSeconds);
uart_write_bytes(UART_NUM_2, 0b00000111, 1);
vTaskDelay(xFiveSeconds);
uart_write_bytes(UART_NUM_2, 0b00001111, 1);
vTaskDelay(xFiveSeconds);
}
}
Invalid pointer arguments
The second argument to uart_write_bytes() should be a const char * (see reference). You are passing it an invalid pointer.
Change
uart_write_bytes(UART_NUM_2, 0b00000000, 1);
to
char c = '\0';
uart_write_bytes(UART_NUM_2, &c, 1);
and similarly for the other calls.
However, this isn't necessarily your only problem.
Stack size for FreeRTOS task
A LoadProhibited error occurs when the ESP32 attempts to read or write an invalid memory address. The relevant address is stored in the EXCVADDR register - which in this case we can see is 0x00000055. This means that your calls to uart_write_bytes() (even though invalid) are not the cause of the reset - because you did not pass the address 0x00000055 in any of the calls.
I suspect your problem is that you are not allocating a large enough stack for your FreeRTOS task. If you create a task with a stack size of configMINIMAL_STACK_SIZE, for example, that might not be enough for using the UART. A stack overflow would also result in a LoadProhibited error.
The stack size is the third parameter passed to xTaskCreate(). Try verifying that it is at least 1024, and increase as needed.