#include <rtems.h>
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
#define UART0_DATA *(volatile unsigned int *)(0x80000070)
#define UART0_STATUS *(volatile unsigned int *)(0x80000074)
#define UART0_CONTRAL *(volatile unsigned int *)(0x80000078)
#define UART0_SCALER *(volatile unsigned int *)(0x8000007c)
#define INT1_MSK *(volatile unsigned int *)(0x80000090)
#define INT1_CLR *(volatile unsigned int *)(0x8000009c)
#define SYSTEM_CLK 9600000
#define BAUDERATE 19200
/*定义共同体变量的原因是,读取系统滴答数指令返回值的类型是rtems_interval,是一个非负整数;
*而printf输出的变量类型是unsigned int,若直接输出rtems_interval类型的数据编译时会提示错误;
*注意到两种类型的变量在内存中都占4个字节,使用共同体变量,使用不同类型的变量表示同一段内存里的值,
*可以解决上述问题*/
union time
{
rtems_interval tick;
unsigned int count;
}ticks1,ticks2,ticks3,ticks4;
rtems_task Init(rtems_task_argument ignored)
{
UART0_SCALER = ((SYSTEM_CLK * 10)/(BAUDERATE * 8) - 5)/10;
UART0_CONTRAL = 0x07;
rtems_status_code status;
/*下面创建了4个同优先级的任务,并依次置于就绪状态*/
rtems_id tid_2;
rtems_name name_2;
name_2 = rtems_build_name('A','P','P','2');
status = rtems_task_create(name_2,2,RTEMS_MINIMUM_STACK_SIZE,
RTEMS_TIMESLICE,RTEMS_NO_FLOATING_POINT,&tid_2); //创建任务,使能时间片模式,下同
rtems_task usr_task_2(rtems_task_argument ignored); //任务的入口地址,下同
status = rtems_task_start(tid_2,usr_task_2,0); //任务处于就绪状态,下同
rtems_id tid_1;
rtems_name name_1;
name_1 = rtems_build_name('A','P','P','1');
status = rtems_task_create(name_1,2,RTEMS_MINIMUM_STACK_SIZE,
RTEMS_TIMESLICE,RTEMS_NO_FLOATING_POINT,&tid_1);
rtems_task usr_task_1(rtems_task_argument ignored);
status = rtems_task_start(tid_1,usr_task_1,1);
rtems_id tid_3;
rtems_name name_3;
name_3 = rtems_build_name('A','P','P','3');
status = rtems_task_create(name_3,2,RTEMS_MINIMUM_STACK_SIZE,
RTEMS_TIMESLICE,RTEMS_NO_FLOATING_POINT,&tid_3);
rtems_task usr_task_3(rtems_task_argument ignored);
status = rtems_task_start(tid_3,usr_task_3,3);
rtems_id tid_4;
rtems_name name_4;
name_4 = rtems_build_name('A','P','P','4');
status = rtems_task_create(name_4,2,RTEMS_MINIMUM_STACK_SIZE,
RTEMS_TIMESLICE,RTEMS_NO_FLOATING_POINT,&tid_4);
rtems_task usr_task_4(rtems_task_argument ignored);
status = rtems_task_start(tid_4,usr_task_4,4);
status = rtems_task_delete(RTEMS_SELF);
//exit(1);
}
/*任务1~任务4均为死循环,每次循环中读取系统自启动后经历的滴答数,
*然后输出到屏幕上,由串口调试助手查看*/
//任务1
rtems_task usr_task_1(rtems_task_argument ignored)
{
while(1)
{
ticks1.tick=rtems_clock_get_ticks_since_boot();
printf("test1 ticks %d \n",ticks1.count);
}
}
//任务2
rtems_task usr_task_2(rtems_task_argument ignored)
{
while(1)
{
ticks2.tick=rtems_clock_get_ticks_since_boot();
printf("test2 ticks %d \n",ticks2.count);
}
}
//任务3
rtems_task usr_task_3(rtems_task_argument ignored)
{
while(1)
{
ticks3.tick=rtems_clock_get_ticks_since_boot();
printf("test3 ticks %d \n",ticks3.count);
}
}
//任务4
rtems_task usr_task_4(rtems_task_argument ignored)
{
while(1)
{
ticks4.tick=rtems_clock_get_ticks_since_boot();
printf("test4 ticks %d \n",ticks4.count);
}
}
/* configuration information */
/* NOTICE: the clock driver is explicitly disabled */
#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
#define CONFIGURE_MICROSECONDS_PER_TICK 1000 //1 tick = 1000微妙=0.001s
#define CONFIGURE_TICKS_PER_TIMESLICE 50 // 一个时间片有50个滴答
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
#define CONFIGURE_MAXIMUM_TASKS 5
#define CONFIGURE_MAXIMUM_MESSAGE_QUEUES 1
#define CONFIGURE_INIT
#include <rtems/confdefs.h>
/* end of file */
按照上述代码的流程,由于先启动的任务2,在整个程序的执行过程中,只有任务2在第一次运行时,循环执行了50个滴答,结果是是5次循环读取滴答数,并将结果输出到屏幕上。
而从后面开始执行任务1,任务3,任务4,再返回执行任务2,每个任务都只读取了一次滴答数并输出——这个过程大约耗时10个滴答,并不是按照预想的,每个任务循环执行50个滴答,再执行任务就绪队列中的下一个任务。
这是我当初想当然的看法了,觉得既然每个任务已经使能了时间片功能,然后又在预编译部分定义了时间片相关的参数,然后每个任务就可以依次执行一个时间片然后这样轮着来了。
现在看来不是这样,不还意思,请问前辈——如何清除时钟节拍中断标志?
拜谢不已! |