FreeRTOS常用API函数(动态内存分配下)

前言

FreeRTOS有其特殊的变量命名和函数命名:

        比如 char 型变量的前缀是 c,short型变量的前缀是s,long 型变量的前缀是l,portBASE_TYPE 类型变量的前缀是x。还有其他的数据类型,比如数据结构,任务句柄,队列句柄等定义的变量名的前缀也是 x。还包括:如果一个变量是无符号型的那么会有一个前缀 u,如果是一个指针变量则会有一个前缀 p。因此,当我们定义一个无符号的 char 型变量的时候会加一个 uc 前缀,当定义一个char型的指针变量的时候会有一个pc前缀。

函数名的命名

       如果是私有的函数则会加一个prv(private)的前缀。命名的格式一般为:

       返回值+源文件名+功能。

如:

①vTaskPrioritySet()函数的返回值为 void 型,在task.c 这个文件中定义。

②xQueueReceive()函数的返回值为 portBASE_TYPE 型,在 queue.c 这个文件中定义。

③vSemaphoreCreateBinary()函数的返回值为 void 型,在 semphr.h 这个文件中定义。

需要注意的事项:

        带阻塞时间的函数一般在调度器开始后调用,不然可能没有阻塞时间

        带阻塞时间或能引起系统阻塞的函数(如等待信号量等)不能够在中断中使用,但函数名后加FromISR是允许在中断中使用的函数(延时参数为NULL)

        使用某些功能要先将对应的宏置1

一、任务的基础操作

        ①任务句柄        TaskHandle_t     StartTask_Handler;

        ②创建任务        xTaskCreate((TaskFunction_t )start_task,                //执行任务的函数名称
                                                              (const char*    )"start_task",         //任务的名称
                                                              (uint16_t       )128,                        //任务堆栈大小
                                                              (void*          )NULL,                      //参数传递
                                                             (UBaseType_t    )2,                     //任务优先级(越大越高)
                                                             (TaskHandle_t*  )&StartTask_Handler);   //任务控制块句柄

         返回值为pdPass(BaseType_t类型)表示创建成功,否则返回错误信息。

        ③删除任务        vTaskDelete(任务句柄)

        ④开启任务调度        vTaskStartScheduler()   

        ⑤手动任务调度        taskYIELD()

        ⑥进入临界区        taskENTER_CRITICAL();   

        ⑦退出临界区        taskEXIT_CRITICAL();       

 二、任务的挂起和解挂

        ①挂起任务        vTaskSuspend(任务句柄)

        ②恢复挂起的任务        vTaskResume(任务句柄)

