3G模块SIM5360E Linux编程2——串口通信检测

本次的代码是在主线程的基础上的延伸,主线程的“上网”请求只是简单的打印,这次就要具体实现“上网操作"。本着一步一个脚印的原则,我目前只写到“上网操作”的一半,在这其中遇到的问题、设计思路以及解决办法如下所示:

一、上网之前检查操作的流程图

在这里插入图片描述

二、写代码过程中遇见的问题

  1. 写发送和接收函数遇见的问题:我把串口指针写到了函数里面,并没有通过形参的方式传入,虽然编译没有错,但是运行的时候系统会提示Segmentation fault

    你可以想象一下,函数就是一个黑匣子,其实里面一团黑,什么都不知道。你要操作函数外的数据,肯定需要一个形参来作为一个引子。

  2. 在buf缓冲区找东西的时候,先遍历,再赋值。然后再进行判断!

  3. 我定义了一个char *prt = NULL;

    搞了半天,我自己一直出现Segmentation fault,出现这个我就知道肯定是指针的错误,原来我定义的是char类型的指针,NULL是个int型的,难怪一直错误!

三、编译操作

/opt/xtools/arm920t/bin/arm-linux-gcc -Wall command.c comport.c internet.c -l pthread
sz a.out

在这里插入图片描述

tftp -gr a.out 192.168.137.3
chmod a+x a.out
./a.out

在这里插入图片描述

四、运行结果

在这里插入图片描述

五、代码

internet.c

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <errno.h>
#include <unistd.h>
#include "comport.h"
#include "command.h"

int getreq(char *buf,int bufsize);
void *internet(void *ptr);
void *message(void *ptr);

//定义一个结构体

typedef struct _Req_Exc
{
    int                 req;
    int                 exc;
    pthread_mutex_t     lock;
}Req_Exc;

int main(int argc,char **argv)
{
    pthread_t           tid_msg,tid_net;    //线程ID
    pthread_attr_t      thread_attr;        //线程属性
    Req_Exc             req_exc;
    char                cmd_buf[16];

    Req_Exc *ptr = &req_exc;                //指针指向结构体
    ptr->req = 0;
    ptr->exc = 0;

    //初始化锁

    pthread_mutex_init(&req_exc.lock, NULL);

    //初始化线程
    
    if( pthread_attr_init(&thread_attr) )
    {
        printf("pthread_attr_init() failure: %s\n",strerror(errno));
        goto Cleanup;
    }

    if( pthread_attr_setstacksize(&thread_attr,120*1024) )
    {
        printf("pthread_attr_setstacksize() failure: %s\n",strerror(errno));
        goto Cleanup;
    }

    if( pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED) )
    {
        printf("pthread_attr_setdetachstate() failure: %s\n",strerror(errno));
        goto Cleanup;        
    }

    //创建子线程

    if( pthread_create(&tid_msg,&thread_attr,message,(void *)ptr) !=0 )
    {
        printf("pthread create [message] failure: %s\n",strerror(errno));
        goto Cleanup;
    }

    if( pthread_create(&tid_net,&thread_attr,internet,(void *)ptr) !=0 )
    {
        printf("pthread create [internet] failure: %s\n",strerror(errno));
        goto Cleanup;
    }

    //摧毁线程属性

    pthread_attr_destroy(&thread_attr);

    printf("\nWelcome!\n");
    printf("Please input 'internet' or 'message'\n");
    printf("Please input the command:\n");
    
    while(1)
    {
        fgets(cmd_buf,sizeof(cmd_buf),stdin);
    
        if( getreq(cmd_buf,sizeof(cmd_buf)) == 1 )
        {
            pthread_mutex_lock(&req_exc.lock);//上锁
            ptr->req = 1;
            pthread_mutex_unlock(&req_exc.lock);//释放锁
        }

        else if( getreq(cmd_buf,sizeof(cmd_buf)) == 2 )
        {
            pthread_mutex_lock(&req_exc.lock);//上锁
            ptr->req = 2;
            pthread_mutex_unlock(&req_exc.lock);//释放锁
        }

        else if( getreq(cmd_buf,sizeof(cmd_buf)) == 0 )
        {
            printf("输入有误,请重新输入!\n");
        }

        //想要发短信但是有上网的情况

        if( ptr->req == 2 )
        {
            if( ptr->exc !=0 )
            {
                //关掉上网线程

                pthread_cancel(tid_net);
                sleep(1);
                printf("Close the internet thread\n");

                //重新打开上网线程

                if(pthread_create(&tid_net,&thread_attr,internet,(void *)ptr) != 0)
                {
                    printf("pthread create [internet] failure: %s\n",strerror(errno));
                    goto Cleanup;
                }

                printf("Restart the internet thread\n");

                //发短信操作

                printf("正在发短信,等待10秒\n");
                sleep(10);
                printf("发短信成功!\n");

                pthread_mutex_lock(&req_exc.lock);//上锁
                ptr->req = 0;
                ptr->exc = 0; 
                pthread_mutex_unlock(&req_exc.lock);//释放锁
            }
        }
    }

    pthread_mutex_destroy(&req_exc.lock);

    return 0;

