Comment puis-je utiliser une carte SD pour enregistrer des données 16 bits à 48 ksamples/s?

Background

Mon conseil incorpore un STM32 microcontrôleur avec un SD / MMC card SPI et échantillonne des données analogues à 48 ksamples / s. J'utilise le noyau RTX de la bibliothèque en temps réel de Keil, et Elm FatFs.

j'ai une tâche de haute priorité qui capture des données analogiques via DMA dans des blocs de 40 échantillons (40 x 16 bits); les données sont passées par une file d'attente de longueur 128 (qui constitue environ 107 ms de tampon d'échantillon) à une deuxième tâche de faible priorité qui rassemble les blocs d'échantillon dans un tampon de 2560 octets (il s'agit d'un multiple de la taille du secteur SD de 512 octets et de la taille du bloc d'échantillon de 40 octets). lorsque ce tampon est plein (32 blocs ou environ 27 ms), les données sont écrites dans le système de fichiers.

Observation

en instrumentant le code, je peux voir que tous les 32 blocs, les données sont écrites et que l'écriture prend environ 6 ms. Ceci est maintenu jusqu'à ce que (sur FAT16) la taille du fichier atteint 1 Mo, lorsque l'opération d'écriture prend 440 ms, au moment où la file d'attente se remplit et la journalisation est avortée. Si je formate la carte FAT32, la taille du fichier avant l'événement 'long-write' est de 4 Mo.

le fait que la taille de fichier à laquelle cela se produit change entre FAT16 et FAT32 me suggère que ce n'est pas une limitation de la carte mais plutôt quelque chose que le système de fichiers fait à la limite de 1 Mo ou 4 Mo qui prend supplémentaire temps.

Il semble aussi que mes tâches sont planifiées en temps opportun, et que le temps est consommé dans de l'ORME FatFs code à la limite de 1 MB (ou 4 pour FAT32).

la question

y a t il une explication ou une solution? Est-ce une question de graisse, ou plutôt spécifique au Code FatFs de ELM peut-être?

j'ai envisagé d'utiliser plusieurs fichiers, mais D'après mon expérience, FAT ne gère pas un grand nombre de fichiers dans un seul répertoire très bien et cela échouerait tout simplement aussi. Ne pas utiliser un système de fichiers du tout et écrire sur la carte raw serait une possibilité, mais idéalement, je voudrais lire les données sur un PC avec des pilotes standard et aucun logiciel spécial.

il m'est venu à l'esprit d'essayer des optimisations de compilateurs pour réduire le temps d'écriture; cela semble avoir un effet, mais les temps d'écriture semblaient beaucoup plus variables. At-O2 j'ai eu un fichier de 8 Mo, mais les résultats étaient incompatible. Je ne suis maintenant pas sûr s'il y a une corrélation directe entre la taille du fichier et le point où il échoue; je l'ai vu échouer de cette façon à différentes longueurs de fichier sur aucune frontière particulière. C'est peut-être un problème de performance.

<!-J'ai ensuite instrumenté le code et appliqué une approche "diviser pour mieux régner". Cette observation rend probablement la question caduque et toutes les observations précédentes sont erronées ou des errements.

j'ai finalement choisi jusqu'à une instance une écriture multisectorielle (CMD25) où parfois le sondage "wait ready" de la carte prend 174 ms pour les trois premiers secteurs sur un bloc de 5. Le temps d'attente prêt est réglé à 500 ms, donc il serait heureux occupé-attendre longtemps. L'utilisation de CMD24 (single sector write) de façon itérative est beaucoup plus lent dans le cas général - 140 ms par secteur - plutôt qu'occasionnel.

il semble Donc un comportement de la carte, après tout. Je m'efforcerai d'essayer une gamme de cartes SD et MMC.

14
demandé sur Peter Mortensen 2010-07-22 13:30:34

2 réponses

la première chose à essayer pourrait être assez facile: augmenter la profondeur de la file d'attente à 640. Cela vous donnerait 535 ms de mise en mémoire tampon et devrait survivre au moins à cet événement particulier du système de fichiers.

la deuxième chose à examiner est la configuration de L'Elm FatFs. De nombreux systèmes de fichiers intégrés sont très difficiles à gérer avec l'utilisation de la mémoire tampon par défaut. J'en ai vu un qui utilisait un seul tampon de 512 octets pour toutes les opérations et qui rampait pour certaines transactions du système de fichiers. On lui a donné un couple de kilooctets et la chose est devenue des ordres de grandeur plus rapidement.

les deux réponses ci-dessus dépendent de la disponibilité de plus de RAM, bien sûr.

une troisième option serait de préallouer un énorme fichier et d'écraser les données pendant la collecte des données. Cela éliminerait un certain nombre d'opérations coûteuses de répartition des grappes et de manipulation des graisses.

puisque l'optimisation du compilateur a affecté ceci, vous devez également considérer la possibilité qu'il s'agisse d'une multi-threading question. Y a-t-il d'autres threads en cours d'exécution qui pourraient perturber le thread de lecteur de priorité inférieure? Vous devriez également essayer de changer le tampon là-bas à quelque chose d'autre qu'un multiple de la taille de l'échantillon et la taille du bloc flash dans le cas où vous frappez une sorte de résonance du système.

4
répondu Amardeep AC9MF 2012-12-10 20:23:06

Vous (ou quelqu'un d'autre lecture de cette question) pourrait essayer cette GRAISSE bibliothèque: https://github.com/fernando-rodriguez/fat32lib.

Sur un 40 MIPS Puce dsPIC33

0
répondu fernan 2017-05-16 11:33:59