在使用環接收串口數據時,在中斷中向環區寫入數據,在主程序中從環區讀出數據。(測試芯片為雅特麗AT32F413)
上邊做法經常出現環中數據沒有完全讀出時ringbuff1.length已經變為0的情況,並且出錯一次有1個字節數據未讀出。
猜測:
全局變量ringbuff1.length內存原始數據為1,此時程序運行到while中的U1ReadOneFrameData;函數中,處理器在使用ringbuff1.length的值進行連續的運算操作時,這個變量的值將在第一次操作時被復制到中間臨時變量中,則緊接其后的其它操作將有可能直接從臨時變量中取數以提高運行效率,即處理器從內存中讀出ringbuff1.length的值1存入中間臨時變量,此時中斷條件到達進入中斷處理函數void USART2_IRQHandler(void);
中斷函數運行完成后ringbuff1.length變為2寫入內存,內存中ringbuff1.length值變為2,並且返回while,然后while中的ringbuff1.length經過編譯器優化實際為中間臨時變量值--,即1-1為0,最后值寫入內存,內存中全局變量ringbuff1.length值為0。
但是理想情況下ringbuff1.length值先經過++,在經過--,最后理想值為1。與實際情況不一致所以出錯。
修改方法:
避免使用在中斷中++,在主函數中--的全局變量ringbuff1.length,即不適用在中斷和主函數同時進行了寫操作的全局變量,改用只在中斷中寫的
ringbuff1.tail和在主函數中進行寫操作的ringbuff1.head,通過二者判斷環中數據是否為空。