STM32 Nor Flash DFU

发布者:NatureLover最新更新时间:2016-12-20 来源: eefocus关键字:STM32  Nor  Flash  DFU 手机看文章 扫描二维码
随时随地手机看文章

这次要讲讲怎么实现Nor Flash的升级。

Nor Flash的DFU工程还是基于之前的flash DFU的工程上修改而来。工程的目录如下:

STM32 Nor Flash DFU - ziye334 - ziye334的博客

 

我使用的Nor Flash芯片是M29W128F,该芯片共有128Mb的空间,通过FSMC挂接在BANK0。正好在UBS的官方程序里也有使用芯片的例子,所以也就是说管方的Nor Flash的驱动代码是使用M29W128F这款芯片的。所以我们需要从拷贝fsmc_nor.c和fsmc_nor,h这两个文件添加到我们的USB_User这个组中。还要讲我们之前的flash_if文件修改为nor_if名。这样工程的文件就算齐了,下面就讲讲怎么修改个文件。

首先hw_config、usb_istr、usb_prop、usb_pwr这些个文件不需要修改。最新需要修该的文件是usb_desc.c这个文件的接口描述符,上面说过了,我们使用的Nor Flash芯片是M29W128,总空间为128Mb,即16MB。我设置这些空间都可读可写可擦除,并以64K为单位,所以接口描述符如下:



/*接口字符串描述符*/

uint8_t DFU_StringInterface0[DFU_SIZ_STRING_INTERFACE0] =

  {

    DFU_SIZ_STRING_INTERFACE0,

    0x03,

    //Interface 0: "@ NOR Flash: M29W128F /0x64000000/256*064Kg"

    '@', 0, 'N', 0, 'O', 0, 'R', 0, ' ', 0, 'F', 0, 'l', 0, 'a', 0, 's', 0, /*18*/

    'h', 0, ' ', 0,':', 0, ' ',0,'M',0,'2',0,'9',0,'W',0,'1',0,'2',0,'8',0,'F',0, /*24*/

    '/',0,'0',0,'x',0,'6',0,'4',0,'0',0,'0',0,'0',0,'0',0,'0',0,'0',0, /*22*/

    '/', 0, '0', 0, '2', 0, '5', 0, '6', 0, '*', 0, '6', 0, '4', 0, 'K', 0, 'g', 0 /*20*/

  };


接下去需要修改的是nor_if.c这个文件,这个文件是介于驱动和MAL层之间的桥梁。这个文件主要是进一步封装一下nor flash的底层驱动程序。这款需要定义NOR_If_Init()、NOR_If_Erase()、NOR_If_Write()、NOR_If_Read()这4个函数,都是调用驱动代码的相关函数:

/*******************************************************************************

* Function Name  : NOR_If_Init

* Description    : Initializes the Media on the STM32

* Input          : None

* Output         : None

* Return         : None

*******************************************************************************/

uint16_t NOR_If_Init(void)

{

  FSMC_NOR_Init();

  return MAL_OK;

}


/*******************************************************************************

* Function Name  : NOR_If_Erase

* Description    : Erase sector

* Input          : None

* Output         : None

* Return         : None

*******************************************************************************/

uint16_t NOR_If_Erase(uint32_t Address)

{

  printf("正在擦除Nor Flash\r\n");

  /* Erase the destination memory */

  FSMC_NOR_EraseBlock(Address & 0x00FFFFFF);    

  printf("擦除成功\r\n");

  return MAL_OK;

}


/*******************************************************************************

* Function Name  : NOR_If_Write

* Description    : Write sectors

* Input          : None

* Output         : None

* Return         : None

*******************************************************************************/

uint16_t NOR_If_Write(uint32_t Address, uint32_t DataLength)

{

  if ((DataLength & 1) == 1) /* Not an aligned data */

  {

    DataLength += 1;

    MAL_Buffer[DataLength-1] = 0xFF;

  }

  printf("向0x%x地址处写入%d个字节\r\n",Address,DataLength);

  FSMC_NOR_WriteBuffer((uint16_t *)MAL_Buffer, (Address&0x00FFFFFF), DataLength >> 1);  

  

  return MAL_OK;

}


/*******************************************************************************

* Function Name  : NOR_If_Read

* Description    : Read sectors

* Input          : None

* Output         : None

* Return         : buffer address pointer

*******************************************************************************/

uint8_t *NOR_If_Read(uint32_t Address, uint32_t DataLength)

{

  printf("在0x%x地址处读出%d个字节数据\r\n",Address,DataLength);

  return  (uint8_t*)(Address);

}


再接下去就是dfu_mal.c媒体接入层的函数了。这个文件也只定义了5个函数:MAL_Init()、MAL_Erase()、MAL_Write()、MAL_Read()、MAL_GetStatus(),这些函数基本上是调用nor_if.c中定义的相关函数:

uint16_t (*pMAL_Init) (void);

uint16_t (*pMAL_Erase) (uint32_t SectorAddress);

uint16_t (*pMAL_Write) (uint32_t SectorAddress, uint32_t DataLength);

uint8_t  *(*pMAL_Read)  (uint32_t SectorAddress, uint32_t DataLength);

uint8_t  MAL_Buffer[wTransferSize]; /* RAM Buffer for Downloaded Data */


NOR_IDTypeDef NOR_ID;


extern ONE_DESCRIPTOR DFU_String_Descriptor[7];



static const uint16_t  TimingTable[3][2] =

  { /*       扇区擦写时间,            扇区编程时间*/    

    { SPI_FLASH_SECTOR_ERASE_TIME,    SPI_FLASH_SECTOR_WRITE_TIME },    /* SPI Flash */

    { M29W128F_SECTOR_ERASE_TIME,  M29W128F_SECTOR_WRITE_TIME }, /* NOR Flash M29W128F */

    { INTERN_FLASH_SECTOR_ERASE_TIME, INTERN_FLASH_SECTOR_WRITE_TIME }, /* Internal Flash */

  };

/*******************************************************************************

* Function Name  : MAL_Init

* Description    : STM32初始化的媒体初始化

* Input          : None

* Output         : None

* Return         : None

*******************************************************************************/

uint16_t MAL_Init(void)

  FSMC_NOR_Init();  

  NOR_If_Init(); 

  FSMC_NOR_ReadID(&NOR_ID);

  printf("  Nor Flash ID:0x%x 0x%x\r\n",NOR_ID.Manufacturer_Code,NOR_ID.Device_Code1);

  FSMC_NOR_ReturnToReadMode();

  return MAL_OK;

}


/*******************************************************************************

* Function Name  : MAL_Erase

* Description    : 擦除扇区

* Input          : None

* Output         : None

* Return         : None

*******************************************************************************/

uint16_t MAL_Erase(uint32_t SectorAddress)

{


  switch (SectorAddress & MAL_MASK) //参看地址

  {

    case NOR_FLASH_BASE:

      pMAL_Erase = NOR_If_Erase;

      break;      

    default:

      return MAL_FAIL;

  }

  return pMAL_Erase(SectorAddress); //指向擦除函数

}


/*******************************************************************************

* Function Name  : MAL_Write

* Description    : 写扇区

* Input          : None

* Output         : None

* Return         : None

*******************************************************************************/

uint16_t MAL_Write (uint32_t SectorAddress, uint32_t DataLength)

{


  switch (SectorAddress & MAL_MASK) //查看地址

  {

    case NOR_FLASH_BASE:

      pMAL_Write = NOR_If_Write;

      break;

    default:

      return MAL_FAIL;

  }

  return pMAL_Write(SectorAddress, DataLength);//调用写扇区函数

}


/*******************************************************************************

* Function Name  : MAL_Read

* Description    : 度扇区

* Input          : None

* Output         : None

* Return         : Buffer pointer

*******************************************************************************/

uint8_t *MAL_Read (uint32_t SectorAddress, uint32_t DataLength)

{

  switch (SectorAddress & MAL_MASK) //查看地址

  {

    case NOR_FLASH_BASE:

      pMAL_Read = NOR_If_Read;

      break;

    default:

      return 0;

  }

  return pMAL_Read (SectorAddress, DataLength);//调用如扇区函数

}


/*******************************************************************************

* Function Name  : MAL_GetStatus

* Description    : 获取状态

* Input          : None

* Output         : None

* Return         : MAL_OK

*******************************************************************************/

uint16_t MAL_GetStatus(uint32_t SectorAddress , uint8_t Cmd, uint8_t *buffer)

{ //更具地址查找定时表的对应的选项

  uint8_t x = (SectorAddress  >> 26) & 0x03 ; 

  /* 0x000000000 --> 0  SPI Flash*/

  /* 0x640000000 --> 1  Nor Flash*/

  /* 0x080000000 --> 2  Internal Flash*/


  uint8_t y = Cmd & 0x01;  


  SET_POLLING_TIMING(TimingTable[x][y]);  /* x: 擦除/写 定时 */

  /* y: Media              */

  return MAL_OK;

}


