Cortex-M0+ 只写带断点的寄存器

Posted

技术标签:

【中文标题】Cortex-M0+ 只写带断点的寄存器【英文标题】:Cortex-M0+ only writes register with breakpoint 【发布时间】:2016-03-13 14:02:22 【问题描述】:

我有一个应用程序,它仅在写入寄存器之前设置断点时才有效。特定的 uC 是 Atmel SAMC21,问题似乎出在写入 GCLK 外设时。我正确写入了 GEN 位,然后设置 CHEN 以启用通道。使用断点可以正确启用。如果没有断点,则在通过 Atmel Studio IO 调试窗口观察时不会设置该位。当未设置该位时(因为它没有计时),此特定通道所连接的 CAN 外围设备会挂起,但如果我设置断点然后允许程序继续运行,则工作正常。它们在代码中没有设置或检查该位的其他位置,并且没有多线程。

违规代码:

// PCHCTRL[26] GCLK_CAN0
GCLK->PCHCTRL[26].bit.GEN = 7;          // Generic clock generator 7
GCLK->PCHCTRL[26].bit.CHEN = 1;         // The peripheral channel is enabled.
GCLK->PCHCTRL[26].bit.WRTLOCK = 0;      // The peripheral channel and the associated generator registers are not locked.

PCHCTRL:

union PCHCTRL 
    uint32_t reg;
    struct bit 
        uint32_t GEN:4;
        uint32_t :2;
        uint32_t CHEN:1;
        uint32_t WRTLOCK:1;
        uint32_t :24;
     bit;
 PCHCTRL[41];

我尝试在两次写入之间插入延迟,但没有成功。非常感谢您对此问题的原因提供任何帮助!

【问题讨论】:

【参考方案1】:

快速浏览一下数据表就会发现(重点是我的):

17.5.8。注册访问保护

所有具有写访问权限的寄存器都可以由外设访问控制器选择性地写保护 (PAC)。

注意: 可选的写保护由寄存器中的“PAC 写保护”属性指示 描述。

当 CPU 在调试模式下停止时,所有写保护都会自动禁用。写保护 不适用于通过外部调试器访问。

因此,听起来很像您的启动代码或应用程序的某些其他部分可能将 PAC 设置为写保护 GCLK,在这种情况下,将需要一些戳才能在修改周围取消保护它.

否则,还有这个:

17.6.3.1。启用外设时钟

在启用外设时钟之前,必须启用其中一个发生器 (GENCTRLn.GENEN) 并且 通过设置外设中的发生器选择位选择作为外设通道的源 通道控制寄存器 (PCHCTRL.GEN)。可以选择任何可用的发生器作为时钟源 每个外围通道。

选择发生器后,通过设置通道使能位来启用外设时钟 外设通道控制寄存器,PCHCTRLm.CHEN = 1。PCHCTRLm.CHEN 位必须为 同步到通用时钟域。 PCHCTRLm.CHEN 将继续读取其先前的状态 直到同步完成。

这表明如果生成器本身没有正确设置和启用,您可能会看到类似的情况。

【讨论】:

【参考方案2】:

这几乎可以肯定是因为在继续之前没有等待时钟同步(击中断点会导致足够长的延迟以使其发生,CAN 和其他一些设备默认情况下不会冻结在断点上)。它需要类似这样的东西来等待时钟同步:

// Set GCLK_CAN0 to use GCLK generator 8
PCHCTRL26 |= PCHCTRL_CHEN | PCHCTRL_GEN_8; // Bit 6 is CHEN, GEN[3:0] set to 8 = GCLK generator 8
while ((PCHCTRL26 & PCHCTRL_CHEN) == 0)   // Wait for sync
    // Spin

【讨论】:

以上是关于Cortex-M0+ 只写带断点的寄存器的主要内容,如果未能解决你的问题,请参考以下文章

在Hardfault期间,ARM Cortex-M0堆栈寄存器是以$ psp还是$ msp保存?

Cortex-M0指令集——ADC

Cortex-M0指令集——ASR

Cortex-M0指令集——CMN

Cortex-M0指令集——EOR

arm cortex-m0plus源码学习GPIO