c - 写入安全的 UART 中断缓冲区
问题描述
我知道易失性键盘,它不能确保同步安全。
以下代码在中断例程中使用,我大量使用该函数
GetCharUART 在主循环中。
编写这样的代码是否安全且稳定?或者我必须像互斥锁一样进行低级同步,如果这是真的,我将如何保护那个 rbuf ?
volatile char rbuf[5][UART_BUFSIZE];
vu16 rin[5] = { 0, 0, 0, 0, 0 };
vu16 rout[5] = { 0, 0, 0, 0, 0 };
void USART_IRQHandler(char Channel, USART_TypeDef *USARTx)
{
volatile unsigned int IIR;
IIR = USARTx->SR;
if (IIR & USART_FLAG_RXNE)
{ // read interrupt
USARTx->SR &= ~USART_FLAG_RXNE; // clear interrupt
rbuf[Channel][rin[Channel]] = USART_ReceiveData(USARTx);
rin[Channel]++;
if(rin[Channel]>=UART_BUFSIZE) rin[Channel]=0;
}
if (IIR & USART_FLAG_TXE)
{
USARTx->SR &= ~USART_FLAG_TXE; // clear interrupt
}
}
int GetCharUART (char Channel)
{
int result;
if (rin[Channel]==rout[Channel]) {
return EMPTY;
}
result=rbuf[Channel][rout[Channel]];
rout[Channel]++;
if(rout[Channel]>=UART_BUFSIZE)
rout[Channel]=0;
return result;
}
修改后的代码:
void USART_IRQHandler(char Channel, USART_TypeDef *USARTx)
{
volatile unsigned int IIR;
IIR = USARTx->SR;
if (IIR & USART_FLAG_RXNE)
{ // read interrupt
USARTx->SR &= ~USART_FLAG_RXNE; // clear interrupt
rbuf[Channel][rin[Channel]% UART_BUFSIZE] = USART_ReceiveData(USARTx);
rin[Channel]++;
}
if (IIR & USART_FLAG_TXE)
{
USARTx->SR &= ~USART_FLAG_TXE; // clear interrupt
}
}
/******************************************************************************/
int GetCharUART (char Channel)
{
int result;
if (rin[Channel]==rout[Channel]) {
return EMPTY;
}
result=rbuf[Channel][rout[Channel]% UART_BUFSIZE];
rout[Channel]++;
return result;
}
解决方案
您的代码存在功能错误。
在 ISR 中,您不会检查“缓冲区已满”情况。代码只是增加rin[Channel]
而不看rout[Channel]
. 因此,整个缓冲区的数据可能会丢失。
示例:如果rout[Channel]
等于 0 且rin[Channel]
等于 UART_BUFSIZE-1,则 ISR 将设置rin[Channel]
为零。换句话说,缓冲区现在将显示为空并且数据丢失。
So the first step is to fix the code.
推荐阅读
- python - Pandas.get_dummies 返回两列(_Y 和 _N)而不是一列
- bash - 如何获取文件中所有带引号的字符串?
- entity-framework - 多个表版本
- java - GSON - 反序列化时忽略空字段
- reactjs - 使用 Typescript 创建 React App 中的自定义代理
- php - Laravel 搜索功能 - 参考第二个模型/集合/表格
- c++ - 如何在 C++ 中循环遍历二维数组?
- java - Java如何在变量参数数组的开头添加插入元素?
- c# - C# PhantomJS 处理内存泄漏并在使用窗口/选项卡时退出
- javascript - 如果值在 javascript 中为真,你将如何制作 iframe?