FreeRTOS 初识

#学习记录

设置sys,因为FreeRTOS操作系统也需要定时器,所以不选择systick,选用tim1

与之前相反的是优先级,序号越高优先级越高,即正序

挂起态 理解:被高优先级抢占了导致暂停的状态

阻塞态 :如osDelay(500)的延时状态

TCB任务控制块  一个结构体(约等于任务句柄?)

任务创建:

动态创建

注意事项是动态内存分配

静态创建

configSUPPORT_STATIC_ALLOCATION 静态内存分配

多任务调度:

在用户程序需要调用特权级的操作系统函数时,SVC异常被触发

系统延时API详解

临界段:

在程序访问资源时,不希望被其他(相同优先级)任务或者中断打断,这段要执行的代码,称为临界代码段

taskDISABLE_INTERRUPTS()

栈堆大小的确定:

State状态包括S、被删除D(详见手册或下面pdf截图)、就绪态R、阻塞态B

configUSE_TRACE_FACILITY 用户追踪功能

configUSE_STATS_FORMATTING_FUNCTIONS 用户实现功能

栈溢出检测方案一、二(两者大同小异,甚至能用程序更改宏定义来更改检测方案选项)

栈溢出后的回调函数

函数参数xTaskHandle xTasksigned char *pcTaskName分别表示发生栈溢出的任务的句柄和名称。

利用回调函数打印溢出的任务名称

方案一二两者大同小异,甚至能用程序更改宏定义来更改检测方案选项

获取任务状态的方案

两个选项使能

CPU利用率统计

configureTimerForRunTimeStats、getRunTimeCounterValue 统计运行时间、获取运行时间。

可用来初始化高精度定时器。

如: 开启定时器6的中断、初始化一个自定义统计值

消息队列

API:

xQueueSend()在任务中使用

xQueueSendFromISR()在中断中使用

代码实现:

__HAL_UART_ENABLE_IT 系统自带库里没找到,我只能来手册看了

添加队列

使能中断:UART_IT_RXNE接收器不为空(疑问:为什么要在usart.c文件中的该位置写中断使能)
入队
出队
pdPASS表示成功接到返回值
portMAX_DELAY是一个宏定义,用于表示无限延时的值
FreeRTOS信号量

Binary二值信号量   (0-1)

Count计数信号量    (0-n)

Mutex互斥信号量(包括RecursiveMutex递归互斥信号量)

task1进入阻塞态,获取信号量后会继续运行,task1运行完后释放资源后task2才能获取资源从阻塞态出来

二值信号量函数应用:

设置、自动初始化

自动生成信号量句柄

自动初始化信号量句柄

达到想要的条件后给handle发送信号量

无限等待直到接收到信号量(return pdPASS)后执行任务内容

计数信号量函数应用:

xSemaphoreCreateCounting()

uxSemaphoreGetCount()

改为KEY1获取 KEY2释放

前置初始化之类的与二值类似

优先级翻转问题

互斥信号量函数应用:

经典死锁现象:

xSemaphoreCreateMutex()

xSemaphoreGetMutexHolder()

设置三个不同的优先级LED normal  DELAY Low   HIGH high

递归互斥信号量函数应用:

xSemaphoreCreateRecursiveMutex()

xSemaphoreTakeRecursive()

xSemaphoreGiveRecursive()

事件标志组函数应用

事件标志组是一组事件标志位的集合,通常可以看作是一个整数(32bit)。每个位(bit)代表一个特定的事件

Cubemx里没有事件标志组的创建设置,我们要在keil里另外自己人为设置

xEventGroupCreate()

xEventGroupSetBits()

xEventGroupSetBitsFromISR()

守护任务:操作系统不想在中断中执行的任务(软件定时器任务)

红框内选项要使能(置1)可在CubeMx实现

xEventGroupGetBits()

xEventGroupGetBitsFromISR()

xEventGroupWaitBits()

xEventGroupSync()

软件定时器函数应用

xTimerCreate()

xTimerStart()

xTimerReset()

pvTimerGetTimerID()

xTimerChangePeriod()

使能低速时钟

用LEDtask和USARTtask实现需要的功能

因为需要定时周期打印实时时间的功能,所以添加Timer:

程序部分较为复杂,可自行查看L7 TimerTask

低功耗管理(Tickless低功耗管理)

复位后串口卡住,是时钟问题,需要将TIM6先关闭

HAL_SuspendTick 挂起tick
HAL_ResumeTick 恢复tick
复位后串口依旧卡住,但取消恢复tick就可以打印了
内存管理

