[英]Atmel Cortex-M0+ SAMC21 hangs after SysTick_Config
So, I have recently acquired a SAMC21 Xplained dev board to begin trying to learn to program for ARM. 因此,我最近购买了SAMC21 Xplained开发板,开始尝试学习ARM编程。 My previous experience is predominantly with PIC's.
我以前的经验主要是在PIC方面。 As an example application I have started an ASF Board project targeting the SAMC21 Xplained board and written the following main function:
作为一个示例应用程序,我已经启动了一个针对SAMC21 Xplained板的ASF板项目,并编写了以下主要功能:
#include <asf.h>
#include <stdbool.h>
int main (void) {
system_init();
SysTick_Config(SystemCoreClock/1000);
system_interrupt_enable(SYSTEM_INTERRUPT_SYSTICK);
while(true);
}
void SysTick_Handler(void) {
port_pin_toggle_output_level(LED_0_PIN);
}
When I start debugging I successfully reach main and execute the system_init() function. 当我开始调试时,我成功到达main并执行system_init()函数。 After that, the program counter hangs forever.
之后,程序计数器将永远挂起。 The Disassembly looks like this:
反汇编如下所示:
int main (void) {
000004D0 ??? Memory out of bounds or read error
system_init();
000004D2 ldr r3, #60
000004D4 blx r3
SysTick_Config(SystemCoreClock/1000);
000004D6 ldr r3, #60
000004D8 ldr r0, [r3]
000004DA movs r1, #250
000004DC lsls r1, r1, #2
000004DE ldr r3, #56
000004E0 blx r3
if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */
000004E2 subs r0, #1
000004E4 ldr r3, #52
000004E6 cmp r0, r3
000004E8 bhi #26
SysTick->LOAD = ticks - 1; /* set reload register */
000004EA ldr r3, #52
000004EC str r0, [r3, #4]
SCB->SHP[_SHP_IDX(IRQn)] = (SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) |
000004EE ldr r2, #52
000004F0 ldr r0, [r2, #32]
000004F2 lsls r0, r0, #8
000004F4 lsrs r0, r0, #8
000004F6 movs r1, #192
000004F8 lsls r1, r1, #24
000004FA orrs r1, r0
000004FC str r1, [r2, #32]
SysTick->VAL = 0; /* Load the SysTick Counter Value */
000004FE movs r2, #0
00000500 str r2, [r3, #8]
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
00000502 movs r2, #7
00000504 str r2, [r3]
NVIC->ISER[0] = (uint32_t)(1 << ((uint32_t)vector & 0x0000001f));
00000506 movs r2, #128
00000508 lsls r2, r2, #24
0000050A ldr r3, #28
0000050C str r2, [r3]
0000050E b #-4 // Debugger PC Hangs
00000510 lsls r1, r2, #16
00000512 movs r0, r0
00000514 movs r4, r0
00000516 movs r0, #0
00000518 lsls r1, r7, #20
0000051A movs r0, r0
0000051C ??? Memory out of bounds or read error
0000051E lsls r7, r7, #3
00000520 b #32
00000522 b #0
00000524 ??? Memory out of bounds or read error
00000526 b #0
00000528 b #512
0000052A b #0
port_base->OUTTGL.reg = pin_mask;
0000052C movs r2, #128
0000052E lsls r2, r2, #8
00000530 movs r3, #130
00000532 lsls r3, r3, #23
00000534 str r2, [r3, #28]
}
00000536 bx lr
I've added a comment to the line where the PC hangs ( 0x0000050E
). 我在PC挂起的行(
0x0000050E
)上添加了注释。 I'm confused because it looks like the b #-4
assembly instruction is behaving correctly by repeatedly branching to itself. 我很困惑,因为它看起来像
b #-4
汇编指令通过反复分支到自身来表现正确。 What I don't understand is why it's there in the first place. 我不明白的是为什么它首先存在。
EDIT First off, thank you to everyone for the responses! 编辑首先,谢谢大家的回应! Secondly, I should have included more of the code (sorry about that ) but wasn't sure what was relevant.
其次,我应该包含更多的代码(对此感到抱歉),但是不确定什么是相关的。 I have edited my code above to show the entire main.c file.
我已经在上面编辑了代码,以显示整个main.c文件。 It almost looks like the while(true) has been misplaced in the code, but I'm still struggling to make sense of it.
看起来while(true)在代码中似乎放错了位置,但是我仍然在努力理解它。
Also adding some (hopefully!) useful snippets from my .lss file: 还从我的.lss文件中添加了一些(希望!)有用的代码片段:
00000000 <_sfixed>:
* Initialize the System and update the SystemCoreClock variable.
*/
void SystemInit(void)
{
// Keep the default device state after reset
SystemCoreClock = __SYSTEM_CLOCK;
0: 20002030 .word 0x20002030
4: 00000441 .word 0x00000441
return;
}
8: 0000043d .word 0x0000043d
c: 0000043d .word 0x0000043d
...
2c: 0000043d .word 0x0000043d
...
38: 0000043d .word 0x0000043d
3c: 0000052d .word 0x0000052d
40: 0000043d .word 0x0000043d
44: 0000043d .word 0x0000043d
48: 0000043d .word 0x0000043d
4c: 0000043d .word 0x0000043d
50: 0000043d .word 0x0000043d
54: 0000043d .word 0x0000043d
58: 0000043d .word 0x0000043d
5c: 0000043d .word 0x0000043d
60: 0000043d .word 0x0000043d
64: 0000043d .word 0x0000043d
68: 0000043d .word 0x0000043d
6c: 0000043d .word 0x0000043d
70: 0000043d .word 0x0000043d
74: 0000043d .word 0x0000043d
78: 0000043d .word 0x0000043d
7c: 0000043d .word 0x0000043d
80: 0000043d .word 0x0000043d
84: 0000043d .word 0x0000043d
88: 0000043d .word 0x0000043d
8c: 0000043d .word 0x0000043d
90: 0000043d .word 0x0000043d
94: 0000043d .word 0x0000043d
98: 0000043d .word 0x0000043d
9c: 0000043d .word 0x0000043d
a0: 0000043d .word 0x0000043d
a4: 0000043d .word 0x0000043d
a8: 0000043d .word 0x0000043d
ac: 0000043d .word 0x0000043d
b0: 0000043d .word 0x0000043d
b4: 0000043d .word 0x0000043d
b8: 0000043d .word 0x0000043d
000004d0 <main>:
#include <asf.h>
#include <stdbool.h>
int main (void) {
4d0: b508 push {r3, lr}
system_init();
4d2: 4b0f ldr r3, [pc, #60] ; (510 <main+0x40>)
4d4: 4798 blx r3
SysTick_Config(SystemCoreClock/1000);
4d6: 4b0f ldr r3, [pc, #60] ; (514 <main+0x44>)
4d8: 6818 ldr r0, [r3, #0]
4da: 21fa movs r1, #250 ; 0xfa
4dc: 0089 lsls r1, r1, #2
4de: 4b0e ldr r3, [pc, #56] ; (518 <main+0x48>)
4e0: 4798 blx r3
must contain a vendor-specific implementation of this function.
*/
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{
if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */
4e2: 3801 subs r0, #1
4e4: 4b0d ldr r3, [pc, #52] ; (51c <main+0x4c>)
4e6: 4298 cmp r0, r3
4e8: d80d bhi.n 506 <main+0x36>
SysTick->LOAD = ticks - 1; /* set reload register */
4ea: 4b0d ldr r3, [pc, #52] ; (520 <main+0x50>)
4ec: 6058 str r0, [r3, #4]
\param [in] priority Priority to set.
*/
__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
{
if(IRQn < 0) {
SCB->SHP[_SHP_IDX(IRQn)] = (SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) |
4ee: 4a0d ldr r2, [pc, #52] ; (524 <main+0x54>)
4f0: 6a10 ldr r0, [r2, #32]
4f2: 0200 lsls r0, r0, #8
4f4: 0a00 lsrs r0, r0, #8
4f6: 21c0 movs r1, #192 ; 0xc0
4f8: 0609 lsls r1, r1, #24
4fa: 4301 orrs r1, r0
4fc: 6211 str r1, [r2, #32]
{
if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */
SysTick->LOAD = ticks - 1; /* set reload register */
NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Systick Interrupt */
SysTick->VAL = 0; /* Load the SysTick Counter Value */
4fe: 2200 movs r2, #0
500: 609a str r2, [r3, #8]
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
502: 2207 movs r2, #7
504: 601a str r2, [r3, #0]
* \param[in] vector Interrupt vector to enable
*/
static inline void system_interrupt_enable(
const enum system_interrupt_vector vector)
{
NVIC->ISER[0] = (uint32_t)(1 << ((uint32_t)vector & 0x0000001f));
506: 2280 movs r2, #128 ; 0x80
508: 0612 lsls r2, r2, #24
50a: 4b07 ldr r3, [pc, #28] ; (528 <main+0x58>)
50c: 601a str r2, [r3, #0]
50e: e7fe b.n 50e <main+0x3e>
510: 00000411 .word 0x00000411
514: 20000004 .word 0x20000004
518: 00000539 .word 0x00000539
51c: 00ffffff .word 0x00ffffff
520: e000e010 .word 0xe000e010
524: e000ed00 .word 0xe000ed00
528: e000e100 .word 0xe000e100
0000052c <SysTick_Handler>:
{
PortGroup *const port_base = port_get_group_from_gpio_pin(gpio_pin);
uint32_t pin_mask = (1UL << (gpio_pin % 32));
/* Toggle pin output level */
port_base->OUTTGL.reg = pin_mask;
52c: 2280 movs r2, #128 ; 0x80
52e: 0212 lsls r2, r2, #8
530: 2382 movs r3, #130 ; 0x82
532: 05db lsls r3, r3, #23
534: 61da str r2, [r3, #28]
while(true);
}
void SysTick_Handler(void) {
port_pin_toggle_output_level(LED_0_PIN);
}
536: 4770 bx lr
Recently faced same systick issue. 最近面临着同样的问题。 On analyzing and changing the linker script (.ld) the problem got resolved.
通过分析和更改链接描述文件(.ld),问题得以解决。 I was using a custom linker script.
我正在使用自定义链接描述文件。 Check your linker script, MSR, vector address (at location 0x0000003C)
检查链接描述文件,MSR,向量地址(在位置0x0000003C)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.