嵌入式OS入门笔记-以RTX为案例:三.初探进程

嵌入式OS入门笔记-以RTX为案例:三.初探进程


1.理论
    进程,英文称呼很多Process, Task 等等,一般通用操作系统称Process的比较多,各种称呼涵义稍微有不一样。一般而言,进程是对一个运行单元的抽象,主要包括内存(code,data,heap和stack),CPU状态(PC,SP和寄存器值等)与其他OS管理相关的内容。进程是一个运行中的程序。在RTX中,一个task就是一个进程。
一般我们有一个进程控制块(Process control block,PCB),用于记录进程的相关信息。在RTX上,这个控制块叫做task control block(TCB),是一个结构体,其中的成员记录了关于该task的信息,其定义在rt_TypeDef.h中:

	typedef struct OS_TCB {  /* General part: identical for all implementations.                        */  U8     cb_type;                 /* Control Block Type                      */  U8     state;                   /* Task state                              */  U8     prio;                    /* Execution priority                      */  U8     task_id;                 /* Task ID value for optimized TCB access  */  struct OS_TCB *p_lnk;           /* Link pointer for ready/sem. wait list   */  struct OS_TCB *p_rlnk;          /* Link pointer for sem./mbx lst backwards */  struct OS_TCB *p_dlnk;          /* Link pointer for delay list             */  struct OS_TCB *p_blnk;          /* Link pointer for delay list backwards   */  U16    delta_time;              /* Time until time out                     */  U16    interval_time;           /* Time interval for periodic waits        */  U16    events;                  /* Event flags                             */  U16    waits;                   /* Wait flags                              */  void   **msg;                   /* Direct message passing when task waits  */  struct OS_MUCB *p_mlnk;         /* Link pointer for mutex owner list       */  U8     prio_base;               /* Base priority                           */  U8     ret_val;                 /* Return value upon completion of a wait  */  /* Hardware dependant part: specific for CM processor                      */  U8     ret_upd;                 /* Updated return value                    */  U16    priv_stack;              /* Private stack size, 0= system assigned  */  U32    tsk_stack;               /* Current task Stack pointer (R13)        */  U32    *stack;                  /* Pointer to Task Stack memory block      */  /* Task entry point used for uVision debugger                              */  FUNCP  ptask;                   /* Task entry address                      */  } *P_TCB;  
一个进程会有它自己的周期,会处在不同的进程状态(state,见上面的state成员),不同的状态有不同的意味,不同的状态间可以相互转换。
在RTX中,task的状态是在rt_Task.h中定义的,一共有10种:
	/* Values for 'state'   */  #define INACTIVE        0  #define READY           1  #define RUNNING         2  #define WAIT_DLY        3  #define WAIT_ITV        4  #define WAIT_OR         5  #define WAIT_AND        6  #define WAIT_SEM        7  #define WAIT_MBX        8  #define WAIT_MUT        9  
简单说来,可以分为4大类,inactive(进程被清理),ready(就绪),running(执行)和waiting(等待)。状态3至9都可以归为等待状态,区别在于他们等待的东西不同,从等待状态触发到就绪状态的条件不同。


进程的创建和消灭都是主要都牵涉到内存分配,排程器的安排,TCB的处理等等,需要具体的OS具体的分析,我们这里贴一下RTX进程创建的源代码:
	OS_TID rt_tsk_create (FUNCP task, U32 prio_stksz, void *stk, void *argv) {  /* Start a new task declared with "task". */  P_TCB task_context;  U32 i;  /* Priority 0 is reserved for idle task! */  if ((prio_stksz & 0xFF) == 0) {  prio_stksz += 1;  }  task_context = rt_alloc_box (mp_tcb);  if (task_context == NULL) {  return (0);  }  /* If "size != 0" use a private user provided stack. */  task_context->stack      = stk;  task_context->priv_stack = prio_stksz >> 8;  /* Pass parameter 'argv' to 'rt_init_context' */  task_context->msg = argv;  /* For 'size == 0' system allocates the user stack from the memory pool. */  rt_init_context (task_context, prio_stksz & 0xFF, task);  /* Find a free entry in 'os_active_TCB' table. */  i = rt_get_TID ();  os_active_TCB[i-1] = task_context;  task_context->task_id = i;  DBG_TASK_NOTIFY(task_context, __TRUE);  rt_dispatch (task_context);  os_tsk.run->ret_val = i;  return ((OS_TID)i);  }  
基本就是填TCB,分配内存空间,确定优先级和排程相关设置,这里就不深入分析。消灭进程的源代码也是类似的。

2.进程相关的基本操作
进程在RTX里的基本形式是:
	__task void task(void){    for(;;){    //...      }    }  
进程相关操作就是RTX提供的围绕这样一个task的一些基本操作,例如创建,消灭等等。
从应用角度来说,了解以下进程基本操作就足够了:
最主要的是这个:
os_tsk_create(task_name,priority);
把函数名填入,和进程的优先度,优先度后面的笔记会介绍。
如果留心看源代码,其实源代码的create操作要求一共4个参数(FUNCP task, U32 prio_stksz, void *stk, void *argv)。我们最基本的这个创建函数并没有接受后两个参数。如果实在有需要,有以下另外三个相关的操作:
os_tsk_create_ex(task_name,priority,para);
这个是用于传递一个初始参数para给相关进程的。例如你有一个LED_On的进程,而你有4个LED,你只有在创建进程时才能决定,你点亮的是哪个LED,那么就可以用这个操作,通过传递参数来决定具体要亮哪个LED。
os_tsk_create_user(task_name,priority,&stack,sizeof(stack));
这个是用来给进程创建自定义stack的。需要传递stack的地址和大小。
os_tsk_create_user_ex(task_name,priority,&stack,sizeof(stack),para);
这个明显就是上面两个的结合。
以上这些创建操作,返回类型都是OS_TID,进程ID,实际值从0到255。 所以可以先声明一个该类型的值,然后创建进程时让其返回该值。

2.消灭
os_tsk_delete(taskID);
填入你要消灭的进程的进程ID,TID。
如果要消灭进程本身,用:
os_tsk_delete_self();
注意,RTX的消灭进程并不清理互斥锁或者信号灯的占有的。所以在消灭一个进程前,确定进程释放了所有资源。内存资源会被这两个操作释放,所以不用担心。

3.杂项
如果想要知道当前进程的ID,使用以下操作:
os_get_TID();
还有一个非常重要的:
os_sys_init(first_task);
这个操作初始化整个RTX,如果不在main中执行这一操作,一切都是空谈。该操作会创建第一个进程,也就是first_task。

一般而言,进程可以创造别的进程,也可以消灭别的进程。但进程只能够消灭本身,而不能创造本身。所以就需要有一个操作去创建第一个进程,然后别的进程可由这个第一个进程去创造。

3.一个完整的例子
一下是一个从初始化,到创建第一个进程,到第一个进程创建别的进程,最后消灭自己的一个例子:
	OS_TID taskID1;   OS_TID taskID2;   __task void init (void) {  //Necessary Initialization  //...  //Create a task  taskID1 = os_tsk_create(task1, 0);  taskID2 = os_tsk_create(task2, 0);  os_tsk_delete_self (); // Delete the init(self) task  }  int main(void)  {  //Necessary Initialization  //...  os_sys_init(init);  }  

这个简单的例子足够应付最基本使用RTX的需求了。

关于RTX的排程,优先度,内存分配和一些OS原语,在后面的笔记会记录。


文章转载自:http://blog.csdn.net/raym0ndkwan/article/details/32859989

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/466040.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

图文方式管理Linux服务器(Webmin)

客户让做webmin,才知道linux下也有界面的管理了 对于大部分使用计算机的人来说,linux的印象就是一大堆的命令字符以及黑黑的显示屏。虽然现在Linux的桌面版有了长足的进步,界面已和Windows不相上下了.但对于Linux服务器来说&am…

最大、最小堆的实现

最大最小堆 堆是一种经过排序的完全二叉树,其中任一非终端节点的数据值均不大于(或不小于)其左子节点和右子节点的值。 最大堆和最小堆是二叉堆的两种形式。 最大堆:根结点的键值是所有堆结点键值中最大者。 最小堆:根…

嵌入式OS入门笔记-以RTX为案例:四.简单的时间管理

嵌入式OS入门笔记-以RTX为案例:四.简单的时间管理 上一节简单记录了进程task。有了进程以后,我们需要关心怎么样分配CPU资源(或者运行时间)给每个进程。那么就要引入排程(scheduling)的概念。排程一般都是O…

我等这个含蓄的技术男当上了CEO

大家好,祝大家五一节日快乐!今天没有写技术文章,今天想吹一个人,他是我的朋友,他做公众号很久了,技术文章写的也不错,但是阅读和关注量一直没有上来,我之前好几次在公众号上转发了他…

Oracle的列转行问题

Oracle的列转行问题Oracle中使用语句将行数据转换称不同的列表示,或者将不同的列数据写到同一列的不同行上的行列转换问题是一个非常传统的话题。网络上流传了很多将行数据转换称列数据的方法和应用实例,一般通过decode或者case函数与聚合函数联合实现功…

Linux CAN通信

Linux CAN通信 实现了Linux下的CAN通信——初始化&#xff0c;发两个送和接收&#xff08;采用队列形式&#xff09;&#xff0c;使用两个线程&#xff0c;还有一个超时响应目前未写。接收部分使用select实现。 #ifndef _CAN_H_ #define _CAN_H_#include <stdio.h> #incl…

(四)Kinect人脸识别

kinect可以通过摄动摄像头不仅可以获取人脸位置旋转信息&#xff0c;也可以获取脸部轮廓的三维坐标 可以参考插件中的场景KinectFaceTrackingDemo1-4&#xff0c;在kinectManager基础上需要脚本FacetrackingManager。 1&#xff09;通过KinectManager kinectManager KinectMan…

广东总冠军

lets go tiger 看这篇文章之前&#xff0c;先看看我们看球的视频 恭喜广东拿下总冠军&#xff01; 恭喜胡明轩夺得FMVP&#xff01; 我当时预测的是周鹏或者胡明轩拿下FMVP&#xff0c;最后是胡明轩&#xff0c;广东后场三条枪表现都非常亮眼。如果是上一场广东夺冠&#xff0c…

Spring切入点表达式常用写法

Spring切入点表达式常用写法自从使用AspectJ风格切面配置&#xff0c;使得Spring的切面配置大大简化&#xff0c;但是AspectJ是另外一个开源项目&#xff0c;其规则表达式的语法也稍稍有些怪异。下面给出一些常见示例的写法&#xff1a;比如&#xff0c;下面是一个对Service包上…

每日一题(1) —— 数组计算

判断下面代码是否可执行&#xff1f;如果可执行&#xff0c;执行结果是多少&#xff1f; #include <stdio.h>int main(void) {int array[10] {0, 2, 3, 4, 5, 6, 7, 8, 9, 10};0[array] 1;printf("%d\n", (-1)[array 5]);return 0; } 分析&#xff1a; C语…

SQLAlchemy Script

SQLAlchemy: 1.由于sqlalchemy中没有提供choice方法&#xff0c;所以借助SQLAlchemy-Utils组件提供的choice方法 from sqlalchemy_utils import ChoiceType Base declarative_base() class Xuan(Base): __tablename__ xuan types_choices ( (1,欧美), (2,日韩), (3,老男孩),…

内存文章汇总,并剖析mmap

在看这篇文章之前&#xff0c;可以先看看下面这几篇文章Linux内存&#xff0c;先看这篇文章Linux内存寻址方式Linux虚拟内存TLBLinux物理内存初始化Linux io内存存在的意义~修改cmdline 把内存改成512MB用mtrace定位内存泄漏什么是内存泄漏&#xff1f;Linux内存管理slub分配器…

[综述泛读] A survey on web services composition (IJWGS, 2005)

Time: 2.5 hours Dustdar S, Schreiner W. "A survey on web services composition." International Journal of Web and Grid Services: 1-30. 2005 (30 pages, 单栏) (gs:169) Schahram Dustdar (维也纳技术大学, full prof) Dusdar是Distributed Systems Group的老…

Spring 事务与脏读、不可重复读、幻读

索引&#xff1a; 目录索引 参看代码 GitHub&#xff1a; 1.Spring 事务 2.事务行为 一、Spring 事务: Spring 的事务机制是用统一的机制来处理不同数据访问技术的事务处理。 Spring 的事务机制提供了一个 PlatformTransactionManager 接口&#xff0c;不同的数据访问技术的事务…

韦老师的开发板和嵌入式书籍赠送

大家五一快乐&#xff01;我知道这个时候大家都没有什么心思学习&#xff0c;所以找了联合了几个朋友一起给大家送点东西。这几个技术号主都非常用心的给大家分享技术文章&#xff0c;我相信&#xff0c;跟他们一起&#xff0c;你们也能变得更加优秀。奖品包括&#xff1a;1. 韦…

每日一题(2)—— -2与2的比较

分析下面的代码&#xff0c;求运行结果。 #include <stdio.h>int main(void) {if(-2 > 2){printf("11111\r\n");}else{printf("22222\r\n");}return 0; }分析&#xff1a; -2和2都没有声明存储类型&#xff0c;编译器默认按int存储&#xff0c;所…

正则表达式之道

正则表达式之道 原著&#xff1a;Steve Mansour smanscruznet.com Revised: June 5, 1999 (copied by jm /at/ jmason.org from , after the original disappeared! ) 翻译&#xff1a;Neo Lee neo.leegmail.com 2004年10月16日 英文版原文 译者按&#xff1a;原文因为年代久远…

truffle unbox react 出坑指南

最近几天差点就被这鬼东西给逼疯了&#xff0c;truffle init 、truffle unbox webpack 不管我怎么运行都是对的&#xff0c;唯独truffle unbox react 不管在哪个windows都会报错&#xff0c;换了好几台电脑&#xff0c;心都累完了&#xff0c;还好我坚持了下来&#xff0c;找了…

单片机6年想转嵌入式Linux ,不知如何下手?

刷知乎看到下面这个提问。单片机6年想转嵌入式Linux &#xff0c;不知如何下手&#xff1f;现在挺尴尬&#xff0c;做的单片机产品总是感觉重复重复再重复&#xff0c;想学习点新东西&#xff0c;不知道如何转。说实话&#xff0c;这个问题自己关注了很久。今天就借题主这个问题…

Visual Studio 2008在设计视图和代码视图切换的快捷键F7

使用VS2008的快捷键F7可以在设计器视图和代码视图进行切换&#xff0c;相当于“视图”菜单 ->“代码”&#xff08;或者“设计器”&#xff09;。在设计器视图可以按F7查看源代码&#xff0c;在代码视图可以按F7转到设计界面。 这是VS2008默认的键盘映射方案&#xff0c;…