基于 MiniLA 的移植与实现 (2)

来源:互联网 发布:微信选课系统源码 编辑:程序博客网 时间:2024/06/10 01:18

软件设计:

1.      fpga驱动

在驱动模块初始化函数里加入下面代码实现中断的注册

enable_edge_trigger(IRQ5_INTERRUPT);

if (request_irq(IRQ5_INTERRUPT, irq5_interrupt,0,"datacoming",fpga_devp) < 0)

         printk(KERN_CRIT "Unable to register IRQ5 interrupt/n");

 

中断处理程序负责将数据搬运到 /mnt/rd/minila.bin文件中,/mnt/rd节点挂接在内存文件系统上

tmpfs on /mnt/rd type tmpfs (rw)

void irq5_interrupt(int irq, void * dev_id, struct pt_regs * regs)

{

     unsigned char buffer[1024];

     int i;

     for(i=0; i<1024; i++)

     {

         buffer[i] = (unsigned char)read_fpga_reg(0);

         //buffer[i]  =         readb(fpga_devp->reg_base);

     }

     g_filp->f_op->write(g_filp, buffer, 1024, &g_filp->f_pos);

     return;

}

 

关于文件/mnt/rd/minila.bin的创建和关闭在ioctrl中实现:

case MINILA_TEST_DATA_START:

{

PREP_KERN_INVOKE_SYS_CALL();

if ((g_filp = filp_open ("/mnt/rd/minila.bin", O_CREAT | O_RDWR, 0777)) == NULL)

{

printk ("Unable to open the file/n");

            return -1;

}

       minila_test_data_gen(1);

       break;

}

 

 

case MINILA_TEST_DATA_STOP:

{

      minila_test_data_gen(0);

      filp_close(g_filp,0);

      INVOKE_SYS_CALL_DONE();

      break;

}

 

应用软件

考虑到调试的方便性,CLI的方式来操作,代码选用了tinyshell,他是一个小巧的开源的CLI项目,支持命令补齐,命令历史记录以及命令树结构的特性。

 

下面是我定义的一些命令:

tinysh$

help    display help

foo     foo command

ctx     contextual command

fpga    FPGA debug commands

miniLA  miniLA command utils

quit    exit shell

atoxi   demonstrate atoxi support

tinysh $ fpga

download  FPGA Programming for Xilinx XC2S400E

showreg   Show the register values in FPGA

regrd     Read register from FPGA

regnrd    Read a FPGA reg for a length

regwr     Write register to FPGA

info      Get FPGA porject infomation

tinysh$ miniLA

start  Test Suite for miniLA

stop   Test Suite for miniLA

reset  Test Suite for miniLA

check  Test Suite for miniLA

 

 

miniLA check是早期的一个调试命令,开始的时候为了验证数据通道的可靠性,我是发测试数据的,check的目的就是按照测试数据的规律检测有没有出现数据丢失,以及数据位上的一些畸变。

 

MiniLA_cmds.h

#ifndef _MINILA_CMDS_H

#define _MINILA_CMDS_H

 

void minilaDataStart(int argc, char **argv);

void minilaDataStop(int argc, char **argv);

void minilaDataReset(int argc, char **argv);

void minilaDataCheck(int argc, char **argv);

 

#endif /* _MINILA_CMDS_H */

 

MiniLA_cmds.c

#include <stdio.h>

#include <stdlib.h>

#include <errno.h>

#include <string.h>

#include <sys/fcntl.h>

#include <sys/ioctl.h>

#include <sys/types.h>

#include <dirent.h>

#include <sys/stat.h>

#include <unistd.h>

#include <pwd.h>

#include <grp.h>

#include <termios.h>

#include <fcntl.h>

#include <sys/time.h>

 

#include "fpgacore.h"

#include "tinysh.h"

 

#define MAX_ERRO_CNT 15

static struct timeval tvafter,tvpre;

static struct timezone tz;

 

void minilaDataStart(int argc, char **argv)

{

     int fd;

     struct stat info;

#if(FPGACMD_DEBUG)

     printf("minilaDataStart %d command called/n",(int)tinysh_get_arg());

     display_args(argc,argv);

#endif /* FPGACMD_DEBUG */

     if ( !access ("/mnt/rd/minila.bin", F_OK) )

     {

         remove("/mnt/rd/minila.bin");

     }

     fd = open("/dev/fpga", O_RDWR, 0755);

        if( fd<0 )

     {

         printf("Opne file /dev/fpga failed, fd = %d/n", fd);

         return;

     }

     gettimeofday (&tvpre , &tz);        

     /* Call ioctl to download image */  

     ioctl(fd, MINILA_TEST_DATA_START, NULL);

     close(fd);

     return;

}

 

void minilaDataStop(int argc, char **argv)

{

     int fd;

     struct stat info;

     int spend_time = 0;

     int date_rate = 0;

     int len;

     struct  stat  buf;

     stat("/mnt/rd/minila.bin", &buf);

     len = buf.st_size;

    

#if(FPGACMD_DEBUG)

     printf("minilaDataStop %d command called/n",(int)tinysh_get_arg());

     display_args(argc,argv);

#endif /* FPGACMD_DEBUG */

 

     fd = open("/dev/fpga", O_RDWR, 0755);

        if( fd<0 )

     {

         printf("Opne file /dev/fpga failed, fd = %d/n", fd);

         return;

     }

        

     /* Call ioctl to download image */  

     ioctl(fd, MINILA_TEST_DATA_STOP, NULL);

     gettimeofday (&tvafter , &tz);

     close(fd);

     spend_time = (tvafter.tv_sec-tvpre.tv_sec)*1000+(tvafter.tv_usec-tvpre.tv_usec)/1000;

     date_rate = len/spend_time;

     printf("Spend time :[%d]ms Rate:[%d]kB/S/n", spend_time, date_rate);

     return; 

}

 

void minilaDataReset(int argc, char **argv)

{

     int fd;

     struct stat info;

#if(FPGACMD_DEBUG)

     printf("minilaReset %d command called/n",(int)tinysh_get_arg());

     display_args(argc,argv);

#endif /* FPGACMD_DEBUG */

 

     fd = open("/dev/fpga", O_RDWR, 0755);

        if( fd<0 )

     {

         printf("Opne file /dev/fpga failed, fd = %d/n", fd);

         return;

     }

        

     /* Call ioctl to download image */  

     ioctl(fd, MINILA_FPGA_RESET, NULL);

     close(fd);

     return; 

}

 

void minilaDataCheck(int argc, char **argv)

{

     unsigned char buffer[1024];

     FILE* pfile;

     unsigned int b_addr = 0;

     int erro_cnt = 0;

     int i,j;

     int len;

     struct  stat  buf;

     pfile = fopen("/mnt/rd/minila.bin", "rb");  

     stat("/mnt/rd/minila.bin", &buf);

     len = buf.st_size;

    

     for(i=0; i<(len>>8); i++)

     {

         fread(buffer, 256, 1, pfile);

         for(j=1; j<256; j++)

         {

              if(buffer[j] != j)

              {

                   erro_cnt ++;

                   printf("#### [addr: 0x%08x] [0x%02x] -> [0x%02x]/n", b_addr+j, j, buffer[j]);

                   if(erro_cnt > MAX_ERRO_CNT)

                       break;

              }

         }

         if(buffer[0] != i%256)

         {

              erro_cnt ++;

              printf("[addr: 0x%08x] [0x%02x] -> [0x%02x]/n", b_addr, i%256, buffer[0]);

         }

         b_addr += 256;

         if(erro_cnt > MAX_ERRO_CNT)

              break;

     }

     fclose(pfile);

    

     if(0 == erro_cnt)

         printf("Check Passed!/n");

     else

         printf("Check Failed!/n");

     return;

}

 

下面就是将这些函数注册到tinyshell的命令字上:

static tinysh_cmd_t minila={0,"miniLA","miniLA command utils","fpga_item1|fpga_item2",

                              0,0,0,0};

static tinysh_cmd_t minilaStart={&minila,"start","Test Suite for miniLA","[-x or -t or -s<strings>]",minilaDataStart,

                           (void *)1,0,0};

static tinysh_cmd_t minilaStop={&minila,"stop","Test Suite for miniLA ","[-x or -t or -s<strings>]",minilaDataStop,

                           (void *)2,0,0};

static tinysh_cmd_t minilaReset={&minila,"reset","Test Suite for miniLA ","[-x or -t or -s<strings>]",minilaDataReset,

                           (void *)3,0,0};

static tinysh_cmd_t minilaCheck={&minila,"check","Test Suite for miniLA ","[-x or -t or -s<strings>]",minilaDataCheck,

                           (void *)3,0,0};

 

/* add MiniLA debug sub commands

*/

  tinysh_add_command(&minila);

  tinysh_add_command(&minilaStart);

  tinysh_add_command(&minilaStop);

  tinysh_add_command(&minilaReset);

  tinysh_add_command(&minilaCheck);

原创粉丝点击