2015-02-12 1 views
1

Итак, у меня есть RTC, подключенный к моей beaglebone, и он отлично работает через cat'ing /sys/class/rtc/rtx(x)/time file, однако мой код C для контроля времени ошибка, которую я не могу решить.open(): занято устройство или ресурс (/ dev/rtc (x))

if ((rtc_fd = open(RTC, O_RDONLY, 444)) < 0) 
    REPORT_ERROR("open(RTC)"); 

где RTC путь к /dev/rtc1. REPORT_ERROR - макрофункция для сообщения пользовательских ошибок.

В любом случае, я запускаю этот код непосредственно перед циклом for с 10 итерациями и выводит его в файл журнала. Я всегда получаю сообщение strerror(perror): Устройство или ресурс занят Но тогда он по-прежнему дает мне мои 10 выходов, которые являются правильными.

Я использую в конце close().

Что дает?

Редактирование: Возможно, я должен добавить, что это работает в процессе daemonized, и я использую iocotl() с RTC_RD_TIME во время цикла.

#define REPORT_ERROR(X) do {\ 
     fprintf(log,"[email protected] "X": %[email protected] %s:%d\n",\ 
     strerror(errno), __FILE__, __LINE__ - 1);\ 
     exit(EXIT_FAILURE);\ 
     } while(0) 

#define RTC "/dev/rtc1" 

int main(void) 
{ 
    int rtc_fd; 
    FILE *log; 
    struct rtc_time tm; 

    if ((log = fopen(LOG_FILE, "a+")) == NULL) 
     exit(EXIT_FAILURE); 

    if ((dup2(fileno(log), STDERR_FILENO)) < 0) 
     REPORT_ERROR("dup2()"); 

    if ((rtc_fd = open(RTC, O_RDONLY, 444)) < 0) 
     REPORT_ERROR("open(RTC)"); 

    /* Main loop */ 
    for (int i = 0; i < 10; ++i) 
    { 
     if ((ioctl(rtc_fd, RTC_RD_TIME, &rtctime)) != 0) 
      REPORT_ERROR("ioctl(rtc_fd)"); 

     fprintf(log, "%02d:%02d:%02.lf %d-%d-%d\n", tm.hour, tm.minute, 
       tm.second, tm.mon + 1, tm.mday, tm.year + 1900); 
     sleep(1); 
    } 

    close(rtc_fd); 
    return 0; 
} 

ВЫВОД:

[email protected] open(RTC): Device or resource [email protected] ha-daemon.c:80 
05:06:09 2-12-2015 
05:06:10 2-12-2015 
05:06:11 2-12-2015 
05:06:12 2-12-2015 
05:06:13 2-12-2015 
05:06:14 2-12-2015 
05:06:15 2-12-2015 
05:06:16 2-12-2015 
05:06:17 2-12-2015 
05:06:18 2-12-2015 
+0

Пожалуйста, создайте [Минимальный, полный и проверенный пример] (http: // stackoverflow.com/help/mcve) и показать нам. –

+0

Вы пытались открыть свое устройство по всему миру? – Shehryar

+0

Что касается вашей фактической проблемы (открытие устройства), вы уверены, что никакой другой процесс не имеет того же самого устройства, которое уже открыто? –

ответ

1

Это не совсем ответ, но мои права на этот вопрос было отклонено с комментарием, что я должен опубликовать его в качестве ответа вместо. Итак, вот оно.

Код, как указано, не компилируется. Я изменил его минимально так, чтобы он компилировался без предупреждений, и я могу проверить его. Вот список изменений. Некоторые из них могут быть специфическими для моего окружения (GCC 4.8.1/Ubuntu Linux 14,04/x86-64):

  • добавил все недостающие #include s
  • определяется LOG_FILE, определив его как /dev/tty просто делает тестирование легче
  • заменил /dev/rtc1 на /dev/rtc0 (у меня нет rtc1)
  • заменил &rtctime (последний аргумент IOCTL) по &tm, в противном случае он не будет ни смысла, ни компилировать
  • фиксированный формат PRINTF: "% 02d" вместо "% 02.lf"
  • поставить правильные имена для rtctime структуры полей: tm_hour, tm_min и т.д.

А вот модифицированный код:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <errno.h> 
#include <unistd.h> 
#include <time.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <sys/ioctl.h> 
#include <fcntl.h> 
#include <linux/rtc.h> 

#define LOG_FILE "/dev/tty" 

#define REPORT_ERROR(X) do {\ 
     fprintf(log,"[email protected] "X": %[email protected] %s:%d\n",\ 
     strerror(errno), __FILE__, __LINE__ - 1);\ 
     exit(EXIT_FAILURE);\ 
     } while(0) 

#define RTC "/dev/rtc0" 

int main(void) 
{ 
    int rtc_fd; 
    FILE *log; 
    struct rtc_time tm; 

    if ((log = fopen(LOG_FILE, "a+")) == NULL) 
     exit(EXIT_FAILURE); 

    if ((dup2(fileno(log), STDERR_FILENO)) < 0) 
     REPORT_ERROR("dup2()"); 

    if ((rtc_fd = open(RTC, O_RDONLY, 444)) < 0) 
     REPORT_ERROR("open(RTC)"); 

    /* Main loop */ 
    for (int i = 0; i < 10; ++i) 
    { 
     if ((ioctl(rtc_fd, RTC_RD_TIME, &tm)) != 0) 
      REPORT_ERROR("ioctl(rtc_fd)"); 

     fprintf(log, "%02d:%02d:%02d %d-%d-%d\n", tm.tm_hour, tm.tm_min, 
       tm.tm_sec, tm.tm_mon + 1, tm.tm_mday, tm.tm_year + 1900); 
     sleep(1); 
    } 

    close(rtc_fd); 
    return 0; 
} 

Результаты испытаний: Он компилируется и работает должным образом. Либо он запускается без сообщения об ошибке, либо печатает сообщение об ошибке и немедленно выходит из системы. Если один экземпляр программы запущен, запуск второго экземпляра дает сообщение об ошибке «Устройство или ресурс занят», как и ожидалось.

Другими словами, «работает для меня».