Linux MTD测试程序
来源:互联网 发布:mac chrome广告终结者 编辑:程序博客网 时间:2024/06/05 07:42
/** 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;elseprintf("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 regionsregion_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+1printf("\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;}/* [] */
0 0
- Linux MTD测试程序
- 运行成功的读写MTD的测试程序
- linux mtd
- 使用linux的MTD tests support测试flash性能
- 使用linux的MTD tests support测试flash性能
- linux-mtd FAQ
- linux mtd源码分析
- Linux MTD 源代码分析
- Linux MTD技术简介
- Linux MTD介绍
- linux下的mtd
- LINUX MTD 驱动
- Linux MTD 源代码分析
- linux MTD架构
- Linux MTD 介绍
- Linux MTD层次
- linux mtd - mtdpart.c
- linux kernel mtd 分区
- coffee、grunt、less协同
- UESTC 1712 Easy Problem With Numbers (线段树区间修改+非互素逆元)
- c#中文字大全,转换为字符串格式
- 车厢重组
- android 体系结构图
- Linux MTD测试程序
- Android开发之如何在WebView中点击链接使用自身打开(解决出现的选择使用第三方应用的问题)
- 《深入理解java虚拟机》之类加载机制
- poj--3624--Charm Bracelet(动态规划 水题)
- 使用Navicat Premium对mssql2008r2授权用户
- MFC绘图知识大全
- IOS 开发学习(3): IOS UI架构设计
- 应对Memcached缓存失效,导致高并发查询DB的几种思路
- 如何将计算机加入到域环境中