你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】FreeRTOS列表应用示例

[复制链接]
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                                       
/************************结束**************************/




收藏 评论0 发布时间:2022-3-26 14:00

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版