Ruffian Heng embedded: take the GPIO module of i.mxrt1xxx as an example to talk about the standard process of interrupt handler (irqhandler)


Hello, I’m ruffian Heng, a serious technical ruffian. What ruffian Heng introduced to you today isTaking the GPIO module of i.mxrt as an example, this paper discusses the standard flow of interrupt handler (irqhandler)

In the old prose of ruffian HengDesign and implementation of serial port (UART) automatic baud rate identification program (interrupt)In, we use the I / O edge detection function integrated in the GPIO module to capture the falling edge of RXD signal, which involves the GPIO interrupt processing function. Interrupt handling function irqhandler is a very special kind of function in embedded system. They are the key for embedded system to complete tasks in real time. Any interrupt handling function needs to be treated with caution.

In the old article above, the GPIO interrupt processing function written by ruffian Heng is actually a little flawed. Although it does not affect the final baud rate recognition function, it is not written in the standard process. Today, ruffian Heng will talk to you about the standard process of interrupt processing function:

1、 Introduction to GPIO module interrupt

GPIO is basically the most entry-level peripheral in MCU. Let’s take a brief look at the functions of GPIO module in i.mxrt1011.

1.1 GPIO general design

i. Each group of GPIO in mxrt contains a maximum of 32 pins, which exactly corresponds to 32bit registers. The following are the three basic registers of GPIO:

Gdir [31:0] - configure the input / output direction of pin (only if GPIO mode is configured in iomuxc)

The precondition for operating the above GPIO peripheral registers is that the pin function mode has been configured as GPIO in the iomuxc module (because each pin may be multiplexed by a variety of peripherals such as UART / timer). For example, in the old article mentioned at the beginning of the article, we used GPIO for baud rate detection_ 09 pin, it has the following eight multiplexing functions, of which alt5 function is GPIO.

GPIO_ After pin 09 is set to GPIO function mode, its pad attributes need to be further configured according to the application scenario. The following figure shows the internal circuit structure of pad. We can configure many attributes, such as driving strength, speed level, up and down, which are also completed in iomuxc module.

In the scenario of serial port baud rate identification and detection, we need to integrate GPIO into iomuxc module_ Pin 09 is configured as GPIO mode, and pad attribute is configured accordingly (mainly enabling internal pull-up because the serial port signal idle status is high level). The example code is as follows:

#include "fsl_iomuxc.h"

void io_pin_config(void)
    CLOCK_EnableClock(kCLOCK_Iomuxc);           /* iomuxc clock (iomuxc_clk_enable): 0x03U */

        IOMUXC_GPIO_09_GPIOMUX_IO09,            /* GPIO_09 is configured as GPIOMUX_IO09 */
        0U);                                    /* Software Input On Field: Input Path is determined by functionality */

        IOMUXC_GPIO_09_GPIOMUX_IO09,            /* GPIO_09 PAD functional properties : */
        0x01B0A0U);                             /* Slew Rate Field: Slow Slew Rate
                                                    Drive Strength Field: R0/4
                                                    Speed Field: fast(150MHz)
                                                    Open Drain Enable Field: Open Drain Disabled
                                                    Pull / Keep Enable Field: Pull/Keeper Enabled
                                                    Pull / Keep Select Field: Pull
                                                    Pull Up / Down Config. Field: 100K Ohm Pull Up
                                                    Hyst. Enable Field: Hysteresis Enabled */

1.2 GPIO interrupt design

If you only control the I / O input and output level, the GPIO peripheral function is too simple. In order to make GPIO peripherals have greater application value, IC designers often add edge detection functions to them, such as the registers marked in the blue box in the figure below (these registers are valid only when the pin direction is configured as input):

EDGE_ SEL [31:0] - configure whether to enable pin double edge detection

The edge detection function will involve interrupt response. In i.mxrt, in order to save interrupt number resources, 16 pins are grouped into a group, and these 16 pins share an interrupt number. i. There are 37 gpios in mxrt1011 (i.e. gpio1 [31:0], gpio2 [13:0], gpio5 [0]), so you will see the following interrupt number definitions in the mimxrt1011. H header file:

typedef enum IRQn {

In the scenario of serial port baud rate identification and detection, we need to integrate GPIO into GPIO module_ Pin 09 is configured as input mode and the falling edge capture interrupt is enabled. The example code is as follows:

#include "fsl_ gpio.h"

2、 Standard flow of interrupt handler (irqhandler)

After all the foreshadowing in the previous section, now we finally come to the core interrupt processing function. We continue to talk about the serial port baud rate recognition scene in the old article mentioned at the beginning of the article (the upper computer sets the transmission baud rate to 115200). In order to better show the problem, we use the oscilloscope to pull out the relevant signal RXD / TXD for observation.

2.1 problematic interrupt handling function

2.1.1 invalid interrupt execution

The following code is our previous writing method of interrupt processing function. The serial port baud rate identification connector codes are 0x5a and 0xa6. From the perspective of signal timing, there are 7 falling edges. In principle, this interrupt processing function should be triggered and executed 7 times (also s)_ pin_ irq_ Func execution times), we add an additional auxiliary debugging variable s_ Irqcount is supposed to be equal to 7 after identification, but in fact, its value is 12, that is, five more interrupts are entered, which is obviously unreasonable. But what makes sense is s_ pin_ irq_ Func did execute only seven times.

