Execution does not resume from the point it was left before interrupt

Hi ,

I am trying to develop an application on STM32 using FreeRTOS. I am new to FreeRTOS. I have a CAN communication task running at osPriorityNormal which is 24 and I have enabled CAN Tx mailbox empty interrupt . I have variable which updates the status of CAN trasmission inside the interrupt. After transmission , I get a Tx mailbox interrupt and sets the CAN transmission status variable . Once the execution of Interrupt is complete , the control is supposed to return back to the exceution point which was left before servicing interrupt. Instead control is returning to begining of the function .

Here is my sample code

can_tx_state_t cancommstx(uint32_t targetid, uint8_t len,
    uint8_t data[]) {
    uint8_t ret_val = CAN_TX_FAILURE;
    fess_os_types_t sem_result = SUCCESS;

    if (can_configured == false) {
        }
    else if (can1_tx_handler.state != CAN_TX_RDY) {
        LOG("Can't send ");
        }
    else {
        can1_tx_handler.state = CAN_TX_TRANSMITTING;
        can1_tx_handler.buf = data;
        can1_tx_handler.len = len;
        can1_tx_handler.index = 0;
        can1_tx_handler.orig_len = len;
        can1_tx_handler.target_id = targetid;

        can_comms_tx_data();
        sem_result =rtos_get_semaphore(can1_tx_handler.can_tx_semaphore,
            CAN_TX_TIMEOUT);
        if (sem_result == SUCCESS) {
       
            if (can1_tx_handler.state != CAN_TX_RDY) {
                 LOG("Semaphore set, but state = %x\n", can1_tx_handler.state);
          
                LOG("CAN TX failure\n");
                ret_val = CAN_TX_FAILURE;               
                }
            else {
                ret_val = CAN_TX_SUCCESS;

                }

            }
        else {
            // Our timeout has been reached, stop trying to send any in-flight
            // messages
            if (can1_tx_handler.tx_mailbox != 0) {
                HAL_CAN_AbortTxRequest(&hcan1, can1_tx_handler.tx_mailbox);
                can1_tx_handler.tx_mailbox = 0;
               LOG("CAN Timeout\n");
                }

            // wait timed out.  Disable interrupts
            HAL_CAN_DeactivateNotification(&hcan1, CAN_IT_TX_MAILBOX_EMPTY);

          
         rtos_get_semaphore(can1_tx_handler.can_tx_semaphore, 0);
            LOG("Dropping CAN\n");
            }

        // clean up
        can1_tx_handler.buf = NULL;
        can1_tx_handler.len = 0;
        can1_tx_handler.index = 0;
        can1_tx_handler.orig_len = 0;
        can1_tx_handler.state = CAN_TX_RDY;
        }

void HAL_CAN_TxMailbox0CompleteCallback(CAN_HandleTypeDef* hcan) {
    bool notify = false;
    HAL_CAN_DeactivateNotification(&hcan1, CAN_IT_TX_MAILBOX_EMPTY);
    can1_tx_handler.tx_mailbox = 0;
    if (can1_tx_handler.len == 0) {
        can1_tx_handler.buf = NULL;
        can1_tx_handler.index = 0;
        can1_tx_handler.state = CAN_TX_RDY;
        notify = true;
        }
    else {
        can_comms_tx_data();
        if (can1_tx_handler.state == CAN_TX_FAILURE) {
            notify = true;
            }
        }
    if (notify) {
       
        rtos_set_semaphore(can1_tx_handler.can_tx_semaphore);
        }
    }

There is no way for an ISR to change the return address it goes to unless it does something incorrect and corrupts the state.

One thing to note, I presume the HAL_CAN_TxMailbox0CompleteCallback is being called inside the CAN ISR, at which point it needs to be using the ISR based functions, so the question comes does the rtos_set_semaphore wrapper deal with that?

[not an answer to your question]

Gosh, why so many different priorities? How many tasks do you have? I hope configUSE_PORT_OPTIMISED_TASK_SELECTION is set to 1.

Yes . The rtos_ set_semaphore is using CMSIS API .

The normal priority in CMSIS is equivalent to 24 . I just have 3 tasks running . A main task which pushes the data to Queue, CAN monitor task which pops out the data and process it .

The question is does the CMSIS API respect the FreeRTOS requirement for using FromISR versions inside an ISR?

Yes . It does handle the FreeRTOS interrupt requirements.

So according to my basics , the execution is supposed to resume from it was left before servicing the interrupt . So if I get an Tx mail box interrupt after sem_result =rtos_get_semaphore(can1_tx_handler.can_tx_semaphore,
CAN_TX_TIMEOUT); then it is supposed to resume at if (sem_result == SUCCESS) after servicing the interrupt . Rather the control is going back to begining of the function . Sorry if I was not clear before .

Or the scheduler selects another task to run as result of the ISR codeā€¦
But yes, sooner or later the task continues at the point it was interrupted.

How do you verify that? Have you verified that it is the same task for which the control is going back to the beginning to the function? Can you share the definition of the function?