Skip to content

Commit 240060e

Browse files
committed
Modify IRQ handler processing without RTOS at Cortex-A ARM Compiler
In case of unusing RTOS, IRQ handler executes "while(1)" and it causes a program freeze. Therefore, I revised this processing. Also I added the heap setting processing and set the align to 8 byte.
1 parent 442cbba commit 240060e

File tree

8 files changed

+258
-50
lines changed

8 files changed

+258
-50
lines changed

targets/TARGET_RENESAS/TARGET_RZ_A1XX/TARGET_GR_LYCHEE/device/TOOLCHAIN_ARM_STD/MBRZA1LU.sct

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ LR_IROM1 MBED_APP_START MBED_APP_SIZE ; load region size_region
7272
RW_IRAM1 +0 ALIGN 0x10
7373
{ * (+ZI) } ; Application ZI data (.bss)
7474

75-
ARM_LIB_HEAP +0
75+
ARM_LIB_HEAP +0 ALIGN 0x8
7676
{ * (HEAP) } ; Application heap area (HEAP)
7777

7878
ARM_LIB_STACK (__RAM_BASE + __NM_RAM_SIZE) EMPTY -__STACK_SIZE ; Stack region growing down

targets/TARGET_RENESAS/TARGET_RZ_A1XX/TARGET_GR_LYCHEE/device/TOOLCHAIN_ARM_STD/startup_RZ_A1LU.c

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -45,16 +45,6 @@
4545
void Vectors (void) __attribute__ ((section("RESET")));
4646
void Reset_Handler(void);
4747

48-
/*----------------------------------------------------------------------------
49-
Exception / Interrupt Handler
50-
*----------------------------------------------------------------------------*/
51-
void Undef_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
52-
void SVC_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
53-
void PAbt_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
54-
void DAbt_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
55-
void IRQ_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
56-
void FIQ_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
57-
5848
/*----------------------------------------------------------------------------
5949
Exception / Interrupt Vector Table
6050
*----------------------------------------------------------------------------*/
@@ -153,10 +143,3 @@ goToSleep
153143
IMPORT __main
154144
BL __main
155145
}
156-
157-
/*----------------------------------------------------------------------------
158-
Default Handler for Exceptions / Interrupts
159-
*----------------------------------------------------------------------------*/
160-
void Default_Handler(void) {
161-
while(1);
162-
}

targets/TARGET_RENESAS/TARGET_RZ_A1XX/TARGET_GR_LYCHEE/device/TOOLCHAIN_ARM_STD/sys.cpp

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,17 +45,54 @@ extern char Image$$ARM_LIB_HEAP$$Base[];
4545
extern char Image$$ARM_LIB_STACK$$Base[];
4646

4747
extern __value_in_regs struct __initial_stackheap _mbed_user_setup_stackheap(uint32_t R0, uint32_t R1, uint32_t R2, uint32_t R3) {
48-
uint32_t zi_limit = (uint32_t)Image$$ARM_LIB_HEAP$$Base;
49-
uint32_t sp_limit = (uint32_t)Image$$ARM_LIB_STACK$$Base;
50-
51-
zi_limit = (zi_limit + 7) & ~0x7; // ensure zi_limit is 8-byte aligned
52-
5348
struct __initial_stackheap r;
54-
r.heap_base = zi_limit;
55-
r.heap_limit = sp_limit;
49+
r.heap_base = (uint32_t)Image$$ARM_LIB_HEAP$$Base;
50+
r.heap_limit = (uint32_t)Image$$ARM_LIB_STACK$$Base;
5651
return r;
5752
}
5853

