FreeRTOS-任务函数

标签:ret get 相关 main eat 定时器 ref ati 安全

1.任务相关的API函数
函数存在于task.c中,主要的函数有:

xTaskCreate():使用动态的方法创建一个任务;
xTaskCreatStatic():使用静态的方法创建一个任务(用的非常少);
xTaskCreateRestricted():创建一个使用MPU进行限制的任务;
vTaskDelete():删除一个任务;
vTaskSuspend():挂起一个任务;
vTaskResume():恢复一个任务的运行;
vTaskResumeFromISR():中断服务函数中恢复一个任务的运行;
portENABLE_INTERRUPTS():打开FreeRTOS中断;
portDISABLE_INTERRUPTS():关闭freeRTOS中断;
2.动态创建任务
xTaskCreate()函数原型:
BaseType_t xTaskCreate(
TaskFunction_t pvTaskCode,
const char * const pcName,
uint16_t usStackDepth,
void *pvParameters,
UBaseType_t uxPriority,
TaskHandle_t *pvCreatedTask
);
动态创建任务:使用前先判断 #if( configSUPPORT_STATIC_ALLOCATION == 1 ) 是否成立,如果不成立需要在FreeRTOSConfig.h 文件中添加;
#include “FreeRTOS.h”
#include “task.h”

//start_task 任务
void start_task(void *pvParameters); // 任务函数
#define start_task_zise 50 // 任务堆栈的大小
#define start_task_prio 1 // 任务优先级
TaskHandle_t start_task_handler; // 任务句柄

//led1_task 任务
void led1_task(void *pvParameters); // 任务函数
#define led1_task_zise 50 // 任务堆栈的大小
#define led1_task_prio 2 // 任务优先级
TaskHandle_t led1_task_handler; // 任务句柄

int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
uart_init(115200);
delay_init();
LED_Init();

// 创建一个任务 xTaskCreate(任务函数, 任务名, 任务堆栈的大小, 传递给任务函数的参数, 任务优先级, 任务句柄);
xTaskCreate( start_task, "start_stask", start_task_zise, NULL, start_task_prio, &start_task_handler);    

vTaskStartScheduler();        // 开启任务调度
return 0;

}

void start_task( void * pvParameters )
{
taskENTER_CRITICAL(); // 创建临界区
// 创建led1任务
xTaskCreate(led1_task, “led1_task”, start_task_zise, NULL, led1_task_prio, &led1_task_handler);

vTaskDelete(start_task_handler); //删除开始任务
taskEXIT_CRITICAL();    // 退出临界区

}
//LED1任务函数
void led1_task( void * pvParameters )
{
for( ;; )
{
LED0 = ~LED0;
vTaskDelay(1000);
}
}
3.静态创建任务
xTaskCreatStatic()函数原型:
TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode,
const char * const pcName,
const uint32_t ulStackDepth,
void * const pvParameters,
UBaseType_t uxPriority,
StackType_t * const puxStackBuffer,
StaticTask_t * const pxTaskBuffer )
静态创建任务:使用前先判断 #if( configSUPPORT_STATIC_ALLOCATION== 1 ) 是否成立,如果不成立需要在FreeRTOSConfig.h 文件中添加;
在FreeRTOSConfig.h 文件中添加中添加宏后,编译报错:
.\Objects\freeRTOS_sCreate_task.axf: Error: L6218E: Undefined symbol vApplicationGetIdleTaskMemory(referred from tasks.o).
.\Objects\freeRTOS_sCreate_task.axf: Error: L6218E: Undefined symbol vApplicationGetTimerTaskMemory (referred from timers.o).
由于把静态创建的宏给打开了,所以这两个数需要我们自己去实现
// 空闲任务
static StackType_t IdleTaskStack[configMINIMAL_STACK_SIZE];
static StaticTask_t IdleTaskTCB;
// 定时器任务
static StackType_t TimerTaskStack[configTIMER_TASK_STACK_DEPTH];
static StaticTask_t TimerTaskTCB;

// 空闲任务所需内存
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer,
StackType_t **ppxIdleTaskStackBuffer,
uint32_t *pulIdleTaskStackSize )
{
*ppxIdleTaskTCBBuffer = &IdleTaskTCB;
*ppxIdleTaskStackBuffer = IdleTaskStack;
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
}
// 定时器任务所需内存
void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer,
StackType_t **ppxTimerTaskStackBuffer,
uint32_t *pulTimerTaskStackSize )
{
*ppxTimerTaskTCBBuffer = &TimerTaskTCB;
*ppxTimerTaskStackBuffer = TimerTaskStack;
*pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
}
静态创建任务
//start_task 任务
void start_task(void *pvParameters); // 任务函数
#define start_task_zise 50 // 任务堆栈的大小
#define start_task_prio 1 // 任务优先级
StackType_t start_task_stack[start_task_zise]; // 任务控制块大小
StaticTask_t start_task_TCB; // 任务堆栈大小
TaskHandle_t start_task_handler; // 任务句柄

//led1_task 任务
void led1_task(void *pvParameters); // 任务函数
#define led1_task_zise 50 // 任务堆栈的大小
#define led1_task_prio 2 // 任务优先级
StackType_t led1_task_stack[start_task_zise]; // 任务控制块大小
StaticTask_t led1_task_TCB; // 任务堆栈大小
TaskHandle_t led1_task_handler; // 任务句柄

//led2_task 任务
void led2_task(void *pvParameters); // 任务函数
#define led2_task_zise 50 // 任务堆栈的大小
#define led2_task_prio 3 // 任务优先级
StackType_t led2_task_stack[start_task_zise]; // 任务控制块大小
StaticTask_t led2_task_TCB; // 任务堆栈大小
TaskHandle_t led2_task_handler; // 任务句柄

int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
uart_init(115200);
delay_init();
LED_Init();

// 创建一个开始任务
start_task_handler = xTaskCreateStatic( (TaskFunction_t    )start_task,
                                        (char              *)"start_task",
                                        (uint32_t         )start_task_zise,
                                        (void *            )NULL,
                                        (UBaseType_t    )start_task_prio,
                                        (StackType_t *    )start_task_stack,    // 任务控制块大小
                                        (StaticTask_t *    )&start_task_TCB );    // 任务堆栈大小

vTaskStartScheduler();        // 开启任务调度
return 0;

}

void start_task( void * pvParameters )
{
led1_task_handler = xTaskCreateStatic( (TaskFunction_t )led1_task,
(char *)“led1_task”,
(uint32_t )led1_task_zise,
(void * )NULL,
(UBaseType_t )led1_task_prio,
(StackType_t * )led1_task_stack, // 任务控制块大小
(StaticTask_t * )&led1_task_TCB ); // 任务堆栈大小

led2_task_handler = xTaskCreateStatic( (TaskFunction_t    )led2_task,
                                        (char              *)"led2_task",
                                        (uint32_t         )led2_task_zise,
                                        (void *            )NULL,
                                        (UBaseType_t    )led2_task_prio,
                                        (StackType_t *    )led2_task_stack,    // 任务控制块大小
                                        (StaticTask_t *    )&led2_task_TCB );    // 任务堆栈大小
vTaskDelete(start_task_handler);

}
void led1_task( void * pvParameters )
{
for( ;; )
{
LED0 = ~LED0;
vTaskDelay(200);
}
}
void led2_task( void * pvParameters )
{
for( ;; )
{
LED1 = ~LED1;
vTaskDelay(1000);
}
}
4.删除任务
void vTaskDelete( TaskHandle_t xTaskToDelete ) PRIVILEGED_FUNCTION;
5.任务挂起
void vTaskSuspend( TaskHandle_t xTaskToSuspend ) PRIVILEGED_FUNCTION;
6.任务恢复
void vTaskResume( TaskHandle_t xTaskToResume ) PRIVILEGED_FUNCTION;
挂起、恢复代码如下:
//key_task 任务
void key_task(void *pvParameters); // 任务函数
#define key_task_zise 50 // 任务堆栈的大小
#define key_task_prio 4 // 任务优先级
TaskHandle_t key_task_handler; // 任务句柄

void start_task( void * pvParameters )
{
taskENTER_CRITICAL(); // 创建临界区

// 创建按键检查任务
xTaskCreate((TaskFunction_t    )key_task,
            (const char *     )"key_task",
            (uint16_t        )key_task_zise,
            (void *            )NULL,
            (UBaseType_t    )key_task_prio,
            (TaskHandle_t * )&key_task_handler);
    ......
vTaskDelete(start_task_handler); //删除开始任务
taskEXIT_CRITICAL();    // 退出临界区

}

//key任务函数
void key_task( void * pvParameters )
{
char key;
for( ;; )
{
key = KEY_Scan(0);
switch(key)
{
case KEY0_PRES:
vTaskSuspend(led1_task_handler);
printf(“led1_task Suspended.\n”);
break;
case KEY1_PRES:
vTaskResume(led1_task_handler);
printf(“led1_task Resumed.\n”);
break;
case KEY2_PRES:
vTaskSuspend(led2_task_handler);
printf(“led2_task Suspended.\n”);
break;
case WKUP_PRES:
vTaskResume(led2_task_handler);
printf(“led2_task Resumed.\n”);
break;
}
vTaskDelay(10); //延时10ms
}
}
7.FreeRTOS开关中断
freeRTOS管理的中断优先级为 5~15,这是在freeRTOSConfig.h中设置的。
#ifdef __NVIC_PRIO_BITS
#define configPRIO_BITS __NVIC_PRIO_BITS
#else
#define configPRIO_BITS 4
#endif

#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15 //中断最低优先级
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5 //系统可管理的最高中断优先级
#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS)
设置好宏后,低于configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY优先级的中断可以安全的调用FreeRTOS的API函数(xxFromISR()函数);
高于configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY优先级的中断不能被FreeRTOS禁止,中断服务函数也不能调用FreeRTOS的API函数。技术分享图片
由于高于configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY的优先级不会被FreeRTOS内核屏蔽,因此那些对实时性要求严格的任务可以使用这些优先级(0~4),比如四轴飞行器中的避障检测;
//start_task 任务
void start_task(void *pvParameters); // 任务函数
#define start_task_zise 50 // 任务堆栈的大小
#define start_task_prio 1 // 任务优先级
TaskHandle_t start_task_handler; // 任务句柄

//interrupt_task 任务
void interrupt_task(void *pvParameters); // 任务函数
#define interrupt_task_zise 50 // 任务堆栈的大小
#define interrupt_task_prio 2 // 任务优先级
TaskHandle_t interrupt_task_handler; // 任务句柄

int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
uart_init(115200);
delay_init();
LED_Init();
TIM3_Int_Init(10000-1,7200-1); //设置定时器3的抢占优先级为 4
TIM5_Int_Init(10000-1,7200-1); //设置定时器5的抢占优先级为 5

// 创建一个任务
xTaskCreate((TaskFunction_t    )start_task,            // 任务函数    
            (const char *     )"start_stask",            // 任务名    
            (uint16_t        )start_task_zise,        // 任务堆栈的大小
            (void *            )NULL,                    // 传递给任务函数的参数
            (UBaseType_t    )start_task_prio,        // 任务优先级
            (TaskHandle_t * )&start_task_handler);    // 任务句柄

vTaskStartScheduler();        // 开启任务调度
return 0;

}

void start_task( void * pvParameters )
{
taskENTER_CRITICAL(); // 创建临界区
// 创建led1任务
xTaskCreate((TaskFunction_t )interrupt_task,
(const char * )“interrupt_task”,
(uint16_t )interrupt_task_zise,
(void * )NULL,
(UBaseType_t )interrupt_task_prio,
(TaskHandle_t * )&interrupt_task_handler);

// 创建led2任务            

vTaskDelete(start_task_handler); //删除开始任务
taskEXIT_CRITICAL();    // 退出临界区

}
//interrupt任务函数
void interrupt_task( void * pvParameters )
{
int i = 0;
for( ;; )
{
if(i == 5)
{
printf(“关闭中断!!!.\n”);
portDISABLE_INTERRUPTS();
delay_xms(5000); // delay_xms执行的时候不会执行任何任务调度
printf(“开中断!!!.\n”);
portENABLE_INTERRUPTS();
}
printf(“interrupt task is %d runing.\n”, i);
LED0 = ~LED0;
vTaskDelay(1000);
i++;
}
}
8.临界段
临界段是指:那些必须完整运行,不能被打断的代码段,比如有的外设的初始化需要严格的时序,初始化过程中不能被打断。FreeRTOS在进入临界段代码的时候需要关闭中断,当处理完临界段代码以后再打开中断。
FreeRTOS中与临界段有关的函数有4个,定义于task.h中:
#define taskENTER_CRITICAL() portENTER_CRITICAL()
#define taskENTER_CRITICAL_FROM_ISR() portSET_INTERRUPT_MASK_FROM_ISR()

#define taskEXIT_CRITICAL() portEXIT_CRITICAL()
#define taskEXIT_CRITICAL_FROM_ISR( x ) portCLEAR_INTERRUPT_MASK_FROM_ISR( x )
taskENTER_CRITICAL():进入任务级的临界区;  
taskEXIT_CRITICAL():退出任务级的临界区;
void start_task( void * pvParameters )
{
taskENTER_CRITICAL(); // 进入临界区
// 创建led1任务
xTaskCreate((TaskFunction_t )interrupt_task,
(const char * )“interrupt_task”,
(uint16_t )interrupt_task_zise,
(void * )NULL,
(UBaseType_t )interrupt_task_prio,
(TaskHandle_t * )&interrupt_task_handler);

// 创建led2任务            

vTaskDelete(start_task_handler); //删除开始任务
taskEXIT_CRITICAL();    // 退出临界区

}
taskEXIT_CRITICAL_FROM_ISR():进入中断级临界区;
taskENTER_CRITICAL_FROM_ISR():退出中断级临界区;
//定时器3中断服务程序
void TIM3_IRQHandler(void) //TIM3中断
{
int status_value;
if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //检查TIM3更新中断发生与否
{
status_value = taskENTER_CRITICAL_FROM_ISR(); //进入临界区
printf(“定时器3发生中断.\n”);
LED1=!LED1;
TIM_ClearITPendingBit(TIM3, TIM_IT_Update ); //清除TIMx更新中断标志
taskEXIT_CRITICAL_FROM_ISR(status_value); //退出临界区
}
}

//定时器3中断服务程序
void TIM5_IRQHandler(void) //TIM3中断
{
int status_value;
if (TIM_GetITStatus(TIM5, TIM_IT_Update) != RESET) //检查TIM5更新中断发生与否
{
status_value = taskENTER_CRITICAL_FROM_ISR(); //进入临界区
printf(“定时器5发生中断.\n”);
LED1=!LED1;
TIM_ClearITPendingBit(TIM5, TIM_IT_Update ); //清除TIMx更新中断标志
taskEXIT_CRITICAL_FROM_ISR(status_value); //退出临界区
}
}

2、FreeRTOS任务相关API函数

标签:ret get 相关 main eat 定时器 ref ati 安全

原文:https://www.cnblogs.com/icefree/p/8684859.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值