提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
前言
为了系统的学习一下freertos,找到一份适配stm32c8t6的freertos工程源码,并加入日志模块,方便更好的定位问题,后期打算用这个工程写个密码锁。
freertos系统以及移植好了,就不赘述了,代码里只开了一个线程,需要可以多开。
xTaskCreate((TaskFunction_t )start_task,
(const char* )"start_task",
(uint16_t )START_STK_SIZE,
(void* )NULL,
(UBaseType_t )START_TASK_PRIO,
(TaskHandle_t* )&StartTask_Handler);
vTaskStartScheduler();
void start_task(void *pvParameters)
{
taskENTER_CRITICAL();
xTaskCreate((TaskFunction_t )led0_task,
(const char* )"led0_task",
(uint16_t )LED0_STK_SIZE,
(void* )NULL,
(UBaseType_t )LED0_TASK_PRIO,
(TaskHandle_t* )&LED0Task_Handler);
xTaskCreate((TaskFunction_t )key_task,
(const char* )"key_task",
(uint16_t )KEY_STK_SIZE,
(void* )NULL,
(UBaseType_t )KEY_TASK_PRIO,
(TaskHandle_t* )&KEYTask_Handler);
vTaskDelete(StartTask_Handler);
taskEXIT_CRITICAL();
}
线程栈大小
经验证,stm32f103c8t6最大可开线程栈大小为1024+128,然后剩余在分配到子线程中去总线程栈大小不超过该值即可。举例代码如下:
#define START_TASK_PRIO 1
#define START_STK_SIZE 1024+128
TaskHandle_t StartTask_Handler;
void start_task(void *pvParameters);
#define LED0_TASK_PRIO 3
#define LED0_STK_SIZE 256
TaskHandle_t LED0Task_Handler;
void led0_task(void *pvParameters);
#define KEY_TASK_PRIO 2
#define KEY_STK_SIZE 256
TaskHandle_t KEYTask_Handler;
void key_task(void *pvParameters);
日志模块
在以上代码基础上,添加日志模块,代码如下:
#define LOGD(FORMAT,...) logd(__FILE__,__LINE__,__FUNCTION__,FORMAT,##__VA_ARGS__)
int logd(const char* filename, int lines, const char* functions,const char*format, ...) {
va_list argPtr;
char buf[128];
int count;
memset(buf,0,sizeof(buf));
va_start(argPtr, format); /* 获取可变参数列表 */
count = vsprintf(buf, format, argPtr); /* 将信息输出到标准出错流设备 */
printf("[%s][%d][%s]:%s\r\n",filename,lines,functions,buf);
va_end(argPtr); /* 可变参数列表结束 */
}
线程函数加一行打印
void led0_task(void *pvParameters)
{
LOGD("led task start\n");
while(1)
{
LED0 = ~LED0;
vTaskDelay(500);
}
}
串口打印如下: