NuttX的應用記錄 2


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_FAMILYNETLIB_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_LOCALAF_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)

此處我就理解爲封包了。替換數據中的 0xDB0xDB 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。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章