MYD-YA157C系列定制板RM500Q-GL驱动移植笔记

Posted 划水程序猿阿硕

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MYD-YA157C系列定制板RM500Q-GL驱动移植笔记相关的知识,希望对你有一定的参考价值。

MYD-YA157C系列定制板RM500Q-GL驱动移植笔记 2021.8.12

一、准备工作

(1)YA157C开发板一块

 

 

 

 

 

 

 

 

 

(2)     Ipex1代转SMA母,转接线若干

(3)     Ipex4代转SMA母,转接线若干

 

 

 

(4)     跳线帽若干,并安装到如下图所示的指定位置

(5G模块硬件拉高开机,默认状态)

(蓝色带包5G模块软件拉高开机)

(5)       准备一个linux环境用来交叉编译,这里我使用了deepin系统,并将其安装在VMware虚拟机环境下

 

 

 

(6)       参考《MYD-YA157C_Linux软件开发指南V2.0.pdf》准备交叉编译环境

  • l  安装米尔定制的 SDK

我们在使用 Yocto 构建完系统镜像之后,还可以使用 Yocto 构建一套可扩展的 SDK。在米尔提供的光盘镜像中包含一个编译好的 SDK 包,位于:03-Tools/Complie Toolchain/QT-SDK/sdk-qt.tar.xz,这个 SDK 中除了包含一个独立的交叉开发工具链还提供 qmake, 目标平台的 sysroot, Qt 应用开发所依赖的库和头文件等。用户可以直接使用这个 SDK 来建立一个独立的开发环境,单独编译 Bootloader,Kernel 或者编译自己的应用程序。

  • l  拷贝 SDK 到 Linux 目录并解压

将 SDK 压缩包拷贝到deepin 下的用户工作目录,如$HOME/work 下,解压文件,得

到安装脚本文件,如下:

PC$ cd $HOME/work

PC$ tar -Jxvf sdk-qt.tar.xz

sdk
  • l  查看脚本文件

进入 SDK 目录,可以看到下面安装脚本文件:

meta-toolchain-qt5-openstlinux-eglfs-myir-x86_64-toolchain-3.1-snapshot.host.manifest

meta-toolchain-qt5-openstlinux-eglfs-myir-x86_64-toolchain-3.1-snapshot.sh

meta-toolchain-qt5-openstlinux-eglfs-myir-x86_64-toolchain-3.1-snapshot.target. manifest

meta-toolchain-qt5-openstlinux-eglfs-myir-x86_64-toolchain-3.1-snapshot.testdata.json
  • l  执行安装脚本
PC$ ./meta-toolchain-qt5-openstlinux-eglfs-myir-x86_64-toolchain-2.6-snapshot.sh
  • l  选择安装目录

SDK 默认被安装到/opt/st/myir/3.1-snapshot 目录下,用户也可以根据提示自己选择合适的目录,具体根据提示进行操作:

ST OpenSTLinux - EGLfs - (A Yocto Project Based Distro) SDK installer version 3.1- snapshot

===============================================

Enter target directory for SDK (default: /opt/st/myir/3.1-snapshot):

You are about to install the SDK to "/opt/st/myir/3.1-snapshot". Proceed [Y/n]? y

[sudo] password for licy:

Extracting SDK

........................................................................................................................................... done

Setting it up...done

SDK has been successfully set up and is ready to be used. Each time you wish to use the SDK in a new shell session, you need to source the

environment setup script e.g. $ . /opt/st/myir/3.1-snapshot/environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi

 

  • l  测试SDK

安装完成后,使用以下命令设置环境变量,测试 SDK 是否完成:

PC$ source /opt/st/myir/3.1-snapshot/environment-setup-cortexa7t2hf-neon-vfp

v4-ostl-linux-gnueabi

PC$ $CC --version

arm-ostl-linux-gnueabi-gcc (GCC) 8.2.0

Copyright (C) 2018 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO

warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

米尔提供的 SDK 中除了包含交叉工具链,还包含 Qt 库,qmake 等开发 Qt 应用程序所需的资源,这些是后续使用 QT Creator 进行应用程序开发和调试的基础。

二、上电开机,通过网络连接开发板,登陆后,执行lsusb命令,正常情况下可以识别移远RM500Q-GL的VID与PID如图所示(我已经移植了驱动,所以可以正常识别型号,如果未做驱动移植,这里可能只会显示2c7c:0800)。

 

 

 

三、参考官方文档《Quectel_LTE&5G_Linux_USB_Driver_User_Guide_V2.0.pdf》移植驱动

(1)为了识别模块,需要将下图最后一行RM500Q的VID和PID信息添加到[KERNEL]/drivers/usb/serial/option.c文件的指定位置中(米尔提供的内核中已添加RM500Q的VID和PID,可省略此步骤)

 

 

 

(2)     添加Zero Packet Mechanism

根据USB协议的要求,需要在bulk-out传输过程中增加处理零包的机制,添加如下语句(米尔提供的内核中已定义,可省略此步骤)。

  • l    For Linux kernel version higher than 2.6.34, add the following statements to the file
[KERNEL]/drivers/usb/serial/usb_wwan.c.

static struct urb *usb_wwan_setup_urb(struct usb_serial *serial, int endpoint,

          int dir, void *ctx, char *buf, int len,void (*callback) (struct urb *))

{

……

  usb_fill_bulk_urb(urb, serial->dev,

     usb_sndbulkpipe(serial->dev, endpoint) | dir,

     buf, len, callback, ctx);

 #if 1   //Added by Quectel for zero packet

 if (dir == USB_DIR_OUT) {

   struct usb_device_descriptor *desc = &serial->dev->descriptor;

 

   if (desc->idVendor == cpu_to_le16(0x2C7C))

    urb->transfer_flags |= URB_ZERO_PACKET ;

 }

#endif

  return urb;

}

 

 

  • l    For Linux kernel version lower than 2.6.35, add the following statements to the file
[KERNEL]/drivers/usb/serial/option.c.

/* Helper functions used by option_setup_urbs */

static struct urb *option_setup_urb(struct usb_serial *serial, int endpoint,

   int dir, void *ctx, char *buf, int len,

   void (*callback)(struct urb *))

{

……

  usb_fill_bulk_urb(urb, serial->dev,

     usb_sndbulkpipe(serial->dev, endpoint) | dir,

     buf, len, callback, ctx);

 #if 1   //Added by Quectel for zero packet

 if (dir == USB_DIR_OUT) {

   struct usb_device_descriptor *desc = &serial->dev->descriptor;

 

   if (desc->idVendor == cpu_to_le16(0x2C7C))

    urb->transfer_flags |= URB_ZERO_PACKET ;

#endif

return urb;

}

 

(3)     配置重置机制

当MCU进入Suspend/Sleep模式时,部分USB主机控制器/USB hub会断电或复位,当MCU退出Suspend/Sleep模式后,部分USB主机控制器/USB hub将无法用于USB恢复。需要通过添加以下语句启用reset-resume机制。

  • l  For Linux kernel version higher than 3.4, add the following statements to the file
[KERNEL]/drivers/usb/serial/option.c.

static struct usb_serial_driver option_1port_device = {

……

#ifdef CONFIG_PM

  .suspend           = usb_wwan_suspend,

  .resume            = usb_wwan_resume,

#if 1  //Added by Quectel

  .reset_resume   = usb_wwan_resume,

#endif

#endif

};

 

 

  • l  For Linux kernel version lower than 3.5, add the following statements to the file
[KERNEL]/drivers/usb/serial/usb-serial.c.

/* Driver structure we register with the USB core */

static struct usb_driver usb_serial_driver = {

        .name =         "usbserial",

        .probe =        usb_serial_probe,

        .disconnect =   usb_serial_disconnect,

        .suspend =      usb_serial_suspend,

        .resume =       usb_serial_resume,

#if 1 //Added by Quectel

        .reset_resume = usb_serial_resume,

#endif

        .no_dynamic_id =        1,

        .supports_autosuspend = 1,

};

 

(4)     添加对MBIM, GobiNet和QMI_WWWAN驱动的支持

当需要使用MBIM、GobiNet或QMI_WWAN驱动时,需要添加如下语句,防止模块接口4作为USB串口设备使用。

  • l  For Linux kernel version higher than 2.6.30, add the following statements to the file
[KERNEL]/drivers/usb/serial/option.c.

static int option_probe(struct usb_serial *serial, const struct usb_device_id *id) {

  struct usb_wwan_intf_private *data;

  ……

#if 1  //Added by Quectel

//Quectel modules’s interface 4 can be used as USB network device

       if (serial->dev->descriptor.idVendor == cpu_to_le16(0x2C7C)) {

               //some interfaces can be used as USB Network device (ecm, rndis, mbim)

               if (serial->interface->cur_altsetting->desc.bInterfaceClass != 0xFF) {

                       return -ENODEV;

               }

               //interface 4 can be used as USB Network device (qmi)

               else if (serial->interface->cur_altsetting->desc.bInterfaceNumber >= 4) {

                       return -ENODEV;

               }

       }

#endif

  /* Store device id so we can use it during attach. */

  usb_set_serial_data(serial, (void *)id);

  return 0;

}

 

  • l  For Linux kernel version lower than 2.6.31, add the following statements to the file
[KERNEL]/drivers/usb/serial/option.c.

static int option_startup(struct usb_serial *serial)

{

……

  dbg("%s", __func__);

#if 1  //Added by Quectel

       if (serial->dev->descriptor.idVendor == cpu_to_le16(0x2C7C)) {

               //some interfaces can be used as USB Network device (ecm, rndis, mbim)

               if (serial->interface->cur_altsetting->desc.bInterfaceClass != 0xFF) {

                       return -ENODEV;

               }

               //interface 4 can be used as USB Network device (qmi)

               else if (serial->interface->cur_altsetting->desc.bInterfaceNumber >= 4) {

                       return -ENODEV;

               }

       }

#endif

……

}

 

(5)     配置内核

解压米尔提供的iso文件,进入04_Sources,找到MYiR-STM32-kernel.tar.bz2,放入即将进行交叉编译的linux环境中(在这里指安装了deepin的虚拟机),并解压

  • l  进入内核目录
cd myir-st-linux
  • l  创建输出文件夹
mkdir -p ../build
  • l  配置内核
make -j16 ARCH=arm O="$PWD/../build" myc-ya157c_defconfig

#注意:此处的-j16是指使用16个处理器进行多线程同时编译,如果你只给虚拟机分配了两个处理器,这里就改为-j2依次类推。
  • l  打开USB driver for GSM and CDMA modems 

进入刚创建的build目录

cd ../build

使用下面的命令编译内核

Make menuconfig

使用以下选项启用CONFIG_USB_SERIAL_OPTION。

make menuconfig

[*] Device Drivers →

  [*] USB Support →
   [*] USB Serial Converter support →

         [*] USB driver for GSM and CDMA modems

使用TAB键,移动光标至Save,然后按照提示保存,保存后执行多次ESC键以退出界面。

(6)     配置GobiNet驱动

  • l  在模块中安装GobiNet驱动程序后,将创建一个网络设备和一个QMI通道。网络设备命名为ethX(内核版本为2.6.39及以下为usbX), QMI通道命名为/dev/ qcqmix。网络设备用于数据传输,QMI通道用于QMI消息交互。
  • l  解压Quectel_Linux&android_GobiNet_Driver_V1.6.zip,将里面的文件除了Makefile、makefile、两个txt文件之外,全部复制到[KERNEL]/drivers/net/usb/(或者[KERNEL]/drivers/usb/net/如果内核版本低于2.6.22
  • l  修改内核配置

在build目录下再次执行make menuconfig,进入

[*] Device Drivers →  

-*- Network device support →                                                                  

USB Network Adapters →

{*} Multi-purpose USB Networking Framework

确保Multi-purpose USB Networking Framework为打开状态(按Y即可打开)

保存并退出,系统生成.config文件。

  • l  在[KERNEL]/drivers/net/usb/Makefile(如果内核版本低于2.6.22,则为[KERNEL]/drivers/usb/net/Makefile)文件中添加以下语句。
  • obj-y += GobiNet.o
    GobiNet-objs := GobiUSBNet.o QMIDevice.o QMI.o

请注意:对于米尔的这个开发板子,需要使用obj-m的方式,obj-m表示把文件test.o作为"模块"进行编译,不会编译到内核,但是会生成一个独立的 "test.ko" 文件;obj-y表示把test.o文件编译进内核;本人在这里卡顿了许久,编译成功后一直打不上驱动,最后在这个地方得到了解决,即在上述文件夹中,添加以下内容:

  • obj-m += GobiNet.o
    GobiNet-objs := GobiUSBNet.o QMIDevice.o QMI.o

保存并退出。

(7)     编译内核

  • l  加载SDK环境变量
Source /opt/st/myir/3.1-snapshot/environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi
  • l  配置内核
make ARCH=arm O="$PWD/../build" myc-ya157c_defconfig
  • l  编译内核
make -j16 ARCH=arm uImage vmlinux dtbs LOADADDR=0xC2000040 O="$PWD/../build"

make -j16 ARCH=arm modules O="$PWD/../build"

以16线程同时编译,大约编译两分钟。以单线程运行时,编译过程大约需要15-20分钟,请合理分配虚拟机CPU,保证最大化的利用系统资源,节省编译时间。

  • l  生成输出文件
make -j16 ARCH=arm INSTALL_MOD_PATH="$PWD/../build/install_artifact" modules_install O="$PWD/../build"

 

mkdir -p $PWD/../build/install_artifact/boot/

 

cp $PWD/../build/arch/arm/boot/uImage $PWD/../build/install_artifact/boot/

 

cp $PWD/../build/arch/arm/boot/dts/st*.dtb $PWD/../build/install_artifact/boot/

l  将编译完成的文件传输到开发板并更新kernel

进入build/install_artifact/目录,执行以下命令

scp -r boot/* root@192.168.2.66:/boot

#更新 uImage 与设备树,此处假设开发板的ip为192.168.2.66,如果有密码,还需输入密码
rm lib/modules/5.4.31/source lib/modules/5.4.31/build

#删除编译生成文件 build/install_artifact/lib 下的软连接文件
scp -r lib/modules/* root@192.168.2.66:/lib/modules/

#更新内核 modules
  • l  连接到开发板,执行同步&重启命令

使用finalshell等软件,连接到开发板

执行以下命令完成同步&重启

sync & reboot

四、测试驱动是否正常安装

(1)     使用lsusb命令,查看能否正常显示RM500Q-GL的型号

(2)     使用ifconfig命令,查看是否新增“eth1”网卡

 

一、交叉编译拨号软件

(1)     解压Quectel_QConnectManager_Linux_V1.6.0.6

(2)     进入Quectel_QConnectManager_Linux_V1.6.0.6,在此处打开终端,加载环境变量

source /opt/st/myir/3.1-snapshot/environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi

(3)     执行编译

make CROSS_COMPILE=arm-hisiv300-linux-

 

编译完成后,将该文件夹拷贝至开发板/home/root目录下

(4)     给该目录下的.sh文件添加可执行权限

chmod a+x *.sh

(5)     运行拨号软件

./quectel-CM &

(出现以上信息代表驱动已经成功移植,5G模块已能够被系统识别,此处我没有插入SIM卡,所以是sim_absent状态)

 

以上是关于MYD-YA157C系列定制板RM500Q-GL驱动移植笔记的主要内容,如果未能解决你的问题,请参考以下文章

米尔STM32MP157系列开发板外设资源分享

Wallys/Support:QUECTEL RM500Q-GL&Support:

TM32MP1核心板资料(基于米尔电子MYC-YA157C)

兼容树莓派引脚定义,适配多种模块--米尔百变STM32MP1开发板演示

构建一个适合stm32mp157系列开发板的嵌入式Linux系统

STM32MP157开发板评测:华清远见FS-MP1A开发板初体验!