首页 > 系统相关 >Linux MTD测试程序

Linux MTD测试程序

时间:2022-12-13 16:04:13浏览次数:44  
标签:return fpga int Linux bytes 测试程序 fd printf MTD



/** filename: program.c
* description: demo of program FPGA application
* date: 2015-10-13
* compiler: ARCH=arm CROSS_COMPILE=arm-fsl-linux-gnueabi- make
*/

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <time.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <asm/ioctl.h>
#include <mtd/mtd-user.h>
#include <errno.h>
#include <ctype.h> /* isprint */



/* gpio index */
#define FPGA_GPIO_NCONFIG 0
#define FPGA_GPIO_ROMPATH_SEL 1
#define FPGA_GPIO_CONF_DONE 2
#define FPGA_GPIO_NSTATUS 3

/* dev/fpga ioctl cmd */
#define FPGA_IOC_SET_GPIO _IO('F',0)
#define FPGA_IOC_RST_GPIO _IO('F',1)
#define FPGA_IOC_GET_GPIO _IO('F',2)


#define BUFFER_SIZE 1048576
#define DEBUG_SIZE 2048

/* buffer */
char buffer[BUFFER_SIZE];
char read_buffer[DEBUG_SIZE];


/* fpga device */
struct fpga {
int fd;

int nconfig;
int rompath_sel;
int conf_done;
int nstaus;
};

/* global variable */
struct fpga fpga_dev;


/** flash erase
*/
int region_erase(int Fd, int start, int count, int unlock, int regcount)
{
int i, j;
region_info_t * reginfo;

reginfo = calloc(regcount, sizeof(region_info_t));

for(i = 0; i < regcount; i++)
{
reginfo[i].regionindex = i;
if(ioctl(Fd,MEMGETREGIONINFO,&(reginfo[i])) != 0)
return 8;
else
printf("Region %d is at %d of %d sector and with sector "
"size %x\n", i, reginfo[i].offset, reginfo[i].numblocks,
reginfo[i].erasesize);
}

// We have all the information about the chip we need.

for(i = 0; i < regcount; i++)
{ //Loop through the regions
region_info_t * r = &(reginfo[i]);

if((start >= reginfo[i].offset) &&
(start < (r->offset + r->numblocks*r->erasesize)))
break;
}

if(i >= regcount)
{
printf("Starting offset %x not within chip.\n", start);
return 8;
}

//We are now positioned within region i of the chip, so start erasing
//count sectors from there.

for(j = 0; (j < count)&&(i < regcount); j++)
{
erase_info_t erase;
region_info_t * r = &(reginfo[i]);

erase.start = start;
erase.length = r->erasesize;

if(unlock != 0)
{ //Unlock the sector first.
if(ioctl(Fd, MEMUNLOCK, &erase) != 0)
{
perror("\nMTD Unlock failure");
close(Fd);
return 8;
}
}
printf("\rPerforming Flash Erase of length 0x%llx at offset 0x%llx",
erase.length, erase.start);
fflush(stdout);
if(ioctl(Fd, MEMERASE, &erase) != 0)
{
perror("\nMTD Erase failure");
close(Fd);
return 8;
}


start += erase.length;
if(start >= (r->offset + r->numblocks*r->erasesize))
{ //We finished region i so move to region i+1
printf("\nMoving to region %d\n", i+1);
i++;
}
}

printf(" done\n");

return 0;
}


int non_region_erase(int Fd, int start, int count, int unlock)
{
mtd_info_t meminfo;
if (ioctl(Fd,MEMGETINFO,&meminfo) == 0)
{
erase_info_t erase;
erase.start = start;
erase.length = meminfo.erasesize;
for (; count > 0; count--) {
printf("\rPerforming Flash Erase of length %u at offset 0x%x",
erase.length, erase.start);
fflush(stdout);
if(unlock != 0)
{
//Unlock the sector first.
printf("\rPerforming Flash unlock at offset 0x%x",erase.start);
if(ioctl(Fd, MEMUNLOCK, &erase) != 0)
{
perror("\nMTD Unlock failure");
close(Fd);
return 8;
}
}
if (ioctl(Fd,MEMERASE,&erase) != 0)
{
perror("\nMTD Erase failure");
close(Fd);
return 8;
}
erase.start += meminfo.erasesize;
}
printf(" done\n");
}
return 0;
}


/** fpga print info
*/
int print_fpga(void)
{
char str[128];

sprintf(str,"nconfig:%d\n", fpga_dev.nconfig);
printf(str);
sprintf(str,"rompath sel:%d\n", fpga_dev.rompath_sel);
printf(str);
sprintf(str,"conf_done:%d\n", fpga_dev.conf_done);
printf(str);
sprintf(str,"nstatus:%d\n", fpga_dev.nstaus);
printf(str);

return 0;
}


/** after write flash, poll up nconfig single, and wait at least 2us
*/
int fpga_nconfig()
{
char str[128];
int ret, param;

/* pull down rompath sel */
ret = ioctl(fpga_dev.fd, FPGA_IOC_RST_GPIO, FPGA_GPIO_ROMPATH_SEL);
if(ret < 0) {
sprintf(str,"Unable to rst nconfig single, errno=%d\n",errno);
printf(str);
return -1;
}

sleep(20);

/* pull down nconfig */
ret = ioctl(fpga_dev.fd, FPGA_IOC_RST_GPIO, FPGA_GPIO_NCONFIG);
if(ret < 0) {
sprintf(str,"Unable to rst nconfig single, errno=%d\n",errno);
printf(str);
return -1;
}

/* sleep 2us */
sleep(2);

/* query nconfig*/
param = FPGA_GPIO_NCONFIG;
ret = ioctl(fpga_dev.fd, FPGA_IOC_GET_GPIO, ¶m);
if(ret < 0) {
sprintf(str,"Unable to get single, errno=%d\n",errno);
printf(str);
return -1;
}
fpga_dev.nconfig = param;
printf("================query nconfig:%d\n", fpga_dev.nconfig);

/* pull up nconfig */
ret = ioctl(fpga_dev.fd, FPGA_IOC_SET_GPIO, FPGA_GPIO_NCONFIG);
if(ret < 0) {
sprintf(str,"Unable to set nconfig single, errno=%d\n",errno);
printf(str);
return -1;
}

return 0;
}


/** check status
*/
int fpga_check()
{
char str[128];
int ret, param;

param = FPGA_GPIO_NCONFIG;
ret = ioctl(fpga_dev.fd, FPGA_IOC_GET_GPIO, ¶m);
if(ret < 0) {
sprintf(str,"Unable to get single, errno=%d\n",errno);
printf(str);
return -1;
}
fpga_dev.nconfig = param;


param = FPGA_GPIO_ROMPATH_SEL;
ret = ioctl(fpga_dev.fd, FPGA_IOC_GET_GPIO, ¶m);
if(ret < 0) {
sprintf(str,"Unable to get rompath sel single, errno=%d\n",errno);
printf(str);
return -1;
}
fpga_dev.rompath_sel = param;


/* get conf done */
param = FPGA_GPIO_CONF_DONE;
ret = ioctl(fpga_dev.fd, FPGA_IOC_GET_GPIO, ¶m);
if(ret < 0) {
sprintf(str,"Unable to get conf_done single, errno=%d\n",errno);
printf(str);
return -1;
}
fpga_dev.conf_done = param;


/* get nstaus */
param = FPGA_GPIO_NSTATUS;
ret = ioctl(fpga_dev.fd, FPGA_IOC_GET_GPIO, ¶m);
if(ret < 0) {
sprintf(str,"Unable to get nstatus single, errno=%d\n",errno);
printf(str);
return -1;
}
fpga_dev.nstaus = param;

print_fpga();
return 0;
}


/** open fpga device
*
*/
static int open_device(void)
{
char str[128];
int ret;

fpga_dev.fd = open("/dev/fpga", O_RDWR);
if (fpga_dev.fd < 0) {
sprintf(str, "Unable to open file /dev/fpga, errno=%d\n", errno);
printf(str);
return -1;
}
printf("successful open device /dev/fpga. file handle:%d\n", fpga_dev.fd);

return 0;
}