Cleanup:
        pthread_mutex_destroy(&req_exc.lock);
        pthread_attr_destroy(&thread_attr);
        return -1;

}

//上网

void *internet(void *ptr)
{
    int oldstate;
    int oldtype;
    Req_Exc *temp_pctr = (Req_Exc *)ptr;

    //串口配置
    int  fd = -1;
    char buf[1024];

    char *com_path = "/dev/ttyUSB2";
    comport *comport_info;
    comport_info = initComport();
    strncpy(comport_info->path,com_path,sizeof(comport_info->path));
    struct termios old_term;


    //使能可取消该线程

    if(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,&oldstate) != 0)
    {
        printf("setcanclesate failure:%s\n",strerror(errno));
        exit(-1);
    }

    //设置取消类型,异步取消,不遇到取消点

    if(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,&oldtype) != 0)
    {
        printf("pthread_setcanceltype failure:%s\n",strerror(errno));
        exit(-1);
    }

    while(1)
    {
        if( temp_pctr->req == 1 )
        {
            printf("请求上网\n");

            if( temp_pctr->exc == 0 )
            {
                pthread_mutex_lock(&temp_pctr->lock);//上锁
                temp_pctr->exc = temp_pctr->req;
                pthread_mutex_unlock(&temp_pctr->lock);//释放锁
            
                //上网操作

                /* 打开串口 */
                fd = openComport(comport_info,&old_term);
                if( fd== 0 )
                {
                    printf("Open comport succeed!\n");
                }
                else
                    printf("Open comport failure!\n");
                
                /* 开始检查 */        
                
                /* 发送AT+CPIN? */
                memset(buf,0,sizeof(buf));
                strcpy(buf,"AT+CPIN?\r");
                fd = send_at_com( comport_info,buf,sizeof(buf));
                if( fd == 0 )
                {
                    printf("发送[AT+CPIN?]成功!\n");
                }
                else
                {
                    printf("发送[AT+CPIN?]失败!\n");
                }
                
                sleep(1);

                /* 读取AT+CPIN? */
                memset(buf,0,sizeof(buf));
                fd = get_at_cpin( comport_info,buf,sizeof(buf));
                if( fd == 0 )
                {
                    printf("Sim卡到位\n");
                }
                else
                {
                    printf("Sim卡没有到位\n");
                }    

                /* 发送AT+CREG? */
                memset(buf,0,sizeof(buf));
                strcpy(buf,"AT+CREG?\r");
                fd = send_at_com( comport_info,buf,sizeof(buf));
                if( fd == 0 )
                {
                    printf("发送[AT+CREG?]成功!\n");
                }
                else
                {
                    printf("发送[AT+CREG?]失败!\n");
                }
                
                sleep(1);

                /* 读取AT+CREG? */
                memset(buf,0,sizeof(buf));
                fd = get_at_creg( comport_info,buf,sizeof(buf));
                if( fd == 0 )
                {
                    printf("注册上网络\n");
                }    
                else
                {
                    printf("没有注册上网络\n");
                }

                /* 发送AT+CIMI */
                memset(buf,0,sizeof(buf));
                strcpy(buf,"AT+CIMI\r");
                fd = send_at_com( comport_info,buf,sizeof(buf));
                if( fd == 0 )
                {
                    printf("发送[AT+CIMI]成功!\n");
                }
                else
                {
                    printf("发送[AT+CIMI]失败!\n");
                }
                
                sleep(1);

                /* 读取AT+CIMI */
                memset(buf,0,sizeof(buf));
                fd = get_at_cimi( comport_info,buf,sizeof(buf));
                if( fd == 0 )
                {
                    printf("运营商:中国移动\n");
                }
                if( fd == 1 )
                {
                    printf("运营商:中国联通\n");
                }
                else
                    printf("运营商:未知\n");
                
                /* 发送AT+CSQ */
                memset(buf,0,sizeof(buf));
                strcpy(buf,"AT+CSQ\r");
                fd = send_at_com( comport_info,buf,sizeof(buf));
                if( fd == 0 )
                {
                    printf("发送[AT+CSQ]成功!\n");
                }
                else
                {
                    printf("发送[AT+CSQ]失败!\n");
                }
                
                sleep(1);

                /* 读取AT+CSQ */
                memset(buf,0,sizeof(buf));
                fd = get_at_csq( comport_info,buf,sizeof(buf));
                if( fd == 0 )
                {
                    printf("信号强,可以上网\n"); 
                }
                else
                {
                    printf("信号弱,不能可以上网\n");
                }
                
                /* 关闭串口 */
                fd = closeComport(comport_info,&old_term);
                if( fd == 0 )
                {
                    printf("Close comport succeed!\n"); 
                }
                else
                    printf("Close comport failure!\n");

                
                printf("正在上网,等待2秒\n");
                sleep(2);
                printf("上网成功!\n");

                pthread_mutex_lock(&temp_pctr->lock);//上锁
                temp_pctr->req = 0;
                temp_pctr->exc = 0;
                pthread_mutex_unlock(&temp_pctr->lock);//释放锁
            }
            else
            {
                printf("正在使用发短信功能...\n");
                sleep(1);
            }
        }
    }
}

//发短信

void *message(void *ptr)
{
    Req_Exc *temp_pctr = (Req_Exc *)ptr;

    while(1)
    {
        if( temp_pctr->req == 2 )
        {   
            if( temp_pctr->exc == 0 )
            {
                printf("请求发短信\n");

                pthread_mutex_lock(&temp_pctr->lock);//上锁
                temp_pctr->exc = temp_pctr->req;
                pthread_mutex_unlock(&temp_pctr->lock);//释放锁

                //发短信操作

                printf("正在发短信,等待10秒\n");
                sleep(10);
                printf("发短信成功!\n");

                pthread_mutex_lock(&temp_pctr->lock);//上锁
                temp_pctr->req = 0;
                temp_pctr->exc = 0;
                pthread_mutex_unlock(&temp_pctr->lock);//释放锁
            }
        }
    }
}

//获取req值

int getreq(char *buf,int bufsize)
{
    char        buf_new[16];

    strncpy(buf_new,buf,bufsize);

    if(strcmp(buf_new,"message\n") == 0)
    {
        return 2;
    }
    else if(strcmp(buf_new,"internet\n") == 0)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

command.c

#include <stdio.h>
#include "command.h"
#include "comport.h"

/*********************
 * 发送AT命令函数
 *
 * 成功:返回 0
 * 失败:返回 -1
 **********************/

int send_at_com( comport *comport_s,char *buf,int bufsize )
{
    int         fd = -1;

    fd = writeComport(comport_s->com_fd,buf,bufsize);

    if( fd > 0 )
    {
        return 0;
    }
    else
        return -1;
}

/******************************
 * 接收"AT+CPIN?"命令返回的信息
 *
 * 成功:返回 0
 * 失败:返回 -1
 ******************************/

int get_at_cpin( comport *comport_s,char *buf,int bufsize )
{
    readComport(comport_s->com_fd,buf,bufsize);
    //printf("读到的数据:\n%s\n",buf);

    if( (strstr(buf,"READY")) != NULL ) 
    {
        return 0;
    }
    else
        return -1;
}
    
/****************************** 
 *接收"AT+CREG?"命令返回的信息
 *
 *成功:返回 0
 *失败:返回 -1
 ******************************/

int get_at_creg( comport *comport_s,char *buf,int bufsize )
{

    int  i;
    char *ptr = buf;

    readComport(comport_s->com_fd,buf,bufsize);
    //printf("读到的数据:\n%s\n",buf);
    
    //遍历buf
    for( i=0;i<bufsize;i++ )
    {
        if( buf[i] == ',' )
        {
            *ptr = buf[i+1];
        }
    }

    if( *ptr == 0x31 )
        return 0;
    else
        return -1;
}

/******************************
 *接收"AT+CIMI"命令返回的信息
 *
 * 成功:返回 0 (移动)
 *       返回 1 (联通)
 * 失败:返回 -1
 ******************************/

int get_at_cimi( comport *comport_s,char *buf,int bufsize )
{
    int  i;
    char *ptr = buf;

    readComport(comport_s->com_fd,buf,bufsize);
    //printf("读到的数据:%s\n",buf);

    //遍历buf
    for( i=0;i<bufsize;i++ )
    {
        if( buf[i] == 0x34 )
        {
            *ptr = buf[i+4];
        }
    }

    if( *ptr == 0x30 )
        return 0;
    else if( *ptr == 0x31 )
        return 1;
    else 
        return -1;
}
 
/******************************
 *接收"AT+CSQ"命令返回的信息
 *
 * 成功:返回 0
 * 失败:返回 -1
 ******************************/

int get_at_csq( comport *comport_s,char *buf,int bufsize )
{
    int  i;
    char *ptr = buf;

    readComport(comport_s->com_fd,buf,bufsize);
    //printf("读到的数据:%s\n",buf);

    //遍历buf
    for( i=0;i<bufsize;i++ )
    {
        if( buf[i] == ',' )
        {
            *ptr = buf[i-1];
        }
    }
    
    if ( *ptr >= 1 )
        return 0;
    else
        return -1;    
}

command.h

#include "comport.h"

int send_at_com( comport *comport_s,char *buf,int bufsize );
int get_at_cpin( comport *comport_s,char *buf,int bufsize );
int get_at_creg( comport *comport_s,char *buf,int bufsize );
int get_at_cimi( comport *comport_s,char *buf,int bufsize );
int get_at_csq( comport *comport_s,char *buf,int bufsize );

串口通信的代码:https://github.com/Sheerandeng/studio_centos/tree/master/sim5360

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值