为什么不能实现时间片轮换
#include "stm32f10x.h" // Device header#include "Delay.h"
#include "LED.h"
#include "key.h"
#include "FreeRTOS.h"
#include "task.h"
#include<stdio.h>
portCHAR flag1;
portCHAR flag2;
TaskHandle_t Task1_Handle;
#define TASK1_STACK_SIZE 128
StackType_t Task1Stack;
StaticTask_t Task1TCB;
TaskHandle_t Task2_Handle;
#define TASK2_STACK_SIZE 128
StackType_t Task2Stack;
StaticTask_t Task2TCB;
/*
*************************************************************************
* 函数声明
*************************************************************************
*/
void delay (uint32_t count);
void Task1_Entry(void *p_arg);
void Task2_Entry(void *p_arg);
/*
************************************************************************
* main函数
************************************************************************
*/
int main(void)
{
/* 硬件初始化 */
led_init();
/* 将硬件相关的初始化放在这里,如果是软件仿真则没有相关初始化代码 */
/* 创建任务 */
Task1_Handle = xTaskCreateStatic( (TaskFunction_t)Task1_Entry, /* 任务入口 */
(char *)"Task1", /* 任务名称,字符串形式 */
(uint32_t)TASK1_STACK_SIZE , /* 任务栈大小,单位为字 */
(void *) NULL, /* 任务形参 */
(UBaseType_t) 9, /* 任务优先级,数值越大,优先级越高 */
(StackType_t *)Task1Stack, /* 任务栈起始地址 */
(StaticTask_t *)&Task1TCB ); /* 任务控制块 */
Task2_Handle = xTaskCreateStatic( (TaskFunction_t)Task2_Entry, /* 任务入口 */
(char *)"Task2", /* 任务名称,字符串形式 */
(uint32_t)TASK2_STACK_SIZE , /* 任务栈大小,单位为字 */
(void *) NULL, /* 任务形参 */
(UBaseType_t) 9, /* 任务优先级,数值越大,优先级越高 */
(StackType_t *)Task2Stack, /* 任务栈起始地址 */
(StaticTask_t *)&Task2TCB ); /* 任务控制块 */
//if(NULL != Task2_Handle)/* 创建成功 */
/* 启动调度器,开始多任务调度,启动成功则不返回 */
vTaskStartScheduler();
for(;;)
{
/* 系统启动成功不会到达这里 */
}
}
/*
*************************************************************************
* 函数实现
*************************************************************************
*/
void delay (uint32_t count)
{
for(; count!=0; count--);
}
/* 任务1 */
void Task1_Entry(void *p_arg)
{
for( ;; )
{
led2_on();
Delay_s(2);
led2_off();
Delay_s(2);
}
}
/* 任务2 */
void Task2_Entry(void *p_arg)
{
for( ;; )
{
led1_on();
Delay_s(2);
led1_off();
Delay_s(2);
}
}
/* 获取空闲任务的内存 */
StackType_t IdleTaskStack;
StaticTask_t IdleTaskTCB;
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer,
StackType_t **ppxIdleTaskStackBuffer,
uint32_t *pulIdleTaskStackSize )
{
*ppxIdleTaskTCBBuffer=&IdleTaskTCB;
*ppxIdleTaskStackBuffer=IdleTaskStack;
*pulIdleTaskStackSize=configMINIMAL_STACK_SIZE;
}
StaticTask_t Timer_Task_TCB;
StackType_t Timer_Task_Stack;
void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer,
StackType_t **ppxTimerTaskStackBuffer,
uint32_t *pulTimerTaskStackSize)
{
*ppxTimerTaskTCBBuffer=&Timer_Task_TCB;/* 任务控制块内存 */
*ppxTimerTaskStackBuffer=Timer_Task_Stack;/* 任务堆栈内存 */
*pulTimerTaskStackSize=configTIMER_TASK_STACK_DEPTH;/* 任务堆栈大小 */
}
为什么这个代码只能使得task1的led灯亮,而不是两个灯都亮
Delay_s怎么实现的 #include "stm32f10x.h"
/**
* @brief微秒级延时
* @paramxus 延时时长,范围:0~233015
* @retval 无
*/
void Delay_us(uint32_t xus)
{
SysTick->LOAD = 72 * xus; //设置定时器重装值
SysTick->VAL = 0x00; //清空当前计数值
SysTick->CTRL = 0x00000005; //设置时钟源为HCLK,启动定时器
while(!(SysTick->CTRL & 0x00010000)); //等待计数到0
SysTick->CTRL = 0x00000004; //关闭定时器
}
/**
* @brief毫秒级延时
* @paramxms 延时时长,范围:0~4294967295
* @retval 无
*/
void Delay_ms(uint32_t xms)
{
while(xms--)
{
Delay_us(1000);
}
}
/**
* @brief秒级延时
* @paramxs 延时时长,范围:0~4294967295
* @retval 无
*/
void Delay_s(uint32_t xs)
{
while(xs--)
{
Delay_ms(1000);
}
}
调用的这个函数 庄永 发表于 2024-1-21 23:12
Delay_s怎么实现的
#include "stm32f10x.h"
/**
* @brief微秒级延时
* @paramxus 延时时长,范围:0~233015
* @retval 无
*/
void Delay_us(uint32_t xus)
{
SysTick->LOAD = 72 * xus; //设置定时器重装值
SysTick->VAL = 0x00; //清空当前计数值
SysTick->CTRL = 0x00000005; //设置时钟源为HCLK,启动定时器
while(!(SysTick->CTRL & 0x00010000)); //等待计数到0
SysTick->CTRL = 0x00000004; //关闭定时器
}
/**
* @brief毫秒级延时
* @paramxms 延时时长,范围:0~4294967295
* @retval 无
*/
void Delay_ms(uint32_t xms)
{
while(xms--)
{
Delay_us(1000);
}
}
/**
* @brief秒级延时
* @paramxs 延时时长,范围:0~4294967295
* @retval 无
*/
void Delay_s(uint32_t xs)
{
while(xs--)
{
Delay_ms(1000);
}
}
调用的这个函数 task1的灯是常亮还是闪烁?能进FREERTOS的空闲中断吗?宏定义 configUSE_TIME_SLICING 和configUSE_PREEMPTION 怎么配置的? 努力成长 发表于 2024-1-22 09:41
#include "stm32f10x.h"
/**
这几个都没有任务切换的,只是死等,没有把时间让出来给其他任务运行,RTOS的osdelay基本都带任务调度的,比如freertos应该用vTaskDelay这类的,可以看看站里硬汉哥的教程 skyshine 发表于 2024-1-22 14:03
这几个都没有任务切换的,只是死等,没有把时间让出来给其他任务运行,RTOS的osdelay基本都带任务调度的 ...
我理解您的意思,这个我设置成相同优先级了,不是应该时间经过一个时间片就轮换的嘛 鱼小木 发表于 2024-1-22 13:39
task1的灯是常亮还是闪烁?能进FREERTOS的空闲中断吗?宏定义 configUSE_TIME_SLICING 和configUSE_PREEMPT ...
是闪烁的,两个宏定义都配置的是1,没有进入空闲中断,我把他们设置成相同优先级,感觉不用系统的延时函数,也可以切换。下面是我把led灯换成标志位,仿真看到的波形 1A1JMIXMC~FCRU_6P4V)D5L.png 或者先把延时换成vTaskDelay(freertos 自己的挂起延时) 试一下。
鱼小木 发表于 2024-1-22 16:56
或者先把延时换成vTaskDelay(freertos 自己的挂起延时) 试一下。
换成vTaskDelay就可以正常切换了,好奇怪啊,用自定义的延时函数无法从当前任务切换出来,我尝试用比这两个任务优先级高的任务,即使优先级高的任务是就绪态,也无法抢占任务1{:19:} 庄永 发表于 2024-1-21 23:12
Delay_s怎么实现的
大哥一下点到了关键,这个延时函数是基于滴答定时器去实现的,在延时函数结束的时候关闭了滴答定时器,导致无法实现任务切换,是这个意思嘛 configUSE_TIME_SLICING1(使能时间片调度) configUSE_PREEMPTION1 (使能抢占式调度)有没有可能,此时运行的是抢占式,然后你两个任务优先级相同,任务一使用Delay_s这种延时方式的话,一直占用着CPU。可以把两个任务优先级设置为不同,再用Delay_s试下
页:
[1]