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。