1. 程式人生 > >SylixOS網絡數據異步處理原理

SylixOS網絡數據異步處理原理

sylixos 網絡 異步

一. 網絡數據異步處理簡介

SylixOS中為了解決網絡數據擁堵的問題,采取數據異步處理的方式,提供了網絡工作隊列。采用網絡工作隊列,可以使得網卡驅動程序無需阻塞等待處理完成。

SylixOS內核網絡netdev封裝了函數netdev_notify,提供了使用網絡工作隊列處理網卡數據的功能。

二. 網絡異步處理工作隊列初始化

系統初始化時會調用函數_netJobqueueInit創建網絡驅動作業處理隊列。網絡驅動作業處理隊列是通過系統異步工作隊列來實現的。

netJobqueueInit函數執行流程如下:

  1. 獲取系統配置LW_CFG_LWIP_JOBQUEUE_NUM,得到系統配置的可以並行工作的netjob個數,存入全局變量_G_uiJobqNum

    中;

  2. 比較_G_uiJobqNum和CPU核數,_G_uiJobqNum不能超過CPU核數;

  3. 對每個工作隊列調用_jobQueueInit函數進行初始化;

  4. 對每個工作隊列創建job處理線程_NetJobThread

三. 網絡異步處理線程

網絡異步處理線程_NetJobThread的工作非常簡單,死循環執行函數_jobQueueExec,執行工作隊列中的工作。

_jobQueueExec函數執行流程如下:

  1. 死循環等待二進制信號量,一旦發現工作隊列中存在未處理數據,則退出循環;

  2. 根據工作隊列中未處理數據個數,循環調用註冊的異步處理回調函數進行數據處理工作;

  3. 處理完成後,修改工作隊列中待處理數據計數值。

四. 加入網絡異步處理工作隊列

SylixOS提供API_NetJobAddAPI_NetJobAddEx兩個API接口實現了添加網絡異步處理工作隊列的功能。

函數API_NetJobAdd通過調用內核添加工作隊列接口函數_jobQueueAdd,實現添加工作隊列到0號網絡工作隊列中。函數API_NetJobAddEx則提供了擴展功能,可以指定添加工作隊列的編號。

函數_jobQueueAdd根據函數API_NetJobAdd傳入的回調函數和參數註冊到工作隊列中,增加待處理數據計數值,同時釋放二進制信號量。網絡異步處理線程接收到此二進制信號量後調用回調函數進行數據處理。

五. 刪除網絡異步處理工作隊列

SylixOS提供API_NetJobDelete

API_NetJobDeleteEx兩個API接口實現刪除網絡異步處理工作隊列。

函數API_NetJobDelete通過調用內核刪除工作隊列接口函數_jobQueueDel,實現刪除0號網絡工作隊列中的一個工作。函數API_NetJobDeleteEx則提供了擴展功能,可以指定刪除工作隊列的編號。

函數_jobQueueDel從工作隊列中刪除一個工作采用的是懶惰刪除方式,也即根據傳入參數,從當前記錄的最近處理完成的工作隊列編號之後,找到第一個匹配的一條工作隊列並將其刪除。

六. 網絡異步處理工作隊列應用

SylixOS中提供的網絡異步處理工作隊列主要應用於網卡接收數據的處理問題,SylixOS封裝的netdev層,提供了函數netdev_notify和函數netdev_notify_ex供驅動程序使用。

以MPC8313網卡驅動為例,介紹函數netdev_notify的使用方法。程序代碼示例如程序清單 6.1所示。

                                 程序清單 6.1 異步處理示例代碼
#include "SylixOS.h"
/****************************************************************
** 函數名稱: __eTSECRxIsr
** 功能描述: 接收中斷
** 輸  入  : pvArg          :  中斷參數
**           uiVector       :  中斷向量號
** 輸  出  : NONE
** 返  回  : LW_IRQ_HANDLED :  正常處理
**           LW_IRQ_NONE    :  處理異常
****************************************************************/
static irqreturn_t  __eTSECRxIsr (PVOID  pvArg, UINT32  uiVector)
{    
     netdev_t      *pNetDev = (netdev_t *)pvArg;    
     __PENET        pEnet;    
     UINT32         uiIevent;    
     UINT32         uiImask;    
     UINT32         uiBaseaddr;    
     
     pEnet       = pNetDev->priv;    
     uiBaseaddr = pEnet->uiBaseaddr;    
     uiIevent    = read32(REG_ETSEC_IEVENT(uiBaseaddr));    
     uiImask     = read32(REG_ETSEC_IMASK(uiBaseaddr));          
     
     /*     
      *  接收成功     
      */    
     if ((uiIevent & ETSEC_IEVENT_RXF)) {                        
         /*         
          *  清除RXF位         
          */        
         write32(uiIevent, REG_ETSEC_IEVENT(uiBaseaddr));    
             
         /*         
          * 關閉接收中斷         
          */
         write32(uiImask & ~(ETSEC_IEVENT_RXF), REG_ETSEC_IMASK(uiBaseaddr)); 
                   
         /*        
          *  通知系統進行接收         
          */        
         netdev_notify(pNetDev, LINK_INPUT, 1);    
     }    
     
     return  (LW_IRQ_HANDLED);
     
}

通過在接收中斷中調用函數netdev_notify,調用網絡數據異步處理函數,通過內核工作隊列調用到驅動接收函數,對網絡數據進行處理,提高系統的運行效率。

對於多核系統,調用函數netdev_notify_ex創建多個網絡異步處理函數,同時需要註意修改內核參數LW_CFG_LWIP_JOBQUEUE_NUM修改隊列個數。


本文出自 “12823848” 博客,請務必保留此出處http://12833848.blog.51cto.com/12823848/1984013

SylixOS網絡數據異步處理原理