Page 1 of 1

ESP32 IllegalInstruction

Posted: Mon Feb 07, 2022 1:26 pm
by Gianthard
I'm building a program that reads data from a RFID receiver through UART2 on ESP32 chip.
However there's a strange phenomenon.
Guru Meditation Error: Core 1 panic'ed (IllegalInstruction). Exception was unhandled.
Core 1 register dump:
PC : 0x6b726f77 PS : 0x00060330 A0 : 0x800d0c89 A1 : 0x3ffb1f50
A2 : 0x3ffc0074 A3 : 0x3ffc0065 A4 : 0x80086330 A5 : 0x3ffb1e70
A6 : 0x00000000 A7 : 0x3ffb0060 A8 : 0x800d0dd3 A9 : 0x3ffb1f30
A10 : 0x3ffc0074 A11 : 0x00000000 A12 : 0x80086330 A13 : 0x3ffb1e50
A14 : 0x00000000 A15 : 0x3ffb0060 SAR : 0x00000018 EXCCAUSE: 0x00000000
EXCVADDR: 0x00000000 LBEG : 0x4000c28c LEND : 0x4000c296 LCOUNT : 0x00000000

ELF file SHA256: 0000000000000000

Backtrace: 0x6b726f77:0x3ffb1f50 0x400d0c86:0x3ffb1f70 0x400d0d5e:0x3ffb1f90 0x400d1fb9:0x3ffb1fb0 0x40086125:0x3ffb1fd0

Rebooting...
␙ 0�␄D)!1�9␌��)��!��Serial begins successfully.
Here PC is a pointer to an address out of the range.

main.cpp
  1. #include <Arduino.h>
  2. #include "lib/RFID_Reader.h"
  3. #include "lib/Utils.h"
  4.  
  5. RFID_Reader RF_Reader;
  6.  
  7. void RFID_Callback(RFID_Pkg *pkg)
  8. {
  9. }
  10.  
  11. void setup()
  12. {
  13.   Serial.begin(9600);
  14.   Serial.println("Serial begins successfully.");
  15.   RF_Reader.Init(RFID_Callback);
  16. }
  17.  
  18. void loop()
  19. {
  20.   RF_Reader.RFID_Read_Loop();
  21. }
RFID_Reader.cpp
  1. #include "RFID_Reader.h"
  2. #include <Arduino.h>
  3.  
  4. RFID_Reader::RFID_Reader()
  5. {
  6. }
  7.  
  8. RFID_Reader::~RFID_Reader()
  9. {
  10. }
  11.  
  12. void RFID_Reader::Init(void (*pCallbackFunc)(RFID_Pkg *))
  13. {
  14.     Reset();
  15.     pCallback = pCallbackFunc;
  16.     Serial2.begin(9600);
  17. }
  18.  
  19. void RFID_Reader::RFID_Read_Loop()
  20. {
  21.     char c = Serial2.read();
  22.     if (m_State != STATE_WAITING_CMD_CAT || c != 0xff)
  23.     {
  24.         // Serial.print(" ");
  25.     }
  26.     switch (m_State)
  27.     {
  28.     case STATE_WAITING_CMD_CAT:
  29.         if (c != 0xff)
  30.         {
  31.             m_Pkg.m_Cmd_Cat[0] = c;
  32.             m_State = STATE_WAITING_PKG_LEN;
  33.         }
  34.         // Serial.println("STATE_WAITING_CMD_CAT");
  35.         break;
  36.  
  37.     case STATE_WAITING_PKG_LEN:
  38.  
  39.         if (c != 0xff)
  40.         {
  41.  
  42.             m_Pkg.m_Pkg_Len = c;
  43.             m_Remain_Count = m_Pkg.m_Pkg_Len - 2;
  44.             m_State = STATE_WAITING_CMD;
  45.             // Serial.println("STATE_WAITING_CMD_CAT");
  46.         }
  47.         break;
  48.  
  49.     case STATE_WAITING_CMD:
  50.         m_Pkg.m_Cmd[0] = c;
  51.         m_Remain_Count--;
  52.         m_State = STATE_WAITING_ADDRESS;
  53.         // Serial.println("STATE_WAITING_CMD");
  54.         break;
  55.  
  56.     case STATE_WAITING_ADDRESS:
  57.         m_Pkg.m_Address[0] = c;
  58.         m_Remain_Count--;
  59.         m_State = STATE_WAITING_CMD_STATE;
  60.         // Serial.println("STATE_WAITING_ADDRESS");
  61.         break;
  62.  
  63.     case STATE_WAITING_CMD_STATE:
  64.         m_Pkg.m_Cmd_State[0] = c;
  65.         m_Remain_Count--;
  66.         m_State = STATE_WAITING_DATA;
  67.         // Serial.println("STATE_WAITING_CMD_STATE");
  68.         break;
  69.  
  70.     case STATE_WAITING_DATA:
  71.         if (m_Remain_Count > 1)
  72.         {
  73.             m_Pkg.m_Data[m_Pkg.m_Data_Count] = c;
  74.             m_Remain_Count--;
  75.             m_Pkg.m_Data_Count++;
  76.             m_State = STATE_WAITING_DATA;
  77.         }
  78.         else
  79.         {
  80.             m_State = STATE_WAITING_VARY;
  81.         }
  82.         // Serial.println("STATE_WAITING_DATA");
  83.         break;
  84.  
  85.     case STATE_WAITING_VARY:
  86.         m_Pkg.m_Vary[0] = c;
  87.         Finish();
  88.         // Serial.println("STATE_WAITING_VARY");
  89.         break;
  90.  
  91.     default:
  92.         break;
  93.     }
  94. }
  95.  
  96. void RFID_Reader::Finish()
  97. {
  98.     pCallback(&m_Pkg);
  99.     Reset();
  100. }
  101.  
  102. void RFID_Reader::Reset()
  103. {
  104.     m_State = STATE_WAITING_CMD_CAT;
  105.     m_Remain_Count = 0;
  106.     m_Pkg.m_Pkg_Len = 0;
  107.     m_Pkg.m_Data_Count = 0;
  108. }
RFID_Reader.h
  1. #ifndef RFID_READER_LIB
  2. #define RFID_READER_LIB
  3. struct RFID_Pkg
  4. {
  5.     unsigned char m_Cmd_Cat[1];
  6.     unsigned int m_Pkg_Len;
  7.     unsigned char m_Cmd[1];
  8.     unsigned char m_Address[1];
  9.     unsigned char m_Cmd_State[1];
  10.     unsigned char m_Data[512];
  11.     unsigned char m_Vary[1];
  12.     unsigned int m_Data_Count;
  13. };
  14. class RFID_Reader
  15. {
  16. private:
  17.     enum RFID_Reader_State
  18.     {
  19.         STATE_WAITING_CMD_CAT,
  20.         STATE_WAITING_PKG_LEN,
  21.         STATE_WAITING_CMD,
  22.         STATE_WAITING_ADDRESS,
  23.         STATE_WAITING_CMD_STATE,
  24.         STATE_WAITING_DATA,
  25.         STATE_WAITING_VARY,
  26.     } m_State;
  27.  
  28.     RFID_Pkg m_Pkg;
  29.  
  30.     unsigned int m_Remain_Count;
  31.  
  32. public:
  33.     RFID_Reader();
  34.     ~RFID_Reader();
  35.  
  36.     void (*pCallback)(RFID_Pkg *);
  37.  
  38.     void Init(void (*pCallbackFunc)(RFID_Pkg *));
  39.     void RFID_Read_Loop();
  40.     void Reset();
  41.     void Finish();
  42. };
  43. #endif
Utils.h
  1. #include <Arduino.h>
  2.  
  3. #ifndef UTILS_LIB
  4. #define UTILS_LIB
  5. void ConvertNumber(unsigned long n, uint8_t base, char *s)
  6. {
  7.     char buf[8 * sizeof(n) + 1]; // Assumes 8-bit chars plus zero byte.
  8.     char *str = &buf[sizeof(buf) - 1];
  9.  
  10.     *str = '\0';
  11.  
  12.     // prevent crash if called with base == 1
  13.     if (base < 2)
  14.     {
  15.         base = 10;
  16.     }
  17.  
  18.     do
  19.     {
  20.         char c = n % base;
  21.         n /= base;
  22.  
  23.         *--str = c < 10 ? c + '0' : c + 'A' - 10;
  24.     } while (n);
  25.     strcpy(s, str);
  26. }
  27. #endif
What's more strange, if I uncomment any Serial.print() in function RFID_Read_Loop(), It can work perfect without any crash.
Print any string in the fuction can solve this.
I dont know how do this happen. Why print a string to Serial can have impact on the crash?

Re: ESP32 IllegalInstruction

Posted: Mon Feb 07, 2022 3:09 pm
by ESP_Sprite
That PC address, 0x6b726f77, looks like ASCII... 'work' if I decode it. That smells like you're trying to put too much data into one of the class members, overwriting your return address with ascii data.

Re: ESP32 IllegalInstruction

Posted: Mon Feb 07, 2022 3:43 pm
by Gianthard
ESP_Sprite wrote: That PC address, 0x6b726f77, looks like ASCII... 'work' if I decode it. That smells like you're trying to put too much data into one of the class members, overwriting your return address with ascii data.
ESP_Sprite wrote:
Mon Feb 07, 2022 3:09 pm
That PC address, 0x6b726f77, looks like ASCII... 'work' if I decode it. That smells like you're trying to put too much data into one of the class members, overwriting your return address with ascii data.
Hi,ESP_Sprite,
but how does it happen? I have nothing like ''work'' in code. And why it can be solved by printing strings?
Is there any perfect solutions?

Re: ESP32 IllegalInstruction

Posted: Tue Feb 08, 2022 1:08 am
by ESP_Sprite
One step at a time. First of all, you want to solve the symptom so you can debug further. The symptom of an illegal instruction is likely caused by m_Remain_Count being larger than the amount of bytes you have storage for; best limit this so it can never become too large, regardless of what you read from the serial port. (This is best practice anyway: always treat incoming data as potentially-corrupt and make sure that you won't do anything unexpected, like crash, on receiving bad data.) Then figure out the root cause, as in: why the read data is bad; potentially you're reading startup chatter from the RFID module or something?