Всем добрый день!
Кто-нибудь пробовал программировать LPT порт на ассемлере, обращаясь напрямую к адресам порта.
Написал прогу - компиляция проходит без ошибок. А запуск программы возвращает
segmentation fault
Может быть что-то предварительно еще надо сделать?
Подскажите, пожалуйста.
Прграммирование LPT порта (проблема)
Модератор: Модераторы разделов
-
/dev/random
- Администратор
- Сообщения: 5456
- ОС: Gentoo
Re: Прграммирование LPT порта (проблема)
nikom писал(а): ↑28.04.2008 13:13Всем добрый день!
Кто-нибудь пробовал программировать LPT порт на ассемлере, обращаясь напрямую к адресам порта.
Написал прогу - компиляция проходит без ошибок. А запуск программы возвращает
segmentation fault
Может быть что-то предварительно еще надо сделать?
Подскажите, пожалуйста.
Думаю, выходов три:
1) писать не юзерспейс-программу, а модуль ядра
2) использовать FreeDOS или какую-нибудь другую операционку, не использующую защищённый режим
3) забить на "обращения напрямую", и использовать средства, предоставляемые для этого линуксом (/dev/lp0)
ИМХО.
-
Galaxy Master
- Сообщения: 142
- ОС: Debian GNU/Linux
Re: Прграммирование LPT порта (проблема)
#include <sys/io.h>
#define base 0x378
int put2lpt(int b)
{
char x = (char) b;
int res;
if( (res = ioperm(base,1,1)) )
{
switch( errno )
{
case EINVAL:
U_Msg("EINVAL");
break;
case EIO:
U_Msg("EIO");
break;
case ENOMEM:
U_Msg("ENOMEM");
break;
case EPERM:
U_Msg("EPERM");
break;
}
return -1;
}
outb(x, base);
}
и добавим запуск от рута!
#define base 0x378
int put2lpt(int b)
{
char x = (char) b;
int res;
if( (res = ioperm(base,1,1)) )
{
switch( errno )
{
case EINVAL:
U_Msg("EINVAL");
break;
case EIO:
U_Msg("EIO");
break;
case ENOMEM:
U_Msg("ENOMEM");
break;
case EPERM:
U_Msg("EPERM");
break;
}
return -1;
}
outb(x, base);
}
и добавим запуск от рута!
-
nikom
- Сообщения: 10
Re: Прграммирование LPT порта (проблема)
Спасибо всем за ответы!
А как можно простому пользователю разрешить выполнять такие посылки в порт?
А как можно простому пользователю разрешить выполнять такие посылки в порт?
-
serg_iv
- Сообщения: 74
- ОС: ubuntu7.10
-
halturin
- Сообщения: 167
- ОС: Linux
-
Galaxy Master
- Сообщения: 142
- ОС: Debian GNU/Linux
Re: Прграммирование LPT порта (проблема)
простому пользователю надо войти в группу lp, выкинуть из головы asm и работать с /dev/parport0
если забанили на гугле могу запостить работающий пример ))))
а то что я постил выше - это неправильное идеологически развлечение близкое к asm
если забанили на гугле могу запостить работающий пример ))))
а то что я постил выше - это неправильное идеологически развлечение близкое к asm
-
MiK13
- Сообщения: 1289
- ОС: Linux Debian
Re: Прграммирование LPT порта (проблема)
Очень хотелось бы посмотреть работающий пример, а также понять как
Также хочу спросить: какие есть стандартные средства работы с последовательным портом?
Причина -- надо работать с портом RS422. Для этого надо управлять битом RTS.
1. Cбросить бит RTS
2. Отправить сообщение
3. Подождать, окончания передачи сообщения
4. Установить бит RTS.
Пока это делается таким образом
1.
ioctl(fc, TIOCMGET, &stat422);
stat422 &=~TIOCM_RTS;
ioctl(fc, TIOCMSET, &stat422);
2.
write(fc,P,6);
4.
ioctl(fc, TIOCMGET, &stat422);
stat422 |=TIOCM_RTS;
ioctl(fc, TIOCMSET, &stat422);
А вот с третим пунктом не придумал ничего кроме
3.
while ((inb(adr_com[com_num])&32)==0) ; // Подождать освобождения выходного буфера
Но для этого явно задать
int adr_com[4] = {0x3FD, 0x2FD, 0x3ED, 0x2ED};
и ещё выдать
ioperm(0x3F8,8,1);
ioperm(0x2F8,8,1);
ioperm(0x3E8,8,1);
ioperm(0x2E8,8,1);
Ну и программа должна запускаться с правами рута.
Но, может быть есть какие-то другие средства проверить, передан ли полностью пакет после команды write?
Также хочу спросить: какие есть стандартные средства работы с последовательным портом?
Причина -- надо работать с портом RS422. Для этого надо управлять битом RTS.
1. Cбросить бит RTS
2. Отправить сообщение
3. Подождать, окончания передачи сообщения
4. Установить бит RTS.
Пока это делается таким образом
1.
ioctl(fc, TIOCMGET, &stat422);
stat422 &=~TIOCM_RTS;
ioctl(fc, TIOCMSET, &stat422);
2.
write(fc,P,6);
4.
ioctl(fc, TIOCMGET, &stat422);
stat422 |=TIOCM_RTS;
ioctl(fc, TIOCMSET, &stat422);
А вот с третим пунктом не придумал ничего кроме
3.
while ((inb(adr_com[com_num])&32)==0) ; // Подождать освобождения выходного буфера
Но для этого явно задать
int adr_com[4] = {0x3FD, 0x2FD, 0x3ED, 0x2ED};
и ещё выдать
ioperm(0x3F8,8,1);
ioperm(0x2F8,8,1);
ioperm(0x3E8,8,1);
ioperm(0x2E8,8,1);
Ну и программа должна запускаться с правами рута.
Но, может быть есть какие-то другие средства проверить, передан ли полностью пакет после команды write?
-
Galaxy Master
- Сообщения: 142
- ОС: Debian GNU/Linux
Re: Прграммирование LPT порта (проблема)
...как я понял осилить гугль (а там это есть) дело непосильное.... ))))))))))
Вот кусок моего работающего кода. (программа управляет телескопом по LPT)
pp_mode - это int
parport - это int
dev_name строка в ней находится /dev/parport0,1,...
int cio_driver_lpt::open_device( void )
{
parport = open( dev_name, O_RDWR );
if( parport == -1 )
{
return 1;
}
if( ioctl( parport,PPCLAIM ) )
{
close( parport );
return 2;
}
pp_mode = IEEE1284_MODE_COMPAT;
if( ioctl( parport, PPNEGOT, &pp_mode) )
{
close( parport );
return 3;
}
// Down all pins
write_data( 0x0 );
return 0;
}
void cio_driver_lpt::close_device( void )
{
// Down all pins
write_data( 0x0 );
ioctl( parport, PPRELEASE );
close( parport );
parport = -1;
}
void cio_driver_lpt::write_data( unsigned int dByte )
{
unsigned int mapped;
mapped = bit_map_encoder[ (u_char)dByte ];
ioctl( parport, PPWDATA, &mapped );
}
И не надо никаких asm-ов, рутов и т.п. ерунды.
А чтобы понять как простому пользователю войти в группу lp надо почитать ман и вообще хоть что-то знать об этом!!!!!
(интересно как вы пользуетесь принтером или сканером или модемом или cdrom-ом или видеокартой, если не в теме про группы... а уже пытаетесь хардваре кодить....)
$groups
$man gpasswd
#gpasswd -a username lp
Вот кусок моего работающего кода. (программа управляет телескопом по LPT)
pp_mode - это int
parport - это int
dev_name строка в ней находится /dev/parport0,1,...
int cio_driver_lpt::open_device( void )
{
parport = open( dev_name, O_RDWR );
if( parport == -1 )
{
return 1;
}
if( ioctl( parport,PPCLAIM ) )
{
close( parport );
return 2;
}
pp_mode = IEEE1284_MODE_COMPAT;
if( ioctl( parport, PPNEGOT, &pp_mode) )
{
close( parport );
return 3;
}
// Down all pins
write_data( 0x0 );
return 0;
}
void cio_driver_lpt::close_device( void )
{
// Down all pins
write_data( 0x0 );
ioctl( parport, PPRELEASE );
close( parport );
parport = -1;
}
void cio_driver_lpt::write_data( unsigned int dByte )
{
unsigned int mapped;
mapped = bit_map_encoder[ (u_char)dByte ];
ioctl( parport, PPWDATA, &mapped );
}
И не надо никаких asm-ов, рутов и т.п. ерунды.
А чтобы понять как простому пользователю войти в группу lp надо почитать ман и вообще хоть что-то знать об этом!!!!!
(интересно как вы пользуетесь принтером или сканером или модемом или cdrom-ом или видеокартой, если не в теме про группы... а уже пытаетесь хардваре кодить....)
$groups
$man gpasswd
#gpasswd -a username lp
-
amaora
- Сообщения: 95
- ОС: Slackware
-
halturin
- Сообщения: 167
- ОС: Linux
Re: Прграммирование LPT порта (проблема)
в 2.6 вродь что-то менялось, но думаю взяв на вооружение предыдущую ссылку (правда она древняя), плюс вот эту http://www.epanorama.net/circuits/parallel_output.html найдешь решение.