FreeRTOS多任务(LED + BEEP)

余生颓废 提交于 2020-03-20 15:16:32

函数流程

int main(void)
{
    /* 第一步:开发板硬件初始化 */
    BSP_Init();

    /* 第二步:创建APP应用任务,所有的应用任务都可以放在这个函数里面 */
    AppTaskCreate();
    
    /* 第三步:启动FreeRTOS,开始多任务调度,启动成功则不返回 */
    vTaskStartScheduler();
    
    while (1)
    {
        
    }
}

创建APP应用任务,

static void AppTaskCreate(void)
{
    xTaskCreate(vTaskLed1,           /* 任务函数名 */
                "Task Led1",         /* 任务名,字符串形式,方便调试 */
                 512,                /* 栈大小,单位为字,即4个字节 */
                 NULL,               /* 任务形参 */
                 0,                  /* 优先级,数值越大,优先级越高 */
                 &xHandleTaskLED1);  /* 任务句柄 */
    
    xTaskCreate(vTaskBeep,"Task Beep",512,NULL,2,&xHandleTaskBeep);
}

pvTaskCode 任务只是永不退出的 C 函数,实现通常是一个死循环。参数pvTaskCode 只是一个指向任务的实现函数的指针(效果上仅仅是函数名)。


pcName 具有描述性的任务名。这个参数不会被 FreeRTOS 使用。其只是单纯地用于辅助调试。识别一个具有可读性的名字总是比通过句柄来识别容易得多。

应用程序可以通过定义常量 config_MAX_TASK_NAME_LEN 来定义任务名的最大长度——包括’\0’结束符。如果传入的字符串长度超过了这个最大值,字符串将会自动被截断。

usStackDepth 当任务创建时,内核会分为每个任务分配属于任务自己的唯一状态。

usStackDepth 值用于告诉内核为它分配多大的栈空间。这个值指定的是栈空间可以保存多少个字(word),

而不是多少个字节(byte)。比如说,如果是 32 位宽的栈空间,传入的 usStackDepth值为 100,
则将会分配 400 字节的栈空间(100 * 4bytes)。栈深度乘以栈宽度的结果千万不能超过一个 size_t 类型变量所能表达的最大值。


应用程序通过定义常量 configMINIMAL_STACK_SIZE 来决定空闲任务任用的栈空间大小。
在 FreeRTOS 为微控制器架构提供的Demo 应用程序中,赋予此常量的值是对所有任务的最小建议值。

如果你的任务会使用大量栈空间,那么你应当赋予一个更大的值。
没有任何简单的方法可以决定一个任务到底需要多大的栈空间。

计算出来虽然是可能的,但大多数用户会先简单地赋予一个自认为合理的值,
然后利用 FreeRTOS 提供的特性来确证分配的空间既不欠缺也不浪费。

pvParameters 任务函数接受一个指向 void 的指针(void*)。pvParameters 的值即是传递到任务中的值。

uxPriority 指定任务执行的优先级。优先级的取值范围可以从最低优先级 0 到最高优先级(configMAX_PRIORITIES – 1)。
configMAX_PRIORITIES 是一个由用户定义的常量。优先级号并没有上限(除了受限于采用的数据类型和系统的有效内存空间),
但最好使用实际需要的最小数值以避免内存浪费。如果 uxPriority 的值超过了(configMAX_PRIORITIES – 1),
将会导致实际赋给任务的优先级被自动封顶到最大合法值。


 

 

void vTaskLed1(void *pvParameters)
{
    /* 任务都是一个无限,不能返回 */
    while(1)
    {
        LED1_ON;
        /* 阻塞延时,单位ms */        
        vTaskDelay( 500 );
        LED1_OFF;
        vTaskDelay( 500 );
    }

}

void vTaskBeep(void *pvParameters)
{
    /* 任务都是一个无限,不能返回 */
    while(1)
    {
        BEEP_ON;
        /* 阻塞延时,单位ms */        
        vTaskDelay( 500 );
        BEEP_OFF;
        vTaskDelay( 500 );
    }

  

调度器保证总是在所有可运行的任务中选择具有最高优先级的任务,并使其进入运行态。
如果被选中的优先级上具有不止一个任务,调度器会让这些任务轮流执行。这种行为方式在本例中可以明显看出来。
两个测试任务被创建在同一个优先级上,并且一直是可运行的。所以每个任务都执行一个”时间片”,
任务在时间片起始时刻进入运行态,在时间片结束时刻又退出运行态。
图  中 t1 与 t2 之间的时段就等于一个时间片。

 

 

 

 



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!