IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Embarqué Discussion :

Carte SD Libraire FatFs [STM32]


Sujet :

Embarqué

  1. #1
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    mars 2018
    Messages
    171
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : mars 2018
    Messages : 171
    Points : 55
    Points
    55
    Par défaut Carte SD Libraire FatFs
    Salut, j'essaye d'ecrire et de lire dans un fichier sur une carte MicroSD (2Gb) a l'aide d'un adaptateur connecte en SPI a ma carte STM32l1.

    Je me sers des drivers suivant pour mon projet: http://elm-chan.org/fsw/ff/00index_e.html

    Mon initialisation se passe bien, j'utilise ensuite les fonction f_mount et f_getfree suivantes:

    Volume Management and System Configuration:
    f_mount - Register/Unregister the work area of the volume
    f_getfree - Get total size and free size on the volume
    Comme cela:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    switch(state)
    	{
    		case INIT:
    
    			if(BSP_SD_Init() == MSD_OK)///*disk_initialize(PD_SD) == 0*/)
    			{
    				debug_printf("SD Card : module initialized\n");
    				state = MOUNT;
    			}
    			else
    			{
    				debug_printf("Fail to initialize disk\n");
    				state = END_WITH_ERROR;
    			}
    			break;
    		case MOUNT:{
    
    			FATFS * fs;
    			Uint32 p2;
    			state = END_WITH_ERROR;	//On fait la supposition que cela ne va pas marcher.... si tout se passe bien, on ira faire la suite.
    			if(FATFS_LinkDriver(&SD_Driver, SD_path) != 0)
    			{
    				display("SD Card : NOT mounted\n");
    			}
    			else
    			{
    				res = f_mount(&SDFatFs, (TCHAR const*)SD_path, 0);
    				if(res == FR_OK)
    				{
    					res = f_getfree("", (DWORD*)&p2, &fs);
    					//res = f_mkfs((TCHAR const*)SDPath, 0, 0);
    
    					if (res == FR_OK)
    					{
    						/*debug_printf("FAT type = %u (%s)\nBytes/Cluster = %lu\nNumber of FATs = %u\n"
    									"Root DIR entries = %u\nSectors/FAT = %lu\nNumber of clusters = %lu\n"
    									"FAT start (lba) = %lu\nDIR start (lba,clustor) = %lu\nData start (lba) = %lu\n\n",
    									(WORD)fs->fs_type,
    									(fs->fs_type==FS_FAT12) ? "FAT12" : (fs->fs_type==FS_FAT16) ? "FAT16" : "FAT32",
    									(DWORD)fs->csize * 512, (WORD)fs->n_fats,
    									fs->n_rootdir, fs->fsize, (DWORD)fs->n_fatent - 2,
    									fs->fatbase, fs->dirbase, fs->database
    						);*/
    						display("SD Card : mounted\n");
    						state = WRITE_TEST_FILE;
    					}
    				}
    				if(res != FR_OK)
    					printf("error\n");
    					//verbose_fresult(res);
    
    			}
    			break;}
    Donc comme je l'ai dit plus haut, le CASE INIT se passe bien, cependant c'est lors de l'utilisation de "f_getfree" que j'ai un probleme.

    Cette fonction contient une ligne qui appelle la fonction "find_volume":
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    res = find_volume(&path, &fs, 0);
    Qui elle meme appelle la fonction "check_fs":

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    fmt = check_fs(fs, bsect);			/* Load sector 0 and check if it is an FAT-VBR as SFD */
    Et c'est dans cette derniere que tout se passe:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    static BYTE check_fs (	/* 0:FAT, 1:exFAT, 2:Valid BS but not FAT, 3:Not a BS, 4:Disk error */
    	FATFS* fs,			/* Filesystem object */
    	DWORD sect			/* Sector# (lba) to load and check if it is an FAT-VBR or not */
    )
    {
    	fs->wflag = 0; fs->winsect = 0xFFFFFFFF;		/* Invaidate window */
    	if (move_window(fs, sect) != FR_OK) return 4;	/* Load boot record */
    
    	if (ld_word(fs->win + BS_55AA) != 0xAA55)
    		return 3;	/* Check boot record signature (always here regardless of the sector size) */
    
    #if FF_FS_EXFAT
    	if (!mem_cmp(fs->win + BS_JmpBoot, "\xEB\x76\x90" "EXFAT   ", 11)) return 1;	/* Check if exFAT VBR */
    #endif
    	if (fs->win[BS_JmpBoot] == 0xE9 || fs->win[BS_JmpBoot] == 0xEB || fs->win[BS_JmpBoot] == 0xE8) {	/* Valid JumpBoot code? */
    		if (!mem_cmp(fs->win + BS_FilSysType, "FAT", 3)) return 0;		/* Is it an FAT VBR? */
    		if (!mem_cmp(fs->win + BS_FilSysType32, "FAT32", 5)) return 0;	/* Is it an FAT32 VBR? */
    	}
    	return 2;	/* Valid BS but not FAT */
    }
    Moi je suis bloque a la ligne en rouge, j'obtiens toujours ce "return 3".
    Si je lis les commentaires de la fonction, j'apprends que "3" correspond a:
    3:Not a BS

    Et c'est la que je suis bloque, je ne sais pas ce que veut dire "BS", est ce que c'est ma carte SD qui pose probleme?

    Merci

  2. #2
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    mars 2018
    Messages
    171
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : mars 2018
    Messages : 171
    Points : 55
    Points
    55
    Par défaut
    EDIT: Il m'est arrive une fois qu'apres avoir reformate la carte j'obitenne fmt=4:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if (fmt == 4)
    		return FR_DISK_ERR;		/* An error occured in the disk I/O layer */
    C'est pas vraiment mieux Mais dans la plupart des cas j'obtiens fmt=3

  3. #3
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    juin 2009
    Messages
    4 467
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : juin 2009
    Messages : 4 467
    Points : 13 616
    Points
    13 616
    Billets dans le blog
    1
    Par défaut
    Hello,

    Je n'ai pas fait joujou avec FatFS depuis un moment mais dans mon souvenir c'est très simple. J'avais encadré un stagiaire qui avait bossé là-dessus, du coup c'est lui qui avait bossé

    Si tu n'y a jamais touché, le mieux est de faire un système de fichier en RAM. (RAM FS). Tu réserves un peu de mémoire, tu écris les fonctions qui vont bien et tu essayes. Il y a visiblement un code pour vérifier que ces fonctions sont correctes : http://elm-chan.org/fsw/ff/res/app4.c Une fois que ça marche, tu peux tenter d'écrire les fonctions pour un autre type de support.

    Au début, je te conseille ne pas utiliser la couche ST si tu galères trop avec (au moins pour le RAM FS). Comprends bien comment marche FatFS, ça t'aidera pour ensuite rajouter les couches ST.

    Au passage, je pense que tu vas trop loin en regardant le code de FatFS. C'est un composant éprouvé, tu devrais te limiter aux fonctions "publiques" sauf si vraiment gros soucis.

  4. #4
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    juin 2009
    Messages
    4 467
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : juin 2009
    Messages : 4 467
    Points : 13 616
    Points
    13 616
    Billets dans le blog
    1
    Par défaut
    J'ai tenté de faire le RAM FS sous Linux. Je suis parti de la dernière version de FatFS et j'ai noté choppé le fichier diskio.c Je l'ai un peu modifié (j'ai fait du C++) :

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    /*-----------------------------------------------------------------------*/
    /* Low level disk I/O module skeleton for FatFs     (C)ChaN, 2016        */
    /*-----------------------------------------------------------------------*/
    /* If a working storage control module is available, it should be        */
    /* attached to the FatFs via a glue function rather than modifying it.   */
    /* This is an example of glue functions to attach various exsisting      */
    /* storage control modules to the FatFs module with a defined API.       */
    /*-----------------------------------------------------------------------*/
     
    #include "fatfs/diskio.h"		/* FatFs lower layer API */
    #include "ramfs/RamFs.hpp"
    using namespace ramfs;
     
    /* Definitions of physical drive number for each drive */
    #define DEV_RAM		0	/* Example: Map Ramdisk to physical drive 0 */
     
    extern "C"
    {
    /*-----------------------------------------------------------------------*/
    /* Get Drive Status                                                      */
    /*-----------------------------------------------------------------------*/
     
    DSTATUS disk_status(BYTE pdrv /* Physical drive nmuber to identify the drive */
    )
    {
        if (pdrv == DEV_RAM)
        {
            return RAM_disk_status();
        }
        else
        {
            return STA_NOINIT;
        }
    }
     
    /*-----------------------------------------------------------------------*/
    /* Inidialize a Drive                                                    */
    /*-----------------------------------------------------------------------*/
     
    DSTATUS disk_initialize(BYTE pdrv /* Physical drive nmuber to identify the drive */
    )
    {
        if (pdrv == DEV_RAM)
        {
            return RAM_disk_initialize();
        }
        else
        {
            return STA_NOINIT;
        }
    }
     
    /*-----------------------------------------------------------------------*/
    /* Read Sector(s)                                                        */
    /*-----------------------------------------------------------------------*/
     
    DRESULT disk_read(BYTE pdrv, /* Physical drive nmuber to identify the drive */
    BYTE *buff, /* Data buffer to store read data */
    DWORD sector, /* Start sector in LBA */
    UINT count /* Number of sectors to read */
    )
    {
        if (pdrv == DEV_RAM)
        {
            return RAM_disk_read(buff, sector, count);
        }
        else
        {
            return RES_PARERR;
        }
    }
     
    /*-----------------------------------------------------------------------*/
    /* Write Sector(s)                                                       */
    /*-----------------------------------------------------------------------*/
     
    DRESULT disk_write(BYTE pdrv, /* Physical drive nmuber to identify the drive */
    const BYTE *buff, /* Data to be written */
    DWORD sector, /* Start sector in LBA */
    UINT count /* Number of sectors to write */
    )
    {
        if (pdrv == DEV_RAM)
        {
            return RAM_disk_write(buff, sector, count);
        }
        else
        {
            return RES_PARERR;
        }
    }
     
    /*-----------------------------------------------------------------------*/
    /* Miscellaneous Functions                                               */
    /*-----------------------------------------------------------------------*/
     
    DRESULT disk_ioctl(BYTE pdrv, /* Physical drive nmuber (0..) */
    BYTE cmd, /* Control code */
    void *buff /* Buffer to send/receive control data */
    )
    {
        if (pdrv == DEV_RAM)
        {
            return RAM_disk_ioctl(cmd, buff);
        }
        else
        {
            return RES_PARERR;
        }
    }
     
    DWORD get_fattime(void)
    {
        return 0; // TODO implement
    }
     
    }

    En gros, j'ai viré les différents types de média pour ne garder que la RAM.

    J'ai ensuite implémenté les fonctions manquantes à savoir :
    DSTATUS RAM_disk_status();
    DSTATUS RAM_disk_initialize();
    DRESULT RAM_disk_read(BYTE* buff, DWORD sector, UINT count);
    DRESULT RAM_disk_write(const BYTE* buff, DWORD sector, UINT count);
    DRESULT RAM_disk_ioctl(BYTE cmd, void *buff);
    Le code ressemble à ça :
    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    #include "RamFs.hpp"
     
    #include <array>
    #include <algorithm>
    #include <iostream>
    #include <cstdint>
     
    #include "fatfs/ffconf.h"
     
    namespace ramfs
    {
    static constexpr std::size_t SECTOR_SIZE = FF_MIN_SS;
    static constexpr std::size_t SECTOR_COUNT = 500;
     
    static std::array<std::uint8_t, SECTOR_COUNT * SECTOR_SIZE> storage;
     
    DSTATUS RAM_disk_status()
    {
        return STA_NOINIT; // TODO
    }
     
    DSTATUS RAM_disk_initialize()
    {
        std::fill(storage.begin(), storage.end(), 0U);
        return 0; // TODO
    }
     
    DRESULT RAM_disk_read(BYTE* buff, DWORD sectorId, UINT sectorCount)
    {
        auto src_begin = storage.begin() + sectorId * SECTOR_SIZE;
        auto src_end = storage.begin() + (sectorId + sectorCount) * SECTOR_SIZE;
        std::copy(src_begin, src_end, buff);
        return RES_OK;
    }
     
    DRESULT RAM_disk_write(const BYTE* buff, DWORD sectorId, UINT sectorCount)
    {
        auto src_end = buff + sectorCount * SECTOR_SIZE;
        auto dest = storage.begin() + sectorId * SECTOR_SIZE;
        std::copy(buff, src_end, dest);
        return RES_OK;
    }
     
    DRESULT RAM_disk_ioctl(BYTE cmd, void *buff)
    {
        DRESULT result = RES_ERROR;
     
        switch (cmd)
        {
        case GET_SECTOR_COUNT:
            *reinterpret_cast<DWORD*>(buff) = SECTOR_COUNT;
            result = RES_OK;
            break;
     
        case GET_SECTOR_SIZE:
            *reinterpret_cast<WORD*>(buff) = SECTOR_SIZE;
            result = RES_OK;
            break;
     
        case GET_BLOCK_SIZE:
            *reinterpret_cast<WORD*>(buff) = SECTOR_SIZE;
            result = RES_OK;
            break;
     
        case CTRL_SYNC:
            // No sync to so it's OK
            result = RES_OK;
            break;
     
        default:
            std::cout << "ioctl cmd " << (int) cmd << '\n';
        }
     
        return result;
    }
     
    }

    Il faut quand même pas mal de RAM pour exécuter le test : 128 secteurs minimum (paramètre en dur dans le code) sachant qu'un secteur fait au minimum 512 bytes (valeurs possibles dans la ffconf.h).

  5. #5
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    mars 2018
    Messages
    171
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : mars 2018
    Messages : 171
    Points : 55
    Points
    55
    Par défaut
    Salut, merci d'avoir pris le temps de repondre. Je suis un peu perdu avec les histoires de "couches" et de RAM. Moi j'ai plutot l'impression que c'est ma carte SD qui n'est pas detectee, et dans le code que tu as ecris je ne vois pas a quel moment on communique avec la carte SD(a quel moment on voit les ports par exemple)?

    Je vais essayer d'implementer ton code en C dans mon programme mais j'avoue que je sais pas trop comment m'en servir car comme je l'ai dis les histoires de RAM j'ai pas trop compris

    edit:

    Au passage je me rends compte que j'ai des erreurs dans diskio.c:
    Nom : diskioerrors.jpg
