Я разрабатываю модуль ядра для настраиваемого устройства, которое на самом деле представляет собой 4 * 8-битные порты i-o, подключенные к шине ISA с адресами 0x0120 - 0x0123. Этот драйвер основан на «черепахе» Алессандро Рубини и Джонатана Корбе. Моя ОС - Ubuntu 10.04, ядро - 2.6.32-74 generic, я использую встроенный консольно-ориентированный компилятор gcc. Теперь модуль успешно загружается и выгружается, функции чтения и записи реализованы. Чтение из файла устройства я реализовал так:Данные не могут быть записаны в файл устройства из программы пользовательского пространства
gboolean DataRead (GtkWidget *widget, gpointer data)
{
GtkWidget *statusbar = GTK_WIDGET(data);
g_assert(statusbar != NULL);
gchar *StatusText = "Reading data from ADC F-4226";
gtk_statusbar_remove (GTK_STATUSBAR(statusbar), StatusBarContext, MessageId);
StatusBarContext = gtk_statusbar_get_context_id (GTK_STATUSBAR(statusbar), "ET3201-read");
MessageId = gtk_statusbar_push (GTK_STATUSBAR(statusbar), StatusBarContext, StatusText);
ERR = NULL;
gchar *contents;
gsize *length = NULL;
gboolean ReadOK = FALSE;
ReadOK = g_file_get_contents (DevFile, &contents, length, &ERR);
if (ReadOK) StatusText = contents;
else
{
g_warning ("Can't open ET3201: %s", ERR->message);
StatusText = g_strdup_printf("Error!!! %s: %d, %s", g_quark_to_string (ERR->domain), ERR->code, ERR->message);
g_error_free(ERR);
}
gtk_statusbar_remove (GTK_STATUSBAR(statusbar), StatusBarContext, MessageId);
StatusBarContext = gtk_statusbar_get_context_id (GTK_STATUSBAR(statusbar), "ET3201-read");
MessageId = gtk_statusbar_push (GTK_STATUSBAR(statusbar), StatusBarContext, StatusText);
g_free(contents);
}
return ReadOK;
}
и все работает, статусный отображает строку, которая считывается из устройства. Но когда я попытался написать файл устройства - проблема возникает. Моя функция, которая записывает файл устройства, всегда сообщает об ошибке.
GError * on_BnStop_clicked (GtkButton *button, gpointer data) { char Data = 255; FILE * ET3201 = NULL; char buf; ERR = NULL; GtkWidget *label = GTK_WIDGET(data); g_assert(label != NULL); if (Started) Started = FALSE; if (! Started) Data = 0; /* FOR TESTING ONLY!!!*/ gchar *LabelText = "STOP"; gtk_label_set_text(GTK_LABEL(label), LabelText); errno = 0; ET3201=fopen(DevFile,"w");/* Opening the device ET3201 */ ErrorCode = errno; if (ET3201 == NULL) { ERR = g_error_new (G_FILE_ERROR, G_FILE_ERROR_NXIO, "Can't open port ET3201!"); goto fail; } setvbuf(ET3201,&buf,_IONBF,1); /* We remove the buffer from the file i/o */ fwrite(&Data,1,1,ET3201); /* Writing to device*/ sleep(1); fclose(ET3201); /* g_free(&buf); - leading to "Program aborted" */ fail: return ERR; }
-Так как ET3201 == NULL постоянно. На этом этапе загружается модуль ядра и чтение из него в порядке. После отладки я обнаружил, что функция «Write» в модуле ядра никогда не вызывается, так как она не печатает соответствующее сообщение «printk» в журнале ядра. В отчаянии я попытался сделать это следующим образом:
GError * on_BnStart_clicked (GtkButton *button, gpointer data)
{
gchar *contents;
gssize length = 0;
ERR = NULL;
GtkWidget *label = GTK_WIDGET(data);
g_assert(label != NULL);
if (! Started) Started = TRUE;
gchar *LabelText = "RUN";
gtk_label_set_text(GTK_LABEL(label), LabelText);
contents = g_strdup_printf("/255"); /*FOR TESTING PURPOSES!!!*/
length = sizeof(contents);
g_file_set_contents (DevFile, contents, length, &ERR);
return ERR;
}
и я получаю сообщение об ошибке в статусной: Ошибка: г-файл ошибок кварка: 2, Не удалось создать файл «/dev/ET32010.* *** 8X ': Permission denied Я думаю, это потому, что g_file_set_contents записывает во временный файл, а затем пытается переименовать его в файл устройства, получив «Permission denied». Возможно, это неправильный способ записи файлов устройств, пожалуйста, помогите мне найти правильный ...
Мои вопросы: Почему моя функция on_BnStop_clicked не работает должным образом? Как сделать правильную запись в файл устройства char из программы пользовательского пространства?
Я проверил прав доступа устройство ...
[email protected]:~$ ls -l /dev/ET3201*
lrwxrwxrwx 1 root root 7 2015-11-23 14:34 /dev/ET3201 -> ET32010
crw-rw-r-- 1 root staff 250, 0 2015-11-23 14:34 /dev/ET32010
crw-rw-r-- 1 root staff 250, 1 2015-11-23 14:34 /dev/ET32011
crw-rw-r-- 1 root staff 250, 2 2015-11-23 14:34 /dev/ET32012
crw-rw-r-- 1 root staff 250, 3 2015-11-23 14:34 /dev/ET32013
затем измененный режим в ядре модуль инициализации сценария 666
lrwxrwxrwx 1 root root 7 2015-11-23 22:27 /dev/ET3201 -> ET32010
crw-rw-rw- 1 root staff 250, 0 2015-11-23 22:27 /dev/ET32010
crw-rw-rw- 1 root staff 250, 1 2015-11-23 22:27 /dev/ET32011
crw-rw-rw- 1 root staff 250, 2 2015-11-23 22:27 /dev/ET32012
crw-rw-rw- 1 root staff 250, 3 2015-11-23 22:27 /dev/ET32013
и on_BnStart_clicked функция вернула «Отказано в доступе», как это было раньше , но on_BnStop_clicked вывел метод «Write» модуля ядра, а затем успешно завершил работу с ERR == NULL. В конце концов, функция отчетов об ошибках разбилась на «Ошибка сегментации» (сообщение ERR == NULL), но я уже исправил эту ошибку.
У вас есть проверка того, что ваш пользователь может писать в файл? Вы проверяли значение errno, когда fopen терпит неудачу? – jku