I wrote a C code to use API as my system base timer, I want to relocate the interrupt service routine into RAM segment, but when debugging, I found the “current_clock++ “(a unsigned long variable) will invoke a function "_LINC" which is locate in the ROM.
How can i put the entire interrupt routine into RAM?
Solved! Go to Solution.
Hi,
_LINC is the run-time function to perform increment of 32-bit (long) integer. Since there is no hw. instruction support for this operation this is done by a routine instead.
One solution is to copy and paste the file below into your local project:
"c:\Program Files (x86)\Freescale\CWS12v5.2\lib\hc12c\src\rtshc12.c"
Now you can adjust the function to be placed into your RAM section "RAM_CODE"
/*---------- Long INCrement ---------------------------------------------------*/
/* D:X = (D:X)+1 */
#ifdef __cplusplus
extern "C"
#endif
#pragma push
#pragma CODE_SEG RAM_CODE
#pragma NO_FRAME
#pragma NO_ENTRY
#pragma NO_EXIT
void _LINC ( void ) {
asm {
IBNE D,done
INX
done: RTS
}
}
#pragma pop
Change the link order so the linker now prefers to uses the source file instead of the ANSI library:
Build the project and check the map file - now both isrVapi and _LINC are located in RAM_CODE section.
MODULE: -- main.c.o --
- PROCEDURES:
main FE8000 E 14 2 .text
isrVapi 2100 14 20 1 RAM_CODE
- VARIABLES:
current_clock 2119 4 4 4 .common
MODULE: -- Start12.c.o --
- PROCEDURES:
Init FE800E 29 41 2 .text
_Startup C000 F 15 0 .init
- VARIABLES:
_startupData C00F 6 6 3 .startData
- LABELS:
__SEG_END_SSTACK 2100 0 0 1
MODULE: -- rtshc12.c.o --
- PROCEDURES:
_LINC 2114 5 5 1 RAM_CODE
- VARIABLES:
The drawback of this approach is that if you perform long increment in any other place of your code it always calls the RAM instance of _LINC.
If you want to have two separate instances for RAM and FLASH you should probably replace the C increment statement in your interrupt handler:
current_clock++;
with a custom function call e.g.:
current_clock=_LINC_RAM(current_clock);
And create your custom version of long increment function in RAM.
Hope it helps.
Stan
Hi,
_LINC is the run-time function to perform increment of 32-bit (long) integer. Since there is no hw. instruction support for this operation this is done by a routine instead.
One solution is to copy and paste the file below into your local project:
"c:\Program Files (x86)\Freescale\CWS12v5.2\lib\hc12c\src\rtshc12.c"
Now you can adjust the function to be placed into your RAM section "RAM_CODE"
/*---------- Long INCrement ---------------------------------------------------*/
/* D:X = (D:X)+1 */
#ifdef __cplusplus
extern "C"
#endif
#pragma push
#pragma CODE_SEG RAM_CODE
#pragma NO_FRAME
#pragma NO_ENTRY
#pragma NO_EXIT
void _LINC ( void ) {
asm {
IBNE D,done
INX
done: RTS
}
}
#pragma pop
Change the link order so the linker now prefers to uses the source file instead of the ANSI library:
Build the project and check the map file - now both isrVapi and _LINC are located in RAM_CODE section.
MODULE: -- main.c.o --
- PROCEDURES:
main FE8000 E 14 2 .text
isrVapi 2100 14 20 1 RAM_CODE
- VARIABLES:
current_clock 2119 4 4 4 .common
MODULE: -- Start12.c.o --
- PROCEDURES:
Init FE800E 29 41 2 .text
_Startup C000 F 15 0 .init
- VARIABLES:
_startupData C00F 6 6 3 .startData
- LABELS:
__SEG_END_SSTACK 2100 0 0 1
MODULE: -- rtshc12.c.o --
- PROCEDURES:
_LINC 2114 5 5 1 RAM_CODE
- VARIABLES:
The drawback of this approach is that if you perform long increment in any other place of your code it always calls the RAM instance of _LINC.
If you want to have two separate instances for RAM and FLASH you should probably replace the C increment statement in your interrupt handler:
current_clock++;
with a custom function call e.g.:
current_clock=_LINC_RAM(current_clock);
And create your custom version of long increment function in RAM.
Hope it helps.
Stan
Hi, Stanislav Sliva,
Thank you for your help! On your suggestion, I modified my code to the following
#define lONG_INC(var) ((uint16_t *)&var)[1]++;\
if(((uint16_t *)&var)[1] == 0){\
((uint16_t *)&var)[0]++;\
}
#pragma CODE_SEG RAM_CODE
/*
** ===================================================================
** Interrupt handler : isrVapi
**
** Description :
** User interrupt service routine.
** Parameters : None
** Returns : Nothing
** ===================================================================
*/
__interrupt void isrVapi(void)
{
/* Write your interrupt code here ... */
VREGAPICL_APIF = 0x01U; /* Reset interrupt request flag */
lONG_INC(current_clock);
}
/* end of isrVapi */
#pragma CODE_SEG DEFAULT