linux平台Rk3588驱动ec20上传数据到onenet(移值+驱动)

EC20简单介绍一下哈

EC20 是移远通信推出的 LTE Cat 4 无线通信模块,采用 LTE 3GPP Rel.11 技术,支持最大下行速率 150Mbps 和 最大上行速率 50Mbps ;同时在封装上兼容移远通信 UMTS/HSPA+ UC20 模块以及移远通信多网络制式 LTE Cat 3 模 块,实现了 3G 网络与 4G 网络之间的无缝切换。

注意:rk高端芯片一般制作开发板的合作厂商都会配置好了有关ec20的驱动,如若没有或有问题请参考一下内容

一、内核源码修改部分

1.1:添加VID和PID

文件名

[KERNEL]/drivers/usb/serial/option.c

添加如下内容(有Quectel EC20便可,其他可以不要

static const struct usb_device_id option_ids[] = {

#if 1 //Added by Quectel

{ USB_DEVICE(0x2C7C, 0x0125) }, /* Quectel EC20 R2.0/EC20 R2.1/EC25/EG25-G/EM05 */ { USB_DEVICE(0x2C7C, 0x0121) }, /* Quectel EC21/EG21-G */

{ USB_DEVICE(0x2C7C, 0x0191) }, /* Quectel EG91 */

{ USB_DEVICE(0x2C7C, 0x0195) }, /* Quectel EG95 */

{ USB_DEVICE(0x2C7C, 0x0306) }, /* Quectel EG06/EP06/EM06 */

{ USB_DEVICE(0x2C7C, 0x0512) }, /* Quectel EG12/EM12/EG18 */

{ USB_DEVICE(0x2C7C, 0x0296) }, /* Quectel BG96 */

{ USB_DEVICE(0x2C7C, 0x0700) }, /* Quectel BG95/BG77/BG600L-M3/BC69 */ { USB_DEVICE(0x2C7C, 0x0435) }, /* Quectel AG35 */

{ USB_DEVICE(0x2C7C, 0x0415) }, /* Quectel AG15 */

{ USB_DEVICE(0x2C7C, 0x0452) }, /* Quectel AG520R */

{ USB_DEVICE(0x2C7C, 0x0455) }, /* Quectel AG550R */

{ USB_DEVICE(0x2C7C, 0x0620) }, /* Quectel EG20 */

{ USB_DEVICE(0x2C7C, 0x0800) }, /* Quectel RG500Q/RM500Q/RG510Q/RM510Q */

#endif

1.2:添加零包机制选择性添加

文件名 [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;

}

1.3:添加复位机制选择性添加

文件位置

[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

};

1.4:使用MBIM, GobiNet or QMI_WWAN驱动

文件位置

[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;

}

二、内核配置

Device Drivers --->

       [*] USB support --->

            <*> USB Serial Converter support --->

                   <*> USB driver for GSM and CDMA modems         //选上

[*] Device Drivers →

 -*- Network device support

 USB Network Adapters

 {*} Multi-purpose USB Networking Framework

[*] Device Drivers →

 -*- Network device support →

USB Network Adapters →

{*} Multi-purpose USB Networking Framework QMI_WWAN driver for Qualcomm MSM based 3G and LTE modems

<*>QMI_WWAN driver for Qualcomm MSM based 3G and LTE modems

Device Drivers --->

        [*] Network device support --->

                         // 将这里面所有的ppp 的支持多选上

Device Drivers  --->

               Network device support  --->

                     USB Network Adapters  --->

                            <*> Multi-purpose USB NetworkingFramework

                                   <*>  CDC Ethernet support (smart devices such ascable modems) (NEW)

                                   -*-   CDC NCM support

                                   <*>   Huawei NCM embedded AT channel support

                                   <*>   Simple USB Network Links (CDC Ethernetsubset) (NEW)

三、内核修改

3.1:添加usb自动支持

文件位置:[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

//For USB Auto Suspend

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

pm_runtime_set_autosuspend_delay(&serial->dev->dev, 3000);

usb_enable_autosuspend(serial->dev);

}

#endif

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

usb_set_serial_data(serial, (void *)id);

return 0;

}

3.2:添加usb远程唤醒功能支持选择性添加

文件位置

[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

//For USB Remote Wakeup

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

device_init_wakeup(&serial->dev->dev, 1); //usb remote wakeup

}

#endif

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

usb_set_serial_data(serial, (void *)id);

return 0;

}

四、其他操作

4.1 编译内核

可根据环境不同选用不同的命令编译适合自己开发板的内核

4.2 烧录内核

可以看到/dev下有这几个串口文件

4.3 编译拨号工具

解压原厂quectel-CM源码,放在系统的任意路径下,它里面有Makefile文件,我们先指定硬件架构和交叉编译链,再make,在当前目录下便可生成执行文件quectel-CM。例如rv1126

ARCH=arm

      CROSS_COMPILE=arm-linux-gnueabihf-

指定完成之后执行make命令即可编译拨号工具

4.4 执行拨号

quectel-CM &

执行完成之后   会自动拿到ip   ping百度能ping同则表示4G模块移植成功

五、连接移动onenet物联网平台

在完成以上操作后/dev/ttyusb*节点(该类设备节点为usb转串口,作为开发人员可直接当作串口来操作它)

本文采用mqtt协议连接物联网平台,下面是常用AT指令(简单例程附在文章最后):

