freertos心跳中断_FreeRTOS之任务管理

FreeRTOS学习记录第一天

一、

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

53int main(void)

{

/*主控及相关外设初始化*/

BspInit ();

/* 创建任务 */

AppTaskCreate();

/* 启动调度,开始执行任务 */

vTaskStartScheduler();

/* 如果一切正常, main()函数不应该会执行到这里。但如果执行到这里,很可能是内存堆空间不足导致空闲

任务无法创建。第五章有讲述更多关于内存管理方面的信息 */

for( ;; );

}

static void vTaskTest1(void *pvParameters)

{

volatile unsigned long u1;

for(;;)

{

printf("Test 1\r\n");

for(u1=0;u1<1000000;u1++)

{

}

}

}

static void vTaskTest2(void *pvParameters)

{

volatile unsigned long u1;

for(;;)

{

printf("Test 2\r\n");

for(u1=0;u1<1000000;u1++)

{

}

}

}

static void AppTaskCreate (void)

{

/*测试任务*/

xTaskCreate( vTaskTest1, "vTaskTest1", 512, NULL, 1, NULL );

xTaskCreate( vTaskTest2, "vTaskTest2", 512, NULL, 1, NULL );

}

串口输出:

freertos心跳中断_FreeRTOS之任务管理_第1张图片

分析:

两个任务的优先级相同,因为我们开启了调度器,调度器会让任务轮流执行一个“时间片”;

如果其中一个优先级高,将一直执行优先级高的任务,优先级低的任务也就被“饿死”了,CPU在任何时刻永远执行当前优先级最高的任务;

二、

仅更改任务的优先级:

1

2

3

4

5

6

7static void AppTaskCreate (void)

{

/*测试任务*/

xTaskCreate( vTaskTest1, "vTaskTest1", 512, NULL, 1, NULL );

xTaskCreate( vTaskTest2, "vTaskTest2", 512, NULL, 2, NULL );

}

串口输出如下图所示:

freertos心跳中断_FreeRTOS之任务管理_第2张图片

三、

使用vTaskDelay()延时:

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

34static void vTaskTest1(void *pvParameters)

{

volatile unsigned long u1;

for(;;)

{

printf("Test 1\r\n");

/*调用vTaskDelay()让任务在延迟期间保持在阻塞态,延迟是以心跳周期为单位,

常量portTick_RATE_MS可以用来在毫秒和心跳周期之间相互转换。*/

vTaskDelay(250 / portTICK_RATE_MS);

}

}

static void vTaskTest2(void *pvParameters)

{

volatile unsigned long u1;

for(;;)

{

printf("Test 2\r\n");

/*调用vTaskDelay()让任务在延迟期间保持在阻塞态,延迟是以心跳周期为单位,

常量portTick_RATE_MS可以用来在毫秒和心跳周期之间相互转换。*/

vTaskDelay(250 / portTICK_RATE_MS);

}

}

static void AppTaskCreate (void)

{

/*测试任务*/

xTaskCreate( vTaskTest1, "vTaskTest1", 512, NULL, 1, NULL );

xTaskCreate( vTaskTest2, "vTaskTest2", 512, NULL, 2, NULL );

}

串口打印如下:

freertos心跳中断_FreeRTOS之任务管理_第3张图片

分析:

当程序进入阻塞态时,CPU将执行当前优先级虽然较低但是可以运行的任务,这样来回切换。

四、

补充1:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16#define configUSE_PREEMPTION 1

#define configSUPPORT_STATIC_ALLOCATION 0

#define configSUPPORT_DYNAMIC_ALLOCATION 1

#define configUSE_IDLE_HOOK 0

#define configUSE_TICK_HOOK 0

#define configCPU_CLOCK_HZ ( SystemCoreClock )

#define configTICK_RATE_HZ ((TickType_t)1000) /*心跳中断频率为1000HZ也就是时间片长度1ms*/

#define configMAX_PRIORITIES ( 7 )

#define configMINIMAL_STACK_SIZE ((uint16_t)128)

#define configTOTAL_HEAP_SIZE ((size_t)( 30 * 1024 ) )

#define configMAX_TASK_NAME_LEN ( 16 )

#define configUSE_16_BIT_TICKS 0

#define configUSE_MUTEXES 1

#define configQUEUE_REGISTRY_SIZE 8

#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1

#define configIDLE_SHOULD_YIELD 1

补充2:

vTaskDelayUntil()可以用于精准延时;

函数原型:

1void vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement )

使用示例如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19static void vTaskTest1(void *pvParameters)