Affichages : 1669
Taille : 168,4 Ko
    Nom : diskioerrors2.jpg
Affichages : 1573
Taille : 73,5 Ko

    diskio.c:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    #if _USE_WRITE == 1
    DRESULT disk_write (
    	BYTE pdrv,		/* Physical drive nmuber to identify the drive */
    	const BYTE *buff,	/* Data to be written */
    	DWORD sector,		/* Sector address in LBA */
    	UINT count        	/* Number of sectors to write */
    )
    diskio.h:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count);
    Y a t-il conflit?

  6. #6
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    juin 2009
    Messages
    4 467
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : juin 2009
    Messages : 4 467
    Points : 13 616
    Points
    13 616
    Billets dans le blog
    1
    Par défaut
    Voici un schéma bloc :
    Nom : Capture.PNG
Affichages : 1540
Taille : 8,7 Ko
    En vert ce que tu dois écrire toi (application : tu peux / dois utiliser app4.c pour vérifier avant de te lancer dans un vrai truc).
    En bleu ce que tu ne touches pas dans FatFS.
    En orange ce que tu dois écrire mais en respectant les noms et prototypes de fonctions donnés par FatFS.

    Les blocs du bas dépendent de ce que tu fais. Si tu n'as que de la RAM, comme mon exemple, alors tu as un seul bloc (ce sont les fonctions RAM_disk_***() que je t'ai montré). Si tu as que SD, tu n'as qu'un bloc. Et ainsi de suite.

    Dans le bloc orange, tu dois choisir en fonction du paramètre 'pdrv' quel bloc tu dois utiliser. Soit aved des if/else, soit avec un switch case, soit avec une table de pointeurs de fonctions, soit tu ne choisis rien si tu n'as qu'un seul lecteur et tu utilises ton bloc perso.

    Quelles sont ces erreurs ? Tu ne les donnes pas... Fais attention aux marqueurs mis par Eclipse CDT :warning: Des fois ce sont des faux positifs. Il faut regarder ce que te dis ton compilateur (en s'assurant d'avoir mis des -Wall -Wextra et autres joyeuses options).

  7. #7
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    mars 2018
    Messages
    171
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : mars 2018
    Messages : 171
    Points : 55
    Points
    55
    Par défaut
    Je vais essayer de voir si j'ai compris:

    Moi ma couche application est dans un fichier machine_SD.c sous forme d'une machine a etat:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    running_e machine_SD_write(bool_e ask_for_finish, char* mot,char* nom_fichier){
    	typedef enum
    	{
    		INIT = 0,
    		MOUNT,
    		WRITE_TEST_FILE,
    		READ_TEST_FILE,
    		DELETE_TEST_FILE,
    		END_WITH_ERROR,
    		IDLE
    	}state_e;
    
    	static state_e state = INIT;
    	FRESULT res = FR_OK;
    	static FIL file;
    	running_e ret;
    	ret = IN_PROGRESS;
    	static uint16_t size = 0;
    	static char write_buf[256] = {0};
    	if(mot != NULL)
    	{
    		size = sprintf(write_buf, mot);
    	}
    	static char current_file[20] = {0};
    	if(nom_fichier != NULL)
    		sprintf(current_file, nom_fichier);
    
    	switch(state)
    	{
    		case INIT:
    
    			if(BSP_SD_Init() == MSD_OK)///*disk_initialize(PD_SD) == 0*/)
    			{
    				debug_printf("SD Card : module initialized\n");
    				state = MOUNT;
    			}
    			else
    			{
    				debug_printf("Fail to initialize disk\n");
    				state = END_WITH_ERROR;
    			}
    			break;
    		case MOUNT:{
    
    			FATFS * fs;
    			Uint32 p2;
    			state = END_WITH_ERROR;	//On fait la supposition que cela ne va pas marcher.... si tout se passe bien, on ira faire la suite.
    			if(FATFS_LinkDriver(&SD_Driver, SD_path) != 0)
    			{
    				display("SD Card : NOT mounted\n");
    			}
    			else
    			{
    				res = f_mount(&SDFatFs, (TCHAR const*)SD_path, 0);
    				if(res == FR_OK)
    				{
    					res = f_getfree("", (DWORD*)&p2, &fs);
    					//res = f_mkfs((TCHAR const*)SDPath, 0, 0);
    
    					if (res == FR_OK)
    					{
    						/*debug_printf("FAT type = %u (%s)\nBytes/Cluster = %lu\nNumber of FATs = %u\n"
    									"Root DIR entries = %u\nSectors/FAT = %lu\nNumber of clusters = %lu\n"
    									"FAT start (lba) = %lu\nDIR start (lba,clustor) = %lu\nData start (lba) = %lu\n\n",
    									(WORD)fs->fs_type,
    									(fs->fs_type==FS_FAT12) ? "FAT12" : (fs->fs_type==FS_FAT16) ? "FAT16" : "FAT32",
    									(DWORD)fs->csize * 512, (WORD)fs->n_fats,
    									fs->n_rootdir, fs->fsize, (DWORD)fs->n_fatent - 2,
    									fs->fatbase, fs->dirbase, fs->database
    						);*/
    						display("SD Card : mounted\n");
    						state = WRITE_TEST_FILE;
    					}
    				}
    				if(res != FR_OK){
    					printf("error\n");
    					//verbose_fresult(res);
    					state = END_WITH_ERROR;
    				}
    
    
    			}
    			break;}
    		case WRITE_TEST_FILE:{
    			UINT nb_to_write = 0;
    			UINT nb_written;
    			if(size && current_file[0]!='\0')
    			{
    				res = f_open(&file, current_file, FA_WRITE | FA_OPEN_ALWAYS);
    				res = f_lseek(&file, f_size(&file));
    
    				if(res == FR_OK)
    				{
    					debug_printf("File %s opened\n",current_file);
    					display("Testfile opened\n");
    
    					nb_to_write += size;
    					res = f_write(&file,write_buf,size,&nb_written);
    					if(res == FR_OK && size == nb_written)
    						debug_printf("datas wrote in file\n");
    					else
    						debug_printf("Fail to write datas in file\n");
    					f_close(&file);
    				}
    				else
    				{
    					debug_printf("Fail to open file %s\n",current_file);
    				}
    				size = 0;
    			}
    
    			state = IDLE;
    			break;}
    		case READ_TEST_FILE:{
    			#define READ_BUFFER_SIZE	32
    			UINT nb_read = 0;
    			uint8_t datas_read[READ_BUFFER_SIZE];
    			res = f_open(&file, path, FA_READ);
    			if(res == FR_OK)
    			{
    				res = f_read(&file,datas_read,READ_BUFFER_SIZE,&nb_read);
    				datas_read[nb_read] = '\0';	//Pour utiliser strcmp...
    				if(strcmp((char*)datas_read,mot) == 0)
    					debug_printf("Correct data read : %d datas : %s\n",nb_read,datas_read);
    				else
    					debug_printf("Bad data read : %d datas : %s\n",nb_read,datas_read);
    				f_close(&file);
    			}
    			state = IDLE;
    			break;}
    		/*case DELETE_TEST_FILE:
    			res = f_unlink(path);
    			if(res == FR_OK)
    				debug_printf("Test File deleted : ok\n");
    			else
    				debug_printf("Error deleting test file\n");
    			state = IDLE;
    			break;*/
    
    		case END_WITH_ERROR:
    			debug_printf("SD Card : error\n");
    			display("SD Card : ERROR\n");
    			state = IDLE;
    			break;
    		case IDLE:
    			if(size)
    				state = WRITE_TEST_FILE;
    			if(ask_for_finish)
    			{
    				state = INIT;
    				ret = END_OK;
    			}
    			if(mot)
    			{
    
    			}
    			break;
    		default:
    			break;
    	}
    
    	if(res != FR_OK)
    		//verbose_fresult(res);
    		printf("error\n");
    	return ret;
    }

    La couche FatFs ce sont tous ces drivers auxquels je ne touche pas (sauf diskio?):

    Nom : fatfsdrivers.jpg
