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!
CAN frame corruption following FATFS write to FLASH
CAN frame corruption following FATFS write to FLASH
& I also believe that IDF CAN should be fixed.
Re: CAN frame corruption following FATFS write to FLASH
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
Re: CAN frame corruption following FATFS write to FLASH
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):
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?
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);
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.
Re: CAN frame corruption following FATFS write to FLASH
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.
Re: CAN frame corruption following FATFS write to FLASH
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 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 131 guests