// 配置EC20模块连接到网络
    send_at_command("AT+CGATT=1");  // 激活移动设备附着

    // 配置MQTT连接参数
    send_at_command("AT+QMTOPEN=0,\"mqtt.eclipse.org\",1883");  // 打开MQTT连接

    // 认证并连接到MQTT代理
    send_at_command("AT+QMTCONN=0,\"client_id\",\"username\",\"password\"");  // 连接到MQTT代理

    // 发布数据到MQTT代理
    char data_to_publish[] = "Hello from EC20!";
    send_at_command("AT+QMTPUBEX=0,1,0,0,\"topic\",0");  // 发布消息
    send_at_command(data_to_publish);

    // 断开MQTT连接
    send_at_command("AT+QMTDISC=0");  // 断开MQTT连接

    // 关闭移动设备附着
    send_at_command("AT+CGATT=0");

以上是上传数据的基本流程send_at_command函数为自己编写的写入功能函数,这里需要注意的是上传设备数据时需转换为json格式。

Onenet的基本操作不在赘述

需要注意的点在于passwd需要进行简单转换;根据密钥生成,为便于开发者开发,平台提供Token生成工具

Token生成工具:

https://open.iot.10086.cn/doc/mqtt/images/tools/token.exeicon-default.png?t=N7T8https://open.iot.10086.cn/doc/mqtt/images/tools/token.exe

​​​​​​时间戳(Unix timestamp)转换工具 - 在线工具Unix时间戳转换可以把Unix时间转成北京时间icon-default.png?t=N7T8https://tool.lu/timestamp/

六、数据上传示例代码(代码仅供参考)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <pthread.h>

#define SERIAL_PORT "/dev/ttyUSB2"  // 根据实际情况更改串口路径
#define BAUD_RATE B115200

int serial_fd;
pthread_mutex_t serial_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t response_cond = PTHREAD_COND_INITIALIZER;
int response_ready = 0;

void init_serial() {
    // ... (与之前相同的初始化代码)
    serial_fd = open(SERIAL_PORT, O_RDWR);
    if (serial_fd == -1) {
        perror("Error opening serial port");
        exit(EXIT_FAILURE);
    }

    struct termios tty;
    if (tcgetattr(serial_fd, &tty) != 0) {
        perror("Error from tcgetattr");
        exit(EXIT_FAILURE);
    }

    cfsetospeed(&tty, BAUD_RATE);
    cfsetispeed(&tty, BAUD_RATE);

    tty.c_cflag |= (CLOCAL | CREAD);
    tty.c_cflag &= ~PARENB;
    tty.c_cflag &= ~CSTOPB;
    tty.c_cflag &= ~CSIZE;
    tty.c_cflag |= CS8;

    tcflush(serial_fd, TCIFLUSH);

    if (tcsetattr(serial_fd, TCSANOW, &tty) != 0) {
        perror("Error from tcsetattr");
        exit(EXIT_FAILURE);
    }
}

void send_at_command(const char *command) {
    //pthread_mutex_lock(&serial_mutex);

    write(serial_fd, command, strlen(command));
    write(serial_fd, "\r\n", 2);
printf("Send: %s\r\n", command);// pthread_mutex_unlock(&serial_mutex);
    // 等待回复完成
    while (!response_ready) {
       // pthread_cond_wait(&response_cond, &serial_mutex);
    }
printf("Re001234\r\n");
    // 重置状态
    response_ready = 0;

   
}

void *receive_thread(void *arg) {
    char buffer[256];
    ssize_t n;

    while (1) {
        pthread_mutex_lock(&serial_mutex);

        // 读取串口缓冲区
        n = read(serial_fd, buffer, sizeof(buffer) - 1);
        pthread_mutex_unlock(&serial_mutex);
        if (n > 0) {
            buffer[n] = '\0';
            printf("Received: %s\r\n", buffer);

            // 通知主线程回复已经准备好
            response_ready = 1;
            //pthread_cond_signal(&response_cond);
        }  
    }

    return NULL;
}

int main() {
    pthread_t tid;
    init_serial();

    // 创建接收线程
    if (pthread_create(&tid, NULL, receive_thread, NULL) != 0) {
        perror("Error creating receive thread");
        exit(EXIT_FAILURE);
    }

    // 配置EC20模块连接到网络
    send_at_command("AT+CGATT=1");
printf("Re00123\r\n");
send_at_command("AT+QMTCFG=\"version\",0,4\r\n");
    // 配置MQTT连接参数
    send_at_command("AT+QMTOPEN=0,\"mqtts.heclouds.com\",1883\r\n"); 
    printf("Re001\r\n");
    usleep(1000000);

    // 认证并连接到MQTT代理
    send_at_command("AT+QMTCONN=0,\"test\",\"559vYG4tGp\",\"version=2018-10-31&res=products%2F559vYG4tGp%2Fdevices%2Ftest&et=1735796532&method=sha1&sign=4fp%2Bxw97YRu0g%2BGCS6shUncq1mw%3D\"\r\n");  // 连接到MQTT代理
    printf("Re022\r\n");//
    usleep(1000000);
    send_at_command("AT+QMTSUB=0,1,\"$sys/559vYG4tGp/test/thing/property/set\",1\r\n");
    usleep(1000000);
    send_at_command("AT+QMTSUB=0,1,\"$sys/559vYG4tGp/test/thing/property/reply\",1\r\n");
    usleep(1000000);
    // 发布数据到MQTT代理
    char data_to_publish[1024] = {0};
 send_at_command("AT+QMTPUBEX=0,0,0,0,\"$sys/559vYG4tGp/test/thing/property/post\",50\r\n");
       usleep(1000000);
    send_at_command(data_to_publish);
    // 断开MQTT连接
    send_at_command("AT+QMTDISC=0");

    // 关闭移动设备附着
    send_at_command("AT+CGATT=0");

    // 等待接收线程结束
    pthread_join(tid, NULL);

    // 关闭串口
    close(serial_fd);

    return 0;
}

七、连接onenet终端log

成功后就可以在onenet上看到设备在线了

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值