Purpose: | Call a subroutine in FLASH memory, but verify that the address given does not point to an invalid FLASH memory destination. Even if the FLASH address (i.e., specified subroutine desination) is valid but the instruction at that address is 0xFFFF (usually an uninitialized FLASH location), skip the ICALL. The idea is to facilitate program extensions, but to avoid as many system crashes as possible. It is easy to setup a pointer to a routine before the subroutine itself is actually in place. This affords a little grace and protection from that programming error while providing the freedom to call any subroutine placed in the non-system PROGRAM memory. |
Although these two subroutines are related, ICALL_IfValid_EEPROM() actually uses ICALL_IfValid_PGM(). The EEPROM version is passed a pointer (in EEPROM) to a pointer (in PROGRAM memory). The PGM version is only passed the second one, the pointer to the subroutine in PROGRAM memory. Stated another way, the EEPROM version just adds the ability to specify a FLASH subroutine's address from EEPROM. In fact, seven (7) of the eight (8) EEfPtr variables use this system function. Only EEfptrSequence1 does not. It does not point to executable code but points to the first sequencing structure, which is a special type of structure, which contains, but does not begin with, executable code. | |
Assumes: | The pointer specified may or may not point to a valid EEPROM address or a valid PROGRAM memory address. If it does not, return gracefully. |
Passed: | R25:R24 | WORD * | wPtrSubr | EEPROM address from which to read the FLASH subroutine's address OR FLASH address of the subroutine to call |
Returns: | All Registers and FLAGS returned by the subroutine called, except R30 and R31, which are PUSHed, used for the ICALL, then then POPped (restored to the calling routine's value) upon return. | |||
Alters: | R24, R25, and the FLAGS | |||
Example #1: |
|
|||
Example #2: |
|
|||
Notes: | The SYSTEM FLASH memory is protected and will always return 0xFF (for a BYTE or 0xFFFF for a WORD, etc.) for any read request. Therefore, these two routines cannot be used to indirectly call system functions. Also, even through it would not reject a subroutine just because it was placed in the 0x3A00 to 0x40FF range (in a 328P), that area is reserved for the Operating System. Please select a different section of FLASH memory. | |||
Also see: | Sequencer logic, program extensions, and system EEPROM variables. |