FreeRTOS的学习总结

一 创建任务
1 创建任务的api是:
/**
pvTaskCode:任务执行的函数
pcName:任务名
usStackDepth:栈空间大小
pvParameters:传递到任务函数中的值,一般是 NULL
uxPriority:任务优先级 任务优先级数值越小 任务优先级越低。
pxCreatedTask :将此任务句柄和创建的任务绑定在一起,主要用于改变任务优先级,或者删除任务。一般是 NULL
/
portBASE_TYPE xTaskCreate( pdTASK_CODE pvTaskCode,
const signed portCHAR * const pcName,
unsigned portSHORT usStackDepth,
void pvParameters,
unsigned portBASE_TYPE uxPriority,
xTaskHandle pxCreatedTask );
其中
举例:
xTaskCreate( vTask1, /
任务函数指针 /
“Task 1”, /
任务名:调试使用 /
1000, /
栈深 /
NULL, /
任务参数 /
1, /
优先级. /
NULL ); /
任务 handle /
其他api:
UBaseType_t uxTaskPriorityGet( TaskHandle_t xTask ); //获取任务优先级
void vTaskPrioritySet( xTaskHandle pxTask, unsigned portBASE_TYPEuxNewPriority ); //设置任务优先级
void vTaskDelete( xTaskHandle pxTaskToDelete ); //删除任务
二 任务调度
1 任务的四种状态
任务状态机运行态:cpu正在执行的任务; 就绪态:等待进入运行态; 阻塞态:不能进入运行态,需要解除阻塞; 挂起态:不能进入运行态,需要解除挂起。
划分优先级:运行态是第一顺位,就绪态是第二顺位,阻塞态和挂起态是第三顺位
cpu当前执行运行态的任务,运行态任务执行结束会在就绪态中找一个最高优先级的任务进入运行运行态,阻塞态解除和挂起态解挂会进入就绪态。
抢占:高优先级任务进入第三顺位,低优先级才会进入运行态
时间片轮询:同一优先级轮询进入运行
taskYIELD():相同优先级任务之间的切换会调用这个函数,任务自己会调用,不用显式调用
vTaskStartScheduler(); //调度函数
三 队列
1 队列用到的api:
1)创建队列的api:
/

uxQueueLength:队列能够存储的最大单元数目,即队列深度
uxItemSize:队列中数据单元的长度,以字节为单位
返回值:此队列的句柄,NULL 表示没有足够的堆空间分配给队列而导致创建失败
/
xQueueHandle xQueueCreate( unsigned portBASE_TYPE uxQueueLength,
unsigned portBASE_TYPE uxItemSize );
2) 将数据发送到队列尾
/

pvItemToQueue:目标队列的句柄
pvItemToQueue:发送数据的指针
xTicksToWait :阻塞超时时间
返回值:返回pdPASS 只会有一种情况,那就是数据被成功发送到队列中
如果由于队列已满而无法将数据写入, 则将返回errQUEUE_FULL。
/
portBASE_TYPE xQueueSendToFront( xQueueHandle xQueue,
const void * pvItemToQueue,
portTickType xTicksToWait );
3) 将数据发送到队列首
/
*
pvItemToQueue:目标队列的句柄
pvItemToQueue:发送数据的指针
xTicksToWait :阻塞超时时间
返回值:返回pdPASS 只会有一种情况,那就是数据被成功发送到队列中
如果由于队列已满而无法将数据写入, 则将返回errQUEUE_FULL。
/
portBASE_TYPE xQueueSendToBack( xQueueHandle xQueue,
const void * pvItemToQueue,
portTickType xTicksToWait );
4)用于从队列中接收(读取)数据单元。接收到的单元同时会从队列中删除
/
*
xQueue:被读队列的句柄
pvBuffer:接收缓存指针
xTicksToWait:阻塞超时时间
返回值:返回pdPASS,那就是成功地从队列中读到数据
如果在读取时由于队列已空而没有读到任何数据,则将返回errQUEUE_FULL
/
portBASE_TYPE xQueueReceive( xQueueHandle xQueue,
const void * pvBuffer,
portTickType xTicksToWait );
5)从队列中接收数据单元,不同的是并不从队列中删出接收到的单元
/
*
xQueue:被读队列的句柄
pvBuffer:接收缓存指针
xTicksToWait:阻塞超时时间
返回值:返回pdPASS,那就是成功地从队列中读到数据
如果在读取时由于队列已空而没有读到任何数据,则将返回errQUEUE_FULL
/
portBASE_TYPE xQueuePeek( xQueueHandle xQueue,
const void * pvBuffer,
portTickType xTicksToWait );
6)用于查询队列中当前有效数据单元个数
/
*
xQueue:被查询队列的句柄
返回值:当前队列中保存的数据单元个数。返回0 表明队列为空
*/
unsigned portBASE_TYPE uxQueueMessagesWaiting( xQueueHandle xQueue );
2 举例
xQueueHandle xQueue;
long lValueToSend;
long lReceivedValue;
portBASE_TYPE xStatus;

xQueue = xQueueCreate( 5, sizeof( long ) );
xStatus = xQueueSendToBack( xQueue, &lValueToSend, 0 );
xStatus = xQueueReceive( xQueue, &lReceivedValue, xTicksToWait );
四 中断管理
1 中断的处理方式
1.) 中断产生。
2.) 中断服务例程启动,给出信号量以使延迟处理任务解除阻塞。
3.) 当中断服务例程退出时,延迟处理任务得到执行。延迟处理任务做的第一件事便是
获取信号量。
4.)延迟处理任务完成中断事件处理后,试图再次获取信号量——如果此时信号量无效,
任务将切入阻塞待等待事件发生。
2 二值信号量
void vSemaphoreCreateBinary( xSemaphoreHandle xSemaphore ); //创建二值信号量
portBASE_TYPE xSemaphoreTake( xSemaphoreHandle xSemaphore,
portTickType xTicksToWait ); //接收信号量
/**
给出信号量
xSemaphore:给出的信号量
pxHigherPriorityTaskWoken:去百度吧 后期补充
*/
portBASE_TYPE xSemaphoreGiveFromISR( xSemaphoreHandle xSemaphore,
portBASE_TYPE *pxHigherPriorityTaskWoken );
xSemaphoreGiveFromISR()是xSemaphoreGive()的特殊形式,专门用于中断服务例程中。

3 计数信号量
/**
创建计数信号量
uxMaxCount:最大计数值
uxInitialCount:信号量的初始计数值
*/
xSemaphoreHandle xSemaphoreCreateCounting( unsigned portBASE_TYPE uxMaxCount,
unsigned portBASE_TYPE uxInitialCount );
xSemaphoreTake();xSemaphoreGiveFromISR();xSemaphoreGive();给出和获取信号量的函数是一样的
4 队列用在中断中
xQueueSendToFrontFromISR(),xQueueSendToBackFromISR()与xQueueReceiveFromISR()
分别是xQueueSendToFront(),xQueueSendToBack()与xQueueReceive()的中断安全版本,专门用于中断服务例程中。

五 资源管理
1 临界区
taskENTER_CRITICAL(); //进入临界区
taskEXIT_CRITICAL(); //退出临界区
2 挂起调度器
vTaskSuspendAll(); //挂起调度器
xTaskResumeAll();//释放调度器
3 互斥信号量
xSemaphoreHandle xSemaphoreCreateMutex( void ); //创建互斥信号量
扩展:
1)互斥信号量
互斥信号量的申请与释放是要在同一个任务中进行的,不能在一个任务中申请而在另一个任务中释放。
互斥信号量主要解决的是,我在用的时候,别人都不能用。举个例子,我在像一段内存中写数据的时候,不允许别人去写和读的,这时候就需要互斥信号量,写之前获取信号量,写完之后再释放互斥信号量。
2)二值信号量
二值信号量允许在一个任务中申请,在另外一个任务中释放。
二值信号量主要解决的是任务同步的问题。举个例子,一个任务用于处理UART的数据,UART中断中接受数据,当任务处理数据时就获取信号量,中断接受到数据就释放信号量,这样就可以使得中断与任务接受和处理协同处理。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值