发新帖本帖赏金 50.00元(功能说明)我要提问
返回列表
打印
[MM32软件]

基于Arm®v8-M架构的MM32系列MCU中关于DWT的应用

[复制链接]
904|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 xld0932 于 2024-11-12 12:55 编辑

#申请原创#   @21小跑堂

1、前言
MM32已经发布了多款基于安谋科技授权的Arm®v8-M 架构“星辰” STAR-MC1内核(兼容 Cortex-M33)处理器,基于STAR-MC1内核,来分享一下有关于DWT的一些常规应用示例,下面以MM32H5480为例。

2、数据监视点和跟踪单元(DWT)
通过MM32H5480芯片的DBG部分的功能框图,我们可以看出其芯片内核带有了数据监视点和跟踪单元(DWT)、指令跟踪宏单元(ITM)、跟踪端口接口单元(TPIU)等等功能;ITM允许通过printf等软件方式生成调试信息,还可以生成时间戳信息,这部分功能,我们在上一篇《MM32H5480通过J-Link实现日志打印的三种方法》有提到;DWT则是可以产生数据跟踪、事件跟踪和概况跟踪信息。

在实际应用的时候,我更多的是使用DWT自带的一个循环计数器来实现精确延时的功能,它可以达到us级别的延时;同时DWT的比较器功能实现对变量或者函数的监测功能,当变量被进行读/写操作或者函数被调用时,可以配置触发DebugMon中断,可以通过DWT的功能实现辅助定位问题。

3、DWT延时功能
首先DWT是属于调试和跟踪部分单元的功能,所以在使用DWT之前我们需要通过配置寄存器来开启这部分功能使能,通过配置DEMCU寄存器的TRCENA位,将这一位置1即可,如下所示:

然后配置DWT_CTRL寄存器,将CYCCNTENA这一位置1,开启DWT的计数功能;在使能CYCCNTENA之前,我们需要将DWT的CYCCNT计数值先清零,如下所示:

代码实现如下:
void PLATFORM_InitDelay(void)
{
    DCB->DEMCR &= ~DCB_DEMCR_TRCENA_Msk;
    DWT->CTRL  &= ~DWT_CTRL_CYCCNTENA_Msk;

    DCB->DEMCR |= DCB_DEMCR_TRCENA_Msk;

    DWT->CYCCNT = 0;
    DWT->CTRL  |= DWT_CTRL_CYCCNTENA_Msk;
}

void PLATFORM_DelayUS(uint32_t us)
{
    uint32_t Start = DWT->CYCCNT;
    uint32_t Count = SystemCoreClock / 1000000 * us;

    while ((DWT->CYCCNT - Start) < Count)
    {
    }
}

void PLATFORM_DelayMS(uint32_t ms)
{
    uint32_t Start = DWT->CYCCNT;
    uint32_t Count = SystemCoreClock / 1000 * ms;

    while ((DWT->CYCCNT - Start) < Count)
    {
    }
}

4、DWT比较器功能
通过将DWT_CTRL寄存器的NUMCOMP位的值打印出来,知晓,MM32H5480最多可设置4个数据监视点、数据跟踪或比较器的功能。通过配置DWT_COMP比较寄存器来确定比较对象,通过配置DWT_FUNCTION寄存器来确定比较的属性。需要注意的是,一定要先设置DWT_COMP之后再配置DWT_FUNCTION寄存器,如果是更新DWT_COMP寄存器,则需要先将DWT_FUNCTION寄存器先配置为0,才可以更新;第二个需要注意的是在MCU与调试器断开的时候,DWT的监测功能能够正常运行,如果在MCU与调试器处于连接的状态时,DWT的监测功能可能会跟调试器产生冲突,这个在使用的时候需要注意!!!

下面示例中配置了通过DWT来监测一个变量的写入/赋值操作,和一个函数被调用的监测;当这个被监测变量的值发生改变时,通过配置会产生DebugMon中断;当这个被监测的函数被调用时,通过配置会产生DebugMon中断,具体代码如下所示:
extern uint32_t DWT_TestVar;

void PLATFORM_InitDelay(void)
{
    DCB->DEMCR &= ~(DCB_DEMCR_TRCENA_Msk | DCB_DEMCR_MON_EN_Msk);
    DWT->CTRL  &= ~DWT_CTRL_CYCCNTENA_Msk;

    DCB->DEMCR |= (DCB_DEMCR_TRCENA_Msk | DCB_DEMCR_MON_EN_Msk);

    DWT->COMP0     = (uint32_t)&DWT_TestVar;
    DWT->FUNCTION0 = (8 << DWT_FUNCTION_ID_Pos)         |   /* Data Address, and Data Address With Value */
                     (2 << DWT_FUNCTION_DATAVSIZE_Pos)  |   /* 4 bytes */
                     (1 << DWT_FUNCTION_ACTION_Pos)     |   /* Generate debug event */
                     (5 << DWT_FUNCTION_MATCH_Pos);         /* Data Address, writes */

    DWT->COMP1     = (uint32_t)(PLATFORM_DelayMS - 1);
    DWT->FUNCTION1 = (10 << DWT_FUNCTION_ID_Pos)        |   /* Instruction Address, Data Address, and Data Address With Value */
                     (1  << DWT_FUNCTION_DATAVSIZE_Pos) |   /* 2 bytes */
                     (1  << DWT_FUNCTION_ACTION_Pos)    |   /* Generate debug event */
                     (2  << DWT_FUNCTION_MATCH_Pos);        /* Instruction Address  */

    DWT->CYCCNT = 0;
    DWT->CTRL  |= DWT_CTRL_CYCCNTENA_Msk;

    printf("\r\nDWT_CTRL->NUMCOMP : %ld", (DWT->CTRL & DWT_CTRL_NUMCOMP_Msk) >> DWT_CTRL_NUMCOMP_Pos);
}
uint32_t DWT_TestVar = 0;

int main(void)
{
    PLATFORM_Init();

    BSP_LED_Init();

    while (1)
    {
        GPIO_WriteBit(GPIOA, GPIO_Pin_9,  Bit_RESET);
        GPIO_WriteBit(GPIOA, GPIO_Pin_10, Bit_RESET);

        PLATFORM_DelayMS(1000);

        GPIO_WriteBit(GPIOA, GPIO_Pin_9,  Bit_SET);
        GPIO_WriteBit(GPIOA, GPIO_Pin_10, Bit_SET);

        PLATFORM_DelayMS(1000);

        DWT_TestVar++;
    }
}
void DebugMon_Handler(void)
{
    if ((DWT->FUNCTION0 & DWT_FUNCTION_MATCHED_Msk) != 0)   /* This bit is read-only and this bit clears to zero when read */
    {
        printf("\r\nDebugMon interrupt comparator 0.");
    }

    if ((DWT->FUNCTION1 & DWT_FUNCTION_MATCHED_Msk) != 0)
    {
        printf("\r\nDebugMon interrupt comparator 1.");
    }
}
运行结果:


5、附件
测试程序: Project.zip (1.09 MB)
参考文献: ARMv8-M Architecture Reference Manual B.x.PDF (12.31 MB)

补充说明:
有细心我网友会发现在上面运行结果的截图中,有2个计算公式及结果的打印,举例了5-20的结果相对于256-20+5的结果,所计算出来的值是一样的,而验证这个的目的是DWT的CYCCNT是一个32位循环计数器,当溢出后又会从0开始计算,所以对于延时函数中的写法做了一个验证。

使用特权

评论回复
沙发
weifeng90| | 2024-11-14 17:26 | 只看该作者
MC1内核有啥特殊之处,感觉ARM现在的内核版本太多了

使用特权

评论回复
板凳
xld0932|  楼主 | 2024-11-14 17:55 | 只看该作者
weifeng90 发表于 2024-11-14 17:26
MC1内核有啥特殊之处,感觉ARM现在的内核版本太多了

‌ARM STAR-MC1处理器与Cortex-M系列处理器在多个方面存在显著差异,主要体现在架构、性能、功耗和安全性等方面。‌

架构差异
‌ARM STAR-MC1‌:基于Armv8-M架构,这是ARM最新的架构,提供了更高的性能和更强的安全性。它支持TrustZone安全技术,能够在安全区和非安全区之间隔离运行环境,保护敏感程序的安全性‌。
‌Cortex-M系列‌:包括Cortex-M0, Cortex-M3, Cortex-M4, 和Cortex-M7等,这些处理器基于Armv7-M架构。Cortex-M23和Cortex-M33是Cortex-M系列的最新成员,基于Armv8-M架构,主打超低功耗和高性能‌。

性能差异
‌ARM STAR-MC1‌:性能指标为1.5DMIPS/MHz到4.02Coremark/MHz,相比上一代Cortex-M4处理器,在同一主频下性能提升20%‌。
‌Cortex-M33‌:作为Cortex-M系列的最新成员,Cortex-M33在性能、功耗和安全性之间达到了最佳平衡。它支持DSP浮点运算和TrustZone安全技术,适用于需要高性能和安全性的应用场景‌。

功耗差异
‌ARM STAR-MC1‌:采用有序三阶管线技术,显著降低系统功耗‌。
‌Cortex-M23‌:主打超低功耗,是Cortex-M0+的继任者,适用于需要极低功耗的应用场景‌。

应用场景差异
‌ARM STAR-MC1‌:适用于高端应用市场,如工业控制、汽车、物联网等,具有高性能和安全性优势‌。
‌Cortex-M系列‌:适用于多种嵌入式设计细分市场,包括物联网、电机控制、医疗、汽车、家电自动化等。Cortex-M23和Cortex-M33特别适用于需要高性能和安全性的应用场景‌。

综上所述,ARM STAR-MC1在性能和安全性方面具有显著优势,适用于高端应用市场;而Cortex-M系列则覆盖更广泛的嵌入式设计需求,包括低功耗和高性能的应用场景。



使用特权

评论回复

打赏榜单

21小跑堂 打赏了 50.00 元 2024-11-18
理由:恭喜通过原创审核!期待您更多的原创作品~~

评论
21小跑堂 2024-11-18 15:07 回复TA
基于STAR-MC1内核的MM32H5480 MCU中的DWT常规应用示例,详细介绍了DWT的功能和常用的几种功能演示。非常有助于开发调试,值得参考学习。 
发新帖 本帖赏金 50.00元(功能说明)我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

认证:上海灵动微电子股份有限公司资深现场应用工程师
简介:诚信·承诺·创新·合作

70

主题

3001

帖子

31

粉丝