简体   繁体   English

SysTick_Config后,Atmel Cortex-M0 + SAMC21挂起

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM