STMCU小助手
发布时间:2022-3-26 14:00
|
01. 概述 掌握FreeRTOS中列表和列表项相关函数的使用。 02. 任务设计 3 个任务:start_task、task1_task 和task2_task,这三个任务的任务功能如下: start_task:用来创建其他2 个任务。 task1_task:应用任务1,控制LED0 闪烁,用来提示系统正在运行。 task2_task: 列表和列表项操作任务,调用列表和列表项相关的API 函数,并且通过串口输出相应的信息来观察这些API 函数的运行过程。 需要用到KEY_UP 按键,用于控制任务的运行。 03. 相关设置 任务优先级和堆栈大小设置 //任务优先级 #define START_TASK_PRIO 1 //任务堆栈大小 #define START_STK_SIZE 128 //任务句柄 TaskHandle_t StartTask_Handler; //任务函数 void start_task(void *pvParameters); //任务优先级 #define TASK1_TASK_PRIO 2 //任务堆栈大小 #define TASK1_STK_SIZE 50 //任务句柄 TaskHandle_t Task1Task_Handler; //任务函数 void task1_task(void *pvParameters); //任务优先级 #define TASK2_TASK_PRIO 3 //任务堆栈大小 #define TASK2_STK_SIZE 50 //任务句柄 TaskHandle_t Task2Task_Handler; //任务函数 void task2_task(void *pvParameters); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 列表和列表项定义 //列表和列表项定义 List_t list; ListItem_t listItem1; ListItem_t listItem2; ListItem_t listItem3; 1 2 3 4 5 04. 程序设计 main.c文件 #include "sys.h" #include "delay.h" #include "usart.h" #include "led.h" #include "key.h" #include "FreeRTOS.h" #include "task.h" //任务优先级 #define START_TASK_PRIO 1 //任务堆栈大小 #define START_STK_SIZE 128 //任务句柄 TaskHandle_t StartTask_Handler; //任务函数 void start_task(void *pvParameters); //任务优先级 #define TASK1_TASK_PRIO 2 //任务堆栈大小 #define TASK1_STK_SIZE 50 //任务句柄 TaskHandle_t Task1Task_Handler; //任务函数 void task1_task(void *pvParameters); //任务优先级 #define TASK2_TASK_PRIO 3 //任务堆栈大小 #define TASK2_STK_SIZE 50 //任务句柄 TaskHandle_t Task2Task_Handler; //任务函数 void task2_task(void *pvParameters); //列表和列表项定义 List_t list; ListItem_t listItem1; ListItem_t listItem2; ListItem_t listItem3; //主函数 int main(void) { NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4 delay_init(168); //初始化延时函数 uart_init(115200); //初始化串口 LED_Init(); //初始化LED端口 KEY_Init(); //按键初始化 //创建开始任务 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(); //进入临界区 //创建TASK1任务 xTaskCreate((TaskFunction_t )task1_task, (const char* )"task1_task", (uint16_t )TASK1_STK_SIZE, (void* )NULL, (UBaseType_t )TASK1_TASK_PRIO, (TaskHandle_t* )&Task1Task_Handler); //创建TASK2任务 xTaskCreate((TaskFunction_t )task2_task, (const char* )"task2_task", (uint16_t )TASK2_STK_SIZE, (void* )NULL, (UBaseType_t )TASK2_TASK_PRIO, (TaskHandle_t* )&Task2Task_Handler); vTaskDelete(StartTask_Handler); //删除开始任务 taskEXIT_CRITICAL(); //退出临界区 } //任务1 不停的闪烁表示系统正在正常运行 void task1_task(void *pvParameters) { while(1) { LED0 = !LED0; //延时1秒 1000个时钟节拍 vTaskDelay(1000); } } //任务2 列表和列表项相关操作 void task2_task(void *pvParameters) { //第一步:初始化列表和列表项 vListInitialise(&list); vListInitialiseItem(&listItem1); vListInitialiseItem(&listItem2); vListInitialiseItem(&listItem3); listItem1.xItemValue=40; //ListItem1列表项值为40 listItem2.xItemValue=60; //ListItem2列表项值为60 listItem3.xItemValue=50; //ListItem3列表项值为50 //第二步:打印列表和其他列表项的地址 printf("/*******************列表和列表项地址*******************/\r\n"); printf("项目 地址 \r\n"); printf("TestList %#x \r\n",(int)&list); printf("TestList->pxIndex %#x \r\n",(int)list.pxIndex); printf("TestList->xListEnd %#x \r\n",(int)(&list.xListEnd)); printf("ListItem1 %#x \r\n",(int)&listItem1); printf("ListItem2 %#x \r\n",(int)&listItem2); printf("ListItem3 %#x \r\n",(int)&listItem3); printf("/************************结束**************************/\r\n"); printf("按下KEY_UP键继续!\r\n\r\n\r\n"); while(Key_Scan()!=WK_UP_PRESS) delay_ms(10); //等待KEY_UP键按下 //第三步:向列表TestList添加列表项ListItem1,并通过串口打印所有 //列表项中成员变量pxNext和pxPrevious的值,通过这两个值观察列表 //项在列表中的连接情况。 vListInsert(&list,&listItem1); //插入列表项ListItem1 printf("/******************添加列表项ListItem1*****************/\r\n"); printf("项目 地址 \r\n"); printf("TestList->xListEnd->pxNext %#x \r\n",(int)(list.xListEnd.pxNext)); printf("ListItem1->pxNext %#x \r\n",(int)(listItem1.pxNext)); printf("/*******************前后向连接分割线********************/\r\n"); printf("TestList->xListEnd->pxPrevious %#x \r\n",(int)(list.xListEnd.pxPrevious)); printf("ListItem1->pxPrevious %#x \r\n",(int)(listItem1.pxPrevious)); printf("/************************结束**************************/\r\n"); printf("按下KEY_UP键继续!\r\n\r\n\r\n"); while(Key_Scan()!=WK_UP_PRESS) delay_ms(10); //等待KEY_UP键按下 //第四步:向列表TestList添加列表项ListItem2,并通过串口打印所有 //列表项中成员变量pxNext和pxPrevious的值,通过这两个值观察列表 //项在列表中的连接情况。 vListInsert(&list,&listItem2); //插入列表项ListItem2 printf("/******************添加列表项ListItem2*****************/\r\n"); printf("项目 地址 \r\n"); printf("TestList->xListEnd->pxNext %#x \r\n",(int)(list.xListEnd.pxNext)); printf("ListItem1->pxNext %#x \r\n",(int)(listItem1.pxNext)); printf("ListItem2->pxNext %#x \r\n",(int)(listItem2.pxNext)); printf("/*******************前后向连接分割线********************/\r\n"); printf("TestList->xListEnd->pxPrevious %#x \r\n",(int)(list.xListEnd.pxPrevious)); printf("ListItem1->pxPrevious %#x \r\n",(int)(listItem1.pxPrevious)); printf("ListItem2->pxPrevious %#x \r\n",(int)(listItem2.pxPrevious)); printf("/************************结束**************************/\r\n"); printf("按下KEY_UP键继续!\r\n\r\n\r\n"); while(Key_Scan()!=WK_UP_PRESS) delay_ms(10); //等待KEY_UP键按下 //第五步:向列表TestList添加列表项ListItem3,并通过串口打印所有 //列表项中成员变量pxNext和pxPrevious的值,通过这两个值观察列表 //项在列表中的连接情况。 vListInsert(&list,&listItem3); //插入列表项ListItem3 printf("/******************添加列表项ListItem3*****************/\r\n"); printf("项目 地址 \r\n"); printf("TestList->xListEnd->pxNext %#x \r\n",(int)(list.xListEnd.pxNext)); printf("ListItem1->pxNext %#x \r\n",(int)(listItem1.pxNext)); printf("ListItem3->pxNext %#x \r\n",(int)(listItem3.pxNext)); printf("ListItem2->pxNext %#x \r\n",(int)(listItem2.pxNext)); printf("/*******************前后向连接分割线********************/\r\n"); printf("TestList->xListEnd->pxPrevious %#x \r\n",(int)(list.xListEnd.pxPrevious)); printf("ListItem1->pxPrevious %#x \r\n",(int)(listItem1.pxPrevious)); printf("ListItem3->pxPrevious %#x \r\n",(int)(listItem3.pxPrevious)); printf("ListItem2->pxPrevious %#x \r\n",(int)(listItem2.pxPrevious)); printf("/************************结束**************************/\r\n"); printf("按下KEY_UP键继续!\r\n\r\n\r\n"); while(Key_Scan()!=WK_UP_PRESS) delay_ms(10); //等待KEY_UP键按下 //第六步:删除ListItem2,并通过串口打印所有列表项中成员变量pxNext和 //pxPrevious的值,通过这两个值观察列表项在列表中的连接情况。 uxListRemove(&listItem2); //删除ListItem2 printf("/******************删除列表项ListItem2*****************/\r\n"); printf("项目 地址 \r\n"); printf("TestList->xListEnd->pxNext %#x \r\n",(int)(list.xListEnd.pxNext)); printf("ListItem1->pxNext %#x \r\n",(int)(listItem1.pxNext)); printf("ListItem3->pxNext %#x \r\n",(int)(listItem3.pxNext)); printf("/*******************前后向连接分割线********************/\r\n"); printf("TestList->xListEnd->pxPrevious %#x \r\n",(int)(list.xListEnd.pxPrevious)); printf("ListItem1->pxPrevious %#x \r\n",(int)(listItem1.pxPrevious)); printf("ListItem3->pxPrevious %#x \r\n",(int)(listItem3.pxPrevious)); printf("/************************结束**************************/\r\n"); printf("按下KEY_UP键继续!\r\n\r\n\r\n"); while(Key_Scan()!=WK_UP_PRESS) delay_ms(10); //等待KEY_UP键按下 //第七步:插入ListItem2,并通过串口打印所有列表项中成员变量pxNext和 //pxPrevious的值,通过这两个值观察列表项在列表中的连接情况。 list.pxIndex=list.pxIndex->pxNext; //pxIndex向后移一项,这样pxIndex就会指向ListItem1。 vListInsertEnd(&list,&listItem2); //列表末尾添加列表项ListItem2 printf("/***************在末尾添加列表项ListItem2***************/\r\n"); printf("项目 地址 \r\n"); printf("TestList->pxIndex %#x \r\n",(int)list.pxIndex); printf("TestList->xListEnd->pxNext %#x \r\n",(int)(list.xListEnd.pxNext)); printf("ListItem2->pxNext %#x \r\n",(int)(listItem2.pxNext)); printf("ListItem1->pxNext %#x \r\n",(int)(listItem1.pxNext)); printf("ListItem3->pxNext %#x \r\n",(int)(listItem3.pxNext)); printf("/*******************前后向连接分割线********************/\r\n"); printf("TestList->xListEnd->pxPrevious %#x \r\n",(int)(list.xListEnd.pxPrevious)); printf("ListItem2->pxPrevious %#x \r\n",(int)(listItem2.pxPrevious)); printf("ListItem1->pxPrevious %#x \r\n",(int)(listItem1.pxPrevious)); printf("ListItem3->pxPrevious %#x \r\n",(int)(listItem3.pxPrevious)); printf("/************************结束**************************/\r\n\r\n\r\n"); while(1) { LED1=!LED1; vTaskDelay(1000); //延时1s,也就是1000个时钟节拍 } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 05. 实验结果 /*******************列表和列表项地址*******************/ 项目 地址 TestList 0x200000bc TestList->pxIndex 0x200000c4 TestList->xListEnd 0x200000c4 ListItem1 0x200000d0 ListItem2 0x200000e4 ListItem3 0x200000f8 /************************结束**************************/ 按下KEY_UP键继续! /******************添加列表项ListItem1*****************/ 项目 地址 TestList->xListEnd->pxNext 0x200000d0 ListItem1->pxNext 0x200000c4 /*******************前后向连接分割线********************/ TestList->xListEnd->pxPrevious 0x200000d0 ListItem1->pxPrevious 0x200000c4 /************************结束**************************/ 按下KEY_UP键继续! /******************添加列表项ListItem2*****************/ 项目 地址 TestList->xListEnd->pxNext 0x200000d0 ListItem1->pxNext 0x200000e4 ListItem2->pxNext 0x200000c4 /*******************前后向连接分割线********************/ TestList->xListEnd->pxPrevious 0x200000e4 ListItem1->pxPrevious 0x200000c4 ListItem2->pxPrevious 0x200000d0 /************************结束**************************/ 按下KEY_UP键继续! /******************添加列表项ListItem3*****************/ 项目 地址 TestList->xListEnd->pxNext 0x200000d0 ListItem1->pxNext 0x200000f8 ListItem3->pxNext 0x200000e4 ListItem2->pxNext 0x200000c4 /*******************前后向连接分割线********************/ TestList->xListEnd->pxPrevious 0x200000e4 ListItem1->pxPrevious 0x200000c4 ListItem3->pxPrevious 0x200000d0 ListItem2->pxPrevious 0x200000f8 /************************结束**************************/ 按下KEY_UP键继续! /******************删除列表项ListItem2*****************/ 项目 地址 TestList->xListEnd->pxNext 0x200000d0 ListItem1->pxNext 0x200000f8 ListItem3->pxNext 0x200000c4 /*******************前后向连接分割线********************/ TestList->xListEnd->pxPrevious 0x200000f8 ListItem1->pxPrevious 0x200000c4 ListItem3->pxPrevious 0x200000d0 /************************结束**************************/ 按下KEY_UP键继续! /***************在末尾添加列表项ListItem2***************/ 项目 地址 TestList->pxIndex 0x200000d0 TestList->xListEnd->pxNext 0x200000e4 ListItem2->pxNext 0x200000d0 ListItem1->pxNext 0x200000f8 ListItem3->pxNext 0x200000c4 /*******************前后向连接分割线********************/ TestList->xListEnd->pxPrevious 0x200000f8 ListItem2->pxPrevious 0x200000c4 ListItem1->pxPrevious 0x200000e4 ListItem3->pxPrevious 0x200000d0 /************************结束**************************/ |
【经验分享】STM32 HAL库移植FreeModbus详细步骤
【逢7发帖赢大礼】STM32开发之IC门禁卡UID读取方法!
实战经验 | Keil工程使用NEAI库的异常问题
经验分享 | FDCAN数据段波特率增加后发送失败的问题分析
STM32几种流行开发环境的优缺点
好用软件推荐-TouchGFX Designer
OpenSTLinux 6.1发布:M33-TD加持+安全升级,STM32MPU开发效率翻倍!
【经验分享】STM32CubeIDE汉化
手把手教你VSCode搭建STM32开发环境
RTOS在STM32中的应用
微信公众号
手机版