嵌入式操作系统实验:实验一:UCOSII任务调度

实验一:UCOSII任务调度

1、实验目的

深入理解STM32的UCOSII的原理和编程方法

2、实验内容

编写任务调度3,通过调用这个任务来控制LED灯的亮灭情况。

3、实验原理和实验步骤

实验原理:

(1).UCOS-II初始化: 首先,需要在嵌入式系统中初始化UCOS-II内核,包括任务调度器和系统时钟。这通常在系统启动时进行。

(2).创建LED控制任务: 创建一个专门的任务,该任务的目的是控制LED灯的状态。这个任务将在一个循环中不断切换LED的状态,使其亮和灭交替进行。

(3).LED硬件控制: 在嵌入式系统中,LED通常由一个GPIO引脚控制。LED亮或灭的控制通过设置GPIO引脚的状态来实现。

(4).任务调度: UCOS-II会根据任务的优先级和调度算法来管理任务的执行。LED控制任务将按照其所分配的时间片或优先级被周期性地调度执行。

实验步骤:

下面是通过UCOS-II任务调度来控制LED灯亮灭情况的一般步骤:

(1).初始化UCOS-II: 在系统启动时,初始化UCOS-II内核。这包括配置系统时钟、任务管理器和创建任务。

(2).创建LED3控制任务: 创建一个LED3控制任务,该任务的代码负责控制LED灯的状态切换。任务可以是无限循环的,交替地将LED引脚的状态设置为高和低,从而实现LED的闪烁效果。

(3).LED引脚配置: 在初始化过程中,需要将与LED连接的GPIO引脚配置为输出模式,以便通过设置引脚状态来控制LED的亮灭。

(4).任务调度: UCOS-II会按照任务的优先级和时间片轮转算法来调度任务的执行。LED控制任务将按照其设置的优先级或时间片被调度执行。

(5).在 PC机的MDK开发环境中编写UCOS-II初始化程序,调试无误后经编译生成.hex文件,通过串口下载到STM32实验平台上运行,观察运行结果。

4、问题分析及算法描述

本实验主要是编写LED任务调度3,通过这个任务调度来控制LED灯的亮灭情况,其整体流程图如下:

图1 整体流程图

1)首先我们要对UCOSII进行任务设置,配置任务的优先级、堆栈大小以及堆栈数组。任务函数将在任务被调度时执行,用于控制LED的行为:

主要代码如下:

//LED2任务

//设置任务优先级

#define LED2_TASK_PRIO        5

//设置任务堆栈大小

#define LED2_STK_SIZE   64

//任务堆栈

OS_STK LED2_TASK_STK[LED2_STK_SIZE];

//任务函数

void led2_task(void *pdata);

以下是对这段代码的解释:LED2_TASK_PRIO:这是宏定义,表示了任务的优先级。在uC/OS-II中,任务的优先级决定了任务在多任务系统中的执行顺序。较低数值的优先级表示较高的任务优先级,任务会在同一时间片内选择优先级最高的任务来执行。在这里,LED2任务的优先级被设置为5。LED2_STK_SIZE:同样是宏定义,表示任务堆栈的大小。任务堆栈用于存储任务执行时的局部变量、返回地址和其他执行上下文信息。较大的堆栈允许任务处理更多的函数调用和局部变量,但也会占用更多的内存。在这里,LED2任务的堆栈大小被设置为64个字。OS_STK LED2_TASK_STK[LED2_STK_SIZE]:这是用于存储LED2任务的堆栈数组。它的大小由LED2_STK_SIZE宏定义决定,因此在这里创建了一个包含64个元素的堆栈数组。void led2_task(void *pdata):这是LED2任务的函数定义。LED2任务是一个C函数,它接受一个void指针作为参数,通常用于传递任务特定的数据。在任务函数内,将编写LED控制逻辑,以实现LED的控制行为。任务函数会被uC/OS-II的任务调度器调用,以便在系统运行时执行该任务。

2)开始任务。它创建了三个任务led0_task、led1_task和led2_task,然后挂起了当前的启动任务,使得其他任务可以开始执行。

主要代码如下:

//开始任务

void start_task(void *pdata)

{

    OS_CPU_SR cpu_sr=0;

pdata = pdata;

   OS_ENTER_CRITICAL(); //进入临界区(无法被中断打断)    

  OSTaskCreate(led0_task,(void *)0,(OS_STK*)&LED0_TASK_STK[LED0_STK_SIZE-1],LED0_TASK_PRIO);    

  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);

OSTaskSuspend(START_TASK_PRIO); //挂起起始任务.

OS_EXIT_CRITICAL(); //退出临界区(可以被中断打断)

}

下面是对该算法的解释:

start_task是一个uC/OS-II任务,用于系统启动时进行一些初始化工作。OS_CPU_SR cpu_sr=0;:定义了一个CPU寄存器,用于保存和恢复中断状态。pdata = pdata;:这行代码看起来似乎是对pdata进行了自赋值的操作,可能是出于保持编译器不生成未使用变量的警告而进行的操作。但实际上这行代码没有实际的功能作用。OS_ENTER_CRITICAL();:这个宏用于进入临界区,保证在此期间不会被中断打断。这是为了保证在对操作系统进行一些关键性操作时不受其他任务的干扰。OSTaskCreate(led0_task,(void*)0,(OS_STK*)&LED0_TASK_STK[LED0_STK_SIZE1],LED0_TASK_PRIO);:这行代码创建了一个名为led0_task的任务,设置了任务的堆栈、参数以及优先级。OSTaskCreate(led1_task,(void *)0,(OS_STK*)&LED1_TASK_STK[LED1_STK_SIZE-1],LED1_TASK_PRIO);:同样,这行代码创建了一个名为led1_task的任务,设置了任务的堆栈、参数以及优先级。OSTaskCreate(led2_task,(void *)0,(OS_STK*)&LED2_TASK_STK[LED2_STK_SIZE-1],LED2_TASK_PRIO);:这行代码创建了一个名为led2_task的任务,设置了任务的堆栈、参数以及优先级。OSTaskSuspend(START_TASK_PRIO);:这行代码挂起了当前的启动任务,意味着这个启动任务在这一步之后不会再被执行。OS_EXIT_CRITICAL();:这个宏用于退出临界区,表示之后的代码可以被中断打断。

流程图2开启任务

3)这段代码是一个典型的嵌入式系统中的任务(task),主要用于控制LED2任务的状态。

主要代码如下:

//LED2任务

void led2_task(void *pdata)

{

while(1)

{

LED0=0;

LED1=0;

delay_ms(300);

LED0=0;

LED1=1;

delay_ms(1500);

}

}

下面是对这个算法的描述:void led2_task(void *pdata): 这是LED2任务的入口函数,它接受一个pdata参数,尽管在任务函数内部并没有使用到该参数。while(1): 这是一个无限循环,表示LED2任务会一直执行下去。LED0=0; 和 LED1=1: 这两行代码设置LED0为低电平(通常表示LED打开),同时设置LED1为高电平(通常表示LED关闭),用于控制LED灯的亮灭。delay_ms(300): 这行代码调用了一个延时函数delay_ms,将任务挂起(或者说暂停执行)300毫秒。在这段时间内,LED1、LED0都保持低电平,模拟了LED0和LED1亮3秒。LED0=0; 和 LED1=1: 这两行代码将LED0和LED1分别设置为低电平和高电平,表示LED0打开,LED1关闭。delay_ms(1500): 这行代码再次调用延时函数,将任务挂起1.5秒。在这段时间内,LED0是亮的。

流程图3 LED2任务

5、实验结果

实验结果如图4所示:

图4 实验结果

实验结果描述:从实验结果图中我们可以看出,首先LED0和LED1都接低电平,都同时闪烁。过了300ms延迟后,LED0接低电平,LED1接高电平,LED0亮,LED1灭。再过1500ms延迟后,LED0与LED1再次闪烁。以此循环反复,图中绿灯代表LED0,红灯代表LED1。

6、分析与心得

通过本次UCOSII任务调度实验,我成功的设计了一个任务调度3,来控制LED灯的亮灭情况,并且通过LED灯的亮灭情况,来验证我们程序的正确性。

  • 54
    点赞
  • 54
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值