这个礼拜封闭开发的生活快要结束了.期间除了做串口下载外,还封装了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函数中,它主要用来指定创建一个新文件时的权限。
阅读(2988) | 评论(0) | 转发(0) |