这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » 国产MCU » 基于国民技术N32G45x的SD卡IAP升级开发

共1条 1/1 1 跳转至

基于国民技术N32G45x的SD卡IAP升级开发

高工
2023-04-27 11:19:01     打赏

由于众所周知的原因,笔者也在做MCU产品的国产化替代方案。N32系列是我的首选方案。

闲话少说,回归正题。我们本次介绍如何基于N32G455VE使用SD卡做为数据媒介完成IAP升级的项目分享。

首先,我们先了解一下什么是IAP?百度百科的解释如下:

“IAP是In Application Programming的首字母缩写,IAP是用户自己的程序在运行过程中对User Flash的部分区域进行烧写,目的是为了在产品发布后可以方便地通过预留的通信口对产品中的固件程序进行更新升级。”

短短几句之中,关键技术点全部包含。我们本次的帖子也将以为为“线”介绍N32的IAP升级过程。

我们首先介绍“用户自己的程序”,我们通常称为“bootloader”,这个技术点。

bootloader,引导程序,在MCU启动首先执行的程序,其也为我们自己编写的程序,但其并不完成项目的任务工作,而是更新或引导app的任务。其主要功能及运行程序流程如下:

  • step0: bootloader启动,与普通程序一样,声明变量,配置外设等

  • step1: 检查是否需要IAP更新

  • step2: 如果不需要更新,则跳转到step4

  • step3: 执行更新操作

  • step4: 运行app程序

经常会被问到:又是bootloader,又是APP程序,这两个和我们平时的程序有什么区别呢?

无论是bootloader还是APP,都是是我们平时编写的程序,它们运行各自的逻辑任务,外设配置与内存读取操作完全一样。仅有一点点儿不同,却非常重要——中断向量表。MCU程序在启动之后,main()函数之前,主要工作是初始化堆栈和配置中断向量表。我们从N32官方的源代码可以看到:

当我们的程序没有bootloader时,即单一程序,则宏的值为默认值0x00,在我们本次有Bootloader程序下,其宏值需要修改为0x4000,即,APP的起始地址为0x08000000+0x4000。

 为了可以在线调试,我们需要修改keil的linker文件,通过keil的工程选项配置完成,如图所示:

01.png

有人会问,为什么是0x08000000,其实道理很简单!因为ARM的spec规定的。咱们平时开发时,也确实没啥必要看得这么深入,这么具体。

程序启动,bootloader,这个步骤我们完成了,接下来就是如何检查是否需要IAP更新了。先放上程序的流程图:

02.png

本次我采取的IAP更新策略是“检查SD卡根目录是否有update.bin文件”?如果有,则进入IAP在线更新程序。否则,直接跳转到已烧入到Flash中的APP。

不过,讲到这里,又引入了另外两个概念:SD卡读写与文件系统。

SD卡读写

SD卡的硬件接口,我本次使用SPI外设接口。SPI的初始化,我们参照N32官方的示例——示例里面写得非常全,超实用。我配置SPI外设参数如下:

/** 
 * @brief:  
 * 
 * @param:  
 * @return: 
 * @note:   
 */
void bsp_spi_init(void)
{
  GPIO_InitType GPIO_InitStructure;
  SPI_InitType SPI_InitStructure;
  /* PCLK2 = HCLK/2 */
  RCC_ConfigPclk2(RCC_HCLK_DIV2);
  RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA | RCC_APB2_PERIPH_SPI1 | RCC_APB2_PERIPH_AFIO, ENABLE);

  /* Configure SPIy pins: SCK, MISO and MOSI ---------------------------------*/
  GPIO_InitStructure.Pin = GPIO_PIN_5 | GPIO_PIN_7;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitPeripheral(GPIOA, &GPIO_InitStructure);

  GPIO_InitStructure.Pin = GPIO_PIN_6;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_InitPeripheral(GPIOA, &GPIO_InitStructure);

  /* SPI1 Config -------------------------------------------------------------*/
  SPI_InitStructure.DataDirection = SPI_DIR_DOUBLELINE_FULLDUPLEX;
  SPI_InitStructure.SpiMode = SPI_MODE_MASTER;
  SPI_InitStructure.DataLen = SPI_DATA_SIZE_8BITS;
  SPI_InitStructure.CLKPOL = SPI_CLKPOL_HIGH;
  SPI_InitStructure.CLKPHA = SPI_CLKPHA_SECOND_EDGE;
  SPI_InitStructure.NSS = SPI_NSS_SOFT;
  SPI_InitStructure.BaudRatePres = SPI_BR_PRESCALER_256;
  SPI_InitStructure.FirstBit = SPI_FB_MSB;
  SPI_InitStructure.CRCPoly = 7;
  SPI_Init(SPI1, &SPI_InitStructure);

  /* Enable SPIy */
  SPI_Enable(SPI1, ENABLE);
}

SD卡的初始化过程的状态流转图

03.png

文件系统

这里不过多解释什么是文件系统。本次采用开源,免费的FatFS协议栈来实现FAT/FAT32文件系统。

FAT文件系统的实现并不复杂,文档内容也不多,建议每个网友们都应该阅读一下,我们按照移植过程说明文档一步一步地实现即可。

还有一个问题我们需要解决:bootloader程序的资源受限。因此,我们对FatFS进行裁减,保留读文件功能,关闭掉其它功能。(这里请参照文末源代码ffconf.h)

说了这么多,在引用内容里面还有一个动词我没有谈及——“烧写”。

在国民技术MCU系列里面N32G455系列的Flash擦除是全片擦除和按页擦除,由于我们Flash的低16KB保存了我们Bootloader程序,全片擦除显示不合适了。在本项目中,我采用了按需擦除的技术方案,用多少擦多少,节约升级操作的时间。核心代码如下:

for (i = 0; i < 256; i++)
    {
        log_buf_len = sprintf(log_buf, "page[%d] is programed, left [%d] bytes\r\n", i, btr);
        bsp_uart_send(log_buf, log_buf_len);
        if (btr < FLASH_PAGE_SIZE)
        {
            fr = f_read(&fil, buf, btr, &br);
            ret = iap_flash_page_write((uint32_t *)buf, FLASH_START_ADDR + i * FLASH_PAGE_SIZE);
            break;
        }
        else
        {
            fr = f_read(&fil, buf, FLASH_PAGE_SIZE, &br);
            ret = iap_flash_page_write((uint32_t *)buf, FLASH_START_ADDR + i * FLASH_PAGE_SIZE);
            btr -= FLASH_PAGE_SIZE;
        }
    }

下面是本次项目bootloader的资源使用情况:

==============================================================================





      Code (inc. data)   RO Data    RW Data    ZI Data      Debug   



      8732        630        700         40       9640     425493   Grand Totals

      8732        630        700         40       9640     425493   ELF Image Totals

      8732        630        700         40          0          0   ROM Totals



==============================================================================



    Total RO  Size (Code + RO Data)                 9432 (   9.21kB)

    Total RW  Size (RW Data + ZI Data)              9680 (   9.45kB)

    Total ROM Size (Code + RO Data + RW Data)       9472 (   9.25kB)



==============================================================================

最后,我们来看看实验的成果:

本次实验的讲解与演示视频











关键词: N32G45x     SD卡     IAP     FATFS     国民技    

共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]