ubuntu在板卡启动后,会占用部分flash的内存。
目前用的是256Mb的flash,型号是w25q256。
数据手册:华邦W25Q256系列flash数据手册
ubuntu系统和启动文件(BOOT.bin等)都放在SD卡。前者放在SD卡的第三个分区,后者放在第一个分区。
现在要进行flash和SD卡的读写测试。
【代码贴到最后了】
flash读写测试
设备名称
首先,要知道板卡中,flash和SD卡分别对应的设备名称。
这样就很清楚了:
- mtdblock0是flash,大小是32MB (= 256Mb);
- mmcblk0是SD卡(因为它有三个分区)。
MAJ:MIN是设备的主设备号、次设备号。
【后面才发现,flash读写的设备不能用mtdblock0,而是通过查找/dev/下设备的方式,寻找以mtd开头的设备】
mtd-utils:
代码测试
接下来就是代码部分: (失败)
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
#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 成功
贴代码(修正过的):
/***************************************************************
文件名 : 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;
}
/***************************************************************
文件名 : 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
!!!!!
和内核的配置没关系!!!