三、消息队列(可多个发送或者多个接收者访问同一个队列)

        ①消息队列句柄        QueueHandle_t     Test_Queue =NULL;

        ②创建消息队列
        Test_Queue = xQueueCreate((UBaseType_t ) QUEUE_LEN,   //消息队列包含几个消息
                        (UBaseType_t ) QUEUE_SIZE);                                //一个消息多少字节

        返回值为任务句柄

        ③接收消息

        uint32_t   r_queue;    //定义一个接收消息的变量 

        xQueueReceive( Test_Queue,                            // 消息队列的句柄 
                                        &r_queue,                           //接收消息的变量地址 
                                        portMAX_DELAY);              //等待时间

        返回值为pdTRUE 表示接收成功

        等待时间:0为不等,其他为等待多少ms,portMAX_DELAY是一直等

        ④发送消息

       uint32_t send_data1 = 1;    //定义一个发送消息的变量 

        xQueueSend( Test_Queue,                            // 消息队列的句柄 
                                    &r_queue,                           //发送的消息内容 
                                    portMAX_DELAY);              //等待时间

        返回值为pdTRUE 表示发送成功

        等待时间:0为不等,其他为等待多少ms,portMAX_DELAY是一直等

        等效于xQueueSendBack();是向队尾发送消息。xQueueSendToFront(()是向队首发送消息。

四、信号量(互斥信号量解决优先级翻转问题)

        ①信号量句柄        SemaphoreHandle_t         BinarySem_Handle =NULL;

        ②创建二值信号量        BinarySem_Handle = xSemaphoreCreateBinary();

        ③创建计数信号量    CountSem_Handle = xSemaphoreCreateCounting(信号量最大值,初值); 

        ④创建互斥信号量        MuxSem_Handle = xSemaphoreCreateMutex();    

        信号量使用相同的句柄去定义,使用相同的函数释放和接收

        ⑤获取信号量        xSemaphoreTake(BinarySem_Handle,                     //信号量句柄 
                                                                        portMAX_DELAY);                         // 等待时间

        若返回值为pdTRUE则证明获取成功 

        ⑥释放信号量        xSemaphoreGive( 信号量句柄 );

        若返回值为pdTRUE则证明释放成功 

        ⑦信号量删除        vSemaphoreDelete(句柄)

五、事件(可多个任务等待同一个多条件事件)

        ①事件句柄        EventGroupHandle_t Event_Handle =NULL;

        ②创建事件        Event_Handle = xEventGroupCreate();

        ③等待事件

         EventBits_t r_event;          //定义一个事件接收变量

         r_event = xEventGroupWaitBits(Event_Handle,  //事件对象句柄 
                                  0x01|0x02,                                 // 接收线程感兴趣的事件 (指定的位)
                                  pdTRUE,                                   //退出时清除参数 2的事件位,dpFalse不清
                                  pdTRUE,                                   //满足感兴趣的所有事件 ,dpFalse满足其一
                                  portMAX_DELAY);                    //指定超时事件,一直等

         返回值r_event为事件中哪些位被置位。

        ④置位函数        xEventGroupSetBits(句柄,想要置位的位);

        返回值为调用函数时事件组中的值

        ⑤清除指定的位        xEventGroupClearBits(句柄,想要复位的位)

        返回值为还没清除事件组中位时的值

        ⑥ 删除事件        vEventGroupDelete(句柄)

六、软件定时器(精度不如硬件定时器)

        ①软件定时器句柄        TimerHandle_t         Swtmr1_Handle =NULL;

        ②创建定时器       
         Swtmr1_Handle=xTimerCreate((const char*        )"AutoReloadTimer",    //定时器名称
                            (TickType_t            )1000,                //定时器周期 1000(tick)
                            (UBaseType_t        )pdTRUE,          // 周期模式 
                            (void*                  )1,                         //为每个计时器分配一个索引的唯一ID 
                            (TimerCallbackFunction_t)Swtmr1_Callback);                     //回调函数名

     

        //软件定时器不要调用阻塞函数,也不要进行死循环,应快进快出
        void Swtmr1_Callback(void* parameter)
        {        
            TickType_t         tick_num1;

            tick_num1 = xTaskGetTickCount();    /* 获取滴答定时器的计数值 */

            printf("滴答定时器数值=%d\n", tick_num1);
        }

        ③启动定时器        xTimerStart(句柄,阻塞时间);    

        ④停止定时器        xTimerStop(句柄,阻塞时间);

        ⑤删除定时器        xTimerDelete(句柄,阻塞时间)

七、任务通知(只能向单个任务发送通知)

7.1通知代替消息队列

        ① 发送通知         

         uint32_t send2 = 2;

         xTaskNotify(Receive2Task_Handler,                                          //任务句柄(哪个任务接收)
                                                                send2,                                 // 发送的数据,最大为4字节 
                                                                eSetValueWithOverwrite );  //覆盖当前通知

        若返回值是pdPASS为发送成功  

        ②获取通知

         xTaskNotifyWait(0x0,                        //进入函数的时候不清除任务bit
                                ULONG_MAX,           //退出函数的时候清除所有的bit
                                &r_num,                     //保存任务通知值的变量地址                     
                                portMAX_DELAY);    //阻塞时间
      若返回值是pdPASS为接收成功

7.2通知代替二值信号量、计数信号量

        ①发送通知        xTaskNotifyGive(接收消息的任务的句柄)

        若返回值是pdPASS为发送成功  

        ②获取通知        ulTaskNotifyTake(pdTRUE,阻塞时间)

        第一个参数若为pdTRUE则在函数退出前将通知值置零,若为pdFALSE则将任务通知值减一(对应二值信号量和计数信号量的使用)

         返回值是改变前的通知值

7.3通知代替事件组

        ①发送通知        

         xTaskNotify((TaskHandle_t    )LED2Task_Handler,               //接收任务通知的任务句柄
                                (uint32_t        )0x01,                                        //要触发的事件的位
                                (eNotifyAction)eSetBits);                                //设置任务通知值中的位

         ②接收通知

         xTaskNotifyWait(0x0,                                    //进入函数的时候不清除任务bit
                                        ULONG_MAX,               //退出函数的时候清除所有的bitR
                                        &r_event,                       //保存任务通知值                    
                                        portMAX_DELAY);        //阻塞时间

        以上发送函数的最后一个参数为更新通知的方式
                        

 八、内存管理

        ① 获取当前内存大小        

        uint32_t g_memsize;

        g_memsize = xPortGetFreeHeapSize();

        ②申请内存

        uint8_t *Test_Ptr = NULL;

        Test_Ptr = pvPortMalloc(1024);

        ③释放内存        vPortFree(Test_Ptr);//释放内存

  • 55
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Zx62365

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值