CAN frame corruption following FATFS write to FLASH

PeterR
Posts: 621
Joined: Mon Jun 04, 2018 2:47 pm

CAN frame corruption following FATFS write to FLASH

Postby PeterR » Mon Dec 09, 2019 12:55 pm

I have a CAN based application which allows configuration parameters to be set from a web page.
I use a small FATFS partition to hold configuration parameters. The end user may configure using a web application.
The web page triggers a save (POST) and the new parameters are written to flash using fopen(), fprintf(). Configuration values are saved from a std::thread woken using a std::mutex.

On clicking the web application 'Save' button I have noticed corruptions within CAN frames received. The corruption always seems to be in data[7] and has the value 0x88. I print the received frames immediately following can_receive(). I only use/decode the frame if can_receive() returns 0.
I am wondering power (& will probe) but it does seem strange that the corruption is always data[7] and always 0x88.

I monitor stack sizes and have 500 bytes left using the high water mark.
I am using ESP-IDF v4.0-dev-562-g2b301f53e

I undestand that there are various limitations in writting to FLASH. My configuration 'saver' is not IRAM, I assume that the FATFS routines are.
Any thoughts welcome!
& I also believe that IDF CAN should be fixed.

ESP_Dazz
Posts: 308
Joined: Fri Jun 02, 2017 6:50 am

Re: CAN frame corruption following FATFS write to FLASH

Postby ESP_Dazz » Tue Dec 10, 2019 4:52 am

Some things that would be useful to check/known:
  • What CAN frames were being sent to the ESP32? What data did they have? Were they STD or EXTD ID?
  • Could you check the flags of each received message?
  • Currently, the driver doesn't handle RX FIFO overruns. The following modification to can_intr_handler_rx() should make it assert on a FIFO overrun

Code: Select all

static void can_intr_handler_rx(BaseType_t *task_woken, int *alert_req)
{
    can_rx_msg_cnt_reg_t msg_count_reg;
    msg_count_reg.val = can_get_rx_message_counter();

    for (int i = 0; i < msg_count_reg.rx_message_counter; i++) {
        //Check for RX FIFO overrun
        assert(!CAN.status_reg.data_overrun);
        can_frame_t frame;
        can_get_rx_buffer_and_clear(&frame);
        //Copy frame into RX Queue
        if (xQueueSendFromISR(p_can_obj->rx_queue, &frame, task_woken) == pdTRUE) {
            p_can_obj->rx_msg_count++;
        } else {
            p_can_obj->rx_missed_count++;
            can_alert_handler(CAN_ALERT_RX_QUEUE_FULL, alert_req);
        }
    }
}
  • Calling can_get_status_info() and printing the status info after receiving each message would also be helpful

PeterR
Posts: 621
Joined: Mon Jun 04, 2018 2:47 pm

Re: CAN frame corruption following FATFS write to FLASH

Postby PeterR » Tue Dec 10, 2019 11:11 am

Cool, thanks.

Frame is EXT ID.
Hooking can_get_status_info() to a URI & Ajax request then with a frame rx rate of approximately 90fps I get an increment of 9
status.rx_missed_count every time I click save (cause FLASH write). So my CAN Reader is being blocked. I can increase my buffer sizes.

The following modification discards corrupt frames (dropped rather than reboot as we expect the condition):

Code: Select all

        
   for (int i = 0; i < msg_count_reg.rx_message_counter; i++) {
        can_frame_t frame;
        if(CAN.status_reg.data_overrun) {
            can_get_rx_buffer_and_clear(&frame);
            can_set_command(CMD_CLR_DATA_OVRN);
        }
        else {
            //Copy frame into RX Queue
            can_get_rx_buffer_and_clear(&frame);
Couple of questions:
Q1) I thought that pthreads were equal priority & round robin (FLASH saver & CAN Reader are both pthreads). Why does my CAN reader stall or put another way how to I get my FLASHER to run in the background as intended? I would like to know how to stop other stuff being trampled.

Q2) I copied /driver to project and made local modifications. How do I just get a local build of can.c?
& I also believe that IDF CAN should be fixed.

WiFive
Posts: 3529
Joined: Tue Dec 01, 2015 7:35 am

Re: CAN frame corruption following FATFS write to FLASH

Postby WiFive » Tue Dec 10, 2019 12:07 pm

The only things that run during flash write are IRAM interrupts. So the buffer will have to be big enough to hold all the data received during the flash write. Maybe you want to make sure the can interrupt is on a different core from the flash write. Using can hw filters could help. Or custom can isr to do some basic processing. If you have frequent writes maybe you should use SD card or second flash chip.

PeterR
Posts: 621
Joined: Mon Jun 04, 2018 2:47 pm

Re: CAN frame corruption following FATFS write to FLASH

Postby PeterR » Tue Dec 10, 2019 1:57 pm

Thanks. IDNK.

I will update my writer to write a blob rather each value one by one, that should improve a little.

Is there a way to avoid copying the entire /driver folder to local components?
& I also believe that IDF CAN should be fixed.

Who is online

Users browsing this forum: No registered users and 109 guests