美文网首页
LYNQ_L501 4G模块在嵌入式linux系统下RNDIS联

LYNQ_L501 4G模块在嵌入式linux系统下RNDIS联

作者: 车到山前必有路2021 | 来源:发表于2020-10-16 18:23 被阅读0次

首先编译并安装驱动文件

drivers/usb/class/cdc-acm.ko

drivers/net/usb/usbnet.ko

drivers/net/usb/cdc_ether.ko

drivers/net/usb/rndis_host.ko

安装顺序如下:

insmod cdc-acm.ko

insmod usbnet.ko

insmod cdc_ether.ko

insmod rndis_host.ko

然后调用sample_serial串口读写程序发送AT指令

初始直接使用echo cat 来读写AT指令,发现不太正常,写个简单的读写AT指令的串口程序(sample_serial)来辅助联网。

sample_serial /dev/ttyACM1 query

sample_serial /dev/ttyACM1 auto4g

如果读取到NETOPEN SUCCESS,表明模块联网成功。

ifconfig eth1 up

udhcpc -i eth1

ping www.baidu.com

file sample_serial.c

#include <stdio.h>

#include <string.h>

#include <termios.h>

#include <fcntl.h>

#ifndef FALSE

#define FALSE   (0)

#endif

#ifndef TRUE

#define TRUE    (!FALSE)

#endif

int speed_arr[] = {B115200, B38400, B19200, B9600, B4800, B2400, B1200, B300,  

                   B115200, B38400, B19200, B9600, B4800, B2400, B1200, B300, };  

int name_arr[] = {115200, 38400, 19200, 9600, 4800, 2400, 1200,  300,   

                  115200, 38400, 19200, 9600, 4800, 2400, 1200,  300, };  

void set_speed(int fd, int speed) {

    int   i;

    int   status;

    struct termios   Opt;

    tcgetattr(fd, &Opt);

    for ( i= 0;  i < sizeof(speed_arr) / sizeof(int);  i++) {

        if  (speed == name_arr[i]) {

            tcflush(fd, TCIOFLUSH);

            cfsetispeed(&Opt, speed_arr[i]);

            cfsetospeed(&Opt, speed_arr[i]);

            status = tcsetattr(fd, TCSANOW, &Opt);

            if  (status != 0) {          

                perror("tcsetattr fd1");    

                return;       

            }

            tcflush(fd,TCIOFLUSH);

        }

    }  

}  

int set_parity(int fd,int databits,int stopbits,int parity)  

{   

    struct termios options;   

    if  ( tcgetattr( fd,&options)  !=  0) {   

        perror("SetupSerial 1");       

        return(FALSE);    

    }  

    options.c_cflag &= ~CSIZE;   

    switch (databits) /*设置数据位数*/  

    {     

    case 7:       

        options.c_cflag |= CS7;   

        break;  

    case 8:       

        options.c_cflag |= CS8;  

        break;     

    default:      

        fprintf(stderr,"Unsupported data size\n");

        return (FALSE);    

    }  

    switch (parity)   

    {     

        case 'n':  

        case 'N':      

            options.c_cflag &= ~PARENB;   /* Clear parity enable */  

            options.c_iflag &= ~INPCK;     /* Enable parity checking */   

            break;    

        case 'o':     

        case 'O':       

            options.c_cflag |= (PARODD | PARENB); /* 设置为奇效验*/    

            options.c_iflag |= INPCK;             /* Disnable parity checking */   

            break;    

        case 'e':    

        case 'E':     

            options.c_cflag |= PARENB;     /* Enable parity */      

            options.c_cflag &= ~PARODD;   /* 转换为偶效验*/       

            options.c_iflag |= INPCK;       /* Disnable parity checking */  

            break;  

        case 'S':   

        case 's':  /*as no parity*/     

            options.c_cflag &= ~PARENB;  

            options.c_cflag &= ~CSTOPB;break;    

        default:     

            fprintf(stderr,"Unsupported parity\n");      

            return (FALSE);    

        }    

    /* 设置停止位*/    

    switch (stopbits)  

    {     

        case 1:      

            options.c_cflag &= ~CSTOPB;    

            break;    

        case 2:      

            options.c_cflag |= CSTOPB;    

           break;  

        default:      

             fprintf(stderr,"Unsupported stop bits\n");    

             return (FALSE);   

    }   

    /* Set input parity option */   

    if (parity != 'n')     

        options.c_iflag |= INPCK;   

    tcflush(fd, TCIFLUSH);  

    options.c_cc[VTIME] = 150; /* 设置超时15 seconds*/     

    options.c_cc[VMIN] = 0; /* Update the options and do it NOW */  

    if (tcsetattr(fd, TCSANOW, &options) != 0)     

    {   

        perror("SetupSerial 3");     

        return (FALSE);    

    }   

    options.c_lflag  &= ~(ICANON | ECHO | ECHOE | ISIG);  /*Input*/  

    options.c_oflag  &= ~OPOST;   /*Output*/  

    return (TRUE);    

}  

int write_atcmd(int fd, char *cmd) {

    char *wbuf = malloc(strlen(cmd) + 3);

    int ret = 0;

    if (wbuf == NULL){

        perror("malloc");

        return -1;

    }

    memset(wbuf, 0, strlen(cmd) + 3);

    sprintf(wbuf, "%s\r\n", cmd);

    printf("===>[%d][%s]\r\n", strlen(wbuf), wbuf);

    ret = write(fd, wbuf, strlen(wbuf));

    if (ret != strlen(wbuf))

        printf("write return %d !!!\r\n", ret);

    free(wbuf);

    return ret;

}

int read_atcmd(int fd, char *match_header, char *data_buf) {

    int ret = 0;

    data_buf[0] = 0;

    printf("match_header:[%s]\r\n", match_header);

    char *p_match = NULL;

    char *rbuf[1024];

    memset(rbuf, 0, sizeof(rbuf));

    while(1) {  

        memset(rbuf, 0, sizeof(rbuf));

        int r_ret = read(fd, rbuf, 1024);

        if(r_ret == 0)  

            continue;  

        if(r_ret == -1)  {

            ret = -1;

            break;

        }

        rbuf[r_ret] = 0;  

        if((strlen(rbuf) == 1) && (rbuf[0]==0x0d || rbuf[0]==0x0a)) {

            continue;

        }

        //printf("<===[%d][%s]\r\n", r_ret, rbuf);

        p_match = strstr(rbuf, match_header);

        if (p_match != NULL){

            memcpy(data_buf, p_match, strlen(p_match));

            data_buf[strlen(p_match)] = 0;

            printf("<===[%d][%s]\r\n", strlen(data_buf), data_buf);

            break;

        }

    }

    return ret;

}

int main(int argc, char *argv[]){

    int i = 0;

    int fd = NULL;

    char buffer[1024] = {0};

    int w_ret, r_ret;

    if (argc < 2) {

        printf("Usage: %s dev_path [write_cmd]\r\n", argv[0]);

        exit(1);

    }

    for (i = 0; i < argc; i++) {

        printf("[%d/%d] %s\r\n", i, argc, argv[i]);

    }

    fd = open(argv[1], O_RDWR);

    if (fd < 0) {  

        perror(argv[1]);  

        exit(1);

    }

    set_speed(fd, 115200);  

    if (set_parity(fd, 8, 1, 'N') == FALSE)  {  

        printf("Set Parity Error\n");  

        exit(0);  

    }

    if (argc >= 3) {

        memset(buffer, 0, sizeof(buffer));

        if (memcmp("query", argv[2], strlen(argv[2])) == 0) {

            write_atcmd(fd, "AT+CEREG?");

            read_atcmd(fd, "+CEREG:", buffer);

            write_atcmd(fd, "AT+CSQ");

            read_atcmd(fd, "+CSQ:", buffer);

            write_atcmd(fd, "AT+COPS?");

            read_atcmd(fd, "+COPS:", buffer);

            write_atcmd(fd, "AT+NETOPEN?");

            read_atcmd(fd, "+NETOPEN:", buffer);

        } else if (memcmp("auto4g", argv[2], strlen(argv[2])) == 0) {

            write_atcmd(fd, "AT+QICSGP=1,1,\"ctnet\",\"\",\"\"");

            write_atcmd(fd, "AT+QICSGP?");

            read_atcmd(fd, "+QICSGP:", buffer);

            read_atcmd(fd, "+QICSGP:", buffer);

            read_atcmd(fd, "+QICSGP:", buffer);

            write_atcmd(fd, "AT+NETOPEN");

            read_atcmd(fd, "+NETOPEN:", buffer);

            read_atcmd(fd, "+NETOPEN:", buffer);

            read_atcmd(fd, "+NETOPEN:", buffer);

        } else {

            if(memcmp("AT", argv[2], 2) != 0){

                printf("%s not AT command\r\n", argv[2]);

                exit(1);

            }

            write_atcmd(fd, argv[2]);

            read_atcmd(fd, argv[2], buffer);

        }

    } else {

        while(1) {  

            memset(buffer, 0, sizeof(buffer));

            r_ret = read(fd, buffer, 1024);

            if(r_ret == 0)  

                continue;  

            if(r_ret == -1)  

                break;

            buffer[r_ret] = 0;  

            if((strlen(buffer) == 1) && (buffer[0]==0x0d || buffer[0]==0x0a)) {

                continue;

            }

            printf("<===[%d][%s]\r\n", r_ret, buffer);

        }

    }

    close(fd);

    printf("-------------the end-------------\r\n");

}

相关文章

网友评论

      本文标题:LYNQ_L501 4G模块在嵌入式linux系统下RNDIS联

      本文链接:https://www.haomeiwen.com/subject/mlctmktx.html