为什么在中断函数中不能使用printf打印函数

为什么在中断函数中不能使用printf打印函数,第1张

在嵌入式设计中,一般不建议在中断函数中调用打印函数printf来打印调试信息,如果真这么做了,可能发生的结果包括:

需要分各种情况讨论。

按照中断函数的行为,有些中断函数为了防止中断嵌套,会将中断临时禁用。

按照printf的实现方式,有些会通过轮询方式实现;优先会通过串口中断方式实现。

如果中断函数中禁用了中断

-- 如果调用的printf依赖中断打印,则会造成printf无法完成打印

-- 如果调用的printf通过轮询方式实现,打印一段字符的时间过长,大大降低中断处理效率,而且在中断禁用期间可能会错失很多其他中断

如果中断函数中没有禁用中断

-- printf函数执行过程中,可能主中断可能会再次被触发,从而再次调用printf,造成printf函数的重入。而很多printf函数由于调用了全局资源,是不支持可重入的,会造成灾难性后果。

最好的实现方式就是,发生中断时,设置标志,构造一个尽量简短的ISR,将printf等其他工作单独创建相应的线程去执行。

https://www.cnblogs.com/mylinux/p/5534325.html

http://blog.sina.com.cn/s/blog_5e3075450100c0my.html

https://www.bbsmax.com/A/Gkz1BBYZJR/

单片机HC32L110 *** 作时,会出现标题所示的错误,下面是数据手册中的一句话:

then,看下实际工程中的代码(无关代码已经删除,保留关键代码),串口配置为接收中断,输出不用中断方式

串口发送

en_result_t Uart_SendData(uint8_t u8Idx, uint8_t u8Data)

{

Uart_ClrStatus(u8Idx,UartTxEmpty) //发送完成标志位清零=FALSE

pstcData->pstcInstance->SBUF =u8Data//要发送的字节

while(FALSE == Uart_GetStatus(u8Idx,UartTxEmpty))//等待发送完成,标志位置位=TRUE

{}

Uart_ClrStatus(u8Idx,UartTxEmpty) //发送完成标志位清零=FALSE

return Ok

}

接收中断函数:

void UART1_IRQHandler(void)

{

Uart_ClrStatus(1,UartRxFull)//清除接收中断

UartRecvBuff[UartRecvWrite++] = M0P_UART1->SBUF //保存数据

Uart_SendData(UARTCH1,0x06)//在接收中断后发送一个字节

}

主函数:

while(1)

{

Uart_SendData(UARTCH1,0x02)

}

软件发生错误的过程:主函数发送一个字节时,还未完成就被中断,跳转到中断函数,然后在接收中断函数中又进行了一个字节的发送 *** 作,就会导致出错(如数据手册所言,当一个发送字节还未完成时,又发送了一个字节),结果就是主函数一直在这里等待数据发送成功while(FALSE == Uart_GetStatus(u8Idx,UartTxEmpty)),而它已经发生了错误永远都不可能成功发送了。


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/bake/11709764.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-18
下一篇 2023-05-18

发表评论

登录后才能评论

评论列表(0条)

保存