历史上的今天
今天是:2024年11月09日(星期六)
2021年11月09日 | u-boot添加yaffs2烧写功能代码分析
2021-11-09 来源:eefocus
最近在学习MINI2440的u-boot移植,在添加yaffs2文件系统烧写这一功能时,网上找到的说明文档都比较笼统,都是给出代码的修改位置。而我想了解其具体执行过程,所以在移植之前简单分析了一下执行过程,记录在此。
本文分析的代码参考了一些文章以及友善之臂UBOOT移植文档的实现,这些文章中的实现基本一致,本文不会列出完整代码,请参考友善之臂UBOOT移植文档或以下文章对比查看:u-boot-2009.08在mini2440上的移植--增加yaffs2文件系统
nand命令执行时调用/common/cmd_nand.c中的do_nand()函数,这里主要的改动是增加了.yaffs2命令的解析,之后执行nand_write_skip_bad(nand,off,&size,(u_char *)addr)函数,这个函数主要的改动如下:
#if defined(CONFIG_MTD_NAND_YAFFS2)
if(nand->rw_oob==1)
{
size_t oobsize = nand->oobsize;
size_t datasize = nand->writesize;
int datapages = 0;
if (((*length)%(nand->oobsize+nand->writesize)) != 0)/* 这里主要判断数据是否对齐 */
{
printf ("Attempt to write error length data!n");
return -EINVAL;
}
datapages = *length/(datasize+oobsize);
*length = datapages*datasize;/* 从这里可以看出此时的length及left_to_write表示的是除 */
left_to_write = *length; /* oob数据之外的数据长度 */
}
#endif
之后调用了nand_write (nand, offset, &write_size, p_buffer)来进行写操作,要注意的是,这里传入的write_size等于上文中的length,即除oob数据之外的有效数据。
接下来的nand_write()函数的修改便是整个过程中最为重要的一个部分了
#if defined(CONFIG_MTD_NAND_YAFFS2)
/*Thanks for hugerat's code!*/
int oldopsmode = 0;
if(mtd->rw_oob==1)
{
int i = 0;
int datapages = 0;
size_t oobsize = mtd->oobsize;
size_t datasize = mtd->writesize;
uint8_t oobtemp[oobsize];
datapages = len / (datasize);
/* 这个for循环将data数据与oob数据进行了整理,以方便赋值给mtd_oob_ops结构体进行写操作 */
/* 这个循环执行流程如下图所示,以5组数据为例 */
for(i = 0; i < (datapages); i++)
{
memcpy((void *)oobtemp, (void *)(buf + datasize * (i + 1)), oobsize);
memmove((void *)(buf + datasize * (i + 1)),
(void *)(buf + datasize * (i + 1) + oobsize),
(datapages - (i + 1)) * (datasize) + (datapages - 1) * oobsize);
memcpy((void *)(buf+(datapages) * (datasize + oobsize) - oobsize),
(void *)(oobtemp), oobsize);
}
}
#endif

从图中可以看出,整个循环结束之后内存中data与oob便分开排列了,且oob区的起始地址为datapages*1024+buf。
接下来便是为上边提到的mtd_oob_ops结构体赋值,包括data和oob的地址、长度,还设置了
chip->ops.mode = MTD_OOB_RAW;这里的意思应该是将ops.oobbuf地址中的oob数据原封不动写入oob区中。
#if defined(CONFIG_MTD_NAND_YAFFS2)//add yaffs2 file system support
/*Thanks for hugerat's code!*/
if(mtd->rw_oob!=1) {
chip->ops.oobbuf = NULL;
} else {
chip->ops.oobbuf = (uint8_t *)(buf+len);
chip->ops.ooblen = mtd->oobsize;
oldopsmode = chip->ops.mode;
chip->ops.mode = MTD_OOB_RAW;
}
#else
chip->ops.oobbuf = NULL;
#endif
之后调用nand_do_write_ops(mtd, to, &chip->ops)函数将数据写入nand flash中,整个过程就基本结束了。
史海拾趣
|
在调上网的时候,新建一个连接的时候,点击配置然后connmc.exe挂掉了。经检查,发现是发的命令(CGQREQ,CGQMIN)返回的数据是空的导致的。但是我手动设置一个,然后在去查也是空,请问这里要如果处理? 我用的上网的方式是用一个虚拟出两个串口, ...… 查看全部问答> |
|
哪位老大帮帮忙,因为有几个接口和JTAG重了,所以我在程序中加了GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable, ENA ...… 查看全部问答> |
|
#include <stdio.h> #include<string.h> void main(void) { char s[20]; strcpy(s, \\"Hello! Turbo C2.0\\ ...… 查看全部问答> |
|
实际设计中,用到的TI器件还是蛮多的,像各种DSP,模拟器件等。德州仪器(TI)通过多种不同的处理技术提供了宽范围的运算放大器产品,在实际应用中非常广泛,其类型包括了高精度、低功率、低电压的产品。TI还开发了业界最大 ...… 查看全部问答> |
|
我想学学430单片机自带的IIC模块使用,现在编了段小程序,可是运行不正确,程序如下,问题在最后面。 //初始化IIC模块 UCB0CTL1 |= UCSWRST; UCB0CTL0 |=UCMST+UCMODE1+UCMODE0+UCSYNC; // I2C Master, syn ...… 查看全部问答> |




