How do you decide which tool is right for you

Thread Starter

Kittu20

Joined Oct 12, 2022
470
I understand what is polling and interrupt, but don't understand when to use it.

I am sure you must have come across a situation when you have to decide whether you need polling or interrupt.

have you ever come across such a situation? How do you decide which tool is right for you polling or interrupt
 

WBahn

Joined Mar 31, 2012
30,045
If you are in a situation in which both are workable options, then there usually is no clear winner. Each approach has pros and cons. Part of it comes down to which you are more comfortable with.

Consider each option and look at the benefits and downsides as it pertains to THIS problem. The evaluate the lists and make a decision.
 

Papabravo

Joined Feb 24, 2006
21,225
I have found that in most cases using interrupts is the best way to ensure that high priority events are handled in a predictable fashion in exchange for low priority processes taking whatever time they need. Maybe that is because the use of interrupts was always natural and intuitive to me.
 

MrChips

Joined Oct 2, 2009
30,795
There are different approaches.

When you are new to MCU programming the first method you encounter is polling that blocks process flow until the event is passed.

wait until condition is satisfied

Students are rarely taught about non-blocking use of polling.

if (condition) do process
else continue with other process


Interrupts are usually introduced at a later stage in embedded programming courses.
Interrupts are immediate and take priority over foreground or background processes. Device servicing may be immediate or may be deferred to the foreground/background process.

In general, use of interrupts is more efficient in complex real-time multi-task processing.

One other topic that is rarely taught is DMA (direct memory access). This is even more efficient than interrupts and can run concurrently without consuming processing cycles.

To answer your question, use polling if it does the job. Use interrupts when polling does not do the job.
 

nsaspook

Joined Aug 27, 2009
13,265
For most non-trivial applications it's a mixture of non-blocking polled, interrupts with callbacks, DMA, etc.... What method goes where is mainly decided by the amount of memory and cpu resources needed for that program section functionality to interact correctly with other program sections vs the added code for interrupts and/or DMA.

https://raw.githubusercontent.com/nsaspook/wfi32/nhost/firmware/src/host.c

Simple non-blocking poll of a input command and a CANFB receive interrupt status.
C:
    while (true) {

        LED_GREEN_Toggle();

        if (state == APP_STATE_CAN_USER_INPUT) {
            user_input = 'n';
            /* Read user input */
            if (UART1_ReceiverIsReady()) {
                UART1_Read((void *) &user_input, 1);
            } else {
                if (CAN1_InterruptGet(2, 0x1f)) {
                    user_input = '3';
                }
            }
// stuff
}
Callback on interrupt on completion of CANFB DMA transfer and then a DMA update of the Oled status display memory buffer.
C:
// callback routine
void APP_CAN_Callback_h(uintptr_t context)
{
    xferContext = context;

    /* Check CAN Status */
    status = CAN1_ErrorGet();
    CAN1_ErrorCountGet(&txe, &rxe);
    sprintf(buffer, "CB %d,TE %d,RE %d,ER %X,DI %X", status, txe, rxe, CFD1TREC,CFD1BDIAG1);
    eaDogM_WriteStringAtPos(5, 0, buffer);

    if ((status & (CANFD_ERROR_TX_RX_WARNING_STATE | CANFD_ERROR_RX_WARNING_STATE |
        CANFD_ERROR_TX_WARNING_STATE | CANFD_ERROR_RX_BUS_PASSIVE_STATE |
        CANFD_ERROR_TX_BUS_PASSIVE_STATE | CANFD_ERROR_TX_BUS_OFF_STATE)) == CANFD_ERROR_NONE) {
        switch ((APP_STATES) context) {
        case APP_STATE_CAN_RECEIVE:
        case APP_STATE_CAN_TRANSMIT:
        {
            state = APP_STATE_CAN_XFER_SUCCESSFUL;
            break;
        }
        default:
            break;
        }
    } else {
        state = APP_STATE_CAN_XFER_ERROR;

    }
}


            case '3':
                msg_ready = CAN1_InterruptGet(2, 0x1f);
                if (msg_ready) {

                    // Waiting for message

                    CAN1_CallbackRegister(APP_CAN_Callback_h, (uintptr_t) APP_STATE_CAN_RECEIVE, 2);
                    state = APP_STATE_CAN_IDLE;
                    memset(rx_message, 0x00, sizeof(rx_message));

                    /* Receive New Message */
                    if (CAN1_MessageReceive(&rx_messageID, &rx_messageLength, rx_message, &timestamp, 2, &msgAttr) == false) {
                        sprintf(buffer, "CAN1_MessageReceive request has failed");
                        eaDogM_WriteStringAtPos(11, 0, buffer);
                    }
                    /* Application can do other task here */
                    sprintf(buffer, " CAN-FD  received %i", recv_count++);
                    eaDogM_WriteStringAtPos(13, 0, buffer);
                    OledUpdate();
                    WaitMs(50);
                } else {
                    state = APP_STATE_CAN_USER_INPUT;
                }
                break;
            case 'm':
                break;
            case 'n':
                break;
            default:
                break;
            }
1672780435478.png
 
Last edited:
Top