Chinaunix首页 | 论坛 | 博客
  • 博客访问: 191732
  • 博文数量: 38
  • 博客积分: 2010
  • 博客等级: 大尉
  • 技术积分: 424
  • 用 户 组: 普通用户
  • 注册时间: 2009-06-19 12:41
文章分类

全部博文(38)

文章存档

2017年(2)

2016年(1)

2010年(8)

2009年(27)

我的朋友

分类: LINUX

2009-12-16 16:04:46

这个礼拜封闭开发的生活快要结束了.期间除了做串口下载外,还封装了LinuxOs的api.包括定时器,线程这2个部分,就一些关键点提出如下:
1.设置系统时间用settimeofday,获取系统时间用gettimeofday,这2个函数不管是在多少频率的定时器下面都由内核进行过优化,是高精度度.其中设置系统时间的时候需要检查调用者传入时间是否合法.这个小程序恐怕大家在大学的时候被得滚瓜烂熟了吧o(∩_∩)o...:
static int check_valid_time(ST_TIME *time)
{
    int year    = time->Year;
    int month   = time->Month;
    int day     = time->Day;
    int hour    = time->Hour;
    int min     = time->Minute;
    int sec     = time->Second;

    if(year < 1900 ||
        month < 1 || month > 12 ||
        hour < 0 || hour > 23 ||
        min < 0 || min > 59 ||
        sec < 0 || sec > 59)
    {
        printf("check_valid_time, year|month|hour|min|sec err!\n");
        return 1;
    }
    switch(month)
    {
        case 1:
        case 3:
        case 5:
        case 7:
        case 8:
        case 10:
        case 12:
            if(day < 1 || day > 31)
            {
                printf("check_valid_time, month err!\n");
                return 1;
            }
            break;
        case 4:
        case 6:
        case 9:
        case 11:
            if(day < 1 || day > 30)
            {
                printf("check_valid_time, day err!\n");
                return 1;
            }
            break;
        case 2:
            if((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
            {//leap year
                if(day < 1 || day > 29)
                {
                    printf("check_valid_time, day err!\n");
                    return 1;
                }
            }
            else
            {
                if(day < 1 || day > 28)
                {
                    printf("check_valid_time, day err!\n");
                    return 1;
                }
            }
            break;
    }
    return 0;
}
 
(PS:settimeofday有权限的问题, 如果你是在非root下面去启动进程,则该进程不能直接调用settimeofday,这时候需要在内核里面修改其权限. 代码在/kernel/time.c里面,屏蔽掉do_sys_settimeofday()中的, error = security_settime(tv, tz);这一行代码.)
 
2.进程休眠函数,我已经在上面一篇文章中进行了详细的性能测试.
 
3.Set/Check定时器.设计思想是根据需求的最大定时器数目,比如5个,去定义一个结构体数组.
设置的时候,记录下时间,检查的时候再次读取系统时间,计算2个时间的差值,将差值返回给用户.
 
4.设置定时器事件的设计思想. 用kernel2.6提供的POSIX定时器API,这些api需要链接rt库.不用kernel2.4信号机制的原因是,2.4的api所用信号是小于32的不可靠信号,可能被丢弃.
 
5.获取开机tick值:从/proc/interrupts文件中读取.读出来的值/定时器频率 则是开机以来经过的时间.
 
6.创建/删除线程需要综合考虑.如果用pthread_exit();则在退出的时候需要pthread_join(),且join和获取线程的返回值.但是如果初始化线程的时候用PTHREAD_CREATE_DETACHED,则不需要join.
 
7.强行终止一个线程用pthread_cancel(),但是请慎用,有可能造成死锁,这个不可避免.
 
8.获取mutex可用超时api:pthread_mutex_timedlock();如果连续调用2次,则第二次会返回超时.
 
9.文件封装的时候,需要在系统调用和库函数之间进行选择open(2)是系统调用,fopen(3)系列是库函数.
这里最好使用系统调用.使用open的时候,如果flag选择了O_CREAT, 那么此时可以有一个扩展参数,作为第三个open的参数.如下:
int open(const char pathname, int oflag ,....../* mode_t mode */)
返回:若成功为int型的文件描述符,若出错为- 1
  
  pathname :你要打开文件所在的目录(包括文件名)。
  oflag :指定打开文件的方式的参数,可以通过单个以下的值或它们的“或”组合。最主要有三个:只读(O_RDONLY)、只写(O_WRONLY)、读写(O_RDWR);另外还有一些其他的控制参数如O_APPEND、O_CREAT等等,这些参数的具体含义和用法可以在LINUX中通过man open来获得。它们都是定义在头文件中。
  mode :是一个可选的参数,只有当oflag中有O_CREAT时,这个参数才会出现在open函数中,它主要用来指定创建一个新文件时的权限。
 
 
阅读(2981) | 评论(0) | 转发(0) |
0

上一篇:修改定时器频率

下一篇:计算百分比

给主人留下些什么吧!~~