最后,我们在main中定义一些测试Nor Flash的一些代码,按键1按下擦写0x64000000地址开始的那个扇区数据;按键2按下表示向spi flash的0地址写入一组数据;按键3按下表示表示向spi flash的0地址写入另一组数据;按键4按下表示读取0地址开始的数据:

u16 TxBuffer0[8]={0x0000,0x0002,0x0004,0x00080,0x0010,0x0020,0x0040,0x0080};

u16 TxBuffer1[8]={0x0100,0x0200,0x0400,0x08000,0x1000,0x2000,0x4000,0x8000};

u16 RxBuffer[8];




int main(void)

{  

u8 i=8;

BSP_Init();

printf(" |===============================================|\r\n");

printf("                  STM32 DFU 程序开始              \r\n");

printf("|===============================================|\r\n");

/* Enter DFU mode */

DeviceState = STATE_dfuERROR;   //程序指向到这句话,说明DFU跳转不成功

DeviceStatus[0] = STATUS_ERRFIRMWARE;

DeviceStatus[4] = DeviceState;


USB_Configuration();   //初始化USB   

while(1)

{

if(!KEY1_STATE())

{

while(!KEY1_STATE());

printf("正在擦除Nor Flash!\r\n");

FSMC_NOR_EraseBlock(0);

printf("擦除成功!\r\n");

}

if(!KEY2_STATE())

{

while(!KEY2_STATE());

i=8;

printf("正在擦除,请稍等...\r\n");

FSMC_NOR_EraseBlock(0);

printf("擦除完毕,正在写入!");

FSMC_NOR_WriteBuffer(TxBuffer0,0,8);

printf("向Nor Flash写入的数据为:\r\n");

while(i--)

printf("0x%x ",TxBuffer0[i]);

printf("\r\n数据写入完毕!\r\n");

}

if(!KEY3_STATE())

{

while(!KEY3_STATE());

i=8;

printf("正在擦除,请稍等...\r\n");

FSMC_NOR_EraseBlock(0);

printf("擦除完毕,正在写入!");

FSMC_NOR_WriteBuffer(TxBuffer1,0,8);

printf("向Nor Flash写入的数据为:\r\n");

while(i--)

printf("0x%x ",TxBuffer1[i]);

printf("\r\n数据写入完毕!\r\n");

}


if(!KEY4_STATE())

{

while(!KEY4_STATE());

i=8;

printf("正在读取数据...\r\n");

FSMC_NOR_ReadBuffer(RxBuffer,0,8);

printf("读出来的数据为:\r\n");

while(i--)

printf("0x%x ",RxBuffer[i]);

printf("\r\n数据读取完毕!\r\n");

}   

}

}


关键字:STM32  Nor  Flash  DFU 引用地址:STM32 Nor Flash DFU

上一篇:STM32 SPI Flash DFU
下一篇:STM32 USB工程的文件分析

推荐阅读最新更新时间:2024-03-16 15:26

机构:DRAM与NAND FLASH价格下半年将下降
  Gartner 表示,在  NAND  Flash 方面 2017 年第 2 季将会开始呈现反转,使得全球 NAND  Flash 和 SSD 的价格会在 2018 年出现明显下滑,并在 2019 年重新陷入一个相对低点。下面就随嵌入式小编一起来了解一下相关内容吧。   Gartner 表示,自 2016 年中期以来,随着  NAND  Flash 的涨价,SSD 的每字节的成本也出现了惊人上涨。 不过,这种上涨趋势将在本季达到顶峰。 其原因在于中国厂商大量投入生产的结果,在产能陆续开出后,市场价格就一反过去的涨势,开始出现下跌的情况。   Gartner 进一步指出,中国曾在 2014 年表示,将在未来 10 年内花费 1
