FX2/FX2LP SDCC Eclipse Project: Interrupt not Serviced - KBA231372
Translation - Japanese: FX2 / FX2LP SDCC Eclipseプロジェクト：割り込みが処理されない - KBA231372 - Community Translated (JA)
Why are the Interrupt Service Routines (ISRs) not executed when the respective interrupt is triggered while using the SDCC-based FX2/FX2LP Eclipse project?
When using SDCC-based FX2/FX2LP Eclipse project, ISR may not be executed even after the interrupt is triggered because of the following two reasons:
A. SDCC Linker:
SDCC linker places the interrupt vector table starting at address 0x0003. Whenever this address is overwritten or corrupted, the jump to the respective ISR will not be executed and interrupts will not be serviced. Make sure to avoid this.
Improper initialization of xdata variables is one of the common reasons for the interrupt vector table to be overwritten.
By default, the initialized xdata variables will be placed at the start of 8051 external RAM, that is, on-chip RAM of FX2LP (See section 5.3 External Program Memory and External Data Memory of the EZ-USB Technical Reference Manual).
This may overwrite the interrupt vector table, which is placed starting at address 0x0003 of the on-chip RAM. As a result, the ISR will not be executed, because the ljmp instructions to the ISRs in the interrupt vector table are overwritten or corrupted.
Follow either one of these methods to avoid overwriting:
1. Absolute Addressing of xdata variables: Each xdata variable can be initialized at a specific address using the __at <address> keyword. Choose the <address> so that there is no overlap with the code area.
Example: __xdata __at (0x3000) unsigned int testVar;
This should be done for each __xdata variable initialization, which can be a tedious task when there are many variables to be initialized. In that case, follow method 2.
2. XSEG placement: The XSEG can be placed after the code area, so that the xdata variables, when initialized, will not overlap the code.
This can be done by adding the --xram-loc <value> linker command line option.
Note that <value> is the address where the XSEG needs to be placed.
The code size can also be restricted using the --code-size <limit> MSC51 command line option, so that the xstack can be placed after the code area without any overlap.
Note that <limit> is the code size limit
The linker will check if the code memory usage is within the limit (<value>) specified and if the code size limit exceeds, the linker will generate an error stating, Insufficient ROM/EPROM/FLASH memory.
Do the following to add the command line options to the SDCC linker of your Eclipse project:
- Go to the corresponding Eclipse project properties (Right-click the project and click Properties).
- In the left pane of the properties window, select Settings from the C/C++ Build section.
- In the Tool Settings tab, select SDCC Linker.
- In the Command textbox, add the command line options after sdcc. See Figure 1.
- Click Apply, and then click OK to apply the changes.
Figure 1. Adding Command Line Options to SDCC Linker
In Figure 1, the code size is restricted to 0x2FFF and the XSEG (xdata) is placed at location 0x3000 in the FX2/FX2LP on-chip RAM.
B. XPAGE Location:
In the default FX2LP Bulkloop_SDCC project, the XPAGE will default to 0x00A0.
As per section 4.1.1 pdata access by SFR of the SDCC User Guide, for the EZ-USB family, the XPAGE should be defined at address 0x92 by adding the following line of code to the fx2regs.h file of the project:
__sfr __at (0x92) _XPAGE; /* Cypress EZ-USB family, Texas Instruments (Chipcon) a.k.a. MPAGE */
Build the project with the Linker command changes (mentioned in A) and XPAGE location changed (mentioned in B).
Attached Example Project:
The FX2LP SDCC Eclipse project (FX2LP_Project_ISR.zip), available with this knowledge base article includes the changes.
The project also includes I2C Debug files referred in FX2LP I2C Based Debug with SDCC on Eclipse IDE - KBA229648 and the isr.c file in which ISRs for external interrupt 0 (INT0#) and external interrupt 1 (INT1#) are defined, and used to toggle the Port B pins:
- INT0#: High to low transaction on this pin will toggle Port B pins once.
- INT1#: High to low transaction on this pin will toggle Port B pins twice.