由于在这个项目中,WIFI模块是采用SDIO总线来控制的,所以先记录下CLIENT DRIVER的SDIO部分的结构,这部分的SDIO分为三层:SdioDrv、SdioAdapter、SdioBusDrv。其中SdioBusDrv是Client Driver中SDIO与WIFI模块的接口,SdioAdapter是SdioDrv和SdioBusDrv之间的适配层,SdioDrv是Client Driver中SDIO与LINUX KERNEL中的MMC SDIO的接口。这三部分只需要关注一下SdioDrv就可以了,另外两层都只是对它的封装罢了。

在SdioDrv中提供了这几个功能:

(1)static struct sdio_driver tiwlan_sdio_drv = {
.probe = tiwlan_sdio_probe,
.remove = tiwlan_sdio_remove,
.name = "sdio_tiwlan",
.id_table = tiwl12xx_devices,
};

(2)int sdioDrv_EnableFunction(unsigned int uFunc)

(3)int sdioDrv_EnableInterrupt(unsigned int uFunc)

(4)SDIO的读写,实际是调用了MMC\Core中的 static int mmc_io_rw_direct_host()功能。

SDIO功能部分简单了解下就可以,一般HOST部分芯片厂商都会做好。我的主要任务还是WIFI模块。

首先从WIFI模块的入口函数wlanDrvIf_ModuleInit()看起,这里调用了wlanDrvIf_Create()。

代码主体部分:

static int wlanDrvIf_Create (void)
{
TWlanDrvIfObj *drv; //这个结构体为代表设备,包含LINUX网络设备结构体net_device

pDrvStaticHandle = drv; /* save for module destroy */

drv->pWorkQueue = create_singlethread_workqueue (TIWLAN_DRV_NAME);//创建了工作队列

/* Setup driver network interface. */
rc = wlanDrvIf_SetupNetif (drv); //这个函数超级重要,后面详细的看

drv->wl_sock = netlink_kernel_create( NETLINK_USERSOCK, 0, NULL, NULL, THIS_MODULE );

// 创建了接受wpa_supplicant的SOCKET接口

/* Create all driver modules and link their handles */
rc = drvMain_Create (drv,
&drv->tCommon.hDrvMain,
&drv->tCommon.hCmdHndlr,
&drv->tCommon.hContext,
&drv->tCommon.hTxDataQ,
&drv->tCommon.hTxMgmtQ,
&drv->tCommon.hTxCtrl,
&drv->tCommon.hTWD,
&drv->tCommon.hEvHandler,
&drv->tCommon.hCmdDispatch,
&drv->tCommon.hReport,
&drv->tCommon.hPwrState);

/*
* Initialize interrupts (or polling mode for debug):
*/

/* Normal mode: Interrupts (the default mode) */
rc = hPlatform_initInterrupt (drv, (void*)wlanDrvIf_HandleInterrupt);

return 0;

}

在调用完wlanDrvIf_Create()这个函数后,实际上WIFI模块的初始化就结束了,下面分析如何初始化的。先看wlanDrvIf_SetupNetif (drv)这个函数的主体,

static int wlanDrvIf_SetupNetif (TWlanDrvIfObj *drv)
{
struct net_device *dev;
int res;

/* Allocate network interface structure for the driver */
dev = alloc_etherdev (0);//申请LINUX网络设备
if (dev == NULL)

/* Setup the network interface */
ether_setup (dev);//建立网络接口 ,这两个都是LINUX网络设备驱动的标准函数

dev->netdev_ops = &wlan_netdev_ops;

/* Initialize Wireless Extensions interface (WEXT) */
wlanDrvWext_Init (dev);

res = register_netdev (dev);

/* Setup power-management callbacks */
hPlatform_SetupPm(wlanDrvIf_Suspend, wlanDrvIf_Resume, pDrvStaticHandle);

}

注意,在这里初始化了wlanDrvWext_Inti(dev),这就说明wpa_supplicant与Driver直接的联系是走的WEXT这条路。也就是说event的接收,处理也应该是在WEXT部分来做的,确定这个,剩下的工作量顿减三分之一,哈哈哈。后面还注册了网络设备dev。而在wlan_netdev_ops中定义的功能如下:

static const struct net_device_ops wlan_netdev_ops = {
.ndo_open = wlanDrvIf_Open,
.ndo_stop = wlanDrvIf_Release,
.ndo_do_ioctl = NULL,

.ndo_start_xmit = wlanDrvIf_Xmit,
.ndo_get_stats = wlanDrvIf_NetGetStat,
.ndo_validate_addr = NULL,

};

功能一看名字就知道了,不说了,这几个对应的都是LINUX网络设备驱动都有的命令字,详见《LINUX设备驱动开发详解》第十六章。

在这之后,又调用了rc =drvMain_CreateI。

在这个函数里完成了相关模块的初始化工作。具体不说了。接下来就是等待Android上层发送来的事件了。


更多相关文章

  1. android studio中使用NDK开发C++
  2. Android(安卓)中input event的分析
  3. Android(安卓)4.1 Netd详细分析(五)代码分析3
  4. Android(安卓)GDI之SurfaceFlinger之动态结构示意图
  5. android velocityTracker 简介
  6. binder实例分析
  7. android native内存泄漏检测原理
  8. Android(安卓)SystemUI的EventBus实现原理
  9. cocos2dx实现获得设备的网络连接状态

随机推荐

  1. How-To: Install Google’s Android Ecli
  2. Android解析xml的Demo
  3. Android SDK 2.0 安装
  4. 2013年上半年CSDN精华0分下载资源
  5. Android之back键拦截处理
  6. android studio 中添加 Volley module
  7. Qt for Android 程序禁止屏幕旋转
  8. android ksoap调用天气预报
  9. android视频播放
  10. Android性能优化之管理应用的内存