Keil download algorithm for making SPI Flash (W25Q16) in the form of STM32 HAL library

Common SPI Flash: W25Qxx series, this article uses W25Q16 as an example to create a Keil download algorithm.

As shown in the figure below, the thing in the red box is the download algorithm.

As long as the download algorithm is imported, the W25Q16 page can be programmed while programming the MCU. This operation is convenient for LCD application scenarios, where fonts and pictures are stored in external Flash.

Actual operation:

1. Hardware: STM32G030C8T6, W25Q16 (2MB FLASH)

2. The hardware connection diagram corresponding to the algorithm:

3. Project construction:

①Enter the \ARM\Pack\ARM\CMSIS\version\Device path in the keil installation directory (vesion is the version number of the actually installed keil pack), copy the _Template_Flash folder, and use it as the project template.

②Open the project with keil, click "Magic Wand", under the Target page, select V5.xx for the compiler version.

On the Device page, select the corresponding MCU model.

Ouput page, set the name of the generated file.

User page, set as follows:

cmd.exe /C copy "Flash_Algx\%L" ".\@L.FLM"

cmd.exe /C copy ".\@L.FLM" "C:\Keil_v5\ARM\Flash\@L.FLM"

(C:\Keil_v5 is the installation path of Keil, and ARM\Flash is the storage address of the download algorithm under the path)

C/C++ page, set as follows.

ASM page, set as follows.

Linker page, set as follows.

Click "Edit" in the red box in the middle,

The content of the opened file is (if it does not match the code below, modify it manually):

; Linker Control File (scatter-loading)

;

PRG 0 PI ; Programming Functions

{

PrgCode +0 ; Code

{

* (+RO)

}

PrgData +0 ; Data

{

* (+RW,+ZI)

}

}

DSCR +0 ; Device Description

{

DevDscr +0

{

FlashDev.o

}

}

③ After the above settings are completed, start generating the project.

Click the button in the red box below.

Once opened, click the corresponding boxes from top to bottom.

After clicking the button behind "STM32Cube HAL",

Jump out of the STM32Cube page and start configuring the MCU

After configuring the IO port and clock frequency (note that the clock frequency will affect the SPI communication rate), after the configuration is complete, click on the project settings, and only need to set the following options,

After the settings are complete, click Generate Code directly.

After the code is generated, the following two code sets will appear after opening the project with keil,

At this time, you need to left-click "Device", as shown in the figure below, click the setting in the red box,

After entering the settings, as shown in the figure below, click the information in the red box from top to bottom,

After clicking OK, you will find that the system_stm32g0xx.c generated by STM32Cube cannot be used.

At this time, you need to copy a copy of system_stm32g0xx.c from other projects and put it in this project, and add it to the project file at the same time. At this time, add W25Qxx.c (FLASH driver code) and system_stm32g0xx.c together, as follows picture.

④ Start to modify the code

Click on main.c

First redefine the following code in main.c.

Then change "int main(void)" to "int Init_main(void)", and modify the function in the original "int main(void)", as shown in the figure below

Then start to modify FlashDev.c, as shown in the following figure,

Make the following changes,

Note that the timeout period should be reasonable, and the full chip erase may be around 10-20s.

Then start to modify FlashPrg.c, the code is as follows,

Since the address is defined as 0x90000000 in FlashDev.c, first set a base address macro:

#define SPI_FLASH_MEM_ADDR 0x90000000

Initialization function:

extern int Init_main(void);

int Init (unsigned long adr, unsigned long clk, unsigned long fnc) {

/* Add your Code */

Init_main();

if(BSP_W25qxx_ReadID() != W25Q16)

{

//return (1);

}

return (0); // Finished without Errors

}

Note: The functions in FlashPrg.c all have return values, while returning 0 means normal, and returning 1 means abnormal.

The clear initialization function does not modify:

int UnInit (unsigned long fnc) {

/* Add your Code */

return (0); // Finished without Errors

}

Full chip erase function:

int EraseChip (void) {

/* Add your Code */

for(uint16_t i = 0; i < 512; i++)

{

BSP_W25qxx_Erase_Sector(i * 0x1000);

}

return (0); // Finished without Errors

}

Sector erase function:

int EraseSector (unsigned long adr) {

/* Add your Code */

adr -= SPI_FLASH_MEM_ADDR;

BSP_W25qxx_Erase_Sector(adr);

return (0); // Finished without Errors

}

Write function:

int ProgramPage (unsigned long adr, unsigned long sz, unsigned char *buf) {

/* Add your Code */

adr -= SPI_FLASH_MEM_ADDR;

B_W25qxx_Write(buf,adr,sz);

return (0); // Finished without Errors

}

Add validation function:

unsigned long Verify(unsigned long adr, unsigned long sz, unsigned char *buf)

{

adr -= SPI_FLASH_MEM_ADDR;

adr += SPI_FLASH_MEM_ADDR;

return (adr + sz); /* verification successful */

}

Note: The current verification function does not perform any operations, just for the purpose of downloading normally if you select "Verify" during downloading.

Add block erasure check function:

int BlankCheck(unsigned long adr, unsigned long sz, unsigned char pat)

{

// adr -= SPI_FLASH_MEM_ADDR;

/* force erase */

return 1;

}

Note: The current block erase check function still does not do anything.

⑤Complete the above operations to complete the modification, click compile to generate the FLM file.

4. FLM download algorithm verification

Open a test code project.

① To modify the test project settings, choose one of the following methods.

Method 1: Open the "Magic Wand", under the Linker page, make the following modifications,

Then click "Edit" to modify the .sct file, and add the following code at the end:

LR_EROM1 0x90000000 0x00200000 { ; load region size_region

ER_EROM1 0x90000000 0x00200000 { ; load address = execution address

*(USE_EXT_FLASH_2MB_BUF_SPACE)

}

}

Method 2: On the Traget page, add the virtual address and size corresponding to the external FLASH, as shown in the figure below,

After setting either of the above two methods, enter the download setting interface, add our FLM algorithm, and then temporarily increase the RAM space, otherwise the algorithm will not be downloaded (the algorithm is downloaded to the MCU to run), as shown in the figure below,

② Add code to the test project

Realize storing the value of the static global variable in the external FLASH.

In order to adapt to the compiler, otherwise the parameters will be optimized by the compiler, define the macro:

#ifdef __CC_ARM /* ARM Compiler */

#define SECTION(x) __attribute__((section(x)))

#define USED __attribute__((used))

#define UNUSEDX __attribute__((unused))

#elif defined (__IAR_SYSTEMS_ICC__) /* for IAR Compiler */

#define SECTION(x) @ x

#define USED __root

#elif defined (__GNUC__) /* GNU GCC Compiler */

#define SECTION(x) __attribute__((section(x)))

#define USED __attribute__((used))

#define UNUSED __attribute__((unused))

#else

#error not supported tool chain

#endif /* __CC_ARM */

Then define static global variables:

USED static const uint16_t Flash_Value SECTION("USE_EXT_FLASH_2MB_BUF_SPACE") = 0x1010;

5. Connect the actual board and click download.

Additional information:

1. You can try to shield some useless library codes, such as the HAL code of the internal flash, which can reduce the amount of code, because the algorithm is temporarily loaded into RAM to run.

2. If you encounter the following problems:

It shows that there is a problem with the FLM algorithm. You can try to shield the self-written driver code and test it. If it still fails after shielding, it may be that the clock setting or the initial system is wrong; if it is normal after shielding, it may be that the IO initialization is wrong.

Guess you like

Origin blog.csdn.net/weixin_39457767/article/details/131329413