UCOS + LWIP + USB WIFI(rtl8188eu) <二>

好长时间没有安静下来想一想人生了, 每天被忙碌的工作和繁琐的家务缠身(超级奶爸, 这个光荣的头衔), 有时候一个人静下来回忆一下过去的经历, 展望一下未来, 也是一种修行.

在上一章中我简单描述了一下TCPIP, 和LWIP方面注意的重点事项, 这些也是项目的主干, 通过主干, 你们可以去研究和领悟细节, 细节这东西是说不清, 理还乱的. 需要大家的悟性. 今天我们同样是来讲一讲RTL8188eu驱动的框架结构realtek瑞昱的无线芯片), 以及移植重点. realtek是台湾的无线芯片公司, 在深圳有分公司, 主要负责技术支持部, 曾经为了移植这个驱动也和他们讨论过, 也感谢他们的技术支持.

接下来我们来看看移植前的准备工作, 首先你得准备一块RTL8188eu的模组, 大概7块人民币, 焊上匹配的天线和一个USB接口, 这样一个无线WIFI就完成了, 插到PC端, 安装上驱动, 如果电脑能正确识别就说明你焊接的没有问题, 如果有问题, 检查一下你安装的RTL8188eu驱动是否正确, 最后检查焊接是否没有问题. 如果PC出现无线图标, 这样一个大概7元人民币的无线WIFI就完成了, 真够便宜实惠的; 最后你得找到RTL8188eu的源码驱动程序, 这样你才能开干, 一般适应LINUX环境的源码在网上可以找到, 大家可以找下, 我这边使用的LINUX rtl8188eu的源码版本是v4.1.3_5938.20121130, 版本比较低, 但是也足够用了.

得到源码后我们来看看源码的文件夹结构:

如图所示:core文件夹是WIFI芯片的核心部分, 里面有处理发送,接收, 加密等核心底层代码; hal\OUTSRC和硬件底层打交道的东西, 如设置什么寄存器, 烧写固件的二进制之类的东西了, 这个只有芯片原厂才知道的东西了; include里面包括了所有源码的头消息了; os_dep\linux这层主要是和操作系统打交道的, 操作系统通过这里面的标识符识别设备, 挂起设备, 恢复设备, TCP/IP协议通过这里面的文件,  发送以太网帧, 接收以太网帧, 由于我们移植的是USB的, 所以sdio, pci, gspi这些就可以不用了; os_dep\osdep_service.c文件是区分不同操作系统之前接口的函数, 如Windows, linux. 如果要移植到其他系统需要关注这块, 主要是不同系统提供的系统函数不一样的原因.

先来看看入口文件, usb_intf.c, 模块加载和卸载最前线的函数rtw_drv_entry()和rtw_drv_halt(), 这两个函数很简单, 我们需要关心的是里面注册的变量static struct rtw_usb_drv *usb_drv = &rtl8188e_usb_drv;

struct rtw_usb_drv rtl8188e_usb_drv = {
	.usbdrv.name = (char*)"rtl8188eu",                      //又名有份,驱动名字
	.usbdrv.probe = rtw_drv_init,<span style="white-space:pre">				</span>//USB内核枚举到设备后就加入到这里来了
	.usbdrv.disconnect = rtw_dev_remove,                    //USB WIFI被别人拔掉了, 需要调用这个函数
	.usbdrv.id_table = rtl8188e_usb_id_tbl,                 //USB内核怎么枚举到我呢? 就是通过这个ID表了
	.usbdrv.suspend =  rtw_suspend,                         //USB WIFI没有用到, 加入这里休息下,准备快速响应
	.usbdrv.resume = rtw_resume,                            //USB WIFI休息介绍,开始工作;额
	#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 22))
  	.usbdrv.reset_resume   = rtw_resume,
	#endif
	#ifdef CONFIG_AUTOSUSPEND	
	.usbdrv.supports_autosuspend = 1,	
	#endif
};

万事开头难, 现在就开了个小头了, 这大从那里着手了, 知道入口了, 就往里面冲了. 

先来看rtw_drv_init()函数, 很简单三个主要函数一个全局对象初始化,所有的私有数据, 和两个网络接口的生成.这个三个对象相辅相成彼此联系, 你中有我,我中有你,就是这样一个绯闻关系.下面我们来看看重点函数rtw_usb_if1_init(),贴出精简代码加注释说明, 不喜欢太长影响文章

_adapter *rtw_usb_if1_init(struct dvobj_priv *dvobj,
	struct usb_interface *pusb_intf, const struct usb_device_id *pdid)
{
	_adapter *padapter = NULL;
	struct net_device *pnetdev = NULL;
	int status = _FAIL;
    //分配内存
	if ((padapter = (_adapter *)rtw_zvmalloc(sizeof(*padapter))) == NULL) {
		goto exit;
	}
    //你中有我,我中有你
	padapter->dvobj = dvobj;
	dvobj->if1 = padapter;
    //初始化赋值
	if((pnetdev = rtw_init_netdev(padapter)) == NULL) {
		goto handle_dualmac;
	}
	SET_NETDEV_DEV(pnetdev, dvobj_to_dev(dvobj));
	padapter = rtw_netdev_priv(pnetdev);
    //该函数调用rtl8188eu_set_hal_ops()函数, 将芯片底层操作函数赋值给回调函数,供系统调用.
	//step 2. hook HalFunc, allocate HalData
	hal_set_hal_ops(padapter);
    //芯片跑起来和停下来回调 函数赋值,供系统调用 
	padapter->intf_start=&usb_intf_start;
	padapter->intf_stop=&usb_intf_stop;
    //这个函数会调用rtl8188eu_set_intf_ops()函数, 赋值些读写芯片数据的回调函数,使用USB控制传输和块传输, 很关键, 重点关注.</span>
	//step init_io_priv
	rtw_init_io_priv(padapter, usb_set_intf_ops);
        //下面三个函数主要是读芯片的版本和软件之类的消息, 如:MAC值.....
	//step read_chip_version
	rtw_hal_read_chip_version(padapter);

	//step usb endpoint mapping
	rtw_hal_chip_configure(padapter);

	//step read efuse/eeprom data and get mac_addr
	rtw_hal_read_chip_info(padapter);	

     //这步初始化网络接口的消息,需要重点关注
	//step 5.
	if(rtw_init_drv_sw(padapter) ==_FAIL) {
		RT_TRACE(_module_hci_intfs_c_,_drv_err_,("Initialize driver software resource Failed!\n"));
		goto free_hal_data;
	}
        //注册给TCPIP协议栈
	//step 6. /* Tell the network stack we exist */
	if (register_netdev(pnetdev) != 0) {
		RT_TRACE(_module_hci_intfs_c_,_drv_err_,("register_netdev() failed\n"));
		goto free_hal_data;
	}
    //成功处理
	status = _SUCCESS;

    //失败处理
free_hal_data:
	if(status != _SUCCESS && padapter->HalData)
		rtw_mfree(padapter->HalData, sizeof(*(padapter->HalData)));
free_wdev:
	if(status != _SUCCESS) {
		#ifdef CONFIG_IOCTL_CFG80211
		rtw_wdev_free(padapter->rtw_wdev);
		#endif
	}
handle_dualmac:
	if (status != _SUCCESS)
		rtw_handle_dualmac(padapter, 0);
free_adapter:
	if (status != _SUCCESS) {
		if (pnetdev)
			rtw_free_netdev(pnetdev);
		else if (padapter)
			rtw_vmfree((u8*)padapter, sizeof(*padapter));
		padapter = NULL;
	}
exit:
	return padapter;
}



今天就到这里了, 下一章就重点讲一下, 上面重点关注的函数,及其展开的东西. 不是很喜欢打字, 有点累了, 休息下.

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值