查看keil帮助手册
安装keil后,可以在帮助中查看手册,也可以在浏览器中输入:
https://arm-software.github.io/CMSIS_5/Pack/html/flashAlgorithm.html
如果网页打开失败,可以试试在C:\Windows\System32\drivers\etc\hosts中添加185.199.109.153 arm-software.github.io然后保存退出,最后在cmd命令窗口执行ipconfig /flushdns,然后再打开
打开界面如下:
我们根据这个帮助来进行下载算法的工程创建,并且安装帮助文档的提示,我们需要实现 Init,UnInit,EraseSector和ProgramPage,EraseChip这几个函数,在实际操作过程中发现,还必须实现BlankCheck和Verify这两个函数,否则下载程序时,会提示超时而下载失败
Keil工程搭建
工程修改这里就不说了,玩过STM32的人,没几个不熟悉keil这个软件,按照帮助文档复制一个过来就好了,魔术棒下的设置都是设置好了的,不用修改。
FlashDev中调整设备参数
我开发板用的是一颗W25Q64
设置的参数如下:
参数后面的英文注释很好理解,但是要说一说 Device Name这个参数,这个名字跟最后显示keil里面的算法名字有关,而跟keil工程输出文件名称无关
FlashPrg中的编程算法
/**************************************************************************//**
* @file FlashPrg.c
* @brief Flash Programming Functions adapted for New Device Flash
* @version V1.0.0
* @date 10. January 2018
******************************************************************************/
/*
* Copyright (c) 2010-2018 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "FlashOS.h" // FlashOS Structures
#include "sys.h"
#include "delay.h"
#include "led.h"
#include "usart.h"
#include "norflash.h"
/*
Mandatory Flash Programming Functions (Called by FlashOS):
int Init (unsigned long adr, // Initialize Flash
unsigned long clk,
unsigned long fnc);
int UnInit (unsigned long fnc); // De-initialize Flash
int EraseSector (unsigned long adr); // Erase Sector Function
int ProgramPage (unsigned long adr, // Program Page Function
unsigned long sz,
unsigned char *buf);
Optional Flash Programming Functions (Called by FlashOS):
int BlankCheck (unsigned long adr, // Blank Check
unsigned long sz,
unsigned char pat);
int EraseChip (void); // Erase complete Device
unsigned long Verify (unsigned long adr, // Verify Function
unsigned long sz,
unsigned char *buf);
- BlanckCheck is necessary if Flash space is not mapped into CPU memory space
- Verify is necessary if Flash space is not mapped into CPU memory space
- if EraseChip is not provided than EraseSector for all sectors is called
*/
/*
* 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
*/
u32 BASEaddr = 0x00; //全局基地址,MDK中可以手动设置起始地址
int Init (unsigned long adr, unsigned long clk, unsigned long fnc) {
/* Add your Code */
Stm32_Clock_Init(160,5,2,4); //设置时钟,400Mhz
LED_Init(); //初始化与LED连接的硬件接口
NORFLASH_Init(); //W25QXX初始化
BASEaddr= adr; //获取地址偏移
return (0); // Finished without Errors
}
/*
* 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) {
/* Add your Code */
return (0); // Finished without Errors
}
/*
* Erase complete Flash Memory
* Return Value: 0 - OK, 1 - Failed
*/
int EraseChip (void) {
/* Add your Code */
NORFLASH_Erase_Chip();
return (0); // Finished without Errors
}
/*
* Erase Sector in Flash Memory
* Parameter: adr: Sector Address
* Return Value: 0 - OK, 1 - Failed
*/
int EraseSector (unsigned long adr) {
/* Add your Code */
NORFLASH_Erase_Sector((adr-BASEaddr)/4096);
return (0); // Finished without Errors
}
/*
* 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) {
u8 check_buf =0;
/* Add your Code */
LED0(adr/4096); //页编程的大小
LED1(adr/4096);
NORFLASH_Write(buf,adr-BASEaddr,sz);
return (0); // Finished without Errors
}
/*外部Flash必须实现以下两个函数,否则MDK会因无操作超时*/
int BlankCheck (unsigned long adr,unsigned long sz,unsigned char pat)
{
return (0);
}
//下载后校验下载的数据是否与编译成的文件一致
unsigned long Verify(unsigned long adr,unsigned long sz,unsigned char *buf){
u8 check_buf[4096];
int i;
NORFLASH_Read(check_buf,adr-BASEaddr,sz);
for(i=0;i<sz;i++)
{
if(buf[i] != check_buf[i])
{
break;
}
}
return (adr + i);
}
下载后校验
QSPI和W25Q64的程序,直接借鉴了正点原子的代码
RAM for Algorithm 参数
在算法制作完成后,如果直接进行下载可是,几乎都会遇到如下提示:
很大原因是 RAM for Algorithm 这个参数设置错误导致 这个参数keil一般默认是0x1000
这参数在帮助文档里面说是编程算法所占用的RAM大小
但是没有找到说如何去设置才算合适,我测试后发现一般将其设置为代码容量的2倍以上合适,要给算法程序运行留下足够的空间,但是不要超过区域所在的大小,这属于个人意见,有其他方法欢迎讨论。
最后可以用一个简单的工程进行下载验证