UcosII 笔记

    xiaoxiao2021-03-25  128

    ucosii的移植,需要修改三个文件:

    os_cpu.h 定义与编译器无关的数据类型,放置处理器相关代码和几个函数原型。 os_cpu_a.asm 需要汇编完成对一些函数,主要就是任务切换函数; os_cpu_c.c 定义一些用户HOOK函数。

    所谓的任务,即是一个死循环函数。 任务优先级:ucosii不支持多个任务优先级相同,每个任务的优先级必须不一样。 任务堆栈 :存储器中的一片连续存储空间。 任务控制块OS_TCB: 用来记录任务堆栈指针,任务当前状态以及任务优先级等任务属性。每个任务控制块有3个重要参数,任务函数指针、任务堆栈指针和任务优先级。 任务就绪表: 一个位图,记录系统中所有处于就绪状态的任务。 任务调度:一是在任务就绪表中查找优先级最高的就绪任务,二是实现任务的切换。 任务的5种状态:睡眠状态、就绪状态、运行状态、等待状态和中断服务状态。

    在UCOSII中,与任务相关的几个函数

    1,建立任务函数 OSTaskCreate \OSTaskCreateExt(提供一些附件功能) 一般用前者 OSTaskCreate( void(*task)(void*pd),void*pdata,OS_STK*ptos,INTU prio ); task 指向任务代码的指针 pdata 任务开始执行时,传递给任务的参数的指针 ptos 分配给任务的堆栈的栈顶指针 prio 任务的优先级

    堆栈必须声明为OS_STK类型

    2,任务删除函数:把任务置于睡眠状态 INT8U OSTaskDel(INT8U prio); 特别提示:任务不能随便删除,必须确保被删除任务的资源被释放的前提下才能删除! 3,请求删除任务函数 INT8U OSTaskDelReq(INT8U prio); 4,改变任务优先级函数 INT8U OSTaskChangePrio(INT8U oldprio,INT8U newprio); 5, 任务挂起函数 INT8U OSTaskSuspend(INT8U prio); 对挂起的任务解挂,任务可继续运 行。 6,任务恢复函数 INT8U OSTaskResume(INT8U prio); 7, 任务信息查询 INT8U OSTaskQuery(INT8U prio, OS_TCB *pdata);

    在UCOSII中任务优先级可以作为任务的唯一标识

    在STM32上面运行UCOSII的步骤:

    1) 移植UCOSII 2)编写任务函数并设置其堆栈大小和优先级等参数 根据函数的局部变量多少和嵌套层数需求设置堆栈大小,设小梁可能导致CPU进入HardFault状况,有些地方还要注意堆栈字节对齐。 3)初始化UCOSII,并在UCOSII中创建任务 4)启动UCOSII 调用OSStart,启动系统。 还要注意必须对os_cfg.h进行部分配置。

    UCOSII在STM32上的实操

    一,存放源码到项目文件中,建立分组,包含头文件路径。 注意:在core文件夹中不要加入 ucos_ii.c文件 ,其他头文件都要加入。PORT文件夹不要加入os_dbg_r.c 文件。

    二, 注释掉stm32f10x_it.c 文件中的函数 void PendSV_Handler(void)和 void SysTick_Handler(void)

    三, 在sys.h 里面设置SYSTEM_SUPPORT_UCOS 为 1

    四, 编写main.c函数 1,包含头文件 #include”includes.h” ; 2, UCOSII任务堆栈设置 ; 如 //LED1 task -#define LED1_TASK_PRIO 7 //设置任务优先级 -#define LED1_STK_SIZE 64 //设置任务堆栈大小 -OS_STK LED1_TASK_STK[LED1_STK_SIZE]; //创建任务堆栈空间 -void led1_task(void *pdata); //任务函数接口

    3, 编写主函数 初始化延时函数,设置中断分组,初始化硬件接口 在创建start_task前首先调用ucos初始化函数OSInit(), 初始化ucos的所有变量和数据结构。 OSTaskCreate(start_task,(void *)0,(OS_STK *)&START_TASK_STK[START_STK_SIZE-1],START_TASK_PRIO );//创建起始任务 创建完start_task后,调用ucos多任务启动函数OSStart(),然后程序才开始真正运行。 4,start_task 我们在主函数中只创建了start_task一个任务,然后在start_task中再创建另外两个任务,在创建之后将自身挂起。 单独创建start任务是为了提供一个单一任务,实现应用程序开始运行之前的准备工作(如:外设初始化、创建信号量、创建邮箱、创建消息队列、创建信号量集、创建任务和初始化统计任务等等) 在应用程序中有一些代码必须不受干扰地连续运行,这样的代码叫临界段。在执行这些代码之前需要使用关中断指令,执行完代码在解除屏蔽。临界段越短越好。

    每个任务里必须要有延时函数,以释放CPU使用权。

    include “sys.h”

    include “delay.h”

    include “led.h”

    include “beep.h”

    include “key.h”

    include “usart.h”

    include “includes.h”

    //============ÈÎÎñ¶ÑÕ»ÉèÖÃ=================== //START ÈÎÎñ

    define START_TASK_PRIO 10

    define START_STK_SIZE 64

    OS_STK START_TASK_STK[START_STK_SIZE]; void start_task(void *pdata);

    //LED1 task

    define LED1_TASK_PRIO 7

    define LED1_STK_SIZE 64

    OS_STK LED1_TASK_STK[LED1_STK_SIZE]; void led1_task(void *pdata);

    //LED2 task // #define LED2_TASK_PRIO 6 // #define LED2_STK_SIZE 64 // OS_STK LED2_TASK_STK[LED2_STK_SIZE]; // void led2_task(void *pdata);

    //BEEP task

    define BEEP_TASK_PRIO 5

    define BEEP_STK_SIZE 64

    OS_STK BEEP_TASK_STK[BEEP_STK_SIZE]; void beep_task(void *pdata);

    //key task

    define KEY_TASK_PRIO 3

    define KEY_STK_SIZE 64

    OS_STK KEY_TASK_STK[KEY_STK_SIZE]; void key_task(void *pdata);

    int main(void) { delay_init(); NVIC_Configuration(); LED_Init(); BEEP_Init(); KEY_Init(); OSInit(); OSTaskCreate(start_task,(void )0,(OS_STK )&START_TASK_STK[START_STK_SIZE-1],START_TASK_PRIO); OSStart(); }

    void start_task(void *pdata) { OS_CPU_SR cpu_sr=0; pdata = pdata; OSStatInit(); OS_ENTER_CRITICAL(); OSTaskCreate(led1_task,(void )0,(OS_STK )&LED1_TASK_STK[LED1_STK_SIZE-1],LED1_TASK_PRIO); //OSTaskCreate(led2_task,(void )0,(OS_STK )&LED2_TASK_STK[LED2_STK_SIZE-1],LED2_TASK_PRIO); OSTaskCreate(beep_task,(void )0,(OS_STK )&BEEP_TASK_STK[BEEP_STK_SIZE-1],BEEP_TASK_PRIO); OSTaskCreate(key_task,(void )0,(OS_STK )&KEY_TASK_STK[KEY_STK_SIZE-1],KEY_TASK_PRIO); OSTaskSuspend(START_TASK_PRIO); OS_EXIT_CRITICAL(); }

    void led1_task(void *pdata) { while(1) { LED0 = !LED0; LED1 = !LED1; delay_ms(500); }; }

    // void led2_task(void *pdata) // { // while(1) // { // LED1 = 0; // delay_ms(500); // LED1 = 1; // delay_ms(500); // }; // }

    void beep_task(void *pdata) { while(1) { if(OSTaskDelReq(OS_PRIO_SELF)== OS_ERR_TASK_DEL_REQ) { OSTaskDel(OS_PRIO_SELF); } BEEP = 1; delay_ms(60); BEEP = 0; delay_ms(940); }; }

    void key_task(void *pdata) { u8 key; while(1) { key = KEY_Scan(0); if(key==KEY_RIGHT) { OSTaskSuspend(LED1_TASK_PRIO); } else if(key == KEY_LEFT) { OSTaskResume(LED1_TASK_PRIO); } else if(key == KEY_UP) { OSTaskDelReq(BEEP_TASK_PRIO); } else if(key == KEY_DOWN) { OSTaskCreate(beep_task, (void )0,(OS_STK)&BEEP_TASK_STK[BEEP_STK_SIZE-1],BEEP_TASK_PRIO); } delay_ms(10); } }

    转载请注明原文地址: https://ju.6miu.com/read-20924.html

    最新回复(0)