[嵌入式]
单片机STM32在开发中常用库函数详解
  1.GPIO初始化函数   用法:   voidGPIO_Configuration(void)   {   GPIO_InitTypeDefGPIO_InitStructure;//GPIO状态恢复默认参数   GPIO_InitStructure.GPIO_Pin=GPIO_Pin_标号|GPIO_Pin_标号;   //管脚位置定义,标号可以是NONE、ALL、0至15。   GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//最高输出速度为50MHz   GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//推挽输出   G
[单片机]
S3C2440移植uboot之支持NORFLASH
上节S3C2440移植uboot之支持NAND启动修改了代码支持了NAND启动。这节我们分析uboo使其支持NORFLASH的操作。 目录 1.分析启动错误 2.修改代码 3.在匹配数组中添加我们的NORFLASH 4.然后重新烧写 5.解决栈设置错误的问题 1.分析启动错误   上一节启动uboot出现如下所示,我们搜索下错误代码Flash:   上面的Flash: *** failed *** 是属于uboot第二阶段函数board_init_r()里的代码, 代码如下所示(位于arch/arm/lib/board.c): /*第二阶段*/ void board_init_r(gd_t *id, ulong
[单片机]
S3C2440移植uboot之支持<font color='red'>NOR</font>FLASH
分布式测试系统中数据存储管理技术研究
  引言   本课题研究的数据存储与管理技术可应用于在大型海域进行的水中爆炸效能参数测试的分布式测试系统中,整个系统中基站与主站通过无线传输。由于在海域中的测试环境比较恶劣,对于测试设备的布置比较困难,因此有时需要在短时间内做多次重复性实验。重复性实验就要求将每次所采集的数据实时回传处理或存储管理,为下次实验作准备。本系统所采用的无线传输方式决定不可能在短时间内把大量数据回传。NAND Flash存储器作为一种非易失、大容量、可擦除与重复性编程等优点,在其内部构建文件系统,把多次重复性采集的多种数据以文件格式存储,可为系统由无线传输引起的瓶颈提供另一种解决方案。在存储冲击波数据时,冲击波信号有其典型的特征(最大值特征),可提取
[测试测量]
分布式测试系统中数据存储管理技术研究
STM32—cubeMX+DMA+USART 接收任意长度的数据
前言     之前的一篇文章中我为了可以实现USART接收任意长度的数据,对HAL的库进行了修改,可以实现接收以0x0a结尾的任意长度数据,即认为接收到0x0a时接收结束,见链接:HAL USART接收任意长度。   然而,上述这种方法并不合适,原则上HAL库一般不去修改,不便于其他人移植程序,降低了程序中库的适用性,这是很不好的习惯,所以这种方法并不可取。   后查资料得知STM32中还可以利用DMA的方式实现串口的任意长度数据的接收,故开始学习DMA+串口接收任意长度的数据这种方式。 cubeMX软件配置过程 首先,第一步都是进行时钟树的配置,配置好系统的时钟,不同的芯片配置不同的时钟频率,如图。
[单片机]
<font color='red'>STM32</font>—cubeMX+DMA+USART 接收任意长度的数据
STM32 单片机之 串口重映射
大家好,从今天开始.本人将自己在工作中遇到的问题 和学习体会跟大家一起分享并探讨.下面跟大家说一下STM32单片机的端口重映射,因为是以自己为实例.这里是以USART1的重映射为例.. 因为我要一个TFT_LCD屏的主控板,考虑到FSMC 我选用了STM32F103VCT6 型号的CPU,一不小心串口接到USART1上了.因为在调程序时才发现错了,没得办法,只能通过端口重映射来解决.但是以前没用过端口重映射,只闻其名,未用其身,所以..呵呵 ...只能从头去看了. STM32上有很多I/O口,也有很多的内置外设想I2C,ADC,ISP,USART等,为了节省引出管脚,这些内置外设基本上是与I/O
[单片机]
<font color='red'>STM32</font> 单片机之 串口重映射
stm32变更外部晶振时如何配置时钟、以及HSI的使用
由于stm32的库默认是外部晶振8M的情况下实现的,所以配置串口波特率的时候也是按8M,包括主频。 如果采用外部晶振12M,配置时钟为72MHZ 。 1)PLL倍频这样改: 8M: RCC- CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9);//8*9=72 12M: RCC- CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL6);//12*6=72 库函数:void RCC_PLLConfig(uint32_t RCC_PLLSource, uint32_t RCC_PLLMul) 例
[单片机]
STM32笔记记录2
外部中断控制: STM32的每个IO 都可以作为外部中断的中断输入口,这点也是STM32的强大之处。STM32F103的中断控制器支持19个外部中断/事件请求。每个中断设有状态位,每个中断/事件都有独立的触发和屏蔽设置。STM32F103 的19个外部中断为:     线0~15:对应外部IO 口的输入中断。     线16:连接到PVD输出。     线17:连接到RTC闹钟事件。     线18:连接到USB唤醒事件。 STM32供IO 口使用的中断线只有16个,但是STM32的IO 口却远远不止16个,STM32就这样设计,GPIO的管教GPIOx.0~GPIOx.15(x=A,B,C,D,E,F,G)分别对应中
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved