在STM32下完成基于FreeRTOS的任务程序

一、FreeRTOS简介

作为一个轻量级的操作系统,FreeRTOS提供的功能包括:任务管理、时间管理、信号量、消息队列、内存管理、记录功能等,可基本满足较小系统的需要。FreeRTOS内核支持优先级调度算法,每个任务可根据重要程度的不同被赋予一定的优先级,CPU总是让处于就绪态的、优先级最高的任务先运行。FreeRT0S内核同时支持轮换调度算法,系统允许不同的任务使用相同的优先级,在没有更高优先级任务就绪的情况下,同一优先级的任务共享CPU的使用时间。FreeRTOS的内核可根据用户需要设置为可剥夺型内核或不可剥夺型内核。当FreeRTOS被设置为可剥夺型内核时,处于就绪态的高优先级任务能剥夺低优先级任务的CPU使用权,这样可保证系统满足实时性的要求;当FreeRTOS被设置为不可剥夺型内核时,处于就绪态的高优先级任务只有等当前运行任务主动释放CPU的使用权后才能获得运行,这样可提高CPU的运行效率。

二、任务要求

学习FreeRTOS原理,在STM32下完成一个基于FreeRTOS的多任务程序,执行3个周期性task。
task1:每间隔500ms闪烁(变化)一次LED;
task2:每间隔2000ms,向串口发送一次指令数据“helloworld!";
task3:每间隔5000ms,从AHT20采集一次温湿度数据
(不考虑硬件情况,仅写出整个多任务框架模拟代码)。

三、具体过程

1.FreeRTOS相关代码

根据提供的资料,打开相应的keil文件代码。
在这里插入图片描述在这里插入图片描述

2.修改代码

本人是选择led的相关代码进行修改。
(1)task1,每间隔500ms闪烁(变化)一次LED。
①main.c里面找到任务句柄语句,可以不做修改。

static TaskHandle_t LED_Task_Handle = NULL;

②main.c里面找到函数声明语句,可以不做修改。

static void LED_Task(void* pvParameters);

③在AppTaskCreate函数里面,找到创建的LED任务,查看代码。

  xReturn = xTaskCreate((TaskFunction_t )LED_Task, 
                        (const char*    )"LED_Task",
                        (uint16_t       )512,   
                        (void*          )NULL,	
                        (UBaseType_t    )2,	    
                        (TaskHandle_t* )&LED_Task_Handle);
  if(pdPASS == xReturn)
    printf("´´½¨LED_TaskÈÎÎñ³É¹¦!\r\n");

④在程序里面找到相关函数,可以不做修改(完成的功能为间隔500ms,使得LED灯亮或者熄灭)。

static void LED_Task(void* parameter)
{	
    while (1)
    {
        LED1_ON;
        vTaskDelay(500);   
        printf("LED_Task Running,LED1_ON\r\n");
        LED1_OFF;     
        vTaskDelay(500);   		 		
        printf("LED_Task Running,LED1_OFF\r\n");
    }
}

⑤到此有关task1的相关函数完成。
(2)task2,每间隔2000ms,向串口发送一次指令数据“helloworld!"。
①main.c里面找到任务句柄语句,添加如下代码。

static TaskHandle_t HELLO_Task_Handle = NULL; /* HELLO任务句柄*/

②main.c里面找到函数声明,为HELLO任务进行函数声明,不然后面引用会报错。

static void HELLO_Task(void* pvParameters);

③在AppTaskCreate函数里面,创建HELLO任务,可以模仿LED任务进行修改,只需要修改任务入口函数、任务的名称、任务的优先级、任务控制块指针。

  xReturn = xTaskCreate((TaskFunction_t )HELLO_Task, /* 任务入口函数 */
                        (const char*    )"HELLO_Task",/* 任务的名称 */
                        (uint16_t       )512,   /* 任务栈大小 */
                        (void*          )NULL,	/* 任务入口函数 */
                        (UBaseType_t    )3,	    /* 任务的优先级 */
                        (TaskHandle_t*  )&HELLO_Task_Handle);/* 任务控制块指针 */
  if(pdPASS == xReturn)
    printf("创建HELLO_Task任务成功!\r\n");

④在程序添加HELLO_Task函数(完成功能为每间隔2000ms,向串口发送一次指令数据“helloworld!")。

static void HELLO_Task(void* pvParameters)
{
	while(1)
	{
	vTaskDelay(2000);   /* 延时发送2000个tick */
	printf("helloword!");  
	}
}

⑤到此有关task2的相关函数完成。

(3)每间隔5000ms,从AHT20采集一次温湿度数据(不考虑硬件情况,仅写出了整个多任务框架模拟代码)。
①main.c里面找到任务句柄语句,添加如下代码。

static TaskHandle_t AHT_Task_Handle = NULL;

②main.c里面找到函数声明,为HELLO任务进行函数声明。

static void AHT_Task(void* pvParameters);

③在AppTaskCreate函数里面,创建HELLO任务。

 xReturn = xTaskCreate((TaskFunction_t )AHT_Task, 
                        (const char*    )"AHT_Task",
                        (uint16_t       )512,   
                        (void*          )NULL,	
                        (UBaseType_t    )4,	   
                        (TaskHandle_t* )&AHT_Task_Handle);
  if(pdPASS == xReturn)
    printf("´´½¨AHT_TaskÈÎÎñ³É¹¦!\r\n");

④在程序添加AHT_Task函数(每间隔5000ms,从AHT20采集一次温湿度数据)。

static void AHT_Task(void* pvParameters)
{
	while(1)
	{
		vTaskDelay(5000);   /* ÑÓʱ5000¸ötick */
		printf("硬件不全,延迟5000ms输出该提示信息");
	}
}

⑤到此有关task3的相关函数完成。

3.整体main.c代码

/**
  *********************************************************************
  * @file    main.c
  * @author  fire
  * @version V1.0
  * @date    2018-xx-xx
  * @brief   FreeRTOS v9.0.0 + STM32 ¶¯Ì¬´´½¨ÈÎÎñ
  *********************************************************************
  * @attention
  *
  * ʵÑéƽ̨:Ò°»ð STM32ȫϵÁпª·¢°å 
  * ÂÛ̳    :http://www.firebbs.cn
  * ÌÔ±¦    :https://fire-stm32.taobao.com
  *
  **********************************************************************
  */ 
 
/*
*************************************************************************
*                             °üº¬µÄÍ·Îļþ
*************************************************************************
*/ 
/* FreeRTOSÍ·Îļþ */
#include "FreeRTOS.h"
#include "task.h"
/* ¿ª·¢°åÓ²¼þbspÍ·Îļþ */
#include "bsp_led.h"
#include "bsp_usart.h"

/**************************** ÈÎÎñ¾ä±ú ********************************/
/* 
 * ÈÎÎñ¾ä±úÊÇÒ»¸öÖ¸Õ룬ÓÃÓÚÖ¸ÏòÒ»¸öÈÎÎñ£¬µ±ÈÎÎñ´´½¨ºÃÖ®ºó£¬Ëü¾Í¾ßÓÐÁËÒ»¸öÈÎÎñ¾ä±ú
 * ÒÔºóÎÒÃÇÒªÏë²Ù×÷Õâ¸öÈÎÎñ¶¼ÐèҪͨ¹ýÕâ¸öÈÎÎñ¾ä±ú£¬Èç¹ûÊÇ×ÔÉíµÄÈÎÎñ²Ù×÷×Ô¼º£¬ÄÇô
 * Õâ¸ö¾ä±ú¿ÉÒÔΪNULL¡£
 */
 /* ´´½¨ÈÎÎñ¾ä±ú */
static TaskHandle_t AppTaskCreate_Handle = NULL;
/* LEDÈÎÎñ¾ä±ú */
static TaskHandle_t LED_Task_Handle = NULL;
static TaskHandle_t HELLO_Task_Handle = NULL; /* HelloÈÎÎñ¾ä±ú*/
static TaskHandle_t AHT_Task_Handle = NULL;   /* AHTÈÎÎñ¾ä±ú*/
/********************************** Äں˶ÔÏó¾ä±ú *********************************/
/*
 * ÐźÅÁ¿£¬ÏûÏ¢¶ÓÁУ¬Ê¼þ±êÖ¾×飬Èí¼þ¶¨Ê±Æ÷ÕâЩ¶¼ÊôÓÚÄں˵ĶÔÏó£¬ÒªÏëʹÓÃÕâЩÄÚºË
 * ¶ÔÏ󣬱ØÐëÏÈ´´½¨£¬´´½¨³É¹¦Ö®ºó»á·µ»ØÒ»¸öÏàÓ¦µÄ¾ä±ú¡£Êµ¼ÊÉϾÍÊÇÒ»¸öÖ¸Õ룬ºóÐøÎÒ
 * ÃǾͿÉÒÔͨ¹ýÕâ¸ö¾ä±ú²Ù×÷ÕâЩÄں˶ÔÏó¡£
 *
 * Äں˶ÔÏó˵°×Á˾ÍÊÇÒ»ÖÖÈ«¾ÖµÄÊý¾Ý½á¹¹£¬Í¨¹ýÕâЩÊý¾Ý½á¹¹ÎÒÃÇ¿ÉÒÔʵÏÖÈÎÎñ¼äµÄͨÐÅ£¬
 * ÈÎÎñ¼äµÄʼþͬ²½µÈ¸÷ÖÖ¹¦ÄÜ¡£ÖÁÓÚÕâЩ¹¦ÄܵÄʵÏÖÎÒÃÇÊÇͨ¹ýµ÷ÓÃÕâЩÄں˶ÔÏóµÄº¯Êý
 * À´Íê³ÉµÄ
 * 
 */


/******************************* È«¾Ö±äÁ¿ÉùÃ÷ ************************************/
/*
 * µ±ÎÒÃÇÔÚдӦÓóÌÐòµÄʱºò£¬¿ÉÄÜÐèÒªÓõ½Ò»Ð©È«¾Ö±äÁ¿¡£
 */


/*
*************************************************************************
*                             º¯ÊýÉùÃ÷
*************************************************************************
*/
static void AppTaskCreate(void);/* ÓÃÓÚ´´½¨ÈÎÎñ */

static void LED_Task(void* pvParameters);/* LED_TaskÈÎÎñʵÏÖ */
static void HELLO_Task(void* pvParameters);/* HELLO_TaskÈÎÎñʵÏÖ */
static void AHT_Task(void* pvParameters);/* AHT_TaskÈÎÎñʵÏÖ */
static void BSP_Init(void);/* ÓÃÓÚ³õʼ»¯°åÔØÏà¹Ø×ÊÔ´ */

/*****************************************************************
  * @brief  Ö÷º¯Êý
  * @param  ÎÞ
  * @retval ÎÞ
  * @note   µÚÒ»²½£º¿ª·¢°åÓ²¼þ³õʼ»¯ 
            µÚ¶þ²½£º´´½¨APPÓ¦ÓÃÈÎÎñ
            µÚÈý²½£ºÆô¶¯FreeRTOS£¬¿ªÊ¼¶àÈÎÎñµ÷¶È
  ****************************************************************/
int main(void)
{	
  BaseType_t xReturn = pdPASS;/* ¶¨ÒåÒ»¸ö´´½¨ÐÅÏ¢·µ»ØÖµ£¬Ä¬ÈÏΪpdPASS */

  /* ¿ª·¢°åÓ²¼þ³õʼ»¯ */
  BSP_Init();
  printf("ÕâÊÇÒ»¸ö[Ò°»ð]-STM32ȫϵÁпª·¢°å-FreeRTOS-¶¯Ì¬´´½¨ÈÎÎñ!\r\n");
   /* ´´½¨AppTaskCreateÈÎÎñ */
  xReturn = xTaskCreate((TaskFunction_t )AppTaskCreate,  /* ÈÎÎñÈë¿Úº¯Êý */
                        (const char*    )"AppTaskCreate",/* ÈÎÎñÃû×Ö */
                        (uint16_t       )512,  /* ÈÎÎñÕ»´óС */
                        (void*          )NULL,/* ÈÎÎñÈë¿Úº¯Êý²ÎÊý */
                        (UBaseType_t    )1, /* ÈÎÎñµÄÓÅÏȼ¶ */
                        (TaskHandle_t*  )&AppTaskCreate_Handle);/* ÈÎÎñ¿ØÖÆ¿éÖ¸Õë */ 
  /* Æô¶¯ÈÎÎñµ÷¶È */           
  if(pdPASS == xReturn)
    vTaskStartScheduler();   /* Æô¶¯ÈÎÎñ£¬¿ªÆôµ÷¶È */
  else
    return -1;  
  
  while(1);   /* Õý³£²»»áÖ´Ðе½ÕâÀï */    
}


/***********************************************************************
  * @ º¯ÊýÃû  £º AppTaskCreate
  * @ ¹¦ÄÜ˵Ã÷£º ΪÁË·½±ã¹ÜÀí£¬ËùÓеÄÈÎÎñ´´½¨º¯Êý¶¼·ÅÔÚÕâ¸öº¯ÊýÀïÃæ
  * @ ²ÎÊý    £º ÎÞ  
  * @ ·µ»ØÖµ  £º ÎÞ
  **********************************************************************/
static void AppTaskCreate(void)
{
  BaseType_t xReturn = pdPASS;/* ¶¨ÒåÒ»¸ö´´½¨ÐÅÏ¢·µ»ØÖµ£¬Ä¬ÈÏΪpdPASS */
  
  taskENTER_CRITICAL();           //½øÈëÁÙ½çÇø
  
  /* ´´½¨LED_TaskÈÎÎñ */
  xReturn = xTaskCreate((TaskFunction_t )LED_Task, /* ÈÎÎñÈë¿Úº¯Êý */
                        (const char*    )"LED_Task",/* ÈÎÎñÃû×Ö */
                        (uint16_t       )512,   /* ÈÎÎñÕ»´óС */
                        (void*          )NULL,	/* ÈÎÎñÈë¿Úº¯Êý²ÎÊý */
                        (UBaseType_t    )2,	    /* ÈÎÎñµÄÓÅÏȼ¶ */
                        (TaskHandle_t*  )&LED_Task_Handle);/* ÈÎÎñ¿ØÖÆ¿éÖ¸Õë */
  if(pdPASS == xReturn)
    printf("´´½¨LED_TaskÈÎÎñ³É¹¦!\r\n");
  
  /* ´´½¨HELLO_TaskÈÎÎñ */
  xReturn = xTaskCreate((TaskFunction_t )HELLO_Task, /* ÈÎÎñÈë¿Úº¯Êý */
                        (const char*    )"HELLO_Task",/* ÈÎÎñÃû×Ö */
                        (uint16_t       )512,   /* ÈÎÎñÕ»´óС */
                        (void*          )NULL,	/* ÈÎÎñÈë¿Úº¯Êý²ÎÊý */
                        (UBaseType_t    )3,	    /* ÈÎÎñµÄÓÅÏȼ¶ */
                        (TaskHandle_t*  )&HELLO_Task_Handle);/* ÈÎÎñ¿ØÖÆ¿éÖ¸Õë */
  if(pdPASS == xReturn)
    printf("´´½¨HELLO_TaskÈÎÎñ³É¹¦!\r\n");
	  /* ´´½¨AHT_TaskÈÎÎñ */
  xReturn = xTaskCreate((TaskFunction_t )AHT_Task, /* ÈÎÎñÈë¿Úº¯Êý */
                        (const char*    )"AHT_Task",/* ÈÎÎñÃû×Ö */
                        (uint16_t       )512,   /* ÈÎÎñÕ»´óС */
                        (void*          )NULL,	/* ÈÎÎñÈë¿Úº¯Êý²ÎÊý */
                        (UBaseType_t    )4,	    /* ÈÎÎñµÄÓÅÏȼ¶ */
                        (TaskHandle_t*  )&AHT_Task_Handle);/* ÈÎÎñ¿ØÖÆ¿éÖ¸Õë */
  if(pdPASS == xReturn)
    printf("´´½¨AHT_TaskÈÎÎñ³É¹¦!\r\n");
  vTaskDelete(AppTaskCreate_Handle); //ɾ³ýAppTaskCreateÈÎÎñ
  
  taskEXIT_CRITICAL();            //Í˳öÁÙ½çÇø
}



/**********************************************************************
  * @ º¯ÊýÃû  £º LED_Task
  * @ ¹¦ÄÜ˵Ã÷£º LED_TaskÈÎÎñÖ÷Ìå
  * @ ²ÎÊý    £º   
  * @ ·µ»ØÖµ  £º ÎÞ
  ********************************************************************/
static void LED_Task(void* parameter)
{	
    while (1)
    {
        LED1_ON;
        vTaskDelay(500);   /* ÑÓʱ500¸ötick */
        printf("LED_Task Running,LED1_ON\r\n");
        
        LED1_OFF;     
        vTaskDelay(500);   /* ÑÓʱ500¸ötick */		 		
        printf("LED_Task Running,LED1_OFF\r\n");
    }
}
/**********************************************************************
  * @ º¯ÊýÃû  £º HELLO_Task
  * @ ¹¦ÄÜ˵Ã÷£º HELLO_TaskÈÎÎñÖ÷Ìå
  * @ ²ÎÊý    £º   
  * @ ·µ»ØÖµ  £º ÎÞ
  ********************************************************************/
static void HELLO_Task(void* pvParameters)
{
	while(1)
	{
	vTaskDelay(2000);   /* ÑÓʱ2000¸ötick */
	printf("helloword!");   /*·¢ËÍhelloword£¡Ö¸Áî*/
	}
}
/**********************************************************************
  * @ º¯ÊýÃû  £º AHT_Task
  * @ ¹¦ÄÜ˵Ã÷£º AHT_TaskÈÎÎñÖ÷Ìå
  * @ ²ÎÊý    £º   
  * @ ·µ»ØÖµ  £º ÎÞ
  ********************************************************************/
static void AHT_Task(void* pvParameters)
{
	while(1)
	{
		vTaskDelay(5000);   /* ÑÓʱ5000¸ötick */
		printf("Ó²¼þ²»È«£¬ÑÓ³Ù5000msÊä³ö¸ÃÌáʾÐÅÏ¢");
	}
}
/***********************************************************************
  * @ º¯ÊýÃû  £º BSP_Init
  * @ ¹¦ÄÜ˵Ã÷£º °å¼¶ÍâÉè³õʼ»¯£¬ËùÓаå×ÓÉϵijõʼ»¯¾ù¿É·ÅÔÚÕâ¸öº¯ÊýÀïÃæ
  * @ ²ÎÊý    £º   
  * @ ·µ»ØÖµ  £º ÎÞ
  *********************************************************************/
static void BSP_Init(void)
{
	/*
	 * STM32ÖжÏÓÅÏȼ¶·Ö×éΪ4£¬¼´4bit¶¼ÓÃÀ´±íʾÇÀÕ¼ÓÅÏȼ¶£¬·¶Î§Îª£º0~15
	 * ÓÅÏȼ¶·Ö×éÖ»ÐèÒª·Ö×éÒ»´Î¼´¿É£¬ÒÔºóÈç¹ûÓÐÆäËûµÄÈÎÎñÐèÒªÓõ½Öжϣ¬
	 * ¶¼Í³Ò»ÓÃÕâ¸öÓÅÏȼ¶·Ö×飬ǧÍò²»ÒªÔÙ·Ö×飬Çмɡ£
	 */
	NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 );
	
	/* LED ³õʼ»¯ */
	LED_GPIO_Config();

	/* ´®¿Ú³õʼ»¯	*/
	USART_Config();
  
}
/********************************END OF FILE****************************/

在下直接从keil中复制过来的,乱码部分是注释,不影响程序正常运行

4.创建程序

在这里插入图片描述

5.生成hex文件

选中工程,右击选中第一个,弹出如下窗口,按照下图进行设置,一定要生成hex文件!
在这里插入图片描述
6.烧录
①将电脑与板子连接好,注意检查不要连接错误。
②安装野火资料里的CH340驱动。
在这里插入图片描述
③安装野火资料里面的mcuisp,并导入刚刚生成的hex文件。
在这里插入图片描述

6.实验结果。
根据设置500msLED灯亮或者熄灭,2000ms发送“helloword!”。
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

四、总结

野火提供的相关资料很全面,可以直接找到FreeRTOS的相关程序代码,在已有代码的基础上进行修改,难度和工作量大大减少。同时,本次实验将软件和硬件结合起来,体会到了玩电子的快乐!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值