vxworks下的串口测试程序 分类: vxWorks 2014-04-22 14:15 657人阅读 评论(0) 收藏

/*
*vxworks 串口测试
*
* zjx at evoc 2007.5.17

*pippo add rs485 串口测试at evoc 2007,12,21*
*pippo add 文件系统测试at evoc 2007,12,21*

*使用方法:
*  1. comrecv  ttynum,rate    (ttynum表示接收串口号,rate表示波特率)
*  2. comsend  ttynum,rate,num  (ttynum表示发送串口号,
*                                                      rate表示波特率,
*                  num表示发送字符串的次数)
*  3. 接收端串口收到字符后会保存到serial_result.c 文件中,调用
*             comchk 命令,可以查看收到字符串的次数。对比发送
*             字符串的次数就可以观察串口是否正常。
  4,在测试rs485时,先将串口置于485模式。rs485send ttynum(485发送模式)
     rs485recv ttynum (485接收模式),再使用2中的函数测试串口.
   5,ata文件系统测试。AtaFsceshi ctrl,drive,num(ctrl ,ata控制器号,drive ata 设备号,num
   发送字符串"12345&jkc?"的次数);
   6,doc文件系统测试DocFsceshi num(num 发送字符串"12345&jkc?"的次数);
*
*note:
*       实现了两种访问串口的方式
*        1, 不通过驱动,直接IO访问
*        2, read/write 方式。
*/

#include "vxworks.h"
#include "stdio.h"
#include "taskLib.h"
#include "ioLib.h"
#include "string.h"
#include <end.h>
#include <in.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <semLib.h>
#include <sigLib.h>

#define inportb sysInByte
#define outportb sysOutByte

#define I8250_MCR_REG_OFFSET    0x04  /* Modem Control Register*/

#define I8250_MCR_DTR 0x01 /* dtr output */
#define I8250_MCR_RTS 0x02 /* rts output */
#define I8250_MCR_OUT2 0x08 /* output #2 */

int COM_PORT[4] =  {0x3f8,0x2f8,0x3e8,0x2e8};

char buf_send[]="abcdefghijklmnopqrstuvwxyz";
int fdRecv = 0;
int comsend(int ttynum,int rate, int num);
void comsendTask(int ttynum,int rate, int num);
int comsendio(int ttynum,int rate, int num);
static void comsendchar(int ttynum,char c);
static int comRW(int ttynum, int rate);
static int comRWio(int ttynum, int rate);
int comchk(void);
int rs485send(int ttynum);
int rs485recv(int ttynum);
int rs232(int ttynum);

/*rs-485串口发送*/
int rs485send(int ttynum)
{
 UCHAR value;
 /*将mcr 寄存器的bit 1置为request send true*/
 value  = sysInByte(COM_PORT[ttynum-1]+I8250_MCR_REG_OFFSET);
 value = value|I8250_MCR_RTS;
 sysOutByte(COM_PORT[ttynum-1]+I8250_MCR_REG_OFFSET,value); 
 return OK;
}    

/*rs-485串口接收*/
int rs485recv(int ttynum)
{
 UCHAR value;
 /*将mcr 寄存器 的bit 1置为request send false*/
 value  = sysInByte(COM_PORT[ttynum-1]+I8250_MCR_REG_OFFSET);
 value = value&(~I8250_MCR_RTS);
 sysOutByte(COM_PORT[ttynum-1]+I8250_MCR_REG_OFFSET,value);
 return OK;
}

int rs232(int ttynum)
{
 UCHAR value;
 /*将mcr 寄存器的bit 1置为request send true*/
 sysOutByte(COM_PORT[ttynum-1]+I8250_MCR_REG_OFFSET,I8250_MCR_DTR|I8250_MCR_RTS|I8250_MCR_OUT2);
 return OK;
}

LOCAL void serialDelay
    (
    UINT32 usec
    )
    {
    int i;
    volatile int a, b;

    for (i = 0; i < usec; i++)
        {
        a = 0;
        b = a;
        }

    return;
    }


int comsend(int ttynum, int rate, int num)
{
    int fd;
    int bytes_out;
 char fd_str[8]={0};
 char buffer[40] = {0};
 int  numSend = 1;
 char *pSendChar = 0;
 int i = 0,j = 0;
    char serila_UMCR = 0;

    if(ttynum ==3)
    {
        ttynum = 2;
    }
 if(ttynum > 1)
 {
     serila_UMCR = sysInByte(0xff404604);
        sysOutByte(0xff404604,0x02);
 }
 
 assert((num>0)&&(ttynum>0)&&(rate>0));
 if(num > 10000000)
 {
     printf("Number is too big! <10000000 ! ");
  return ERROR;
 }
 
 sprintf(fd_str,"/tyCo/%d", ttynum-1);
 fd = open(fd_str,O_RDWR,0);

    ioctl(fd,FIOSETOPTIONS,OPT_RAW);             /* 设置串口的数据模式  */
    ioctl(fd,FIOBAUDRATE,rate);                  /*设置串口 的波特率*/
    ioctl(fd,FIOFLUSH ,0);                     /*清空串口的缓冲区*/

    printf("The send string is "%s" ",buf_send);

    FOREVER
    {
     sprintf(buffer, "[%s(%d)]", buf_send, numSend);
        for(pSendChar = buffer, i = 0; i<strlen(buffer); pSendChar++,i++)
        {
      bytes_out = write(fd, pSendChar, /*strlen(buffer[i])*/1);   /* 往串口写入一个字符串*/
      #if 0
      taskDelay(1);
      #else
      serialDelay(0x10000);
      #endif
        }
  printf(" %d", numSend);

  numSend++;
  if(numSend>num)
  {
   break;
  }
    }
 
    /*关闭串口1 */
    close(fd);

 if(ttynum > 1)
 {
        sysOutByte(0xff404604,serila_UMCR);
    }

    return OK;
}    

/* 读写文件方式*/
static int comRW(int ttynum, int rate)
{
    int fd/*,fd1*/;
   int bytes_in,bytes_write;
    char buf[40];
 char fd_str[8];
 char filenamestr[40];

 assert((ttynum>0)&&(rate>0));

 memset(buf, 0 , 40*sizeof(char));
 memset(buf, 0 , 8*sizeof(char));
 
    if(fdRecv >0)
    {
        close(fdRecv);
    }
 strcpy(filenamestr,"serial_result.txt");
 fdRecv = creat(filenamestr, O_RDWR);
    if(fdRecv<0)
    {
     printf("creat fd1 failded! ");
  return ERROR;
    }
 
 sprintf(fd_str,"/tyCo/%d", ttynum-1);
 fd=open(fd_str,O_RDWR,0);
 
 ioctl(fd,FIOSETOPTIONS,OPT_RAW);   /* 设置串口的数据模式  */
 ioctl(fd,FIOBAUDRATE,rate);        /*设置串口 的波特率*/
 
 for(;;)
    {
     memset(buf, 0 , 40*sizeof(char));
  /* 读串口*/ 
  bytes_in=read(fd, buf, sizeof(buf_send));
  
  /* 把结果存入文件中*/
  bytes_write = write(fdRecv,buf,strlen(buf));
  if(bytes_write<0)
  {
   printf("write data error ");
   return ERROR;
  }
    }

 close(fd);
 close(fdRecv);
 
 return OK;
}

/*串口发送*/
void comsendTask(int ttynum,int rate, int num)
{
     int taskID;
 
    taskID=taskNameToId("sendTask");
 
 if(taskID>0)
 {
     /* 把访问方式改为中断方式*/
        outportb(COM_PORT[ttynum-1]+1,0x01); 
  
     taskDelete(taskID);
 }

 /* 创建发送任务*/
 taskSpawn("sendTask",255,0,4000,(FUNCPTR)comsend,ttynum,rate,num,0,0,0,0,0,0,0);
}


/*串口接收*/
void comrecv(int ttynum,int rate)
{
     int taskID;
 
    if(ttynum ==3)
    {
        ttynum = 2;
    }
    taskID=taskNameToId("recvTask");
 
 if(taskID>0)
 {
     /* 把访问方式改为中断方式*/
        outportb(COM_PORT[ttynum-1]+1,0x01); 
  
     taskDelete(taskID);
 }

 /* 创建接收任务*/
 taskSpawn("recvTask",254,0,4000,(FUNCPTR)comRW,ttynum,rate,0,0,0,0,0,0,0,0);
}

/* 发送一个字符*/
static void comsendchar(int ttynum, char c)
{
 if(((unsigned char )inportb(COM_PORT[ttynum-1]+5) & 0x20)!= 0)
 {
  outportb(COM_PORT[ttynum-1], c);
 }
 
 taskDelay(1);
}

/* 访问寄存器方式*/
int comsendio(int ttynum,int rate,int count)
{
    int i,j;
 char countBuffer[10] = {0};
 unsigned char c;
 
 assert((ttynum>0)&&(count>0)&&(rate>0));

    switch(rate) 
    { 
     case   2400:    c=0x30;break;
  case   4800:    c=0x18;break;
        case   9600:    c=0x0c;break;
  case   19200:   c=0x06;break;
        case   28800:   c=0x04;break;
  case   38400:   c=0x03;break;
        case   57600:   c=0x02;break; 
        case   115200:  c=0x01;break;

        default: 
             printf("Set  comm   bps   fail!"); 
    return  ERROR; 
    } 
 
 outportb(COM_PORT[ttynum-1]+3,0x80); /* DLAB="1", set baud*/
 outportb(COM_PORT[ttynum-1],c);      /* 波特率 0x30:2400 0x18:4800
                0x0c:9600 0x01:115200*/
    outportb(COM_PORT[ttynum-1]+1,0x00);
    outportb(COM_PORT[ttynum-1]+3,0x03); /* data length: 8 , stop bits: 1*/
 outportb(COM_PORT[ttynum-1]+4,0x0b);
    outportb(COM_PORT[ttynum-1]+1,0x01); /* receive interrupt enable*/
 inportb(COM_PORT[ttynum-1]);
 
 for(i=0; i<count; i++)
 {
  /*以轮询的方式访问*/
  outportb(COM_PORT[ttynum-1]+1,0); 

  /* 发送字符串,格式为[abedefghijklmnopqrstuvwxyz(12323)] */
  comsendchar(ttynum, '[');
  for(j=0; j<26; j++)
  {
   comsendchar(ttynum,buf_send[j]); 
  }

  
  comsendchar(ttynum, '(');
  /* 发送计数值*/
  sprintf(countBuffer, "%d", i+1);
  for(j=0; j < strlen(countBuffer); j++)
  {
   comsendchar(ttynum, countBuffer[j]);
  }

  comsendchar(ttynum, ')');
  comsendchar(ttynum, ']');
  
  printf(" %d", i+1);
  
 } 

 /* 把访问方式改为中断方式*/
    outportb(COM_PORT[ttynum-1]+1,0x01); 
  
 return OK;
}

/* 访问寄存器方式*/
static int comRWio(int ttynum, int rate)
{
 int /*fd1,*/bytes_write;
 unsigned char c;
 char buf[30];
 char filenamestr[40];
 assert((ttynum>0)&&(rate>0));

 strcpy(filenamestr,"serial_result.txt");
 fdRecv = creat(filenamestr, O_RDWR);
    if(fdRecv<0)
    {
     printf("creat fd1 failded! ");
  return ERROR;
    }

 
 
    switch(rate) 
    { 
     case   2400:    c=0x30;break;
  case   4800:    c=0x18;break;
        case   9600:    c=0x0c;break;
  case   19200:   c=0x06;break;
        case   28800:   c=0x04;break;
  case   38400:   c=0x03;break;
        case   57600:   c=0x02;break; 
        case   115200:  c=0x01;break;

        default: 
             printf("Set  comm   bps   fail!"); 
    return  ERROR; 
    }

 outportb(COM_PORT[ttynum-1]+3,0x80);   /* DLAB="1", set baud*/
    outportb(COM_PORT[ttynum-1],c);        /*设置 波特率 0x30:2400 0x18:4800 0x0c:9600*/
    outportb(COM_PORT[ttynum-1]+1,0x00);
    outportb(COM_PORT[ttynum-1]+3,0x03);   /* data length: 8 , stop bits: 1*/
    outportb(COM_PORT[ttynum-1]+4,0x0b);
    outportb(COM_PORT[ttynum-1]+1,0x01);   /* receive interrupt enable*/
    inportb(COM_PORT[ttynum-1]);

 FOREVER
    {
     memset(buf, 0 , 30*sizeof(char));
     /* 以轮询的方式访问*/
     outportb(COM_PORT[ttynum-1]+1,0);
  
  /* 读串口*/ 
     if(((unsigned char )inportb(COM_PORT[ttynum-1]+5) & 0x01)!= 0)
        {
         sprintf(buf,"%c", inportb(COM_PORT[ttynum-1]));
  }

  /* 把结果存入文件中*/  
  bytes_write = write(fdRecv,buf,strlen(buf));
  if(bytes_write<0)
  {
   printf("write data error ");
   return ERROR;
  }
    }

 close(fdRecv);
 return OK;
}

/*串口接收*/
void comrecvio(int ttynum,int rate)
{
     int taskID;
 
    taskID=taskNameToId("recvTask");
 
 if(taskID>0)
 {
  /* 把访问方式改为中断方式*/
        outportb(COM_PORT[ttynum-1]+1,1); 

  taskDelete(taskID);
 }

 /* 创建接收任务*/
 taskSpawn("recvTask",254,0,4000,(FUNCPTR)comRWio,ttynum,rate,0,0,0,0,0,0,0,0);
}

/* 检查串口收到的字符串的条数*/
int comchk(void)
{
 FILE *fd = NULL;
 char buffer[40] = {0};
 char buffer1[40] = {0};

 int count = 0;
 char filenamestr[40];
 
    if(fdRecv >0)
    {
        close(fdRecv);
    }
 
 strcpy(filenamestr,"serial_result.txt");
 
 fd = fopen(filenamestr, "r");
 if(fd<0)
 {
  printf("opent file error! ");
  return ERROR;
 }

 while(!feof(fd))
 {
  memset(buffer1, 0 ,sizeof(buffer1));
     sprintf(buffer1,"[%s(%d)]", buf_send, count+1);
  
  memset(buffer, 0 ,sizeof(buffer));
  fread(buffer, strlen(buffer1), 1, fd);
  if(0 == memcmp(buffer, buffer1, strlen(buffer)))
  {
   count++;
  }
 }

 if(count < 1 )
 {
     printf("The number of received strings is 0 ");
     return ERROR;
 }
 else
 {
     printf("The number of received strings is %d ", count-1);
 }
 fclose(fd);
 
 return OK;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

原文地址:https://www.cnblogs.com/mao0504/p/4706632.html