首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >这是在PIC24上禁用中断的安全方法吗?

这是在PIC24上禁用中断的安全方法吗?
EN

Stack Overflow用户
提问于 2020-07-01 17:00:52
回答 1查看 861关注 0票数 3

我正在做一个使用微芯片PIC24FJ256GA702的项目。几天来,我一直在寻找一个带有UART代码的间歇性错误。它使用中断服务例程(ISR)传输名为char txBuff[]的缓冲区及其长度int txLen

在主代码(即非ISR)中,我偶尔访问缓冲区以添加字节或查看要传输的字节数。为了确保主代码看到缓冲区的干净副本,它在表单中有一个关键部分:

代码语言:javascript
复制
Disable interrupts
Read and write 'txBuff' and its length 'txLen'
Enable interrupt

在此PIC上有几种禁用ISR的方法。包括:使用DISI指令,或清除GIE位,或更改中断优先级级别。

但我选择清除中断,以启用IECx中特定中断位的位。在本例中,它是IEC1bits.U2TXIE,因为我使用的是UART2。我这么做是因为它很简单,它不会禁用不相关的中断,而且它在我的其他项目中一直运行良好。所以在C中,关键部分是:

代码语言:javascript
复制
IEC1bits.U2TXIE = 0;
copyOfTxLen = txLen;
...
IEC1bits.U2TXIE = 1;

拆卸清单开始:

代码语言:javascript
复制
 BCLR 0x9B, #7 // disable interrupt
 MOV txLen, W1 // read txLen
...

The problem:我现在相当肯定的是,ISR在read txLen期间偶尔会被调用,这样copyOfTxLen最终会成为调用ISR之前的txLen值,但是关键部分的其余部分会看到在调用ISR之后它们所处状态的变量。

问题:我的代码有问题吗?如果是这样,怎样才能避免错误呢?

一些背景:

  • UART以高速(250 kBaud)的速度运行,PIC24时钟为8 MHz,每160个指令一个字节,因此ISR相当繁忙,我认为与以前的项目相比,这增加了进入竞赛状态的机会。
  • 我看到了dsPIC33 33/PIC24 24家庭参考手册/中断,第2.3.1Note 2节说:“在清除GIE位和禁用中断之间有一个周期延迟。”这指的是GIE,而不是U2TXIE,我不确定它是否会像我看到的那样导致问题,因为MOV指令是一个2周期指令。但无论如何,这似乎是一种狡猾的方法来诱捕粗心大意的程序员。
  • 如果我尝试调试它或添加任何调试代码,那么已经非常间歇性的问题就会消失(感觉就像一种竞赛条件)。我不想仅仅添加一些NOP,而不知道我为什么要这样做,因为除非您确实修复了它们,否则竞争条件总是会对您不利。
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-07-02 11:25:17

问题中的代码是错误的。若要修复此问题,请将用于禁用中断(如IEC1bits.U2TXIE = 0 )的表达式包装在宏中,如下所示:

代码语言:javascript
复制
__write_to_IEC(IEC1bits.U2TXIE = 0);

XC16编译器发布说明说:

__write_to_IEC(X) -一个宏,它用适当数量的nop指令包装表达式X,以确保对IEC寄存器的写入在程序执行之前生效。例如,__write_to_IEC(IEC0bits.T1IE = 0);将在设备禁用中断启用位( T1,Timer1)之前不会进行。

在与p24FJ256GA702.h编译器一起提供的XC16中,定义了宏:

代码语言:javascript
复制
#define __write_to_IEC(X) \
   ( (void)(X), \
     __builtin_nop() \
   )

因此,尽管在PIC24FJ256GA705族数据表单独中断文档中没有提到任何地方,但显然这里需要一个NOP

更新:我在dsPIC33EP256MU806 (dsPIC33E系列)上发现了同样的问题,它需要两个NOP指令。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62681838

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档