Question about ISR and arg

Hello !

I’ve a project developped with WinARM.

In the main function, I declared a struct data which is allocated dynamically. Therefore this struct is local. I’ve an interrupt function as well, which must process data in the structure. This function passed no argument and return nothing (void ISR_handler(void)).

Does it possible to pass a pointer to the ISR to process data into my struct without allocated it as global ?

It don’t know how to do it… maybe a pointer to function ?

Thanks for your help,

David

Since (I would assume, at least) your main() function isn’t calling your ISR(), the ISR has no way of knowing where main’s local variables are located (at least that I know of). Either you would have to define a global pointer that main set to the address of your data struct or you would have to make the entire data structure global. If your main and ISR functions are in the same file, you could declare the data structure globally as static, and then it could only be modified within that file. Is there any reason you are avoiding declaring the variable as global (other than the fact that you were probably taught in school/books that this is bad :wink: )?

Globals are your only method of communication with the ISR - you’d need a global pointer to the struct, if for some reason the struct itself can’t be made global.

OK, thanks Brennen and Jason.

That exactly what I did, I just declared a global ptr to the structure which is allocated into the main() and destroyed after. I was pretty sure that there was no means to communicate with ISR directly, I needed to confirm this point.

I asked this because this program will be a sub-program among others (like an application) which is called from the real main() above (a kind of OS). That’s why I looked for to limit the ram usage for the other applications.

ps : you’re right Brennen, my teachers always said the global variables were bad :? but unfortunatly, most of them hadn’t never worked on embedded systems :twisted:

A strategy I’ve seen a lot is to use a central interrupt handler. Other parts of the software can register for an interrupt there by providing an interrupt bit mask, a callback function pointer and an optional argument. When an interrupt occurs, the central interrupt handler checks the interrupt status against the interrupt bit mask in its list of registered interrupts. If a bit matches, it calls the registered interrupt handler (using the function pointer), with the stored argument.

By using the register/callback mechanism, the central interrupt handler can be kept generic, with no dependency on the actual device interrupt handlers. The interrupt handler function pointers can be pointers to static functions and the interrupt arguments can be pointers to static structures, no need for global variables. Spurious interrupts like non-registered interrupts can be detected easily: if a bit in the interrupt status register does not match any of the bit masks of the interrupt handlers.

If you have (for example) two serial ports, you can service them with a single interrupt handler, by registering the same function pointer twice (but with different interrupt bit mask and argument). The argument can be a pointer to a data structure, or it can simply be an index (e.g. 0 for UART0, 1 for UART1). The central interrupt handler just passes the argument along to the handler; it’s up to the software module that handles the interrupt how to use it.

This works only for software based interrupt handling, it’s not suited for vectored IRQs.