c - Atmel Cortex-M0+ SAMC21 在 SysTick_Config 之后挂起

标签 c arm microcontroller atmel cortex-m

所以,我最近购买了一 block SAMC21 Xplained 开发板,开始尝试学习 ARM 编程。我以前的经验主要是与 PIC 相关。作为示例应用程序,我启动了一个针对 SAMC21 Xplained 板的 ASF Board 项目,并编写了以下主要函数:

#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);
}

当我开始调试时,我成功到达 main 并执行 system_init() 函数。此后,程序计数器将永远挂起。反汇编如下所示:

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

我已向 PC 挂起的行添加了注释 (0x0000050E)。我很困惑,因为看起来 b #-4 汇编指令通过重复分支到自身而表现正确。我不明白的是为什么它首先存在。

编辑 首先感谢大家的热心回复!其次,我应该包含更多的代码(对此感到抱歉),但不确定哪些是相关的。我已经编辑了上面的代码以显示整个 main.c 文件。看起来代码中的 while(true) 几乎被放错了地方,但我仍然在努力理解它。

还从我的 .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

最佳答案

最近遇到了同样的系统问题。通过分析和更改链接描述文件 (.ld),问题得到了解决。我正在使用自定义链接器脚本。 检查您的链接器脚本、MSR、 vector 地址(位于位置 0x0000003C)

关于c - Atmel Cortex-M0+ SAMC21 在 SysTick_Config 之后挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32333739/

相关文章:

c - 在格式化输出函数中使用 $

c - 结构体中的指针值发生变化而不重新分配

c - 如何在 Linux 中使用 SDL?

android - 如何强制 Cmake 执行多组件依赖的顶级 CMakeLists.txt?

arm - 如何使用适用于 ARM 的 IAR 编译器编译 Google Test

c - For LOOP 被编译器优化丢弃

assembly - DCD指令和IRQ堆栈

assembly - 有人能解释一下 LDRD ARM 指令是如何工作的吗?

android - 识别android中的DTMF音调

c - STM32 USB CDC 不工作