HNUST嵌入式系统实验七 —任务调度
了解嵌入式实时操作系统的基本概念和特点,并能够运用实时操作系统编写嵌入式程序。同时,通过本实验让学生对实时性和可靠性的要求有更深入的理解。实验的内容包括以下几个方面:1. 实时操作系统的概念和基本特点,嵌入式操作系统移植;2. 实时操作系统的任务调度机制;3. 实时操作系统的信号量和消息队列;4. 在实时操作系统 uC/os 上编写一个简单的示例程序包含三个以上任务,在信号量、邮箱、消息队列任等
·
不介绍了,直接上代码吧
/**
****************************************************************************************************
* @file main.c
* @author HNUST
* @version V1.0
* @date 2024-07-21
* @brief EBD-A23 HAL库版UCOSII V2.93.01 任务调度
* @license Copyright (c) 2024, 湖南科技大学计算机学院
****************************************************************************************************
*/
#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/LED/led.h"
/*uC/OS-II*********************************************************************************************/
#include "os.h"
#include "cpu.h"
//设置任务堆栈大小
#define LED0_STK_SIZE 64
#define LED1_STK_SIZE 64
#define LED2_STK_SIZE 64
#define START_STK_SIZE 128
//设置任务优先级
#define LED0_TASK_Prio 9
#define LED1_TASK_Prio 7
#define LED2_TASK_Prio 5
#define START_TASK_Prio 10
/* 定义消息队列 */
#define QUEUE_SIZE 10 // 队列大小
OS_EVENT *MsgQueue; // 消息队列指针
void *MsgQueueTbl[QUEUE_SIZE]; // 消息队列存储区
/* 新增任务的堆栈大小 */
#define PRODUCER_STK_SIZE 64
#define CONSUMER_STK_SIZE 64
/* 新增任务的优先级 */
//#define PRODUCER_TASK_Prio 6 // 介于 LED1(5) 和 LED2(7) 之间
//
/* 新增任务的堆栈 */
OS_STK TASK_PRODUCER_STK[PRODUCER_STK_SIZE];
OS_STK TASK_CONSUMER_STK[CONSUMER_STK_SIZE]; // 注意拼写:CONSUMER(原错误是 CONSUMER_STK_SIZE)
//任务堆栈
OS_STK TASK_LED2_STK[LED2_STK_SIZE];
OS_STK TASK_LED1_STK[LED1_STK_SIZE];
OS_STK TASK_LED0_STK[LED0_STK_SIZE];
OS_STK TASK_START_STK[START_STK_SIZE];
//任务申明
void TaskStart(void *pdata);
void TaskLed0(void *pdata);
void TaskLed1(void *pdata);
void TaskLed2(void *pdata);
/* 新增任务声明 */
//void TaskProducer(void *pdata);
//void TaskConsumer(void *pdata);
//系统时钟配置函数
void SysTick_Configuration(void);
INT32U segi = 0;
int main(void)
{
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
delay_init(72); /* 延时初始化 */
LED_Init(); /* 初始化LED */
OSInit();
MsgQueue = OSQCreate(&MsgQueueTbl[0], QUEUE_SIZE); // 创建消息队列
OSTaskCreate( TaskStart, //task pointer
(void *)0, //parameter
(OS_STK *)&TASK_START_STK[START_STK_SIZE - 1],//task stack top pointer
START_TASK_Prio ); //task priority
OSStart();
return 0;
}
//开始任务
void TaskStart(void * pdata)
{
OS_CPU_SR cpu_sr = 0u;
pdata = pdata;
OS_ENTER_CRITICAL();
OSTaskCreate(TaskLed0, (void * )0, (OS_STK *)&TASK_LED0_STK[LED0_STK_SIZE - 1], LED0_TASK_Prio);
OSTaskCreate(TaskLed1, (void * )0, (OS_STK *)&TASK_LED1_STK[LED1_STK_SIZE - 1], LED1_TASK_Prio);
OSTaskCreate(TaskLed2, (void * )0, (OS_STK *)&TASK_LED2_STK[LED2_STK_SIZE - 1], LED2_TASK_Prio);
OSTaskSuspend(START_TASK_Prio); //suspend but not delete
OS_EXIT_CRITICAL();
}
//任务1
void TaskLed0(void *pdata)
{
INT8U err;
INT8U msg = 0; // 消息内容(数码管要显示的值)
while(1)
{
SetLed(segi, msg);
GPIOB->ODR = segi;
// 发送消息到队列
OSQPost(MsgQueue, (void *)&msg);
msg++; // 每次发送后消息值+1
if (msg > 2) msg = 0; // 限制在0-2范围内
segi++;
if(segi > 7) segi = 0;
OSTimeDlyHMSM(0, 0, 0, 900);
}
}
//任务2
void TaskLed1(void *pdata)
{
INT8U err;
INT8U *received_msg;
while(1)
{
// 接收消息(阻塞方式,如果没有消息则等待)
received_msg = (INT8U *)OSQPend(MsgQueue, 0, &err);
if (err == OS_ERR_NONE)
{
// 确保接收到的值在0-2范围内
INT8U display_val = *received_msg % 3; // 取模确保值在0-2
SetLed(segi, display_val); // 使用接收到的消息更新显示
GPIOB->ODR = segi;
}
if(segi > 7) segi = 0;
OSTimeDlyHMSM(0, 0, 0, 600);
}
}
//任务3
void TaskLed2(void *pdata)
{
}
更多推荐



所有评论(0)