Merge branch 'bugfix/can_driver_assertions_v3.2' into 'release/v3.2'

drivers/can: fix skipped function calls when assertions disabled (backport v3.2)

See merge request espressif/esp-idf!6407
This commit is contained in:
Ivan Grokhotkov 2019-10-30 03:53:45 +08:00
commit 077bd351e4
4 changed files with 35 additions and 20 deletions

View file

@ -376,7 +376,8 @@ static void can_intr_handler_err_warn(can_status_reg_t *status, BaseType_t *task
can_alert_handler(CAN_ALERT_ABOVE_ERR_WARN, alert_req); can_alert_handler(CAN_ALERT_ABOVE_ERR_WARN, alert_req);
} else if (p_can_obj->control_flags & CTRL_FLAG_RECOVERING) { } else if (p_can_obj->control_flags & CTRL_FLAG_RECOVERING) {
//Bus recovery complete. //Bus recovery complete.
can_enter_reset_mode(); esp_err_t err = can_enter_reset_mode();
assert(err == ESP_OK);
//Reset and set flags to the equivalent of the stopped state //Reset and set flags to the equivalent of the stopped state
CAN_RESET_FLAG(p_can_obj->control_flags, CTRL_FLAG_RECOVERING | CTRL_FLAG_ERR_WARN | CAN_RESET_FLAG(p_can_obj->control_flags, CTRL_FLAG_RECOVERING | CTRL_FLAG_ERR_WARN |
CTRL_FLAG_ERR_PASSIVE | CTRL_FLAG_BUS_OFF | CTRL_FLAG_ERR_PASSIVE | CTRL_FLAG_BUS_OFF |
@ -452,13 +453,17 @@ static void can_intr_handler_tx(can_status_reg_t *status, int *alert_req)
//Update TX message count //Update TX message count
p_can_obj->tx_msg_count--; p_can_obj->tx_msg_count--;
configASSERT(p_can_obj->tx_msg_count >= 0); //Sanity check assert(p_can_obj->tx_msg_count >= 0); //Sanity check
//Check if there are more frames to transmit //Check if there are more frames to transmit
if (p_can_obj->tx_msg_count > 0 && p_can_obj->tx_queue != NULL) { if (p_can_obj->tx_msg_count > 0 && p_can_obj->tx_queue != NULL) {
can_frame_t frame; can_frame_t frame;
configASSERT(xQueueReceiveFromISR(p_can_obj->tx_queue, &frame, NULL) == pdTRUE); int res = xQueueReceiveFromISR(p_can_obj->tx_queue, &frame, NULL);
can_set_tx_buffer_and_transmit(&frame); if (res == pdTRUE) {
can_set_tx_buffer_and_transmit(&frame);
} else {
assert(false && "failed to get a frame from TX queue");
}
} else { } else {
//No more frames to transmit //No more frames to transmit
CAN_RESET_FLAG(p_can_obj->control_flags, CTRL_FLAG_TX_BUFF_OCCUPIED); CAN_RESET_FLAG(p_can_obj->control_flags, CTRL_FLAG_TX_BUFF_OCCUPIED);
@ -674,7 +679,8 @@ esp_err_t can_driver_install(const can_general_config_t *g_config, const can_tim
} }
periph_module_reset(PERIPH_CAN_MODULE); periph_module_reset(PERIPH_CAN_MODULE);
periph_module_enable(PERIPH_CAN_MODULE); //Enable APB CLK to CAN peripheral periph_module_enable(PERIPH_CAN_MODULE); //Enable APB CLK to CAN peripheral
configASSERT(can_enter_reset_mode() == ESP_OK); //Must enter reset mode to write to config registers esp_err_t err = can_enter_reset_mode(); //Must enter reset mode to write to config registers
assert(err == ESP_OK);
can_config_pelican(); //Use PeliCAN addresses can_config_pelican(); //Use PeliCAN addresses
/* Note: REC is allowed to increase even in reset mode. Listen only mode /* Note: REC is allowed to increase even in reset mode. Listen only mode
will freeze REC. The desired mode will be set when can_start() is called. */ will freeze REC. The desired mode will be set when can_start() is called. */
@ -729,7 +735,8 @@ esp_err_t can_driver_uninstall()
//Check state //Check state
CAN_CHECK_FROM_CRIT(p_can_obj != NULL, ESP_ERR_INVALID_STATE); CAN_CHECK_FROM_CRIT(p_can_obj != NULL, ESP_ERR_INVALID_STATE);
CAN_CHECK_FROM_CRIT(p_can_obj->control_flags & (CTRL_FLAG_STOPPED | CTRL_FLAG_BUS_OFF), ESP_ERR_INVALID_STATE); CAN_CHECK_FROM_CRIT(p_can_obj->control_flags & (CTRL_FLAG_STOPPED | CTRL_FLAG_BUS_OFF), ESP_ERR_INVALID_STATE);
configASSERT(can_enter_reset_mode() == ESP_OK); //Enter reset mode to stop any CAN bus activity esp_err_t err = can_enter_reset_mode(); //Enter reset mode to stop any CAN bus activity
assert(err == ESP_OK);
//Clear registers by reading //Clear registers by reading
(void) can_get_interrupt_reason(); (void) can_get_interrupt_reason();
(void) can_get_arbitration_lost_capture(); (void) can_get_arbitration_lost_capture();
@ -767,7 +774,8 @@ esp_err_t can_start()
//Reset RX queue, and RX message count //Reset RX queue, and RX message count
xQueueReset(p_can_obj->rx_queue); xQueueReset(p_can_obj->rx_queue);
p_can_obj->rx_msg_count = 0; p_can_obj->rx_msg_count = 0;
configASSERT(can_enter_reset_mode() == ESP_OK); //Should already be in bus-off mode, set again to make sure esp_err_t err = can_enter_reset_mode(); //Should already be in bus-off mode, set again to make sure
assert(err == ESP_OK);
//Currently in listen only mode, need to set to mode specified by configuration //Currently in listen only mode, need to set to mode specified by configuration
can_mode_t mode; can_mode_t mode;
@ -780,7 +788,8 @@ esp_err_t can_start()
} }
can_config_mode(mode); //Set mode can_config_mode(mode); //Set mode
(void) can_get_interrupt_reason(); //Clear interrupt register (void) can_get_interrupt_reason(); //Clear interrupt register
configASSERT(can_exit_reset_mode() == ESP_OK); err = can_exit_reset_mode();
assert(err == ESP_OK);
CAN_RESET_FLAG(p_can_obj->control_flags, CTRL_FLAG_STOPPED); CAN_RESET_FLAG(p_can_obj->control_flags, CTRL_FLAG_STOPPED);
CAN_EXIT_CRITICAL(); CAN_EXIT_CRITICAL();
@ -795,7 +804,8 @@ esp_err_t can_stop()
CAN_CHECK_FROM_CRIT(!(p_can_obj->control_flags & (CTRL_FLAG_STOPPED | CTRL_FLAG_BUS_OFF)), ESP_ERR_INVALID_STATE); CAN_CHECK_FROM_CRIT(!(p_can_obj->control_flags & (CTRL_FLAG_STOPPED | CTRL_FLAG_BUS_OFF)), ESP_ERR_INVALID_STATE);
//Clear interrupts and reset flags //Clear interrupts and reset flags
configASSERT(can_enter_reset_mode() == ESP_OK); esp_err_t err = can_enter_reset_mode();
assert(err == ESP_OK);
(void) can_get_interrupt_reason(); //Read interrupt register to clear interrupts (void) can_get_interrupt_reason(); //Read interrupt register to clear interrupts
can_config_mode(CAN_MODE_LISTEN_ONLY); //Set to listen only mode to freeze REC can_config_mode(CAN_MODE_LISTEN_ONLY); //Set to listen only mode to freeze REC
CAN_RESET_FLAG(p_can_obj->control_flags, CTRL_FLAG_TX_BUFF_OCCUPIED); CAN_RESET_FLAG(p_can_obj->control_flags, CTRL_FLAG_TX_BUFF_OCCUPIED);
@ -846,11 +856,13 @@ esp_err_t can_transmit(const can_message_t *message, TickType_t ticks_to_wait)
CAN_ENTER_CRITICAL(); CAN_ENTER_CRITICAL();
if (p_can_obj->control_flags & (CTRL_FLAG_STOPPED | CTRL_FLAG_BUS_OFF)) { if (p_can_obj->control_flags & (CTRL_FLAG_STOPPED | CTRL_FLAG_BUS_OFF)) {
//TX queue was reset (due to stop/bus_off), remove copied frame from queue to prevent transmission //TX queue was reset (due to stop/bus_off), remove copied frame from queue to prevent transmission
configASSERT(xQueueReceive(p_can_obj->tx_queue, &tx_frame, 0) == pdTRUE); int res = xQueueReceive(p_can_obj->tx_queue, &tx_frame, 0);
assert(res == pdTRUE);
ret = ESP_ERR_INVALID_STATE; ret = ESP_ERR_INVALID_STATE;
} else if ((p_can_obj->tx_msg_count == 0) && !(p_can_obj->control_flags & CTRL_FLAG_TX_BUFF_OCCUPIED)) { } else if ((p_can_obj->tx_msg_count == 0) && !(p_can_obj->control_flags & CTRL_FLAG_TX_BUFF_OCCUPIED)) {
//TX buffer was freed during copy, manually trigger transmission //TX buffer was freed during copy, manually trigger transmission
configASSERT(xQueueReceive(p_can_obj->tx_queue, &tx_frame, 0) == pdTRUE); int res = xQueueReceive(p_can_obj->tx_queue, &tx_frame, 0);
assert(res == pdTRUE);
can_set_tx_buffer_and_transmit(&tx_frame); can_set_tx_buffer_and_transmit(&tx_frame);
p_can_obj->tx_msg_count++; p_can_obj->tx_msg_count++;
CAN_SET_FLAG(p_can_obj->control_flags, CTRL_FLAG_TX_BUFF_OCCUPIED); CAN_SET_FLAG(p_can_obj->control_flags, CTRL_FLAG_TX_BUFF_OCCUPIED);
@ -941,7 +953,8 @@ esp_err_t can_initiate_recovery()
CAN_SET_FLAG(p_can_obj->control_flags, CTRL_FLAG_RECOVERING); CAN_SET_FLAG(p_can_obj->control_flags, CTRL_FLAG_RECOVERING);
//Trigger start of recovery process //Trigger start of recovery process
configASSERT(can_exit_reset_mode() == ESP_OK); esp_err_t err = can_exit_reset_mode();
assert(err == ESP_OK);
CAN_EXIT_CRITICAL(); CAN_EXIT_CRITICAL();
return ESP_OK; return ESP_OK;

View file

@ -16,10 +16,11 @@ import IDF
STR_EXPECT = ("CAN Alert and Recovery: Driver installed", "CAN Alert and Recovery: Driver uninstalled") STR_EXPECT = ("CAN Alert and Recovery: Driver installed", "CAN Alert and Recovery: Driver uninstalled")
EXPECT_TIMEOUT = 20 EXPECT_TIMEOUT = 20
@IDF.idf_example_test(env_tag='Example_CAN')
@IDF.idf_example_test(env_tag='Example_CAN1', ignore=True)
def test_can_alert_and_recovery_example(env, extra_data): def test_can_alert_and_recovery_example(env, extra_data):
#Get device under test, flash and start example. "dut4" must be defined in EnvConfig # Get device under test, flash and start example. "dut4" must be defined in EnvConfig
dut = env.get_dut('dut4', 'examples/peripherals/can/can_alert_and_recovery') dut = env.get_dut('dut1', 'examples/peripherals/can/can_alert_and_recovery')
dut.start_app() dut.start_app()
for string in STR_EXPECT: for string in STR_EXPECT:

View file

@ -17,7 +17,7 @@ import IDF
#Define tuple of strings to expect for each DUT. #Define tuple of strings to expect for each DUT.
master_expect = ("CAN Master: Driver installed", "CAN Master: Driver uninstalled") master_expect = ("CAN Master: Driver installed", "CAN Master: Driver uninstalled")
slave_expect = ("CAN Slave: Driver installed", "CAN Slave: Driver uninstalled") slave_expect = ("CAN Slave: Driver installed", "CAN Slave: Driver uninstalled")
listen_only_expect = ("CAN Listen Only: Driver installed", "Listen Only: Driver uninstalled") listen_only_expect = ("CAN Listen Only: Driver installed", "CAN Listen Only: Driver uninstalled")
def dut_thread_callback(**kwargs): def dut_thread_callback(**kwargs):
#Parse keyword arguments #Parse keyword arguments
@ -34,7 +34,7 @@ def dut_thread_callback(**kwargs):
#Mark thread has run to completion without any exceptions #Mark thread has run to completion without any exceptions
result[0] = True result[0] = True
@IDF.idf_example_test(env_tag='Example_CAN') @IDF.idf_example_test(env_tag='Example_CAN2', ignore=True)
def test_can_network_example(env, extra_data): def test_can_network_example(env, extra_data):
#Get device under test. "dut1", "dut2", and "dut3" must be properly defined in EnvConfig #Get device under test. "dut1", "dut2", and "dut3" must be properly defined in EnvConfig

View file

@ -16,10 +16,11 @@ import IDF
STR_EXPECT = ("CAN Self Test: Driver installed", "CAN Self Test: Driver uninstalled") STR_EXPECT = ("CAN Self Test: Driver installed", "CAN Self Test: Driver uninstalled")
EXPECT_TIMEOUT = 20 EXPECT_TIMEOUT = 20
@IDF.idf_example_test(env_tag='Example_CAN')
@IDF.idf_example_test(env_tag='Example_CAN1', ignore=True)
def test_can_self_test_example(env, extra_data): def test_can_self_test_example(env, extra_data):
#Get device under test, flash and start example. "dut4" must be defined in EnvConfig # Get device under test, flash and start example. "dut4" must be defined in EnvConfig
dut = env.get_dut('dut4', 'examples/peripherals/can/can_self_test') dut = env.get_dut('dut1', 'examples/peripherals/can/can_self_test')
dut.start_app() dut.start_app()
for string in STR_EXPECT: for string in STR_EXPECT: