ostaskcreateext后会立即运行该任务吗

Qsys与uCOS学习笔记3:Hello uC/OS-II
&&&&&&&& uC/OS-II(又名Micro C/OS)是基于嵌入式系统的完整的,可移植、可固化、可裁剪的可剥夺型实时内核,其已经广泛应用在航空飞行器、医疗设备、工业控制等可靠性和稳定性要求较高的场合。该内核的代码也是完全开源的,如果不做商业用途,完全免费。因此对于广大的嵌入式爱好者与工程师们而言,了解OS从uC/OS-II开始不失为一个很好的选择。
&&&&&&&& 之前是使用特权同学自己的SF-NIOS2开发套件进行了EDS上的uC/OS-II样板工程测试,为了当前学习笔记的持续性,这里重新就DE2-115板重新整理一个Hello uC/OS-II实例的创建和演示。
Qsys组件添加
&&&&&&&& 在一个工程实例基础上,添加一个Interval Timer外设,设置该Timer的定时Period为10ms,用于作为uC/OS-II的时钟节拍(Clock tick),如图1所示。
&&&&&&&& 修改该Timer外设名称为ucosii_timer。将它的clk和reset信号分别连接到clk组件的clk和clk_reset信号上,将它的Avalon从机接口s1连接到nios_qsys_0的data_master上,并将它的irq连接到nios_qsys_0的d_irq上。
&&&&&&&& 自动分配地址,点击System&Assign Base Addresses。自动分配中断向量号,点击System&Assign Interrupt Numbers,接着点击Generate生成新的系统。
&&&&&&&& 完成Qsys新系统的Generate,接着重新编译Quartus II的project。自此,硬件的修改已经就绪。
软件工程创建
&&&&&&&& 如图3所示,打开EDS后,点击File&New&Nios II Application and BSP from Template新建模板工程。
&&&&&&&& 如图4所示,在新建工程向导中,选择SOPC Information File name为当前工程目录下的sopcinfo文件。Project name命名为ucosii_swprj,选择Project template为Hello MicroC/OS II。最后点击Finish创建工程。
&&&&&&&& 新建工程出现在工程管理窗口后,右键单击ucosii_swprj文件夹,选择NIOS II&BSP Editor,如图5所示。
&&&&&&&& 如图6所示,确定Main页面中Common里面的stderr/stdin/stdout均为jtag_uart,ucosii_timer为sys_clk_timer即可。点击Generate更新设置。
&&&&&&&& 右键点击应用工程,选择Build Project进行软件工程编译。完成后Console窗口打印如图7所示的信息,可见这个uC/OS-II内核以及软件的HAL占用了大约94KB的存储空间,uC/OS-II其实还是很小的,只不过NIOS II各种外设的HAL比较大,不过也都是可以裁剪的。
uC/OS-II运行调试
&&&&&&&& 首先将Quartus II工程产生的sof硬件配置文件烧录到FPGA中。
&&&&&&&& 接着应用工程上点击右键弹出菜单选择Run as&Nios II Hardware,在线运行uC/OS-II实例工程。
&&&&&&&& 这个uC/OS-II工程的实验目的只是创建两个task分别打印一串字符,正如readme所描述:
Readme - Hello MicroC/OS-II Hello Software Example
Hello_uosii is a simple hello world program running MicroC/OS-II.&The
purpose of the design is to be a very simple application that just
demonstrates MicroC/OS-II running on NIOS II.&The design doesn't account
for issues such as checking system call return codes. etc.
&&&&&&&& 在NIOS II Console中,我们可以看到最终运行的效果,如图8所示,两个任务所打印的字符串&Hello from task1&和&Hello from task2&循环出现。
&&&&&&&& 主要实例源码如下:
#include &stdio.h&
#include &includes.h&
/* Definition of Task Stacks */
#define&& TASK_STACKSIZE &&&&&&2048
OS_STK&&& task1_stk[TASK_STACKSIZE];
OS_STK&&& task2_stk[TASK_STACKSIZE];
/* Definition of Task Priorities */
#define TASK1_PRIORITY&&&&& 1
#define TASK2_PRIORITY&&&&& 2
/* Prints &Hello World& and sleeps for three seconds */
void task1(void* pdata)
&while (1)
&&& printf(&Hello from task1\n&);
&&& OSTimeDlyHMSM(0, 0, 3, 0);
/* Prints &Hello World& and sleeps for three seconds */
void task2(void* pdata)
&while (1)
&&& printf(&Hello from task2\n&);
&&& OSTimeDlyHMSM(0, 0, 3, 0);
/* The main function creates two task and starts multi-tasking */
int main(void)
&OSTaskCreateExt(task1,
&&&&&&&&&&&&&&&&& NULL,
&&&&&&&&&&&&&&&&& (void *)&task1_stk[TASK_STACKSIZE-1],
&&&&&&&&&&&&&&&&& TASK1_PRIORITY,
&&&&&&&&&&&&&&&&& TASK1_PRIORITY,
&&&&&&&&&&&&&&&&& task1_stk,
&&&&&&&&&&&&&&&&& TASK_STACKSIZE,
&&&&&&&&&&&&&&&&& NULL,
&&&&&&&&&&&&&&&&& 0);
&&&&&&&&&&&&&
&&&&&&&&&&&&&&
&OSTaskCreateExt(task2,
&&&&&&&&&&&&&&&&& NULL,
&&&&&&&&&&&&&&&&& (void *)&task2_stk[TASK_STACKSIZE-1],
&&&&&&&&&&&&&&&&& TASK2_PRIORITY,
&&&&&&&&&&&&&&&&& TASK2_PRIORITY,
&&&&&&&&&&&&&&&&& task2_stk,
&&&&&&&&&&&&&&&&& TASK_STACKSIZE,
&&&&&&&&&&&&&&&&& NULL,
&&&&&&&&&&&&&&&&& 0);
&OSStart();
&return 0;
&&&&&&&& 源码中,一个标准的uC/OS-II工程,如图9所示,初始化时调用OSInit();函数;接着调用OSTaskCreate();或OSTaskCreateExt();函数创建用户任务;最后调用OSStart();函数运行任务。这里的main函数里虽然没有出现OSInit();函数,但实际上在HAL后台外设初始化时候肯定调用了。中间是任务的创建,这里创建两个任务task1和task2,优先级分别为1和2,并且分配了相应的堆栈空间。在两个任务中,分别打印字符串&Hello from task1&和&Hello from task2&,字符串打印后调用OSTimeDlyHMSM(0, 0, 3, 0);函数做了3s的延时。如果修改这个延时时间,打印效果会发生改变,根据延时的情况,Console窗口出现的打印字样频率和速度会不一样。
&&&&&&&& 前面提到我们的实例其实是有OSInit();函数存在的,而且是在系统的main();函数之前就调用了。这里也探个究竟,也算是给大家讲讲NIOS II的软件执行顺序吧。NIOS II软件在上电后其实并非如同一帮的裸奔的嵌入式软件一样直接从main();函数开始执行程序,而是先执行HAL里面的alt_main();函数,这个函数在bsp工程下的HAL&src里面,找到名为alt_main();的函数便是。
&&&&&&&& 打开alt_main.c源代码文件后,如图11所示,alt_main();函数中执行了Qsys系统的几乎所有可用外设的初始化,因为我们这个模板工程用的是uC/OS-II的例子,所以必有其初始化,图11中的ALT_OS_INIT();便是。如果右击该函数,选择Open Declaration,则我们便能看到这样的定义:
#define ALT_OS_INIT()&&& OSInit();&
&&&&&&&& 再来简单的熟悉一下这个模板工程中所涉及的几个函数,包括OSInit();函数、OSTaskCreate();函数、OSTaskCreateExt();函数、OSStart();函数。
OSInit();函数
void&OSInit (void)
&&&&&&&& 在使用uC/OS-II的任何功能之前,必须调用该函数。该函数建立了两个任务:空闲任务&&在所有其他任务均未就绪时运行;统计任务&&计算CPU的利用率。此外,该函数也对uC/OS-II所有的变量和数据结构进行初始化。
OSTaskCreate();函数
INT8U&OSTaskCreate (void (*task)(void *p_arg),
&&&&&&&&&&&&&&&&&&&&&&& void *p_arg,
&&&&&&&&&&&&&&&&&&&&&&& OS_STK *ptos,
&&&&&&&&&&&&&&&&&&&&&&& INT8U prio)
&&&&&&&& 除了OSInit();函数执行时为系统建立的2个基本任务(优先级最低的2个任务),uC/OS-II建议用户另外保留2个优先级最低的任务和4个优先级最高的任务,为了将来的内核升级只用,当然了,其实也可以不保留。所以,通常来讲,用户至少可以建立56个任务。
&&&&&&&& OSTaskCreate();函数有4个入口参数,其含义分别为:task是指向任务代码的指针;p_arg是任务开始执行时,传递给任务的参数的指针;ptos是分配给任务的堆栈的栈顶指针;prio是分配给任务的优先级。
OSTaskCreateExt();函数
INT8U&OSTaskCreateExt (void&& (*task)(void *p_arg),
&&&&&&&&&&&&&&&&&&&&&&& void&&& *p_arg,
&&&&&&&&&&&&&&&&&&&&&&& OS_STK&*ptos,
&&&&&&&&&&&&&&&&&&&&&&& INT8U&&& prio,
&&&&&&&&&&&&&&&&&&&&&&& INT16U&& id,
&&&&&&&&&&&&&&&&&&&&&&& OS_STK&*pbos,
&&&&&&&&&&&&&&&&&&&&&&& INT32U&& stk_size,
&&&&&&&&&&&&&&&&&&&&&&& void&&& *pext,
&&&&&&&&&&&&&&&&&&&&&&& INT16U&& opt)
&&&&&&&& OSTaskCreateExt();函数其实是OSTaskCreate();函数的扩展,前4个参数的定义用法完全一致,后面5个入口参数的定义为:id是为要建立的任务创建一个特殊标志符,主要是保留为了将来内核升级使用,当前只要将此参数值设置成和任务的优先级一样就行;pbos指向任务堆栈栈底的指针,用于堆栈的检验;stk_size用于指定堆栈的容量;pext指向用户附加的数据域的指针,用来扩展任务的任务控制块OS_TCB;opt用于设定OSTaskCreateExt();的选项,指定是否允许堆栈的检验,是否将堆栈清0,任务是否要进行浮点操作等。
OSStart();函数
void&OSStart (void)
&&&&&&&& 该函数负责从任务就绪表中找出用户建立的优先级最高的任务控制块,并开始执行这个任务。调用该函数后,软件就将控制权交给了uC/OS-II的内核,开始运行多任务。在调用该函数之前,必须先建立一个任务,否则,应用程序将会崩溃。
&&&&&&&& NIOS II上的uC/OS-II移植,其实就这么简单。当然了,如果要不断的深入进去,一定大有学问。
旗下网站:
与非门科技(北京)有限公司 All Rights Reserved.
京ICP证:070212号
北京市公安局备案编号: 京ICP备:号//建立一个新任务。与OSTaskCreate()不同的是,OSTaskCreateExt()允许用户设置更多的细节 &
//内容。任务的建立可以在多任务环境启动之前,也可以在正在运行的任务中建立,但中断处理 &
//程序中不能建立新任务。一个任务必须为无限循环结构,且不能有返回点。 &
#if OS_TASK_CREATE_EXT_EN & 0 &&&&&&&&&&&&&&&//允许生成OSTaskCreateExt()函数 &
INT8U &OSTaskCreateExt (void &&(*task)(void *pd), &&//建立扩展任务(任务代码指针) &
&&&&&&&&&&&&&&&&&&&&&&&&void &&&*pdata, &&&&&&&&&&&&//传递参数指针 &
&&&&&&&&&&&&&&&&&&&&&&&&OS_STK &*ptos, &&&&&&&&&&&&&//分配任务堆栈栈顶指针 &
&&&&&&&&&&&&&&&&&&&&&&&&INT8U &&&prio, &&&&&&&&&&&&&//分配任务优先级 &
&&&&&&&&&&&&&&&&&&&&&&&&INT16U &&id, &&&&&&&&&&&&&&&//(未来的)优先级标识(与优先级相同)
&&&&&&&&&&&&&&&&&&&&&&&&OS_STK &*pbos, &&&&&&&&&&&&&//分配任务堆栈栈底指针 &
&&&&&&&&&&&&&&&&&&&&&&&&INT32U &&stk_size, &&&&&&&&&//指定堆栈的容量(检验用) &
&&&&&&&&&&&&&&&&&&&&&&&&void &&&*pext, &&&&&&&&&&&&&//指向用户附加的数据域的指针
&&&&&&&&&&&&&&&&&&&&&&&&INT16U &&opt) &&&&&&&&&&&&&&//建立任务设定选项 &
#if OS_CRITICAL_METHOD == 3 &&&&&&&&&&&&&&&&&//中断函数被设定为模式3 &
&&&&OS_CPU_SR &cpu_ &
&&&&OS_STK &&&* &&&&&&&&&&&&&&&&&&&&&&&&//初始化任务堆栈指针变量,返回新的栈顶指针 &
&&&&INT8U &&&&& &&&&&&&&&&&&&&&&&&&&&&&&//定义(获得定义初始化任务控制块)是否成功 &
#if OS_ARG_CHK_EN & 0 &&&&&&&//所有参数必须在指定的参数内 &
&&&&if (prio & OS_LOWEST_PRIO) { &&&&&&&&&&&&//检查任务优先级是否合法 &
&&&&&&&&return (OS_PRIO_INVALID); &&&&&&&&&&&//参数指定的优先级大于OS_LOWEST_PRIO &
&&&&OS_ENTER_CRITICAL(); &&&&&&&//关闭中断 &
&&&&if (OSTCBPrioTbl[prio] == (OS_TCB *)0) { //确认优先级未被使用,即就绪态为0 &
&&&&&&&&OSTCBPrioTbl[prio] = (OS_TCB *)1; &&&//保留这个优先级,将就绪态设为0 &
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&OS_EXIT_CRITICAL(); &&&&//打开中断 &
&&&&&&&&//以下两为1堆栈才能清0 &
&&&&&&&&if (((opt & OS_TASK_OPT_STK_CHK) != 0x0000) || &&//检验任务堆栈,CHK=1 &
&&&&&&&&&&&&((opt & OS_TASK_OPT_STK_CLR) != 0x0000)) { &&//任务建立时是否清0,CLR=1 &
&&&&&&&&&&&&#if OS_STK_GROWTH == 1 &&&&&&&&&//堆栈生长方向 &
&&&&&&&&&&&&(void)memset(pbos, 0, stk_size * sizeof(OS_STK)); &&&&&&//从下向上递增 &
&&&&&&&&&&&&#else &
&&&&&&&&&&&&(void)memset(ptos, 0, stk_size * sizeof(OS_STK)); &&&&&&//从下向下递减 &
&&&&&&&&&&&&#endif &
&&&&&&&&} &
&&&&&&&&psp = (OS_STK *)OSTaskStkInit(task, pdata, ptos, opt); &&&&&//初始化任务堆栈 &
&&&&&&&&err = OS_TCBInit(prio, psp, pbos, id, stk_size, pext, opt); &&&&//获得并初始化任务控制块 &
&&&&&&&&if (err == OS_NO_ERR) { //任务控制初始化成功 &
&&&&&&&&&&&&OS_ENTER_CRITICAL(); &&&&&&&//关闭中断 &
&&&&&&&&&&&&OSTaskCtr++; &&&&&&&&&&&&&&&//任务计数器加1 &
&&&&&&&&&&&&OS_EXIT_CRITICAL(); &&&&&&&&//打开中断 &
&&&&&&&&&&&&if (OSRunning == TRUE) { &&&&&&&&&&&&&//检查是否有(某个)任务在运行 &
&&&&&&&&&&&&&&&&OS_Sched(); &&&&&&&&&&&&&&&&&&&&&&//任务调度,最高任务优先级运行 &
&&&&&&&&&&&&} &
&&&&&&&&} else { &&&&&&&//否则,任务初始化失败 &
&&&&&&&&&&&&OS_ENTER_CRITICAL(); &&&&&&&//关闭中断 &
&&&&&&&&&&&&OSTCBPrioTbl[prio] = (OS_TCB *)0; &&&&&&&&&&&&&&&&//放弃任务,设此任务就绪态为0 &
&&&&&&&&&&&&OS_EXIT_CRITICAL(); &&&&&&&&//打开中断 &
&&&&&&&&} &
&&&&&&&&return (err); &&&&&&//返回(获得并定义初始化任务控制块是否成功) &
&&&&OS_EXIT_CRITICAL(); &&&&//打开中断 &
&&&&return (OS_PRIO_EXIST); &&&&//具有该优先级的任务已经存在 &
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:11078次
排名:千里之外
转载:169篇
(3)(29)(11)(4)(8)(3)(6)(98)(12)君,已阅读到文档的结尾了呢~~
广告剩余8秒
文档加载中
精品:ostaskcreateext ostaskcreatehook ostaskdel pthread create createthread ostasksuspend create createfile create table createevent
扫扫二维码,随身浏览文档
手机或平板扫扫即可继续访问
OSTaskCreate
举报该文档为侵权文档。
举报该文档含有违规或不良信息。
反馈该文档无法正常浏览。
举报该文档为重复文档。
推荐理由:
将文档分享至:
分享完整地址
文档地址:
粘贴到BBS或博客
flash地址:
支持嵌入FLASH地址的网站使用
html代码:
&embed src='/DocinViewer-4.swf' width='100%' height='600' type=application/x-shockwave-flash ALLOWFULLSCREEN='true' ALLOWSCRIPTACCESS='always'&&/embed&
450px*300px480px*400px650px*490px
支持嵌入HTML代码的网站使用
您的内容已经提交成功
您所提交的内容需要审核后才能发布,请您等待!
3秒自动关闭窗口论文:基于μC/OS的嵌入式系统应用开发研究-中大网校论文网}

我要回帖

更多关于 create task 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信