Revue du stockage des variables et apprentissage et pratique de l'éditeur Clion
- 1. Exigences expérimentales
- Deuxième examen du stockage variable
- 3. Présentation, installation et configuration de Clion
- 4. Expérimentez
- V. Résumé
- 6. Références
1. Exigences expérimentales
1. Écrivez un programme C, revisitez les concepts de variables globales, variables locales, tas, piles, etc., et programmez et vérifiez dans le système Ubuntu (x86) et STM32 (Keil) respectivement (informations STM32 printf via le port série vers le assistant de port série de l'ordinateur hôte) . Résumez les adresses d'allocation de variables telles que les variables de tas, de pile, globales et locales dans les programmes C sous Ubuntu et stm32, et effectuez une analyse comparative.
2. Installez Clion2021 et utilisez un nouveau kit de développement logiciel intégré (remplaçant Keil) pour compléter le programme d'éclairage LED stm32F103.
Deuxième examen du stockage variable
1. Allocation de mémoire
(1) Brève description des attributs de mémoire
静态分配内存:在程序编译和链接时就确定好的内存
动态分配内存:在程序加载、调入、执行的时候分配/回收的内存
(2) Brève description de la partition de mémoire
Zone de pile (stack) : allouée et libérée automatiquement par le compilateur pour stocker les paramètres de la fonction et les variables locales (type auto). Il fonctionne comme une pile dans une structure de données.
Zone de tas (heap): Le programme alloue et libère dynamiquement de l'espace. Généralement, il est alloué et libéré par le programmeur, si le programmeur ne le libère pas, il peut être recyclé par l'OS à la fin du programme. (différente du tas dans la structure de données, la méthode d'allocation est similaire à une liste chaînée)
Zone globale/statique (statique) : le stockage des variables globales et des variables statiques est regroupé, et les variables globales initialisées et les variables statiques sont dans la zone même zone, les variables globales non initialisées et les variables statiques non initialisées se trouvent dans une autre zone adjacente. (Lorsque le programme se termine, la variable est libérée par le système)
Zone constante littérale : stocke les chaînes constantes (lorsque le programme se termine, les chaînes constantes sont libérées par le système)
Zone de code programme : stocke le code binaire du corps de la fonction
Remarque :
un programme normal est stocké en mémoire. Il est généralement divisé en trois parties : segment de programme, segment de données et pile.
Segment de programme : le code machine du programme, les données en lecture seule, généralement en lecture seule, et l'écriture dans celui-ci est illégale.
Segment de données : données statiques dans le programme.
Pile : un bloc contigu en mémoire. Les données dynamiques sont stockées dans la pile. Le registre de pointeur de pile (SP) pointe vers le haut de la pile. Le bas de la pile est une adresse fixe, caractérisée par le dernier entré, premier sorti, c'est-à-dire que les données introduites plus tard sont extraites en premier. Il prend en charge les opérations PUSH, POP. PUSH consiste à placer les données en haut de la pile et POP à retirer les données en haut de la pile.
(3) Comparaison des partitions
Remarque :
① Lorsque le nombre de couches d'appel de fonction augmente, le cadre de la pile de fonctions s'étend jusqu'à l'adresse basse de la mémoire bloc par bloc.
② Au fur et à mesure que le nombre de couches d'appel de fonction dans le processus diminue (c'est-à-dire le retour de chaque appel de fonction), le cadre de pile sera abandonné pièce par pièce et rétracté à l'adresse haute de la mémoire.
③ La taille du cadre de pile de chaque fonction varie avec la nature de la fonction et est déterminée par le nombre de variables locales de la fonction.
④ L'application dynamique du processus pour la mémoire se produit dans le tas (tas). À mesure que la quantité de mémoire allouée dynamiquement au processus par le système augmente, le tas (tas) peut s'étendre aux adresses hautes ou basses, qui dépendent des différents processeurs. , mais d'une manière générale, il croît vers l'adresse haute de la mémoire.
⑤ Lorsque la croissance de la zone de données non initialisées (BSS) ou Stack (zone de pile) épuise la mémoire libre allouée par le système au processus, le processus sera bloqué et reprogrammé par le système d'exploitation avec un module de mémoire plus grand.
(4) Emplacement de stockage des données STM32
Le contenu de la zone de code et de la zone constante est compilé et stocké dans la ROM ; la pile, le tas et la zone globale (segment .bss, segment .data) sont stockés dans la RAM.
2. Programmation pour vérification
(1) Authentification gratuite
[1] Le code est le suivant
#include <stdio.h>
#include <stdlib.h>
//定义全局变量
int init_global_a = 1;
int uninit_global_a;
static int inits_global_b = 2;
static int uninits_global_b;
void output(int a)
{
printf("hello");
printf("%d",a);
printf("\n");
}
int main( )
{
//定义局部变量
int a=2;
static int inits_local_c=2, uninits_local_c;
int init_local_d = 1;
output(a);
char *p;
char str[10] = "lyy";
//定义常量字符串
char *var1 = "123456";
char *var2 = "yushu";
//动态分配
int *p1=malloc(4);
int *p2=malloc(4);
//释放
free(p1);
free(p2);
printf("栈区-变量地址\n");
printf(" a:%p\n", &a);
printf(" init_local_d:%p\n", &init_local_d);
printf(" p:%p\n", &p);
printf(" str:%p\n", str);
printf("\n堆区-动态申请地址\n");
printf(" %p\n", p1);
printf(" %p\n", p2);
printf("\n全局区-全局变量和静态变量\n");
printf("\n.bss段\n");
printf("全局外部无初值 uninit_global_a:%p\n", &uninit_global_a);
printf("静态外部无初值 uninits_global_b:%p\n", &uninits_global_b);
printf("静态内部无初值 uninits_local_c:%p\n", &uninits_local_c);
printf("\n.data段\n");
printf("全局外部有初值 init_global_a:%p\n", &init_global_a);
printf("静态外部有初值 inits_global_b:%p\n", &inits_global_b);
printf("静态内部有初值 inits_local_c:%p\n", &inits_local_c);
printf("\n文字常量区\n");
printf("文字常量地址 :%p\n",var1);
printf("文字常量地址 :%p\n",var2);
printf("\n代码区\n");
printf("程序区地址 :%p\n",&main);
printf("函数地址 :%p\n",&output);
return 0;
}
【2】Création et visualisation du terminal
(2) Vérification STM32
[1] Génération de code
Étant donné que le processus de génération automatique de code a été effectué à plusieurs reprises, je ne le répéterai pas ici. Le package de compression de code généré est donné comme suit :
Lien : https://pan.baidu.com/s/1jJHzOzG4AjrXWWC4wJ8xBA
Code d'extraction : 1521
[2] Ecriture de code
Le fichier bsp_usart.h
ajoute le fichier d'en-tête :
#include <stdio.h>
#include <stdlib.h>
fichier main.c
#include "stm32f10x.h"
#include "bsp_usart.h" //添加 bsp_usart.h 头文件
int init_global_a = 1;
int uninit_global_a;
static int inits_global_b = 2;
static int uninits_global_b;
void output(int a)
{
printf("hello");
printf("%d",a);
printf("\n");
}
int main(void)
{
//定义局部变量
int a=2;
static int inits_local_c=2, uninits_local_c;
int init_local_d = 1;
char *p;
char str[10] = "lyy";
//定义常量字符串
char *var1 = "123456";
char *var2 = "yushu";
//动态分配
int *p1=malloc(4);
int *p2=malloc(4);
USART_Config();//串口初始化
output(a);
//释放
free(p1);
free(p2);
printf("栈区-变量地址\n");
printf(" a:%p\n", &a);
printf(" init_local_d:%p\n", &init_local_d);
printf(" p:%p\n", &p);
printf(" str:%p\n", str);
printf("\n堆区-动态申请地址\n");
printf(" %p\n", p1);
printf(" %p\n", p2);
printf("\n全局区-全局变量和静态变量\n");
printf("\n.bss段\n");
printf("全局外部无初值 uninit_global_a:%p\n", &uninit_global_a);
printf("静态外部无初值 uninits_global_b:%p\n", &uninits_global_b);
printf("静态内部无初值 uninits_local_c:%p\n", &uninits_local_c);
printf("\n.data段\n");
printf("全局外部有初值 init_global_a:%p\n", &init_global_a);
printf("静态外部有初值 inits_global_b:%p\n", &inits_global_b);
printf("静态内部有初值 inits_local_c:%p\n", &inits_local_c);
printf("\n文字常量区\n");
printf("文字常量地址 :%p\n",var1);
printf("文字常量地址 :%p\n",var2);
printf("\n代码区\n");
printf("程序区地址 :%p\n",&main);
printf("函数地址 :%p\n",&output);
return 0;
}
Le fichier bsp_usart.c
remplace la fonction fputc :
int fputc(int ch, FILE *f)
{
USART_SendData(DEBUG_USARTx, (uint8_t)ch);
while(USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_TXE) == RESET);
return (ch);
}
Après avoir compilé main.c
, vous pouvez voir la taille des sections Code, RO-data, RW-data et ZI-data.
Remarque
Code : stocker le code de programme
RO - data :
les instructions
stocker RAM=RW-data+ZI-data
【3】Sortie du programme
Utilisez le logiciel mcuisp pour commencer la programmation.Après
avoir ouvert le port série avec SSCOM, appuyez sur RESET sur la puce pour afficher le résultat de sortie :
lors de l'utilisation de l'assistant de débogage du port série XCOM, il sortira horizontalement, et il n'est pas recommandé de l'utiliser ici
(3) Analyse et comparaison
La valeur d'adresse d'Ubuntu dans la zone de pile et la zone de tas augmente de haut en bas, la valeur d'adresse de STM32 dans la zone de pile diminue de haut en bas et la valeur d'adresse dans la zone de tas augmente de haut en bas. Du point de vue de chaque zone, l'adresse de la zone de pile est à une adresse haute, et l'adresse de la zone de code est à une adresse basse.
3. Présentation, installation et configuration de Clion
1. Présentation de Clion
Clion est un IDE multiplateforme conçu pour développer C et C++. Il est conçu sur IntelliJ et comprend de nombreuses fonctionnalités intelligentes pour augmenter la productivité des développeurs. CLion aide les développeurs à utiliser des éditeurs intelligents pour améliorer la qualité du code, automatiser la refactorisation du code et intégrer profondément le système de compilation CMake pour améliorer la productivité des développeurs.
2. Installez CLion2021
(1) Télécharger
site officiel de clion :
CLion : un IDE multiplateforme pour C et C++ de JetBrains
peut être téléchargé via le disque réseau Baidu (ici, j'ai emprunté l'URL de quelqu'un d'autre)
disque réseau : https://pan.baidu.com/s/1-uhNBBdWsPfgxBqaDqigqA
Code d'extraction : qwer
(2) Tutoriel d'installation
Double-cliquez sur le fichier exe et cliquez sur Suivant
pour modifier l'emplacement d'installation.
Vous pouvez le vérifier, ajouter le dossier "bin" au PATH, et vous n'avez pas besoin d'ajouter des variables d'environnement
plus tard. Ensuite, passez à
la finition suivante
et ouvrez clion pour un essai à court terme.
Cliquez sur se connecter pour… créer un compte
ici J'utilise la boîte aux lettres QQ pour m'inscrire
et cliquez sur Soumettre. Une fois l'inscription réussie, déconnectez-vous et reconnectez-vous.
Cliquez sur Démarrer l'essai
3. Installez arm-none-eabi-gcc
(1) Télécharger
Adresse du site Web officiel : GNU Toolchain | Téléchargements de la chaîne d'outils intégrée GNU Arm - Développeur Arm
选择gcc-arm-none-eabi-10.3-2021.10-win32.exe
(2) Tutoriel d'installation
Sélectionnez Chinois simplifié
et suivez l'assistant d'installation pour continuer.
Le bloc-notes et cmd s'afficheront automatiquement
4. Installez openocd
(1) Télécharger et décompresser
Site officiel : Télécharger OpenOCD pour
le téléchargement de Windows est le dernier 11.18, il s'agit d'un package compressé, il suffit de le décompresser
5. Installez MinGW
(1) Télécharger et décompresser
Téléchargement du disque net : https://pan.baidu.com/s/1Q9lzsIWJJ4_MPThVYDnENg
Code d'extraction :
après avoir téléchargé qwer, décompressez simplement le fichier comme openocd
6. Ajouter à la variable d'environnement système
arm-none-eabi-gcc 路径下bin文件夹
Openocd路径下bin文件夹
mingw64路径下bin文件夹
Comment ajouter des variables d'environnement système :
Paramètres -> Système -> À propos de -> Paramètres système avancés -> Variables d'environnement
Vérifiez ensuite si l'installation est réussie
Entrez arm-none-eabi-gcc -v sur la ligne de commande, s'il y a une sortie, cela signifie succès.
7. Configuration de Clion
(1) Créer un projet
cliquez sur créer
(2) Configurer les chaînes d'outils
Sélectionnez File-Settings-Build-Toolchains, ajoutez MinGW, les informations de chemin seront automatiquement mises en correspondance à droite, et sélectionnez le débogueur arm-none-eabi-gdb.exe dans le dossier bin sous le chemin arm-none-eabi-gcc
(3) Configurer le développement intégré
Sélectionnez File-Settings-Build-Embedded Development, convertissez le répertoire de fichiers OpenOCD sur la droite à l'emplacement que vous avez téléchargé, puis cliquez sur Test et constatez que la couleur de l'invite est vert foncé, ce qui signifie que la configuration est réussie (en passant, CubeMX est également configuré)
OK
4. Expérimentez
1. Création de projet
Créer un nouveau projet avec CLion
Sélectionnez STM32CubeMX, remplissez le chemin pour enregistrer le projet et cliquez sur Créer
2. Générer le projet
Après avoir entré cubemx, le système par défaut est f030F4Px, et nous devons utiliser f103c8t6, cliquez sur retour pour sélectionner l'emplacement de la puce. Sélectionnez ensuite la puce
, configurez RCC , configurez
SYS
, configurez les broches
et définissez la broche PC13 sur GPIO_Output pour allumer la LED.
Configurez le port série USART1
pour nommer le fichier de projet et définissez
le nom du projet à remplir à nouveau (car le processus de changement de puce est en fait un nouveau fichier ioc créé par le Cube), il est recommandé de remplir le nom du projet précédent et répertoire de fichiers, afin que vous puissiez mettre celui précédemment indésirable. Le fichier ioc est écrasé.
Ensuite, dans Toolchain/IDE, sélectionnez SW4STM32
Enfin, cliquez sur le coin supérieur droit, sélectionnez Oui, générez le projet et cliquez sur les projets ouverts
3. Configurer le projet clion
De retour à CLion, vous pouvez voir l'interface suivante apparaître, sélectionnez le fichier stm32f103c8_biue_pill.cfg et utilisez
4. Changement de code et opération de gravure
Ajouter du code
Ouvrez le fichier main.c et ajoutez le code pour faire clignoter la LED de la broche PC13 dans la boucle while
while (1)
{
/* USER CODE END WHILE */
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
HAL_Delay(500);
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
HAL_Delay(500);
/* USER CODE BEGIN 3 */
}
compiler
graver
5. Résultats
V. Résumé
Cette expérience nécessite uniquement que vous compreniez le code. Vous n'avez pas besoin de l'écrire vous-même. Vous pouvez utiliser le code. L'installation et la configuration du logiciel clion peuvent être gênantes. Vous devez créer un compte. Les autres doivent faire attention à l'opération avec soin et minutie. Bref, référez-vous au code du patron et au blog pour compléter l'expérience.
6. Références
https://blog.csdn.net/qq_43279579/article/details/110308101
https://blog.csdn.net/liwei16611/article/details/88545248
https://my.oschina.net/mizhinian/blog/4472814
https https://blog.csdn.net/u011784994/article/details/53157614
https://blog.csdn.net/m0_58892312/article/details/121866325
https://blog.csdn.net/qq_60678931/article/details/121866156