博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
RTEMS初始化线程(task)运行
阅读量:6243 次
发布时间:2019-06-22

本文共 4679 字,大约阅读时间需要 15 分钟。

RTEMS是如何运行第一个任务的?又是怎么样新建任务并进行切换的?

这要从RTEMS运行到boot_card开始说起,boot_card之前的初始化过程可参考之前的博文:

boot_card函数位于c/src/lib/libbsp/shared/boot_card.c文件中,函数在调用完一些驱动和hooking之后,最后调用rtems_initialize_start_multitasking函数来进入初始化task。

void boot_card(  const char *cmdline){.......  /*   *  Complete initialization of RTEMS and switch to the first task.   *  Global C++ constructors will be executed in the context of that task.   */  rtems_initialize_start_multitasking();  /***************************************************************   ***************************************************************   *  APPLICATION RUNS NOW!!!  We will not return to here!!!     *   ***************************************************************   ***************************************************************/}

rtems_initialize_start_multitasking函数位于rtems/cpukit/sapi/exinit.c中:

void rtems_initialize_start_multitasking(void){  _System_state_Set( SYSTEM_STATE_UP );  _SMP_Request_start_multitasking();  _Thread_Start_multitasking();  /*******************************************************************   *******************************************************************   *******************************************************************   ******                 APPLICATION RUNS HERE                 ******   ******              THE FUNCTION NEVER RETURNS               ******   *******************************************************************   *******************************************************************   *******************************************************************/}

那么通常第一个调用的task就是Init,这也是RTEMS的testsuites中大部分例子的第一个task。也就是用户的初始化任务,那么为了保证在其他应用任务启动前初始化任务能先启动,必须给它分配一个较高的优先级。

比如在rtems/testsuites/samples/base_sp中init.c中的函数init就是典型的例子:

rtems_task Init(  rtems_task_argument argument){  rtems_name        task_name;  rtems_id          tid;  rtems_status_code status;  TEST_BEGIN();  printf( "Creating and starting an application task\n" );  task_name = rtems_build_name( 'T', 'A', '1', ' ' );  status = rtems_task_create( task_name, 1, RTEMS_MINIMUM_STACK_SIZE,             RTEMS_INTERRUPT_LEVEL(0), RTEMS_DEFAULT_ATTRIBUTES, &tid );  directive_failed( status, "create" );   status = rtems_task_start( tid, Application_task, ARGUMENT );  directive_failed( status, "start" );   status = rtems_task_delete( RTEMS_SELF );  directive_failed( status, "delete" ); }
首先用户初始化任务会创建并启动一个新的任务,然后把自身删除。然后就是运行这个新任务了。

那么用户的初始化任务,也就是init是如何开始运行的?

在cpukit/rtems/include/rtems/rtems/tasks.h中定义了系统的初始化任务表这样一个数据结构,包含了初始化任务的名字,栈的大小,初始的优先级,属性,入口点等参数。

typedef struct {  /** This is the Initialization Task's name. */  rtems_name            name;  /** This is the Initialization Task's stack size. */  size_t                stack_size;  /** This is the Initialization Task's priority. */  rtems_task_priority   initial_priority;  /** This is the Initialization Task's attributes. */  rtems_attribute       attribute_set;  /** This is the Initialization Task's entry point. */  rtems_task_entry      entry_point;  /** This is the Initialization Task's initial mode. */  rtems_mode            mode_set;  /** This is the Initialization Task's argument. */  rtems_task_argument	argument;} rtems_initialization_tasks_table;

在cpukit/sapi/include/confdefs.h中定义哥系统的初始化任务表,只包含一个初始化任务:

rtems_initialization_tasks_table Initialization_tasks[] = {    { CONFIGURE_INIT_TASK_NAME,      CONFIGURE_INIT_TASK_STACK_SIZE,      CONFIGURE_INIT_TASK_PRIORITY,      CONFIGURE_INIT_TASK_ATTRIBUTES,      CONFIGURE_INIT_TASK_ENTRY_POINT,      CONFIGURE_INIT_TASK_INITIAL_MODES,      CONFIGURE_INIT_TASK_ARGUMENTS    }  };
其中CONFIGURE_INIT_TASK_ENTRY_POINT的定义如下:
#ifndef CONFIGURE_INIT_TASK_ENTRY_POINT  #ifdef __cplusplus  extern "C" {  #endif    rtems_task Init (rtems_task_argument );  #ifdef __cplusplus  }  #endif  #define CONFIGURE_INIT_TASK_ENTRY_POINT   Init  extern const char* bsp_boot_cmdline;  #define CONFIGURE_INIT_TASK_ARGUMENTS     ((rtems_task_argument) &bsp_boot_cmdline)#endif
也就是说如果用户没有定义
CONFIGURE_INIT_TASK_ENTRY_POINT,则系统会将init作为默认的初始化任务的入口点。也就是转到了init函数。而且CONFIGURE_INIT_TASK_PRIORITY的值为1,优先级非常高,仅次于0,因此能够保证其优先执行。

ps:RTEMS共256个优先级(0-255).数字越小,优先级越高,要注意的是RTEMS与POSIX标准正好相反,所以使用RTEMS的标准时,会转化为POSIX的优先级,转化方法是Prtems=255-Pposix。

那么在RTEMS中
新建一个task的函数就是
rtems_task_create

rtems_status_code rtems_task_create(  rtems_name           name,  rtems_task_priority  initial_priority,  size_t               stack_size,  rtems_mode           initial_modes,  rtems_attribute      attribute_set,  rtems_id            *id);

可以利用该函数实现多线程。

注意:该函数从功能上类似于Unix中的fork和exec,但是不同的在于,Unix具有内存管理功能,fork和exec函数之后的父进程和子进程之间的地址空间是隔离的。但是RTEMS并不具有这种功能,因此更为准确的描述是该函数与POSIX 的thread功能相同。

转载于:https://www.cnblogs.com/sichenzhao/p/9320165.html

你可能感兴趣的文章
MVC视图中Html常见的辅助方法
查看>>
分享一下刚刚HP电话面试。。。。。。。。我估计我挂了,不过还是要来分享一下...
查看>>
PT 转 PX
查看>>
平凡世界里的万千思绪
查看>>
(二)java环境搭建
查看>>
深入推荐引擎相关算法 - 协同过滤2
查看>>
mybatis逆向工程之配置
查看>>
使用.NET 4.0+ 操作64位系统中的注册表
查看>>
剑指offer——面试题26:判断二叉树B是否为二叉树A的子结构
查看>>
scrapy主动退出爬虫的代码片段
查看>>
ny12 喷水装置(二)
查看>>
C\C++语言细节(2)
查看>>
Jenkins持续部署-自动生成版本号
查看>>
设计模式--代理模式
查看>>
javascript基础知识--最基础的
查看>>
[转] vue自定义组件(通过Vue.use()来使用)即install的使用
查看>>
[转] 函数声明和函数表达式——函数声明的声明提前
查看>>
敢死队2影评
查看>>
浅析 JavaScript 中的 apply 和 call 用法的差异
查看>>
html5-css综合练习
查看>>