FreeRTOS学习笔记一

FreeRTOS 任务不允许以任何方式从实现函数中返回--它们绝不能有一条“return”
语句。

void ATaskFunction(void *pvParameters)
{
    int iVariableExample = 0;

    for(;;)
    {
        
    }
    传入NULL参数表示删除的是当前任务
    vTaskDelete(NULL);
}

FreeRTOS的调度器是能让任务切入切出的唯一实体。

创建任务

xTaskCreate()

portBASE_TYPE xTaskCreate( pdTASK_CODE pvTaskCode,           //是函数名
               const sifned portCHAR * const pcName,//具有描述性的任务名。这个参数不会被FreeRTOS使用。
               unsigned portSHORT usStackDepth,     //用于告诉内核为它分配多大的栈空间 ,指定的是栈空间可以保存多少个字(word)。
               void *pvParameters,   //任务函数接受一个指向void的指针(void*),即传递到任务中的值。
               unsigned portBASE_TYPE uxPriority,  //指定任务执行的优先级
               xTaskHandle *pxCreatedTask          //用于传出任务句柄

);

返回值,
1、pdTRUE : 表明任务创建成功
2、errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY
由于内存堆空间不足,FreeRTOS无法分配足够的空间来保存任务

int main(void)
{
    xTaskCreate(vTask2, "Task 2", 1000, NULL, 1, NULL);
    
    vTaskStartScheduler(); //启动调度器,任务开始执行
    
    for(; ;); //如果执行到这里很可能是内存堆栈不足导致空闲任务无法创建。
}


可以先在mani()中创建任务1,然后在任务1中创建任务2.


void vTaskFunction(void *pvParameters)
{

}

尽管现在只有一个任务实现代码(vTaskFunction),但是可以创建多个任务实例。


static const char *pcTextForTask1 = “Task 1 is running\r\n”;
static const char *pcTextForTask2 = “Task 2 is running\t\n”;

int main( void )
{
    xTaskCreate( vTaskFunction, "Task 1", 1000, (void*)pcTextForTask1, 1, NULL );
    xTaskCreate( vTaskFunction, "Task 2", 1000, (void*)pcTextForTask2, 1, NULL );
    vTaskStartScheduler();
    for( ;; );
}


任务优先级

uxPriority建立任务的时候初始化一个优先级,这个优先级可以在调度器启动后调用vTaskPrioritySet() API函数进行修改。

在FreeRTOSConfig.h 中配置configMAX_PRIORITIES的值,即是最多可具有的优先级数目。

低优先级号表示任务的优先级低,优先级号0表示最低优先级。有效的优先级号范围从0到(configMAX_PRIORITES-1)


要能够选择下一个运行的任务,调度器需要在每个时间片的结束时刻运行自己本身。一个称为心跳(tick,时钟滴答)中断的周期性中断
用于此目的。时间片的长度通过心跳中断的频率进行设定,心跳中断频率由FreeRTOSConfig.h中的编译时配置常量configTICK_RATE_HZ进行配置。

比如说如果configTICK_RATE_HZ设为100(HZ),则时间片长度为10ms。

需要说明的是,FreeRTOS API 函数调用中指定的时间总是以心跳中断为单位。常量portTICK_RATE_MS用于将以心跳为单位的时间值转化为
以毫秒为单位的时间值。有效精度依赖于系统心跳频率。

心跳计数(tick count)值表示的是从调度器启动开始,心跳中断的总数,并假定心跳计数器不会溢出。用户程序在指定延迟周期时不必考虑心跳计数溢出问题,yin
因为时间连贯性在内核中进行管理。


1.6 扩充“非运行态”

调度器总是选择所有能够进入运行态的任务中具有最高优先级的任务。一个高优先级但不能够运行的任务
意味着不会被调度器选中,而代之以另一个优先级虽然更低但能够运行的任务。


阻塞状态
如果一个任务正在等待某个事件,则称这个任务处于“阻塞态(blocked)”。阻塞态是非运行态的一个
子状态。

任务可以进入阻塞态以等待一下两种不同类型的事件:
1、定时(时间相关)事件

2、同步事件

互斥信号量可以实现同步事件。


任务可以在进入阻塞态以等待同步事件是指定一个等待超时时间,这样可以有效地实现阻塞状态下同时
等待两类的事件。比如说,某个任务可以等待队列中有数据到来,但最多只等10ms。如果10ms内有数据到来,
或是10ms过去了还没有数据到来,这两种情况下该任务都将退出阻塞态。

挂起状态

让一个任务进入挂起状态的唯一办法就是调用vTaskSuspend()函数
而吧一个挂起状态的任务唤醒的唯一途径就是调用vTaskResume()或vTaskResumeFromISR()函数

就绪状态

任务能够被运行

void vTaskDelay(portTickType xTicksToDelay);

xTicksToDelay  延时多少个心跳周期。调用该延迟函数的任务将进入阻塞态,经延迟指定的心跳周期数后,
再转移到就绪态。

常数portTICK_RATE_MS 可以用来将以毫秒为单位的时间值转
换为以心跳周期为单位的时间值。

vTaskDelay( 250 / portTICK_RATE_MS );
250ms

空闲任务是在调度启动时自动创建的,以保证至少有一个任务可运行。


空间任务可以获得的执行时间量,是系统处理能力裕量的一个度量指标。

vTaskDelayUntil()函数

vTaskDelayUntil() 类似于vTaskDelay()






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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值