Yang Shanghai

人与人的差距取决于工作、睡觉之外的8个小时!
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Android4.0移植3G详细记录---ICOOL210

Posted on 2014-05-27 12:21  yangshanghai  阅读(549)  评论(0编辑  收藏  举报

使用3G上网卡(或称为3G modem)

平台:Icool210,Android4.0

1. 简单使用:
1.1 选型:
中国电信:AC2728
更多型号可参考: usb_modeswitch的device_reference.txt

1.2 使用步骤(以windows为例)
a. 接上发现移动硬盘,里面有安装程序和驱动程序
b. 安装完后,移动硬盘消失;
c. 发现新硬件,自动安装好驱动程序后,发现2个串口和一个modem
d. 运行程序即可拨号上网

zeroCD: 3G上网卡自带程序,接到PC后先作为移动硬盘使用,安装程序后切换为modem

对于Linux使用过程:
a. 接上后切换mode: usb_modeswitch
b. 安装驱动程序: linux内核自带, 会出现3个ttyUSB0,1,2
c. 拨号上网:pppd

1.3 交叉编译应用程序并测试
(1)配置内核
Device Drivers--→
Network device support---→
<*> PPP (point-to-point protocol) support
[*] PPP multilink support (EXPERIMENTAL)
[*] PPP filtering
<*> PPP support for async serial ports
<*> PPP support for sync tty ports
<*> PPP Deflate compression
<*> PPP BSD-Compress compression
<*> PPP MPPE compression (encryption) (EXPERIMENTAL)
<*> PPP over Ethernet (EXPERIMENTAL)
Device Drivers---→
USB support---→
<*>USB SerialConverter support--→
[*]USB Generic Serial Driver
<*>USB driver for GSM and CDMA modems
(2)修改内核

在内核源码包中找到usb的3G驱动文件 driver/usb/serial/option.c
在其中加入
#define HUAWEI_VENDOR_ID 0x12D1(已有)
#define HUAWEI_PRODUCT_AC2728 0x1505
找到static const struct usb_device_id option_ids[] = {......}添加下面内容:
{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_AC2728) },

注:厂商ID、产品ID可通过windows或者在linux上使用lsusb查看。


(3)编译内核烧到板子上
make

应用程序源码:
http://www.draisberghof.de/usb_modeswitch/
http://www.libusb.org/
ftp://ftp.samba.org/pub/ppp/

1.4移植usb-modeswitch
(1)交叉编译libusb:
libusb:
./configure --host=arm-linux --prefix=$PWD/tmp
make
make install

为交叉编译工具链添加库文件方法
1)
把头文件和库复制进交叉工具链里
sudo cp libusb.h /usr/local/arm/4.3.2/arm-none-linux-gnueabi/libc/usr/include
sudo cp * -rfd /usr/local/arm/4.3.2/arm-none-linux-gnueabi/libc/armv4t/lib

把库复制到根文件系统的lib目录下
sudo cp *so* -d /work/nfs_root/fs_mini_mdev_new/lib/

2)也可以在编译usb_modeswitch时修改Makefile,指定库路径。一下我们使用这种办法静态编译usb_modeswitch

 

(2)交叉编译usb_modeswitch:
①usb_modeswitch目录下的usb_modeswitch.conf文件,加入以下内容:

DefaultVendor= 0x12d1
DefaultProduct=0x1505

TargetVendor=0x12d1
TargetProductList="140b,140c,1506,150f,150a"
MessageContent="55534243123456780000000000000011062000000101000100000000000000"

注:(其他的不需要修改,其他的也就两句话
DisableSwitching=0
EnableLogging=0

②修改Makefile,加上以下几句即可
LIBS = -l usb
CC = arm-linux-gcc

INCLUDEDIR = /home/liuquan/3g/libusb-0.1.12/install/include
LIBDIR = /home/liuquan/3g/libusb-0.1.12/install/lib

$(PROG): $(OBJS) usb_modeswitch.h
$(CC) -I $(INCLUDEDIR) -L $(LIBDIR) -o $(PROG) $(OBJS) $(CFLAGS) $(LIBS) $(LDFLAGS) -static

注:CC=arm-linux-gcc为修改交叉工具链,原来为CC ?= gcc
$(PROG): $(OBJS) usb_modeswitch.h
$(CC) -I $(INCLUDEDIR) -L $(LIBDIR) -o $(PROG) $(OBJS) $(CFLAGS) $(LIBS) $(LDFLAGS) -static
为在原来的基础上修改的
原来为:$(PROG): $(OBJS) usb_modeswitch.h
$(CC) -o $(PROG) $(OBJS) $(CFLAGS) $(LIBS) $(LDFLAGS)


3.将usb-modeswitch移到开发板上
将usb_switchmode移到/system/bin下,然后将usb_switchmode.conf文件夹复制进arm文件系统中的/etc/目录下
注意要修改usb_switchmode的权限


(3)交叉编译usb-modeswitch-data-20140327:
make DESTDIR=$PWD/tmp install
cd tmp
sudo cp * -rfd /work/nfs_root/fs_mini_mdev_new

 

(4)交叉编译pppd:
修改这6个文件, "$(INSTALL) -s"改为"$(INSTALL) "
chat/Makefile.linux
pppd/plugins/radius/Makefile.linux
pppd/plugins/rp-pppoe/Makefile.linux
pppd/Makefile.linux
pppdump/Makefile.linux
pppstats/Makefile.linux

./configure --host=arm-linux --prefix=$PWD/tmp
make CC=arm-linux-gcc
make CC=arm-linux-gcc install
cd tmp
sudo cp * -rfd /work/nfs_root/fs_mini_mdev_new

(5)最后把/work/nfs_root/fs_mini_mdev_new相应的文件都拷到文件系统中的相应文件夹下
然后把【pppd配置文件】中的【etc】文件夹里的全部拷到文件系统中的/etc下
注意:一定要把需要的文件全部拷到相应的文件夹下

 

2、拨号上网
1)通过串口登陆开发板
插入3G上网卡前后通过lsusb命令比较
会生成Bus 002 Device 006: ID 12d1:1505


