问题

 

当使用其它型号的外部SPI Flash时,需要如何扩展Bootloader源码?

答案

 

针对于Silicon Labs EmberZNet 和Thread 协议栈,Silicon Labs的Bootloader源码中已经支持多种型号的外部SPI Flash驱动,驱动源码在如下目录:

C:\SiliconLabs\SimplicityStudio\v4\developer\sdks\gecko_sdk_suite\v1.1\platform\base\hal\micro\cortexm3\common\spiflash-class1.c

 

对于客户来说,不同的项目中可能会使用不同大小以及型号的外部SPI Flash,而这些Flash型号可能并不在Silicon Labs默认支持的列表中。因此,需要软件工程师对spiflash-class1.c 进行扩展,以增加对该SPI Flash的支持。本文的目的是帮助工程师理解并掌握如何扩展自己所需要的外部SPI Flash。

 

下表列出了Silicon Labs已经支持的SPI Flash型号。如果客户使用的型号已经在这个表格里面,则无需做任何扩展。

Macronix

·         MX25L2006E (2Mbit)

·         MX25L4006E (4Mbit)

·         MX25L8006E (8Mbit)

·         MX25R8035F (8Mbit low power)

·         MX25L1606E (16Mbit)

·         MX25U1635E (16Mbit 2Volt)

·         MX25R6435F (64Mbit low power)

ISSI

·         IS25LQ025B (256Kbit)

·         IS25LQ512B (512Kbit)

·         IS25LQ010B (1Mbit)

·         IS25LQ020B (2Mbit)

·         IS25LQ040B (4Mbit)

Numonyx/Micron

·         M25P20 (2Mbit)

·         M25P40 (4Mbit)

·         M25P80 (8Mbit)

·         M25P16 (16Mbit)

 Atmel/Adesto

·         AT25DF041A (4Mbit)

·         AT25SF041 (4Mbit)

·         AT25DF081A (8Mbit)

Winbond

·         W25X20BV (2Mbit)

·         W25Q80BV (8Mbit)

Spansion

·         S25FL208K (8Mbit)

 

当客户使用的SPI Flash不属于以上表格中列出的型号时,则需通过对驱动文件spiflash-class1.c进行扩展。

 

  1. 首先,需要理解SPI Flash驱动文件中的结构。
  • 第 43-155行,定义Flash芯片的各种参数,比如大小、速率、页定义以及时序。
  • 第157-247行,定义芯片的Part number名字,注意命名时需要唯一。
  • 第249-533行,定义HalEepromInformationType 结构体,这些参数已经在第43-155行中定义。
  • 第535-561行,定义芯片的枚举变量。
  • 第563行,函数实现。
  1. 接下来最主要的工作是定义HalEepromInformationType 结构体。这需要参考SPI Flash的数据手册。请在bootloader-eeprom.h中查找结构体的定义。
typedef struct {
  uint16_t version;                     /** The version of this data structure */
  uint16_t capabilitiesMask;            /** A bitmask describing the capabilites of this particular external EEPROM */
  uint16_t pageEraseMs;                 /** Maximum time it takes to erase a page. (in 1025Hz Milliseconds) */
  uint16_t partEraseMs;                 /** Maximum time it takes to erase the entire part. (in 1024Hz Milliseconds) */
  uint32_t pageSize;                    /** The size of a single erasable page in bytes */
  uint32_t partSize;                    /** The total size of the external EEPROM in bytes */
  const char * const partDescription;   /** Pointer to a string describing the attached external EEPROM */
  uint8_t wordSizeBytes;                /** The number of bytes in a word for the external EEPROM **/
} HalEepromInformationType;

 

如下示例所示:

 
#if defined(SPIFLASH_SPANSION_S25FL208K)
static const HalEepromInformationType spansion8MInfo = {
 EEPROM_INFO_VERSION,
 EEPROM_CAPABILITIES_ERASE_SUPPORTED | EEPROM_CAPABILITIES_PAGE_ERASE_REQD,
 TIMING_ERASE_4K_MAX_MS,
 TIMING_ERASE_SPANSION_8M_MAX_MS,
 DEVICE_SECTOR_SIZE,
 DEVICE_SIZE_8M,
 "S25FL208K",
 DEVICE_WORD_SIZE // word size in bytes
};
#endif

 

当填充这个结构体时,以下这些值需要使用文件中的默认值。

  • version
  • capabilitiesMask
  • wordSizeBytes

 

以下这些值需要使用Flash的数据手册中的数值。

  • pageEraseMs
  • partEraseMs
  • pageSize
  • partSize

 

以下这个值用于描述Part的字符串。

  • partDescription

 

将结构体定义完成后,使用#if defined宏定义将其包裹起来。一旦所有的这些完成之后,当编译项目时,能正常选择扩展的SPI驱动。如果有任何设置不正确,通常会导致初始化Flash时出现ASSERT。

 

更多内容请参考:

UG266: Silicon Labs Gecko Bootloader User’s Guide

AN1084: Using the Gecko Bootloader with EmberZNet and Silicon Labs Thread

AN772: Using the Ember Application Bootloader

 

  • Proprietary
  • Knowledge Base Articles
  • Wireless