我使用i2c适配器(在主模式下)进行异步写或读操作,这些操作将永远等待OS\ U事件从回调发出信号。
然而,我不想永远等待,我想能够设置一个超时值,这样它就不会卡住,如果说没有设备在总线上。
但是,如果我尝试启动另一个异步读或写,那么在超时之后,适配器将挂起,因为(例如2)有未完成的挂起事务。如何取消这些挂起的事务,或者更好的方法是,使用什么样的超时来执行ad\u i2c\u async\u read或ad\u i2c\u async\u write。
设备:
你好,拉贾姆斯,
如果您使用SDK的ASYNCH函数启动异步事务,则API为您提供回调参数,应在完成事务时执行此回调。如果由于任何原因在尝试访问I2C设备时设备获取NACK,则交互将终止适当的错误,在设备侧HW_I2C_ABORT_7B_ADDR_NO_ACK中的NACK的情况下,您将能够知道在回调时。而不是拥有wait_for_event(事件)(我想这就是你的意思)你可以ommit是为了不阻止任务,但你不能取消已经开始的事务,并且你不能在之前使用第二个ASYNCH事务前一个返回,这在doxygen中清楚地说明了ad_i2c_asynch_read和写入函数的描述中。
谢谢你的对话
嗨,达洛,
感谢您的答复。
如果我理解正确,即使发生错误,回调也应该始终执行。
我使用回调来通知任务,请参见下面的伪代码:
回调(params){
//句柄参数
操作系统信号(事件)
}
任务(){
异步写入(数据,回调)
OS\事件\等待(事件,超时)
//以相同方式进行更多异步写入或读取
}
我面临的问题是,如果在超时过期之前没有执行回调,那么我就不能取消任何挂起的事务。这就是为什么永远使用OS\u EVENT\u。
但是回调并不总是被执行。回调是否会在以下错误期间执行?假设在异步写入或读取开始之前,从设备将SCLK线保持在低位。回调是否仍会以HW\u I2C\u ABORT执行?当回调没有被触发时,还有其他情况吗?
如何按以下顺序防止堵塞
主设备:ad\u i2c\u async\u read
Master:启动读取请求
从机:确认并保持SCLK线路低
从机:从不发送响应
主机:操作系统事件等待超时过期
主机:启动另一个ad\U i2c\U异步\U读取请求
母版:因为有挂起的事务。
谢谢你的帮助
你好,拉贾姆斯,
所以,你是说有时操作永远不会完成,所以设备会暂停并等待?你提到的是可能的,因为如果I2C硬件看到的时钟线低,它不会传输任何数据,它不会返回一个错误(因为没有错误),它只会等到时钟线得到自由,并传输数据的缓冲区。所以是的,在这种情况下,不应该有任何交易完成。但是你不能有一个奴隶,将保持低时钟线的所有时间。如果发生这种情况,并且线路保持低位,那么最好由从设备处理,而不是从主设备处理,因为将时钟线路保持低位会阻止连接在该总线上的所有设备的通信,即使有取消过程来停止异步事务,如果从机继续保持低位,所有后续事务也必须中止。在任何情况下,您都可以尝试使用以下代码片段来取消该过程(请注意,这是没有测试,不是正式的SDK代码,我无法预测任何副作用,这可能会有行为的I2C交易):
静态void i2c_release_uncomp_transact(i2c_device dev)
{
i2c\U设备\U配置*设备=(i2c\U设备\U配置*)设备;
i2c\总线\动态\数据*数据=设备->总线\数据;
如果(数据->事务处理)0)
{
数据->事务_ix=0;
/*只需释放总线和设备*/
AD_I2C_BUS_RELEASE(DEV);
设备释放(dev);
}
}
因此,使用上面可以使用超时而不是使用WAIT_FOR_EVENT()函数中的OS_EVENT_FOREVER,并且一旦超时结束,您可以调用上述功能以取消先前的事务并继续使用另一个事务。
谢谢你的对话