当前位置:   article > 正文

【正点原子STM32连载】 第五十五章 FreeRTOS移植实验 摘自【正点原子】APM32E103最小系统板使用指南

【正点原子STM32连载】 第五十五章 FreeRTOS移植实验 摘自【正点原子】APM32E103最小系统板使用指南

1)实验平台:正点原子APM32E103最小系统板
2)平台购买地址:https://detail.tmall.com/item.htm?id=609294757420
3)全套实验源码+手册+视频下载地址: http://www.openedv.com/docs/boards/xiaoxitongban

第五十五章 FreeRTOS移植实验

前面章节中的实验都是在裸机环境下实现,本章将介绍FreeRTOS的简单使用,对RTOS感兴趣的读者,可以参考正点原子推出的FreeRTOS或µC/OS-III的全套教程资料,包含教学视频、开发指南并配套有例程源码。通过本章的学习,读者将学习到FreeRTOS的简单应用。
本章分为如下几个小节:
55.1 硬件设计
55.2 程序设计
55.3 下载验证

55.1 硬件设计
55.1.1 例程功能

  1. LED0由LED0任务控制80毫秒亮,920毫秒灭
  2. LED1由LED1任务控制300毫秒亮,300毫秒灭
    55.1.2 硬件资源
  3. LED
    LED0 - PB5
    LED1 - PE5
    55.1.3 原理图
    本章实验使用的FreeRTOS为软件库,因此没有对应的连接原理图。
    55.2 程序设计
    55.2.1 FreeRTOS的移植
    FreeRTOS的源码可参考正点原子推出的《FreeRTOS开发指南》或相关的配套教学视频至FreeRTOS的官网下载,也可在A盘6,软件资料FreeRTOS学习资料中找到。
    FreeRTOS的移植请读者参考正点原子推出的《FreeRTOS开发指南》或相关的配套教学视频,在上述资料中,对FreeRTOS的移植和使用都做了非常详细地介绍,是入门FreeRTOS的一个非常好的选择。
    55.2.2 实验应用代码
    本章实验的应用代码,如下所示:
/* START_TASK任务配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define START_TASK_PRIO 1               /* 任务优先级 */
#define START_STK_SIZE  128             /* 任务堆栈大小 */
TaskHandle_t StartTask_Handler;         /* 任务句柄 */
void start_task(void *pvParameters);    /* 任务函数 */

/* LED0任务配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define LED0_PRIO      2                /* 任务优先级 */
#define LED0_STK_SIZE  128              /* 任务堆栈大小 */
TaskHandle_t LED0Task_Handler;          /* 任务句柄 */
void led0_task(void *pvParameters);     /* 任务函数 */

/* LED1任务配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define LED1_PRIO      2                				/* 任务优先级 */
#define LED1_STK_SIZE  128              				/* 任务堆栈大小 */
TaskHandle_t LED1Task_Handler;          				/* 任务句柄 */
void led1_task(void *pvParameters);     				/* 任务函数 */

int main(void)
{
    NVIC_ConfigPriorityGroup(NVIC_PRIORITY_GROUP_4);  	/* 设置中断优先级分组为组4 */
    sys_apm32_clock_init(15);                         	/* 配置系统时钟 */
    delay_init(120);                                  	/* 初始化延时功能 */
    usart_init(115200);                               	/* 初始化串口 */
    led_init();                                       	/* 初始化LED */
    
    xTaskCreate((TaskFunction_t )start_task,          	/* 任务函数 */
                (const char*    )"start_task",        	/* 任务名称 */
                (uint16_t       )START_STK_SIZE,      	/* 任务堆栈大小 */
                (void*          )NULL,                	/* 传入给任务函数的参数 */
                (UBaseType_t    )START_TASK_PRIO,		/* 任务优先级 */
                (TaskHandle_t*  )&StartTask_Handler)/* 任务句柄 */
    vTaskStartScheduler();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

从上面的代码中可以看出,在完成必要的初始化后,便创建了“start_task”任务,随后便开始了任务调度,“start_task”任务的入口函数为函数start_task(),如下所示:

/**
 * @brief       start_task
 * @param       pvParameters: 传入参数(未用到)
 * @retval      无
 */
void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();           /* 进入临界区 */
    
    /* 创建LED0任务 */
    xTaskCreate((TaskFunction_t )led0_task,
                (const char*    )"led0_task",
                (uint16_t       )LED0_STK_SIZE,
                (void*          )NULL,
                (UBaseType_t    )LED0_PRIO,
                (TaskHandle_t*  )&LED0Task_Handler);
                
    /* 创建LED1任务 */
    xTaskCreate((TaskFunction_t )led1_task,
                (const char*    )"led1_task",
                (uint16_t       )LED1_STK_SIZE,
                (void*          )NULL,
                (UBaseType_t    )LED1_PRIO,
                (TaskHandle_t*  )&LED1Task_Handler);
                
    vTaskDelete(StartTask_Handler); /* 删除开始任务 */
    taskEXIT_CRITICAL();            /* 退出临界区 */
}
从上面的代码中可以看出,“start_task”任务主要用于创建“led0_task”和“led1_task”任务,这两个任务的入口函数,如下所示:
/**
 * @brief       LED0任务
 * @param       pvParameters: 传入参数(未用到)
 * @retval      无
 */
void led0_task(void *pvParameters)
{
    while(1)
    {
        LED0(0);
        vTaskDelay(80);
        LED0(1);
        vTaskDelay(920);
    }
}

/**
 * @brief       LED1任务
 * @param       pvParameters: 传入参数(未用到)
 * @retval      无
 */
void led1_task(void *pvParameters)
{
    while(1)
    {
        LED1(0);
        vTaskDelay(300);
        LED1(1);
        vTaskDelay(300);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60

可以看到,两个任务分别控制开发板板载的两个LED闪烁,但其闪烁的频率和亮灭时间都不相同,因此因该能看到开发板板载的两个LED以不同的频率和不同的亮灭时间进行闪烁。
55.3 下载验证
在完成编译和烧录操作后,可以看到开发板板载的两个LED以不用的频率和不同的亮灭时间闪烁着,其中LED0在一个闪烁周期内的亮灭时间约分别为80毫秒和920毫秒,LED1在一个闪烁周期内的亮灭时间约分别为300毫秒和300毫秒。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/172505
推荐阅读
相关标签
  

闽ICP备14008679号