EtherCAT Slave 入门教程 - 邮箱服务(1)

mailbox.c Implementation

邮箱buffer处理的描述(MAILBOX_QUEUE = 0):

两个邮箱buffer用于发送和接收邮箱服务。

正常运行:
启动邮箱处理(handler) psWriteMbx以及邮箱buffer 1,、psReadMbx、psRepeatMbx和psStoreMbx为0。
在此状态下,将忽略Repeat请求,因为尚未发送任何服务。

发送第一个邮箱服务时(在MBX_CopyToSendMailbox中),psWriteMbx获取邮箱buffer 2,psReadMbx获取发送邮箱buffer 1,psRepeatMbx 和 psStoreMbx仍为0。
从主站读取第一个邮箱服务时,发送的邮箱buffer 1存储在psRepeatMbx(MBX_MailboxReadInd)中。

在psReadMbx始终获取实际发送的邮箱buffer之后,psWriteMbx设置为0(在发送邮箱服务被读且调用MBX_MailboxReadInd之前,不会处理从主站接收的另一个邮箱服务)。
当读取邮箱服务时,psWriteMbx得到psRepeatMbx的buffer,psRepeatMbx得到psReadMbx的buffer。

主站Repeat请求:
当主站发Repeat请求时(MBX_MailboxRepeatReq),有三种不同的可能:

  1. 自邮箱处理(handler)启动以来未发送任何邮箱服务(psRepeatMbx=0):无需执行任何操作

  2. 接收到上一个已发送邮箱服务的确认(MBX_MailboxReadInd())(bSendMbxIsFull = 0):
    上一个发送邮箱服务(psRepeatMbx)将被再次发送(在MBX_CopyToSendMailbox中)并存储在psReadMbx中,psRepeatMbx将设为0

  3. 未接收到上一次的发送邮箱服务的确认(psReadMbx和psRepeatMbx包含不同的buffer,psReadMbx仍在邮箱中(因为尚未调用MBX_MailboxReadInd,bSendMbxIsFull = 1):
    psReadMbx将在邮箱中被删除(调用DisableSyncManChannel和EnableSyncManChannel)然后存储在psStoreMbx中,psRepeatMbx将再次发送(在MBX_CopyToSendMailbox中)并存储在psReadMbx中,psRepeatMbx将置为0。
    发送重复邮箱服务(调用MBX_MailboxReadInd)时,psReadMbx将存储在psRepeatMbx中,psStoreMbx将被发送(在mbx中)并存储在psReadMbx中,psStoreMbx将被设为0。

邮箱buffer处理的描述(MAILBOX_QUEUE = 1):

有两个邮箱buffer用于发送和接收邮箱服务。

正常操作(psWriteMbx仅用于本地存储):
启动邮箱处理(handler) psReadMbx,psRepeatMbx和psStoreMbx为0。
在此状态下,将忽略Repeat请求,因为尚未发送任何服务。

当从主站接收到邮箱服务时(在MBX_CheckAndCopyMailbox中),邮箱buffer将使用APPL_AllocMailboxBuffer获取,相应的协议服务功能将被调用(在MBX_WriteMailboxInd中)。
该buffer应用于协议服务响应。
发送第一个邮箱服务时(在MBX_CopyToSendMailbox中),psReadMbx将获取发送邮箱buffer,psRepeatMbx和psStoreMbx仍为0。

读取第一个来自主站的邮箱服务时,将存储发送的邮箱buffer(psReadMbx)。在psRepeatMbx中(在MBX_MailboxReadInd中)。
之后,psReadMbx始终获取实际发送的邮箱buffer(在MBX_CopyToSendMailbox中)当读取邮箱服务时,将返回psRepeatMbx(使用appl eu freemailboxbuffer),psRepeatMbx将获取psReadMbx的buffer。

主站Repeat请求:

当主站发Repeat请求时(mbx_mailboxrepeatreq),有三种不同的可能:

  1. 自邮箱处理(handler)启动以来未发送任何邮箱服务(psRepeatMbx=0):无需执行任何操作

  2. 接收到上一个已发送邮箱服务的确认(以MBX_MailboxReadInd为单位)(bSendMbxIsFull=0):
    最后发送的邮箱服务(psRepeatMbx)将再次发送(在MBX_CopyToSendMailbox中)并存储在psReadMbx中,psRepeatMbx将设置为0

  3. 未收到最后发送的邮箱服务的确认(psReadMbx和psRepeatMbx包含不同的buffer,psReadMbx仍在邮箱中(因为尚未调用mbx_-mailboxreadind,bSendMbxIsFull=1):
    psReadMbx将在邮箱中删除(调用DisableSyncManChannel和EnableSyncManChannel)和存储在psStoreMbx中,psRepeatMbx将再次发送(在MBX_CopyToSendMailbox中)并存储在psReadMbx中,psRepeatMbx将设置为0。
    发送重复邮箱服务(调用MBX_MailboxReadInd)时,psReadMbx将存储在psRepeatMbx中。
    psStoreMbx将被发送(在mbx中)并存储在psReadMbx中,psStoreMbx将被设置为0。

mailbox.c 解析

1. UINT8 PutInMbxQueue(TMBX MBXMEM * pMbx, TMBXQUEUE MBXMEM * pQueue)

2. TMBX MBXMEM * GetOutOfMbxQueue(TMBXQUEUE MBXMEM * pQueue)

3. void MBX_Init(void)

4. UINT16 MBX_StartMailboxHandler(void)

5. void MBX_StopMailboxHandler(void)

6. UINT8 MailboxServiceInd(TMBX MBXMEM *pMbx)

checks the mailbox header:
(pMbx->Mbxheader.Flags[MBX_OFFS_TYPE] & MBX_MASK_TYPE) >> MBX_SHIFT_TYPE

when mailbox header type is MBX_TYPE_COE, it calls:

COE_ServiceInd((TCOEMBX MBXMEM *) pMbx);

7. void MBX_MailboxWriteInd(TMBX MBXMEM *pMbx)

8. void MBX_MailboxReadInd(void)

9. void MBX_MailboxRepeatReq(void)

10. UINT8 MBX_MailboxSendReq( TMBX MBXMEM * pMbx, UINT8 flags )

11. void MBX_CheckAndCopyMailbox(void)

Check if the received mailbox command can be processed, the contents of the Receive Mailbox will be copied in the variable sMbx.

12. UINT8 MBX_CopyToSendMailbox(TMBX MBXMEM *pMbx)

13. void MBX_Main(void)

  1. GetOutOfMbxQueue(&sMbxReceiveQueue);
    to check if a received mailbox service was stroed.
  2. MailboxServiceInd(pMbx);
    to check the mailbox header for the requested service and calls the corresponding XXX_ServiceInd function.
  3. if (bReceiveMbxIsLocked)
      MBX_CheckAndCopyMailbox();
posted @ 2019-06-20 13:36  Salvare  阅读(1930)  评论(0编辑  收藏  举报