使用FreeRTOS搭建工程项目(一)

一、freamework框架的设计

做软件框架,实际上就是定义规范,解耦代码,目的,无非是这几个:

●方便复用:代码写了,以后还能用

●定位问题:机器bug,代码bug,容易找到具体模块查出问题。

●代码好改:按照规范写的代码,修改接口时,一下子就搞定了。

●兜底管理:如果你是管理层,小弟跑了,马上能够接手工作。

二、基础学习

a.freertos的配置

配置文件是FreeRTOSConfig.h,打开这个文件,我们有以下关键点需要配置

cpp 复制代码
//CPU工作频率 SWM320RET7经过倍频后,工作在110592000 Hz

#define configCPU_CLOCK_HZ            ( ( unsigned long ) 110592000 )        

//系统滴答,1秒钟产生多少次系统滴答 没有别的需求,设置1000即可

#define configTICK_RATE_HZ            ( ( TickType_t ) 1000 )

//配置堆大小,SWM320RET7拥有128KB大小的SRAM,80KB拿出来给freertos管理。

#define configTOTAL_HEAP_SIZE        ( ( size_t ) ( 80 * 1024 ) )

b.如何创建freertos任务

以task_start为例:

cpp 复制代码
//静态分配一个任务句柄
static TaskHandle_t TaskHandle_start;

//任务入口函数,相当于main函数
void task_start_entry(void *arg)
{
    printf("%s\r\n",__FUNCTION__);
    while(1)
    {

    }
}

//创建任务函数
void create_task_of_start( void )
{    
    //创建任务
    xTaskCreate( task_start_entry, (const char *)"start", 128, NULL, 2, &TaskHandle_start );
}

c.获取系统滴答

cpp 复制代码
uint32_t tick = xTaskGetTickCount();

d.任务延时函数

cpp 复制代码
vTaskDelay( 1000 );    //延时1000个滴答

也可以用系统自带的宏pdMS_TO_TICKS( xTimeInMs),将ms转化为tick,

cpp 复制代码
vTaskDelay( pdMS_TO_TICKS( 1000 ) );    //延时1000ms

​ 我们裸机下的delay()函数,是阻塞的,也就是说,在延时过程中,main()函数是在空转的;

​ 而在freertos中,延时函数vTaskDelay,不单单能实现延时,还会释放CPU资源。

​ 在释放CPU资源后,系统便会马上进行调度,若有就绪任务,会切换到其他就绪任务执行。

再次重复说明一遍:延时函数vTaskDelay,不单单能实现延时,还会释放CPU资源,触发系统调度

e.互斥量解决打印紊乱问题

互斥量,又称互斥信号量,本质上是信号量,是一种特殊的二值信号量。用于对临界资源的独立式处理,我一般称之为锁。

​ 因为任何时刻,互斥量只有两种状态,开锁和闭锁。

​ 举个例子说明一下:


例子1:

​ □ A同学正在使用电饭锅,正在煮绿豆汤

​ □ B同学不管谁在用电饭锅,往里面扔自己的米饭。

​ □ 结果:就是A同学和B同学都得不到自己想要的食物。

​ □ 这种情况,不合理,我们应该定一些规则,让2位同学都能用电饭锅煮好食物。


例子2:

​ □ A同学正在使用电饭锅,正在煮绿豆汤

​ □ B同学想用电饭锅煮米饭,看到有人在用典范锅,等待电饭锅空闲

​ □ 等电饭锅空闲下来了,B同学才用电饭锅煮米饭。

​ □ 结果:A同学可以煮好绿豆汤,B同学可以煮好米饭。


​ 例子1和例子2的差别是,添加了规则,必须等别人用完电饭锅,才使用。

​ 而互斥量,就是用于规则限制的,在多个任务都需要访问互斥资源( 电饭锅 )的时候,都需要先获取锁,操作系统会根据锁的状态,来决定你是否能够正常获取锁:

​ □ 如果你能够成功获取锁,说明资源资源成功被你占用了,你使用完资源后,需要释放锁。

​ □ 如果没能成功获取锁,说明资源被别的任务占用了,需要等待别人释放锁。

首先要在FreeRTOSConfig.h添加一行代码,开启互斥量功能:

cpp 复制代码
#define configUSE_MUTEXES 1

​ 否则会编译报错,找不到互斥量相关函数。

​ 示例代码:

cpp 复制代码
#include "semphr.h"        

static SemaphoreHandle_t cslock;    //保存锁对象

static int flag_init = 0;            //描述锁是否已经初始化了

//初始化锁
void cslock_init(void)
{
    if( flag_init == 1 ) return;
    cslock = xSemaphoreCreateMutex();
    if( cslock == NULL )
    {//说明不成功
        printf( "err:%s\r\n",__func__ );
        while(1);
    }
    flag_init = 1;
}

//获取锁
void cslock_get(void)
{
    if( flag_init == 0 ) return;

    //获取cslock,最多等待100个tick,超时,则返回错误;成功,返回TRUE
    int ret = xSemaphoreTake( cslock,0xFFFFFFFF );
    if( ret == pdTRUE )
    {//说明,成功获取了

    }
    else
    {//失败

    }
}

//释放锁
void cslock_free(void)
{
    if( flag_init == 0 ) return;
    xSemaphoreGive( cslock );
}

//实现自己的打印函数
void myprintf( char* format, ... )
{
    if( flag_init == 0 ) return;

    char buf[256];        //最大可以打印的字符串长度

    va_list v_args;
    va_start( v_args,format );
    (void)vsnprintf( buf,sizeof(buf),format,v_args );

    va_end( v_args );

    //获取锁
    cslock_get();
    //使用互斥资源,因为printf最终调用到uart,指向同一个硬件资源,好几个任务同时使用,是不行的。
    printf("%s",buf);
    //释放锁
    cslock_free();
}
相关推荐
@嵌入式扫地僧8 天前
RTOS 面试实战:任务状态切换原理
freertos·rtos·时间片轮转·任务状态切换·抢占式调度
WWJA王文举15 天前
Bootloader、App 和升级分区之间是什么关系?
stm32·freertos·嵌入式开发·在线升级
怀民民民15 天前
嵌入式软件学习路线与项目实践记录:STM32、FreeRTOS、Linux 与 OpenMV
stm32·freertos·嵌入式软件·嵌入式linux·openmv
长江后浪博客1 个月前
ESP32-SOLO-1 在 ESP-IDF v5.5 下启动不断重启问题分析与解决
单片机·嵌入式硬件·嵌入式·esp32·freertos·esp-idf
WWJA王文举1 个月前
FreeRTOS动态创建任务和静态创建任务详解:xTaskCreate与xTaskCreateStatic区别
操作系统·freertos·嵌入式开发
离凌寒1 个月前
一、关于rtthread nano使用上的细节总结
freertos
桃蹊、1 个月前
串口/网络透传实战:FreeRTOS 多任务架构与连接池设计
stm32·物联网·wifi·freertos
虎王物联1 个月前
ESP32 FreeRTOS多任务优先级翻转与互斥量保护实战
物联网·嵌入式·esp32·freertos
桃蹊、1 个月前
FreeRTOS(六)之队列:任务间通信的基石
freertos·队列