CANBus alarm monitoring after bus recovery

ICONDev
Posts: 9
Joined: Mon Oct 22, 2018 2:12 pm

CANBus alarm monitoring after bus recovery

Postby ICONDev » Mon May 31, 2021 9:21 am

we are using the can interface, idf 3.3.5 release version.

We have a seperate recovery task to get CAN alerts ant to recover from BUS_OFF. Basically we followed the recovery example, contained in the idf.

we are get the alerts properly (eg if we shorten the bus for a short moment), also the bus recovers propperly from bus of by calling the function can_initiate_recovery().

Our problem is that the event "CAN_ALERT_BUS_ERROR" is only working until the first occurence of a bus recovery. After the first recovery, the system does not report alerts like CAN_ALERT_BUS_ERROR anymore.

Reading the counters by using can_get_status_info() sows the same: info.bus_error_count counts up in case of a bus error, but after a bus-recover the counter of bus_error_count stays at its last value before the recovery happened.

A reconfiguring of the needed alerts after a bus recovery does not help.

What is wrong? Why stays the bus error counter at its position when a bus off occures and the bus recovers (and stays there till a complete restart?)

thanks for your help.




Juergen





Code snippet:

void can_recovery_task(void *arg)
{
ESP_LOGI(tag, "Starting CAN recovery task");

while(1)
{
uint32_t alerts=0;
can_read_alerts(&alerts, portMAX_DELAY);
ESP_LOGI(tag, "---Alert Read: -- : %04x", alerts);

if (alerts & CAN_ALERT_ABOVE_ERR_WARN)
{
ESP_LOGI(tag, "Surpassed Error Warning Limit");
}

if (alerts & CAN_ALERT_ERR_PASS)
{
ESP_LOGI(tag, "Entered Error Passive state");
}

if (alerts & CAN_ALERT_ERR_ACTIVE)
{
ESP_LOGI(tag, "Entered Can Error Active");
}

if (alerts & CAN_ALERT_BUS_ERROR)
{
ESP_LOGI(tag, "Entered Alert Bus Error");
}

if (alerts & CAN_ALERT_BUS_OFF)
{
ESP_LOGE(tag, "Bus Off --> Initiate bus recovery");
can_initiate_recovery(); //Needs 128 occurrences of bus free signal
vTaskDelay(pdMS_TO_TICKS(1000));
}

if (alerts & CAN_ALERT_BUS_RECOVERED)
{
//Bus recovery was successful

// only for testing. Does not help !!
esp_err_t res = can_reconfigure_alerts(ALERTS_ENABLED, NULL);
ESP_LOGI(tag, "Bus Recovered %d--> restarting Can", res);

//put can in start state again and re-enable alert monitoring
can_start();
}
}
}

ICONDev
Posts: 9
Joined: Mon Oct 22, 2018 2:12 pm

Re: CANBus alarm monitoring after bus recovery

Postby ICONDev » Mon May 31, 2021 12:29 pm

Additionally:

if I recover the situation by completely reinstalling the driver (can_driver_uninstall() / can_driver_install()) instead of using can_initiate_recovery(), the code works propperly and the bus error counters are working as before the recovery..

This is why I assume that this is a bug in the idf can driver. (or maybe I miss something..)

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

Re: CANBus alarm monitoring after bus recovery

Postby ESP_Dazz » Tue Jun 01, 2021 5:22 pm

@ICONDev Could it be related to the Bus Off REC errata?

A workaround for that errata has been added v4.3 and later.

Since you are on v3.3.5, could you try modifying the can_intr_handler_err_warn() in components/driver/can.c as follows and see if the issue is resolved:
  1. static CAN_ISR_ATTR void can_intr_handler_err_warn(can_status_reg_t *status, BaseType_t *task_woken, int *alert_req)
  2. {
  3.     if (status->bus) {
  4.         if (status->error) {
  5.             //Bus-Off condition. TEC should set and held at 127, REC should be 0, reset mode entered
  6.             CAN_SET_FLAG(p_can_obj->control_flags, CTRL_FLAG_BUS_OFF);
  7.             /* Note: REC is still allowed to increase during bus-off. REC > err_warn
  8.                can prevent "bus recovery complete" interrupt from occurring. Set to
  9.                listen only mode to freeze REC. */
  10.             can_config_mode(CAN_MODE_LISTEN_ONLY);
  11.             //Re-trigger the Bus Off interrupt to clear the REC
  12.             CAN.tx_error_counter_reg.byte = 0;
  13.             CAN.tx_error_counter_reg.byte = 255;
  14.             //Clear the re-triggered interrupt
  15.             (void) can_get_interrupt_reason();
  16.             can_alert_handler(CAN_ALERT_BUS_OFF, alert_req);
  17.         } else {
  18.             //Bus-recovery in progress. TEC has dropped below error warning limit
  19.             can_alert_handler(CAN_ALERT_RECOVERY_IN_PROGRESS, alert_req);
  20.         }
  21. ...

ICONDev
Posts: 9
Joined: Mon Oct 22, 2018 2:12 pm

Re: CANBus alarm monitoring after bus recovery

Postby ICONDev » Wed Jun 02, 2021 12:52 pm

Thank you for the quick response, seems that this is the issue. I saw that there are further work arounds implemented in the current idf versions in terms of CAN.

Does Espressif intent to update the V3.x release idf with these CAN/TWAI component options (as done in the latest V3 release with the ISR IRAM option) ? Would appreciate it and would like that more than patching the component or using the current idf (which e.g means a lot of additional adaptions and testings of our complete system, also stuff like renaming can to twai and so on..).
Thank you

Juergen

Who is online

Users browsing this forum: Google [Bot] and 72 guests