static int close_device(void)
{
close(fpga_dev.fd);

return 0;
}


/** get file size
*/
unsigned long get_file_size(const char *path)
{
unsigned long filesize = -1;
struct stat statbuff;
if(stat(path, &statbuff) < 0) {
return filesize;
}else{
filesize = statbuff.st_size;
}
return filesize;
}



/* read */
int flash_erase(const char* device)
{
int fd;
int bytes_read;
struct mtd_info_user info;
int regcount;
int start;
int count;
int unlock;
int ret;

/*1. open dst mtd device file */
if ((fd = open(device, O_RDWR)) < 0)
{
fprintf(stderr,"Open %s Error:%s\n", device, strerror(errno));
return -1;
}
else
{
if(ioctl(fd,MEMGETINFO,&info) == 0)
{
/*
printf("info.size=%d\n info.erasesize=%d\ninfo.writesize=%d\n
info.oobsize=%d\n",
info.size,info.erasesize,info.writesize,info.oobsize);
*/
}
}

/* flash erase */
start = 0;
count = info.size/info.erasesize;
unlock = 0;
printf("Erase Total %d Units\n", count);

if (ioctl(fd,MEMGETREGIONCOUNT,®count) == 0)
{
printf("regcount=%d\n",regcount);
if(regcount == 0)
{
ret = non_region_erase(fd, start, count, unlock);
}
else
{
ret = region_erase(fd, start, count, unlock, regcount);
}
}

printf("erased flash!\n");
sleep(3);


/* */
close(fd);

return 0;
}


/** write the FPGA config file to Altera ECPS flash device
*/
int program(const char *filename, const char* device)
{
int ret;
int from_fd,to_fd;
int bytes_read,bytes_write;
int file_count, left_bytes;
unsigned long file_size, total_bytes;
char *ptr;

/* check */
if(!filename || !*filename || !device || !*device) {
fprintf(stderr,"Invalidate parameter, application exit\n");
return -1;
}

file_size = get_file_size(filename);
file_count = file_size / BUFFER_SIZE;
left_bytes = file_size % BUFFER_SIZE;
printf("file name:%s, file size:%d bytes, file count:%d, left bytes:%d\n",
filename, file_size, file_count, left_bytes);


/*1. open source file */
if((from_fd=open(filename,O_RDONLY))==-1) /*open file readonly, if error return -1, otherwise return file desc */
{
fprintf(stderr,"Open %s Error:%s\n", filename,strerror(errno));
return -2;
}

/*2. open dst mtd device file */
if ((to_fd = open(device, O_RDWR)) < 0)
{
fprintf(stderr,"Open %s Error:%s\n", device, strerror(errno));
close(from_fd);
return -1;
}


/*3. this is classical copy file code */
int cnt = 0;

total_bytes = 0;
while(bytes_read = read(from_fd, buffer, BUFFER_SIZE))
{
/* debug code */
if(cnt == 0)
{
//memset(buffer, 'A', BUFFER_SIZE);
}

if((bytes_read == -1)&&(errno != EINTR))
break;
else if(bytes_read > 0)
{
ptr = buffer;
while(bytes_write = write(to_fd, ptr, bytes_read))
{
if((bytes_write == -1)&&(errno != EINTR))
{
printf("flash write error.....\n\n\n ");
break;
}
else if(bytes_write == bytes_read)
{
total_bytes += bytes_write;
break;
}
else if(bytes_write > 0)
{
ptr += bytes_write;
bytes_read -= bytes_write;

total_bytes += bytes_write;
}
}// end while

printf("\rWrite %ld bytes\n ", total_bytes);

if(bytes_write == -1)
break;
}

cnt++;
}// end for


printf("\n\n\n");
sleep(5);

// clean:
close(from_fd);
close(to_fd);

return 0;
}

/* read */
int flash_read(const char* device, int size)
{
int fd;
int bytes_read;

/*1. open dst mtd device file */
if ((fd = open(device, O_RDWR)) < 0)
{
fprintf(stderr,"Open %s Error:%s\n", device, strerror(errno));
return -1;
}

/*2. read */
bytes_read = read(fd, read_buffer, size);
printf("read %d bytes from device %s\n", bytes_read, device);

int i;
for(i = 0; i < bytes_read; i++)
{
if(isprint(read_buffer[i]))
printf("%c", read_buffer[i]);
else
printf(".");

if((i + 1) % 16 == 0)
printf("\n");
}
printf("\n\n");

/* */
close(fd);

return 0;
}



/** main routine
*/
int main(int argc, char *argv[])
{
if(3 > argc)
{
printf("Usage: ./program filename device\n");
return -1;
}

fpga_dev.conf_done = -99;
fpga_dev.nstaus = -99;


/* open device */
open_device();

/* check */
fpga_check();

/* erase flash */
flash_erase(argv[2]);


/* program FPGA */
if(program(argv[1], argv[2]) == 0)
{
printf("success program flash!\n");
sleep(3);

flash_read(argv[2], DEBUG_SIZE);

sleep(10);

/* trigger */
fpga_nconfig();

/* check singele */
int i;
for(i = 0; i < 5; i ++)
{
fpga_check();
if( fpga_dev.conf_done == 1 || fpga_dev.nstaus == 1)
{
printf("success query fpga state.");
break;
}
sleep(1);
}

if(i > 5)
printf("can't query fpga state");


}else {
printf("program flash failed!\n");
}


/* close fpga device */
close_device();

return 1;
}


/* [] */



标签:return,fpga,int,Linux,bytes,测试程序,fd,printf,MTD
From: https://blog.51cto.com/u_15911341/5934370

相关文章

  • Linux系统如何查看服务器带宽及网络使用情况
    前言操作系统:Linux操作环境:Centos7Linux系统中如何查看服务器带宽?本篇文章主要和大家分享一下Linux系统中查看服务器带宽的方法,有需要的朋友可以参考一下。 li......
  • linux创建oracle定时任务备份数据
    目录linux创建oracle定时任务备份数据1、查看定时任务2、编辑生成定时任务3、root存放脚本/usr/local/sbin/目录下4、增加免密登录4.1、生成ssh密钥4.2、分发公钥文件linu......
  • Linux上安装MySQL超详细
    Linux上安装MySQL第一步:确保服务器在最新的状态(可有可无)[root@chenstudy~]#yum-yupdate第二步:检测系统是否自带安装MySQL我之前安装过MySQL,现在已经卸载了[roo......
  • [ Linux ] 一篇带你理解Linux下线程概念
    1.Linux线程的概念1.1什么是线程在之前我们谈过Linux的进程,每一个进程都有自己的PCB,和自己的进程地址空间。地址空间和物理内存通过页表建立映射。那么现在我要创建一个新的......
  • Linux(Ubuntu,Cent OS)环境安装mkfontscale mkfontdir命令以及中文字库
    1. 安装mkfontscalemkfontdir和fc-cache命令如果运行mkfontscale命令时终端提示mkfontscale:commandnotfound,则需要首先安装这个命令,安装方法如下:Ubuntu环境下使用......
  • Linux系统查看ntp是否同步的方法有几种?
    Linux中如何查看ntp是否同步?在Linux中,查看ntp是否同步的方法主要有三种,分别是:ntpd命令、ntpstat命令、timedatectl命令,接下来是详细的内容介绍。NTP用于将计算机客......
  • Linux GDB Debugging
    LinuxGDBDebuggingCatalog1.GDBIntroduction2.GDB基本命令 1.GDBIntroductionGDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具,GDB主......
  • Linux相关命令
    目录相关命令1.pwd显示当前工作目录绝对路径2.ls列出目录下全部文件ls-a显示全部文件,包括隐藏文件ls-l可简化成ll,列出详细信息,包括文件的属性和权限3.cd切换到指......
  • 【Azure 应用服务】PHP应用部署在App Service for Linux环境中,上传文件大于1MB时,遇见
    问题描述在PHP项目部署在AppService后,上传文件如果大于1MB就会遇见413RequestEntityTooLarge的问题。 问题解决目前这个问题,首先需要分析应用所在的环境。在AppSe......
  • linux c 语言 strsep trim isspace
     函数原型:              char*strtok(char*s,constchar*delim);                       char*strsep......