📄 5.htm
字号:
<br>
址里面。 <br>
int pthread_attr_init(pthread_attr_t* attr); <br>
初始化线程运行的属性值。 <br>
pthread_t pthead_self(void); <br>
获得当前正在运行的线程号。 <br>
int pthread_attr_getcpu_np(pthread_att_t *attr, int* cpu); <br>
设置当前的线程属性的CPU号。 <br>
clockid_t rtl_getschedclock(void); <br>
获得当前调度方法的时钟。 <br>
int rtl_setclockmode (clockid_t clock, int mode, hrtime_t mode_param); <br>
设置当前时钟模式,mode = RTL_CLOCK_MODE_ONESHOT时是非周期状态,mode_param参 <br>
<br>
无用;mode = RTL_CLOCK_MODE_PERIODIC时是周期状态,mode_param参数是周期的长度。 <br>
<br>
int pthread_wait_np(void); <br>
当前周期的线程运行结束。总是返回0值。 <br>
4.5.1.2 时间控制函数 <br>
void clock_getres(clockid_t clock, struct timespec* resolution); <br>
获得clock时钟的解析度,并且将解析度存放在resolution所指向的地址里面。 <br>
4.5.1.3 FIFO控制函数 <br>
int rtf_create(unsigned int fifo, int size); <br>
创建一个FIFO设备,该FIFO设备为第fifo个,缓冲区大小为size字节。 <br>
int rtf_destroy(unsigned int fifo); <br>
销毁第fifo个FIFO设备。 <br>
4.5.2 程序原理 <br>
该程序的原理是测出在RT Linux中进行实时任务调度过程中调度需要花费时间的多少。算 <br>
法如下: <br>
法如下: <br>
/*实时任务端*/ <br>
对于每500个周期 <br>
等待上一个周期的任务完成 <br>
获得当前时间和上次周期任务完成时间的差,就是调度的时间 <br>
循环 <br>
向FIFO输出500个周期中完成的最大值和最小值。 <br>
/*应用程序端*/ <br>
读取FIFO设备,获取最大值和最小值 <br>
在屏幕上打印出来 <br>
<br>
这种编程方法是进行RT Linux编程的通用方法,将一个任务分为实时部分和非实时部分 <br>
<br>
在实时部分完成的是实时任务;在非实时部分主要是完成显示等不需要实时的功能。程序 <br>
的体系结构如下所示: <br>
<br>
<br>
4.5.3 程序实现 <br>
正如上面所说的,程序分为两个部分,实时部分和非实时部分。实时部分通过使用一个 <br>
<br>
块,在将该实时模块插入之后,运行实时任务。对于非实时部分,实现对FIFO设备的读取 <br>
,完成和实时任务的通信就可以了。 <br>
4.5.3.1 实时部分代码 <br>
1)init_module() <br>
_________________________________________________________init_module() <br>
int init_module(void) <br>
{ <br>
pthread_attr_t attr; <br>
struct sched_param sched_param; <br>
int thread_status; <br>
int fifo_status; <br>
<br>
rtf_destroy(0); <br>
fifo_status = rtf_create(0, 4000);/*创建/dev/rtf0用来通信*/ <br>
if (fifo_status) { <br>
rtl_printf("FIFO Create failed. fifo_status=%d\n",fifo_status) <br>
; <br>
return -1; <br>
} <br>
rtl_printf("RTL measurement module on CPU %d\n",rtl_getcpuid()); <br>
pthread_attr_init (&attr); <br>
pthread_attr_setcpu_np(&attr, 0);/*第一个CPU*/ <br>
sched_param.sched_priority = 1;/*调度参数*/ <br>
pthread_attr_setschedparam (&attr, &sched_param); <br>
rtl_printf("Begin to create thread\n"); <br>
thread_status = pthread_create (&task1, &attr, thread_code, (void *)1 <br>
); <br>
/*创建一个实时任务的线程,线程代码过程为thread_code*/ <br>
if (thread_status != 0) { <br>
rtl_printf("failed to create RT-thread: %d\n", thread_status); <br>
<br>
return -1; <br>
} <br>
else {/*成功创建*/ <br>
rtl_printf("created RT-thread\n"); <br>
} <br>
<br>
return 0; <br>
} <br>
<br>
2)cleanup_module() <br>
_____________________________________________________cleanup_module() <br>
void cleanup_module(void) <br>
{ <br>
pthread_delete_np(task1);/*删除该线程*/ <br>
close(fifo);/*关闭/dev/rtf0的文件描述符*/ <br>
rtf_destroy(0);/*销毁该FIFO设备*/ <br>
} <br>
_____________________________________________________________________ <br>
3)实时任务过程thread_code(): <br>
_________________________________________________________thread_code() <br>
void *thread_code(void* param) { <br>
hrtime_t expected, diff, now, min, max,;/*纳秒为单位*/ <br>
struct data samp;/*写到FIFO设备的形式*/ <br>
<br>
int i; <br>
int count = 0; <br>
DECLARE_CPUID(cpu_id);/*获得CPU 号,前面指定为第一个CPU*/ <br>
<br>
rtl_printf ("Measurement task starts on CPU %d\n", cpu_id); <br>
if (mode) {/*周期模式*/ <br>
int ret = rtl_setclockmode (rtl_getschedclock(), RTL_CLOCK_MODE_PERIODIC, pe <br>
riod); <br>
if (ret != 0) { <br>
rtl_printf("Setting periodic mode failed\n"); <br>
mode = 0;/*仍然是oneshot模式*/ <br>
} <br>
} <br>
if (mode) {//周期模式 <br>
struct timespec resolution; <br>
clock_getres (rtl_getschedclock(), &resolution); <br>
period = timespec_to_ns (&resolution);/*从时钟里获得解析度*/ <br>
} <br>
else {//oneshot模式 <br>
rtl_setclockmode (rtl_getschedclock(), RTL_CLOCK_MODE_ONESHOT, 0); <br>
} <br>
fifo = open("/dev/rtf0", O_NONBLOCK);/*非阻塞模式打开rtf0*/ <br>
/*使用rtf0来和Linux进程进行通信*/ <br>
if (fifo < 0) {/*打开失败*/ <br>
rtl_printf("Error in opening /dev/rtf0: returned %d\n", fifo); <br>
return (void *) -1; <br>
} <br>
expected = clock_gethrtime(rtl_getschedclock()) + 5*period;/*开始时间*/ <br>
pthread_make_periodic_np(pthread_self(), expected, period); <br>
/*设置调度的开始时间和周期*/ <br>
/*死循环*/ <br>
do { <br>
min = 2000000000;//2 seconds. <br>
max = -2000000000;//-2 seconds. <br>
<br>
for (i = 0; i < ntests; i++) {/**/ <br>
++count; <br>
pthread_wait_np(); <br>
now = clock_gethrtime(CLOCK_REALTIME); <br>
if (!mode) { <br>
if (now < expected) { <br>
rtl_delay (expected - now); <br>
} <br>
now = clock_gethrtime(CLOCK_REALTIME); <br>
}/*if*/ <br>
diff = now - expected; <br>
if (diff < min) { <br>
min = diff; <br>
} <br>
if (diff > max) { <br>
max = diff; <br>
} <br>
expected += period;/*下一个周期的开始时间*/ <br>
}/*for*//*一次循环结束,得到最大值最小值*/ <br>
samp.min = min; <br>
samp.max = max; <br>
write (fifo, &samp, sizeof(samp));/*向FIFO设备写*/ <br>
} while (1);/*无穷的循环*/ <br>
return 0; <br>
} <br>
_____________________________________________________________________ <br>
4)程序头 <br>
______________________________________________________mymeasurement.c <br>
#include <rtl.h> <br>
#include <rtl_fifo.h> <br>
#include <rtl_sched.h> <br>
#include <rtl_sync.h> <br>
#include <rtl_debug.h> <br>
<br>
#include <pthread.h> <br>
#include <unistd.h> <br>
#include <time.h> <br>
#include <errno.h> <br>
#include “myheader.h” <br>
<br>
pthread_t task1; <br>
<br>
int ntests = 100; <br>
int period = 100000; <br>
int mode = 0; <br>
int mode = 0; <br>
/*可以向该模块传入下面三个整型参数*/ <br>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -