La lecture à partir d’un flash SPI de plus de 35 octets provoque une temporisation du pilote et des résultats corrompus

julumme

La lecture à partir d’un flash SPI de plus de 35 octets provoque une temporisation du pilote et des résultats corrompus


J’ai connecté un flash SPI à ma carte linux (basée sur imx 233) fonctionnant dans son bus SPI. J’ai configuré le noyau, le bus SPI et la puce flash.

Le flash est actuellement sur une maquette. Avant d’essayer de travailler sur Linux, j’ai essayé séparément et je suis capable de lire et d’écrire à ma guise avec une puce FT2232H (carte de dérivation FT2232 par dangerousprototypes.com). Cependant, linux-board, j’ai dû ajouter des résistances de pull-up (10k) dans les lignes d’entrée et de sortie des données, la puce n’a pas été reconnue correctement sinon.

Mon problème réel est que maintenant j’essaie de lire simplement le flash brut via le pilote mtd, et tout semble correct, si je lis moins de 35 octets. Immédiatement si je lis plus de 35 octets (36 ou plus), le pilote se plaint de l’erreur DMA:

[  521.700000] mxs-spi 80034000.ssp: DMA transfer timeout
[  521.700000] spi_master spi32766: failed to transfer one message from queue

De plus, lorsque cela se produit, la plupart (sinon la totalité) des octets seront incorrects. La lecture de moins de 35 octets renverra « immédiatement » (pas de délai) et tous les octets lus seront corrects.

Mon code C vient directement de l’exemple de lecture MTD:

int main(int argc, char * argv[])
{

    if (argc != 2)
    {
    printf("Need arguments how many chars to readnExiting...n");
    return 1;
    }

    int amount = atoi(argv[1]);
    printf("reading (%d) charsn", amount);

    mtd_info_t mtd_info;
    int fd = open("/dev/mtd0", O_RDONLY);
    ioctl(fd, MEMGETINFO, &mtd_info);

    printf("MTD type: %un", mtd_info.type);
    printf("MTD total size : %u bytesn", mtd_info.size);
    printf("MTD erase size : %u bytesn", mtd_info.erasesize);

    /* read buffer */
    unsigned char buf[amount];

    read(fd, buf, sizeof(buf));

    int i = 0;

    for (i = 0; i < amount; i++)
    {
            printf("%i: %Xn",i,buf[i]);
    }
return 0;
} 

Le délai d’attente se produit « comme prévu » (10 secondes) dans spi-mxs.c:

drivers/spi/spi-msx.c:
static int mxs_spi_txrx_dma(...):
....
ret = wait_for_completion_timeout(&spi->c, msecs_to_jiffies(SSP_TIMEOUT));

Des idées qui pourraient être erronées? Je ne suis pas très bon avec l’électronique, alors s’il vous plaît, toutes les suggestions sont les bienvenues.

John U

Si vous avez un oscilloscope, cela vous montrera ce qui se passe sur les lignes de données / horloge.

Kaz

Du côté logiciel, une raison possible pour laquelle vous voyez de mauvaises données n’est pas parce que quelque chose était corrompu, mais parce que l’ readappel système est retourné -1. Vous ignorez la valeur de retour et, dans ce cas, votre boucle imprime des données non initialisées à partir du tableau de longueur variable.

miceuz

peut être un problème d’horloge, essayez de réduire la vitesse d’horloge et voyez si cela aide. Plus tard, lorsque vous passez de la maquette, vous pourrez peut-être augmenter la fréquence d’horloge.

julumme

John, j’ai un oscilloscope, et je vais vérifier ce que je peux en voir. Mais, la mémoire est limitée, et généralement on ne peut voir que les premiers messages de couple. Kaz, vous avez raison à 100%, je devrais le vérifier .. bien que le problème soit toujours en dessous de la fonction de lecture. Miceuz, merci pour votre suggestion, je vais voir à ce sujet ..

Réponses


 Marex

Je pense que c’est un problème avec le pilote SPI. Ne fonctionne-t-il toujours pas avec le noyau amont 3.7? Il y avait beaucoup de correctifs appliqués là-bas.

julumme

Salut Marex, En effet, je travaille sur le pilote en amont (selon notre discussion dans les forums Freescale), je vais essayer vos suggestions à partir de là, et voyons si je peux vous aider à enquêter sur la cause première! Merci!

julumme

Marex, merci d’avoir aidé à corriger le bogue du pilote.

spearson

patchwork-mail1.kernel.org/patch/1910641 Le correctif n’est pas présent sur Linux 3.8.4 mais a été ajouté à Linux 3.9.4.


 Dave Tweed

Ce n’est pas un problème électronique. Sur un bus SPI, le maître contrôle totalement la synchronisation de tout transfert initié. En particulier, lors d’une opération de lecture, le périphérique esclave peut renvoyer des données incorrectes ou aucune donnée, mais cela ne peut pas affecter la fin du transfert.

En d’autres termes, l’erreur de timeout DMA que vous obtenez est entièrement un problème dans le noyau Linux ou le pilote spécifique que vous utilisez. Dans tous les cas, une réponse plus précise va exiger beaucoup plus de détails de votre part: quelle puce flash utilisez-vous? Quelle carte CPU utilisez-vous? Quelle distribution Linux utilisez-vous? Quels sont les numéros de version du noyau et des modules de noyau et / ou pilotes de périphérique que vous utilisez? Avez-vous des liens vers où ces articles peuvent être trouvés?

Chris Stratton

Ce n’est pas l’histoire complète cependant; alors que l’esclave ne peut pas changer le moment d’un transfert individuel, une opération complète peut inclure l’interrogation de l’état de l’esclave, et attendre que cela atteigne un état prêt peut retarder les choses.

Dave Tweed ♦

C’est un bon point, mais cela n’apparaîtrait pas comme un «délai d’attente DMA» (c’est-à-dire au niveau du transfert matériel), il serait identifié comme un délai d’attente de protocole de plus haut niveau.

julumme

Dave, merci beaucoup pour ta réponse! Ma puce flash est SST25VF064 (Microchip), et elle est connectée à la maxi carte Olinuxino (d’Olimex). Je n’utilise pas de distribution particulière, mais je construis un système de fichiers simple basé sur busybox. La version linux est 3.7, c’est la dernière de la ligne principale de Freescales ( github.com/Freescale/linux-mainline/branches ).

julumme

De plus, je suis vraiment nouveau dans ce domaine, donc je pourrais aussi bien avoir une erreur de débutant quelque part .. Actuellement, je n’ai défini ma puce qu’en dtsi et ajouté le support de cette puce flash particulière à m25p80.c (seulement 32Mbit flash était là, je viens de vérifier le JEDEC à partir de la fiche technique (0xbf254b), et j’ai doublé le nombre de secteurs à 128, je me demande si c’est correct?)

 

#(une, #à, #de, #et, #la, 3,5, corrompus?, d’un, des, du, Flash, lecture, octets, partir, pilote, plus, provoqué, résultats, SPI, temporisation

 

google

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *