LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1949|回复: 4

编译没错,但是运行就说ioctl: Invalid argument

[复制链接]
发表于 2006-11-13 23:35:24 | 显示全部楼层 |阅读模式
#include <stdio.h>
#include <linux/rtc.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
int main(int argc, char** argv)
{

  int i, fd, retval, irqcount = 0;
  unsigned long tmp, data;
  struct rtc_time rtc_tm;

  // 打开RTC设备
  fd = open ("/dev/rtc", O_RDONLY);
  if (fd ==  -1) {
    perror("/dev/rtc");
    exit(errno);
  }

  fprintf(stderr, "\n\t\t\tEnjoy TV while boiling water.\n\n");
  // 首先是一个报警器的例子,设定10分钟后"响铃"   
  // 获取RTC中保存的当前日期时间信息
  /* Read the RTC time/date */

  retval = ioctl(fd, RTC_RD_TIME, &rtc_tm);
  if (retval == -1) {
    perror("ioctl");
    exit(errno);
  }

  fprintf(stderr, "\n\nCurrent RTC date/time is %d-%d-%d,%02d:%02d:%02d.\n",rtc_tm.tm_mday, rtc_tm.tm_mon + 1, rtc_tm.tm_year + 1900, rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec);

  // 设定时间的时候要避免溢出

  rtc_tm.tm_min += 1;

  if (rtc_tm.tm_sec >= 60) {
    rtc_tm.tm_sec %= 60;
    rtc_tm.tm_min++;
  }

  if  (rtc_tm.tm_min == 60) {
    rtc_tm.tm_min = 0;
    rtc_tm.tm_hour++;
  }

  if  (rtc_tm.tm_hour == 24)
    rtc_tm.tm_hour = 0;

  fprintf(stderr, "\n\nCurrent RTC date/time is %d-%d-%d,%02d:%02d:%02d.\n",rtc_tm.tm_mday, rtc_tm.tm_mon + 1, rtc_tm.tm_year + 1900, rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec);
  // 实际的设定工作

  retval = ioctl(fd, RTC_ALM_SET, &rtc_tm);
  if (retval == -1) {
    perror("ioctl");
    exit(errno);
  }

  // 检查一下,看看是否设定成功
  /* Read the current alarm settings */
  retval = ioctl(fd, RTC_ALM_READ, &rtc_tm);
  if (retval == -1) {
    perror("ioctl");
    exit(errno);
  }

  fprintf(stderr, "Alarm time now set to %02d:%02d:%02d.\n", rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec);

  // 光设定还不成,还要启用alarm类型的中断才行
  /* Enable alarm interrupts */
  retval = ioctl(fd, RTC_AIE_ON, 0);
  if (retval == -1) {
    perror("ioctl");
    exit(errno);
  }

  // 现在程序可以耐心的休眠了,10分钟后中断到来的时候它就会被唤醒
  /* This blocks until the alarm ring causes an interrupt */
  retval = read(fd, &data, sizeof(unsigned long));
  if (retval == -1) {
    perror("read");
    exit(errno);
  }

  irqcount++;
  fprintf(stderr, " okay. Alarm rang.\n");
        return (0);
}
 楼主| 发表于 2006-11-13 23:37:43 | 显示全部楼层
:comp

求教

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

发表于 2006-11-14 22:22:52 | 显示全部楼层
小弟虽然没写过linux的程序,不过看大虾的程序怎么好乱阿,需要好好参考手册哦
回复 支持 反对

使用道具 举报

发表于 2006-11-14 22:24:47 | 显示全部楼层
ioctl的第三个参数在VxWorks里接受的是int的参数,8知道linux里是什么类型的,
回复 支持 反对

使用道具 举报

发表于 2006-11-15 00:22:49 | 显示全部楼层
我是在虚拟机下运行你的程序, 结果没有问题啊.我设成等待一分钟,运行后等待一分钟, 就出现楼主的"okay. Alarm rang". 实在不知道为什么你出错...

关于how to use RTC driver, 下面有个连接.
http://blackfin.uclinux.org/docm ... C_device_driver.pdf

接着看看drivers/char/rtc.c源代码
static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel)
{
         struct rtc_time wtime;
#ifdef RTC_IRQ
         if (rtc_has_irq == 0) {
                 switch (cmd) {
                 case RTC_AIE_OFF:
                 case RTC_AIE_ON:
                 case RTC_PIE_OFF:
                 case RTC_PIE_ON:
                 case RTC_UIE_OFF:
                 case RTC_UIE_ON:
                 case RTC_IRQP_READ:
                 case RTC_IRQP_SET:
                         return -EINVAL;
                 };
         }
#endif
这里出现了"-EINVAL", 我想这其中的错误跟中断有关吧....
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表