Affichages : 1541
Taille : 64,2 Ko

    Apres j'ai le fichier diskio.c dans lequel je dois choisir entre USB RAM ou SD mais je ne vois pas comment faire (je souhaite prendre seulement SD):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    /**
      * @brief  Gets Disk Status
      * @param  pdrv: Physical drive number (0..)
      * @retval DSTATUS: Operation status
      */
    DSTATUS disk_status (
    	BYTE pdrv		/* Physical drive nmuber to identify the drive */
    )
    {
      DSTATUS stat;
    
      stat = disk.drv[pdrv]->disk_status(disk.lun[pdrv]);
      return stat;
    }
    
    /**
      * @brief  Initializes a Drive
      * @param  pdrv: Physical drive number (0..)
      * @retval DSTATUS: Operation status
      */
    DSTATUS disk_initialize (
    	BYTE pdrv				/* Physical drive nmuber to identify the drive */
    )
    {
      DSTATUS stat = RES_OK;
    
      if(disk.is_initialized[pdrv] == 0)
      {
        disk.is_initialized[pdrv] = 1;
        stat = disk.drv[pdrv]->disk_initialize(disk.lun[pdrv]);
      }
      return stat;
    }
    
    /**
      * @brief  Reads Sector(s)
      * @param  pdrv: Physical drive number (0..)
      * @param  *buff: Data buffer to store read data
      * @param  sector: Sector address (LBA)
      * @param  count: Number of sectors to read (1..128)
      * @retval DRESULT: Operation result
      */
    DRESULT disk_read (
    	BYTE pdrv,		/* Physical drive nmuber to identify the drive */
    	BYTE *buff,		/* Data buffer to store read data */
    	DWORD sector,	        /* Sector address in LBA */
    	UINT count		/* Number of sectors to read */
    )
    {
      DRESULT res;
    
      res = disk.drv[pdrv]->disk_read(disk.lun[pdrv], buff, sector, count);
      return res;
    }
    
    /**
      * @brief  Writes Sector(s)
      * @param  pdrv: Physical drive number (0..)
      * @param  *buff: Data to be written
      * @param  sector: Sector address (LBA)
      * @param  count: Number of sectors to write (1..128)
      * @retval DRESULT: Operation result
      */
    #if _USE_WRITE == 1
    DRESULT disk_write (
    	BYTE pdrv,		/* Physical drive nmuber to identify the drive */
    	const BYTE *buff,	/* Data to be written */
    	DWORD sector,		/* Sector address in LBA */
    	UINT count        	/* Number of sectors to write */
    )
    {
      DRESULT res;
    
      res = disk.drv[pdrv]->disk_write(disk.lun[pdrv], buff, sector, count);
      return res;
    }
    #endif /* _USE_WRITE == 1 */
    
    /**
      * @brief  I/O control operation
      * @param  pdrv: Physical drive number (0..)
      * @param  cmd: Control code
      * @param  *buff: Buffer to send/receive control data
      * @retval DRESULT: Operation result
      */
    #if _USE_IOCTL == 1
    DRESULT disk_ioctl (
    	BYTE pdrv,		/* Physical drive nmuber (0..) */
    	BYTE cmd,		/* Control code */
    	void *buff		/* Buffer to send/receive control data */
    )
    {
      DRESULT res;
    
      res = disk.drv[pdrv]->disk_ioctl(disk.lun[pdrv], cmd, buff);
      return res;
    }
    #endif /* _USE_IOCTL == 1 */
    
    /**
      * @brief  Gets Time from RTC
      * @param  None
      * @retval Time in DWORD
      */
    __weak DWORD get_fattime (void)
    {
      return 0;
    }


    Pour ce qui est de app4.c j'obtiens ca:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    <NUL>test_diskio(0, 3, 0x200136F0, 0x00000800)<LF>
    **** Test cycle 1 of 3 start ****<LF>
     disk_initalize(0)
    Et ensuite je rentre dans une fonction bloquante de uart et plus rien ne se passe j'arrive pas a voir a quel moment je rentre dans cette fonction qui m'empeche de continuer.


    En ce qui concerne les erreurs dans diskio.c je pense les avoir solutionnees car elles n'apparaissent plus pour le moment.

  8. #8
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    mars 2018
    Messages
    171
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : mars 2018
    Messages : 171
    Points : 55
    Points
    55
    Par défaut
    Est ce que les erreurs que j'obtiens assez regulierement ne sont pas dues a une mauvaise initialisation du SPI ?

    Je poste ici quelques bouts de code, principalement genere par STM32CubeMX:

    Dans main.c:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    /* SPI2 init function */
    static void MX_SPI2_Init(void)
    {
    
      /* SPI2 parameter configuration*/
      hspi2.Instance = SPI2;
      hspi2.Init.Mode = SPI_MODE_MASTER;
      hspi2.Init.Direction = SPI_DIRECTION_2LINES;
      hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
      hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;
      hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
      hspi2.Init.NSS = SPI_NSS_HARD_OUTPUT;
      hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
      hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
      hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
      hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
      hspi2.Init.CRCPolynomial = 10;
      if (HAL_SPI_Init(&hspi2) != HAL_OK)
      {
        _Error_Handler(__FILE__, __LINE__);
      }
    
    }
    Dans stm32l1xx_hal_msp.c:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
    {
    
      GPIO_InitTypeDef GPIO_InitStruct;
      if(hspi->Instance==SPI2)
      {
      /* USER CODE BEGIN SPI2_MspInit 0 */
    
      /* USER CODE END SPI2_MspInit 0 */
        /* Peripheral clock enable */
        __HAL_RCC_SPI2_CLK_ENABLE();
      
        /**SPI2 GPIO Configuration    
        PB12     ------> SPI2_NSS
        PB13     ------> SPI2_SCK
        PB14     ------> SPI2_MISO
        PB15     ------> SPI2_MOSI 
        */
        GPIO_InitStruct.Pin = SPI_NSS_SD_Pin|SPI_CLK_SD_Pin|SPI_MISO_SD_Pin|SPI_MOSI_SD_Pin;
        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
        GPIO_InitStruct.Pull = GPIO_PULLUP;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
        GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;
        HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
    
      /* USER CODE BEGIN SPI2_MspInit 1 */
    
      /* USER CODE END SPI2_MspInit 1 */
      }
      else if(hspi->Instance==SPI3)
      {
      /* USER CODE BEGIN SPI3_MspInit 0 */
    
      /* USER CODE END SPI3_MspInit 0 */
        /* Peripheral clock enable */
        __HAL_RCC_SPI3_CLK_ENABLE();
      
        /**SPI3 GPIO Configuration    
        PC10     ------> SPI3_SCK
        PC11     ------> SPI3_MISO
        PB5     ------> SPI3_MOSI 
        */
        GPIO_InitStruct.Pin = SPI_CLK_Pressure_Pin|SPI_MISO_Pressure_Pin;
        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
        GPIO_InitStruct.Alternate = GPIO_AF6_SPI3;
        HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
    
        GPIO_InitStruct.Pin = SPI_MOSI_Pressure_Pin;
        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
        GPIO_InitStruct.Alternate = GPIO_AF6_SPI3;
        HAL_GPIO_Init(SPI_MOSI_Pressure_GPIO_Port, &GPIO_InitStruct);
    
      /* USER CODE BEGIN SPI3_MspInit 1 */
    
      /* USER CODE END SPI3_MspInit 1 */
      }
    
    }



    EDIT: Je pense que dans ce projet il y a des solutions pour les fonctions SDRAM dont tu me parlais mais elles sont developpees pour une stm32f4 et je possede une stm32l1, est ce que je peux tenter de les implementer quand meme ou c'est peine perdue ?
    https://stm32f4-discovery.net/2014/0...2f4xx-devices/

  9. #9
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    juin 2009
    Messages
    4 467
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : juin 2009
    Messages : 4 467
    Points : 13 616
    Points
    13 616
    Billets dans le blog
    1
    Par défaut
    Franchement, là, comme ça, c'est très dur de dire d'où vient le problème. Je pense que tu essayes de faire fonctionner trop de choses en même temps. Il faut prendre les choses une part et les faire fonctionner au fur et à mesure.

    * Comprendre FatFS et tenter le RAM FS. Le code que je t'ai montré a été fait sous Linux, sur un PC. Pas de problème de F4 ou L0 ou xxx. C'est un tableau de bytes et des fonctions pour lire et écrire dans ce tableau de bytes.
    J'ai réussi à le faire compiler avec arm-none-eabi-gcc (en faisant des typedef pour les types de FatFS et en mettant des valeurs bidons pour les constantes).

    * Faire fonctionner le SPI et ta carte SD. Tu dois pouvoir réussir à lire et à écrire dedans (sans parler de fichier : juste l'espace de stockage). Au final, c'est que fera FatFS pour y créer un système de fichiers.

    * Utiliser FatFS avec ta carte SD est une suite logique à tout ça.

  10. #10
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    mars 2018
    Messages
    171
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : mars 2018
    Messages : 171
    Points : 55
    Points
    55
    Par défaut
    Salut, alors j'ai un peu laisse le code de cote car j'ai remarque des erreurs sur un autre de mes capteurs du au fait que le 3.3v delivre par ma carte etait mauvais.
    J'ai donc branche mon lecteur de carte SD en 5v (car il possede lui meme un convertisseur 3.3v.

    Et la surprise tout fonctionne parfaitement, j'arrive a ecrire sur la carte SD comme je le souhaite.

    Est ce que ca veut dire que l'erreur provient d'une mauvaise alimentation ? Normalement ma carte doit etre alimentee avec du 3.3 donc je m'etais dit que je pouvais directement prendre celui de la STM mais apparement ce dernier etait plutot de 3.2 voire 3.1 a cause d'autres capteurs qui pompent pas mal.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 6
    Dernier message: 09/04/2007, 16h52
  2. [DX 9][C++]Plein ecran + carte graphique
    Par delire8 dans le forum DirectX
    Réponses: 2
    Dernier message: 09/05/2003, 20h11
  3. carte graphique et pixels shader
    Par yeeep dans le forum DirectX
    Réponses: 2
    Dernier message: 26/04/2003, 10h54
  4. [Turbo Pascal] [MS-DOS] Lire la Mac-address de la carte réseau
    Par toctoc dans le forum Turbo Pascal
    Réponses: 14
    Dernier message: 21/02/2003, 22h08
  5. Accès au port 700h pour une carte d'interface
    Par haypo dans le forum Matériel
    Réponses: 3
    Dernier message: 07/11/2002, 11h30

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo