Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: вопрос по драйверу последовательного порта  (Прочитано 11475 раз)
0 Пользователей и 1 Гость смотрят эту тему.
konst
Гость
« : 25-06-2004 09:28 » 

rh9 Linux 2.4.20-8
из исходников ядра взял исходник serial.c и малость подправил под свою железяку. использую как загружаемый в ядро модуль. правда создал имя mknod fscm 4 111. инициализация (имя и нумера те же, что и в mknod), завершение, open, close и ioctrl вызываются работают точно (лог пишеца). когда пытаюсь что-либо писать туда (write-ом), то write возвращает 0, а errno == 5, при этом, судя по логу, не происходит вход в функцию драйвера, отвечающую  за запись. хм...что делать?
Записан
RXL
Технический
Администратор

ru
Online Online
Пол: Мужской

WWW
« Ответ #1 : 25-06-2004 09:44 » 

konst, значит что-то ты не так сделал. Код 5 = I/O error.
Открытие делаешь для записи? Ошибки проверяешь? Хорошо бы и код посмотреть.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
konst
Гость
« Ответ #2 : 25-06-2004 09:55 » 

код из юзер-спейса:

int fd;
unsigned char t[64];
memcpy(t, teststr, 8);
write(fd, t, 8); // и не работает

ядрёного много, вроде лишнего не покоцал Улыбаюсь куда там смотреть? ну, т.е. наводящий вопрос требуеца.
Записан
konst
Гость
« Ответ #3 : 25-06-2004 09:59 » 

Код:
int fd;
unsigned char t[64];
memcpy(t, teststr, 8);
write(fd, t, 8); // и не работает
« Последнее редактирование: 28-11-2007 18:59 от Алексей1153++ » Записан
RXL
Технический
Администратор

ru
Online Online
Пол: Мужской

WWW
« Ответ #4 : 25-06-2004 12:54 » 

konst, тут не видно open() и проверку на ошибки. Во-вторых, давай код модуля.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
konst
Гость
« Ответ #5 : 25-06-2004 13:40 » 

Цитата: RXL
konst, тут не видно open() и проверку на ошибки.
тестовый пример подробнее:
Код:
static const char teststr[] = "abcdefghijklmn";
void mshowerror(int err, const char* s) {
  char t[128];
  t[0] = 0;
  strerror_r(err, t, sizeof(t));
  printf("%s #%d: \"%s\"\n", s, err, t);
}

int main(int argc, char *argv[])
{
  int fd, i;
  unsigned char t[64];

  fd = open("/dev/fscm", O_RDWR);
  if (fd != -1) {
    printf("opened\n");

    memcpy(t, teststr, 8);

    do {
      i = write(fd, t, 8);
      if (i <= 0) {
        mshowerror(-errno, "error write");
        break;
      }

      i = read(fd, t, 8);
      if (i <= 0) {
        mshowerror(-errno, "error read");
      }
    } while (0);

    close(fd);
  } else {
    mshowerror(-errno, "error opening device");
  }

  return EXIT_SUCCESS;
}
Цитата: RXL
Во-вторых, давай код модуля.
он же здоровый! вот на мой вкус критические места:
Код:
static int __init rs_init(void)
{
int i;

init_bh(SERIAL_BH, do_serial_bh);
init_timer(&serial_timer);
serial_timer.function = rs_timer;
mod_timer(&serial_timer, jiffies + RS_STROBE_TIME);

for (i = 0; i < NR_IRQS; i++) {
IRQ_ports[i] = 0;
IRQ_timeout[i] = 0;
}
 
show_serial_version();

/* Initialize the tty_driver structure */

memset(&serial_driver, 0, sizeof(struct tty_driver));
serial_driver.magic = TTY_DRIVER_MAGIC;
serial_driver.driver_name = "fscserial";
serial_driver.name = "fscm";
serial_driver.major = TTY_MAJOR;
serial_driver.minor_start = 111; // my own magic minor number
serial_driver.num = NR_PORTS;
serial_driver.type = TTY_DRIVER_TYPE_SERIAL;
serial_driver.subtype = SERIAL_TYPE_NORMAL;
serial_driver.init_termios = tty_std_termios;
serial_driver.init_termios.c_cflag =
B9600 | CS8 | CREAD | HUPCL | CLOCAL;
serial_driver.flags = TTY_DRIVER_REAL_RAW;
serial_driver.refcount = &serial_refcount;
serial_driver.table = serial_table;
serial_driver.termios = serial_termios;
serial_driver.termios_locked = serial_termios_locked;

serial_driver.open = rs_open;
serial_driver.close = rs_close;
serial_driver.write = rs_write;
serial_driver.put_char = rs_put_char;
serial_driver.flush_chars = rs_flush_chars;
serial_driver.write_room = rs_write_room;
serial_driver.chars_in_buffer = rs_chars_in_buffer;
serial_driver.flush_buffer = rs_flush_buffer;
serial_driver.ioctl = rs_ioctl;
serial_driver.throttle = rs_throttle;
serial_driver.unthrottle = rs_unthrottle;
serial_driver.set_termios = rs_set_termios;
serial_driver.stop = rs_stop;
serial_driver.start = rs_start;
serial_driver.hangup = rs_hangup;
#if (LINUX_VERSION_CODE >= 131394) /* Linux 2.1.66 */
serial_driver.break_ctl = rs_break;
#endif
#if (LINUX_VERSION_CODE >= 131343)
serial_driver.send_xchar = rs_send_xchar;
serial_driver.wait_until_sent = rs_wait_until_sent;
serial_driver.read_proc = rs_read_proc;
#endif

/*
* The callout device is just like normal device except for
* major number and the subtype code.
*/
callout_driver = serial_driver;
callout_driver.name = "fscm";
callout_driver.major = TTYAUX_MAJOR;
callout_driver.subtype = SERIAL_TYPE_CALLOUT;
#if (LINUX_VERSION_CODE >= 131343)
callout_driver.read_proc = 0;
callout_driver.proc_entry = 0;
#endif

  if (tty_register_driver(&serial_driver))
panic("Couldn't register serial driver\n");
  if (tty_register_driver(&callout_driver))
panic("Couldn't register callout driver\n");

  probe_serial_pci();

return 0;
}

static int rs_open(struct tty_struct *tty, struct file * filp)
{
struct async_struct *info;
int retval, line;
unsigned long page;

MOD_INC_USE_COUNT;
line = MINOR(tty->device) - tty->driver.minor_start;
if ((line < 0) || (line >= NR_PORTS)) {
MOD_DEC_USE_COUNT;
return -ENODEV;
}

retval = get_async_struct(line, &info);
if (retval) {
MOD_DEC_USE_COUNT;
return retval;
}
tty->driver_data = info;
info->tty = tty;
if (serial_paranoia_check(info, tty->device, "rs_open"))
return -ENODEV;
#if (LINUX_VERSION_CODE > 0x20100)
info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
#endif
/*
* This relies on lock_kernel() stuff so wants tidying for 2.5
*/
if (!tmp_buf) {
page = get_zeroed_page(GFP_KERNEL);
if (!page) 
return -ENOMEM;
if (tmp_buf)
free_page(page);
else
tmp_buf = (unsigned char *) page;
}
/*
* If the port is the middle of closing, bail out now
*/
if (tty_hung_up_p(filp) ||
    (info->flags & ASYNC_CLOSING)) {
if (info->flags & ASYNC_CLOSING)
interruptible_sleep_on(&info->close_wait);
return -EAGAIN;
}
/*
* Start up serial port
*/
retval = startup(info);
if (retval)
return retval;
retval = block_til_ready(tty, filp, info);
if (retval)
return retval;

if ((info->state->count == 1) &&
    (info->flags & ASYNC_SPLIT_TERMIOS)) {
if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
*tty->termios = info->state->normal_termios;
else
*tty->termios = info->state->callout_termios;
change_speed(info, 0);
}
info->session = current->session;
info->pgrp = current->pgrp;
set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
return 0;
}
« Последнее редактирование: 28-11-2007 19:02 от Алексей1153++ » Записан
RXL
Технический
Администратор

ru
Online Online
Пол: Мужской

WWW
« Ответ #6 : 29-06-2004 11:40 » 

konst, посмотрел. Позжее попробую разобраться.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
RXL
Технический
Администратор

ru
Online Online
Пол: Мужской

WWW
« Ответ #7 : 01-07-2004 09:25 » new

konst, как я понял, ты модифицировал стандартный драйвер? Попробуй сделать diff с оригинальным и посмотри что ты забыл проинициализировать или написать.
Предупреждаю, я сравнивал с оригинальними исходниками, а не с RH.
Мне в приведенном куске что не понравилось:
1) у тебя serial_driver.name и callout_driver.name совпадают, а в оригинале это разные имена.
2) в serial_driver.flags ты не устанавливаешь TTY_DRIVER_NO_DEVFS.
3) у тебя не инициируется поле serial_driver.name_base .
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines