This is the mail archive of the ecos-bugs@sourceware.org mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug 1002169] New: Broken cyg_interrupt_disable/enable for cortex m3


Please do not reply to this email, use the link below.

http://bugs.ecos.sourceware.org/show_bug.cgi?id=1002169

            Bug ID: 1002169
           Summary: Broken cyg_interrupt_disable/enable for cortex m3
           Product: eCos
           Version: unknown
            Target: All
 Architecture/Host_ Other
                OS:
            Status: UNCONFIRMED
          Severity: major
          Priority: low
         Component: HAL
          Assignee: unassigned@bugs.ecos.sourceware.org
          Reporter: bernard.fouche@kuantic.com
        QA Contact: ecos-bugs@ecos.sourceware.org
                CC: ecos-bugs@ecos.sourceware.org

Problem 1:

hal_interrupt_set_level() does not consider the way bits are used in IPR0..8:
the lowest bits are zero, the priority level is to be set in the upper bits.

An example for LPC17XX:

- CYGNUM_HAL_CORTEXM_PRIORITY_MAX is set to 8, because eCos sees 5 bits for
priority levels, so it does CYGNUM_HAL_CORTEXM_PRIORITY_MAX = (1 << (8-5)).

- when entering hal_interrupt_set_level(), the user set level in the .ecc file
is added to CYGNUM_HAL_CORTEXM_PRIORITY_MAX (so the priority level defined in
the .ecc file isn't what will be used by the hardware, it will be silently
changed by an offset of 8). 

- For instance, if I set the priority of an UART to 12, eCos will set 12+8=20.

- but the bit layout of IPR0..8 isn't considered, so eCos writes directly 20
(0x14) into the register corresponding to the interrupt number.

- since for LPC the 3 lower bits of IPR0..8 aren't used, what the MCU keeps in
the register is 0x10 and the priority level described is now 0x10 >> 3 = 0x02.

- When one wants to disable an interrupt, cyg_interrupt_disable() writes
CYGNUM_HAL_CORTEXM_PRIORITY_MAX (8) into BASEPRI. But with a priority level of
2, the UART interrupt can still fire.

Some TI MCU will have 16 levels of priority instead of 32 for LPC17XX and the
same problem arises, the priority level bits are always in the upper parts of
IPR0..8.

Note also that the default priority set for all vectors, 128, will be 128>>3=16
at the hardware level. This 128 value is hardcoded in hal_reset_vsr(), that
doesn't call hal_interrupt_set_level().

Fixes:

- have hal_reset_vsr() to store 0xFF instead of 0x80 (fix default priority
level)
- have hal_interrupt_set_level() to write '(l<<3)'
(level+CYGNUM_HAL_CORTEXM_PRIORITY_MAX) instead of 'l'.

Problem 2:

In hal_misc.c for cortexm/lpc17xx, the system tick has priority 0: SHPR3
(stangely SHPR* registers are named differently in eCos and in the doc: ecos's
SHPR2 is NXP/ARM SHPR3...) is set with a priority of zero for system tick,
while SVC is set with priority 255.

This means that using BASEPRI to enable/disable int's won't filter the system
tick since 0 < 8 : this breaks the specification of cyg_interrupt_disable().

Worse, the system tick processing may trigger a context switch calling SVC,
hence triggering an interrupt with a 255 (more likely 31) level priority,
leading to a hard fault.

Possible solutions:

- use PRIMASK instead of BASEPRI for cyg_interrupt_disable/enable since the
goal is to filter all kind of ints without considering priorities (seems the
best).
- have system tick priority set to CYGNUM_HAL_CORTEXM_PRIORITY_MAX + 1

-- 
You are receiving this mail because:
You are the QA Contact for the bug.
You are on the CC list for the bug.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]