11.23

搞了个广和通FM650-CN 03的国产5g模块,打算用在openwrt软路由上。需求:在校改善校园网网络,或者带回老家使用(老家没宽带)。在csdn上搜了相关测评,说可以免驱,没想到手后插上竟无法直接使用。接上win10系统提示缺少相关驱动,而Linux下lsusb能识别到但却完全使用不了。又看到有帖子说在win11下可以读取,接了舍友的笔记本插上后提示缺少ncm驱动。相继搜索了该模块的文档,仍没找到解决方法。

20231123215910.pngb116b42887aa4cf99c510fa4860a448f.png

恰巧在咸鱼上搜到有一个卖家出同款模块的成品,而且还演示了在openwrt下可正常使用,便向卖家老哥请教了一番。

不得不说,没有这个老哥的帮助,这个模块就要在我手上了吃灰了。老哥人很好,帮我编译了对应的openwrt固件。刷上老哥编译的固件后拨号相关的驱动都有了,但还是没成功拨号上网。

老哥建议我把模块接windows上测试一下,同时还发了份对应的驱动,这是我找了大半天都没找到的,不得不说还是专业的人办专业的事。在win下打上驱动成功使用putty连接串口使用AT命令,老哥还把对应的指令发了过来。老哥说我的模块在ncm模式下工作,切换到自动的ecm即可

AT+GTUSBMODE=35

AT+GTAUTOCONNECT=1

AT+CFUN=15

把模块工作模式改为自动拨号上网并重启,插回openwrt后发现模块还是没能成功获取ip

那天没搞好,郁闷地到了周末

11.25

热心的老哥说直接远程帮我调一下,发现模块设置工作模式不成功,每次设置提示OK,但重启后总是为36,这下陷入了困境。

当时我找了下这个模块的相关文档,发现了极有可能是供电问题(模块工作需要4v 4a)看到4a时有点惊讶,这下要排查的就很多了,转接板供电,软路由供电。因为没相关电器设备,排查起来很麻烦。老哥建议我在台式上试试,毕竟台式机供电带这个模块应该没什么问题。但是,在win上这个不能改变工作模式的问题还是存在。

20231125171011.png

之后找了下这个模块原先工作的电路板,发现转接板供电似乎真的差点意思,2R2,4r7,奈何没学过电路相关的,无法深究。我直接询问了老哥正常使用的转接板,可是那要100+,而且等到货也要时间。老哥建议我先从便宜的开始,换一根带辅助供电的usb3.0线试试

20231125130543.jpg20231125203518.jpg

11.28

带辅助供电的线到了,换上后还是不能成功切换,便把转接板退了,斥巨资120买下确定是能支持FM650的转接板

后续

经排查发现该模块只能在ncm模式下工作,这就有点小麻烦,所以并没有继续折腾

记录编译openwrt驱动相关操作

来源:https://blog.csdn.net/bailiqiuyu/article/details/124489444

  • 内核选中USB driver for GSM and CDMA modems 组件,增加设备支持打开内核源码文件ption.c({kernel/drivers/usb/serial/option.c)

#define FIBOCOM_VENDOR_ID 0x2CB7
#define FIBOCOM_PRODUCT_FG650_ECM 0x0A04
#define FIBOCOM_PRODUCT_FG650_NCM 0x0A05
#define FIBOCOM_PRODUCT_FG650_RNDIS 0x0A06
 
 
 
static const struct usb_device_id option_ids[] = {
 
#if 1
{ USB_DEVICE(FIBOCOM_VENDOR_ID, FIBOCOM_PRODUCT_FG650_ECM)},
{ USB_DEVICE(FIBOCOM_VENDOR_ID, FIBOCOM_PRODUCT_FG650_NCM)},
{ USB_DEVICE(FIBOCOM_VENDOR_ID, FIBOCOM_PRODUCT_FG650_RNDIS)},
#endif

在 USB 串口驱动中,过滤 ECM/NCM/RNDIS 接口。由于 USB 串口跟 ECM/NCM/RNDIS 都属于 非标准 CDC 设备,需要防止 ECM/NCM/RNDIS 口被 USB 串口驱动加载而导致无法正常加载 ECM/NCM/RNDIS 口驱动。

  • 比较新的 kernel 版本,在 option.c 中的 opiton_ids 添加代码如下:

{ USB_DEVICE(FIBOCOM_VENDOR_ID, FIBOCOM_PRODUCT_FG650_ECM),
  .driver_info =  RSVD(0) | RSVD(1) | RSVD(5)},
{ USB_DEVICE(FIBOCOM_VENDOR_ID, FIBOCOM_PRODUCT_FG650_NCM),
  .driver_info =  RSVD(0) | RSVD(1) | RSVD(6)},
{ USB_DEVICE(FIBOCOM_VENDOR_ID, FIBOCOM_PRODUCT_FG650_RNDIS),
  .driver_info =  RSVD(0) | RSVD(1) | RSVD(6)
},
  • 比较老的内核,在option_ids[]添加

static const struct usb_device_id option_ids[] = {
 
#if 1
{ USB_DEVICE(FIBOCOM_VENDOR_ID, FIBOCOM_PRODUCT_FG650_ECM)},
{ USB_DEVICE(FIBOCOM_VENDOR_ID, FIBOCOM_PRODUCT_FG650_NCM)},
{ USB_DEVICE(FIBOCOM_VENDOR_ID, FIBOCOM_PRODUCT_FG650_RNDIS)},
 
#endif
  • 并在 probe 函数内判断当前的 interface num 进行过滤,具体如下:

#if 1
 
	if (serial->dev->descriptor.idVendor == cpu_to_le16(FIBOCOM_VENDOR_ID) &&
		serial->dev->descriptor.idProduct == cpu_to_le16(FIBOCOM_PRODUCT_FG650_ECM) &&
		serial->interface->cur_altsetting->desc.bInterfaceNumber <= 1) {
			printk(KERN_INFO "Discover the 4th interface for fibocom\n");
			return -ENODEV;
	}
	if (serial->dev->descriptor.idVendor == cpu_to_le16(FIBOCOM_VENDOR_ID) &&
		serial->dev->descriptor.idProduct == cpu_to_le16(FIBOCOM_PRODUCT_FG650_NCM) &&
		serial->interface->cur_altsetting->desc.bInterfaceNumber <= 1) {
			printk(KERN_INFO "Discover the 4th interface for fibocom\n");
			return -ENODEV;
	}
	if (serial->dev->descriptor.idVendor == cpu_to_le16(FIBOCOM_VENDOR_ID) &&
		serial->dev->descriptor.idProduct == cpu_to_le16(FIBOCOM_PRODUCT_FG650_RNDIS) &&
		serial->interface->cur_altsetting->desc.bInterfaceNumber <= 1) {
			printk(KERN_INFO "Discover the 4th interface for fibocom\n");
			return -ENODEV;
	}
 
#endif	
	/* Store the device flags so we can use them during attach. */
	usb_set_serial_data(serial, (void *)device_flags);
 
	return 0;

驱动,AT命令资料分享:https://pan.baidu.com/s/1Kw1F8jg-HZ3HpnTJOqGkfA?pwd=34sb