Functions VS ISR

Functions VS ISR

Have you ever thought why interrupt service routines(ISR) in some tool-chains is written in a special format that is different from the normal C functions? to answer this question we should first know the difference between normal C functions and interrupt service routines.

Normal C Functions

A function is a group of statements that together perform a task.This function is executed when it is called from a certain point in our code.so this means that in functions there is what we call a caller and callee. since functions is called at certain points of our code this means that functions are synchronized to the call which means functions are synchronous.

Interrupt service routines

On the other hand ISR is a group of statements that is executed in response to an event that leads to a change in the program execution.the events are asynchronous which means those events could happen at any time we don't know when they will occur and so ISR is asynchronous. but what is the effect of an ISR being asynchronous?

No alt text provided for this image

Effect of asynchronous property of ISR

To show the effect this property on code behavior. follow up with this assumption. imagine you have a function that takes two numbers add them together and return the result what would you expect will happen if an ISR occurred while the function was at the middle of executing the function? to know what will happen lets see the assembly code of the function and observe what would happen if an interrupt occurred at certain point of execution.

No alt text provided for this image
No alt text provided for this image

the above assembly code is just explained as follows the two numbers is loaded into two registers and added so now what will happen if an interrupt occurred at the second line?the catch is the CPU will wait to finish the instruction which means Register R24 is now loaded with the number we want to add but after that the ISR will be executed the ISR could actually change the content of Register R24 which contains the number we want to add and after it returns the addition operation would be wrong as the number changed by the ISR!!! so how Compiler deal with this issue so it don't happen? yes this will lead us to why ISR is written in a different format than normal function this is because compiler generate special code for ISR that allows it to store the context of most CPU registers so when the ISR finishes its execution the CPU context is returned and the function that was executing won't be affected by the ISR at all as the context that the function was acting on is restored from the ISR as it is.

so the difference here is that compiler will generate different code from code it will generate to normal functions in order to do the following

1-store most CPU registers (more than what is saved in functions) by pushing them into stack

2-adding a return from interrupt instruction at end of ISR to pop all saved registers from stack. so the return instruction form ISR is different form a return from function.

As an example for that we could observe the standard that of AVR GCC tool chain and how it says that ISR should have a different code than normal functions.

AVR-GCC Context switching

As we could observe that in GCC the registers mentioned here is allowed to be changed and clobbered by normal functions without having to be stored while at the same time those registers is not allowed to be clobbered by ISR and have to be saved so as we said the code written for ISR would include additional Registers to be saved and pushed into the stack and that's why ISR in GCC has an attribute to show that it is not a normal function.

No alt text provided for this image


to prove that this case is highly platform dependent i will discuss next how ARM managed to make ISR as a normal C functions without any overhead of adding other code or writing any additional attributes.

How Arm managed to make ISR normal C functions

So logically after we have seen how ISR is different for normal functions in two ways which is the number of saved registers and the special return instruction in order to make a normal c function able to be used for ISR the function should normally match the two conditions and that is what we will see how ARM managed to do.

How C functions work in ARM

C compilers for ARM architecture follow a specification from ARM called the AAPCS, Procedure Call Standard for ARM Architecture (reference 13). According to this standard, a C function can modify R0 to R3, R12, R14 (LR), and PSR. If the C function needs to use R4 to R11, it should save these registers on to the stack memory and restore them before the end of the function.R0-R3, R12, LR, and PSR are called “caller saved registers.” The program code that calls a subroutine needs to save these register contents into memory (e.g., stack) before the function call if these values will still be needed after the function call. R4-R11 are called “callee-saved registers.” The subroutine or function being called needs to make sure the contents of these registers are unaltered at the end of the function (same value as when the function is entered). The values of these registers could change in the middle of the function execution, but need to be restored to their original values before function exit.


Exception entry mechanism in ARM

In order to allow a C function to be used as an exception handler, the exception mechanism needs to save R0 to R3, R12, LR, and PSR at exception entrance automatically, and restore them at exception exit under the control of the processor’s hardware. In this way when returned to the interrupted program, all the registers would have the same value as when the interrupt entry sequence started. In addition, since the value of the return address (PC) is not stored in LR as in normal C function calls (the exception mechanism puts an EXC_RETURN code in LR at exception entry, which is used in exception return), the value of the return address also needs to be saved by the exception sequence. So in total eight registers need to be saved during the exception handling sequence on the Cortex-M3 or Cortex-M4 processors without a floating point unit.

No alt text provided for this image





Mohamed Mahran

Senior Embedded Software Engineer at eJad | PSM

4 年

Very good article Omar ??

要查看或添加评论,请登录

Omar Ehab的更多文章

  • Introduction to Cache Memory

    Introduction to Cache Memory

    Microcontrollers are the heart of every embedded system and in the last decades we have seen an increase in their…

    3 条评论
  • CPU Utilization in Embedded systems

    CPU Utilization in Embedded systems

    An important metric that give an insight about the system performance is the CPU load or utilization. In the following…

    30 条评论
  • Flash Memory in Embedded Systems

    Flash Memory in Embedded Systems

    A trivial mistake that lots of beginners in embedded systems do when they get introduced to Flash and EEPROM is they…

    2 条评论
  • Secure Firmware flashing using firmware signing

    Secure Firmware flashing using firmware signing

    The ability to flash a new Firmware to your embedded target using a boot-loader is essential but did you think what if…

    3 条评论
  • Synchronous VS Asynchronous Operations

    Synchronous VS Asynchronous Operations

    One of the concepts that I recognized that lots of people get it wrong is the difference between synchronous and…

    7 条评论
  • Access Synchronization

    Access Synchronization

    Writing Embedded software you will usually encounter the situation where you have to synchronize your tasks either for…

    3 条评论
  • Thread safe and Non-Thread safe Vs Re entrant and Non-Re entrant functions

    Thread safe and Non-Thread safe Vs Re entrant and Non-Re entrant functions

    Multi threading environment could be chaotic if careful design consideration is not taken and one of the most famous…

    4 条评论
  • Interrupt Latency

    Interrupt Latency

    It is known that we use interrupts in embedded software in order to serve asynchronous event almost immediately.so the…

    7 条评论
  • Scheduling analysis and testing using Rate monotonic algorithm with time demand analysis.

    Scheduling analysis and testing using Rate monotonic algorithm with time demand analysis.

    Following up with the article i published before about scheduling and multitasking.In this short tutorial we will see…

  • Introduction to multitasking and scheduling in Embedded systems

    Introduction to multitasking and scheduling in Embedded systems

    This will be a short introduction into multitasking in embedded systems. First what is multitasking? Multitasking is…

    3 条评论

社区洞察

其他会员也浏览了