I2C采用者永远阻塞

⚠️
大家好. .谢谢你来到论坛。令人兴奋的消息!我们现在正在转移到新的论坛平台,它将提供更好的功能,包含在主对话网站中。所有岗位和账户都已迁移。我们现在只接受新论坛的流量-请在上面发布任何新帖子//www.wsdof.com/support.我们将在未来几天修复bug /优化搜索和标记。
7个帖子/ 0个新
最后发表
UnicycleBloke
离线
最后看到:三个月两个星期前
加入:2015-10-26 13:43
I2C采用者永远阻塞

我试图让I2C适配器工作,但由于某些原因,它永远阻塞当我调用ad_i2c_write_read()。

对于上下文,我正在以以下方式使用适配器:
- 有一个任务具有处理I2C事务的唯一功能。
—该任务有一个FreeRTOS队列,其中包含等待处理的事务。
—任务从队列中获取下一个事务(如果为空则阻塞),然后执行
事务同步。
—当事务完成时,任务向事务的发起任务发送一个信号。
- 没有其他任务使用I2C外设。

这种设计非常简单,这意味着所有其他线程都可以使用I2C
阻塞。这与我在其他处理器上实现I2C驱动程序的方式相匹配,并且可以工作
很好。

任务看起来是这样的(它是一个c++类的一部分):

空白I2CMasterDriver: task_func_impl ()

//初始化I2C设备。
ad_i2c_init();

//可能有休息或暂停条件。
而(真实)

//如果队列中没有任何内容,则将阻止。
m_queue.receive (m_trans);

//调用者可以传入一个指向数据缓冲区的指针(对于更大的块)。
//如果为null,则指向我们自己的缓冲区。注意:在这一点上这样做
//因为结构体是按值复制的,任何其他指针都可能
//无效。
如果(m_trans。数据= = nullptr)

m_trans。data = &m_trans.buffer [0];

//打开我们想要通话的I2C从设备。这是最奇怪的建筑
//我已经看到了管理奴隶。
i2c_device device = ad_i2c_open(NFC_CHIP);

这是一个阻塞调用。
Int ret_code = ad_i2c_write_read()
设备,
(m_trans.tx_length> 0)?&m_trans.data [0]:nullptr,
m_trans.tx_length,
(m_trans。Rx_length > 0) ?&m_trans.data [m_trans。tx_length]: nullptr,
m_trans.rx_length,
HW_I2C_F_ADD_STOP);

//我们将返回值-通过调度程序-所以恢复数据指针到
//表示我们使用了自己的缓冲区或外部缓冲区。
如果(m_trans。数据= = &m_trans.buffer [0])

m_trans。数据= nullptr;

//让客户知道我们已经完成了。
m_on_complete.emit (m_trans);

//关闭设备以准备下一个事务。
ad_i2c_close(设备);

以下几行包含在我的配置中:

#define dg_configUSE_HW_I2C (1)
#define dg_configI2C_ADAPTER (1)

以下行包含在外围的init中:

hw_gpio_configure_pin(HW_GPIO_PORT_0, HW_GPIO_PIN_0, HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_I2C_SCL, true);
hw_gpio_configure_pin(HW_GPIO_PORT_0, HW_GPIO_PIN_1, HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_I2C_SDA, true);

platform_devices.h包含以下几行:

I2C_BUS (I2C1)
I2C1, nfc_chip, 0x28, HW_I2C_ADDRESSING_7B, HW_I2C_SPEED_STANDARD, 0)
I2C_BUS_END

此问题是对AD_I2C_WRITE_READ()块的调用,而不是返回。如果我发表评论
排队,以便排队的事务刚刚被抛弃,任务完全按预期工作。
我可能错过了其他哪些设置、宏或选项?因为只有一个任务使用I2C,也许我应该使用低级的驱动程序代替…

按照目前的情况,我想我宁愿为此编写自己的裸金属驱动程序。有这样的例子吗?

谢谢。

设备:
UnicycleBloke
离线
最后看到:三个月两个星期前
加入:2015-10-26 13:43
看来我需要

似乎我需要在启动事务之前获得总线——这是初始化外围设备本身并启用中断的原因。所以它现在不会阻塞。然而……

电线上什么都没有。没有附加设备,但我至少应该看到地址。

谢谢。

UnicycleBloke
离线
最后看到:三个月两个星期前
加入:2015-10-26 13:43
啊!回答了我自己的问题。

啊!回答了我自己的问题。它帮助很多,如果你使引脚输出开路排水沟和粘在总线上的设备拉上来的线。

谢谢。

PM_Dialog
离线
最后看到:2天15小时前
工作人员
加入:2018-02-08 11:03
嗨UnicycleBloke,

嗨UnicycleBloke,

我强烈建议您看一看I2C适配器概念(HTML)从DA14680的支持页面。本教程解释了I2C适配器以及如何将DA1468x配置为I2C主设备。适配器未实现为单独的任务,并且应视为应用程序和LLD之间的附加层。建议使用适配器来访问硬件块。

谢谢,PM_Dialog

UnicycleBloke
离线
最后看到:三个月两个星期前
加入:2015-10-26 13:43
谢谢,但我已经准备好了

谢谢,但我已经完成了所有这些。我理解I2C适配器概念。不幸的是,我认为设计是理想的。这就是为什么我创建了一个线程到序列式调用的线程,而不停止应用程序中的任何其他线程。它现在运作得很好,并且更适合我的活动驱动应用程序框架。

我还有一个问题:如果我要使用两个I2C外设,适配器似乎会阻止它们上的并发事务。这是真的吗?

谢谢。

PM_Dialog
离线
最后看到:2天15小时前
工作人员
加入:2018-02-08 11:03
嗨UnicycleBloke,

嗨UnicycleBloke,

是的,这是真的!适配器将阻止它们上的并发事务。

谢谢,PM_Dialog

UnicycleBloke
离线
最后看到:三个月两个星期前
加入:2015-10-26 13:43
嗯。谢谢你让我

嗯。谢谢你告诉我。我觉得这是个很糟糕的设计。