heap_1 功能:只能分配,不能释放 (可以用于一些不能删除的数值)

heap_2 功能:支持分配,也支持释放,但是没有内存管理,容易产生内存碎片。

heap_3 功能:封装malloc/free,且任务保护

heap_4 功能:有分配、释放、管理功能

heap_5 功能:4的基础上带有外部扩展,防止空间不够

heap2、heap4的区别:

heap2释放的内存下次如要分配,就必须与之前释放的空间大小一致,否则无法使用

注意:申请时需要空间已经释放,释放时需要空间不为空(复制CubeMx工程为EventTask)

void *pvPortMalloc( size_t xWantedSize );申请

void vPortFree( void *pv );释放

size_t xPortGetFreeHeapSize( void )获取空闲堆空间大小(byte)

列表操作

pxReady TasksLists [] 优先级

xDelayed TaskList1/xDelayed TaskList2  用于systick累加溢出处理

xPending ReadyList 挂起任务就绪管理

xTasks Waiting Termination 在空闲任务中读取后删除该列表里的任务(等待删除列表)

xSuspended TaskList 单独挂起任务列表

Timer设定两个列表也是为了应对溢出的情况

List_t列表,ListItem_t 列表项,MiniList Item_t 相当于一个链式结构的head,但是在列表里ta是相当于end(尾部),即这里的列表不用头部定位,用的是尾部定位

vListInitialise()  注意,使用列表就必须以此初始化

vListInitialiseItem() 同上

vListInsert()  每个ListItem自带一个value值,根据这个值产生序号,以此来排列插入,我们可以初始化列表项时就给value赋值,如:ListItemTest[index].xItemValue = index;

vListInsertEnd()

uxListRemove()

​​​​​​​

/* USER CODE BEGIN Header_DELAY_Task */
#define 	ITEM_NUMBER 	5
List_t 		ListTest;
ListItem_t	ListItemTest[ITEM_NUMBER];
/**
* @brief Function implementing the DELAYTask thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_DELAY_Task */
void DELAY_Task(void const * argument)
{
  /* USER CODE BEGIN DELAY_Task */
EventBits_t KeyEventBits;
	uint8_t	index;
	static uint8_t record = 0;
	ListItem_t* pListItem;
	
	/*
		1、列表及列表项初始化
	*/
	vListInitialise(&ListTest);
	for(index=0;index<ITEM_NUMBER;index++){
	
		vListInitialiseItem(&ListItemTest[index]);
		ListItemTest[index].xItemValue = index;
	}
  /* Infinite loop */
  for(;;)
  {
		KeyEventBits = xEventGroupWaitBits(KeyEventGroup,
									 KEY1_EVENT_BIT|KEY2_EVENT_BIT|KEY3_EVENT_BIT|KEY4_EVENT_BIT,
									 pdTRUE,
									 pdFALSE,
									 portMAX_DELAY);
		printf("key is down key event bit is %x\r\n",KeyEventBits);
		switch(KeyEventBits){
		  case KEY1_EVENT_BIT:
			  /*
				当列表项在范围内,允许插入
				插入完毕后,记录值record加一
			  */
			  if(record < ITEM_NUMBER){
				vListInsert(&ListTest,&ListItemTest[record++]);
			  }
			  else{
				printf("plese press K2 remove!\r\n");
			  }
				
			break;
		  case KEY2_EVENT_BIT:
		 /*
				当记录值有效时,允许移除
				插入完毕后,记录值record减一
			  */
			  if((record != 0)&&(record <= ITEM_NUMBER)){
				uxListRemove(&ListItemTest[--record]);
			  }
			  else{
				printf("plese press K1 insert!\r\n");
			  }
							  
			break;		 
		  case KEY3_EVENT_BIT:
			   /*
				1、打印有效列表项地址
				2、打印有效列表项(ItemValue)
				3、打印有效列表项前节点地址
				4、打印有效列表项后节点地址
			*/
			 for(pListItem = ListTest.xListEnd.pxNext;pListItem != (ListItem_t*)&ListTest.xListEnd;pListItem=pListItem->pxNext){
			 
				printf("pListItem addr = %x\r\n",pListItem);
				printf("pListItem item value = %d\r\n",pListItem->xItemValue);
				printf("pListItem previous addr = %x\r\n",pListItem->pxPrevious);
				printf("pListItem next addr = %x\r\n",pListItem->pxNext);
			 }
			 
	  }
    osDelay(10);
  }
  /* USER CODE END DELAY_Task */
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值