Forums d'entraide informatique - Astuces - Conseils
Des experts à votre écoute pour tous vos dysfonctionnements
Vous n'êtes pas identifié.
#1 23-10-2008 19:38:59
- Admin
- Administrateur
- Date d'inscription: 30-07-2008
- Messages: 683
Stockage de masse non volatile : un block device (2)
DÉDIÉ
goto exit;
goto exit;
break;
case WRITE :
refile_buffer (bh);
for (i 0; i < nb_block; i++)
count 2;
do
{
size write_block (block_addr_ptr[i][0],
block_addr_ptr[i][1], block_addr_ptr[i][2], block_addr_ptr[i][3], bh->b_data + (i * DFLT_HARDSECT_SIZE));
while ((size I. DFLT_HARDSECT_SIZE) && (count--)); if (size != DFLT_HARDSECT_SIZE)
err("failed to write block %d - %d - %d - %d", block_addr_ptr[i][0],
block_addr_ptr[i][1], block_addr_ptr[i][2], block_addr_ptr[i][3]);
status = 0;
goto exit;
mark_buffer_uptodate (bh, 1); goto exit;
break;
default
status = 0; goto exit; break;
exit :
bh->b_end_io (bh, status); return (0);
Afin d'illustrer les transferts de données avec la MMC, nous allons présenter la fonction read_bl ock ( ) ainsi que quelques-unes des fonctions qu'elle utilise. Comme nous venons de le voir, read _b1 ockc ) est appelée par la fonction mmc_bl k_ma ke_request ( ) chaque fois que le pilote doit procéder à une lecture sur la MMC. Elle est définie dans l'élément mmc_cispi du module mmc_q spi _mod.
int read_block (unsigned char al, unsigned char a2, unsigned char a3, unsigned char a4, char *block)
int nb_bytes_read, retval;
unsigned int count 10;
unsigned char answer, status[2]; unsigned short checksum, block_crc;
dbg("%s : block %d %d %d %d", __FUNCT1ON , al, a2, a3, a4);
if (!block)
{
err("%s - first•argument is a NULL pointer",
_FONCTION_); return (-EINVAL);
mmc_cmd_array[CMD_17].al al;
mmc_cmd_array[CMD_17].a2 a2;
mmc_cmd_array[CMD_17].a3 a3;
mmc_cmd_array[CMD_17].a4 = a4;
/* send the single read block command retval send_cmd (CMD_17, &answer); if (retval < 0)
err("%s - failed to send CMD_17", __FUNCTION__); .
return (retval);
while (((answer & Oxff) !.• Oxfe) && (count--)) {
retval read_answer (&answer);
if (retval < 0)
return (retval);
if (answer I. Oxfe)
err("%s - CMD_17 failure (answer Ox%x)",
FUNCTIOÎ__, answer & Oxff);
return (-EPROTO);
retval cispi_read (MMC_DEVICE, block,
MMC_BLOCK_SIZE * sizeof (unsigned char)); if (retval < 0)
{
err("%s - failed to read block", FUNCTION__);
return (retval);
if (retval != MMC_BLOCK_SIZE)
err("%s - %d bytes read instead of %d", FUNCTION__, retval, MMC_BLOCK_SIZE);
nb_bytes_read retval;
/* read the checksum (2 bytes) */
retval = qspi_read (MMC_DEVICE, (char *) &checksum, sizeof (unsigned short));
if (retval < 0)
err("%s - failed to read checksum", FUNCTION );
return (retval);
if (retval != sizeof (unsigned short))
err("%s - failed to read checksum", _FUNCTION_); return (-E10);
/* compute the block checksum and compare with
* the checksum send by the MMC */
block_crc (unsigned short) crc16 (block, MMC_BLOCK_SIZE);
block_crc = __cpu_to_be16(block_crc); /* endianness */ if (block_crc !. checksum)
6.AMÉLIORATIONS DU SYSTÈME DE BASE
Nous avons, à force de tester notre pilote dans diverses configurations, constaté la présence de quelques erreurs de communications, particulièrement visibles lors du stockage de fichiers volumineux (qui ne sont pas nécessairement le standard dans des applications embarquées mais sont devenues courants dans une utilisation quotidienne d'un ordinateur).Afin d'identifier ces erreurs et d'éventuellement les corriger, nous avons implémenté plusieurs Méthodes que nous décrirons ici :
Implémentation du code de redondance cyclique (CRC)'',,, visant à valider les blocs lus ; -„
• Implémentation d'une lecture après toute écriture sur la carte mémoire : cette méthode nous permet de valider le stockage de données sans nécessairement implémenter toute la chaîne de validation qui va suivre
• Implémentation des CRC en lecture comme en écriture qui
nécessite par conséquent le calcul du CRC lors de l'envoi de commandes. Rappelons que par défaut la vérification de CRC est désactivée en mode SPI et nous la réactivons manuellement au moyen de la commande CMD5 9. Ceci nécessite donc, en plus de l'implémentation du CRC 16 utilisé lors de transitions de blocs de données tel que validé dans la phase précédente, d'implémenter le CRC7 utilisé lors de la transmission de commandes.
L'intérêt additionnel de valider les communications certifiées par CRC est d'offrir la perspective d'une implémentation complète du mode natif de communication des MMC, plus robuste et plus rapide que le mode SPI (mais nécessitant toutes les vérifications de CRC fastidieuses à valider sans passer par le mode SPI).
6.1 VALIDATION DES BLOCS DE DONNÉES: CRC16
La vérification qui implique le moins de changement au code existant est le calcul du CRC associé à une transaction en lecture de la MMC vers le processeur. En effet, la MMC nous fournit toujours un CRC valide, même en mode SPI où le calcul du CRC n'est pas requis. Ainsi, tester le CRC en fin de CMD1 7 (lecture) n'implique aucune modification de notre code existant si ce n'est implémenter la version appropriée de CRC 16 et comparer ce résultat à celui fourni par la MMC.
Malgré les excellentes présentations des CRC présentées par ailleurs dans ces pages pas Yann Guidon [10, I I], nous nous sommes contentés de trouver sur le web une implémentation compréhensible du code que nous recherchions [12]. La
{
err("%s - bad checksum : compute %d instead of %d",
FONCTIONblock_crc,
checksum); return (-EI0);
/* take a look on the MMC status */
retval = get_status (status);
if (retval < 0)
{
err("%s - unable to get MMC status", __FUNCTION__); return (retval);
if ((status[0]) II (status[1]))
err("%s - status Ox%x Ox%x", __FUNCTION__, status[0] & Oxff, status[1] & Oxff); return (-EPROTO);
}
return (nb_bytes_read);
static int read_answer (unsigned char *answer)
int retval r 0;
unsigned int count 1000;
do
retval r gspi_read (MMC_DEVICE, answer,
sizeof (unsigned char));
if (retval < 0)
return (retval);
/* must handle the case retval == 0 */
while ((*answer == Oxff) && (count--));
/* if the MMC is mot ready, Oxff is returned
as answer. we retry count times... */
if (!count)
return (-EBUSY);
dbg("%s - answer : Ox%x count :
__FUNCTION__, *answer & Oxff,
1000 - count);
return (0);
static int send_cmd (unsigned int cmd_num, unsigned char *answer)
int retval
/* test cmd_num */
mmc_cmd_array[cmd_num].checksum = 0; mmc_cmd_array[cmd_num].checksum
crc7 (&mmc_cmd_array[cmd_num].cmd, 5);
dbg("%s - cmd %d - checksum : Ox%x", __FUNCTION , cmd_num, mmc_cmd_array[cmd_num].checksum & Oxff);
retval = gspi_write (MMC_DEVICE,
(char*) &mmc_cmd_array[cmd_num].cmd, CMD_SIZE); if (retval < 0)
return (retval);
seule subtilité en termes d'implémentation portable à la fois sur processeur Coldfire et Intel est de tenir compte de l'endianness du résultat qui tient sur 2 octets. L'ajout de la fonction hton s ( ) après calcul du CRC se charge de convertir le résultat issu du processeur en un format compréhensible par la MMC.
6.2 VALIDATION DES ÉCRITURES
Après avoir implémenté une méthode de contrôle des lectures, nous désirons valider les écritures de blocs de données. Nous verrons plus loin que l'activation de tous les contrôles par la MMC nécessite de valider d'autres méthodes de calcul (CRC7) : nous allons donc dans un premier temps nous contenter d'implémenter la méthode — relativement inefficace mais la plus simple — de relire tout bloc immédiatement après son écriture pour en vérifier la validité. Cette correction n'a pas donné satisfaction car pour des raisons que nous n'expliquons pas, nous sommes capables d'écrire plusieurs MB sur une MMC connectée au bus QSPI du Coldfire sans qu'aucun bloc erroné ne soit détecté par comparaison d'une lecture après chaque écriture. Cependant, après avoir démonté (umoun t) et remonté le système de fichiers sur la MMC, le fichier est apparu corrompu. La MMC n'a pourtant pas de mémoire cache en interne à notre connaissance.
6.3 VALIDATION DES COMMANDES : CRC7
Ayant validé le code de calcul du CRC 16 en constatant que notre calcul correspond toujours à celui de la MMC tel que fourni en fin de lecture d'un bloc, nous proposons finalement d'activer totalement le contrôle de flux par
la MMC. Ceci nécessite un calcul additionnel : en plus de valider les transactions de blocs de données, la MMC valide aussi les commandes qu'elle reçoit au moyen d'un CRC plus cours, le CRC7.
Le CRC7 définit un code de vérification de petites quantités de données — dans notre cas 40 bits — au moyen d'un code sur 7 bits. Ce code est transmis à la carte sous forme de bits de poids fort d'un octet complétant la transmission dont le bit de poids le plus faible est défini à I [I, chap.5.7.2, p.55]. Ainsi, nous implémentons dans un premier temps le CRC7, puis devons multiplier par 2 le résultat et ajouter I avant d'avoir un octet validant la transaction. Nous avons repris un code simple de calcul de CRC7 (table I) tel que disponible dans la littérature [13], bien que ce calcul courant dans les transmissions gagne probablement à être optimisé.
La seule façon de valider ce code est de calculer le CRC7 de la commande CMDO — la seule pour laquelle nous connaissions le résultat. Nous constatons qu'appliquer le code présenté en table I aux octets {0x40 0x00 0x00 0x00 0x00} donne bien le résultat escompté, à savoir Ox 9 5. Par ailleurs, nous constatons qu'en activant le contrôle de tous les flux (blocs et commandes) au niveau de la MMC, compléter les commandes avec ce CRC7 résulte en un acquittement de la commande par la carte.
L'activation de la vérification de tous les CRC lors des transactions avec la carte s'obtient en insérant la commande CMD5 9 (CRC ON OFF) juste après l'acquittement de CMD1 par la MMC. Désormais, tous les CRC que nous avions jusqu'ici ignoré devront être validés après chaque transaction.
#include <stdio.h>
#include <stdlib.h>
/*
Name Polynomial Representations: Normal or Reverse (Normal of Reciprocal) CRC-1 x + 1 (Used in hw, also known as parity bit) 0x1 or 0x1 (0x1)
CRC-5-USB x5 + x2 + 1 (used in USB token packets) 0x05 or 0x14 (0x9)
CRC-7 x7 + x3 + 1 (used in some telecom systems) 0x09 or 0x48 (0x11)
CRC-8 x8 + x2 + x + I 0x07 or 0xE0 (0xCl)
CRC-12 x12 + xll + x3 + x2 + x + 1 (used in telecom) 0x80F or 0xF01 (0xE03)
CRC-16-CCITT x16 + x12 + x5 + 1 0x1021 or 0x8408 (0x0811)
CRC-16-IBM x16 +x15 + x2 + 1 0x8005 or 0x4001 (0x4003)
/* Computation of CRC-7 polynom (x**7+x**3+1), used in MMC cmds and responses */
unsigned char crcl(unsigned char *pc) {unsigned int i,ibit,c,crc=0x00,1en=5; for (1=0; i<len; i++,pc++)
{c = *pc;
for (ibit = 0; ibit < 8; ibit++) {crc <<= 1;
if ((c crc) & 0x80) crc 0x09;
c <<= 1;
crc &= 0x7F;
return ((crc<<1)+1);
int main()
{char data[5]={0x40,0x00,0x00,0x00,0x00}; // CMDO printfr0x%x\r,crc7(data)l;
return(0);
Table 1: Implémentation naïve du calcul de CRC7 validant la transmission de commandes à la INC.
7.UTILISATION
L'utilisation du block device nécessite plusieurs étapes
• La création du point d'entrée approprié dans le répertoire /dev.Nous avons choisi un block device de nombre majeur 254 nommé mica (de nombre mineur 0) et les partitions mmc a i avec i e [ I :4] le nombre mineur. Sur PC pour l'implémentation sur port parallèle du protocole SPI, le block device se crée par mknod /dev/mmca b 254 0
• La disponibilité d'un outil de formatage.Alors que toutes les versions de mkfs sont disponibles sur PC, il nous faut cross-compiler une version de cet outil à uClinux sur processeur Coldfire. Par habitude et limités par les formats de fichiers reconnus par le noyau par défaut d'uClinux, nous avons sélectionné mke2f s pour formater notre MMC en format ext2 [141;
• Si l'ensemble de la MMC est utilisée sans partition,formater la MMC complète sans y créer de table de partition mke2f s -1 /dev/mmca sous uClinux, ou sans l'option - I sur PC et répondre par l'affirmative à la confirmation de formater l'ensemble du périphérique
• Éventuellement créer des partitions sur /dev/mmca au moyen de fdi sk et les formater individuellement en y accédant par mke2f s /dey /mmc ai, ie [1:4]
• Finalement, monter le nouveau périphérique en un point d'accès : le seul répertoire accessible en écriture sous uClinux tel que fourni installé sur le Coldfire 5282 du circuit SSV étant / v a r, et /mnt étant déjà occupé pour un accès N FS au PC de développement, nous avons choisi de mkdi r /var/mmc suivi de mount /dev/mmca /var/mmc ou mount /dev/mmcai /var /mmc si la partition i a été initialisée. Notez qu'il arrive souvent que l'initialisation de la MMC échoue à la première tentative : relancer la commande mount résout ce problème dès le second essai.
Nous obtenons ainsi un nouveau répertoire dans notre arborescence donnant accès à l'espace mémoire de la MMC. Il est fondamental de penser à umo un t /va r/mmc avant de retirer la carte si l'on veut conserver la cohérence du système de fichier de la MMC, car nous constatons rapidement qu'une utilisation intensive du cache est effectuée. Cette utilisation de la mémoire est particulièrement appréciable compte tenu de la lenteur d'accès à la MMC.
À titre d'exemple, voici le fonctionnement de notre driver contrôlant un montage sur le port parallèle du Libretto 100CT, après avoir i nsmod pport_spi .o et i n smod mmc_qspi . o
• I. Nous commençons par partitionner notre carte afin de mettre en pratique le bout de code associé à la gestion de cette option du block device :
libretto:/home/jmfriedt# fdisk /dev/mmca Device contains neither a valid DOS partition table, nor Sun, SOI or OSF disklabel
Building a new DOS disklabel. Changes will remain in memory only,until you decide ta write them. After that, of course, the previous content won't be recoverable.
The number of cylinders for this disk is set ta 3972.
There is nothing wrong with that, but this (s larger than 1024, and could in certain setups cause problems with:
1) software that runs at boot time (e.g., old versions of LILO)
2) booting and partitioning software from other OSs
(e.g., DOS FDISK, OS/2 FDISK)
Command (m for help): n Command action
e extended
p primary partition (1-4)
Partition number (1-4): I
First cylinder (1-3972, default 1):
Using default value I
Last cylinder or +size or +sizeM or +sizeK (1-3972, default 3972): +30M
Command (m for help): n Command action
e extended
p primary partition (1-4)
Partition number (1-4): 2
First cylinder (962-3972, default 962):
Using default value 962
Last cylinder or +size or +sizeM or +sizeK (962-3972, default 3972): +40M
Command (m for help): p
Disk /dev/mmca: 4 heads, 16 sectors, 3972 cylinders Units = cylinders of 64 * 512 bytes
Device Boot Start End Blocks Id System
/dev/mmcal 1 961 30744 83 Linux
/dev/mmca2 962 2242 40992 83 Linux
Command (m for help):
afin de créer deux partitions, l'une de 30 MB et l'autre de 40 MB, qui ne remplissent donc pas l'ensemble de notre carte de 128 MB. Le nombre de blocs a bien été reconnu, l'architecture de la carte est cohérente avec ce que nous nous attendons à trouver.
2.11 nous faut ensuite formater chacune de ces partitions. Si nous avions décidé de travailler sur l'ensemble de la carte sans réaliser de partition, une commande de type mke2fs /dev/mmca aurait convenu. Notez que le nombre d'octets
par blocs — ici 1024 — est dépendant de la géométrie du
block device et doit donc être alloué dynamiquement en fonction des requêtes du VFS :
libretto:/home/jmfriedt# mke2fs /dev/mmcal
mke2fs 1.19, 13-Jul-2000 for EXT2 FS 0.5b, 95/08/09 Filesystem label=
OS type: Linux
Block size.1024 (log.0)
Fragment size.1024 (logrO)
7712 (modes, 30744 blocks
1537 blocks (5.00%) reserved for the super user First data blockr1
4 block groups
8192 blocks per group, 8192 fragments per group 1928 modes per group
Superblock backups stored on blocks:
8193, 24577
DÉDIÉ
♦ 3. Ayant monté dans un point d'accès approprié notre nouveau bloc — et vérifié ainsi que le formatage a bien été reconnu puisque GNU/Linux teste l'intégrité du périphérique bloc au moment du montage, nous allons tester le débit en écriture :
Nous avons donc mis I minute, 41 secondes pour écrire un fichier d'environ 2,3 MB.
Les performances ne sont pas pour le moment l'objectif principal de ce développement. L'implémentation logicielle du protocole SPI sur port parallèle prend un temps considérable : le temps de transfert est de l'ordre de 24 kB/s en écriture et 26 kB/s en lecture.
Afin de rendre la main aux autres processus au cours des accès à la MMC sur le PC, nous insérons une fonction schedule( ) après chaque accès à un octet échangé avec la MMC dans son implémentation sur le port parallèle (la version Coldfire utilisant les interruptions pour acquitter chaque transaction n'a pas ce problème) : nous avons constaté que les performances sur un système peu chargé ne sont pas affectées par la fréquence aux appels à schedul e ( ) ni par les moments auxquels cette fonction est appelée.
Cependant, alors que les performances en termes de débit ne sont pas affectées sur un système peu chargé, l'interactivité pour l'utilisateur est nettement améliorée. Enfin, nous utilisons ici l'algorithme d'allocation de blocs de ext2,qui vise à allouer des blocs d'inodes afin d'accélérer les accès aux fichiers.
Cette notion n'a pas lieu d'être sur un support de type MMC où tous les emplacements mémoire sont accédés avec une latence indépendante de leur localisation.
Il est donc envisageable d'utiliser d'autres méthodes d'allocations d'inodes plus appropriées, notamment dans le but d'utiliser une fonctionnalité récente des MMC — qui a été ajoutée à la norme pour le mode de communication SPI — qu'est l'écriture de plusieurs blocs adjacents (CMD 18 — READ_MU LT I P LE_B LOC K,
et CMD25 — WRITE_MULTIPLE_BLOCK).
Il n'est cependant pas clair que la charge additionnelle de gestion des queues de données conservées en cache améliore réellement le débit au vu des gains limités qu'offre cette commande, ou qu'il existe un algorithme capable d'accélérer les accès à un périphérique de stockage de masse de type « mémoire non volatile » tel que la MMC pour laquelle aucun élément mécanique ne limite les délais de lecture ou d'écriture.
8.CONCLUSION
Nous avons développé un montage électronique d'interfaçage de MultiMediaCard (MMC) et MMC+ avec le Coldfire fourni sur la carte SSV DNPS280 ainsi que sur le port parallèle d'un PC.
Nous nous sommes familiarisés avec le protocole de communication (SPI) fourni comme périphérique matériel dans le premier cas, émule de façon logicielle dans le second.
Étant capable de lire et écrire des informations sur la MMC après en avoir extrait la géométrie, nous avons implémenté un block device donnant accès à toutes les fonctionnalités d'un système de fichier qui fait apparaître notre périphérique comme un nouveau répertoire de l'arborescence uClinux ou GNU/Linux.
Nous avons amélioré l'intégrité des transactions en implémentant l'ensemble des méthodes de validation des échanges par CRC.
Ce travail répond à un besoin lors de l'utilisation de circuits embarqués tel que le SSV DNP5280 à des fins de télémesure de pouvoir écrire une grande quantité de données sur mémoire non volatile.
Le block device ajoute une souplesse d'accès et d'intégrité des données qu'une écriture brute sur mémoire non volatile ne propose pas. L'utilisation de MMC+ offre ainsi plus de I GB de mémoire avec des débits d'accès raisonnables (de plus de 40 kB/s sur processeur Coldfire à plus de 20 kB/s sur le port parallèle du PC).
Afin de parfaire les fonctionnalités de ce driver, nous avons implémenté le support des partitions. En effet, une des premières applications hors embarqué d'un tel circuit qui vient à l'idée est la lecture de cartes utilisées dans des appareils photographiques numériques (APN).
L'utilisation d'un format de type VFAT est pris en charge automatiquement par IeVFS sous réserve que le noyau supporte ce format. Il apparaît à l'utilisation qu'une carte formatée par un APN tel que le Nikon Coolpix 3200 contient une unique partition en FAT 16 s'étendant sur l'ensemble de la carte.
Une solution possible que nous avons testée est de formater la carte via notre montage par mkfs . vfat /dev/mmca (ce qui correspond à formater tout le périphérique bloc sans y créer de partition) et la carte résultante est reconnue par
Writing inode tables: done
Writing superblocks and filesystem accounting information: done
libretto:/home/jmfriedt# mount /dev/mmcal /mnt/mmcal/ libretto:/home/jmfriedt# mount /dev/mmca2 /mnt/mmca2/
libretto:/home/jmfriedt# df Filesystem 1k-blocks Used Available Use% Mounted on
/dev/libretto/rootfs 307184 265164 42020 87% /
/dev/librettevar 102392 92928 9464 91% /var
/dev/libretto/usr 1261524 854044 407480 68% /usr
/dev/hdal 104792 38288 66504 37% /boot
/dev/mmcal 29765 13 28215 1% /mnt/mmcal
/dev/mmca2 39659 13 37597 1% /mnt/mmca2
libretto:/home/jmfriedt# cp /home/jmfriedt/latex/collagen/ collagen.pdf /mnt/mmcal
libretto:/home/jmfriedt# time umount /mnt/mmcal
real 1m41.987s
user 0m0.000s
sys 1m41.380s
libretto:/home/jmfriedt# mount /dev/mmcal /mnt/mmcal libretto:/home/jmfriedt# ls /mnt/mmcal/
total 2265
-rwxr-xr-x 1 root root 2296050 Mar 12 00:24 collagen.pdf drwxr-xr-x 2 root root 12288 Mar 12 00:00 lost+found
l'APN. Après ce formatage, l'APN se contente d'ajouter les répertoires dont il a besoin et les images stockées alors sont visibles sur un PC équipé de notre montage.
Avec la gestion des partitions, une carte formatée par l'APN est directement accessible sous /dev/mmcal d'où nous avons pu lire et afficher les images qui y sont emmagasinées.
De plus, nous devons encore valider la fiabilité des transactions à long terme et notamment la corruption possible de quelques blocs de 512 octets lors du stockage de fichiers volumineux (>7 MB).
9.REMERCIEMENTS
Nous remercions l'entreprise Alcôve (www.alcove.fr) pour son soutien à la réalisation de ce projet. L'association de diffusion des Logiciels libres sur la Franche-Comté — Sequanux (www. sequanux.org) est également remerciée pour son support logistique.
Enfin, nous remercions Frédéric Tronel pour le don du Toshiba Libretto 100CT qui illustre cet article, grâce auquel même une application sur le port parallèle d'un PC garde une orientation « application embarquée ».
Praqmatec
De nombreux kits de développement avec du hardware ... 1111kr
* ARM7 S3C44BOX
* 66 MHz
8 Mo SDRam
2 Mo Flash NOR
uainux
16 Mo de flash NAND
* Port LCD
* USB host et device
* Port IDE
* Ports RS232 " Ethernet
* I2C
* SPI
* Buzzer
• Boutons
* Sonde JTAG
BIOS
linux 2.4 ers exemples schémas datasheets tutoriels en françai debug sous eclipse
gerigzing
•
www.pragmatux.net www.pragmatec.net/catalog
Kits complets à partir de :
I 40 f HT
Support inclus !
,
4*i-trie"-
Kits de développement
• [9] Petazzoni (Thomas) et Decotigny
(David), « Conception d'OS : Pilotes de périphériques blocs », GNU/Linux Magazine France 80, janvier 2006, pp. 74-90.
• [10] Guidon (Y.), « Réalisation du CRC
pour le conteneur MDS », GNUILinux Magazine France 78, décembre 2005, , pp. 70-86.
é [1 1] Guidon (Y.), «Comprendre lei générateurs de nombres pseudo- aléatoires», GNU/Linux Magazine Frdnce 81, mars 2006, pp. 64-76.
é [12] Thomas (G.), code source disponible à : http://dsl.ee.unsw.edu.au/dsl-cdrorn/ unsw/projects/ecosiecos/packageservices/ crc/current/src/crc I 6.c (2002)
é [13] http://en.wikipedia.org/wiki/Cyclic_ redundancy_check
• [14] Card (R.), Dumas (E.), Mével (F.),
Programmation Linux 2.0, Eyrolles, 1997, pp. 228-240.
BIBLIOGRAPHIE
• [i] MultiMediaCard Product Manual, rev. 3,
Sandisk, 07/2001, disponible à : www.fuw. edu.p1/—pablo/s/opisy/mmcprodmn_r3 I .pdf
• [2] Une des premières webcams
disponibles sur le marché, brièvement décrite à : http://www.pcworld.com/news/ article/0,aid, I 23950,pg,5,00.asp
• [3] L'alimentation sur un clavier PS2 se prend entre les broches 3 et 4 telles que définies par exemple à : http://www. burtonsys.com/PS2 keyboard and mouse mini-DIN-6_connector pinouts.html
• [4] MCF5282 Coldfire Microcontroller
User's Manual, MCF5282UM Rev. 2.3, 11/2004.
• [5] Bodor (D.), « Réalisation de circuits »,
GNU/Linux Magazine Hors-série 23,
novembre/décembre 2005, pp. 18-23.
• [6] Bodor (D.), « Programmation du port parallèle », GNUILinux Magazine Hors-série 23, novembre/décembre 2005, pp. 24-30. [7] Friedt J.-M. & Carry É., «Enregistrement de trames GPS», GNU/Linux Magazine France 81, mars 2006, pp.80-91.
• [8] Rubini (A.), Corbet (J.) & Kroah- Hartman (G.), Linux Device Drivers, 3ème éd., O'Reilly Ed., 2001, disponible à: http://lwn.net/Kernel/LDD3/
Cordialement
L'équipe Parisdepannage.fr
Hors ligne
2008 Parisdepannage |Plan du site|Forums |Blog|Lexique ![]()