54+
#if !defined(MBED_CONF_RTOS_PRESENT) || !MBED_CONF_RTOS_PRESENT
55+
56+
/* The single region memory model would check stack collision at run time, verifying that
57+
* the heap pointer is underneath the stack pointer. With two-region memory model/RTOS-less or
58+
* multiple threads(stacks)/RTOS, the check gets meaningless and we must disable it. */
59+
#if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
60+
__asm(".global __use_two_region_memory\n\t");
61+
__asm(".global __use_no_semihosting\n\t");
62+
#else
63+
#pragma import(__use_two_region_memory)
64+
#endif
65+
66+
/* Fix __user_setup_stackheap and ARM_LIB_STACK/ARM_LIB_HEAP cannot co-exist in RTOS-less build
67+
*
68+
* According AN241 (http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dai0241b/index.html),
69+
* __rt_entry has the following call sequence:
70+
* 1. _platform_pre_stackheap_init
71+
* 2. __user_setup_stackheap or setup the Stack Pointer (SP) by another method
72+
* 3. _platform_post_stackheap_init
73+
* 4. __rt_lib_init
74+
* 5. _platform_post_lib_init
75+
* 6. main()
76+
* 7. exit()
77+
*
78+
* Per our check, when __user_setup_stackheap and ARM_LIB_STACK/ARM_LIB_HEAP co-exist, neither
79+
* does __user_setup_stackheap get called and nor is ARM_LIB_HEAP used to get heap base/limit,
80+
* which are required to pass to __rt_lib_init later. To fix the issue, by subclass'ing
81+
* __rt_lib_init, heap base/limit are replaced with Image$$ARM_LIB_HEAP$$ZI$$Base/Limit if
82+
* ARM_LIB_HEAP region is defined in scatter file.
83+
*
84+
* The overriding __rt_lib_init is needed only for rtos-less code. For rtos code, __rt_entry is
85+
* overridden and the overriding __rt_lib_init here gets meaningless.
86+
*/
87+
extern __value_in_regs struct __argc_argv $Super$$__rt_lib_init(unsigned heapbase, unsigned heaptop);
88+
89+
__value_in_regs struct __argc_argv $Sub$$__rt_lib_init (unsigned heapbase, unsigned heaptop)
90+
{
91+
return $Super$$__rt_lib_init((unsigned)Image$$ARM_LIB_HEAP$$Base, (unsigned)Image$$ARM_LIB_STACK$$Base);
92+
}
93+
94+
#endif
95+
5996
#ifdef __cplusplus
6097
}
6198
#endif
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/*
2+
* Copyright (c) 2013-2018 Arm Limited. All rights reserved.
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the License); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
14+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*
18+
* -----------------------------------------------------------------------------
19+
*
20+
* Project: CMSIS-RTOS RTX
21+
* Title: Cortex-A Exception handlers
22+
*
23+
* -----------------------------------------------------------------------------
24+
*/
25+
26+
#include "core_ca.h"
27+
28+
#define MODE_SVC 0x13
29+
30+
/*----------------------------------------------------------------------------
31+
Exception / Interrupt Handler
32+
*----------------------------------------------------------------------------*/
33+
void Undef_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
34+
void SVC_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
35+
void PAbt_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
36+
void DAbt_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
37+
void FIQ_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
38+
39+
/*----------------------------------------------------------------------------
40+
Default Handler for Exceptions / Interrupts
41+
*----------------------------------------------------------------------------*/
42+
void Default_Handler(void) {
43+
while(1);
44+
}
45+
46+
/*----------------------------------------------------------------------------
47+
Default IRQ Handler for Exceptions / Interrupts
48+
*----------------------------------------------------------------------------*/
49+
__WEAK __ASM void IRQ_Handler(void) {
50+
IMPORT IRQ_GetActiveIRQ
51+
IMPORT IRQ_GetHandler
52+
IMPORT IRQ_EndOfInterrupt
53+
54+
SUB LR, LR, #4 // Pre-adjust LR
55+
SRSFD SP!, #MODE_SVC // Save LR_irq and SPSR_irq on to the SVC stack
56+
CPS #MODE_SVC // Change to SVC mode
57+
PUSH {R0-R3, R12, LR} // Save APCS corruptible registers
58+
59+
MOV R3, SP // Move SP into R3
60+
AND R3, R3, #4 // Get stack adjustment to ensure 8-byte alignment
61+
SUB SP, SP, R3 // Adjust stack
62+
PUSH {R3, R4} // Store stack adjustment(R3) and user data(R4)
63+
64+
BLX IRQ_GetActiveIRQ // Retrieve interrupt ID into R0
65+
MOV R4, R0 // Move interrupt ID to R4
66+
67+
BLX IRQ_GetHandler // Retrieve interrupt handler address for current ID
68+
CMP R0, #0 // Check if handler address is 0
69+
BEQ IRQ_End // If 0, end interrupt and return
70+
71+
CPSIE i // Re-enable interrupts
72+
BLX R0 // Call IRQ handler
73+
CPSID i // Disable interrupts
74+
75+
IRQ_End
76+
MOV R0, R4 // Move interrupt ID to R0
77+
BLX IRQ_EndOfInterrupt // Signal end of interrupt
78+
79+
POP {R3, R4} // Restore stack adjustment(R3) and user data(R4)
80+
ADD SP, SP, R3 // Unadjust stack
81+
82+
POP {R0-R3, R12, LR} // Restore stacked APCS registers
83+
RFEFD SP! // Return from IRQ handler
84+
}

targets/TARGET_RENESAS/TARGET_RZ_A1XX/TARGET_RZ_A1H/device/TOOLCHAIN_ARM_STD/MBRZA1H.sct

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ LR_IROM1 MBED_APP_START MBED_APP_SIZE ; load region size_region
7272
RW_IRAM1 +0 ALIGN 0x10
7373
{ * (+ZI) } ; Application ZI data (.bss)
7474

75-
ARM_LIB_HEAP +0
75+
ARM_LIB_HEAP +0 ALIGN 0x8
7676
{ * (HEAP) } ; Application heap area (HEAP)
7777

7878
ARM_LIB_STACK (__RAM_BASE + __NM_RAM_SIZE) EMPTY -__STACK_SIZE ; Stack region growing down

targets/TARGET_RENESAS/TARGET_RZ_A1XX/TARGET_RZ_A1H/device/TOOLCHAIN_ARM_STD/startup_RZ_A1H.c

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -45,16 +45,6 @@
4545
void Vectors (void) __attribute__ ((section("RESET")));
4646
void Reset_Handler(void);
4747

48-
/*----------------------------------------------------------------------------
49-
Exception / Interrupt Handler
50-
*----------------------------------------------------------------------------*/
51-
void Undef_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
52-
void SVC_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
53-
void PAbt_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
54-
void DAbt_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
55-
void IRQ_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
56-
void FIQ_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
57-
5848
/*----------------------------------------------------------------------------
5949
Exception / Interrupt Vector Table
6050
*----------------------------------------------------------------------------*/
@@ -153,10 +143,3 @@ goToSleep
153143
IMPORT __main
154144
BL __main
155145
}
156-
157-
/*----------------------------------------------------------------------------
158-
Default Handler for Exceptions / Interrupts
159-
*----------------------------------------------------------------------------*/
160-
void Default_Handler(void) {
161-
while(1);
162-
}

targets/TARGET_RENESAS/TARGET_RZ_A1XX/TARGET_RZ_A1H/device/TOOLCHAIN_ARM_STD/sys.cpp

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,17 +45,54 @@ extern char Image$$ARM_LIB_HEAP$$Base[];
4545
extern char Image$$ARM_LIB_STACK$$Base[];
4646

4747
extern __value_in_regs struct __initial_stackheap _mbed_user_setup_stackheap(uint32_t R0, uint32_t R1, uint32_t R2, uint32_t R3) {
48-
uint32_t zi_limit = (uint32_t)Image$$ARM_LIB_HEAP$$Base;
49-
uint32_t sp_limit = (uint32_t)Image$$ARM_LIB_STACK$$Base;
50-
51-
zi_limit = (zi_limit + 7) & ~0x7; // ensure zi_limit is 8-byte aligned
52-
5348
struct __initial_stackheap r;
54-
r.heap_base = zi_limit;
55-
r.heap_limit = sp_limit;
49+
r.heap_base = (uint32_t)Image$$ARM_LIB_HEAP$$Base;
50+
r.heap_limit = (uint32_t)Image$$ARM_LIB_STACK$$Base;
5651
return r;
5752
}
5853

