裸机开发:
while(1)
{
WEIFAN();
LIAOTIAN();
}//多任务并行在while(1)循环
FreeeRTOS:
while(1)
{
creat_task(喂饭);
creay_task(回信息);
start_scheduler();//让多任务交叉执行
while(1)
{
//可以什么也不用干
}
}
堆:一堆空闲的内存
char heap_buf[1024];//空闲内存,即为堆
int pos = 0;//位置
void *my_malloc(int size)
{
old_pos = pos;//先储存原始变量,即为申请内存的首地址
pos +=size; //记录下堆在申请内存之后的首地址
return &heap[old_pos];//返回申请内存的地址
}
栈:和堆一样,都是一块儿空闲的内存
栈使用地址时是从高到低的
void fun_c()
{
int temp_c;
}
void fun_b()
{
int temp_b;
}
int func_a()
{
int temp_a = 0;
func_b();
func_c();
}
int main()
{
func_a();
return 0;
}
其中 SP 是栈的地址,起始文件给栈分配了空间,SP也指向了main函数
BL 是BL指令,用来调用main函数,并且会把main函数的返回地址保存在LR寄存器中
精简官方FreeRTOS文件
以下为下载源码之后需要保留的源码文件
串口(serial port)
增加串口打印,分为两步:1.初始化串口 2.实现Printf中的putc()函数
上图是串口的F103芯片手册,表示串口的状态寄存器,即为USART->SR,
如图所示状态寄存器在Bit7时,若为1,则表示数据已经完全发送。
串口发送数据时先将数据存入USART->DR,然后串口才会发送。
/*自己编写的fputc函数,并通过printf("hello world\r\n")发送字符串验证*/
int fputc( int ch, FILE *f )
{
USART_TypeDef* USARTx = USART1; //定义一个串口
USARTx->DR = ch;//将数据存进传接口发送的寄存器
while((USARTx->SR & 1<<7) == 0);//判断状态寄存器的第7位是否为1,是1
return ch;
}
使用MDK验证串口发送,先打开魔法棒中Debug,再点击simulator(模拟器),点击左上角的view,选择serial view,再点击usart1,即可以显示串口1发送的数据。
Demo文件夹里是各种架构的示例工程
Source文件夹里是FreeRTOS的核心文件(队列、定时器等)还有portable移植文件
1.数据类型
BaseType_t是FreeRTOS中最高效的数据类型,会根据芯片的架构来自己适应。
2.变量命名
p代表指针、x代表复杂的结构体、后面代表具体内容
前缀表示类型、后面表示内容
3.函数:
x代表返回值类型,Task代表在那个文件里面,Create代表这个函数的功能
prv代表是私有函数,即就是static函数
TCB_t 任务控制块结构体
Handle_t 句柄(当想使用一个结构体但不想了解它的内容时,使用句柄)
xTaskCreate函数:(动态创建栈从而创建任务)
Task1Function是具体的任务函数,“Task1”是任务名称,100是分配栈的容量,NULL是向函数传递的参数,1是&HandleTask1是返回的任务句柄,用于传递一个处理——引用创建的任务。
这里牵扯一个函数指针,Task1Function是函数的指针,类型为TaskFunction_t,
函数指针定义:typedef void (* TaskFunction_t)( void * );
但是具体定义函数时,是void Task1Function(void *param)这种形式,返回值是void,函数指针的类型为TaskFunction_t。
pvCreatedTask这个返回的结构体,代表创建的任务,包含这个任务的所有信息,后面也可以通过删除句柄来删除任务。
xTaskCreateStatic函数:(提前创建栈,然后静态创建任务)
xTask3Stack是栈,xTask3TCB是任务结构体
此处需要补充一个函数,要不然vTaskStartScheduler()开启任务调度函数无法使用
//补充的函数
StackType_t xIdleTaskStack[100]; //空闲栈
StaticTask_t xIdleTaskTCB;//空闲任务的结构体句柄
void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer, StackType_t ** ppxIdleTaskStackBuffer,uint32_t * pulIdleTaskStackSize )
{
*ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
*ppxIdleTaskStackBuffer = xIdleTaskStack;
*pulIdleTaskStackSize = 100;
}