欢迎光临
我们一直在努力

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

一、freamework框架的设计

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

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

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

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

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

二、基础学习

a.freertos的配置

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

//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为例:

//静态分配一个任务句柄
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.获取系统滴答

uint32_t tick = xTaskGetTickCount();

d.任务延时函数

vTaskDelay( 1000 ); //延时1000个滴答

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

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添加一行代码,开启互斥量功能:

#define configUSE_MUTEXES 1

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

​ 示例代码:

#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();
}

赞(0)
未经允许不得转载:171主机测评 » 使用FreeRTOS搭建工程项目(一)
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址