Taking large esp_camera images using PSRAM crashes with LoadStoreAlignment exception

chris-rfs
Posts: 1
Joined: Sun Dec 18, 2022 8:36 pm

Taking large esp_camera images using PSRAM crashes with LoadStoreAlignment exception

Postby chris-rfs » Sun Dec 18, 2022 9:18 pm

I am trying to use the `esp_camera` library to take large (i.e. `FRAMESIZE_UXGA`) images from an OV2640 camera on an ESP32S2. Images this large must be stored in PSRAM, i.e. `config.fb_location = CAMERA_FB_IN_PSRAM`.

Upon executing `esp_camera_fb_get()`, a `LoadStoreAlignment` exception apparently triggered within cam_verify_jpeg_eoi occurs. This occurs at any requested resolution.

Firmware / hardware used

Minimal code required to reproduce:

Using Arduino 2.0.3:
  1. #include <Arduino.h>
  2. #include "esp_camera.h"
  3.  
  4. #define PIN_SDA 41
  5. #define PIN_SCL 42
  6.  
  7. #define PIN_CAM_D0      13
  8. #define PIN_CAM_D1      18
  9. #define PIN_CAM_D2      17
  10. #define PIN_CAM_D3      14
  11. #define PIN_CAM_D4      12
  12. #define PIN_CAM_D5      34
  13. #define PIN_CAM_D6      35
  14. #define PIN_CAM_D7      37
  15. #define PIN_CAM_PCLK    33
  16. #define PIN_CAM_MCLK    36
  17. #define PIN_CAM_VSYNC   39
  18. #define PIN_CAM_HSYNC   38
  19. #define PIN_CAM_RST     40
  20.  
  21.  
  22. bool takePicture(void)
  23. {
  24.   camera_config_t config;
  25.   config.ledc_channel = LEDC_CHANNEL_0;
  26.   config.ledc_timer = LEDC_TIMER_0;
  27.   config.pin_d0 = PIN_CAM_D0;
  28.   config.pin_d1 = PIN_CAM_D1;
  29.   config.pin_d2 = PIN_CAM_D2;
  30.   config.pin_d3 = PIN_CAM_D3;
  31.   config.pin_d4 = PIN_CAM_D4;
  32.   config.pin_d5 = PIN_CAM_D5;
  33.   config.pin_d6 = PIN_CAM_D6;
  34.   config.pin_d7 = PIN_CAM_D7;
  35.   config.pin_xclk = PIN_CAM_MCLK;
  36.   config.pin_pclk = PIN_CAM_PCLK;
  37.   config.pin_vsync = PIN_CAM_VSYNC;
  38.   config.pin_href = PIN_CAM_HSYNC;
  39.   config.pin_sscb_sda = PIN_SDA;
  40.   config.pin_sscb_scl = PIN_SCL;
  41.   config.fb_location = CAMERA_FB_IN_DRAM;
  42.   config.pin_pwdn = -1;
  43.   config.pin_reset = PIN_CAM_RST;
  44.   config.xclk_freq_hz = 20000000;
  45.   config.pixel_format = PIXFORMAT_JPEG;
  46.   config.grab_mode = CAMERA_GRAB_LATEST;
  47.  
  48.  
  49.   if (psramFound())
  50.   {
  51.       Serial.println("PSRAM found");
  52.       config.fb_location = CAMERA_FB_IN_PSRAM;
  53.       config.frame_size = FRAMESIZE_VGA;   // Use a normal frame size. If config.fb_location is set to CAMERA_FB_IN_DRAM, this function succeeds.
  54.       config.jpeg_quality = 10;
  55.       config.fb_count = 2;
  56.   }
  57.   else
  58.   {
  59.     Serial.println("PSRAM not found");
  60.     return false;
  61.   }
  62.  
  63.   esp_err_t err = esp_camera_init(&config);
  64.   if (err != ESP_OK)
  65.   {
  66.     Serial.printf("Camera init failed w/ err 0x %d\r\n", err);
  67.     return false;
  68.   }
  69.  
  70.   sensor_t* s;
  71.   s->set_exposure_ctrl(s, true);                  // Want auto-exposure
  72.   s->set_aec2(s, true);                           // Auto-exposure DSP mode on
  73.   s->set_aec_value(s, 300);                       // Set expose time ceiling [uS]
  74.   s->set_ae_level(s, 0);                          // Auto expose level = 0 (-2 to 2). Dictates the exposure algorithm.
  75.   s->set_brightness(s, 0);                        // Brightness 0 (-2 to 2)
  76.   s->set_gain_ctrl(s, true);                      // Want auto-gain
  77.   s->set_agc_gain(s, 30);                         // Set to maximum gain ceiling (0 to 30)
  78.  
  79.   camera_fb_t* photo = esp_camera_fb_get();
  80.   Serial.printf("Photo taken, has addr. %d\r\n", photo);
  81.   if (photo == NULL) {
  82.     Serial.println("Null ptr as camera framebuffer");
  83.     return false;
  84.   }
  85.    
  86.   err = esp_camera_deinit();
  87.   if (err != ESP_OK)
  88.   {
  89.     Serial.printf("Camera deinit failed w/ err 0x%x\r\n", err);
  90.     return false;
  91.   }
  92.   esp_camera_fb_return(photo);
  93.  
  94.   return true;
  95. }
  96.  
  97. void setup(void)
  98. {
  99.   bool success;
  100.   Serial.begin(115200);
  101.   success = psramInit();
  102.   if (!success) {
  103.     Serial.println("Error initing PSRAM");
  104.   }
  105.  
  106.   takePicture();
  107. }
  108.  
  109. void loop(void)
  110. {
  111.  
  112. }
