这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » MCU » 【互斥访问】如何保证互斥地读写一个寄存器,Exclusively read th

共6条 1/1 1 跳转至

【互斥访问】如何保证互斥地读写一个寄存器,Exclusively read then write a register

菜鸟
2014-04-11 23:23:12     打赏

应用场合:电机控制,脉冲输出,TIM1的CH1和CH2输出2个不同频率的脉冲来控制两个电机。其他TIM有其他用处,因此不能再被使用。

问题描述:

芯片:STM32F103 ZET6

工程中使用TIM1CCR1CCR2作为输出比较模式(在TIM1_CNTTIM1_CCR12匹配时翻转电平,并触发TIM1_CC_IRQHandler中断进行处理,以给定间隔增加CCR1CCR2的值,从而使用TIM1来输出两路不同频率的脉冲信号来控制电机,CCR1每次增加562CCR2每次增加18000)。

测试工程已经添加到附件,直接运行就可以到我设置的断点,表明问题已经出现。

TestPrjTH.rar

问题所在程序段位于测试工程的stm32f10x_it.c文件中,出现问题的代码如下:


void TIM1_CC_IRQHandler(void)
{
    unsigned char test=1;
    unsigned long TIM1_SR_mask;
__TRY_:
    TIM1_SR_mask = __LDREXH(&(TIM1->SR));
    TIM1->SR = 1; //即使不添加这句话,上下两个语句之间仍然可能发生SR被硬件修改的情况。可以根据进入中断test=6来证明。
    if (__STREXH(0,&(TIM1->SR)))
    {
        goto __TRY_; //因为TIM1->SR被修改了,本来应该__STREXH返回失败并进入这个断点的,但是却没有进入。
    }

    //程序段1
    if (TIM1_SR_mask&(1<<1))    //CC1IF
    {
        CCR_Mask_x += CCR_Acc_x;
        TIM1->CCR1 = CCR_Mask_x;
    }
    //程序段2:
    if (TIM1_SR_mask&(1<<2))    //CC2IF
    {
        CCR_Mask_y += CCR_Acc_y;
        TIM1->CCR2 = CCR_Mask_y;
    }

    if (CCR_Mask_x_last2==CCR_Mask_x_last && CCR_Mask_x_last==CCR_Mask_x)
    {
        test = 6;   //进入这个断点,可以说明确实会发生丢失CC1中断的情况。因为CCR1的匹配间隔为562,而CCR2的匹配间隔为18000,正常情况下绝对不会发生连续三次中断里面CCR1都相等的情况。
    }
    CCR_Cnt_last2 = CCR_Cnt_last;
    CCR_Cnt_last = TIM1->CNT;
    CCR_Mask_x_last2 = CCR_Mask_x_last;
    CCR_Mask_x_last = CCR_Mask_x;
}


程序解释:

程序关键代码在于__LDREXH(&(TIM1->SR));__STREXH(0,&(TIM1->SR));

使用互斥的目的是:

在将SR读取到内存变量TIM1_SR_mask中,然后再清零SR,然而在这两个操作之间,硬件仍然会改变SR的值,则TIM1_SR_mask不能如实的反应SR的正真状态。且第二句话又清零了SR,这样SR将无法被还原。

这种情况如下所示:

可能出现的问题


在此请教的问题是:

①如何保证Exclusively Read/Write TIM1_SR?即如何保证先读寄存器TIM1_SR,然后再写TIM1_SR,在此期间是一个独占的访问?按我的理解,可以使用LDREXSTREX来实现这种功能,并写出了上述的代码,但是我的代码没有达到预期的效果。是我使用LDREX/STREX有误吗?

②我做了测试:即在LDREXSTREX之间人为的改变了TIM1->SR的值,按理来说,STREX一定会失败,但是STREX却总是成功的。难道STM32芯片不支持STREX指令?我想应该是我对这个指令的理解不够深刻,请问怎样才能正确使用这对指令来处理我现在的这个情况。

TIM1_SR_mask = __LDREXH(&(TIM1->SR));

TIM1->SR = 1;

__STREXH(0,&(TIM1->SR)); // 应该失败才对,结果还是成功的


谢谢!




关键词: 互斥访问     LDREX     STREX    

工程师
2014-04-12 14:50:22     打赏
2楼
这个完全不会。。

院士
2014-04-12 21:48:02     打赏
3楼

等待高手的出现吧。

楼主的问题实在是没有看懂。有时间再研究吧~~


菜鸟
2014-04-13 20:20:55     打赏
4楼
Up someone please help...

高工
2014-04-13 22:59:44     打赏
5楼

有点头晕......

帮顶吧


菜鸟
2014-04-15 11:28:42     打赏
6楼
啊,木有人知道吗。。。

共6条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]