54+
#if !defined(MBED_CONF_RTOS_PRESENT) || !MBED_CONF_RTOS_PRESENT
55+
56+
/* The single region memory model would check stack collision at run time, verifying that
57+
* the heap pointer is underneath the stack pointer. With two-region memory model/RTOS-less or
58+
* multiple threads(stacks)/RTOS, the check gets meaningless and we must disable it. */
59+
#if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
60+
__asm(".global __use_two_region_memory\n\t");
61+
__asm(".global __use_no_semihosting\n\t");
62+
#else
63+
#pragma import(__use_two_region_memory)
64+
#endif
65+
66+
/* Fix __user_setup_stackheap and ARM_LIB_STACK/ARM_LIB_HEAP cannot co-exist in RTOS-less build
67+
*
68+
* According AN241 (http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dai0241b/index.html),
69+
* __rt_entry has the following call sequence:
70+
* 1. _platform_pre_stackheap_init
71+
* 2. __user_setup_stackheap or setup the Stack Pointer (SP) by another method
72+
* 3. _platform_post_stackheap_init
73+
* 4. __rt_lib_init
74+
* 5. _platform_post_lib_init
75+
* 6. main()
76+
* 7. exit()
77+
*
78+
* Per our check, when __user_setup_stackheap and ARM_LIB_STACK/ARM_LIB_HEAP co-exist, neither
79+
* does __user_setup_stackheap get called and nor is ARM_LIB_HEAP used to get heap base/limit,
80+
* which are required to pass to __rt_lib_init later. To fix the issue, by subclass'ing
81+
* __rt_lib_init, heap base/limit are replaced with Image$$ARM_LIB_HEAP$$ZI$$Base/Limit if
82+
* ARM_LIB_HEAP region is defined in scatter file.
83+
*
84+
* The overriding __rt_lib_init is needed only for rtos-less code. For rtos code, __rt_entry is
85+
* overridden and the overriding __rt_lib_init here gets meaningless.
86+
*/
87+
extern __value_in_regs struct __argc_argv $Super$$__rt_lib_init(unsigned heapbase, unsigned heaptop);
88+
89+
__value_in_regs struct __argc_argv $Sub$$__rt_lib_init (unsigned heapbase, unsigned heaptop)
90+
{
91+
return $Super$$__rt_lib_init((unsigned)Image$$ARM_LIB_HEAP$$Base, (unsigned)Image$$ARM_LIB_STACK$$Base);
92+
}
93+
94+
#endif
95+
5996
#ifdef __cplusplus
6097
}
6198
#endif
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/*
2+
* Copyright (c) 2013-2018 Arm Limited. All rights reserved.
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the License); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
14+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*
18+
* -----------------------------------------------------------------------------
19+
*
20+
* Project: CMSIS-RTOS RTX
21+
* Title: Cortex-A Exception handlers
22+
*
23+
* -----------------------------------------------------------------------------
24+
*/
25+
26+
#include "core_ca.h"
27+
28+
#define MODE_SVC 0x13
29+
30+
/*----------------------------------------------------------------------------
31+
Exception / Interrupt Handler
32+
*----------------------------------------------------------------------------*/
33+
void Undef_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
34+
void SVC_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
35+
void PAbt_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
36+
void DAbt_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
37+
void FIQ_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
38+
39+
/*----------------------------------------------------------------------------
40+
Default Handler for Exceptions / Interrupts
41+
*----------------------------------------------------------------------------*/
42+
void Default_Handler(void) {
43+
while(1);
44+
}
45+
46+
/*----------------------------------------------------------------------------
47+
Default IRQ Handler for Exceptions / Interrupts
48+
*----------------------------------------------------------------------------*/
49+
__WEAK __ASM void IRQ_Handler(void) {
50+
IMPORT IRQ_GetActiveIRQ
51+
IMPORT IRQ_GetHandler
52+
IMPORT IRQ_EndOfInterrupt
53+
54+
SUB LR, LR, #4 // Pre-adjust LR
55+
SRSFD SP!, #MODE_SVC // Save LR_irq and SPSR_irq on to the SVC stack
56+
CPS #MODE_SVC // Change to SVC mode
57+
PUSH {R0-R3, R12, LR} // Save APCS corruptible registers
58+
59+
MOV R3, SP // Move SP into R3
60+
AND R3, R3, #4 // Get stack adjustment to ensure 8-byte alignment
61+
SUB SP, SP, R3 // Adjust stack
62+
PUSH {R3, R4} // Store stack adjustment(R3) and user data(R4)
63+
64+
BLX IRQ_GetActiveIRQ // Retrieve interrupt ID into R0
65+
MOV R4, R0 // Move interrupt ID to R4
66+
67+
BLX IRQ_GetHandler // Retrieve interrupt handler address for current ID
68+
CMP R0, #0 // Check if handler address is 0
69+
BEQ IRQ_End // If 0, end interrupt and return
70+
71+
CPSIE i // Re-enable interrupts
72+
BLX R0 // Call IRQ handler
73+
CPSID i // Disable interrupts
74+
75+
IRQ_End
76+
MOV R0, R4 // Move interrupt ID to R0
77+
BLX IRQ_EndOfInterrupt // Signal end of interrupt
78+
79+
POP {R3, R4} // Restore stack adjustment(R3) and user data(R4)
80+
ADD SP, SP, R3 // Unadjust stack
81+
82+
POP {R0-R3, R12, LR} // Restore stacked APCS registers
83+
RFEFD SP! // Return from IRQ handler
84+
}

0 commit comments

Comments
 (0)