Форум по операционной системе GNU/Linux и свободному программному обеспечению
Текущее время: 18 фев 2019, 07:48

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 21 ]  На страницу 1, 2, 3  След.
Автор Сообщение
 Заголовок сообщения: драйвер , обновление информации
Непрочитанное сообщениеДобавлено: 17 фев 2017, 21:14 
Не в сети
Интересующийся

Зарегистрирован: 17 фев 2017, 20:20
Сообщения: 8
Добрый вечер .
Мною был написан драйвер для ISA устройства .
Драйвер работает , но есть одна проблема .
Простенькая программа читает данные из драйвера , но обновляются данные только если разкомментировать freopen();
Код:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

char name[]="/proc/ISA_TIME";
char str[]="day 000 run 00 hour 00 min 00 sec 00 msec 0000 irq 0 \n      ";
FILE * dfd;
unsigned int uistrlen;

int main(void){
uistrlen=strlen(str);
dfd=fopen(name,"r");
if(dfd==NULL){
  printf("open device error\n");
  exit(0);
  };
while(1){
  sprintf(str,"day 000 run 00 hour 00 min 00 sec 00 msec 0000 irq 0 ");
  fgets(str,uistrlen,dfd);
  //freopen(name,"r",dfd);
  fseek(dfd,0,SEEK_SET);
  printf("%s\n",str);
  usleep(100000);
  };
fclose(dfd);
return(0);
}

cat /proc/ISA_TIME работает .
строка обновляется по прерыванию от устройства .
Код:
static irqreturn_t ISATIME_irq_handler(int irq,void *dev_id){
set3=inw(0x326);
irqgen=set3>>12;
if(irqgen>0){
  set0=inw(0x320);
  set1=inw(0x322);
  set2=inw(0x324);
  den=((set0>>14)&0x3)*100+((set0>>10)&0xf)*10+((set0>>6)&0xf);
  tmp=((set0&0x3)<<2)|((set1>>14)&0x3);
  chas=tmp+((set0>>2)&0x3)*10;
  min=((set1>>10)&0x7)*10+((set1>>6)&0xf);
  tmp=((set1&0x3)<<2)|((set2>>14)&0x3);
  sec=((set1>>2)&0x7)*10+tmp;
  msec=((set2>>10)&0xf)*100+((set2>>6)&0xf)*10+((set2>>2)&0xf);
  mksec=set3&0xf;
  run=chas*4;
  if(min<15)             run=run+1;
  if((min>=15)&(min< 30))run=run+2;
  if((min>=30)&(min< 45))run=run+3;
  if((min>=45)&(min<=59))run=run+4;
  inw(0x328);
  sprintf(str,"day %03d run %02d hour %02d min %02d sec %02d msec %04d irq %1x\n",den,run,chas,min,sec,msec,irqgen);
  return IRQ_HANDLED;
  }else{
  return IRQ_NONE;
  };
}

код обработки чтения :
Код:
static ssize_t proc_node_read(char *buffer,char **start,off_t off,int count,int *eof,void *data){
  static int offset=0,i;
  //printk( KERN_INFO "read: %d\n", count );
  for(i=0;(offset<=len)&&('\0'!=str[offset]);offset++,i++)
    *(buffer+i)=str[offset];
  *(buffer+i)='\n';
  i++;
  if((offset>=len)||('\0'==str[offset])){
    offset=0;
    *eof=1;
  }else{
    *eof=0;
  };
  //printk( KERN_INFO "return bytes: %d\n", i );
  //if(*eof!=0)printk(KERN_INFO "EOF\n");
  return i;
};
хотя пробовал и такой :
[code]
static ssize_t device_read(struct file * file,char * buf,size_t count,loff_t *ppos){
if(count<len)return -EINVAL;
if(*ppos!=0){return 0;};
if(copy_to_user((void*)buf,str,len))return -EINVAL;
//printk("ISA module : copy to user Ok\n");
*ppos=len+1;
//*ppos=0;
returned=count;
return returned;
}
результат одинаковый .
[/code]


Вернуться к началу
 Профиль Отправить личное сообщение Отправить email  
 
Непрочитанное сообщениеДобавлено: 17 фев 2017, 21:23 
Не в сети
Писатель
Аватара пользователя

Зарегистрирован: 24 сен 2011, 14:22
Сообщения: 11512
Откуда: Харьков
Вы полный архив .tgz прикрепите к сообщению, чтобы предметно обсуждать, конкретно (там достаточно много вопросов).

1. По 1-му впечатлению, ваше устройство после 1-го чтения устанавливает признак EOF.

2. Зачем это вы придумали "устройство" создать по такому дикому пути?
Код:
"/proc/ISA_TIME"


Цитата:
Мною был написан драйвер для ISA устройства .

3. ISA устройства не должны разделять IRQ-линию.

Цитата:
cat /proc/ISA_TIME работает .
строка обновляется по прерыванию от устройства .

4. Скопируйте с терминала как это выглядит - вот с этого и нужно начинать.


Вернуться к началу
 Профиль Отправить личное сообщение Отправить email  
 
Непрочитанное сообщениеДобавлено: 17 фев 2017, 22:17 
Не в сети
Интересующийся

Зарегистрирован: 17 фев 2017, 20:20
Сообщения: 8
Olej писал(а):
Вы полный архив .tgz прикрепите к сообщению, чтобы предметно обсуждать, конкретно (там достаточно много вопросов).
1. По 1-му впечатлению, ваше устройство после 1-го чтения устанавливает признак EOF.
2. Зачем это вы придумали "устройство" создать по такому дикому пути?
Код:
"/proc/ISA_TIME"


туда его закидывает :
Код:
#define DEV_NAME "ISA_TIME"
...
create_proc_read_entry(DEV_NAME,0,NULL,proc_node_read,NULL)

как объяснить системе место в иерархии я ещё не разбирался .
Цитата:
3. ISA устройства не должны разделять IRQ-линию.

оно не разделяет . промышленный компьютер . линия прерывания зарезервирована для шины isa в биосе .
Цитата:
4. Скопируйте с терминала как это выглядит - вот с этого и нужно начинать.

работа cat-а :
Изображение

программа без freopen() :
Изображение

программа с freopen() :
Изображение

irq - эти тип прерывания внутри устройства , не обращайте внимания .


Вложения:
Комментарий к файлу: последняя версия
drv009.zip [3.5 КБ]
Скачиваний: 46
Вернуться к началу
 Профиль Отправить личное сообщение Отправить email  
 
Непрочитанное сообщениеДобавлено: 18 фев 2017, 09:49 
Не в сети
Писатель
Аватара пользователя

Зарегистрирован: 24 сен 2011, 14:22
Сообщения: 11512
Откуда: Харьков
Kurenya писал(а):
Драйвер работает , но есть одна проблема .
Простенькая программа читает данные из драйвера , но обновляются данные только если разкомментировать freopen();

Я так предполагаю, что вы просто ловите EOF при всех чтениях после 1-го, а не изменяющийся "результат" str[] - это просто мусор, застрявший там после 1-го чтения.
Код:
[olej@dell Linux.books.own]$ man fgets
...
fgets() reads in at most one less than size characters from stream and stores them into the buffer pointed to by s.   Read‐
       ing  stops  after an EOF or a newline.

- поменяйте (временно) fgets() на fread(), то же самое, но нагляднее:
Код:
fread()  does  not distinguish between end-of-file and error, and callers must use feof(3) and ferror(3) to determine which
       occurred.

- анализируйте EOF после каждого чтения ...
- очистите str[] после каждого чтения...

И наблюдайте ;-)


Вернуться к началу
 Профиль Отправить личное сообщение Отправить email  
 
Непрочитанное сообщениеДобавлено: 18 фев 2017, 10:12 
Не в сети
Писатель
Аватара пользователя

Зарегистрирован: 24 сен 2011, 14:22
Сообщения: 11512
Откуда: Харьков
Не делайте (и не показывайте) эти вот не нужные телодвижения:
Код:
# ./test

Куда понятнее и нагляднее нормальная команда, которая и есть ваш test:
Код:
# cat /proc/ISA_TIME

(и скриншоты вкопировать не есть хорошая практика - куда проще и нагляднее 1-2 строчки скопировать с терминала и вставить под тэгом code).

Но сама идея (архитектурно) отображение быстро меняющихся данных, и вообще передачу пользовательских данных сделать через /proc - неудачная.
Куда лучше это сделать через драйвер символьного (байтового) устройства в /dev.
Или, на худой конец, это временами делают через /sys.

Кроме того, может быть много мелких замечаний по вашему драйверу:

1. Не нужно при open() (функция device_open()) делать:
Код:
try_module_get()

И соответственно, при close():
Код:
module_put()

Дефаултные реализации операций open()/close() сделают это по умолчанию.

2. И, как следствие, вашему драйверу вообще не нужны реализации open()/close() - пусть используются дефаултные.

3.
Цитата:
Цитата:
ISA устройства не должны разделять IRQ-линию.

оно не разделяет . промышленный компьютер . линия прерывания зарезервирована для шины isa в биосе .

Я написал "не может разделять" к тому, что ваш обработчик прерываний не может возвращать разные значения кода возврата:
Код:
...
  return IRQ_HANDLED;
  }else{
  return IRQ_NONE;
  };

Он должен обрабатывать прерывание безусловно и всегда (IRQ_HANDLED). Он никогда не может передавать обработку (IRQ_NONE) другому обработчику того же IRQ (как это и сделано для PCI устройств).

Ну и конечно ... стиль написания кода :-o - отступы от уровней структурной вложенности :cry:
Это, может, и "мелочь", но разобраться в такой мелочи и не понаделать лишних ошибок - невозможно, при чуть более-менее сложном коде.


Вернуться к началу
 Профиль Отправить личное сообщение Отправить email  
 
Непрочитанное сообщениеДобавлено: 19 фев 2017, 04:12 
Не в сети
Интересующийся

Зарегистрирован: 17 фев 2017, 20:20
Сообщения: 8
Olej писал(а):
Но сама идея (архитектурно) отображение быстро меняющихся данных, и вообще передачу пользовательских данных сделать через /proc - неудачная.
Куда лучше это сделать через драйвер символьного (байтового) устройства в /dev.
Или, на худой конец, это временами делают через /sys.

первая версия драйвера была через /dev .
из /dev инфа читается только если программа запущена с root правами .

само физическое устройство может работать в нескольких режимах .
из них только работа прерыванием на каждую миллисекунду можно считать частым .

Olej писал(а):
Кроме того, может быть много мелких замечаний по вашему драйверу:

1. Не нужно при open() (функция device_open()) делать:
Код:
try_module_get()

И соответственно, при close():
Код:
module_put()

Дефаултные реализации операций open()/close() сделают это по умолчанию.

2. И, как следствие, вашему драйверу вообще не нужны реализации open()/close() - пусть используются дефаултные.

3.
Цитата:
Цитата:
ISA устройства не должны разделять IRQ-линию.

оно не разделяет . промышленный компьютер . линия прерывания зарезервирована для шины isa в биосе .

Я написал "не может разделять" к тому, что ваш обработчик прерываний не может возвращать разные значения кода возврата:
Код:
...
  return IRQ_HANDLED;
  }else{
  return IRQ_NONE;
  };

Он должен обрабатывать прерывание безусловно и всегда (IRQ_HANDLED). Он никогда не может передавать обработку (IRQ_NONE) другому обработчику того же IRQ (как это и сделано для PCI устройств).

Ну и конечно ... стиль написания кода :-o - отступы от уровней структурной вложенности :cry:
Это, может, и "мелочь", но разобраться в такой мелочи и не понаделать лишних ошибок - невозможно, при чуть более-менее сложном коде.

1.2.знаю уже . это остаток от /dev варианта .
3.это я проверял версию того , что кроме устройства кто-то ещё дёргает прерывание .

вот как раз с таким стилем ещё ни разу не было путаницы . :)
вы не поверите с каким чужим кодом приходится работать - "go to" в коде , без отступов и форматирования вообще .


Вернуться к началу
 Профиль Отправить личное сообщение Отправить email  
 
Непрочитанное сообщениеДобавлено: 19 фев 2017, 07:58 
Не в сети
Писатель
Аватара пользователя

Зарегистрирован: 24 сен 2011, 14:22
Сообщения: 11512
Откуда: Харьков
Kurenya писал(а):
первая версия драйвера была через /dev .
из /dev инфа читается только если программа запущена с root правами .

Этому делу легко помочь ;-) : написать правила udev для этого устройства в /etc/udev/rules.d
Но это более "цивильный" подход: устройство, создающее поток байт, отображается в /dev

Kurenya писал(а):
само физическое устройство может работать в нескольких режимах .
из них только работа прерыванием на каждую миллисекунду можно считать частым .

Я неточно выразился, вопрос не в том, насколько часто, а в том что периодически ... или даже точнее - асинхронно: если даже устройство генерирует данные, то это - устройство, а /proc - это инструмент для диагностики (и иногда управления) некоторыми переменными состояниями ядра (и модулей в частном случае).
Может быть, конечно, и так ... но это несколько нарушает логику, для того, кто будет работать с этим "со стороны".


Вернуться к началу
 Профиль Отправить личное сообщение Отправить email  
 
Непрочитанное сообщениеДобавлено: 19 фев 2017, 08:06 
Не в сети
Писатель
Аватара пользователя

Зарегистрирован: 24 сен 2011, 14:22
Сообщения: 11512
Откуда: Харьков
Kurenya писал(а):
вот как раз с таким стилем ещё ни разу не было путаницы . :)
вы не поверите с каким чужим кодом приходится работать - "go to" в коде , без отступов и форматирования вообще .

Вот как-раз с go to в коде ядра/модулей как-раз всё в порядке - там их миллион, и там это хороший стиль - вся обработка ошибочных ситуаций.

Но я не имел в виду вообще "кодестайл" и "говнокод", по которым сопли льют юные дарования на интернет-ресурсах.
Пишите как хотите и как удобно.
Но структурные отступы уровней не соблюдать на структурном языке C не соблюдать? ... это не комильфо.
Смотреть такой чужой код невозможно.
Пишите тогда в одну строчку, без переносов строк - ещё круче станет смотреться. :lol:
(кстати, в последнем развитии линии C/C++ языков Go как раз пошли, наконец, в этом направлении, что потребовали соблюдать синтаксически некоторую структурность текста + придали смысл переносам строк ... не Python, конечно, но подвижки в этом направлении)


Вернуться к началу
 Профиль Отправить личное сообщение Отправить email  
 
Непрочитанное сообщениеДобавлено: 20 фев 2017, 11:51 
Не в сети
Интересующийся

Зарегистрирован: 17 фев 2017, 20:20
Сообщения: 8
получилось с обновлением так :
Код:
...
char str[]="day 000 run 00 hour 00 min 00 sec 00 msec 0000  ";
len=strlen(str);
...
while(){
  ...
  fread(str,len,1,dfd);
  fseek(dfd,0,SEEK_SET);
  ...
  };

размер буфера должен быть чуть больше принимаемой строки .
если сделать большим считывается хлам какой-то .
осталось понять почему так происходит и чем провинился fgets() .


Вернуться к началу
 Профиль Отправить личное сообщение Отправить email  
 
Непрочитанное сообщениеДобавлено: 20 фев 2017, 12:40 
Не в сети
Писатель
Аватара пользователя

Зарегистрирован: 24 сен 2011, 14:22
Сообщения: 11512
Откуда: Харьков
Kurenya писал(а):
осталось понять почему так происходит и чем провинился fgets() .

Потому, что ваша операция в модуле возвращает строку без завершающего '\0'.


Вернуться к началу
 Профиль Отправить личное сообщение Отправить email  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 21 ]  На страницу 1, 2, 3  След.

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
cron
Создано на основе phpBB® Forum Software © phpBB Group
Русская поддержка phpBB
[ Time : 0.134s | 17 Queries | GZIP : On ]