
139
Chapter 2 Applications Programming
supplied C handler. Note that it assumes that the interrupt procedure has a one–word
procedure tag preceded by an interrupt tag word –– this is almost always the case. If
no interrupt tag is found then signal handling is selected. This would be the case if the
handler routine had been built with the GNU compiler which does not currently
support interrupt tag words.
Depending on the tag word, Freeze mode or signal processing is selected and the
appropriate code copied into heap memory space. For Freeze mode processing, only
the required number of global registers is saved in the interrupt context cache
(
gr64–gr80
). Additionally, only the minimum required amount of heap memory is
requested via the HIF–library
malloc()
service. After copying code into heap
memory, some instruction
patching
is performed to correctly reference the assigned
C handler. Finally the HIF–library
_settrap()
service is used to assign a trap handler
address to the requested trap number. Note that when the copying is performed, the
heap memory is only written to and never read. This will prevent the code being
placed into on–chip data cache, as 29K family data caches only allocate cache blocks
on data reads. Avoiding caching of the relevant heap memory ensures that the new
code will be fetched from instruction memory (see sections 5.13.2 and 5.14.4).
int
int
void (*C_handler)();
{
int
int
int
int
_LOCK volatile int *code_p, *mem_p; /* see section 5.14.1 */
if((tag_word & 0xff000000) != 0)
tag_word = –1;
if((tag_word & 0xffff00ff)==0)
{
glob_regs=(tag_word & 0xff00) >> 8;
code_p=&interrupt_cache_code;
size=4*((2*glob_regs)+6+8);
mem_p=(int*)malloc(size)
trap_handler=mem_p;
code_p=code_p+(16–glob_regs); /* find start of save */
for(i=1; i <=glob_regs; i++) /* copy save code */
*mem_p++=*code_p++;
/* supply address to CONST instruction *
*mem_p++ =*code_p++ | ( (((int)C_handler&0xff00)<<8)
+ ((int)C_handler&0xff) );
/* supply address to CONSTH inst. */
*mem_p++ =*code_p++ | ( (((int)C_handler&0xff000000) >>8)
+ (((int)C_handler&0xff0000) >>16) );
for(i=1; i <=(4–2); i++)
*mem_p++=*code_p++;
code_p=code_p + (16–glob_regs); /* find start of restore */
for(i=1;i<=(glob_regs+2+8);i++) /* copy restore code */
*mem_p++=*code_p++;
ret_sig=0;
interrupt
(trap_number, C_handler)
trap_number;
*tag_p=(int*)C_handler – 2;
ret_sig;
tag_word = *tag_p;
glob_regs, *trap_handler, i, size;
/* return signal value */
/* no interrupt tag word */
8 for sig_sig code support
/* get heap memory */
/* copy the call code */
8 required for sig_sig code support