Je ne sais plus si normalement il devrait jeter les octets qu'il
recoit en trop ou s'il est en mesure de bloquer l'ecriture depuis
l'ordinateur. S'il les jete, j'ai du ecrire une fonction genre
nx_usb_overloaded() pour savoir si ca se produit ... mais mes
souvenirs a ce sujet ne sont plus tres frais, je vais tacher de
regarder ca une fois rentre chez moi.
> Si ce n'est pas le cas je ne vois pas comment gérer l'envoi
> de plusieurs entiers par exemple, sans mette de wait coté pc.
>
Je suggererais l'etablissement d'un protocole avec envoi et accuse de reception.
Genre le PC envoi, la brique traite et renvoit un accuse de reception
pour demander la suite. (je sais pas si c'est cette attente d'accuse
de reception que tu appelles un wait() ?)
> Et si ce
> n'est pas le cas je ne vois pas l'utilité de ce paramètre size.
>
> Après ca arrive la seconde question... je me dis cool je vais
> reprendre le script python de la console, l'adapter un peu et envoyer
> 1 entier sur 4 octet donnant la taille du fichier puis ensuite
> télécharger le fichier sur la brick après avoir alloué dynamiquement
> la mémoire.
>
> Mon problème est que je n'arrive pas à envouer un entier de 4 octet
> depuis python.
>
> J'utilise :
>
> while not (brick.write(...)):
> time.sleep(1)
>
> La fonction write prend apparement comme paramètre une séquence. A
> priori elle servait à envoyer les commandes, chaine de caractère donc.
> Je me suis dit, aller j'envoi un tableau : [12] , ca marche. Mais la
> fonction n'envoi qu'un octet. Je test [123456789] bien sur codé sur
> largement plus d'un octet (4 je crois), et ma brick ne reçois qu'un
> octet.
>
Euf, je dirais, essaye un tableau de 4 elements d'un octet chacun.
Mais la encore je me souviens plus precisement comment le code python
marche.
> Conclusion, je suis dans une impasse :)
>
Mais non mais non ... :)
> Sinon j'en profite pour signaler une erreur dans le kernel de tests je
> crois :
>
> void tests_usb(void) {
> U16 i;
> U32 lng = 0;
>
> char buffer[NX_USB_PACKET_SIZE];
>
> hello();
>
> while(1) {
> nx_display_cursor_set_pos(0, 0);
> nx_display_string("Waiting command ...");
>
> nx_usb_read((U8 *)&buffer, NX_USB_PACKET_SIZE * sizeof(char)); //
> <---------------- (U8*)buffer me semble plus approprié, mais
> apparement ca n'a pas d'influence, si quelqu'un sait pourquoi...
> ...
>
Parce-que le tableau 'buffer' est "alloue" sur la stack de la
fonction. Ce n'est donc pas un pointeur vers un tableau alloue
dynamiquement mais directement le tableau lui-meme. Et donc en
utilisant '&' tu obtiens un pointeur vers le debut de ce tableau.
Tu peux essayer sans '&' si tu veux : si ma theorie est juste, ca
devrait planter, parce-qu'il va alors considerer les 4 premiers octets
du tableau comme un pointeur.
> }
>
> ...
>
> }
>
> Merci d'avance pour votre aide !
>
> Alexandre H.
PS: Desole pour les accents manquants, mais je suis sur un clavier
qwerty actuellement.
Beaucoup plus simple: utilise le module struct. C'est un module qui
permet de sérialiser/désérialiser des types fondamentaux du C. Il est
utilisé pour parser des protocoles binaires (je m'en suis par exemple
déjà servi pour décortiquer des trames ethernet), et peut également
construire des messages binaires. Il sait encoder des entiers 32 bits,
et est même au courant des questions d'endianness.
http://docs.python.org/lib/module-struct.html
En gros:
import struct
bin = struct.pack('<L', 12345)
te donnera la séquence d'octets correspondant au nombre 12345, au
format unsigned long int (32 bits), au format little-endian. De même,
struct.unpack te permttra de faire l'opération inverse, et
struct.calcsize te dire combien d'octets fait une sérialisation
donnée.
> J'ai des gros doutes la dessus. Un tableau est un pointeur sur son
> premier élément.
> Essaye de faire :
>
> void func(char* t)
> {
>
> }
>
> char tab[10];
> func(&tab);
>
> Tu auras un problème de typage car tu passes un char**
> Cette erreur est masquée par le cast dans le code NxOS : (U8 *)&buffer
>
> Ca doit marcher parceque, ... ne me demande pas pourquoi :), c'est un
> détail d'implémentation dont je n'ai pas connaissance. Mais en tout
> cas je ne crois pas que ce soit la notation correcte.
Je n'ai pas le code sous la main, mais si buffer est effectivement un
tableau, et si la fonction prend un U8*, alors on a effectivement un
problème :-). Et, comme Jérôme, je ne suis pas sur de comprendre
comment ca a bien pu marcher jusqu'à présent s'il y a effectivement un
bug là. J'étudierai ça plus en détails ce soir.
Voila, mon humble contribution ici, mais pour les questions qui
touchent à l'USB, c'est Jérôme l'expert, pas moi :-).
- Dave
Je vais me pencher la dessus, c'est vraiment pas normal que ca puisse
marcher. Et comme je suis à la recherche de possibles corruptions de
mémoire dans les pilotes, qui entraineraient un plantage de mon
scheduler, ce genre de bug m'intéresse fortement :P
> Une idée pour éviter le débordement lors de l'envoi de plus de size
> octets ?
Jérôme? Je n'ai pas trop suivi ce qui se passe la avec le driver USB.
- Dave