2018.10.18
从逻辑分析仪上发现发送的数据是按照一定的大小来发送的,末尾对应BIN文件的地方正好是1024bytes的末尾。也就是说每次发送的数据有1kb,但是计算发送的数据包的个数大于1024。这就奇怪了,为啥会有变化呢。
BIN文件中的数据段是
01fb ffc0 0000
而逻辑分析仪接收到的数据为:
0x01,0xFB,0xFF,0xDB,0xDC,0x00,0x00
这个C0被转换成了DB DC
那这是个啥呢?
搜索一番,找到一个计算机试题。其中就提到了这个报头如果出现在数据中 ,会被转义成DB DC。。
而这道题的答案就是SLIP。
什么是SLIP,说白了就是串口网络。
快看看NuttX支不支持这个SLIP,搜索一番果然有。有几个地方需要开启一下。
> Networking Support > [*] Networking support
> Device Drivers > [*] Network Device/PHY Support
> Device Drivers > [*] Network Device/PHY Support > [*] SLIP (serial line) support
> Networking Support > Link layer support > [*] SLIP support
接下来编译就出错了。。。。
这个错误提示AF_FAMILY
和NETLIB_SOCK_TYPE
没有定义。
询问了作者,他告诉我,要至少开启一个网络网络协议。但是我觉得这个通讯没有这么复杂。有可能使用SLIP是不对的,因为这个下载并没有建立任何网络联接,只是发送了一些使用SLIP封包格式的数据而已。唉,网络和协议并没有学过啊啊啊啊啊,实在不行,就把SLIP里的封包和解包方式抄过来。。询问作者有什么更好建议,也许是问题太白痴了,人家并没有给出建议。只是给出了需要定义的一些东西。
60 /* The address family that we used to create the socket really does not
61 * matter. It should, however, be valid in the current configuration.
62 */
63
64 #if defined(CONFIG_NET_IPv4)
65 # define AF_FAMILY AF_INET
66 #elif defined(CONFIG_NET_IPv6)
67 # define AF_FAMILY AF_INET6
68 #elif defined(CONFIG_NET_LOCAL)
69 # define AF_FAMILY AF_LOCAL
70 #elif defined(CONFIG_NET_PKT)
71 # define AF_FAMILY AF_PACKET
72 #elif defined(CONFIG_NET_IEEE802154)
73 # define AF_FAMILY AF_IEEE802154
74 #elif defined(CONFIG_NET_BLUETOOTH)
75 # define AF_FAMILY AF_BLUETOOTH
76 #elif defined(CONFIG_NET_USRSOCK)
77 # define AF_FAMILY AF_INET
78 #endif
行吧,随便来搞~~~
去掉可能会涉及到网络还是IP的东西。就剩下AF_LOCAL
和AF_PACKET
。第一个查了一下是进程间的,那么就是这个PACKET了。
menuconfig查找定义,依次开启:
> Build Setup > [*] Prompt for development and/or incomplete code/drivers
> Networking Support > Raw Socket Support > [*] Socket packet socket support
再编译。
提示这是一个没有MAC的网络设备,所以要定义CONFIG_NSH_NOMAC
> Application Configuration > NSH Library > Networking Configuration > [*] Hardware has no MAC address
再来!
IPv4被先定义成了AF_PACKET
,好,关掉。再来。
这回连slip.c都报错了。。。。
行吧。放弃了。事实证明,这里根本就没有所谓的SLIP。只不过是因为连接方式是串口的,而且还用了相同的封包格式。实际上并没有所谓的SLIP。又着实浪费了不少时间啊。。。。。我都怀疑这种封包方式是不是一个什么非常通用的东西啊。。。明天再说。
2018.10.20
把之前开的东西都关掉。还是仔细的来查看esptool.py吧。
def write(self, packet):
buf = b'\xc0' \
+ (packet.replace(b'\xdb',b'\xdb\xdd').replace(b'\xc0',b'\xdb\xdc')) \
+ b'\xc0'
self.trace("Write %d bytes: %s", len(buf), HexFormatter(buf))
self._port.write(buf)
此处我就理解为封包了。替换数据中的 0xDB
为 0xDB 0xDD
,列出来。
0xDB -> 0xDB 0xDD
0xC0 -> 0xDB 0xDC
这个一定要做处理。那就把读取写入封装一下。
先来读取。读取一个帧后,去掉头和尾(就可以吃了),替换转义字符后就是数据内容了。
反过来写:
0xDB 0xDD -> 0xDB
0xDB 0xDC -> 0xC0
先写好定义:
#define ESP_PACK_END 0xC0
#define ESP_PACK_ESC 0xDB
#define ESP_PACK_ESC_END 0xDC
#define ESP_PACK_ESC_ESC 0xDD
2018.10.22
重写接收pthread的逻辑部分,顺便添加一个联合体方便读取数据。:
union RX_FRAME
{
uint8_t RAW_DATA[8];
struct COMMAND_UNPACK
{
uint8_t is_rec;
uint8_t com_ret;
uint16_t len;
uint32_t data;
} COMMAND_UNPACK;
} RX_FRAME;
...
static void *rx_pthread(FAR void *parameter)
{
int rx_fd = (int) ((intptr_t) parameter);
uint8_t RX_TMP;
sem_wait(&sem);
tcflush(rx_fd, TCIFLUSH);
sem_wait(&sem);
int index = 0;
bool REC_PAK = FALSE;
while (1)
{
read(rx_fd, &RX_TMP, 1);
switch(RX_TMP)
{
/* Get END byte */
case ESP_PACK_END:
{
if (index == 0){
REC_PAK = TRUE;
memset((void*) RX_FRAME.RAW_DATA, 0, 10); /* clear RX_FARM */
}
else
{
REC_PAK = FALSE; /* Pass finally byte */
index = 0;
sem_post(&sem);
}
break;
}
/* Get ESC byte */
case ESP_PACK_ESC:
{
uint8_t ESC_CHAR;
read(rx_fd, &ESC_CHAR, 1);
if(ESC_CHAR == ESP_PACK_ESC_ESC)
{
RX_FRAME.RAW_DATA[index] = 0xDB;
}
else if(ESC_CHAR == ESP_PACK_ESC_END)
{
RX_FRAME.RAW_DATA[index] = 0xC0;
}
else
{
RX_FRAME.RAW_DATA[index] = RX_TMP;
}
break;
}
default:
{
if(REC_PAK)
{
RX_FRAME.RAW_DATA[index] = RX_TMP;
index++;
}
}
}
}
pthread_exit((pthread_addr_t) OK);
}
读取线程中就可以改成这样了:
READ_MAC:
// ESP_READ_REG 0x3FF00050
write(tx_fd, READ_ESP_OTP_MAC[0], (size_t) 14);
sem_wait(&sem);
ESP_OTP_MAC0 = RX_FRAME.COMMAND_UNPACK.data;
printf("tx_pthread: 0x3FF00050: 0x%08X\n", ESP_OTP_MAC0);
// ESP_READ_REG 0x3FF00054
write(tx_fd, READ_ESP_OTP_MAC[1], (size_t) 14);
sem_wait(&sem);
ESP_OTP_MAC1 = RX_FRAME.COMMAND_UNPACK.data;
printf("tx_pthread: 0x3FF00054: 0x%08X\n", ESP_OTP_MAC1);
// ESP_READ_REG 0x3FF00058
write(tx_fd, READ_ESP_OTP_MAC[2], (size_t) 14);
sem_wait(&sem);
ESP_OTP_MAC2 = RX_FRAME.COMMAND_UNPACK.data;
printf("tx_pthread: 0x3FF00058: 0x%08X\n", ESP_OTP_MAC2);
// ESP_READ_REG 0x3FF0005C
write(tx_fd, READ_ESP_OTP_MAC[3], (size_t) 14);
sem_wait(&sem);
ESP_OTP_MAC3 = RX_FRAME.COMMAND_UNPACK.data;
printf("tx_pthread: 0x3FF0005C: 0x%08X\n", ESP_OTP_MAC3);
其实这部分也可以写个循环,减少代码量。
for (int i = 0; i < 4; ++i) {
write(tx_fd, READ_ESP_OTP_MAC[i], (size_t) 14);
sem_wait(&sem);
ESP_OTP_MAC[i] = RX_FRAME.COMMAND_UNPACK.data;
printf("tx_pthread: 0x%08X: 0x%08X\n", MAC_ADDR, ESP_OTP_MAC[i]);
}
但是出错了,MAC不正确了。逻辑分析仪显示,tx_pthread连续发送了两次数据;看起来它wait的时候sem值是1。应该是同步没做好。
调整了好久最后也没发现哪里有问题。总是tx在运行到READ_MAC的时候,sem的值还能等于-1,这严重布不合理。总之,这里我使用sem_init初始化了sem值,总算是可以正常工作了。明天开始研究那块8MB的FLASH,我觉得MBED的那个虚拟盘就不错,如果可以利用在这里就好了,可以把固件直接拷贝进去。那时候就可以再留一个自动挂载模块的功能。这个esptool应该也是可以做成模块的。只要把板子连在电脑上,把flash里的esptool模块删除掉。替换一个新的再重启就能更新esptool,美滋滋
2018.10.25
很郁闷,这个flash怎么都挂载不上去。
再三寻找下,无果,最后又又又去group求助,结果是我没格式化。。。。格式化后,果然可以挂载了。但是当我试着创建一个文件夹的时候,出错了。
2018.10.26
找了很久,都没发现问题。那好吧。看起来我需要从头到尾梳理一遍。
先从SPI的驱动开始验证。
芯片手册上说明的时钟速度都在60M以上所以时钟没有超。
使用echo "HAHA" >> /dev/smart0
后用sofi的烧录器读取flash,有HAHA在开头。
SPI部分应该没有问题。
那问题就在这个smartfs文件系统上了?
smartfs的文件在这里:
drivers\mtd\smart.c
有5000+行,有点多。。。
先从初始化开始
int smart_initialize(int minor, FAR struct mtd_dev_s *mtd, FAR const char *partname)
{
FAR struct smart_struct_s *dev;
int ret = -ENOMEM;
uint32_t totalsectors;
#ifdef CONFIG_SMARTFS_MULTI_ROOT_DIRS
FAR struct smart_multiroot_device_s *rootdirdev = NULL;
#endif
/* 完整性检查 */
#ifdef CONFIG_DEBUG_FEATURES
if (minor < 0 || minor > 255 || !mtd)
{
return -EINVAL;
}
#endif
分配SMART设备结构体空间
dev = (FAR struct smart_struct_s *)smart_zalloc(NULL, sizeof(struct smart_struct_s),
"Dev struct");
if (dev)
{
初始化SMART设备结构体
dev->mtd = mtd;
获取设备几何图形。转换为uintptr_t是为了消除对一些长度不同的架构的不同指针的大小的差异
将它们设置为零,假如设备不支持它们。 这里的MTDIOC_GEOMETRY是可以找到地方的,在drivers\mtd\mx25rxx.c文件中的ioctl里。
这部分是为了获取设备的容量,具体查看代码,获取了设备的pageshift,这个应该是页偏移。查了查,这些涉及到Linux的页帧号。打开CONFIG_DEBUG_FS_INFO
后,将打印存起来,因为输出的东西很多。
case MTDIOC_GEOMETRY:
{
FAR struct mtd_geometry_s *geo =
(FAR struct mtd_geometry_s *)((uintptr_t)arg);
if (geo)
{
/* Populate the geometry structure with information need to know
* the capacity and how to access the device.
*
* NOTE: that the device is treated as though it where just an array
* of fixed size blocks. That is most likely not true, but the client
* will expect the device logic to do whatever is necessary to make it
* appear so.
*/
geo->blocksize = (1 << priv->pageshift);
geo->erasesize = (1 << priv->sectorshift);
geo->neraseblocks = priv->nsectors;
ret = OK;
finfo("blocksize: %d erasesize: %d neraseblocks: %d\n",
geo->blocksize, geo->erasesize, geo->neraseblocks);
/* 此处对应输出:
* mx25rxx_ioctl: blocksize: 256 erasesize: 4096 neraseblocks: 16384
*/
}
}
break;
ret = MTD_IOCTL(mtd, MTDIOC_GEOMETRY, (unsigned long)((uintptr_t)&dev->geo));
if (ret < 0)
{
ferr("ERROR: MTD ioctl(MTDIOC_GEOMETRY) failed: %d\n", ret);
goto errout;
}
现在将扇区大小设置为默认值
dev->sectorsize = 0;
ret = smart_setsectorsize(dev, CONFIG_MTD_SMART_SECTOR_SIZE);
if (ret != OK)
{
goto errout;
}
计算此设备上的总扇区并进行验证,如果等于65536,还要减去两个
totalsectors = dev->neraseblocks * dev->sectorsPerBlk;
if (totalsectors > 65536)
{
ferr("ERROR: SMART Sector size too small for device\n");
ret = -EINVAL;
goto errout;
}
else if (totalsectors == 65536)
{
totalsectors -= 2;
}
dev->totalsectors = (uint16_t)totalsectors;
dev->freesectors = (uint16_t)dev->availSectPerBlk * dev->geo.neraseblocks;
dev->lastallocblock = 0;
dev->debuglevel = 0;
将设备格式状态标记为未知,设备名称不超过6,此处为0,所以dev->partname[0] == '\0'
dev->formatstatus = SMART_FMT_STAT_UNKNOWN;
dev->namesize = CONFIG_SMARTFS_MAXNAMLEN; // 6
if (partname)
{
strncpy(dev->partname, partname, SMART_PARTNAME_SIZE);
}
else
{
dev->partname[0] = '\0';
}
这个没定义,所以忽略.
#ifdef CONFIG_SMARTFS_MULTI_ROOT_DIRS
dev->minor = minor;
#endif
扫描设备,跳转到这个函数:(这个函数超级长,就挑重点的)
static int smart_scan(FAR struct smart_struct_s *dev)
{
finfo("Entry\n"); // 日志上有: smart_scan: Entry
/* 通过从大小减小的扇区读取标题来查找卷上的扇区大小。 在格式化的卷上,
* 扇区大小保存在seach扇区的头状态字节中,因此从最大支持的扇区大小开始
* 并从那里开始减少,我们将确保找到作为头而不是扇区数据的数据。
* (就是说从头开始读取扇区,因为每个扇区的开头都会存着此扇区的信息)
*/
sectorsize = 0xffff;
offset = 16384;
while (sectorsize == 0xffff)
{
readaddress = 0;
while (readaddress < dev->erasesize * dev->geo.neraseblocks) // 这两个相乘就是 67108864 = 64M
{
/* Read the next sector from the device */
ret = MTD_READ(dev->mtd, readaddress, sizeof(struct smart_sect_header_s), // 从0开始读取5个字节
(FAR uint8_t *) &header);
/*
* mx25rxx_read: offset: 00000000 nbytes: 5
* mx25rxx_read_byte: address: 00000000 nbytes: 5
* mx25rxx_read: return nbytes: 5
*
* 读取flash上的数据为:00 00 00 00 29
*/
// struct smart_sect_header_s
// {
// uint8_t logicalsector[2]; /* The logical sector number */
// uint8_t seq; /* Incrementing sequence number */
// uint8_t crc8; /* CRC-8 or seq number MSB */
// uint8_t status; /* Status of this sector:
// * Bit 7: 1 = Not commited
// * 0 = commited
// * Bit 6: 1 = Not released
// * 0 = released
// * Bit 5: Sector CRC enable
// * Bit 4-2: Sector size on volume
// * Bit 1-0: Format version (0x1) */
// };
/*
* 在这里加上几行代码,显示一下这个头的内容
*/
finfo("header.logicalsector[0] = %d\n", header.logicalsector[0]);
finfo("header.logicalsector[1] = %d\n", header.logicalsector[1]);
finfo("header.seq = %d\n", header.seq);
finfo("header.crc8 = %d\n", header.crc8);
finfo("header.status = %d\n", header.status);
/*
* 结果是:
* smart_scan: header.logicalsector[0] = 0
* smart_scan: header.logicalsector[1] = 0
* smart_scan: header.seq = 0
* smart_scan: header.crc8 = 0
* smart_scan: header.status = 41
*
* 前面的先不管,后面的status写成二进制:0010 1001
* 0 commited
* 0 released
* 1 enable
* 0 -\
* 1 > Sector size = 2
* 0 -/
* 0 -\
* 1 --> Format version = 1
*
*/
if (ret != sizeof(struct smart_sect_header_s))
{
goto err_out;
}
if (header.status != CONFIG_SMARTFS_ERASEDSTATE)
{
sectorsize = (header.status & SMART_STATUS_SIZEBITS) << 7; // 此时等于256,循环结束
break;
}
readaddress += offset; // 此时等于16384
}
offset >>= 1;
if (offset < 256 && sectorsize == 0xffff) // (sectorsize == 0xffff) = false
{
/* No valid sectors found on device. Default the
* sector size to the CONFIG value
*/
sectorsize = CONFIG_MTD_SMART_SECTOR_SIZE;
}
}
/* 现在设置sectorize和其他sectorize派生变量 */
ret = smart_setsectorsize(dev, sectorsize);
if (ret != OK)
{
goto err_out;
}
ret = smart_scan(dev);
if (ret < 0)
{
ferr("ERROR: smart_scan failed: %d\n", -ret);
goto errout;
}
点进去:
static int smart_scan(FAR struct smart_struct_s *dev)
{
int sector;
int ret;
uint16_t totalsectors;
uint16_t sectorsize, prerelease;
uint16_t logicalsector;
uint16_t loser;
uint32_t readaddress;
uint32_t offset;
uint16_t seq1;
uint16_t seq2;
struct smart_sect_header_s header;
#ifdef CONFIG_MTD_SMART_MINIMIZE_RAM
int dupsector;
uint16_t duplogsector;
#endif
#ifdef CONFIG_SMARTFS_MULTI_ROOT_DIRS
int x;
char devname[22];
FAR struct smart_multiroot_device_s *rootdirdev;
#endif
finfo("Entry\n");
/* Find the sector size on the volume by reading headers from
* sectors of decreasing size. On a formatted volume, the sector
* size is saved in the header status byte of seach sector, so
* by starting with the largest supported sector size and
* decreasing from there, we will be sure to find data that is
* a header and not sector data.
*/
sectorsize = 0xffff;
offset = 16384;
while (sectorsize == 0xffff)
{
readaddress = 0;
while (readaddress < dev->erasesize * dev->geo.neraseblocks) // 这两个相乘就是 67108864 = 64M
{
/* Read the next sector from the device */
ret = MTD_READ(dev->mtd, readaddress, sizeof(struct smart_sect_header_s), // 从0开始读取5个字节
(FAR uint8_t *) &header);
/*
* mx25rxx_read: offset: 00000000 nbytes: 5
* mx25rxx_read_byte: address: 00000000 nbytes: 5
* mx25rxx_read: return nbytes: 5
*
* 读取flash上的数据为:00 00 00 00 29
*/
// struct smart_sect_header_s
// {
// uint8_t logicalsector[2]; /* The logical sector number */
// uint8_t seq; /* Incrementing sequence number */
// uint8_t crc8; /* CRC-8 or seq number MSB */
// uint8_t status; /* Status of this sector:
// * Bit 7: 1 = Not commited
// * 0 = commited
// * Bit 6: 1 = Not released
// * 0 = released
// * Bit 5: Sector CRC enable
// * Bit 4-2: Sector size on volume
// * Bit 1-0: Format version (0x1) */
// };
/*
* 在这里加上几行代码,显示一下这个头的内容
*/
finfo("header.logicalsector[0] = %d\n", header.logicalsector[0]);
finfo("header.logicalsector[1] = %d\n", header.logicalsector[1]);
finfo("header.seq = %d\n", header.seq);
finfo("header.crc8 = %d\n", header.crc8);
finfo("header.status = %d\n", header.status);
/*
* 结果是:
* smart_scan: header.logicalsector[0] = 0
* smart_scan: header.logicalsector[1] = 0
* smart_scan: header.seq = 0
* smart_scan: header.crc8 = 0
* smart_scan: header.status = 41
*
* 前面的先不管,后面的status写成二进制:0010 1001
* 0 commited
* 0 released
* 1 enable
* 0 -\
* 1 > Sector size = 2
* 0 -/
* 0 -\
* 1 --> Format version = 1
*
*/
if (ret != sizeof(struct smart_sect_header_s))
{
goto err_out;
}
if (header.status != CONFIG_SMARTFS_ERASEDSTATE)
{
sectorsize = (header.status & SMART_STATUS_SIZEBITS) << 7; // 此时等于1024,循环结束
finfo("((header.status & SMART_STATUS_SIZEBITS) << 7) = %d\n", sectorsize);
break;
}
readaddress += offset; // 此时等于16384
}
offset >>= 1;
if (offset < 256 && sectorsize == 0xffff) // (sectorsize == 0xffff) = false
{
/* No valid sectors found on device. Default the
* sector size to the CONFIG value
*/
sectorsize = CONFIG_MTD_SMART_SECTOR_SIZE;
}
}
/* Now set the sectorsize and other sectorsize derived variables */
/* 现在设置sectorize和其他sectorize派生变量 */
ret = smart_setsectorsize(dev, sectorsize);
if (ret != OK)
{
goto err_out;
}
/* Initialize the device variables */
/* 初始化设备变量 */
totalsectors = dev->totalsectors;
dev->formatstatus = SMART_FMT_STAT_NOFMT;
dev->freesectors = (dev->availSectPerBlk) * (dev->geo.neraseblocks);
dev->releasesectors = 0;
finfo("totalsectors = %d\n", totalsectors);
finfo("dev->formatstatus = %d\n", dev->formatstatus);
finfo("dev->availSectPerBlk = %d\n", dev->availSectPerBlk);
finfo("dev->geo.neraseblocks = %d\n", dev->geo.neraseblocks);
finfo("dev->freesectors = %d\n", dev->freesectors);
finfo("dev->releasesectors = %d\n", dev->releasesectors);
finfo("dev->neraseblocks = %d\n", dev->neraseblocks);
/*
* smart_scan: totalsectors = 65534
* smart_scan: dev->formatstatus = 2
* smart_scan: dev->availSectPerBlk = 4
* smart_scan: dev->geo.neraseblocks = 16384
* smart_scan: dev->freesectors = 0 这里很奇怪,上面的东西无论如何也不可能乘出0啊
* smart_scan: dev->releasesectors = 0
* smart_scan: dev->neraseblocks = 16384
*/
/*
* 再加一行:
*/
finfo("dev->freesectors <= %d\n", (dev->availSectPerBlk) * (dev->geo.neraseblocks));
/*
* 显示
* smart_scan: dev->freesectors <= 65536
* 这个freesectors是uint16_t的,把65536这个值赋给它就会溢出,0x10000 就剩下后面的0x0000了。不过后面的--一次会变成65535是对的。不知道是故意的还是有意的。
*/
/* Initialize the freecount and releasecount arrays */
for (sector = 0; sector < dev->neraseblocks; sector++) // dev->neraseblocks = 16384
{
if (sector == dev->neraseblocks - 1 && dev->totalsectors == 65534) // if(sector == 16383)
{
prerelease = 2;
}
else
{
prerelease = 0;
}
#ifdef CONFIG_MTD_SMART_PACK_COUNTS
smart_set_count(dev, dev->freecount, sector, dev->availSectPerBlk - prerelease);
smart_set_count(dev, dev->releasecount, sector, prerelease);
#else
dev->freecount[sector] = dev->availSectPerBlk - prerelease;
dev->releasecount[sector] = prerelease;
#endif
}
/* Initialize the sector map */
#ifndef CONFIG_MTD_SMART_MINIMIZE_RAM
for (sector = 0; sector < totalsectors; sector++)
{
dev->sMap[sector] = -1;
}
#else
/* Clear all logical sector used bits */
memset(dev->sBitMap, 0, (dev->totalsectors + 7) >> 3); // 这里吧有点奇怪,把这个长度print一下
finfo("(dev->totalsectors + 7) >> 3 = %d\n", (dev->totalsectors + 7) >> 3);
/*
* smart_scan: (dev->totalsectors + 7) >> 3 = 8192
* 8192看起来没啥问题
*/
#endif
/* Now scan the MTD device */
finfo("dev->mtdBlksPerSector = %d\n", dev->mtdBlksPerSector);
finfo("dev->geo.blocksize = %d\n", dev->geo.blocksize);
finfo("dev->freesectors = %d\n", dev->freesectors);
/*
* smart_scan: dev->mtdBlksPerSector = 4
* smart_scan: dev->geo.blocksize = 256
*
* 读取65534次每个扇区的头
*/
for (sector = 0; sector < totalsectors; sector++)
{
finfo("Scan sector %d\n", sector);
/* Calculate the read address for this sector */
readaddress = sector * dev->mtdBlksPerSector * dev->geo.blocksize; // sector * 4 * 256
/* Read the header for this sector */
ret = MTD_READ(dev->mtd, readaddress, sizeof(struct smart_sect_header_s),
(FAR uint8_t *) &header);
if (ret != sizeof(struct smart_sect_header_s))
{
goto err_out;
}
/* Get the logical sector number for this physical sector */
/* 获取物理扇区的逻辑扇区号 */
logicalsector = *((FAR uint16_t *) header.logicalsector);
#if CONFIG_SMARTFS_ERASEDSTATE == 0x00
if (logicalsector == 0)
{
logicalsector = -1;
}
#endif
/* Test if this sector has been committed */
if ((header.status & SMART_STATUS_COMMITTED) == // if ((header.status & 0x80) == 0x80)
(CONFIG_SMARTFS_ERASEDSTATE & SMART_STATUS_COMMITTED)) // 如果该扇区未被提交,则跳过下面的代码。反知如果被提交了,那么向下运行。
{
continue;
}
/* This block is commited, therefore not free. Update the
* erase block's freecount.
*/
/* 这个块区不是空闲的,更新空闲块区的数量
* erase block's freecount.
*/
#ifdef CONFIG_MTD_SMART_PACK_COUNTS
smart_add_count(dev, dev->freecount, sector / dev->sectorsPerBlk, -1);
#else
dev->freecount[sector / dev->sectorsPerBlk]--;
finfo("dev->freecount[%d] = %d\n", sector / dev->sectorsPerBlk, dev->freecount[sector / dev->sectorsPerBlk]);
/*
* smart_scan: dev->freecount[0] = 3
*/
#endif
dev->freesectors--;
finfo("After dev->freesectors--\n dev->freesectors = %d\n", dev->freesectors);
/* Test if this sector has been release and if it has,
* update the erase block's releasecount.
*/
if ((header.status & SMART_STATUS_RELEASED) != // if((header.status & 0x40) != 0x40)
(CONFIG_SMARTFS_ERASEDSTATE & SMART_STATUS_RELEASED)) // 如果该扇区被释放了,则标记该扇区有释放计数(这个专业名词不知道,起名好难)然后跳过下方代码,第一个扇区的就会运行到if里面去。
{
/*
* Keep track of the total number of released sectors and
* released sectors per erase block.
*/
dev->releasesectors++;
#ifdef CONFIG_MTD_SMART_PACK_COUNTS
smart_add_count(dev, dev->releasecount, sector / dev->sectorsPerBlk, 1);
#else
dev->releasecount[sector / dev->sectorsPerBlk]++;
#endif
continue;
}
if ((header.status & SMART_STATUS_VERBITS) != SMART_STATUS_VERSION) // 如果该扇区格式化版本为1,则继续向下运行
{
continue;
}
/* Validate the logical sector number is in bounds */
if (logicalsector >= totalsectors) // 如果逻辑扇区号超出了65534,那么报错
{
/* Error in logical sector read from the MTD device */
ferr("ERROR: Invalid logical sector %d at physical %d.\n",
logicalsector, sector);
continue;
}
/* If this is logical sector zero, then read in the signature
* information to validate the format signature.
*/
if (logicalsector == 0) // 如果逻辑扇区号等于0,也就是开始的扇区
{
/* Read the sector data */
ret = MTD_READ(dev->mtd, readaddress, 32, // 那么读取32字节
(FAR uint8_t *)dev->rwbuffer);
if (ret != 32)
{
ferr("ERROR: Error reading physical sector %d.\n", sector); // 扇区读不够32
goto err_out;
}
/* Validate the format signature */ // 从flash读出来的BIN文件中可以看到最开头有SMRT这样的字符串
if (dev->rwbuffer[SMART_FMT_POS1] != SMART_FMT_SIG1 || // dev->rwbuffer[5] != 'S'
dev->rwbuffer[SMART_FMT_POS2] != SMART_FMT_SIG2 || // dev->rwbuffer[6] != 'M'
dev->rwbuffer[SMART_FMT_POS3] != SMART_FMT_SIG3 || // dev->rwbuffer[7] != 'R'
dev->rwbuffer[SMART_FMT_POS4] != SMART_FMT_SIG4) // dev->rwbuffer[8] != 'T'
{
/* Invalid signature on a sector claiming to be sector 0! // 释放它
* What should we do? Release it?
*/
continue;
}
/* Mark the volume as formatted and set the sector size */
dev->formatstatus = SMART_FMT_STAT_FORMATTED; // 标记为已被格式化
dev->namesize = dev->rwbuffer[SMART_FMT_NAMESIZE_POS]; // 16
dev->formatversion = dev->rwbuffer[SMART_FMT_VERSION_POS]; // 格式化版本
#ifdef CONFIG_SMARTFS_MULTI_ROOT_DIRS
dev->rootdirentries = dev->rwbuffer[SMART_FMT_ROOTDIRS_POS];
/* If rootdirentries is greater than 1, then we need to register
* additional block devices.
*/
for (x = 1; x < dev->rootdirentries; x++)
{
if (dev->partname[0] != '\0')
{
snprintf(dev->rwbuffer, sizeof(devname), "/dev/smart%d%sd%d",
dev->minor, dev->partname, x+1);
}
else
{
snprintf(devname, sizeof(devname), "/dev/smart%dd%d", dev->minor,
x + 1);
}
/* Inode private data is a reference to a struct containing
* the SMART device structure and the root directory number.
*/
rootdirdev = (struct smart_multiroot_device_s *)
smart_malloc(dev, sizeof(*rootdirdev), "Root Dir");
if (rootdirdev == NULL)
{
ferr("ERROR: Memory alloc failed\n");
ret = -ENOMEM;
goto err_out;
}
/* Populate the rootdirdev */
rootdirdev->dev = dev;
rootdirdev->rootdirnum = x;
ret = register_blockdriver(dev->rwbuffer, &g_bops, 0, rootdirdev);
/* Inode private data is a reference to the SMART device structure */
ret = register_blockdriver(devname, &g_bops, 0, rootdirdev);
}
#endif
}
/* Test for duplicate logical sectors on the device */
/* 测试是否有多个分区 */
#ifndef CONFIG_MTD_SMART_MINIMIZE_RAM
if (dev->sMap[logicalsector] != 0xffff)
#else
if (dev->sBitMap[logicalsector >> 3] & (1 << (logicalsector & 0x07))) /* sBitMap 注释上说这个就是扇区的向量表。
* logicalsector 取低三位 对1进行 左移位
* dev->sBitMap[logicalsector >> 3]
*/
#endif
{
fwarn("Found more than 1 physical sector at %d\n", readaddress);
/* Uh-oh, we found more than 1 physical sector claiming to be
* the same logical sector. Use the sequence number information
* to resolve who wins.
*/
#if SMART_STATUS_VERSION == 1
if (header.status & SMART_STATUS_CRC)
{
seq2 = header.seq;
}
else
{
seq2 = *((FAR uint16_t *) &header.seq);
}
#else
seq2 = header.seq;
#endif
/* We must re-read the 1st physical sector to get it's seq number */
#ifndef CONFIG_MTD_SMART_MINIMIZE_RAM
readaddress = dev->sMap[logicalsector] * dev->mtdBlksPerSector * dev->geo.blocksize;
#else
/* For minimize RAM, we have to rescan to find the 1st sector claiming to
* be this logical sector.
*/
for (dupsector = 0; dupsector < sector; dupsector++)
{
/* Calculate the read address for this sector */
readaddress = dupsector * dev->mtdBlksPerSector * dev->geo.blocksize;
/* Read the header for this sector */
ret = MTD_READ(dev->mtd, readaddress, sizeof(struct smart_sect_header_s),
(FAR uint8_t *) &header);
if (ret != sizeof(struct smart_sect_header_s))
{
goto err_out;
}
/* Get the logical sector number for this physical sector */
duplogsector = *((FAR uint16_t *) header.logicalsector);
#if CONFIG_SMARTFS_ERASEDSTATE == 0x00
if (duplogsector == 0)
{
duplogsector = -1;
}
#endif
/* Test if this sector has been committed */
if ((header.status & SMART_STATUS_COMMITTED) ==
(CONFIG_SMARTFS_ERASEDSTATE & SMART_STATUS_COMMITTED))
{
continue;
}
/* Test if this sector has been release and skip it if it has */
if ((header.status & SMART_STATUS_RELEASED) !=
(CONFIG_SMARTFS_ERASEDSTATE & SMART_STATUS_RELEASED))
{
continue;
}
if ((header.status & SMART_STATUS_VERBITS) != SMART_STATUS_VERSION)
{
continue;
}
/* Now compare if this logical sector matches the current sector */
if (duplogsector == logicalsector)
{
break;
}
}
#endif
ret = MTD_READ(dev->mtd, readaddress, sizeof(struct smart_sect_header_s),
(FAR uint8_t *) &header);
if (ret != sizeof(struct smart_sect_header_s))
{
goto err_out;
}
#if SMART_STATUS_VERSION == 1
if (header.status & SMART_STATUS_CRC)
{
seq1 = header.seq;
}
else
{
seq1 = *((FAR uint16_t *) &header.seq);
}
#else
seq1 = header.seq;
#endif
/* Now determine who wins */
if ((seq1 > 0xfff0 && seq2 < 10) || seq2 > seq1)
{
/* Seq 2 is the winner ... bigger or it wrapped */
#ifndef CONFIG_MTD_SMART_MINIMIZE_RAM
loser = dev->sMap[logicalsector];
dev->sMap[logicalsector] = sector;
#else
loser = dupsector;
#endif
}
else
{
/* We keep the original mapping and seq2 is the loser */
loser = sector;
}
/* Now release the loser sector */
readaddress = loser * dev->mtdBlksPerSector * dev->geo.blocksize;
ret = MTD_READ(dev->mtd, readaddress, sizeof(struct smart_sect_header_s),
(FAR uint8_t *) &header);
if (ret != sizeof(struct smart_sect_header_s))
{
goto err_out;
}
#if CONFIG_SMARTFS_ERASEDSTATE == 0xff
header.status &= ~SMART_STATUS_RELEASED;
#else
header.status |= SMART_STATUS_RELEASED;
#endif
offset = readaddress + offsetof(struct smart_sect_header_s, status);
ret = smart_bytewrite(dev, offset, 1, &header.status);
if (ret < 0)
{
ferr("ERROR: Error %d releasing duplicate sector\n", -ret);
goto err_out;
}
}
#ifndef CONFIG_MTD_SMART_MINIMIZE_RAM
/* Update the logical to physical sector map */
dev->sMap[logicalsector] = sector;
#else
/* Mark the logical sector as used in the bitmap */
dev->sBitMap[logicalsector >> 3] |= 1 << (logicalsector & 0x07);
if (logicalsector < SMART_FIRST_ALLOC_SECTOR)
{
smart_add_sector_to_cache(dev, logicalsector, sector, __LINE__);
}
#endif
}
#if defined (CONFIG_MTD_SMART_WEAR_LEVEL) && (SMART_STATUS_VERSION == 1)
#ifdef CONFIG_MTD_SMART_CONVERT_WEAR_FORMAT
/* We need to check if we are converting an older format with incorrect
* wear leveling data in sector zero to the new format. The old format
* put all zeros in the wear level bit locations, but the new (better)
* way is to leave them 0xff.
*/
#ifndef CONFIG_MTD_SMART_MINIMIZE_RAM
sector = dev->sMap[0];
#else
sector = smart_cache_lookup(dev, 0);
#endif
在这里点进去
static uint16_t smart_cache_lookup(FAR struct smart_struct_s *dev, uint16_t logical)
{
int ret;
uint16_t block, sector;
uint16_t x, physical, logicalsector;
struct smart_sect_header_s header;
size_t readaddress;
physical = 0xffff;
/*
* smart_readsector: logical = 0
*/
/* Test if searching for the last sector used */
fwarn("Test if searching for the last sector used\n");
if (logical == dev->cache_lastlog)
{
fwarn("logical == dev->cache_lastlog = %d", logical);
return dev->cache_lastphys;
}
/* First search for the entry in the cache */
fwarn("First search for the entry in the cache\n");
fwarn("dev->cache_entries = %d\n", dev->cache_entries);
for (x = 0; x < dev->cache_entries; x++)
{
if (dev->sCache[x].logical == logical)
{
/* Entry found in the cache. Grab the physical mapping. */
physical = dev->sCache[x].physical;
break;
}
}
/* If the entry wasn't found in the cache, then we must search the volume
* for it and add it to the cache.
*/
fwarn("If the entry wasn't found in the cache, then we must search the volume\n for it and add it to the cache.\n");
// 刚开始启动的时候是不会找到扇区表的。下面应该就是重建扇区表。
// 照旧把这些变量打印出来,方便分析。
fwarn("dev->availSectPerBlk = 0x%X", dev->availSectPerBlk);
if (physical == 0xffff)
{
/* Now scan the MTD device. Instead of scanning start to end, we
* span the erase blocks and read one sector from each at a time.
* this helps speed up the search on volumes that aren't full
* because of sector allocation scheme will use the lower sector
* numbers in each erase block first.
*/
/* 可以看出,sect per blk 应该是就是块中的每个扇区的意思。
*
*/
for (sector = 0; sector < dev->availSectPerBlk && physical == 0xffff; sector++)
{
/* Now scan across each erase block */
for (block = 0; block < dev->geo.neraseblocks; block++)
{
/* Calculate the read address for this sector */
readaddress = block * dev->erasesize +
sector * dev->sectorsize;
/* Read the header for this sector */
ret = MTD_READ(dev->mtd, readaddress,
sizeof(struct smart_sect_header_s), (FAR uint8_t *) &header);
if (ret != sizeof(struct smart_sect_header_s))
{
goto err_out;
}
/* Get the logical sector number for this physical sector */
logicalsector = *((FAR uint16_t *) header.logicalsector);
#if CONFIG_SMARTFS_ERASEDSTATE == 0x00
if (logicalsector == 0)
{
continue;
}
#endif
fwarn("Sector\t0x%04x\tblock\t0x%04x\taddress\t0x%08x\tlogicsector\t0x%08x\t", sector, block, readaddress, logicalsector);
/* 返回65536行数据:
* smart_cache_lookup: Sector 0x0000 block 0x0000 address 0x00000000 logicsector 0x00000000
* smart_cache_lookup: Sector 0x0000 block 0x0001 address 0x00001000 logicsector 0x00000000
* smart_cache_lookup: Sector 0x0000 block 0x0002 address 0x00002000 logicsector 0x00008888
* ...
* smart_cache_lookup: Sector 0x0000 block 0x3ffd address 0x03ffd000 logicsector 0x00000000
* smart_cache_lookup: Sector 0x0000 block 0x3ffe address 0x03ffe000 logicsector 0x00000000
* smart_cache_lookup: Sector 0x0000 block 0x3fff address 0x03fff000 logicsector 0x00000000
* smart_cache_lookup: Sector 0x0001 block 0x0000 address 0x00000400 logicsector 0x0000ffff
* smart_cache_lookup: Sector 0x0001 block 0x0001 address 0x00001400 logicsector 0x0000ffff
* smart_cache_lookup: Sector 0x0001 block 0x0002 address 0x00002400 logicsector 0x0000ffff
* ...
* smart_cache_lookup: Sector 0x0001 block 0x3ffd address 0x03ffd400 logicsector 0x00000000
* smart_cache_lookup: Sector 0x0001 block 0x3ffe address 0x03ffe400 logicsector 0x00000000
* smart_cache_lookup: Sector 0x0001 block 0x3fff address 0x03fff400 logicsector 0x00000000
* smart_cache_lookup: Sector 0x0002 block 0x0000 address 0x00000800 logicsector 0x0000ffff
* smart_cache_lookup: Sector 0x0002 block 0x0001 address 0x00001800 logicsector 0x0000ffff
* smart_cache_lookup: Sector 0x0002 block 0x0002 address 0x00002800 logicsector 0x0000ffff
* ...
* smart_cache_lookup: Sector 0x0002 block 0x3ffd address 0x03ffd800 logicsector 0x00000000
* smart_cache_lookup: Sector 0x0002 block 0x3ffe address 0x03ffe800 logicsector 0x00000000
* smart_cache_lookup: Sector 0x0002 block 0x3fff address 0x03fff800 logicsector 0x00000000
* smart_cache_lookup: Sector 0x0003 block 0x0000 address 0x00000c00 logicsector 0x0000ffff
* smart_cache_lookup: Sector 0x0003 block 0x0001 address 0x00001c00 logicsector 0x0000ffff
* smart_cache_lookup: Sector 0x0003 block 0x0002 address 0x00002c00 logicsector 0x0000ffff
* ...
* smart_cache_lookup: Sector 0x0003 block 0x3ffd address 0x03ffdc00 logicsector 0x00000000
* smart_cache_lookup: Sector 0x0003 block 0x3ffe address 0x03ffec00 logicsector 0x00000000
* smart_cache_lookup: Sector 0x0003 block 0x3fff address 0x03fffc00 logicsector 0x00000000
*
* 可以看到是分成了四个扇区,每个扇区有16384个块,共计65536个块。每个块有1KB,不过对应表是穿插开的。
* 即向分区1写超过1kb的文件的话,不会连续写在一个地方,会分布开。
* 这里的`0x00000000`很可疑啊。手动检查。对照flash的bin文件。就查找这个·0x03fffc00·地址的数据。
* 结果是意味着末尾的3fffc00 和bin文件的地址对不上。bin的最后地址为7fffff,偏差有一倍。
* 检查datasheet后,发现实际上的地址范围是 7FFFFFh ~ 000000h这样看起来,有可能是smart文件系统将其
* 地址范围搞错了。而且3fffc00地的数据也是FF,并不是00,这样说来,很有可能和驱动那边有关系。
* 这块板子的config文件的作者也回应我了,他怀疑问题在驱动里。此处的问题也验证了作者的话。
* 但是hexdump可以显示的数据可以到达7aa000,这样有没法说明驱动有问题。所以我猜想问题应该是在扇区
* 和块的分配上。
*/
/* Test if this sector has been committed */
if ((header.status & SMART_STATUS_COMMITTED) ==
(CONFIG_SMARTFS_ERASEDSTATE & SMART_STATUS_COMMITTED))
{
continue;
}
/* Test if this sector has been release and skip it if it has */
if ((header.status & SMART_STATUS_RELEASED) !=
(CONFIG_SMARTFS_ERASEDSTATE & SMART_STATUS_RELEASED))
{
continue;
}
if ((header.status & SMART_STATUS_VERBITS) != SMART_STATUS_VERSION)
{
continue;
}
/* Test if this is the sector we are looking for */
if (logicalsector == logical)
{
/* This is the sector we are looking for! Add it to the cache */
physical = block * dev->sectorsPerBlk + sector;
smart_add_sector_to_cache(dev, logical, physical, __LINE__);
break;
}
}
}
}
/* Update the last logical sector found variable */
dev->cache_lastlog = logical;
dev->cache_lastphys = physical;
err_out:
return physical;
}
下面寻找这个扇区大小和块数量到底是在哪里分配的。
最后还是回到了smart的初始化函数中。
int smart_initialize(int minor, FAR struct mtd_dev_s *mtd, FAR const char *partname)
{
...
ret = MTD_IOCTL(mtd, MTDIOC_GEOMETRY, (unsigned long)((uintptr_t)&dev->geo));
...
}
实际执行的代码是:
case MTDIOC_GEOMETRY:
{
FAR struct mtd_geometry_s *geo =
(FAR struct mtd_geometry_s *)((uintptr_t)arg);
if (geo)
{
/* Populate the geometry structure with information need to know
* the capacity and how to access the device.
*
* NOTE: that the device is treated as though it where just an array
* of fixed size blocks. That is most likely not true, but the client
* will expect the device logic to do whatever is necessary to make it
* appear so.
*/
geo->blocksize = (1 << priv->pageshift);
geo->erasesize = (1 << priv->sectorshift);
geo->neraseblocks = priv->nsectors;
ret = OK;
finfo("blocksize: %d erasesize: %d neraseblocks: %d\n",
geo->blocksize, geo->erasesize, geo->neraseblocks);
}
}
break;
更具这里的赋值可以判断得出,这里赋值被初始化。再往下就找到了万恶之源。
/* Set the sector size to the default for now */
dev->sectorsize = 0;
ret = smart_setsectorsize(dev, CONFIG_MTD_SMART_SECTOR_SIZE);
if (ret != OK)
{
goto errout;
}
这里CONFIG_MTD_SMART_SECTOR_SIZE
就是1024
看看内容。
static int smart_setsectorsize(FAR struct smart_struct_s *dev, uint16_t size)
{
uint32_t erasesize;
uint32_t totalsectors;
uint32_t allocsize;
/* Validate the size isn't zero so we don't divide by zero below */
/* 事实上,此时 size = 1024 */
if (size == 0)
{
fwarn("Get size == 0; Set size = %d\n", CONFIG_MTD_SMART_SECTOR_SIZE);
size = CONFIG_MTD_SMART_SECTOR_SIZE;
}
if (size == dev->sectorsize)
{
fwarn("Get size(%d) == dev->sectorsize(%d); Return\n", size, dev->sectorsize);
finfo("size == dev->sectorsize == %d\n", size);
return OK;
}
else
{
fwarn("Get size(%d) != dev->sectorsize(%d);\n", size, dev->sectorsize);
}
/*
* smart_setsectorsize: Get size(1024) != dev->sectorsize(0);
* 说明后面操作被执行了。
*/
fwarn("dev->geo.erasesize = %d\n", dev->geo.erasesize);
erasesize = dev->geo.erasesize;
fwarn("dev->geo.neraseblocks = %d\n", dev->geo.neraseblocks);
dev->neraseblocks = dev->geo.neraseblocks;
fwarn("erasesize = %d\n", erasesize);
dev->erasesize = erasesize;
fwarn("size = %d\n", size);
dev->sectorsize = size;
fwarn("dev->sectorsize / dev->geo.blocksize = %d\n", dev->sectorsize / dev->geo.blocksize);
dev->mtdBlksPerSector = dev->sectorsize / dev->geo.blocksize;
/*
* smart_setsectorsize: dev->geo.erasesize = 4096
* smart_setsectorsize: dev->geo.neraseblocks = 16384
* smart_setsectorsize: erasesize = 4096
* smart_setsectorsize: size = 1024
* smart_setsectorsize: dev->sectorsize / dev->geo.blocksize = 4
*
* 这说明设备的参数还是从dev里来的,还要在往上。
*/
最后找到这里:
int mx25rxx_readid(struct mx25rxx_dev_s *dev)
{
/* Lock the QuadSPI bus and configure the bus. */
mx25rxx_lock(dev->qspi, false);
/* Read the JEDEC ID */
mx25rxx_command_read(dev->qspi, MX25R_RDID, dev->cmdbuf, 3);
/* Unlock the bus */
mx25rxx_unlock(dev->qspi);
finfo("Manufacturer: %02x Device Type %02x, Capacity: %02x\n",
dev->cmdbuf[0], dev->cmdbuf[1], dev->cmdbuf[2]);
/* Check for Macronix MX25Rxx chip */
if (dev->cmdbuf[0] != MX25R_JEDEC_MANUFACTURER ||
dev->cmdbuf[1] != MX25R_JEDEC_MEMORY_TYPE)
{
ferr("ERROR: Unrecognized device type: 0x%02x 0x%02x\n",
dev->cmdbuf[0], dev->cmdbuf[1]);
return -ENODEV;
}
/* Check for a supported capacity */
switch (dev->cmdbuf[2])
{
case MX25R_JEDEC_MX25R6435F_CAPACITY:
dev->sectorshift = MX25R6435F_SECTOR_SHIFT;
dev->pageshift = MX25R6435F_PAGE_SHIFT;
dev->nsectors = MX25R6435F_SECTOR_COUNT;
break;
default:
ferr("ERROR: Unsupported memory capacity: %02x\n", dev->cmdbuf[2]);
return -ENODEV;
}
return OK;
}
而这里的定义在前面
/* MX25R6435F (64 MB) memory capacity */
#define MX25R6435F_SECTOR_SIZE (4*1024)
#define MX25R6435F_SECTOR_SHIFT (12)
#define MX25R6435F_SECTOR_COUNT (16384)
#define MX25R6435F_PAGE_SIZE (256)
#define MX25R6435F_PAGE_SHIFT (8)
而
geo->blocksize = (1 << priv->pageshift);
geo->erasesize = (1 << priv->sectorshift);
geo->neraseblocks = priv->nsectors;
整理一下:
int mx25rxx_readid(struct mx25rxx_dev_s *dev)
{
...
dev->sectorshift = 12;
dev->pageshift = 8;
dev->nsectors = 16384;
...
}
int mx25rxx_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg)
{
...
geo->blocksize = 256;
geo->erasesize = 4096;
geo->neraseblocks = 16384;
...
}
static int smart_geometry(FAR struct inode *inode, struct geometry *geometry)
{
...
erasesize = 4096;
geometry->geo_nsectors = 16384 * 4096 / 1024; // 65536
geometry->geo_sectorsize = 1024;
...
}
结果65536*1024就等于0x4000000
smart_cache_lookup: dev->availSectPerBlk = 0x4
smart_cache_lookup: dev->geo.neraseblocks = 0x4000
smart_cache_lookup: dev->erasesize = 0x1000
smart_cache_lookup: dev->sectorsize = 0x400
...
for (sector = 0; sector < dev->availSectPerBlk && physical == 0xffff; sector++)
{
for (block = 0; block < dev->geo.neraseblocks; block++)
{
...
readaddress = block * dev->erasesize + sector * dev->sectorsize;
...
}
}
感觉是flash的参数配置错误了,把这些数据全发给作者。等他的回信。
作者给我回信了,他确定是驱动问题,将在下周改正。感谢 Simon Piriou。