FreeRTOS学习笔记.docx
《FreeRTOS学习笔记.docx》由会员分享,可在线阅读,更多相关《FreeRTOS学习笔记.docx(14页珍藏版)》请在冰豆网上搜索。
FreeRTOS学习笔记
FreeRTOS学习笔记
使用注意:
FreeRTOS与ucOS相比,需要修改启动文献。
1.任务创立
包括FreeRTOS.h//这个是必要要包括//和task.h。
调用API函数:
xTaskCreate
pvTaskCode:
函数指针(函数名)。
pcName:
描述性任务名,只是用于辅助调试。
可以通过
FreeRTOSConfig.h第100行
configMAX_TASK_NAME_LEN来变化描述名长度。
usStackDepth:
任务栈大小。
建议为64整数倍。
pvParameters:
任务参数,void*类型。
不用写NULL。
uxPriority:
任务优先级。
值越大优先级越高。
同等优先级时,
按照osheart进行时间片轮转。
xTaskHandle:
任务句柄。
变化该任务优先级、删除任务等时才会
用到。
不用写NULL。
2.开始多任务
vTaskStartScheduler()
3.如何多任务切换
调用API函数:
vTaskDelay(unsignedinttime)
Time为多少个osheart。
4.时间片轮转例子
创立两个任务
xTaskCreate(USART1_Task,"USART1",256,(void*)str1,3,NULL);
xTaskCreate(USART2_Task,"USART2",256,(void*)str2,3,NULL);
相似优先级,波特率可以设立低某些。
然后就会看到
这就是时间片轮转。
5.系统心跳频率
在FreeRTOSConfig.h第97行configTICK_RATE_HZ,源码使用1000HZ,就是1ms,如果为200就是200HZ,5ms。
有关宏:
portTICK_RATE_MS。
6.vTaskDelayUntil
和vTaskDelay不同,这个函数不涉及函数运营时间,而
vTaskDelayUntil涉及。
例如,一种函数A执行时间为2ms,
使用vTaskDelay(10),则再次执行这个函数至少需要等待12ms。
使用vTaskDelayUntil(10),则这2ms涉及在内,A以固定10ms周期运营。
用法:
红圈地方就是固定心跳周期。
7.空闲任务钩子函数
voidvApplicationIdleHook(void)
{}
需使能FreeRTOSConfig.h中第126行configUSE_IDLE_HOOK。
8.消息队列---Queue
包括:
#include"queue.h"
声明:
QueueHandle_tqMsg;
创立:
qMsg=xQueueCreate(4,2);//4个队列,每个队列2个成员
发送:
xQueueSendToFront(qMsg,&Value,1)//最后是超时时间
xQueueSendToBack(qMsg,&Value,1)//最后是超时时间
xQueueSend(qMsg,&Value,1)//最后是超时时间
成功返回pdPASS;失败返回errQUEUE_FULL。
注:
中断中就是在函数名字后加上”FromISR”。
接受:
xQueueReceive(qMsg,&value,1)
xQueuePeek(qMsg,&value,1)//不会删除读取数据
成功返回pdPASS;失败返回errQUEUE_EMPTY
注:
中断中就是在函数名字后加上”FromISR”。
删除:
vQueueDelete(qMsg);
查询队列未读数据个数:
unsignedportBASE_TYPEcount=0;
count=uxQueueMessagesWaiting(qMsg);
例程:
按键发送队列消息,接受任务接受到就显示。
按键是两个,这里没有截出来。
9.二值信号量
包括:
#include"semphr.h"
声明:
SemaphoreHandle_tsSem;
创立:
sSem=xSemaphoreCreateBinary();//创立二值信号量(推荐)
vSemaphoreCreateBinary(sSem);//创立二值信号量
Give:
portBASE_TYPExHigherPriorityTaskWoken=pdFALSE;
xSemaphoreGiveFromISR(sSem,&xHigherPriorityTaskWoken);
if(xHigherPriorityTaskWoken==pdTRUE)
;
-----中断办法
xSemaphoreGive(sSem);
-----普通办法
Take:
portBASE_TYPExHigherPriorityTaskWoken=pdFALSE;
xSemaphoreGiveFromISR(sSem,&xHigherPriorityTaskWoken);
if(xHigherPriorityTaskWoken==pdTRUE)
;
-----中断办法
if(xSemaphoreTake(sSem,1)==pdTRUE)
-----普通办法
删除:
vSemaphoreDelete(sSem);
例程
Timer7每隔3sGive一次BinarySema,LCD任务循环TakeBinarySema,这是中断延迟解决例子。
10.计数信号量
包括:
#include"semphr.h"
声明:
SemaphoreHandle_tsSem;
创立:
sSem=xSemaphoreCreateCounting(10,0);
注:
别的办法完全同样,只是创立是不同。
第一种参数:
计数容量。
第二个参数:
初值。
需要在FreeRTOS.h中第252行
#defineconfigUSE_COUNTING_SEMAPHORES0。
改为1才可使用。
例程
按键控制Timer7启停,Timer7干事情就是每隔0.5s去Give一种CountingSema,LED任务就是Take到CountingSema,执行一次LED动作。
当Timer7停止时,LED任务会吧CountingSemaTake到为0为止。
11.互斥信号量
包括:
#include"semphr.h"
声明:
SemaphoreHandle_tsSem;
创立:
sSem=xSemaphoreCreateMutex();//创立互斥信号量
注:
别的办法完全同样,只是创立是不同。
需要在FreeRTOS.h中第244行
#defineconfigUSE_MUTEXES1。
改为1才可使用。
例程:
临界资源
USART1_Task先调用Usart_Func函数,里边先获取互斥量,然后打印一句,积极放弃cpu控制权,此时该运营USART2_Task,但是它获取不到互斥量,阻塞,然后再执行USART1_Task某些,执行完毕,give互斥量,此时USART2_Task即可打印出来。
例程2
12.事件标志组-Event_Groups
包括:
#include"event_groups.h"
声明:
EventGroupHandle_teEvent;//事件标志组句柄
创立:
eEvent=xEventGroupCreate();
设立:
xEventGroupSetBits(eEvent,0x01);//设立标志
等待:
getBits=xEventGroupWaitBits(eEvent,0x01,pdTRUE,pdTRUE,1);
//句柄-等待标志-完毕后与否清零标志-与否等待所有标志-超时时间
if((getBits&0x01)==0x01)
{
//…
}
vTaskDelay(10);
删除:
vEventGroupDelete(eEvent);
例程:
如果是等待bit1和bit3,pdTRUE、pdTRUE时(一定要判断if((getBits&0x09)==0x09)),先发生Bit1事件,getBits就会始终为0x01,然后发生Bit3事件,才会触发然后标志组内部吧相应事件清零;pdTRUE、pdFALSE时,发生任意一种事件后,触发然后标志组内部吧事件清零。
13.软件定期器
包括:
#include"timers.h"
声明:
TimerHandle_tt1_Thdl,t2_Thdl,t3_Thdl;
创立:
t1_Thdl=xTimerCreate("Timer1",200,pdTRUE,(void*)1,(TimerCallbackFunction_t)Timer_Callback);
参数1:
定期器名,调试用到。
参数2:
定期周期。
参数3:
pdTRUE-周期定期器;pdFALSE-单次定期器。
参数4:
TimerID。
容许各种定期器回调同一种函数,通过ID区别。
参数5:
回调函数地址。
启停:
xTimerStart(t1_Thdl,1);句柄、等待时间。
xTimerStop(t1_Thdl,1);
复位:
xTimerReset(t1_Thdl,1);
14.内存管理
为了减少内存碎片产生。
FreeRTOS提供了一套内存分派与释放办法。
分派:
void*pvPortMalloc(size_txWantedSize)
释放:
voidvPortFree(void*pv)
用法同C库malloc和free。
C库内存分派方案弊端