{

portTickType xLastWakeTime;

/*变量xLastWakeTime需要被初始化为当前心跳计数值。说明一下,这是该变量

唯一一次被显式赋值,之后,xLastWakeTime将在函数vTaskDelayUntil()中自动

更新*/

xLastWakeTime = xTaskGetTickCount();

for(;;)

{

printf("Test 1\r\n");

/*调用vTaskDelay()让任务在延迟期间保持在阻塞态,延迟是以心跳周期为单位,

常量portTick_RATE_MS可以用来在毫秒和心跳周期之间相互转换。*/

vTaskDelayUntil(&xLastWakeTime,(1000 / portTICK_RATE_MS));

}

}

FreeRTOS学习记录第二天

一、钩子函数

程序如下:

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

34unsigned long ulIdleCycleCount=0UL;//钩子函数变量初始值

static void vTaskTest1(void *pvParameters)

{

for(;;)

{

printf("Test 1\r\n");

printf("ulIdleCycleCount=%ld\r\n",ulIdleCycleCount);

/*调用vTaskDelay()让任务在延迟期间保持在阻塞态,延迟是以心跳周期为单位,

常量portTick_RATE_MS可以用来在毫秒和心跳周期之间相互转换。*/

vTaskDelay(250 / portTICK_RATE_MS);

}

}

static void vTaskTest2(void *pvParameters)

{

volatile unsigned long u1;

for(;;)

{

printf("Test 2\r\n");

printf("ulIdleCycleCount=%ld\r\n",ulIdleCycleCount);

/*调用vTaskDelay()让任务在延迟期间保持在阻塞态,延迟是以心跳周期为单位,

常量portTick_RATE_MS可以用来在毫秒和心跳周期之间相互转换。*/

vTaskDelay(250 / portTICK_RATE_MS);

}

}

/*钩子函数必须命名为vApplicationIdleHook,无参数也无返回值*/

void vApplicationIdleHook( void )

{

ulIdleCycleCount++;

}

串口打印如下:

freertos心跳中断_FreeRTOS之任务管理_第4张图片

注:使用钩子函数必须把configUSE_IDLE_HOOK配置为1

freertos心跳中断_FreeRTOS之任务管理_第5张图片

分析如下:

空闲任务钩子函数会被空闲任务每循环一次就自动调用一次。

通常空闲任务钩子函数被用于:

1.执行低优先级,后台或需要不停处理的功能代码;

2.测试系统处理裕量;

3.将处理器配置到低功耗模式–提供一种自动省电的方法,使得在没有任何应用功能需要处理的时候,系统自动进入省电模式;

二、改变任务优先级

原型:void vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority )

注:

1.改变任务优先级

2.最高优先级为configMAX_PRIORITIES-1,如果设置的值超过了最大可用优先级,则自动封顶为最大值

原型:UBaseType_t uxTaskPriorityGet( TaskHandle_t xTask )

注:

1.获取任务当前的优先级

程序如下:

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/*声明变量用于保存任务2的句柄*/

xTaskHandle xTask2Handle;

static void vTaskTest1(void *pvParameters)

{

UBaseType_t uxNewPriority;

/*NULL表示获取“返回我自己的优先级”*/

uxNewPriority=uxTaskPriorityGet(NULL);

for(;;)

{

printf("Test 1\r\n");

printf("About to run Task2\r\n");

/*将任务2的优先级,设置为比任务1的优先级高1也就是3,

如果不改变优先级的话,就将一直运行任务1了*/

vTaskPrioritySet( xTask2Handle, (uxNewPriority+1));

}

}

static void vTaskTest2(void *pvParameters)

{

UBaseType_t uxNewPriority;

/*NULL表示获取“返回我自己的优先级”*/

uxNewPriority=uxTaskPriorityGet(NULL);

for(;;)

{

printf("Test 2\r\n");

printf("About to lower the Task2 priority\r\n");

/*uxNewPriority-2=1即恢复原来的优先级1,任务1得以运行,否则将

一直运行任务2,任务1将被饿死*/

vTaskPrioritySet( NULL, (uxNewPriority-2));

}

}

static void AppTaskCreate (void)

{

/*测试任务*/

/*任务1创建在优先级2上。任务参数没有用到,设为NULL。任务句柄也不会用到,也设为NULL*/

xTaskCreate( vTaskTest1, "vTaskTest1", 512, NULL, 2, NULL );

/*任务2创建在优先级1上,此优先级低于任务1,任务参数没有用到,设为NULL。但任务2的任务

句柄会被用到,故将xTask2Handle的地址传入*/

xTaskCreate( vTaskTest2, "vTaskTest2", 512, NULL, 1,&xTask2Handle );

}

串口打印如下:

freertos心跳中断_FreeRTOS之任务管理_第6张图片

三、删除任务

原型:void vTaskDelete( TaskHandle_t xTaskToDelete )

注:

1.只有内核为任务分配的内存空间才会在任务被删除后自动回收。任务自己占用的内存或资源需要由应用程序自己显式地释放。

你可能感兴趣的:(freertos心跳中断)