Crash report
When run on our hardware this causes the ESP32 to crash:
  1. ...
  2. PSRAM found
  3. Guru Meditation Error: Core 0 panic'ed (LoadStoreAlignment)
  4. ...
Decoding the exception gives this stacktrace:
  1. /Users/ficeto/Desktop/ESP32/ESP32S2/esp32-arduino-lib-builder/components/esp32-camera/driver/cam_hal.c:70:::0x40095555:cam_verify_jpeg_eoi
  2.     (inlined by) cam_take at /Users/ficeto/Desktop/ESP32/ESP32S2/esp32-arduino-lib-builder/components/esp32-camera/driver/cam_hal.c:480
  3. /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/freertos/port/xtensa/xtensa_vectors.S:633:::0x40028390:_xt_user_exc
  4. /Users/ficeto/Desktop/ESP32/ESP32S2/esp32-arduino-lib-builder/components/esp32-camera/driver/cam_hal.c:68:::0x40095552:cam_verify_jpeg_eoi
  5.     (inlined by) cam_take at /Users/ficeto/Desktop/ESP32/ESP32S2/esp32-arduino-lib-builder/components/esp32-camera/driver/cam_hal.c:480
  6. /Users/ficeto/Desktop/ESP32/ESP32S2/esp32-arduino-lib-builder/components/esp32-camera/driver/esp_camera.c:360:::0x40094c77:esp_camera_fb_get
  7. C:\Users\Chris\Project\PSRAMCameraTest.ino:98 (discriminator 2):::0x400820a4:takeDummyPicture(int)
  8. C:\Users\Chris\Project\PSRAMCameraTest.ino(168): error 0x40082224:takePictureUnsafe(bool)
  9. C:\Users\Chris\Project\PSRAMCameraTest.ino(284): error 0x40082580:setup()
  10. C:\Users\Chris\AppData\Local\arduino15\packages\esp32\hardware\esp32\2.0.5\cores\esp32/main.cpp(42): error 0x40087f16:loopTask(void*)
  11. /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/esp_system/esp_system.c:44 (discriminator 1):::0x40026de9:esp_restart_noos_dig
Further details, inlcuding hardware setup and things I've tried so far, are located here. The PSRAM can be tested and shown to work by making a buffer with `ps_malloc`, writing to it and reading it back prior to taking an image.

FRANCISCO2020
Posts: 21
Joined: Mon Sep 20, 2021 9:13 am

Re: Taking large esp_camera images using PSRAM crashes with LoadStoreAlignment exception

Postby FRANCISCO2020 » Tue Jan 03, 2023 11:09 am

To fix this, you must first make sure you have PSRAM enabled in your project. To do this, you must add the following line of code to the sdkconfig.h file:


#define CONFIG_SPIRAM_SUPPORT 1

Also, you should verify that you are using the latest version of the esp_camera library, as this may fix any compatibility issues with the ESP32S2. You can also try to disable the load/store alignment mode by adding the following line of code to your main file (before the setup function):

portDISABLE_LOAD_STORE_ALIGNMENT_FAULT();

If none of this works, you may need to further investigate the issue to determine the exact cause. You can try enabling debugging and review the exception logs for more information.

You can also try to check if there is a problem with the camera or the ESP32S2, and make sure you are using the correct settings in the esp_camera library.

Who is online

Users browsing this forum: No registered users and 83 guests