zoukankan      html  css  js  c++  java
  • v3s Linux中读取GPS数据。

    我尝试在荔枝派中读取gps的信息,我用的gps模块是NEO-6M。

    以下是我的程序

    #include <stdio.h>
    #include <stdlib.h>
    #include <common.h>
    
    char GPS_Data_Temp[256]= {0}; //送去解析的GPS数据
    gps_process_data gps;//gps数据结构体
    #pragma pack (4)
    unsigned char outbuf[50];//用于规范打印的buf
    #pragma pack ()
    int s,bufflen,uartfd=-1;
    int gpsbuflen=0;//避免线程间错误
    
    
    
    static sem_t semA;//设置信号量
    
    void GPS_Show()
    {
    //                float tp;
    //                tp=gps.longitude;
    //                sprintf((char *)outbuf,"Longitude:%.5f %1c 
    ",tp/=100000,gps.ewhemi);    //得到经度字符串
    //
    //                tp=gps.latitude;
    //                sprintf((char *)outbuf,"Latitude:%.5f %1c 
    ",tp/=100000,gps.nshemi);        //得到纬度字符串
    //
    //                sprintf((char *)outbuf,"Valid satellite:%02d
    ",gps.posslnum);             //用于定位的卫星数
    //
    //                sprintf((char *)outbuf,"Visible satellite:%02d
    ",gps.svnum%100);             //可见卫星数
    }
    
    static void *threadRead(void *arg)//串口读取线程
    {
        int i,Bufcnt=0;//设置一个计数器
        char RecvBuff[33];//接受数据缓存,因为一次最多只能读到32个字节
        char Storebuf[256]={0};//数据暂存,用于分割线程之间的联系
        while(1)
        {
            bufflen=UART_Recv(uartfd,RecvBuff,33);
            if(bufflen>0)
            {
                if((Bufcnt+bufflen)<255)
                {
                    for(i=0; i<bufflen; i++)
                    {
                        Storebuf[i+Bufcnt]=RecvBuff[i];//赋值
                    }
                    Bufcnt+=bufflen;//用于确定下一次赋值的偏移量
    
                }
                else //发出条件信号
                {
                    memcpy(GPS_Data_Temp,Storebuf,Bufcnt);//数据拷贝,再清零
                    memset(Storebuf,0,256);
                    gpsbuflen=Bufcnt;
                    Bufcnt=0;
                    for(i=0; i<bufflen; i++)
                    {
                        Storebuf[i+Bufcnt]=RecvBuff[i];//把剩下的数据重新赋值到buf
                    }
                    Bufcnt+=bufflen;//用于确定下一次赋值的偏移量
                    sem_post(&semA);
                }
            }
    
        }
        return NULL;
    }
    
    static void *threadSend(void *arg)
    {
        int i;
        while(1)
        {
            sem_wait(&semA);//等待信号量
            for(i=0;i<gpsbuflen;i++)
            {
                printf("%c",GPS_Data_Temp[i]);//输出数据,并将计数器清零
            }
            memset(GPS_Data_Temp,0,256);
            gpsbuflen=0;
        }
    
        return NULL;
    }
    
    
    int main()
    {
    
        pthread_t Rec,Snd;
        uartfd=UART_Open(uartfd,UART_PORT2);//打开串口1
        if(uartfd==0)
            errExit("open");
        if(UART_Init(uartfd,9600,0,8,1,'N')==0)//串口初始化
            errExit("set uart");
    
        sem_init(&semA,0,0); //信号量初始化
    
        s=pthread_create(&Rec,NULL,threadRead,"read");//线程初始化
        if(s!=0)
            errExitEN(s,"pthread_create");
    
        s=pthread_create(&Snd,NULL,threadSend,"Send");//线程初始化
        if(s!=0)
            errExitEN(s,"pthread_create");
    
        //死循环
        while(1)
        {
    
        }
    
        s=pthread_join(Rec,NULL);
        if(s!=0)
            errExitEN(s,"pthread_join");
    
    
        s=pthread_join(Snd,NULL);
        if(s!=0)
            errExitEN(s,"pthread_join");
    
        sem_destroy(&semA);
    
        exit(EXIT_SUCCESS);
    }

    我现在就是开了两个线程,一个线程用于读取串口数据,一个线程用于解析gps数据,当然我目前只是把数据printf出来。

    遇到几个问题,线程之间的数据的传递,是一个很难解决的问题,主要在于我没有找到合适的方法。

    如果都使用全局变量,那么两个线程,姑且称读取线程为生产者,解析线程为消费者。在生产和消费的过程中,就需要两个线程进行同步。

    线程同步,我想到两个方法,一个用互斥锁+条件变量,一个是用信号量。

    开始我用第一个方法,但是写的时候又发现有个问题,我一次性只能读取32字节的数据,我需要多读几个字节才可以送去解析。这个时候,就需要分情况考虑,

    那么互斥锁加条件变量的方法就显得非常麻烦。

    目前我用第二个方法,当数据读满的时候,发出信号量来提醒消费者进行消费。但是这个时候问题又来了,现在我没有互斥锁,无法避免消费者去使用全局变量的时候产生错误。所以我就讲生产者中的局部变量赋值到全局变量中,让消费者独自使用。

    总的来说这两个方法都很不爽,我在想有没有可以直接在线程中等待,并且传递数据的方法。类似freeRTOS中的信号量+消息队列。

    我测试的数据如下

    接收到的如下

  • 相关阅读:
    C# .Net基础知识点解答
    依赖注入框架Autofac的简单使用
    Linq表达式、Lambda表达式你更喜欢哪个?
    C#抽象类、接口、虚函数和抽象函数
    MVC面试问题与答案
    并发 并行 同步 异步 多线程的区别
    .Net中的控制翻转和依赖注入
    解析ASP.NET WebForm和Mvc开发的区别
    测试与代码质量
    netty 同步调用
  • 原文地址:https://www.cnblogs.com/ZQQH/p/8432957.html
Copyright © 2011-2022 走看看