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。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值