您好!
我们将基于 CC3220的 AP 连接到基于 CC3220的基站。 在 AP 上使用 sendto ()函数将 UDP 数据发送到站点。
我们注意到,在极少数情况下,当停止工作站的电源时,sendto ()函数不会返回,它会阻止。 这种情况仅发生在断电而未通电的情况下。
这是可能的、还是有其他事情发生了?
此致、
Tunstar_User
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
您好!
我们将基于 CC3220的 AP 连接到基于 CC3220的基站。 在 AP 上使用 sendto ()函数将 UDP 数据发送到站点。
我们注意到,在极少数情况下,当停止工作站的电源时,sendto ()函数不会返回,它会阻止。 这种情况仅发生在断电而未通电的情况下。
这是可能的、还是有其他事情发生了?
此致、
Tunstar_User
Kobi、
虽然我们只等了大约5分钟,但它却“永远”地封锁了。 我假设从软件的角度来看、5分钟将被视为"永远"。
在我们的应用程序中,更明显的是在 SendTo()调用一个信号量被释放后。
当它被阻断时、我们可以在 CCS8调试器中看到发送 UDP 任务滞留在 sendto ()调用行上、而另一个任务在信标上被阻止。
足够有趣的是、在信号量上被阻止的另一个任务是 sl_task、它在尝试获取信号量时卡在断开代码的开头、因此 NWP 已将断开事件发送到 CPU。
此致、
Kobi、
AP sendto ()命令周围是一个信标、当 sendto ()返回时、它会释放信标。
如果基站终止且断开事件进入、则处理该事件的 sl_task 代码开始尝试获取信号量。
现在、如果此事件在 AP 位于 sendto ()的中间时发生、则 sl_task 获取信号量的尝试会在 sem_wait ()上挂起、直到 sendto ()完成。
在我们确实看到分块的情况下,sendto ()任务在 sendto ()上被阻止,而 sl_task 在 sem 等待()调用上被阻止。 sendto ()似乎从未完成,因此僵局仍在继续。
解释我们所看到的内容的一种方法是 NWP 事件代码是否为单线程。 因此,它会在 用户应用程序中调用 SimpleLinkWlanEventHandler(),并等待函数完成。 在等待期间、它无法处理任何用户应用程序内部事件、例如 sendto ()完成、因此不会处理 sendto ()、因此不会释放信标和锁定的 sl_task。
[有趣的是,当阻塞发生时,即使套接字具有1秒的超时,recvfrom()任务也会阻止 recvfrom()。]
为了克服这一问题,我尝试将 sendto ()移出信标块,以查看它是否可以解决问题。 到目前为止。
NWP 事件处理循环是否会暂停、直至用户应用发布的事件返回?
此致、
tUNSTALL_USER
Kobi、
信号量在我的应用程序代码中、它保护保存站信息(例如 IP 地址)的数据结构。 当通过 sl_task 进入时、连接/断开站事件也会更新此结构。 因此是信标。
插槽最初处于阻塞状态、因此我假设使它们处于非阻塞状态可以解决问题。 但是正如我在上面提到的,recvfrom()套接字上的1秒超时和使 sendto ()套接字不阻塞都不能解决问题。 sl_task 停留在 SEM_WAIT ()上、并且 recvfrom / sendto 被阻止。 我唯一能解释这种行为的原因是 NWP 端的单线程事件处理。
我并不感到惊讶的是,你不能复制它。 我从未注意到过这一点、直到其中一名测试人员有一个无响应的 AP 并打电话给我。
在我们的应用中、我们有一个站点和一个 AP、它们可以连续地相互发送和接收 UDP 数据包。 AP 接收来自集线器的音频并将其发送到基站、而基站将麦克风音频发送回 AP、AP 将其转发到集线器。
两个单元均使用3104编解码器并发送/接收20ms 音频数据包。 对于 AP、它等待编解码器填充20ms 缓冲区、然后将音频数据包发送到基站、然后重复。 发送大约需要1.5ms。 最初、信标包围了 sendto ()、因此信标锁定了大约1.5ms。
只有在这1.5ms 内发生断开事件时才会出现此问题、如果稍后或更早的时间一切正常、则会出现此问题。 当我尝试重现它时、我仅在20个站的循环通电后获得1。 因此、这很棘手。
通过使用 BSD 调用而不是 Texas SL_xxx、我知道 BSD 调用映射到 SL_xx 调用、但我提到了它"以防万一"。
当任务被阻止时、我添加了 CCS8调用堆栈、sl_Task 列表中的步骤4是 SEM_WAIT ()块出现在我的代码中的地方。 下调用栈中的步骤6是被阻止的 sendto ()、信标是在 sendto 调用之前获取的。
此致
NWP 是多线程的、但在主机 MCU 上、我们只有一个 处理 NWP 事件的任务(即 sl_Task)。
如果您在 SimpleLinkWlanEventHandler 内阻止(在信标上)、sl_Task 将无法处理下一个事件(可能是 sl_sentto 的响应事件)、因此 sl_Sendto (等待响应事件)不会完成...
解决 方案是从 SimpleLinkWlanEventHandler 中删除关键段保护(即信号量使用)、而是使用此回调来触发(使用邮箱或通过发布信号量)另一个将处理断开事件的线程。