RTEMS:扩展管理与使用
21.2.3 扩展
%A 21.2.3 .1:任务创建扩展 TASK_CREATE
%A
%A TASK_CREATE 任务创建扩展用于扩展 rtems_task_create 函数。如果系统中定义了该扩展,那么任务创建时会自动调用该扩展。扩展的原型应该符合下面的原型:
%A
%A boolean user_task_create(
%A
%A rtems_tcb *current_task,
%A
%A rtems_tcb *new_task
%A
%A );
%A
%A current_task 指针可以用来访问当前任务的 TCB ,而 new_task 则是用来访问新创建任务的 TCB 。当应用调用rtems_task_create创建新任务后,并且在新任务进入就绪队列前,系统将会调用该扩展。
%A
%A 如果扩展执行成功,应该返回布尔变量TRUE否则返回FLASE。如果在为用户扩展分配资源时失败,那么扩展将会返回FLASE,此时,会导致整个任务创建函数
%A
%A 执行失败(无论任务是否真的没有成功创建)。
%A
%A
%A 21.2.3 .2: 任务启动扩展 TASK_START
%A
%A TASK_START 扩展和 task_start 函数对应。任务启动时将会调用。启动扩展原型如下所示:
%A
%A
%A
%A rtems_extension user_task_start(
%A
%A rtems_tcb *current_task,
%A
%A rtems_tcb *started_task
%A
%A );
%A
%A
%A
%A current_task指针指向当前任务TCB,而 started_task 指针指向被启动的睡眠状态的任务的TCB。在调用task_start函数启动任务,该扩展将会被调用。 扩展的调度时机是在task_start 函数调用后,任务进入就绪TCB链表之前。
%A
%A
%A 21.2.3 .3: 重启扩展TASK_RESTART
%A
%A TASK_RESTART 扩展和函数 task_restart 相对应。如果定义了该扩展,任务重新启动时将会调用。该扩展原型如下所示:
%A
%A
%A
%A rtems_extension user_task_restart(
%A
%A rtems_tcb *current_task,
%A
%A rtems_tcb *restarted_task
%A
%A );
%A
%A
%A
%A current_task指针指向当前任务TCB,而restarted_task指针则指向重新启动的任务TCB。 该扩展的调用时机在task_restart 函数完成重启的准备工作,并准备要将任务放入就绪TCB链之前。
%A
%A
%A 21.2.3 .4: TASK_DELETE 扩展
%A
%A TASK_DELETE 扩展与 task_delete 函数相对应。如果定义了该扩展,那么任务删除时将自动调用对应函数。扩展应原型如下:
%A
%A rtems_extension user_task_delete(
%A
%A rtems_tcb *current_task,
%A
%A rtems_tcb *deleted_task
%A
%A );
%A
%A
%A
%A current_task指针指向当前任务TCB,而 deleted_task 则指向被删除任务的TCB。该扩展的调用时机在函数task_delete 调用后,将任务从就绪TCB上移除后,但是在任务的资源(包括 TCB等)被释放回资源池以前。如果一个任务正在删除它自己,此时current_task 和 deleted_task 相等,该扩展不能调用任何RTEMS 函数。
%A
%A
%A 21.2.3 .5: 任务切换扩展TASK_SWITCH
%A
%A 当任务进行切换时,将调用TASK_SWITCH扩展。如果定义了任务切换扩展,那么RTEMS将会自动调用用户扩展,用户扩展的原型如下:
%A
%A rtems_extension user_task_switch(
%A
%A rtems_tcb *current_task,
%A
%A rtems_tcb *heir_task
%A
%A );
%A
%A 这里current_task指针指向当前任务TCB,而 heir_task则指向被切换任务的TCB。在该扩展调用的时机是任务切换发生后,该扩展在current_task 上下文存储后,在 heir_task 上下文被调入处理器前执行,该扩展不能调用RTEMS的系统函数。
%A
%A
%A 21.2.3 .6: 任务开始扩展 TASK_BEGIN
%A
%A 当一个任务开始执行的时候 , 将调用 TASK_BEGIN 扩展。该函数在执行 rtems_task_start 后运行 , 函数运行在当前任务的上下文中。该扩展的原型如下所示:
%A
%A rtems_extension user_task_begin(
%A
%A rtems_tcb *current_task
%A
%A );
%A
%A 这里current_task指针指向当前任务的TCB。TASK_BEGIN 和 TASK_START 这两个扩展之间的区别是,TASK_START 扩展执行环境是调用 task_start 函数的任务上下文中运行,而TASK_BEGIN 扩展在则是在真实的任务语境中被运行。
%A
%A
%A 21.2.3 .7: 任务异常退出扩展 TASK_EXITTED
%A
%A 当任务 ( 因故 ) 退出当前的执行体。 TASK_EXITTED 扩展被叫唤被或一个暗示的或明白的回返语句。 任务退出扩展原型如下所示:
%A
%A rtems_extension user_task_exitted(
%A
%A rtems_tcb *current_task
%A
%A );
%A
%A 这里current_task指针指向当前退出任务的TCB
%A
%A 虽然任务的推出通常是因为异常引起的,然而任务推出扩展却有能力通过让任务重新执行或者删除当前推出的任务让系统恢复正常状态。如果用户没有提供 TASK_EXITTED 扩展或扩展将执行权限返回给 RTEMS,此后 RTEMS 默认的异常处理将会启用。 该默认处理使用 带RTEMS_TASK_EXITTED 状态码的fatal_error_occurred函数 。
%A 21.2.3 .8: 异常处理扩展
%A
%A 异常处理扩展与 fatal_error_occurred 函数相对应。当调用系统函数fatal_error_occurred 时,该扩展会被调用。扩展的原型如下所示:
%A
%A rtems_extension user_fatal_error(
%A
%A Internal_errors_Source the_source,
%A
%A rtems_boolean is_internal,
%A
%A rtems_unsigned32 the_error
%A
%A );
%A
%A 这里 the_error 是传给 fatal_error_occurred 函数的错误码。该扩展在函数 fatal_error_occurred 调用时执行。
%A
%A 如果定义了异常处理扩展,用户的异常处理函数会在调用RTEMS异常处理前进行必要的处理。例如异常处理可以将错误信息传递给调试器。在这个异常处理代码中,不能调用RTEMS系统函数。
%A 21.2.4 : 扩展调用顺序
%A
%A 当出现关键系统事件时,用户扩展将会 “ 前向 ” 或 “ 反向 ” 次序启动。前向次序意味着静态扩展集将跟在动态扩展调用以后调用,如果有多个动态扩展,那么这些扩展调用的次序和他们创建的次序相同。反向次序意味着先调用静态扩展,然后调用动态扩展,动态扩展调用的次序和创建的次序相反。使用前向或者反向次序,可以在系统中放入多层扩展,使系统构建更加灵活。下面的系统事件发生后,将使用前向顺序调用扩展:
%A
%A • 任务创建
%A
%A • 任务初始化
%A
%A • 任务重新初始化
%A
%A • 任务删除
%A
%A • 任务上下文切换
%A
%A • 任务开始运行
%A
%A 下面的系统事件发生后,将使用前向顺序调用扩展:
%A
%A • 任务推出
%A
%A • 异常检测
%A
%A 使用反向扩展调用次序主要是因为考虑到如果有的扩展是基于其他扩展创建的,那么往往是后创建的扩展比较全(类似于C++中继承关系),这样,有些情况下需要优先调用供能比较全的扩展。
%A
%A 前向次序中最后调用静态扩展是因为有些系统异常在静态扩展中实现,这些异常处理将会关闭所有的应用以及系统服务。所以有时候需要这些处理在其他扩展处理完后进行。此外使用任务删除扩展时,如果扩展的安装后于标准C库,那么即使这些扩展使用了C库,任务删除时工作也是正常的,因为C库的TASK_DELETE 扩展将在其他扩展调用之后进行。
%A 21.3: 扩展操作
%A 21.3.1 : 创建扩展集
%A
%A rtems_extension_create 函数创建并安装一个扩展集。函数也会创建一个扩展集控制块(ESCB),并为扩展命名,分配ID标识。创建扩展后扩展将会被安装,如果对应的系统事件发生就会被调用。
%A
%A 函数原型:
%A
%A rtems_status_code rtems_extension_create(
%A
%A rtems_name name,
%A
%A rtems_extensions_table *table,
%A
%A rtems_id *id
%A
%A );
%A
%A
%A
%A 返回值代表的状态:
%A
%A RTEMS_SUCCESSFUL- 成功创建
%A
%A RTEMS_INVALID_NAME- 无效名字
%A
%A RTEMS_TOO_MANY- 已创建太多扩展
%A
%A
%A
%A 描述:
%A
%A 该函数创建一个扩展集。id是创建扩展的ID标识。RTEMS 分派从本地ESCB空闲链表中为扩展集分配ESCB并且将其初始化。
%A 21.3.2 : 获得扩展的ID标识
%A
%A 扩展创建时, RTEMS 为扩展分配一个唯一的ID标识。扩展 ID标识可使用二个方法获得。 首先, rtems_extension_create 函数的返回参数;其次,使用 rtems_extension_ident 函数。
%A
%A 函数原型:
%A
%A rtems_status_code rtems_extension_ident(
%A
%A rtems_name name,
%A
%A rtems_id *id
%A
%A );
%A
%A
%A
%A 返回值代表的状态:
%A
%A RTEMS_SUCCESSFUL- 分机成功获取ID
%A
%A RTEMS_INVALID_NAME- 扩展名称没找到
%A
%A
%A
%A 描述:
%A
%A 按照扩展的名称查询ID,如果ID不唯一,那么返回找到的第一个同名扩展的ID。
%A 21.3.3 : 删除扩展集
%A
%A rtems_extension_delete 函数用来删除一个扩展集。当扩展集被删除的时候,扩展的控制块将被释放到空闲ESCB链表中。扩展集可能被所有知道其名称的任务删除。
%A
%A 函数原型:
%A
%A rtems_status_code rtems_extension_delete(
%A
%A rtems_id id
%A
%A );
%A
%A
%A
%A 返回值代表的状态:
%A
%A RTEMS_SUCCESSFUL- 成功地删除
%A
%A RTEMS_INVALID_ID- 无效的ID标识
%A
%A
%A
%A 描述:
%A
%A 该函数删除被 ID标识指定的扩展。如果扩展正在运行,它自动地结束。扩展的ESCB将被回收。
%A%A
%A
*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。