Langue: FR

Vitesse de la carte SD sur ESP32 - pourquoi elle s’arrête à 20 MHz

Notes · Publié le

Une carte géographique affichée sur un écran de 3,2 pouces, chargée depuis la carte SD d’un ESP32

Ma visionneuse de photos sur ESP32 lit chaque photo depuis une carte SD. Je voulais donc savoir à quelle vitesse la carte va vraiment. La plupart des pages citent la classe de la carte ou l’horloge SPI. J’ai mesuré ce qu’un ESP32 obtient réellement avec la bibliothèque Arduino SD, et j’ai trouvé deux limites qui ne sautent pas aux yeux.

Le montage

  • ESP32 DOIT DevKit V1 (ESP32-WROOM-32), Arduino core pour ESP32 3.3.
  • Un module de carte SD sur son propre bus SPI (HSPI). SCK 14, MOSI 13, MISO 27, CS 15, avec des fils de connexion sur une plaque d’essai.
  • La bibliothèque Arduino SD, carte en FAT32.

Limite 1 - impossible d’avoir 25 MHz

Les cartes SD en mode SPI sont prévues jusqu’à 25 MHz, c’est donc ce que j’ai demandé.

SD.begin(PIN_SD_CS, sdSpi, 25000000);

Le bus tourne à 20 MHz. Deux choses se combinent.

  1. La bibliothèque SD limite l’horloge à 25 MHz. Dans le fichier sd_diskio.cpp du core, un commentaire l’appelle le « SD spec maximum for non-UHS cards ».
  2. L’ESP32 fabrique son horloge SPI en divisant son horloge de bus de 80 MHz par un nombre entier. Les choix en haut de l’échelle sont 80 / 2 = 40 MHz, 80 / 3 = 26,7 MHz et 80 / 4 = 20 MHz. 26,7 dépasse la limite, donc le suivant est 20 MHz.

Avec cette bibliothèque, 20 MHz est donc le vrai maximum. La vitesse brute du bus est alors de 20 MHz / 8 = 2,5 Mo/s.

Les mesures

J’ai écrit 512 Ko sur la carte, je les ai relus et j’ai vérifié chaque octet. Seul le temps passé dans les fonctions de fichier compte, pas le temps de préparer les données de test.

uint32_t t0 = micros();
size_t n = f.write(buf, chunk);    // same for f.read(buf, chunk)
busy += micros() - t0;

Résultats à 20 MHz.

Taille de bloc Écriture Lecture
4 Ko 1,3 Mo/s 1,37 Mo/s
16 Ko 1,7 Mo/s 1,37 Mo/s
32 Ko 1,7 Mo/s 1,37 Mo/s

Limite 2 - de plus gros blocs n’aident pas la lecture

L’écriture accélère avec de plus gros blocs, jusqu’à environ 16 Ko. La lecture reste à 1,37 Mo/s, quelle que soit la taille. C’est 55 % des 2,5 Mo/s que le bus pourrait transporter.

La raison est dans la façon dont la bibliothèque SD lit. Elle déplace chaque secteur de 512 octets avec le processeur, sans DMA, et attend la carte entre deux secteurs. Un bloc plus gros veut seulement dire plus de secteurs à la suite, chacun avec la même attente. Le bus reste inoccupé pendant ces attentes.

Deux autres choses que j’ai vues.

  • L’écriture fait parfois des pauses de 10 à 250 ms. C’est la carte qui efface en interne. Pour enregistrer des données, gardez-les dans un tampon pour qu’une pause ne fasse rien perdre.
  • Sur ma carte SDHC de 4 Go, les fichiers copiés depuis le PC se lisent plus lentement (environ 0,75–0,8 Mo/s) qu’un fichier que l’ESP32 vient d’écrire (1,37 Mo/s). Ça vient de l’intérieur de la carte, pas de l’ESP32. Une carte plus rapide (classée A1 ou U3) peut mieux se comporter.

Comment aller plus vite

  • Écrire par blocs de 16 Ko ou plus. C’est gratuit et donne environ 30 % de vitesse d’écriture en plus qu’avec 4 Ko.
  • Utiliser le pilote SD-sur-SPI d’ESP-IDF au lieu de celui d’Arduino. Il peut utiliser le DMA, il devrait donc s’approcher de la limite de 2,5 Mo/s. Je ne l’ai pas encore mesuré.
  • Utiliser le bus 4 bits propre aux cartes SD (SDMMC) au lieu du SPI. L’ESP32 a le matériel pour, et c’est bien plus rapide. Mais ses broches fixes comprennent GPIO2 et GPIO12, qui sont des broches de démarrage. GPIO12 surtout peut empêcher la carte de démarrer, comme je l’explique dans L’ESP32 ne démarre plus avec une carte SD sur GPIO12.

Un mot sur le câblage

C’était un projet du week-end sur une plaque d’essai, avec des fils de connexion. Ils n’ont pas limité les chiffres ci-dessus. Le bus tournait déjà au maximum de la bibliothèque, 20 MHz, et chaque octet a été relu correctement.

Ils vous limiteront si vous allez plus loin. Le bus SDMMC tourne à 20–40 MHz sur six lignes à la fois, et c’est là que de longs fils volants causent des erreurs. J’ai vu la même chose avec l’écran de ce projet. À 80 MHz en SPI, il affichait des lignes coupées sur ma plaque d’essai, alors je suis resté à 40 MHz.

Si vous faites un vrai PCB pour aller plus vite, quelques règles simples aident plus que tout le reste.

  • Des pistes courtes, quelques centimètres, au-dessus d’un plan de masse continu.
  • Une petite résistance en série (environ 22–33 Ω) près de l’ESP32 sur l’horloge et les lignes de données, pour amortir les oscillations.
  • Des pull-ups de 10 kΩ sur les lignes de commande et de données de la carte, et un condensateur de découplage juste à côté de la carte.

L’impédance contrôlée n’est pas nécessaire à ces vitesses. Elle compte pour des signaux bien plus rapides ou des pistes bien plus longues.

Format de la carte

La bibliothèque Arduino SD lit le FAT32 (et le FAT16). Les cartes de plus de 32 Go sont en général formatées en exFAT, qu’elle ne gère pas de base. Reformatez-les en FAT32 avant de les utiliser.

Liens

← Retour aux articles