嵌入式Linux系列第5篇:Nand Flash根文件系统制作
1.引言
之前系列的文章介绍了如何编译Uboot、Kernel以及使用默认的ramdisk根文件系统来构建一个完整的嵌入式Linux系统,本篇文章介绍如何从头制作一个放在NAND Flash上的根文件系统。经过我这段时间的总结,rootfs相关的编译、配置等工作还是比较麻烦的。所以你可能会看到一般做核心板的第三方厂家会建议初学者直接使用现成提供的文件系统,比如一个做NUC972核心板的厂家,其文档里这么描述:
再比如另外一个做NXP I.MX6核心板的厂家,其文档里这么描述:
他们都建议初学者直接使用他们提供好的文件系统。但是我还是强烈建议大家自己一步一步的去操作制作一次,因为一是这有助于你理解根文件系统是怎么来的,最小的能用的根文件系统包含了哪些东西,二是将来你很有可能需要对文件系统做一些定制化的裁剪和修改工作,只有自己做了一遍你对会明白这个东西到底是怎么回事,比如我原来就搞不清楚Busybox、Buildroot、Yocto这些名词在Linux中的作用,现在随着实践增多,就大概知道他们的用处了。
2.环境介绍
2.1.硬件
因为本系列博客都会以NUC972为平台来介绍。
2.2.软件
本篇新用到的软件工具一个是busybox,它用来生成文件系统里的几个最基本的文件夹,二是打包工具mkyaffs2,它用来生成能直接烧录到板子里的镜像文件。
大家有没有注意,我为什么每次都把这个官方的链接放过来,让大家自己去下载,原因是我们要知道我们用的东西的源头在哪里,最官方的资料渠道在哪里,这很重要。
我们这次要实现的目标是:自己亲手制作的文件系统能够跑起来,同时能够运行我们第二篇文章介绍的Helloworld程序。
3.使用Busybox制作根文件系统
1)进入到nuc972文件夹,新建一个tool文件夹,用来存放busybox、mkyaffs2等工具,把上面下载的NUC970_Linux_Applications-master.zip文件解压到tool文件夹里,因为解压后含有NUC970_Linux_Applications-master,我们把里面的内容移出来,然后删除掉空的NUC970_Linux_Applications-master文件夹和NUC970_Linux_Applications-master.zip源文件。然后进入到busybox目录里。同样的,在编译前要设置交叉编译的环境变量。
cd ~/nuc972
mkdir tool
unzip NUC970_Linux_Applications-master.zip
cd NUC970_Linux_Applications-master
mv ./* ../
cd ..
rm NUC970_Linux_Applications-master -fr
rm NUC970_Linux_Applications-master.zip
cd busybox-1.22.1/
source ~/nuc972//toolchain/environment.sh
2)make menuconfig 进入配置界面
make menuconfig
我们这里就设置一个地方,其他的全部使用默认配置。
修改make install生成的文件夹路径,我们把默认的./_install改成nuc972目录下的rootfs。
Busybox Settings --->
Installation Options ("make install" behavior) --->
(../../rootfs) BusyBox installation prefix
3)make 编译
make
编译成功后显示如下:
编译完成之后我们可以查看一下busybox的文件属性,可以看到如下信息,说明我们交叉编译的没问题。
4)make install 安装
make install
这样就在前面我们设置的地方生成一个rootfs的文件夹,进到里面看一下
cd ~/nuc972/rootfs
ls
bin、sbin、usr :存放一些命令
linuxrc :挂载根文件系统时,第一个执行的文件
4)再创建几个文件夹
mkdir etc lib dev
5)在 rootfs 目录的dev目录下创建设备节点
cd dev
sudo mknod console c 5 1
sudo mknod null c 1 3
6)在根文件系统rootfs/etc目录下创建一个inittab 文件,在文件里面填写:.console::askfirst:-/bin/sh
cd ../etc
vim inittab
4.文件系统打包
1)进入到tool文件夹的yaffs2utils目录里
cd yaffs2utils
2)编译,生成mkyaffs2
make clean
make
注:编译这个工具,不需要修改Makefile,用file看下属性,它是在x86-64运行的,这是没问题的,因为它就是在Ubuntu下使用的,不是在嵌入式环境下去执行使用的。
将它复制到/usr/bin下以后用起来方便了,可以直接使用这个指令了,你可一在终端敲mkya,然后TAB建看不能出来。
sudo cp mkyaffs2 /usr/bin/
4) 生成文件系统
sudo mkyaffs2 --inband-tags -p 2048 rootfs rootfs_yaffs2.img
5.内核修改
内核也要做一定的修改,具体如下:
1)make menuconfig进入到内核配置界面
make menuconfig
2)默认用的RAM filesytem 需要去掉
General setup —>
[ ] Initial RAM filesystem and RAM disk (initramfs/initrd) support
3)默认的Boot option需要修改成如下:
Boot options --->
(noinitrd root=/dev/mtdblock2 rootfstype=yaffs2 rootflags=inband-tags console=ttyS0,115200n8 rdinit=/sbin/init mem=64M)
4)NAND Flash驱动相关配置
Device Drivers --->
Generic Driver Options --->
<*> Nuvoton NUC970 FMI function selection
Select FMI device to support (Support MTD NAND Flash) --->
5)选中MTD的支持
Device Drivers --->
<*> Memory Technology Device (MTD) support --->
<*> Caching block device access to MTD devices
-*- NAND Device Support --->
-*- Nuvoton NUC970 MTD NAND --->
NUC970 NAND Flash pin selection (Port C) --->
6)选中yaff2文件系统的支持
File systems --->
[*] Miscellaneous filesystems --->
<*> yaffs2 file system support
7)保存配置,编译
6.结果查看
6.1.验证文件系统是否可用
1)将上述生成的kernel 970uimage、文件系统rootfs_yaffs2.img、还有之前第三讲生成的uboot.bin,uboot-spl.bin,以及env.txt 下载到板子里,env.txt做了一些改动,主要是加入了boocmd那一行,这样下载进去就能直接启动了。
baudrate=115200
bootcmd=nboot 0x7fc0 0 0x200000; bootm 0x7fc0
bootdelay=1
ethact=emac
ethaddr=00:00:00:11:66:88
stderr=serial
stdin=serial
stdout=serial
烧写前,最好对芯片进行一次Erase。几个文件的烧写类型及地址大家注意下,别搞错了。
2)上电,看看效果,调试串口打印信息如下:
这一次很顺利啊,一次就成功了,这就说明我们上述做的根文件系统是可以正常使用的了。
6.2.验证helloworld能否在板子上运行
我们还要看看我们之前编译的helloworld程序能不能运行,我们把helloworld放到板子里去,怎么把这个文件放到板子上呢?有以下几种方式:
a) 把Helloworld在Ubuntu下放到rootfs文件夹里,然后按照上述的方法打包、下载进去。
b)通过scp或者NFS服务,直接通过网口放到板子里
c) 先放到U盘里,然后U盘插入到板子上,再复制过去
方法a)自然没问题,不过有些麻烦,方法b)现阶段我们的文件系统并不支持,暂时先不弄了,下一篇文章会介绍scp的移植,我们来试试方法c)吧
1)插入U盘到电脑上,把helloworld拷贝过去
2)把U盘插入到板子上,这时调试串口会自动输出如下信息,提示我们有USB Mass Storage设备接入了,看来内核已经把USB这部门驱动已经做进去了。这不是有点像我们给PC机重装Windows系统的过程,默认鼠标键盘也是可以直接使用的。
我们进入到/dev目录里,可以看到有sda1设备,LINUX所有的存储设备都是映射成"文件"来访问的,包括U盘、光驱、硬盘等。这个sda1就对应我们刚插入的U盘。
那么该如何访问U盘的东西呢?
我们需要挂载,使用mount指令,我们执行以下命令:
mkdir mnt
cd mnt
mkdir usb
cd usb
mount -t vfat /dev/sda1 /mnt/usb
cd /
mkdir opt
cp /mnt/usb/helloworld /opt
完成的事情是把sda1挂载到了/mnt/usb目录上,这样/mt/usb目录里就有了U盘里的内容,然后再复制到了系统的/opt目录。
我们在/opt目录里执行./helloworld,提示如下错误:
-/bin/sh: ./helloworld: not found
这是怎么回事呢?原因很简单,helloworld的执行是需要依赖一些库的,不可能系统里什么都没有就执行能执行成功了。所以需要我们把交叉编译链~/nuc972/toolchain/arm-2014.05/arm-none-linux-gnueabi/libc/lib里的库文件复制到板子的lib目录里。
可以先到arm-2014.05/arm-none-linux-gnueabi/libc/lib目录中,压缩下
tar -cvf lib.bin *
然后通过U盘放到板子的/lib目录中解压
tar -xvf lib.bin
这样操作之后,再次执行helloword,结果如下:
另外可以对板子断电-再上电,看看我们之前操作的内容都还在,因为它是存到NAND Flash里的,所以断电是不丢失的。
7.结束语
如果你亲自动手实现了这篇文章介绍的所有内容,相信你对根文件系统一定有了一个非常感官的认识。包括这篇在内,我用了5篇文章一直在介绍嵌入式Linux基础环境相关的内容,你应该也能感受到这和我们以前接触的单片机开发还是有着较大的差异。从下一篇文章开始,我们就正式进入到具体的应用了。我会陆续介绍GPIO、UART使用;网络通信;WIFI使用;摄像头采集数据;EC20 4G模块使用;QT编程;Opencv使用等。
stm32 CubeMx 怎么实现SD卡sd nand FATFS读写测试
本实验仅用于记录和分享技术经验若涉及侵权请联系我删除。
stm32 CubeMx 实现SD卡/sd nand FATFS读写测试。
材料:stm32F407ZGT6开发板、雷龙公司的SD_NAND 测试板(CSNP1GCR01-AOW)。(一开始是使用 Nandflash的操作起来不太方便而且 stm32cubemx自带的 fatfs还没有磨损平衡算法,很是难受。)
CSNP1GCR01-AOW的优势:
不用写驱动程序自带坏块管理的NAND Flash(贴片式TF卡),尺寸小巧,简单易用,兼容性强,稳定可靠,固件可定制,LGA-8封装,标准SDIO接口,兼容SPI/SD接口,兼容各大MCU平台,可替代普通TF卡/SD卡,尺寸6x8mm毫米,内置SLC晶圆擦写寿命10万次,通过1万次随机掉电测试耐高低温,支持工业级温度-40°~+85°,机贴手贴都非常方便,速度级别Class10(读取速度23.5MB/S写入速度12.3MB/S)标准的SD 2.0协议使得用户可以直接移植标准驱动代码,省去了驱动代码编程环节。支持TF卡启动的SOC都可以用SD NAND,提供STM32参考例程及原厂技术支持,主流容量:128MB/512MB/4GB/8GB,比TF卡稳定,比eMMC便宜,样品免费试用(可到官网找客服小姐姐领取样品哦)。雷龙官网
话不多说开始正文:
stm32cubeMX 版本:6.6.1
MDK5 版本5.35
开始配置STM32
1、 配置时钟:
系统时钟树配置(我这里直接拉满,实际使用根据功耗要求作相应的调整)
2、 配置调试接口
注意DEBUG这个一定要配置,如果是默认的那下载一次程序之后第二次就下载不进去了.
3、配置SDIO:
(我这里还是用了DMA 减少mcu的资源开销)
配置完成之后随便选一个IO口作为SD_NAND的插入检测引脚(没有检测脚的也选上不然在生成代码的时候会有警告,看着很不舒服,我这里选的是 PE4 引脚)
4、配置SDIO的DMA
5、添加文件系统
6、配置堆栈大小(稍微调大一点,不然在读写大一点的数据的时候可能会出错)
7、生成代码
8、生成代码后在 bsp_driver_sd.c这个文件中将这三行代码注释(这是检测SD卡是否接入的引脚 如果不注释在挂载sdnand的时候会提示 not_ready)
9、在main.c中 添加测试代码
*//* USER CODE END Header *//* Includes ------------------------------------------------------------------*/#include "main.h"#include "dma.h"#include "fatfs.h"#include "sdio.h"#include "gpio.h"/* Private includes ----------------------------------------------------------*//* USER CODE BEGIN Includes *//* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*//* USER CODE BEGIN PTD */FATFS fs; /* FatFs 文件系统对象 */FIL file; /* 文件对象 */FRESULT f_res; /* 文件操作结果 */UINT fnum; /* 文件成功读写数量 */BYTE ReadBuffer[1024] = {0}; /* 读缓冲区 */BYTE WriteBuffer[] = /* 写缓冲区 */"This is STM32 working with FatFs\r\n";/* USER CODE END PTD *//* Private define ------------------------------------------------------------*//* USER CODE BEGIN PD *//* USER CODE END PD *//* Private macro -------------------------------------------------------------*//* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*//* USER CODE BEGIN PV *///HAL_SD_CardInfoTypeDef SDCardInfo;//HAL_SD_CardCIDTypeDef SDCard_CID;/* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/void SystemClock_Config(void);/* USER CODE BEGIN PFP *//* USER CODE END PFP *//* Private user code ---------------------------------------------------------*//* USER CODE BEGIN 0 *//* USER CODE END 0 *//*** @brief The application entry point.* @retval int*/int main(void){/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_DMA_Init();MX_SDIO_SD_Init();MX_FATFS_Init();/* USER CODE BEGIN 2 */f_res = f_mount(&SDFatFS, "0:/",1);HAL_Delay(100);if(f_res == FR_NO_FILESYSTEM){f_res = f_mkfs("0:/",FM_FAT|FM_SFD,0,&ReadBuffer,sizeof(ReadBuffer));//格式化SDNANDHAL_Delay(100);if(f_res == FR_OK){f_res = f_mount(NULL,"0:/",1);//取消挂载f_res = f_mount(&SDFatFS, "0:/",1);//重新挂载}}HAL_Delay(100);//写测试--------------------------------------------------------------------f_res = f_open(&SDFile,"helloWorld.txt",FA_CREATE_ALWAYS|FA_WRITE);HAL_Delay(100);f_res = f_write(&SDFile,WriteBuffer,sizeof(WriteBuffer),&fnum);HAL_Delay(100);f_res = f_close(&SDFile);//读测试--------------------------------------------------------------------f_res = f_open(&SDFile,"helloWorld.txt",FA_OPEN_EXISTING | FA_READ);HAL_Delay(100);if(f_res == FR_OK){f_res = f_read(&SDFile,ReadBuffer,sizeof(ReadBuffer),&fnum);}HAL_Delay(100);f_res = f_close(&SDFile);HAL_Delay(100);/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */}/* USER CODE END PTD */配置没问题的程序运行后则可以将 sdnand测试板 插入到读卡器中,读卡器再接到电脑上则就会出现:
打开文件则会出现
至此大功告成!!!!!
需要注意的是最新版的fatfs 文件系统中
FRESULT f_mkfs (const TCHAR* path, /* Logical drive number */BYTE opt, /* Format option */DWORD au, /* Size of allocation unit [byte] */void* work, /* Pointer to working buffer */UINT len /* Size of working buffer */)f_mkfs 这个函数有五个参数,老版本的只有三个参数
所以在格式化的时候得这么来操作
f_res = f_mkfs("0:/",FM_FAT|FM_SFD,0,&ReadBuffer,sizeof(ReadBuffer));相关问答
gps导航仪上看电子书怎么老死机目前导航仪从款式上和使用上分主要有车载嵌入式的和手持便携式(PND)之分,就价格、产品便携性、娱乐性、实用性等多方面来衡量手持便携式都相对具有...
flash 能打开什么文件?flash能直接打开的文件当然是它的后缀为fla的源文件;能通过导入方式添加到它库里的文件有各种视频和音频文件,如mp3、mp4、avi等等,有位图文件bmp、gif、jpg、...
flash 如何画长方体如何用 flash 8画一个动态变化的长方体?长方...[最佳回答]this.createEmptyMovieClip("target_mc",this.getNextHighestDepth());target_mc.loadVariables(...
什么是bios文件?1、先从网站上下载BIOS文件到本地磁盘或者软盘中,再解压缩将生成三个文件***.EXE、***.BIN、README.TXT。2、把以上的***.EXE、***.BIN两个文件存在专门建立...
切出来之后显示adobe flash player崩溃!-ZOL问答7人讨论9775次围观关注问题写回答讨论回答(7)dsnfszbqeulgflash有火狐专用版的,你下载这个重新安装试试。百度搜搜这款。有用(0)回复qiaoteng555这是....
怎样找源代码?可以在项目的官方网站上寻找相关的源代码链接。2.版本控制系统:许多开源项目使用版本控制系统(如Git或SVN)来管理源代码。可以通过访问项目的版本控制仓库来...
电脑上怎么样下载安装我的文档-ZOL问答dsnzyxvmeiwy将百度文库中的文档下载至电脑中的操作步骤:1、浏览器进入百度...这很正常,电视可以播放flash,TXT试一下。有用(0)回复limingjie95你把你的d....
网站如何快速收录,不收录怎么办?5.完成验证后,权益继承成功,回到工具页面即可进行数据提交;4.提交方式快速收录包含手动提交和API提交两种方式,使用API提交方式请使用平台提供的最新接口进...
m文件是什么类型的?单个文件网页可将网站的所有元素(包括文本和图形)都保存到单个文件中。这种封装使您可将整个网站发布为单个内嵌MIME(MIME:通过Internet连接传递多媒体资...
为什么7k7k小游戏打不开?有两种可能。第一你的电脑上没有安装flash动画播放器,所以txt开游戏无法在电脑上进行播放。第二,你的浏览器设置了儿童模式,切开切开游戏设置了权限,所以不...