创建Cortex-M系列芯片下载算法

     我们平时在使用 S T M 32 STM32 STM32系列芯片的时候,在编译好程序之后,可能就是一个简单的鼠标操作,单机一下 K e i l M D K I D E Keil\quad MDK\quad IDE KeilMDKIDE上的 D o w n l o a d Download Download就可以了,但是实际上在下载程序到 F l a s h Flash Flash上的时候还需要一个叫做 F l a s h p r o g r a m m i n g a l g o r i t h m Flash\quad programming\quad algorithm Flashprogrammingalgorithm的东西,如图1所示。因为我们知道一般芯片内部的 F l a s h Flash Flash如果要进行烧录的话,需要先擦除,那么这个 F l a s h p r o g r a m m i n g a l g o r i t h m Flash\quad programming\quad algorithm Flashprogrammingalgorithm就相当于给 K e i l M D K I D E Keil\quad MDK\quad IDE KeilMDKIDE提供了一系列操作内部的 F l a s h Flash Flash的接口。

 
图1.

     一般情况下,芯片供应商已经在对应的 P A C K PACK PACK包里面为你准备好了对应的 F l a s h p r o g r a m m i n g a l g o r i t h m Flash\quad programming\quad algorithm Flashprogrammingalgorithm。那我们现在的问题是如何自己去构建 F l a s h p r o g r a m m i n g a l g o r i t h m Flash\quad programming\quad algorithm Flashprogrammingalgorithm文件。关于这一点大家可以先看一看 A R M ARM ARM公司关于这一块的官方介绍。下面我将简单的介绍一下 C O R T E X − M CORTEX-M CORTEXM系列芯片的 F l a s h p r o g r a m m i n g a l g o r i t h m Flash\quad programming\quad algorithm Flashprogrammingalgorithm文件的构建过程,注意这里是 C O R T E X − M CORTEX-M CORTEXM系列芯片, A R M ARM ARM公司其他系列芯片的 F l a s h p r o g r a m m i n g a l g o r i t h m Flash\quad programming\quad algorithm Flashprogrammingalgorithm文件的构建过程可能还不同。下面的讲解主要基于 C M S I S CMSIS CMSIS官方介绍
     首先找到你的 K e i l M D K I D E Keil\quad MDK\quad IDE KeilMDKIDE P A C K PACK PACK包的安装目录,然后将到图1(这里是我的 K e i l M D K I D E Keil\quad MDK\quad IDE KeilMDKIDE P A C K PACK PACK包的安装目录,你需要确定你自己的)所示的 F l a s h p r o g r a m m i n g a l g o r i t h m Flash\quad programming\quad algorithm Flashprogrammingalgorithm模板工程复制出来。然后可以根据自己的喜好改一下图4和图5中的名字,当然这里不改也是可以的,但是图3的地方还是需要改一下,因为我打算用 S T M 32 F 103 STM32F103 STM32F103作为测试的例子, S T M 32 F 103 STM32F103 STM32F103 M 3 M3 M3的内核,因此这里选择 M 3 M3 M3。最后一步也是最重要的一步是更改图6中的那两个文件,也就是一系列操作内部的 F l a s h Flash Flash的接口,接下来我们会重点讲到。有了这些之后编译这个工程就会生成你所需的 F l a s h p r o g r a m m i n g a l g o r i t h m Flash\quad programming\quad algorithm Flashprogrammingalgorithm

 
图2.
 
图3.
 
图4.
 
图5.
 
图6.

     文件 F l a s h D e v . c FlashDev.c FlashDev.c里面主要是一些参数定义,定义在一个结构体中。图7是这个参数结构体的定义,结构体的第1个元素是下载算法的版本,这里自己填写,第2个元素是芯片相关描述,这里自己填写,第3个元素是 F l a s h Flash Flash所在位置,是片上( O N C H I P ONCHIP ONCHIP),还是片外( E X T _ x _ B I T EXT\_x\_BIT EXT_x_BIT),这里自己填写。第4个元素和第5个元素分别是 F l a s h Flash Flash的起始地址和大小(因为我这里的测试芯片是 S T M 32 F 103 Z E T 6 STM32F103ZET6 STM32F103ZET6,因此 F l a s h Flash Flash 512 K B = 0 x 00080000 512KB=0x00080000 512KB=0x00080000,虽然芯片在启动的时候,地址 0 x 00000000 0x00000000 0x00000000可以自动映射到地址 0 x 08000000 0x08000000 0x08000000,但是这里的起始地址只能写为 0 x 08000000 0x08000000 0x08000000),第6个元素是 F l a s h Flash Flash的一个页的大小, S T M 32 F 103 Z E T 6 STM32F103ZET6 STM32F103ZET6 F l a s h Flash Flash的一个页的大小为 2 K B = 2048 B Y T E S 2KB=2048BYTES 2KB=2048BYTES,第7个元素保留,第8个元素说明 F l a s h Flash Flash擦除完之后的内容,一般擦除完之后都是全F。第9个元素和第10个元素分别是 F l a s h Flash Flash页擦除和片擦除超时时间。最后一个元素定义了整片 F l a s h Flash Flash的页的分布情况,它是一个结构体数组。这个结构体有两个元素,第一个是一个页的大小,另一个是页的起始地址,要注意的是这里不用把每一个页的起始地址和大小都列出来,比如 S T M 32 F 103 Z E T 6 STM32F103ZET6 STM32F103ZET6 F l a s h Flash Flash一共有256个页,每一个页的大小都是 2 K B = 2048 B Y T E S 2KB=2048BYTES 2KB=2048BYTES,因此这里结构体数组的第0个元素写为 ( 2048 , 0 x 00000000 ) (2048,0x00000000) (2048,0x00000000)就可以了(注意这里的起始地址只能写为 0 x 00000000 0x00000000 0x00000000而不能写为 0 x 08000000 0x08000000 0x08000000,具体的细节的原因我占时不知道,如果你这里写为 0 x 08000000 0x08000000 0x08000000,在下载程序的时候会报错,程序无法下载成功),这就表明整片 F l a s h Flash Flash的大小都是 2 K B = 2048 B Y T E S 2KB=2048BYTES 2KB=2048BYTES。别忘了最后还要加一个数组元素 S E C T O R _ E N D SECTOR\_END SECTOR_END。那如果出现 F l a s h Flash Flash的所有页不是同样大小的情况怎么样,我们现在举一个简单的例子,假如 F l a s h Flash Flash开头的8页,每一页的大小都是 8 K B 8KB 8KB,接下来的两页,每一页的大小都是 64 K B 64KB 64KB,接下来的所有页,每一页的大小都是 8 K B 8KB 8KB,如图8所示,这个例子也是上面复制的模板工程里面原来的代码。改完之后的参数结构体如图9所示。

 
图7.
 
图8.
 
图9.

     下面我们来详细介绍一下 F l a s h p r o g r a m m i n g a l g o r i t h m Flash\quad programming\quad algorithm Flashprogrammingalgorithm需要用到的一些接口函数以及相应的流程,这些函数都在文 F l a s h P r g . c FlashPrg.c FlashPrg.c中,如下所示,其中前面4个是必须的,后面3个可以根据需求可选,这里我在测试的时候只实现了必须要实现的接口函数。

  • I n i t ,(必须) Init,(必须) Init,(必须)
  • U n I n i t ,(必须) UnInit,(必须) UnInit,(必须)
  • E r a s e S e c t o r ,(必须) EraseSector,(必须) EraseSector,(必须)
  • P r o g r a m P a g e ,(必须) ProgramPage,(必须) ProgramPage,(必须)
  • E r a s e C h i p ,(可选) EraseChip,(可选) EraseChip,(可选)
  • B l a n k C h e c k ,(可选) BlankCheck,(可选) BlankCheck,(可选)
  • V e r i f y ,(可选) Verify,(可选) Verify,(可选)

     接口函数 B l a n k C h e c k BlankCheck BlankCheck主要的功能是用来检查当前的 F l a s h Flash Flash区域是否是空的,注意对于 F l a s h Flash Flash区域来说空的含义就是这个区域的每一个字节的内容都是全 F F F 0 x F F 0xFF 0xFF,起始如果对于一个区域是全 F F F的话,我们不去擦除就可以直接去烧录。当然这个函数也可以用来检查一块特定的 F l a s h Flash Flash区域的内容是否等于特定的值,比如每一个字节的内容是否等于 0 x A A 0xAA 0xAA。其中参数 a d r adr adr表示要检查的 F l a s h Flash Flash区域的起始地址,参数 s z sz sz表示要检查的 F l a s h Flash Flash区域的大小,参数 p a t pat pat表示要检查的 F l a s h Flash Flash区域的预期的特定值,比如 0 x F F 0xFF 0xFF

int BlankCheck (unsigned long adr, unsigned long sz, unsigned char pat);
Parameters
    adr	Block start address
    sz	Block size in bytes
    pat	Pattern to compare
Returns
    status information:0 when the block content is equal to the pattern pat.
    status information:1 when the block content differs from the pattern pat.

     接口函数 E r a s e C h i p EraseChip EraseChip主要的功能是用来擦除整片 F l a s h Flash Flash区域,如果我们在图10中配置下载算法的对话框中勾选了 E r a s e F u l l C h i p Erase\quad Full\quad Chip EraseFullChip的话,在下载程序的过程中, K e i l M D K I D E Keil\quad MDK\quad IDE KeilMDKIDE就会调用下载算法中的这个接口首先将整片 F l a s h Flash Flash区域擦除,这个函数实现起来是比较简单的,一般芯片设计公司提供的库函数里面就有响应功能的接口函数,参考一下就可以了,比如 S T ST ST公司的 S T M 32 F 103 STM32F103 STM32F103提供的擦除整片 F l a s h Flash Flash区域的接口函数如图11所示。如果我们没有实现这个接口函数的话, K e i l M D K I D E Keil\quad MDK\quad IDE KeilMDKIDE会不断调用 E r a s e S e c t o r EraseSector EraseSector接口函数,直到整片 F l a s h Flash Flash区域被擦除。

int EraseChip (void);
Returns 
    status information: 0 on success.
    status information: 1 on failure.
 
图10.
/*
 *  Erase complete Flash Memory
 *    Return Value:   0 - OK,  1 - Failed
 */

int EraseChip (void) 
{
    FLASH_Status status = FLASH_COMPLETE;

    /* Wait for last operation to be completed */
    status = FLASH_WaitForLastOperation(EraseTimeout);
    if(status == FLASH_COMPLETE)
    {
        /* if the previous operation is completed, proceed to erase all pages */
        FLASH->CR |= CR_MER_Set;
        FLASH->CR |= CR_STRT_Set;
    
        /* Wait for last operation to be completed */
        status = FLASH_WaitForLastOperation(EraseTimeout);

        /* Disable the MER Bit */
        FLASH->CR &= CR_MER_Reset;
    }
    /* Return the Erase Status */
    if(status == FLASH_COMPLETE)
    { 
        return (0);  		
	}
	else
    {
        return (1);  	
	}
}

 
图11.

     接口函数 E r a s e S e c t o r EraseSector EraseSector主要的功能是用来擦除 F l a s h Flash Flash区域的一页内容,如果我们在图10中配置下载算法的对话框中勾选了 E r a s e F u l l S e c t o r s Erase\quad Full\quad Sectors EraseFullSectors的话,在下载程序的过程中, K e i l M D K I D E Keil\quad MDK\quad IDE KeilMDKIDE就会调用下载算法中的这个接口。参数 a d r adr adr表示要擦除的 F l a s h Flash Flash区域的页的起始地址,这个函数实现起来是比较简单的,一般芯片设计公司提供的库函数里面就有响应功能的接口函数,参考一下就可以了,比如 S T ST ST公司的 S T M 32 F 103 STM32F103 STM32F103提供的擦除 F l a s h Flash Flash区域的一页接口函数如图12所示。

int EraseSector (unsigned long adr);
Parameters
    adr	Sector address
Returns
    status information:0 on success.
    status information:1 on failure.

     接口函数 E r a s e S e c t o r EraseSector EraseSector我的具体实现如下所示,因为原本的工程里面没有下面函数中 F L A S H FLASH FLASH等结构体的定义,因此这些结构体的定义,你需要自己添加进去。

/*
 *  Erase Sector in Flash Memory
 *    Parameter:      adr:  Sector Address
 *    Return Value:   0 - OK,  1 - Failed
 */

int EraseSector (unsigned long adr) 
{
    FLASH_Status status = FLASH_COMPLETE;

    /* Wait for last operation to be completed */
    status = FLASH_WaitForLastOperation(EraseTimeout);
  
    if(status == FLASH_COMPLETE)
    { 
        /* if the previous operation is completed, proceed to erase the page */
        FLASH->CR|= CR_PER_Set;
        FLASH->AR = adr; 
        FLASH->CR|= CR_STRT_Set;
    
        /* Wait for last operation to be completed */
        status = FLASH_WaitForLastOperation(EraseTimeout);
    
        /* Disable the PER Bit */
        FLASH->CR &= CR_PER_Reset;
    }

    /* Return the Erase Status */
    if(status == FLASH_COMPLETE)
    { 
        return (0);  		
    }
    else
    {
        return (1);  	
    }
}
 
图12.

     接口函数 I n i t Init Init用来在操作 F l a s h Flash Flash区域前的一些初始化操作,像最基本的,在操作 F l a s h Flash Flash相关的寄存器前需要先解锁。参数 a d r adr adr表示 F l a s h Flash Flash设备的基地址,参数 f n c fnc fnc表示不同的操作,1表示擦除,2表示烧录,3表示验证,参数 c l k clk clk表示操作时的时钟频率,但是我看官方的模板函数里面这三个参数基本没有用到,这里我也没有细究了。这里我的具体实现也比较简单,也就是给 F l a s h Flash Flash操作解锁了。

int Init (unsigned long adr, unsigned long clk, unsigned long fnc);
Parameters
    adr	Device base address
    clk	Clock frequency (Hz)
    fnc	Function code
Returns
    status information:0 on success.
    status information:1 on failure.
/*
 *  Initialize Flash Programming Functions
 *    Parameter:      adr:  Device Base Address
 *                    clk:  Clock Frequency (Hz)
 *                    fnc:  Function Code (1 - Erase, 2 - Program, 3 - Verify)
 *    Return Value:   0 - OK,  1 - Failed
 */

int Init (unsigned long adr, unsigned long clk, unsigned long fnc) 
{
  FLASH_Unlock();
  return (0);                                 
}

     接口函数 P r o g r a m P a g e ProgramPage ProgramPage主要的功能是在下载程序的过程中将编译好的代码文件烧录到 F l a s h Flash Flash区域中,每调用一次该函数只能烧录一页的内容。参数 a d r adr adr表示要烧录的 F l a s h Flash Flash区域的页的起始地址,参数 s z sz sz表示要烧录的 F l a s h Flash Flash区域的页的大小,参数 b u f buf buf存储要烧录到 F l a s h Flash Flash区域的页中的代码的实际内容。这个函数实现起来是比较简单的,但是这里 S T ST ST公司的 S T M 32 F 103 STM32F103 STM32F103的库函数里面没有直接的烧录一页的接口函数,只有烧录一个字或半个字的接口函数, S T M 32 F 103 STM32F103 STM32F103 F l a s h Flash Flash区域一次只能烧录半个字,我们可以可以调用如图13所示的烧录半个字的接口来实现烧录一页的接口函数。

int ProgramPage (unsigned long adr, unsigned long sz, unsigned char *buf);
Parameters
    adr	Page start address
    sz	Page size
    buf	Data to be written
Returns
    status information: 0 on success.
    status information: 1 on failure.
/*
 *  Program Page in Flash Memory
 *    Parameter:      adr:  Page Start Address
 *                    sz:   Page Size
 *                    buf:  Page Data
 *    Return Value:   0 - OK,  1 - Failed
 */

int ProgramPage (unsigned long adr, unsigned long sz, unsigned char *buf) 
{
    FLASH_Status status = FLASH_COMPLETE;	
    sz = (sz + 1) & ~1;                          // Adjust size for Half Words
 
    while (sz) 
    {
        status = FLASH_COMPLETE;
        status=FLASH_ProgramHalfWord(adr, *((unsigned short *)buf));		
        /* Return the Program Status */
        if(status != FLASH_COMPLETE)
        { 
            return (1);  	
	    }	
        /* Go to next Half Word */
        adr += 2;
        buf += 2;
        sz  -= 2;				
    }
    return (0);                                 
}
 
图13.

     接口函数 U n I n i t UnInit UnInit用来进行在操作(擦除,烧录,验证) F l a s h Flash Flash区域后的一些操作,像最基本的,对 F l a s h Flash Flash相关的寄存器重新上锁。参数 f n c fnc fnc表示不同的操作,1表示擦除,2表示烧录,3表示验证,但是我看官方的模板函数里面这个参数基本没有用到,这里我也没有细究了。这里我的具体实现也比较简单,也就是给 F l a s h Flash Flash重新上锁。

int UnInit (unsigned long fnc);
Parameters
    fnc	Function code
Returns
    status information:0 on success.
    status information:1 on failure.
/*
 *  De-Initialize Flash Programming Functions
 *    Parameter:      fnc:  Function Code (1 - Erase, 2 - Program, 3 - Verify)
 *    Return Value:   0 - OK,  1 - Failed
 */

int UnInit (unsigned long fnc) 
{
  FLASH_Lock();
  return (0);                                 
}

     接口函数 V e r i f y Verify Verify主要的功能是对比已经下载到 F l a s h Flash Flash区域中的代码和代码文件,也就是看下载到 F l a s h Flash Flash区域中的代码和编译生成的代码是否一致。参数 a d r adr adr表示要对比的 F l a s h Flash Flash区域的起始地址,参数 s z sz sz表示要对比的 F l a s h Flash Flash区域的大小,参数 b u f buf buf存储要对比的代码的实际内容。

unsigned long Verify (unsigned long adr, unsigned long sz, unsigned char *buf);
Parameters
    adr	Start address
    sz	Size in bytes
    buf	Data to be compared
Returns
    status information:the sum of (adr+sz) - on success.
    status information:any other number - on failure, and represents the failing address.

     有了以上修改之后,编译这个模板工程就可以生成你所需的下载算法了,下载算法的文件名后缀为 F L M FLM FLM,可以将这个生成的下载算法替代以前的下载算法,测试看看能否下载成功。最后图14是 F l a s h p r o g r a m m i n g a l g o r i t h m Flash\quad programming\quad algorithm Flashprogrammingalgorithm的擦除流程,图15是 F l a s h p r o g r a m m i n g a l g o r i t h m Flash\quad programming\quad algorithm Flashprogrammingalgorithm的程序烧录流程,图16是 F l a s h p r o g r a m m i n g a l g o r i t h m Flash\quad programming\quad algorithm Flashprogrammingalgorithm的验证流程。我的测试工程在这里。

 
图14.
 
图15.
 
图16.
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qqssss121dfd

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值