当前位置:   article > 正文

STM32F103ZET6 J-flash外部SPI Flash烧录算法制作(keil)_stm32外部spi烧写算法

stm32外部spi烧写算法

STM32F103ZET6 J-flash外部SPI Flash烧录算法制作(keil

1 说明

需要的软件
Keil
STM32cubeMX
J-Flash

参考博客:
基于Keil生成外部Nor Flash下载算法,并使用J-Flash直接烧录(以W25Q64为例)
手把手系列–编写Keil MDK 外部FLASH下载算法
教你如何找到导致程序跑飞的指令
制作jflash下载算法,并解决堆栈溢出导致的写数据错误问题

参考文档:
在这里插入图片描述
这个是keil官方给的参考文档,但由于我在keil官方只下载到STM32F103ZE系列的标准库设备支持包,所以无法按照教程来配置,没有从keil打开STM32CubeMX的选项,这个走了会弯路

2 步骤

我前面贴了很多链接,都可以参考,但我这里主要划分3步核心

  • 1.使用STM32cubeMX生成MDK工程(keil),保证这个工程能够正常进行外部spi Flash的读写
  • 2.参考文档,或者keil安装目录下的模板去设置工程参数
  • 3.J-flash测试,调整报错

2.1 STM32cubeMX生成简单工程(spi Flash)

2.1.1 PinOut
  • (1)时钟
    时钟
    在这里插入图片描述
  • (2)SYS
    在这里插入图片描述
    (3)SPI
    在这里插入图片描述

(4)GPIO
在这里插入图片描述

2.1.2 生成配置
  • 1勾选Do not generate the main()
    这个可以先不勾选,生成main函数了就先测试下Flash能不能正常读写,然后再勾选重新生成项目
    在这里插入图片描述
  • code生成选项
添加必要的文件;
生成外设相关的.c和.h文件(这个没影响,只是勾了就不会所有函数都挤在main.c里);
保持用户代码(这个勾一下,重新生成时user注释区域的代码会保持的);
删除之前的文件
  • 1
  • 2
  • 3
  • 4

在这里插入图片描述
在这里插入图片描述

2.2 MDK工程配置

  • 1 取消一些不参加编译的文件
系统启动文件
  • 1

在这里插入图片描述
在这里插入图片描述

  • 2 添加Flash相关的文件,包括添加include路径
    这个不细说了,直接添加就行
    在这里插入图片描述

在这里插入图片描述

2.3 Options配置

这个直接参考文档,不细说 了,重要的提示一下

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
cmd.exe /C copy "STM32F103ZET6_SPIFLASH\%L" ".\@L.FLM"
这只是个复制的命令,生成FLM文件
Q:\NewStart\sample\STM32F10x_W25Q128\MDK-ARM\after_bulid.bat @L
这是个bat批处理文件,@L是传入的链接路径;这个可以不管,只是把FLM文件复制到对应的地方,懒得手动复制来复制去了

@echo off
set linker_output_file_name=%1	
REM 将文件复制到第一个目录
cmd.exe /C copy ".\%linker_output_file_name%.FLM" "D:\ProSoft2\MDK5\ARM\Flash\%linker_output_file_name%.FLM"
REM 将文件复制到第二个目录
cmd.exe /C copy ".\%linker_output_file_name%.FLM" "C:\Users\qianmen\AppData\Roaming\SEGGER\JLinkDevices\STM32F10x_W25QXX\STM32F10x_W25Q128\%linker_output_file_name%.FLM"
REM 添加更多的复制命令...
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3 Flash文件修改

FlashDev.c

struct FlashDevice const FlashDevice  =  
{
   FLASH_DRV_VERS,             // Driver Version, do not modify!
   "STM32F10x_W25Q128 Flash",   // Device Name 
   EXTSPI,                     // Device Type
   0x00000000,                 // Device Start Address
   0x01000000,                 // Device Size in Bytes (256kB)
   0x1000,                       // Programming Page Size
   0,                          // Reserved, must be 0
   0xFF,                       // Initial Content of Erased Memory
   10000,                        // Program Page Timeout 100 mSec
   30000,                       // Erase Sector Timeout 3000 mSec

   // Specify Size and Address of Sectors
   0x1000, 0x000000,         // Sector Size  8kB (8 Sectors)
   //   0x010000, 0x010000,         // Sector Size 64kB (2 Sectors) 
   //   0x002000, 0x030000,         // Sector Size  8kB (8 Sectors)
   SECTOR_END
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

FlashPrg.c
配置相关函数,init函数中进行一些初始化,uninit我没写,其他看着配置自己的flash擦除、写入、校验函数即可

#include "FlashOS.H"        // FlashOS Structures
#include "main.h"
#include "spi.h"
#include "gpio.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
 */
#include "flash_W25Qx.h"
#include "nst_flash.h"
#include "nst_log.h"
#include "stdint.h"
#include "stdio.h"
#include "main.h"


extern void SystemClock_Config(void);
int Init (unsigned long adr, unsigned long clk, unsigned long fnc) 
{
	int ret = 0;
	volatile int i;
	volatile unsigned char * ptr = (volatile unsigned char * )&hspi2;

	for (i = 0; i < sizeof(hspi2); i++) 
	{
		*ptr++ = 0U;
	}

	HAL_Init();
	SystemClock_Config();
	MX_GPIO_Init();
	MX_SPI2_Init();
//	MX_USART1_UART_Init();
	  
	ret=nst_flash_init();
	  
  /* Add your Code */
	return (ret);                                  // 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) {

//	printf("EraseChip  %d",__LINE__);
	nst_flash_erase_chip();
  /* Add your Code */
  	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) {

//	printf("EraseSector  %d",__LINE__);
	nst_flash_erase_block((uint32_t)adr);
  /* Add your Code */
  	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) {
	
//	printf("ProgramPage  %d",__LINE__);
//	nst_flash_write(buf,(uint32_t)adr,(uint32_t)sz);
	BSP_W25Qx_Write(buf,adr,sz);
  /* Add your Code */
  	return (0);                                  // Finished without Errors
}

#define bufsize 4096

uint8_t aux_buf[bufsize];

unsigned long Verify (unsigned long adr, unsigned long sz, unsigned char *buf) 
{
	volatile int i=0, j=0;

	for(i = 0; i < sz/bufsize; i++)
	{
		nst_flash_read(aux_buf,adr+bufsize*i,bufsize);
		
		for (j = 0; j< bufsize; j++) 
		{
			if (aux_buf[j] != buf[j+bufsize*i]) 
			return (adr + j + bufsize*i);                  
		}	
	}
	
	if(sz%bufsize)
	{
		nst_flash_read(aux_buf,adr+bufsize*i,sz%bufsize);
		
		for (j = 0; j< sz%bufsize; j++) 
		{
			if (aux_buf[j] != buf[j+bufsize*i]) 
			return (adr + j + bufsize*i);                   
		}			
	}

    return (adr+sz);                     
}

int BlankCheck (unsigned long adr, unsigned long sz, unsigned char pat) 
{
	volatile int i=0, j=0;

	for(i = 0; i < sz/bufsize; i++)
	{
		nst_flash_read(aux_buf, adr+bufsize*i, bufsize);
		
		for (j = 0; j< bufsize; j++) 
		{
			if (aux_buf[j] != pat) 
			return 1;                
		}	
	}
	
	if(sz%bufsize)
	{
		nst_flash_read(aux_buf, adr+bufsize*i, sz%bufsize);
		
		for (j = 0; j< sz%bufsize; j++) 
		{
			if (aux_buf[j] != pat) 
			return 1;                
		}			
	}

    return 0;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192

4 J-flash测试

1 在 C:\Users\用户\AppData\Roaming\SEGGER 这个目录下创建JlinkDevices文件夹
在这里插入图片描述
2 接着创建
在这里插入图片描述
3 打开,接着创建
在这里插入图片描述
4 将FLM文件复制到这个目录下
在这里插入图片描述
5 回到上一个目录,创建并编辑xml文件
在这里插入图片描述

<Database>
  <Device>
    <ChipInfo Vendor="STM32F10x_W25QXX" Name="STM32F10x_W25Q128" WorkRAMAddr="0x20000000" WorkRAMSize="0x29000" Core="JLINK_CORE_CORTEX_M3" />
    <!-- 512 KB internal code flash bank with 1 loader -->
    <FlashBankInfo Name="SPI Flash" BaseAddr="0x00000000" AlwaysPresent="1" >
      <LoaderInfo Name="Default" MaxSize="0x01000000" Loader="C:/Users/qianmen/AppData/Roaming/SEGGER/JLinkDevices/STM32F10x_W25QXX/STM32F10x_W25Q128/STM32F10x_W25Q128.FLM" LoaderType="FLASH_ALGO_TYPE_OPEN" />
    </FlashBankInfo>
  </Device>
</Database>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

5 J-Flash测试遇到的一些错误

  • 1 J-Flash搜不到设备
    检差路径的配置,xml文件是否写对了

-2 需要配置链接文件
在这里插入图片描述
在这里插入图片描述

SP=0x200064C8,STM32F103的RAM起始地址是0x20000000,64C8对应的就是map的aux_buf数组区域
bss段的起始地址和DSCR一样,我解决的办法是推移

在这里插入图片描述

target.lin 文件的DSCR地址加0x2000
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/人工智能uu/article/detail/946672
推荐阅读
相关标签
  

闽ICP备14008679号