次要讲讲怎么实现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 Flashrn");

  /* Erase the destination memory */

  FSMC_NOR_EraseBlock(Address & 0x00FFFFFF);    

  printf("擦除成功rn");

  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个字节rn",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个字节数据rn",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%xrn",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(" |===============================================|rn");

printf("                  STM32 DFU 程序开始              rn");

printf("|===============================================|rn");

/* 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!rn");

FSMC_NOR_EraseBlock(0);

printf("擦除成功!rn");

}

if(!KEY2_STATE())

{

while(!KEY2_STATE());

i=8;

printf("正在擦除,请稍等...rn");

FSMC_NOR_EraseBlock(0);

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

[1] [2]
关键字:STM32  Nor  Flash  DFU 引用地址:STM32 Nor Flash DFU

上一篇:STM32 usb_init.c和usb_int.c文件分析
下一篇:STM32 SPI Flash DFU

推荐阅读

从报告的数据显示,华为、OPPO、vivo的出货量无论是在国内还是海外市场都呈现增长状态,而小米虽然整体上升,但在国内市场呈现16%负增长,这与小米将销售重心外移的政策不无关系。        一个都不能少,国内国外两手抓:华为、OV        “黑科技”这个关键词在华为的发展史上出现的频率一向很高, 拿Mate 20系列来说,7nm AI处理器、...
(文章来源:动点科技) 来自美国哥伦比亚大学创意机器实验室的 Hod Lipson,研发出自我建模的仿生群体 “粒子机器人”,这种机器人未来将可能拥有创造力和自主思考能力。 “一个真正的粒子机器人可能会由成千上百个粒子组成,即便其中 20% 的粒子坏掉,也仍然可以继续运作。”Hod Lipson 强调,“我们认为它带来的好处将会远远超过它的风险。...
据韩国媒体报道称,受断供华为影响,全球内存价格暴降 9%。 报道中提到,统计数据显示截至 10 月底,PC DRAM(DDR4 8Gb)的固定交易价格为 2.85 美元,相比 9 月份的交易价格下降 8.9%。 NAND 闪存 128GB 存储卡和用于 USB 的多层单元存储(MLC)产品在 10 月份的固定交易价格为 4.2 美元,与九月份相比下降了 3.4%,这是今年最低的一...
故障现象有时不开机,不定时重启。检测过程经检测,仪器控制板损坏,造成有时不开机;端口1输出电平超差大,微波开关损坏。维修过程更换控制板组件,更换微波开关组件,调整检测仪器。维修结果仪器开机正常,完成修复。

史海拾趣

问答坊 | AI 解惑

上传一个DIY山寨版的光影棒设计方案

1.显示部分 这是光影棒关键部分,用16个LED显示效果比较好,点阵多,可显示16×16的汉字,也好取模。还可以显示自画图案,点阵多点也好画图案。 最好用双色二极管,这样可以显示两种颜色的字。如果选用贴片的二极管那只能显示两种颜色了。但如果 ...…

查看全部问答∨

Avr的书

发几本书 如有需要请下载…

查看全部问答∨

播放视频时 怎样在上面显示半透明的图标?

   如上,我想了两种办法,但不知道会不会影响效率 1.在每帧图像上画PNG图标或者alphablend画图 2.在播放窗口上搞一个半透明的窗体,有图标的半透明,没图标的全透明 大家有没有更好的办法?…

查看全部问答∨

驱动加载的问题

自己添加的一个无线网卡驱动,如果在内核编译时选M,然后insmod xxx.ko,无线网卡可以正常运行。 如果内核编译时选Y,无线网卡工作不了。 大家有遇到过这种情况吗?问题最有可能出现在哪? …

查看全部问答∨

PIC单片机读出来的.dat文件是BIN文件吗?

公司买了一个单片机程序,结果发给我一个.dat文件 编程器能烧写的是.hex  .bin等没有.dat文件啊 这个.dat文件是不是.bin文件 我烧写的话,是不是要把.dat改成 .bin啊? 有人见过这样的事情吗?…

查看全部问答∨

硬件的问题

开机后出现屏幕出现黑屏是怎么回事啊,盖怎么处理啊…

查看全部问答∨

无线电通信

RT 无线电通信怎么入门啊~~~…

查看全部问答∨

TinyM0开发板的20针脚位定义?

自己收到ZLG的TinyM0的学习板的CK100是采用LPC1343F,通过20针连接LPC1114,不知道这个20针是什么定义的! 是标准的JTAG脚位吗?…

查看全部问答∨

想搞快板子实验,不知道430的开发流程如何,谁来帮个忙发表下!

如题!一直弄着PIC,看到430的功耗更低就想试试!谁知道整套开发工具流程的可以介绍下入门资料,比如编程器以及开发编译环境之类的推荐和简易入门指南都可以!…

查看全部问答∨
小广播
设计资源 培训 开发板 精华推荐

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

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

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved