42 freertos内存管理试验 2

四十二、freertos内存管理2

/**
**************************************************************************************************/
#include <stdio.h>
#include <limits.h>//标准C库文件,定义了各种类型的范围
#include "board.h"
#include "led.h"
#include "key.h"
#include "uart.h"
#include "tim_mrt.h"

/**********************系统相关和硬件接口**************************************/
/*** System oscillator rate and clock rate on the CLKIN pin  ****/
/**/const uint32_t OscRateIn = MAIN_OSC_XTAL_FREQ_HZ;		 /**/
/**/const uint32_t ExtRateIn = EXT_CLOCK_IN_FREQ_HZ;		 /**/
 //系统复位
#define	System_restart	(LPC_SWM->PINENABLE0 = 0xffffffffUL) /**/
/**********************End**************************************/

//static void TIM_CallBack1(void);
//static void TIM_CallBack2(void);

/**********************FreeRTOS操作系统头文件**************************************/
#include "FreeRTOSConfig.h"
#include "FreeRTOS.h"
#include "task.h"
#include "event_groups.h"//事件头文件
#include "queue.h"//队列头文件
#include "semphr.h"//信号量头文件
#include "timers.h"//软件定时器头文件
/**********************End**************************************/

/**************************** 任务句柄 ********************************/

static xTaskHandle LED_TaskHandle=NULL;
static xTaskHandle KEY_TaskHandle=NULL;
static QueueHandle_t xQueue1 = NULL;

typedef struct Msg
{
	uint8_t  ucMessageID;
	uint16_t usData[2];
	uint32_t ulData[2];
}MSG_T;


/*************************** 宏定义 ************************************/
#define TASK_STACK_SIZE 32//每个任务的栈大小


/* Sets up system hardware 
**********************************************************************
  * @ 函数名  : BSP_Init
  * @ 功能说明: 板级外设初始化,所有板子上的初始化均可放在这个函数里面
  * @ 参数    :   
  * @ 返回值  : 无
*********************************************************************/
static void prvSetupHardware(void)
{

	SystemCoreClockUpdate();

	DEBUGINIT();
	led_Init() ;	
	Key_INIT();
	MRT_Init();
	DEBUGOUT("%u MHz\n",SystemCoreClock/1000000);
	Board_UARTPutSTR("build date: " __DATE__ " build time: " __TIME__ "\n");

}

/**********************************************************************
 * @ 函数名 :  
 * @ 功能说明:  接收发送通知
 * @ 参数 :
 * @ 返回值 : 无
 ********************************************************************/
static void LED_Task(void* parameter)
{
	TickType_t xLastWakeTime;
	const TickType_t xFrequency = 500;
	/* 获取当前的系统时间 */
    xLastWakeTime = xTaskGetTickCount();
	while(1)
	{

		Board_LED_Toggle(0);
		/* vTaskDelayUntil是绝对延迟,vTaskDelay是相对延迟。*/
		vTaskDelayUntil(&xLastWakeTime, xFrequency);
	}
}


/**********************************************************************
 * @ 函数名 :   
 * @ 功能说明: 发送任务
 * @ 参数 :
 * @ 返回值 : 无
 ********************************************************************/
static void KEY_Task(void* parameter)
{
	MSG_T *ptMsg;
	uint8_t ucCount = 0;
	
	u8 ucKeyCode=0;
	while(1)
	{
		u8 key=0;
		if(Scan_Key())
			vTaskDelay(20);
		else continue;
		if(!Scan_Key())continue;
		else
		{
			key=Scan_Key();
			ucKeyCode=key;
		}
		while(Scan_Key()){};//等按键抬起
		
		if(ucKeyCode)
		{

			switch(ucKeyCode)
			{
				case 1:
				{
					/* K1键按下 */
//					printf ( "KEY1 被按下\n" );
					Board_LED_Toggle(6);
					
					printf("=================================================\r\n");
					printf("当前动态内存大小 = %d\r\n", xPortGetFreeHeapSize());
					ptMsg = (MSG_T  *)pvPortMalloc(sizeof(MSG_T));
					printf("申请动态内存后剩余大小 = %d\r\n", xPortGetFreeHeapSize());
					
					ptMsg->ucMessageID = ucCount++; 
					ptMsg->ulData[0] = ucCount++;
					ptMsg->usData[0] = ucCount++;
					
					/* 使用消息队列实现指针变量的传递 */
					if(xQueueSend(xQueue1,                  /* 消息队列句柄 */
								 (void *) &ptMsg,           /* 发送结构体指针变量ptMsg的地址 */
								 (TickType_t)10) != pdPASS )
					{
						/* 发送失败,即使等待了10个时钟节拍 */
						printf("K2键按下,向xQueue2发送数据失败,即使等待了10个时钟节拍\r\n");
						vPortFree(ptMsg);
						printf("释放申请的动态内存后大小 = %d\r\n", xPortGetFreeHeapSize());
					
					}
					else
					{
						/* 发送成功 */
						printf("K2键按下,向xQueue2发送数据成功\r\n");
                        /* 由于是低优先级任务向高优先级任务发送消息队列,如果成功的话说明高优先级任务已经执行。
						   并获得了消息队列中的数据,所以我们可以在此处释放动态内存,不会出现高优先级任务还没有
						   获得消息队列数据,我们就将动态内存释放掉了。
						*/						
						vPortFree(ptMsg);
						printf("释放申请的动态内存后大小 = %d\r\n", xPortGetFreeHeapSize());						
					}
				}break;
				case 2:
				{
					 /* K2键按下 */
//					printf ( "k2 被按下\n" );
					Board_LED_Toggle(5);
					 
				}break;
				case 3:
				{
					/* K3键按下*/
					 
				}break;
				default:break;
			}
			ucKeyCode=0;
		}
			
	}
}
/*
*********************************************************************************************************
*	函 数 名: vTaskMsgPro
*	功能说明: 使用函数xQueueReceive接收任务vTaskTaskUserIF发送的消息队列数据(xQueue1)
*	形    参: pvParameters 是在创建该任务时传递的形参
*	返 回 值: 无
*   优 先 级: 3  
*********************************************************************************************************
*/
static void vTaskMsgPro(void *pvParameters)
{
	MSG_T *ptMsg;
	BaseType_t xResult;
	const TickType_t xMaxBlockTime = pdMS_TO_TICKS(200); /* 设置最大等待时间为200ms */
	
	while(1)
    {
		xResult = xQueueReceive(xQueue1,                   /* 消息队列句柄 */
		                        (void *)&ptMsg,  		   /* 这里获取的是结构体的地址 */
		                        (TickType_t)xMaxBlockTime);/* 设置阻塞时间 */
		if(xResult == pdPASS)
		{
			/* 成功接收,并通过串口将数据打印出来 */
			printf("接收到消息队列数据ptMsg->ucMessageID = %d\r\n", ptMsg->ucMessageID);
			printf("接收到消息队列数据ptMsg->ulData[0] = %d\r\n", ptMsg->ulData[0]);
			printf("接收到消息队列数据ptMsg->usData[0] = %d\r\n", ptMsg->usData[0]);
		}
		else
		{
			/* 超时 */
			Board_LED_Toggle(1);
			Board_LED_Toggle(4);
		}
		
	}
}
/***********************************************************************
  * @ 函数名  : AppTaskCreate
  * @ 功能说明: 为了方便管理,所有的任务创建函数都放在这个函数里面
  * @ 参数    : 无  
  * @ 返回值  : 无
  **********************************************************************/
static void AppTaskCreate(void)
{
	BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为 pdPASS */
	taskENTER_CRITICAL();//进入临界区,禁止中断打断
	
	xReturn = xTaskCreate(	 LED_Task,
							"LED_Task",
							TASK_STACK_SIZE*1,
							NULL,
							2,
							&LED_TaskHandle);
	if (pdPASS == xReturn)
		printf("创建 Receive1_Task 任务成功!\r\n");
	

	xReturn = xTaskCreate(	 KEY_Task,
							"KEY_Task",
							TASK_STACK_SIZE*2,
							NULL,
							1,
							&KEY_TaskHandle);
	if (pdPASS == xReturn)
		printf("创建 KEY_Task 任务成功!\r\n");
	
	 xTaskCreate( vTaskMsgPro,     		/* 任务函数  */
                 "vTaskMsgPro",   		/* 任务名    */
                 TASK_STACK_SIZE*2,             		/* 任务栈大小,单位word,也就是4字节 */
                 NULL,           		/* 任务参数  */
                 3,               		/* 任务优先级*/
                 NULL );  /* 任务句柄  */
	
	
	
	taskEXIT_CRITICAL(); //退出临界区	

}
/*
*********************************************************************************************************
*	函 数 名: AppObjCreate
*	功能说明: 创建任务通信机制
*	形    参: 无
*	返 回 值: 无
*********************************************************************************************************
*/

static void AppObjCreate (void)
{
	 /* 创建10个存储指针变量的消息队列,由于CM3/CM4内核是32位机,一个指针变量占用4个字节 */
	xQueue1 = xQueueCreate(10, sizeof(struct Msg *));
    if( xQueue1 == 0 )
    {
        /* 没有创建成功,用户可以在这里加入创建失败的处理机制 */
    }
}
/**
 * @brief	main routine for blinky example
 * @return	Function should not exit.
 */
int main(void)
{
	
	prvSetupHardware();
	Board_UARTPutSTR("LPC824 FreeRTOS 任务通知任务间通信 \n");
	DEBUGSTR("内存管理\n");
	

	AppTaskCreate();
	/* 创建任务通信机制 */
	AppObjCreate();
	
	vTaskStartScheduler();//任务调度

	/* Loop forever */
	while (1) {
			printf("FreeRTOS 运行失败\n\r");
 	}
	
	
}

/******************
*函数名 : HardFault_Handler
*功能 	:硬件错误时会跳进这里
*说明 : 
******(1)可能是内存溢出,堆栈溢出。
******(2)可能是开启了中断,但没有中断函数。
******(3)可能指针赋值错误,最有可能是函数指针赋值错误。
******************/
void HardFault_Handler(void)
{
	printf("硬件错误中断\n");
	while(1)
	{

	}
}

获取当前内存大小

xPortGetFreeHeapSize();
pvPortMalloc();

获取当前内剩余存大小

xPortGetFreeHeapSize();
vPortFree(); //释放内存

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值