2)执行usb_modeswitch -W -c /etc/usb_modeswitch.conf后
执行lsusb命令发现
Bus 002 Device 006: ID 12d1:1505
变成
Bus 002 Device 008: ID 12d1:140c
说明转换成功,同时在/dev/下面会生成ttyUSB*

3)在系统/var/目录下创建2个文件夹:(注意,这一步很关键,不然在进行拨号时会报Can't create lock file /var/lock/LCK..ttyUSB0: No such file or directory的错误)
mkdir /var/run -p
mkdir /var/lock -p
4)修改拨号文件etc/ppp/peers/evdo-dailer
debug
lock
nodetach
/dev/ttyUSB0
115200
user "ctnet@mycdma.cn"
password "vnet.mobi"
crtscts
show-password
usepeerdns
noauth
noipdefault
novj
novjccomp
noccp
defaultroute
ipcp-accept-local
ipcp-accept-remote
connect '/system/bin/chat -s -v -f /etc/ppp/chat/evdo-connect-chat'
disconnect '/system/bin/chat -s -v -f /etc/ppp/chat/disconnect-chat'

5)拨号上网

执行以下命令
usb_switchmode -W -c /etc/usb_modeswitch.conf
pppd call evdo-dailer &
cp /etc/ppp/resolv.conf /etc/resolv.conf

使用ifconfig ppp0查看是否拨号成功,是否已经分配好ip;得到类似以下打印信息:
ppp0: ip 10.88.1.166 mask 255.255.255.255 flags [up point-to-point running multicast]

然后打开Android上的浏览器,可以正常上网了

 

 

-----------------------------------------------------------

(4)修改Android源码,使它支持3g上网卡热插拔能自动转换为ttyUSB*
1)../system/core/libsysutils/src/NetlinkListener.cpp
bool NetlinkListener::onDataAvailable(SocketClient *cli)
{
int socket = cli->getSocket();
ssize_t count;

count = TEMP_FAILURE_RETRY(uevent_kernel_multicast_recv(socket, mBuffer, sizeof(mBuffer)));
if (count < 0) {
SLOGE("recvmsg failed (%s)", strerror(errno));
return false;
}
// 添加以下代码
NetlinkEvent *evt = new NetlinkEvent();
if (!evt->decode(mBuffer, count, mFormat)) {
SLOGE("Error decoding NetlinkEvent");
} else {
onEvent(evt);
}

delete evt;
return true;
}

2}../system/vold/NetlinkHandler.cpp
void NetlinkHandler::onEvent(NetlinkEvent *evt) {
VolumeManager *vm = VolumeManager::Instance();
const char *subsys = evt->getSubsystem();

if (!subsys) {
SLOGW("No subsystem found in netlink event");
return;
}

if (!strcmp(subsys, "block")) {
vm->handleBlockEvent(evt);
}
#if defined(BOARD_USES_HDMI) || defined(S5P_BOARD_USES_HDMI)
else if ((!strcmp(subsys, "misc")) || (!strcmp(subsys, "video4linux"))) {
vm->handleMiscEvent(evt);
}
#endif
//添加以下代码
else if (!strcmp(subsys, "usb")) {
vm->handleUsbEvent(evt);
}
}
3)../system/vold/VolumeManager.h
class VolumeManager {
public:
//增加如下一行
void handleUsbEvent(NetlinkEvent *evt);
}
/////////////////////////////////////////////////////////////
void VolumeManager::handleUsbEvent(NetlinkEvent *evt) {
const char *devtype = evt->findParam("DEVTYPE");
char *cmd;
if(1 == evt->getAction() && !strcmp(devtype, "usb_device")) {
asprintf(&cmd, "usb_modeswitch -W -c /etc/usb_modeswitch.conf"); //务必在文件系统中存在/etc/usb_modeswitch.conf
system(cmd);
free(cmd);
}
}



使用ifconfig ppp0查看是否拨号成功,是否已经分配好ip;得到类似以下打印信息:
ppp0: ip 10.88.1.166 mask 255.255.255.255 flags [up point-to-point running multicast]

然后打开Android上的浏览器,可以正常上网了

参考文章:
嵌入式Linux下3G USB Modem的使用 - 空之轨迹~约修亚 - 博客频道 - CSDN.NET.htm
http://blog.csdn.net/ling1874/article/details/8148822
http://wenku.baidu.com/link?url=HLRk3U9Jbr2Zx35e5knamYeUKYs14bhV3F9-hzC6rWMwdxCu2gTtAR89VBAdpoAF4UC9LmxCPxGLbjAu_XoSXuy065ZbbvfwtWm9vLy5UWe

配置文件最全:
HI3515海思开发板移植3G模块笔记 - 倔强的晓奇 - 博客频道 - CSDN.NET.htm
http://blog.csdn.net/alangdangjia/article/details/9413009

好文章:ppp及usb_modeswitch等工具移植说明_百度文库.htm
http://wenku.baidu.com/link?url=Y7gsW5izmXwzur3VS3hGYWV_k_glZwzmu7Prdh_F69LuFxcOGT1LwhtsmXA3TVhR6F0l8_ozspcQvO08nlHex2yss0EW7wWIzysw9cZn-wu

华为3GE261在Android4.0、linux3.0.8内核上的移植记录1
http://blog.csdn.net/w6028819321/article/details/8883044