Comment gérez-vous les transferts de données sur la mémoire très limitée, les systèmes embarqués?

StackOverflow https://stackoverflow.com/questions/359745

Question

J'ai un microcontrôleur qui doit télécharger un fichier volumineux à partir d'un port série du PC (115200 de transmission) et l'écrire dans la mémoire flash série sur SPI (~ 2 MHz). Les écritures flash doivent être en 256 blocs d'octets précédés d'une commande d'écriture et l'adresse de la page. La RAM totale disponible sur le système est de 1 kB avec une taille de la pile 80 d'octets.

travaille actuellement en remplissant un tampon de 256 octets à partir du UART puis ping-ponging à un autre tampon de 256 octets étant rempli par une interruption du signal prêt tampon RX lorsque le flash est écrit avec écrit occupé. L'échange de tampon est répétée jusqu'à ce que l'opération est terminée.

Je préférerais configurer TX / RX des gestionnaires d'interruption pour les deux ports SPI et UART qui fonctionnent sur des tampons circulaires séparés. Ainsi, au lieu du scrutin pour les nouveaux octets et d'attente pour les opérations pour terminer, je peux simplement remplir les tampons TX et permettent l'interruption ou vérifier les tampons pour les données entrantes. Cela donnerait beaucoup plus de cycles d'horloge pour le travail réel au lieu d'attendre sur les périphériques.

Après la mise en œuvre des IRQ avec des tampons circulaires 128 octets, je Pöll la mémoire tampon UART RX pour les données et placer immédiatement dans le tampon SPI TX pour faire le transfert de fichiers. Le problème que je rencontre avec cette approche est que je n'ai pas suffisamment de RAM pour les tampons et le PC tampon de réception se remplit plus vite que je reçois les données vers la mémoire tampon de transmission flash. De toute évidence, la vitesse de transmission est pas le problème (115,2 kHz et 2 MHz out), mais il y a un cycle d'écriture attente après chaque page de 256 octets est transmise.


Il semble que les interruptions fréquentes SPI bloquaient certaines des interruptions UART et causant octets à manquer. La solution I a été choisi d'utiliser un tampon en anneau pour l'UART interruption de réception et alimenter les données dans une mémoire tampon de page de 256 octets qui est envoyé à la mémoire flash série de sondages pour des transferts d'octets et à écrire la fin. Un tampon circulaire 128 est assez grand pour éviter les débordements lors de la SPI écriture.

Était-ce utile?

La solution

Je ferais quelque chose comme une dispersion se rassemblent sur un PC. Créer une liste chaînée d'une struct comme ceci:

typedef struct data_buffer {
    char flags;
    char[128] data;
}

Avoir l'un des bits dans le drapeau signifie « ReadyToFlash » et un pour « clignotant ». Vous devriez être en mesure de régler le nombre de tampons dans votre liste chaînée pour que le flash d'attraper l'UART comme il l'écrit ou vice-versa.

Si le flash arrive à un bloc tampon qui n'est pas « ReadyToFlash » il bloquerait et vous aurez besoin d'avoir votre départ UART IRQ back up. Si l'UART arrive à un bloc qui est « ReadyToFlash » ou « clignotant », il remplit trop vite et vous avez probablement besoin d'un autre tampon, si vous avez la mémoire dynamique, vous pouvez le faire accordage à l'exécution et ajouter un tampon à la liste à la volée , sinon vous aurez juste besoin de faire quelques tests empiriques.

Autres conseils

Est-ce que l'UART et le côté PC du support d'application RS-232 handshaking (contrôle de flux)? Si oui, quand votre tampon de réception se rapproche d'être plein, ont le ISR tomber la ligne CTS - si le côté PC est configuré pour respecter le contrôle de flux de matériel, il doit cesser d'envoyer quand il voit cette condition. Une fois que vous avez vidé (ou presque vidé) le tampon de réception, affirmer à nouveau CTS et le PC devrait commencer à envoyer à nouveau.

Notez que ce qui rend le logiciel sur le dispositif embarqué beaucoup plus complexe -. Si c'est un compromis que vous êtes prêt à faire devrait être l'analyse faite par vous et votre gestionnaire et équipe

Ceci est exactement ce que le contrôle de flux a été créé pour, je sais que d'une douleur énorme mis en place, mais si vous activez le contrôle de flux sur la ligne série vos problèmes serait historique.

Je suppose que vous transférez un fichier binaire si XON-XOFF est pas la meilleure solution, ce qui laisse le contrôle de flux matériel.

Une autre option consiste à utiliser un protocole de contrôle de flux intégré tel que XModem. J'ai un projet similaire embedded où le flash est écrit dans les pages 128byte. Quelle coïncidence que XModem envoie des données en morceaux de 128byte attend ensuite un accusé de réception avant d'envoyer les autres.

Je ne sais pas ce que je suis absent, mais si le fait est que le taux moyen de données provenant du PC est plus élevé que le taux moyen, vous pouvez écrire sur le flash, vous êtes soit avoir besoin d'un beaucoup de RAM, ou que vous allez avoir besoin de contrôle de flux.

Mais vous dites que cela a fonctionné quand vous avez eu des tampons de blocs, mais maintenant que vous avez des tampons d'octets, il ne fonctionne pas?

Pouvez-vous coller avec les tampons de blocs qui sont remplis par l'interruption UART RX, et quand chaque tampon est plein, la transférer au code SPI / Flash pour vider ce tampon en utilisant l'interruption SPI? Cela vous permettra d'économiser la copie chaque octet, et au lieu d'avoir à faire la logique de tampon circulaire deux fois pour chaque octet, vous ne devez le faire pour chaque bloc.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top