Flash SPI commun : série W25Qxx, cet article utilise W25Q16 comme exemple pour créer un algorithme de téléchargement Keil.
Comme le montre la figure ci-dessous, l'élément dans la case rouge est l'algorithme de téléchargement.
Tant que l'algorithme de téléchargement est importé, la page W25Q16 peut être programmée lors de la programmation du MCU. Cette opération est pratique pour les scénarios d'application LCD, dans lesquels les polices et les images sont stockées dans un Flash externe.
Fonctionnement réel :
1. Matériel : STM32G030C8T6, W25Q16 (FLASH 2 Mo)
2. Le schéma de connexion matérielle correspondant à l'algorithme :
3. Construction du projet :
①Entrez le chemin \ARM\Pack\ARM\CMSIS\version\Device dans le répertoire d'installation de keil (vesion est le numéro de version du pack keil réellement installé), copiez le dossier _Template_Flash et utilisez-le comme modèle de projet.
②Ouvrez le projet avec keil, cliquez sur "Magic Wand", sous la page Target, sélectionnez V5.xx pour la version du compilateur.
Sur la page Appareil, sélectionnez le modèle de MCU correspondant.
Page de sortie, définissez le nom du fichier généré.
Page utilisateur, définie comme suit :
cmd.exe /C copie "Flash_Algx\%L" ".\@L.FLM"
cmd.exe /C copier ".\@L.FLM" "C:\Keil_v5\ARM\Flash\@L.FLM"
(C:\Keil_v5 est le chemin d'installation de Keil et ARM\Flash est l'adresse de stockage de l'algorithme de téléchargement sous le chemin)
Page C/C++, définie comme suit.
Page ASM, définie comme suit.
Page de liaison, définie comme suit.
Cliquez sur "Modifier" dans la case rouge au milieu,
Le contenu du fichier ouvert est (s'il ne correspond pas au code ci-dessous, modifiez-le manuellement) :
; Fichier de contrôle de l'éditeur de liens (chargement dispersé)
;
PRG 0 PI ; Fonctions de programmation
{
Code Prg +0 ; Code
{
* (+RO)
}
PrgDonnées +0 ; Données
{
* (+RW,+ZI)
}
}
DSCR +0 ; Description de l'appareil
{
DevDscr +0
{
FlashDev.o
}
}
③ Une fois les paramètres ci-dessus terminés, commencez à générer le projet.
Cliquez sur le bouton dans la case rouge ci-dessous.
Une fois ouvert, cliquez sur les cases correspondantes de haut en bas.
Après avoir cliqué sur le bouton derrière "STM32Cube HAL",
Sortez de la page STM32Cube et commencez à configurer le MCU
Après avoir configuré le port IO et la fréquence d'horloge (notez que la fréquence d'horloge affectera le taux de communication de SPI), une fois la configuration terminée, cliquez sur les paramètres du projet et il vous suffit de définir les options suivantes :
Une fois les paramètres terminés, cliquez directement sur Générer le code.
Une fois le code généré, les deux jeux de codes suivants apparaîtront après l'ouverture du projet avec keil,
À ce stade, vous devez cliquer avec le bouton gauche sur « Périphérique », comme indiqué dans la figure ci-dessous, cliquer sur le paramètre dans la case rouge,
Après avoir saisi les paramètres, comme indiqué dans la figure ci-dessous, cliquez sur les informations dans la case rouge de haut en bas,
Après avoir cliqué sur OK, vous constaterez que le system_stm32g0xx.c généré par STM32Cube ne peut pas être utilisé.
À ce stade, vous devez copier une copie de system_stm32g0xx.c à partir d'autres projets et la placer dans ce projet, et l'ajouter au fichier de projet en même temps. À ce stade, ajoutez W25Qxx.c (code du pilote FLASH) et system_stm32g0xx.c ensemble, comme l'image suivante.
④ Commencez à modifier le code
Cliquez sur main.c
Redéfinissez d’abord le code suivant dans main.c.
Remplacez ensuite "int main(void)" par "int Init_main(void)" et modifiez la fonction dans l'original "int main(void)", comme indiqué dans la figure ci-dessous.
Commencez ensuite à modifier FlashDev.c, comme le montre la figure suivante,
Apportez les modifications suivantes,
Notez que le délai d'attente doit être raisonnable et que l'effacement complet de la puce peut être d'environ 10 à 20 secondes.
Commencez ensuite à modifier FlashPrg.c, le code est le suivant,
Puisque l'adresse est définie comme 0x90000000 dans FlashDev.c, définissez d'abord une macro d'adresse de base :
#définir SPI_FLASH_MEM_ADDR 0x90000000
Fonction d'initialisation :
extern int Init_main(void);
int Init (adr long non signé, clk long non signé, fnc long non signé) {
/* Ajoutez votre code */
Init_main();
si(BSP_W25qxx_ReadID() != W25Q16)
{
//retour (1);
}
retourner (0); // Fini sans erreurs
}
Remarque : Les fonctions de FlashPrg.c ont toutes des valeurs de retour, tandis que renvoyer 0 signifie normal et renvoyer 1 signifie anormal.
La fonction d'initialisation clear ne modifie pas :
int UnInit (fnc long non signé) {
/* Ajoutez votre code */
retourner (0); // Fini sans erreurs
}
Fonction d'effacement complet des puces :
int EraseChip (vide) {
/* Ajoutez votre code */
pour(uint16_t je = 0; je < 512; je++)
{
BSP_W25qxx_Erase_Sector(je * 0x1000);
}
retourner (0); // Fini sans erreurs
}
Fonction d'effacement de secteur :
int EraseSector (adr longue non signée) {
/* Ajoutez votre code */
adr-= SPI_FLASH_MEM_ADDR ;
BSP_W25qxx_Erase_Sector(adr);
retourner (0); // Fini sans erreurs
}
Fonction d'écriture :
int ProgramPage (adr long non signé, sz long non signé, char non signé *buf) {
/* Ajoutez votre code */
adr-= SPI_FLASH_MEM_ADDR ;
B_W25qxx_Write(buf,adr,sz);
retourner (0); // Fini sans erreurs
}
Ajouter une fonction de validation :
non signé long Vérifier (adr long non signé, sz long non signé, char non signé *buf)
{
adr-= SPI_FLASH_MEM_ADDR ;
adr += SPI_FLASH_MEM_ADDR ;
return (adr + sz); /* vérification réussie */
}
Remarque : La fonction de vérification actuelle n'effectue aucune opération, uniquement dans le but de télécharger normalement si vous sélectionnez « Vérifier » pendant le téléchargement.
Ajouter une fonction de vérification de l'effacement des blocs :
int BlankCheck (adr long non signé, taille longue non signée, pat de caractère non signé)
{
// adr -= SPI_FLASH_MEM_ADDR;
/* forcer l'effacement */
renvoyer 1 ;
}
Remarque : La fonction de vérification d'effacement de bloc actuelle ne fait toujours rien.
⑤ Terminez les opérations ci-dessus pour terminer la modification, cliquez sur compiler pour générer le fichier FLM.
4. Vérification de l'algorithme de téléchargement FLM
Ouvrez un projet de code de test.
① Pour modifier les paramètres du projet de test, choisissez l'une des méthodes suivantes.
Méthode 1 : Ouvrez la "Magic Wand", sous la page Linker, apportez les modifications suivantes,
Cliquez ensuite sur « Modifier » pour modifier le fichier .sct, et ajoutez le code suivant à la fin :
LR_EROM1 0x90000000 0x00200000 { ; charger la région size_region
ER_EROM1 0x90000000 0x00200000 { ; adresse de chargement = adresse d'exécution
*(USE_EXT_FLASH_2MB_BUF_SPACE)
}
}
Méthode 2 : Sur la page Traget, ajoutez l'adresse virtuelle et la taille correspondant au FLASH externe, comme indiqué dans la figure ci-dessous,
Après avoir défini l'une des deux méthodes ci-dessus, entrez dans l'interface de configuration de téléchargement, ajoutez notre algorithme FLM, puis augmentez temporairement l'espace RAM, sinon l'algorithme ne sera pas téléchargé (l'algorithme est téléchargé sur le MCU pour être exécuté), comme indiqué dans la figure ci-dessous,
② Ajouter du code au projet de test
Réalisez le stockage de la valeur de la variable globale statique dans le FLASH externe.
Afin de s'adapter au compilateur, sinon les paramètres seront optimisés par le compilateur, définissez la macro :
#ifdef __CC_ARM /* Compilateur ARM */
#define SECTION(x) __attribute__((section(x)))
#define USED __attribute__((utilisé))
#define UNUSEDX __attribute__((inutilisé))
#elif défini (__IAR_SYSTEMS_ICC__) /* pour le compilateur IAR */
#définir SECTION(x) @ x
#define UTILISÉ __root
#elif défini (__GNUC__) /* Compilateur GNU GCC */
#define SECTION(x) __attribute__((section(x)))
#define USED __attribute__((utilisé))
#define INUTILISÉ __attribute__((inutilisé))
#autre
#erreur chaîne d'outils non prise en charge
#endif /* __CC_ARM */
Définissez ensuite des variables globales statiques :
UTILISÉ const uint16_t Flash_Value SECTION("USE_EXT_FLASH_2MB_BUF_SPACE") = 0x1010 ;
5. Connectez la carte réelle et cliquez sur Télécharger.
Informations Complémentaires:
1. Vous pouvez essayer de protéger certains codes de bibliothèque inutiles, tels que le code HAL du flash interne, ce qui peut réduire la quantité de code, car l'algorithme est temporairement chargé dans la RAM pour s'exécuter.
2. Si vous rencontrez les problèmes suivants :
Cela montre qu'il y a un problème avec l'algorithme FLM. Vous pouvez essayer de protéger le code du pilote auto-écrit et de le tester. S'il échoue toujours après le blindage, il se peut que le réglage de l'horloge ou le système initial soit erroné ; s'il est normal après blindage, il se peut que l'initialisation IO soit erronée.