OVH Cloud OVH Cloud

Synchro ioctl

2 réponses
Avatar
Ronan COLMOU
Bonjour,
J'écris un driver pour un LCD sur //. Je souhaite programmer
l'applicatif en Perl.
Lors de l'application du code suivant :

# On affiche la version
ioctl (LCD, $nbioctl{"LCD_PLACE_CURSEUR"},1);
print LCD "-->Lcd Status<--";
ioctl (LCD, $nbioctl{"LCD_PLACE_CURSEUR"},17);
print LCD "--> ver 0.8 <-- ";

sleep(2);

je récupère le log suivant du driver :

lcd_open
LCD_CLEAR ioctl request
LCD_PLACE_CURSEUR ioctl : position : 1
LCD_PLACE_CURSEUR ioctl : position : 41
lcd_write
lcd_release

En gros : les 2 ioctl sont exécutées l'une après l'autre, et le premier
PRINT est exécuté ensuite. Le second PRINT n'est jamais exécuté. D'autre
part, le sleep est exécuté AVANT les 2 ioctls.

Je ne comprends pas trop ce qui se passe.
Pouvez-vous me tuyauter ?
Merci d'avance.

2 réponses

Avatar
Jedaï
Ronan COLMOU wrote:

Bonjour,
J'écris un driver pour un LCD sur //. Je souhaite programmer
l'applicatif en Perl.
Lors de l'application du code suivant :

# On affiche la version
ioctl (LCD, $nbioctl{"LCD_PLACE_CURSEUR"},1);
print LCD "-->Lcd Status<--";
ioctl (LCD, $nbioctl{"LCD_PLACE_CURSEUR"},17);
print LCD "--> ver 0.8 <-- ";

sleep(2);

je récupère le log suivant du driver :

lcd_open
LCD_CLEAR ioctl request
LCD_PLACE_CURSEUR ioctl : position : 1
LCD_PLACE_CURSEUR ioctl : position : 41
lcd_write
lcd_release

En gros : les 2 ioctl sont exécutées l'une après l'autre, et le premier
PRINT est exécuté ensuite. Le second PRINT n'est jamais exécuté. D'autre
part, le sleep est exécuté AVANT les 2 ioctls.

Je ne comprends pas trop ce qui se passe.
Pouvez-vous me tuyauter ?
Merci d'avance.



Les I/O Perl standards fonctionne avec un tampon, pour forcer un flush
de ce tampon à chaque écriture avec print, il faut positionner la
variable $| à 1 pour le handle de fichier concerné, on peut faire ainsi :
select( (select(LCD), $|=1)[0] );
c'est un dialecte couramment rencontré, pour faire plus propre, on peut
faire ainsi :
my $oldhandle = select(LCD);
$|=1;
select( $oldhandle );

Et si tu veux que ça soit encore plus propre, tu peux faire ça :
use IO::Handle;
open LCD, blabla...;
LCD->autoflush();

Pas mal de module hérite de IO::Handle, donc vérifie que tu n'en as pas
déjà un de chargé. :)

Dans ton cas particulier, les deux print devaient être exécutés en une
fois (donc un seul lcd_write), par contre je ne sais pas pourquoi le
sleep n'était pas au bon endroit... Essaie déjà de mettre l'autoflush,
on verra si tu as encore un problème. :)

--
Jedaï

Avatar
Ronan COLMOU
Je me la suis fait avec l'"autoflush", et ça marche nickel ! (les IOCTL
fonctionnent et le sleep se comporte de nouveau comme attendu).

Merci beaucoup !


Jedaï wrote:
Ronan COLMOU wrote:

Bonjour,
J'écris un driver pour un LCD sur //. Je souhaite programmer
l'applicatif en Perl.
Lors de l'application du code suivant :

# On affiche la version
ioctl (LCD, $nbioctl{"LCD_PLACE_CURSEUR"},1);
print LCD "-->Lcd Status<--";
ioctl (LCD, $nbioctl{"LCD_PLACE_CURSEUR"},17);
print LCD "--> ver 0.8 <-- ";

sleep(2);

je récupère le log suivant du driver :

lcd_open
LCD_CLEAR ioctl request
LCD_PLACE_CURSEUR ioctl : position : 1
LCD_PLACE_CURSEUR ioctl : position : 41
lcd_write
lcd_release

En gros : les 2 ioctl sont exécutées l'une après l'autre, et le
premier PRINT est exécuté ensuite. Le second PRINT n'est jamais
exécuté. D'autre part, le sleep est exécuté AVANT les 2 ioctls.

Je ne comprends pas trop ce qui se passe.
Pouvez-vous me tuyauter ?
Merci d'avance.



Les I/O Perl standards fonctionne avec un tampon, pour forcer un flush
de ce tampon à chaque écriture avec print, il faut positionner la
variable $| à 1 pour le handle de fichier concerné, on peut faire ainsi :
select( (select(LCD), $|=1)[0] );
c'est un dialecte couramment rencontré, pour faire plus propre, on peut
faire ainsi :
my $oldhandle = select(LCD);
$|=1;
select( $oldhandle );

Et si tu veux que ça soit encore plus propre, tu peux faire ça :
use IO::Handle;
open LCD, blabla...;
LCD->autoflush();

Pas mal de module hérite de IO::Handle, donc vérifie que tu n'en as pas
déjà un de chargé. :)

Dans ton cas particulier, les deux print devaient être exécutés en une
fois (donc un seul lcd_write), par contre je ne sais pas pourquoi le
sleep n'était pas au bon endroit... Essaie déjà de mettre l'autoflush,
on verra si tu as encore un problème. :)

--
Jedaï