UART TEST

#include<stdio.h>

#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<termios.h>
#include<string.h>
#include<ctype.h>


#include <unistd.h>


#define FRAMEHEADER_FLAG  0XA5
#define FRAMEND_FLAG   0X5A

#define READ_RET_FLAG   0XAF
#define READ_FLAG    0X0A
#define READ_LOCALSYSTEM_PARM_FLAG  0X00
#define READ_LINUX_VER  0X01
#define READ_LINUX_TIME  0X02
#define READ_LINUX_IP  0X03
#define READ_LINUX_MAC  0X04
#define READ_LINUX_DNS  0X05


unsigned int TaskList;  //任務列表
#define TASK_START   0X01//BIT0
#define R_LINUX_VER_TASK 0X02//BIT1
#define R_LINUX_TIME_TASK 0X04//BIT2
#define R_LINUX_IP_TASK  0X08//BIT3
#define R_LINUX_MAC_TASK 0X10//BIT4
#define R_LINUX_DNS_TASK 0X20//BIT5

unsigned int TaskErrorDeal;//出錯任務處理


#define DNS_FILE "/etc/resolv.conf"
char ReadBuf[80] = {0};
char  WriteBuf[50] = {0};
int uart_fd;
char DatNum;

static char* getDNSInfo(char *maches);
void DecodeTask(void);
int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop);
char CheckOutDat(char *checkDat,unsigned int n);
char comp_dat(char *SourDat,char Num);
void ReadUart(void);

#define Debug

/*=================================================================
函數功能描述;實現對串口設備的設置
參數描述:  fd:需要設置的串口的文件描述符
     nSpeed:設置波特率
     nBits:設置數據位
     nEvent:設置校驗位
     nStop:停止位
===================================================================*/
int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop)
{
 struct termios newtio,oldtio;
 if (tcgetattr(fd,&oldtio) != 0) //保存原先串口的配置
 {
  perror("SetupSerial 1");
  return -1;
 }
 bzero(&newtio, sizeof(newtio));
 newtio.c_cflag  |=  CLOCAL | CREAD;//本地連接,接收使能
 newtio.c_cflag &= ~CSIZE;//

//設置數據位
 switch (nBits)
 {
  case 7:
   newtio.c_cflag |= CS7;
   break;
  case 8:
   newtio.c_cflag |= CS8;
   break;
  default:
   break;
 }

//設置校驗位
 switch (nEvent )
 {
  case 'O':
   newtio.c_cflag |= PARENB;
   newtio.c_cflag |= PARODD;
   newtio.c_iflag |= (INPCK | ISTRIP);
   break;
  case 'E':
   newtio.c_iflag |= (INPCK | ISTRIP);
   newtio.c_cflag |= PARENB;
   newtio.c_cflag &= ~PARODD;
   break;
  case 'N': 
   newtio.c_cflag &= ~PARENB;
   break;
  default:
   break;
 }

// 設置波特率
 switch (nSpeed)
 {
  case 2400:
   cfsetispeed(&newtio, B2400);
   cfsetospeed(&newtio, B2400);
   break;
  case 4800:
   cfsetispeed(&newtio, B4800);
   cfsetospeed(&newtio, B4800);
   break;
  case 9600:
   cfsetispeed(&newtio, B9600);
   cfsetospeed(&newtio, B9600);
   break;
  case 115200:
   cfsetispeed(&newtio, B115200);
   cfsetospeed(&newtio, B115200);
   break;
  case 460800:
   cfsetispeed(&newtio, B460800);
   cfsetospeed(&newtio, B460800);
  break;
  default:
   cfsetispeed(&newtio, B9600);
   cfsetospeed(&newtio, B9600);
   break;
 }

//設置停止位 
 if (nStop == 1)
  newtio.c_cflag &=  ~CSTOPB;
 else if ( nStop == 2 )
  newtio.c_cflag |=  CSTOPB;

//設置最少字符 和等待時間,對此無要求時,可寫0
 newtio.c_cc[VTIME]  = 0;
 newtio.c_cc[VMIN] = 0;

//刷新(丟棄)輸入緩存(驅動已經收到,但是用戶還沒有讀出)或輸出緩存(用戶程序已經寫,但是驅動還沒有送出)
 tcflush(fd,TCIFLUSH);

//設置完成之後,激活配置,並立即生效
 if ((tcsetattr(fd,TCSANOW,&newtio))!=0)
 {
  perror("com set error");
  return -1;
 }
 
 return 0;
}


int main(void)
{
 int nRead;
 TaskList = 0;
 char funcRetDat = 0;
 uart_fd = open( "/dev/ttyAMA0", O_RDWR);
 
 if (uart_fd == -1)
 {
  printf("open uart error \n");
  exit(1);
 }
#ifdef Debug
 printf("ttyAMA0 open success\n");
#endif

 if(set_opt(uart_fd,9600,8,'N',1) == -1)
 {
  printf("set uart error \n");
  exit(1);
 }
#ifdef Debug
  printf("ttyAMA0 Init success\n");
#endif

// while(1)
 {
  ReadUart();
  if ((TaskList & TASK_START) == TASK_START)
  {
   TaskList &=~ TASK_START;
   
   DecodeTask();
  }
  usleep(20000);
#ifdef Debug
    printf("ttyAMA0 IWORKING\n");
#endif

 }

 close(uart_fd);
 return 0;
 

}


void ReadUart(void)
{
 char temp = 0;
 char i = 0;
 
 while(1)
 {
  if ((read(uart_fd,&temp,1))>0)
  {
   if (temp == FRAMEHEADER_FLAG)
   {
    ReadBuf[i] = temp;
    i = 1;   
   }
   else if (temp == FRAMEND_FLAG)
   {
    ReadBuf[i] = temp;
    DatNum = i;
    i = 0; 
    TaskList |= TASK_START;
    //置讀結束標誌,可以開始執行返回的線程;
    break;
   }
   else
   {
    ReadBuf[i] = temp;
    i++; 
    if (i>80)
    {
     break;
    }
   }
   
  }
  else
  {
#ifdef Debug
 printf("ttyAMA0 read no data\n");
#endif
   break;
  }
 }
}


void writeUart(char *W_buf,char n)
{
 
 WriteBuf[0] = FRAMEHEADER_FLAG;
 WriteBuf[1] = READ_RET_FLAG;
 WriteBuf[2] = READ_LOCALSYSTEM_PARM_FLAG;
 WriteBuf[3] = READ_LINUX_DNS;
 WriteBuf[4] = FRAMEND_FLAG;
 write(uart_fd,WriteBuf,4); 
 write(uart_fd,W_buf,n);
 write(uart_fd,&WriteBuf[4],1);
#ifdef Debug
  printf("ttyAMA0 write uart \n");
#endif


}

 


char *szNetwork=NULL;

static char* getDNSInfo(char *maches)
{
    char szBuf[128];
 //char *szDNS=NULL;   
    int i = 0;
   
 FILE *fp = NULL;

    if((fp=fopen(DNS_FILE, "r"))==NULL)             //判斷文件是否爲空
   
    {
        printf( "Can 't   open   file!\n");
        return 0;
    }
    while(fgets(szBuf,128,fp))                         //從文件開關開始向下讀,把讀到的內容放到szBuf中
    {                        
        if(strstr(szBuf,maches) != NULL)                 //找到maches在文件中第一次出現的位置。。如address
        {
            for(i =0;i < strlen(szBuf);i++)
          {             
                if(isdigit(*(szBuf+i)))                      //從szBuf字符串中找出數字。
                {
                    szNetwork = (char*)malloc(strlen(szBuf));  //爲szNetwork分配內存
                    strcpy(szNetwork,szBuf+i);            
                    fclose(fp);
                 //   strcpy(szNetwork,szDNS);
                 //  free(szDNS);
                    return szNetwork;
                }
            }
        }else
            continue;
    }
    fclose(fp);
    return szNetwork;
   
}

 


void DecodeTask(void)
{

    char *DNSadd;  
 char funcRetDat = 0;
 
 funcRetDat = comp_dat(ReadBuf,DatNum);
 if (funcRetDat != 0 )
 {
  TaskErrorDeal = funcRetDat;
 }  

 

 if ((TaskList & R_LINUX_DNS_TASK) == R_LINUX_DNS_TASK)
 {
 
  TaskList &=~ R_LINUX_DNS_TASK;
  DNSadd =  getDNSInfo("nameserver");

  writeUart(DNSadd, sizeof(DNSadd));

  
  free(szNetwork);
  
 }
 else if ((TaskList & R_LINUX_IP_TASK) == R_LINUX_IP_TASK)
 {
  
  TaskList &=~ R_LINUX_IP_TASK;
 }
 else if ((TaskList & R_LINUX_MAC_TASK) == R_LINUX_MAC_TASK)
 {
  TaskList &=~ R_LINUX_MAC_TASK;
  
 }
 else if ((TaskList & R_LINUX_TIME_TASK) == R_LINUX_TIME_TASK)
 {
  TaskList &=~ R_LINUX_TIME_TASK;
  
 }
 else if ((TaskList & R_LINUX_VER_TASK) == R_LINUX_VER_TASK)
 {
  TaskList &=~ R_LINUX_VER_TASK;
  
 }
 else
 {
  
 }
 
}

 

char CheckOutDat(char *checkDat,unsigned int n)
{
 unsigned int Sum = 0;
 unsigned int i = 0;
 for (i=1; i<(n-1); i++)
 {
  Sum += checkDat[i];
  
 }
 Sum = Sum % 0X100;
 if (checkDat[n-1] == Sum)
 {
  return 0;//校驗正確
 }
 else
 {
  return 1;//校驗錯誤
 }
}

/*===========================================================

 

返回值:
       0:正確執行
       1:數據接收錯誤
       2:校驗出錯
       3:查無該指令

============================================================*/
char comp_dat(char *SourDat,char Num)
{

 char temp = 0;
 if (SourDat[0] != FRAMEHEADER_FLAG)
 {
  return 1;//接收錯誤,該幀丟棄
 }
 switch (SourDat[1])
 {
  case READ_FLAG:
   break;
   //可擴展其他參數
  default:
   break;
 }
 if ((SourDat[1] & READ_FLAG) ==  READ_FLAG)//讀的指令判斷
 {
  switch (SourDat[2])
  {
   case READ_LOCALSYSTEM_PARM_FLAG:
    //驗證校驗位與幀尾數據
    if ((CheckOutDat(SourDat,Num) == 0) && (SourDat[Num] == FRAMEND_FLAG))
    {
     switch (SourDat[3])
     {
      case READ_LINUX_VER:
       TaskList |= R_LINUX_VER_TASK;
       break;
      case READ_LINUX_IP:
       TaskList |= R_LINUX_IP_TASK;
       break;
      case READ_LINUX_MAC:
       TaskList |= R_LINUX_MAC_TASK;
       break;
      case READ_LINUX_TIME:
       TaskList |= R_LINUX_TIME_TASK;
       break;
      case READ_LINUX_DNS:
       TaskList |= R_LINUX_DNS_TASK;
       break;
      //可以擴展讀取其他的參數
      default:
       temp = 3;//查無該指令
       break;
       
     }
    }
    else
    {
     temp = 2;
    }
    break;
    
   //可以擴展作爲讀取其他的分支參數;
   default :
    temp = 3;//查無該指令
    break;
  }
 }
 else
 {
  //可擴展寫/操作 相關指令的解碼;
  //if()   作寫/操作數據進行判斷
 }

 return temp;
}

 

 


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章