一. RTOS的概念
// 经典单片机程序
void main()
{
while (1)
{
喂一口饭();
回一个信息();
}
}
------------------------------------------------------
// RTOS程序
喂饭()
{
while (1)
{
喂一口饭();
}
}
回信息()
{
while (1)
{
回一个信息();
}
}
void main()
{
create_task(喂饭);
create_task(回信息);
start_scheduler();
while (1)
{
sleep();
}
}
二.FreeRTOS目录结构
三.从官方源码裁剪
1. 下载
2. 删减目录
3. 编译、执行
4. 添加串口打印功能
-
去掉无关的代码:LCD等
-
增加串口打印功能
-
初始化串口
-
实现fputc
-
四. 创建任务
BaseType_t xTaskCreate(
TaskFunction_t pxTaskCode, // 函数指针, 任务函数
const char * const pcName, // 任务的名字
const configSTACK_DEPTH_TYPE usStackDepth, // 栈大小,单位为word,10表示40字节
void * const pvParameters, // 调用任务函数时传入的参数
UBaseType_t uxPriority, // 优先级
TaskHandle_t * const pxCreatedTask // 任务句柄, 以后使用它来操作这个任务
);
1.创建第一个任务
void Task1Function(void*param)//函数指针
{
while(1)
{
printf("1");
}
}
/*-----------------------------------------------------------*/
int main( void )
{
TaskHandle_t xHandleTask1;
#ifdef DEBUG
debug();
#endif
prvSetupHardware();
printf("hello,world,nimade!\r\n");
xTaskCreate(Task1Function,"Task1",100,NULL,1,&xHandleTask1);//创建任务
/* Start the scheduler. */
vTaskStartScheduler();
/* Will only get here if there was not enough heap space to create the
idle task. */
return 0;
}
不断的执行1
2.创建第二个任务
void Task1Function(void*param)
{
while(1)
{
printf("1");
}
}
void Task2Function(void*param)
{
while(1)
{
printf("2");
}
}
/*-----------------------------------------------------------*/
int main( void )
{
TaskHandle_t xHandleTask1;
#ifdef DEBUG
debug();
#endif
prvSetupHardware();
printf("hello,world,nimade!\r\n");
xTaskCreate(Task1Function,"Task1",100,NULL,1,&xHandleTask1);
xTaskCreate(Task2Function,"Task2",100,NULL,1,NULL);//这里没有加句柄
/* Start the scheduler. */
vTaskStartScheduler();
/* Will only get here if there was not enough heap space to create the
idle task. */
return 0;
}
3.动态内存的使用
TCB_t * pxNewTCB;//任务控制块
BaseType_t xReturn;
对于每一个任务都有一个TCB_t 结构体,对于这个结构体可以使用动态分配也可以静态分配。动态分配在程序里面使用 xTaskCreate();
TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode,
const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
const uint32_t ulStackDepth,
void * const pvParameters,
UBaseType_t uxPriority,
StackType_t * const puxStackBuffer,
StaticTask_t * const pxTaskBuffer )
{
void Task1Function(void*param)
{
while(1)
{
printf("1");
}
}
void Task2Function(void*param)
{
while(1)
{
printf("2");
}
}
void Task4Function(void*param)
{
while(1)
{
printf("3");
}
}
/*-----------------------------------------------------------*/
StackType_t xTask4Stack[100];//100*4字节
StaticTask_t xTask4TCB;
StackType_t xIdleTaskStack[100];//100*4字节
StaticTask_t xIdleTaskTCB;
void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer,
StackType_t ** ppxIdleTaskStackBuffer,
uint32_t * pulIdleTaskStackSize )
{
*ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
*ppxIdleTaskStackBuffer = xIdleTaskStack;
*pulIdleTaskStackSize = 100;
}
int main( void )
{
LED_Init();
TaskHandle_t xHandleTask1;
#ifdef DEBUG
debug();
#endif
prvSetupHardware();
printf("hello,world,nimade!\r\n");
xTaskCreate(Task1Function,"Task1",100,NULL,1,&xHandleTask1);
xTaskCreate(Task2Function,"Task2",100,NULL,1,NULL);
xTaskCreateStatic(Task4Function,"Task4",100,NULL,1,xTask4Stack,&xTask4TCB);
/* Start the scheduler. */
vTaskStartScheduler();
/* Will only get here if there was not enough heap space to create the
idle task. */
return 0;
}