Time实验
实验目的
- 熟悉 Linux 应用程序编程;
- 熟悉 Linux 定时器的使用
实验设备
实 验 设 备 | 数 量 | 备 注 |
---|---|---|
感知 RF2-210 实验箱 | 1 | 运行 linux 程序 |
串口线 | 1 | 连接网关板 COM3 与 PC 串口 |
PC 机 | 1 | 编译和下载程序 |
实验内容
程序通过定时器,中断 10 次,每秒钟中断一次,最后退出。
实验原理
setitimer一个进程中只能有一个,下一个会覆盖前一个的定时,想一个进程多个定时器只能自己实现。
setitimer()不支持在同一进程中同时使用多次以支持多个定时器。
linux 有关定时器(setitimer)的叙述是这样的:
linux 系统给每个进程提供了 3 个定时器,每个定时器在各自不同的域里面 计数。当任何一个 timer 计数到结束了,系统就发送一个信号(signal)给该进程, 同时计数器重置。
一共支持以下3种计数器形式:
ITIMER_REAL在real time 中计数器减1,然后等计数往比后发送 SIGALRM信号。
ITIMER_VIRTUAL当进程在执行的过程中计数,然后当计数完毕后发送 SIGVTALRM 信号给该进程。
ITIMER_PROF 在该进程被执行和系统在代表该进程执行的时间都进行 计数
【getitimer/setitimer 系统调用】
功能描述:
获取或设定间歇计时器的值。系统为进程提供三种类型的计时器,每一类以 不同的时间域递减其值。当计时器超时,信号被发送到进程,之后计时器重启动。
用法:
#include <sys/time.h>
int getitimer(int which, struct itimerval *value);
int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue);
参数:which:间歇计时器类型,有三种选择
ITIMER_REAL //数值为0,计时器的值实时递减,发送的信号是 SIGALRM。
ITIMER_VIRTUAL //数值为 1,进程执行时递减计时器的值,发送的信号是 SIGVTALRM。
ITIMER_PROF //数值为 2,进程和系统执行时都递减计时器的值,发送的信 号是 SIGPROF。 value,ovalue:时间参数,原型如下
struct itimerval {
struct timeval it_interval;
struct timeval it_value;
};
struct timeval {
long tv_sec;
long tv_usec;
};
getitimer()用计时器的当前值填写 value 指向的结构体。
setitimer()将 value 指向的结构体设为计时器的当前值,如果 ovalue 不是 NULL,将返回计时器原有值。
返回说明:
成功执行时,返回 0。
失败返回-1,errno 被设为以下的某个值
EFAULT:value 或 ovalue 是不有效的指针
EINVAL:其值不是 ITIMER_REAL,ITIMER_VIRTUAL 或 ITIMER_PROF 之一。
实验步骤
1.进入虚拟机ubuntu系统下,打开终端调试软件进入“/opt/WXL/Basic”实验操作目录
输入以下命令进入“/opt/WXL/Basic”目录
#cd /opt/WXL/Basic
2.编译实验代码
2.1 输入以下命令新建time文件夹
# mkdir time
2.2 进入time实验目录
输入以下命令新建timer.c文件并填写内容
# touch timer.c
输入命令新建Makefile文件并填写内容
# touch Makefile
2.3 编译生成可执行文件
输入命令如下进行编译
# make
编译完成后在/opt/WXL/Basic/time 目录下生成了可执行目标文件 timer。
3.下载到目标板执行
将生成的可执行文件“timer”拷贝到Windows目录下,通过超级终端使用串口下载到感知RF2-210实验箱目标板上运行。
3.1拷贝可执行文件到Windows;
3.2通过超级终端发送文件到感知RF2-210;
3.3修改可执行文件的权限和执行
修改权限输入命令:
#chmod 775 timer
3.4执行程序命令:
# ./timer
附录
timer.c文件
#include <stdio.h>
#include <signal.h>
#include <sys/time.h>
//#include <fcntl.h>
int limit = 10;
/* signal process */
void timeout_info(int signo)
{
if(limit == 0)
{
printf("Sorry, time limit reached.\n");
exit(0);
}
printf("only %d senconds left.\n", limit--);
}
/* init sigaction */
void init_sigaction(void)
{
struct sigaction act;
act.sa_handler = timeout_info;
act.sa_flags = 0;
sigemptyset(&act.sa_mask);
sigaction(SIGPROF, &act, NULL);
}
/* init */
void init_time(void)
{
struct itimerval val;
val.it_value.tv_sec = 1;
val.it_value.tv_usec = 0;
val.it_interval = val.it_value;
setitimer(ITIMER_PROF, &val, NULL);
}
int main(void)
{
char *str;
char c;
init_sigaction();
init_time();
printf("You have only 10 seconds for thinking.\n");
while(1);
exit(0);
}
Makefile文件
EXEC = timer
OBJS = timer.o
SRC = time.c
CC = arm-linux-gcc
CFLAGS += -O2 -Wall
LDFLAGS +=
all:$(EXEC)
$(EXEC):$(OBJS)
$(CC) $(CFLAGS) -c $@ $(OBJS)
%.o:%.c
$(CC) $(CFLAGS) -c $< -o $@
clean:
@rm -vf $(EXEC) *.o*-