fmql之Linux flash读写

ubuntu在板卡启动后,会占用部分flash的内存。

目前用的是256Mb的flash,型号是w25q256。

数据手册:华邦W25Q256系列flash数据手册

ubuntu系统和启动文件(BOOT.bin等)都放在SD卡。前者放在SD卡的第三个分区,后者放在第一个分区。

现在要进行flash和SD卡的读写测试。

【代码贴到最后了】

flash读写测试

设备名称

首先,要知道板卡中,flash和SD卡分别对应的设备名称。

linux下flash操作命令 • Worktile社区

这样就很清楚了:

  • mtdblock0是flash,大小是32MB (= 256Mb);
  • mmcblk0是SD卡(因为它有三个分区)。

MAJ:MIN是设备的主设备号、次设备号。

【后面才发现,flash读写的设备不能用mtdblock0,而是通过查找/dev/下设备的方式,寻找以mtd开头的设备】

mtd-utils:

嵌入式linux下Flash使用 - 耿通宇 - 博客园

代码测试

接下来就是代码部分: (失败)

Linux下spi读写flash_linux spi flash-CSDN博客

代码中,用的设备是"/dev/mtd4",要把它改成自己对应的flash设备名称。

测试:失败。

驱动代码分析 & 用户驱动代码:

linux块驱动程序分析 之 nand flash 驱动编写过程分析-CSDN博客

https://news.eeworld.com.cn/mcu/ic624239.html

APP代码: (失败)

linux 下对 flash 设备操作的应用程序(嵌入式参考用)_linux 应用层怎么操作flash-CSDN博客

擦除、写入失败。

百度AI给的代码:

flashAPP4.c

cpp 复制代码
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <mtd/mtd-user.h>
#include <string.h>

#define FLASH_DEVICE	"/dev/mtd"	// Flash设备
#define ERASE_SIZE		(256 * 8)			// 擦除块大小

int main() {
	int fd;
	char *data_to_write = "Hello, NOR Flash!";	// 写入的数据
	char *read_buffer;
	struct mtd_info_user mtd_info;
	struct erase_info_user erase_params;
	int result;
	off_t offset = 0; // 假设我们从0字节的位置开始读写

	// 打开Flash设备文件
	fd = open(FLASH_DEVICE, O_RDWR);
	if (fd < 0) {
		perror("Failed to open flash device");
		return -1;
	}

	// 获取Flash信息
	result = ioctl(fd, MEMGETINFO, &mtd_info);
	if (result < 0) {
		perror("Failed to get flash info");
		close(fd);
		return -1;
	}

	// 擦除Flash
	erase_params.start = 0;       // 从0地址开始擦除
	erase_params.length = ERASE_SIZE; // 擦除块大小
	result = ioctl(fd, MEMERASE, &erase_params);
	if (result < 0) {
		perror("Failed to erase flash");
		close(fd);
		return -1;
	} else{
		printf("erase sucessfully\r\n");
	}

	// 写入数据到Flash
	lseek(fd, offset, SEEK_SET); // 设置文件偏移到offset
	result = write(fd, data_to_write, strlen(data_to_write) + 1); // +1是为了包含字符串结尾的null字符
	if (result < 0) {
		perror("Failed to write to flash");
		close(fd);
		return -1;
	} else{
		printf("write sucessfully\r\n");
	}

	// 从Flash读取数据
	lseek(fd, offset, SEEK_SET);
	result = read(fd, read_buffer, sizeof(read_buffer) - 1);
	if (result < 0) {
		perror("Failed to read from flash");
		close(fd);
		return -1;
	}
	read_buffer[result] = '\0'; // 确保字符串结尾有null字符

	// 输出读取的数据
	printf("Read from flash: %s\n", read_buffer);

	// 关闭Flash设备文件
	close(fd);

	return 0;
}

shell命令

shell命令读写擦除flash测试 (应该先做这一步,再写程序)

  • fmql官方给的:
  • 正点原子pdf:
  • 测试:

原来是flash设备名称不对。

代码

修改了flash设备名称后,继续测试:

  • flashAPP4.c 成功
  • flashAPP3.c 成功

贴代码(修正过的):

cpp 复制代码
/***************************************************************
 文件名                 : flashAPP3.c
 作者                   : Skylar
 版本                   : V1.0
 描述                   : flash 读写测试	    w25q256		
 其他                   : /dev/mtd0
 ***************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>

#define FLASH_DEV	"/dev/mtd0"

/* w25q256 */		// 单位是字节
#define FLASH_MAX_SIZE      (32 * 1024 * 1024)		// 256Mb
#define FLASH_PAGE_SIZE     (256)				// 256B
#define FLASH_SECT_SIZE		(16 * 256)			// 4KB
// #define FLASH_BLOCK_SIZE	(32 * 1024)			// 32KB

int main() {
	int fd;
	unsigned char buffer[FLASH_PAGE_SIZE];
	ssize_t bytes_read;
	ssize_t bytes_written;
	off_t offset = 256; // 假设我们从256字节的位置开始读写
	unsigned char erase_buf[4];
	
	// write_data
	int i;
	for(i = 0; i < 256; i++){
		buffer[i] = i + 1;
	}
 
	// 打开NOR Flash设备文件
	fd = open(FLASH_DEV, O_RDWR);
	if (fd == -1) {
		perror("open");
		exit(EXIT_FAILURE);
	}
 
	// 读取数据
	lseek(fd, offset, SEEK_SET); // 移动到指定的文件偏移量
	bytes_read = read(fd, buffer, sizeof(buffer));
	if (bytes_read == -1) {
		perror("read");
		exit(EXIT_FAILURE);
	}
	// 输出读取的数据
	printf("Read from flash: %s\n", buffer);

	// 擦出数据
	lseek(fd, offset, SEEK_SET); // 移动到擦出的起始位置
	bytes_written = write(fd, buffer, sizeof(buffer));
	if (bytes_written == -1) {
		perror("erase");
		exit(EXIT_FAILURE);
	}else{
		printf("erase sucessfully\r\n");
	}
 
	// 写入数据
	// 修改buffer中的数据...
	lseek(fd, offset, SEEK_SET); // 移动到写入的起始位置
	bytes_written = write(fd, buffer, sizeof(buffer));
	if (bytes_written == -1) {
		perror("write");
		exit(EXIT_FAILURE);
	}else{
		printf("write sucessfully\r\n");
	}
 
	close(fd);
	return 0;
}
cpp 复制代码
/***************************************************************
 文件名                 : flashAPP4.c
 描述                   : flash 读写测试	w25q256		
 其他                   : /dev/mtd0		
 ***************************************************************/

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <mtd/mtd-user.h>
#include <string.h>

#define FLASH_DEVICE	"/dev/mtd0"	// Flash设备
#define ERASE_SIZE		(256 * 8 * 32)			// 擦除块大小

int main() {
	int fd;
	char *data_to_write = "Hello, NOR Flash!";	// 写入的数据
	char read_buffer[ERASE_SIZE];
	struct mtd_info_user mtd_info;
	struct erase_info_user erase_params;
	int result;
	off_t offset = 0; // 假设我们从0字节的位置开始读写

	// 打开Flash设备文件
	fd = open(FLASH_DEVICE, O_RDWR);
	if (fd < 0) {
		perror("Failed to open flash device");
		return -1;
	}

	// 获取Flash信息
	result = ioctl(fd, MEMGETINFO, &mtd_info);
	if (result < 0) {
		perror("Failed to get flash info");
		close(fd);
		return -1;
	}

	// 擦除Flash
	erase_params.start = offset;       // 从0地址开始擦除
	erase_params.length = offset + ERASE_SIZE; // 擦除块大小
	result = ioctl(fd, MEMERASE, &erase_params);
	if (result < 0) {
		perror("Failed to erase flash");
		close(fd);
		return -1;
	} else{
		printf("erase sucessfully\r\n");
	}

	// 写入数据到Flash
	lseek(fd, offset, SEEK_SET); // 设置文件偏移到offset
	result = write(fd, data_to_write, strlen(data_to_write) + 1); // +1是为了包含字符串结尾的null字符
	if (result < 0) {
		perror("Failed to write to flash");
		close(fd);
		return -1;
	} else{
		printf("write sucessfully\r\n");
	}

	// 从Flash读取数据
	lseek(fd, offset, SEEK_SET);
	result = read(fd, read_buffer, sizeof(read_buffer) - 1);
	if (result < 0) {
		perror("Failed to read from flash");
		close(fd);
		return -1;
	}
	read_buffer[result] = '\0'; // 确保字符串结尾有null字符

	// 输出读取的数据
	printf("Read from flash: %s\n", read_buffer);

	// 关闭Flash设备文件
	close(fd);

	return 0;
}

读写地址计算:

如何编写linux下nand flash驱动-3 - xmj - 博客园

其他-内核配置修改&编译

内核编译失败!!!

kernel编译失败。

应该是之前make menuconfig修改了某些配置,然后今天编译的时候才发现不通过了。

但是已经忘了修改了什么配置。

目前只知道是AXI Ethernet有关的。

解决了: (花了一整天)

是因为在内核的目录下,make menuconfig之前,没有在FMQL-bsp包的目录下输入source env.sh

!!!!!

和内核的配置没关系!!!

相关推荐
哎呦喂-ll27 分钟前
Linux进阶:环境变量
linux
Rverdoser29 分钟前
Linux环境开启MongoDB的安全认证
linux·安全·mongodb
PigeonGuan39 分钟前
【jupyter】linux服务器怎么使用jupyter
linux·ide·jupyter
东华果汁哥1 小时前
【linux 免密登录】快速设置kafka01、kafka02、kafka03 三台机器免密登录
linux·运维·服务器
北城笑笑1 小时前
FPGA 14 ,硬件开发板分类详解,FPGA开发板与普通开发板烧录的区别
fpga开发·fpga
咖喱鱼蛋2 小时前
Ubuntu安装Electron环境
linux·ubuntu·electron
2202_754421542 小时前
一个计算频率的模块
驱动开发·fpga开发
ac.char2 小时前
在 Ubuntu 系统上安装 npm 环境以及 nvm(Node Version Manager)
linux·ubuntu·npm
肖永威2 小时前
CentOS环境上离线安装python3及相关包
linux·运维·机器学习·centos