树莓派GPIO同步通信为何需sched_yield()?能否规避?
树莓派3B与6502/6522同步通信问题排查
我在树莓派3B V1.2与6502/6522处理器间实现同步通信协议,最初使用pigpio库时发现:必须插入usleep(0)或sched_yield()调用才能正常通信,否则会出现异常,但这种方案的吞吐量远低于预期。
为验证问题是否与pigpio库相关,我切换至bcm2835库,结果完全一致:仍需调用上述函数,吞吐量依旧不理想。
请问该现象的原因是什么?是否有办法避免这些调用?
读取字节的代码如下(GPIO_READ等为指向pigpio或bcm2835函数的宏,YIELD为调用usleep(0)或sched_yield()的宏):
static void wait_data_ready_rx() { while( GPIO_READ(PIN_DATAREADY_RX) != 0 ) { ; } YIELD; } static void data_taken_rx() { GPIO_WRITE(PIN_DATATAKEN_RX, 0); YIELD; GPIO_WRITE(PIN_DATATAKEN_RX, 1); } static unsigned char read_byte() { int bit; int bitno = 0; unsigned char byte = 0; for(bitno=0; bitno<8; ++bitno) { wait_data_ready_rx(); bit = GPIO_READ(PIN_DATA_RX_0); byte = byte << 1 | bit; data_taken_rx(); } return byte; }
注:我也曾尝试使用__sync_synchronize()内存屏障,但无效果。
更新:感谢各位提示,实际是时序问题——两次
GPIO_WRITE之间需要延时,sched_yield()恰好提供了合适时长,这让我之前误入歧途。目前我已理解其中逻辑,并能优化两台设备间的通信。
内容的提问来源于stack exchange,提问作者Dottore
相关产品推荐
相关产品推荐

