This is the mail archive of the
ecos-bugs@sourceware.org
mailing list for the eCos project.
[Bug 1002169] New: Broken cyg_interrupt_disable/enable for cortex m3
- From: bugzilla-daemon at ecoscentric dot com
- To: ecos-bugs at ecos dot sourceware dot org
- Date: Sun, 10 Jul 2016 09:21:41 +0000
- Subject: [Bug 1002169] New: Broken cyg_interrupt_disable/enable for cortex m3
- Authentication-results: sourceware.org; auth=none
- Authentication-results: mail.ecoscentric.com; dkim=permerror (bad message/signature format)
- Auto-submitted: auto-generated
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.