通过阅读rtems源码中的测试用例,对信号处理的简单理解。下在附上代码。代码编译时有告警,但不影响结果。
init.c 初始化任务:创建两个任务,并启动。任务的优先级高于任务1。
任务1
1、调用rtems_signal_catch设置异步信号的处理函数为Process_asr
2、调用rtems_signal_send向它本身发送一个信号RTEMS_SIGNAL_16
3、判定全局变量Task_2_preempted是否为真,如果是,刚输出"TA1 - TA2 correctly preempted me"
任务2
1、将全局变量Task_2_preempted设为假
2、调用rtems_task_suspend将自己挂起
3、在得到恢复运行后将Task_2_preempted设为真,然后把自己挂起
ASR处理函数Process_asr:这个函数就是调用rtems_task_resume使任务2恢复运行。
在这个例子中,虽然任务2的优先级更高,但它将自己挂起,所以任务1得以运行。它向自己发送一个信号,这个信号的处理函数会恢复任务2 的执行,而任务的优先级又高于任务1,所以它能够得到执行,把全局变量Task_2_preempted设为真。这里的ASR处理函数并没有区分是哪一个异步信号,如果需要对不同的鸽采取不同的行为,可以在ASR的处理函数中使用条件分支结构,这和linux下的信号处理函数类似。
第一个文件: 里面定义的任务名称,任务堆栈大小,任务的个数等
/* system.h */
#include <tmacros.h>
/* functions */
rtems_task Init(
rtems_task_argument argument
);
rtems_asr Process_asr(
rtems_signal_set signal_set
);
rtems_task Task_1(
rtems_task_argument argument
);
rtems_task Task_2(
rtems_task_argument argument
);
/* configuration information */
#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
#define CONFIGURE_MAXIMUM_TASKS 3
#define CONFIGURE_MICROSECONDS_PER_TICK RTEMS_MILLISECONDS_TO_MICROSECONDS(25)
#define CONFIGURE_TICKS_PER_TIMESLICE 1000
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
第二个文件
/* init.c */
#define CONFIGURE_INIT
#include "system.h"
rtems_task Init(
rtems_task_argument argument
)
{
rtems_status_code status;
puts( "/n/n*** TEST 17 ***" );
Task_name[ 1 ] = rtems_build_name( 'T', 'A', '1', ' ' );
Task_name[ 2 ] = rtems_build_name( 'T', 'A', '2', ' ' );
Task_2_preempted = FALSE;
status = rtems_task_create(
Task_name[ 1 ],
2,
RTEMS_MINIMUM_STACK_SIZE,
RTEMS_DEFAULT_MODES,
RTEMS_DEFAULT_ATTRIBUTES,
&Task_id[ 1 ]
);
directive_failed( status, "rtems_task_create of TA1" );
status = rtems_task_start( Task_id[ 1 ], Task_1, 0 );
directive_failed( status, "rtems_task_start of TA1" );
status = rtems_task_create(
Task_name[ 2 ],
1,
RTEMS_MINIMUM_STACK_SIZE,
RTEMS_DEFAULT_MODES,
RTEMS_DEFAULT_ATTRIBUTES,
&Task_id[ 2 ]
);
directive_failed( status, "rtems_task_create of TA2" );
status = rtems_task_start( Task_id[ 2 ], Task_2, 0 );
directive_failed( status, "rtems_task_start of TA2" );
status = rtems_task_delete( RTEMS_SELF );
directive_failed( status, "rtems_task_delete of RTEMS_SELF" );
}
/* end of task1.c */
第三个:task1.c
#include "system.h"
rtems_task Task_1(
rtems_task_argument argument
)
{
rtems_status_code status;
puts( "TA1 - rtems_signal_catch: initializing signal catcher" );
status = rtems_signal_catch( Process_asr, RTEMS_NO_ASR | RTEMS_NO_PREEMPT );
directive_failed( status, "rtems_signal_catch" );
puts( "TA1 - Sending signal to self" );
status = rtems_signal_send( Task_id[ 1 ], RTEMS_SIGNAL_16 );
directive_failed( status, "rtems_signal_send" );
if ( Task_2_preempted == TRUE )
puts( "TA1 - TA2 correctly preempted me" );
puts("TA1 - Got Back!!!");
puts( "*** END OF TEST 17 ***" );
rtems_test_exit( 0 );
}
第四个:task2.c
/* task2.c */
#include "system.h"
rtems_task Task_2(
rtems_task_argument argument
)
{
rtems_status_code status;
Task_2_preempted = FALSE;
puts( "TA2 - Suspending self" );
status = rtems_task_suspend( RTEMS_SELF );
directive_failed( status, "rtems_task_suspend of TA2" );
puts( "TA2 - signal_return preempted correctly" );
Task_2_preempted = TRUE;
status = rtems_task_suspend( RTEMS_SELF );
directive_failed( status, "rtems_task_suspend of TA2" );
}
/* end of task2.c */
任务处理函数
/* asr.c */
#include "system.h"
rtems_asr Process_asr(
rtems_signal_set signal_set
)
{
rtems_status_code status;
#include "system.h"
rtems_asr Process_asr(
rtems_signal_set signal_set
)
{
rtems_status_code status;
printf ("signal process running!/n");
status = rtems_task_resume( Task_id[ 2 ] );
directive_failed( status, "RTEMS_ASR - rtems_task_resume of TA2" );
}
status = rtems_task_resume( Task_id[ 2 ] );
directive_failed( status, "RTEMS_ASR - rtems_task_resume of TA2" );
}
/* end of asr.c */
Makefile 文件
PGM=${ARCH}/signal.exe
# optional managers required
MANAGERS=all
# C source names
CSRCS = init.c task1.c task2.c asr.c
#CSRCS = init.c
COBJS = $(CSRCS:%.c=${ARCH}/%.o)
include $(RTEMS_MAKEFILE_PATH)/Makefile.inc
include $(RTEMS_CUSTOM)
include $(PROJECT_ROOT)/make/leaf.cfg
OBJS= $(COBJS) $(CXXOBJS) $(ASOBJS)
all: ${ARCH} $(PGM)
$(PGM): $(OBJS)
$(make-exe)
#end of Makefile
执行结果
*** TEST 17 ***
TA2 - Suspending self
TA1 - rtems_signal_catch: initializing signal catcher
TA1 - Sending signal to self
printf ("signal process running!/n");
TA2 - signal_return preempted correctly
TA1 - TA2 correctly preempted me
TA1 - Got Back!!!
*** END OF TEST 17 ***
简单小结:简单介绍一下rtems的信号处理流程。1、rtems里的信号处理是非常有用的,当任务挂起时,可以使用信号处理函数来唤醒任务。2、基于优先级的任务在执行时,高优先级的先执行,低优先级的后执行。3、任务的执行是基于优先级的。当低优先级的任务在执行时,如果有高优先级的任务准备好时,要立刻调度到高优先级的任务执行。
欢迎转载:请注明出处。