我在RTEMS中首先定义了一个用户初始化任务Init,然后在用户初始化任务Init中定义了4个相同优先级的用户任务usr_tsk1,usr_tsk2,usr_tsk3,usr_tsk4,并在定义任务时使能timeslice(时间片)功能。然后,规定了一个时间片包含50个滴答(tick),一个滴答0.001s。
每个任务当中都只有一个循环——在每次循环里,读取系统自启动开始总共发生的滴答数并输出到屏幕上,用串口调试助手查看。
然后,疑问出现了——只有在最开始执行的任务,如usr_tsk1,中循环执行了50个ticks即一个时间片的时间,而紧接着从usr_tsk2开始,usr_tsk2只执行了一次读取滴答数并输出的操作,然后就跳转到usr_tsk3开始执行,而usr_tsk3同样只执行了一次读取滴答数并输出的操作,接下来usr_tsk4和usr_tsk1也执行同样的操作,然后一直循环下去——每次读取滴答数并输出,然后跳转到下一个任务开始执行的过程,平均耗时10个滴答。
而在下预想的结果应该是每个任务依次执行50个滴答后,再开始新一轮的循环。为什么会出现上面这种情况,求各位大大解惑。
在下不胜感激!
4 个解决方案
#1
每个任务下加while(true)循环了吗?还是系统调度原因,执行完一个任务后,执行就绪的任务???
#2
#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 */
#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 */
#3
按照上述代码的流程,由于先启动的任务2,在整个程序的执行过程中,只有任务2在第一次运行时,循环执行了50个滴答,结果是是5次循环读取滴答数,并将结果输出到屏幕上。
而从后面开始执行任务1,任务3,任务4,再返回执行任务2,每个任务都只读取了一次滴答数并输出——这个过程大约耗时10个滴答,并不是按照预想的,每个任务循环执行50个滴答,再执行任务就绪队列中的下一个任务。
求问各位大侠解惑,感激不尽!
而从后面开始执行任务1,任务3,任务4,再返回执行任务2,每个任务都只读取了一次滴答数并输出——这个过程大约耗时10个滴答,并不是按照预想的,每个任务循环执行50个滴答,再执行任务就绪队列中的下一个任务。
求问各位大侠解惑,感激不尽!
#4
急求大神帮助啊!
拜谢各位了!
拜谢各位了!
#1
每个任务下加while(true)循环了吗?还是系统调度原因,执行完一个任务后,执行就绪的任务???
#2
#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 */
#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 */
#3
按照上述代码的流程,由于先启动的任务2,在整个程序的执行过程中,只有任务2在第一次运行时,循环执行了50个滴答,结果是是5次循环读取滴答数,并将结果输出到屏幕上。
而从后面开始执行任务1,任务3,任务4,再返回执行任务2,每个任务都只读取了一次滴答数并输出——这个过程大约耗时10个滴答,并不是按照预想的,每个任务循环执行50个滴答,再执行任务就绪队列中的下一个任务。
求问各位大侠解惑,感激不尽!
而从后面开始执行任务1,任务3,任务4,再返回执行任务2,每个任务都只读取了一次滴答数并输出——这个过程大约耗时10个滴答,并不是按照预想的,每个任务循环执行50个滴答,再执行任务就绪队列中的下一个任务。
求问各位大侠解惑,感激不尽!
#4
急求大神帮助啊!
拜谢各位了!
拜谢各位了!