//Auxiliary debugging variable 1

In order to further locate the problem, we use another gpio1 [10] to assist, configure it to GPIO output mode, the initial value is high, make a flip in the interrupt processing function, and then grab gpio1 [10:9] at the same time with the oscilloscope. The waveform is as follows. It can be seen that each falling edge in the middle triggers the execution of the interrupt processing function twice continuously:

This problem is actually related to arm errata 838869. On cortex-m4 / 7, if the CPU execution speed (here i.mxrt1011 works at 500MHz dominant frequency) is much higher than the GPIO peripheral register writing speed (1 / 4 dominant frequency), and the interrupt flag bit ISR [9] is cleared in the interrupt processing function code before exiting, it will cause that the interrupt flag bit has not been really cleared, The CPU immediately executes the interrupt processing function again (as long as the flag bit in the ISR register is still set). As for function callback function s_ pin_ irq_ Func is not misexecuted because there is an interrupt status position judgment statement in the interrupt processing function. When it is executed here, the status bit ISR [9] has been cleared (but this is not reliable).

2.1.2 missing valid interrupt

Are there any other problems with this interrupt handler? In fact, we know that the general principle of interrupt processing function is fast in and fast out, that is, do not execute too much code in the function, resulting in too long execution time, which will affect the response of similar interrupts during this period. In order to facilitate the location problem, we add an additional 40us delay to the execution of the first falling edge interrupt (time starting point) response to deliberately miss the second falling edge interrupt (3bit * (1s / 115200bit) = 26.04us), but do not miss the third falling edge interrupt (6bit * (1s / 115200bit) = 52.08us).

//Auxiliary debugging variable 1

The test waveform of the above code is as follows. In this case, the baud rate recognition function is abnormal, S_ The irqcount value is 11, and more importantly, S_ pin_ irq_ Func was executed only 6 times and missed 1 time. Because of this 40us delay, the second falling edge interrupt was not responded in time. It can be understood that the first interrupt processing function cleared the interrupt flag bit before exiting, and cleared the interrupt status bit twice at a time.

2.2 solving problems in interrupt handling functions

2.2.1 avoid invalid interrupt execution

Based on the final analysis in section 2.1.1, our improved code is as follows:

void GPIO1_ Combined_ 0_ 15_ IRQHandler(void)

After the interrupt processing function code is improved, grab the waveform with the oscilloscope again, and the test results are normal:

2.2.2 avoid missing effective interruption

Based on the final analysis in section 2.1.2, our improved code is as follows:

void GPIO1_ Combined_ 0_ 15_ IRQHandler(void)

After the interrupt processing function code is improved, the oscilloscope is used to capture the waveform again. According to the test results, at least the second falling edge interrupt is not missed. Of course, the real-time performance is not guaranteed (if the time of the second interrupt is strictly recorded, it is obviously impossible), but it does not affect the function for the serial port baud rate identification application scenario discussed in this paper. However, this solution is not omnipotent. If two or more similar interrupts occur during the execution of the first interrupt processing function, there will still be a case of missing valid interrupts.

2.3 standard interrupt processing function flow

Combined with the above problem display, analysis and solution, now let’s seriously discuss what is the standard process of interrupt processing function irqhandler. Ruffian Heng believes that it is mainly divided into the following four steps: the first step is to confirm the setting of interrupt status bit (optional, some peripherals do not necessarily have status bit), and the second step is to clear the status flag immediately, The third step is to ensure that the status flag has been cleared, and the fourth step is to execute the real interrupt processing task (the shorter the execution time of this task, the better. It is best to only record the necessary information and expand the task when the interrupt exits and enters the main cycle). Therefore, the standard template of interrupt processing function is as follows:

void xxx_ IRQHandler(void)

3、 External chapter – Magical gpio1 [7:0]

Finally, on some i.mxrt models, the status of gpio1 [7:0] is different from that of other GPIO pins. They also have special interrupt numbers. For example, you can see gpio1 in the mimxrt1062. H header file_ INTx_ IRQn:

typedef enum IRQn {

So far, taking the GPIO module of i.mxrt as an example to talk about the standard process of irqhandler, ruffian Heng has introduced it. Where is the applause~~~

Welcome to subscribe

The article will be published to me at the same timeBlog Park home pageCSDN home pageZhihu home pageWeChat official accountOn the platform.

Wechat search“Ruffian scale“Or scan the QR code below to see it for the first time on the mobile phone.