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