单片机FreeRtos实验1

单片机 :STM32F407

开发板:DMF407电机开发板

平台:keil V5.31

HSE 为8MHZ

HSI为16MHZ

一、移植实验

主函数

复制代码
int main(void)
{
    HAL_Init();                         /* 初始化HAL库 */
    sys_stm32_clock_init(336, 8, 2, 7); /* 设置时钟,168Mhz */
    delay_init(168);                    /* 延时初始化 */
    usart_init(115200);                 /* 串口初始化为115200 */
    led_init();                         /* 初始化LED */
    lcd_init();                         /* 初始化LCD */
    key_init();                         /* 初始化按键 */
    my_mem_init(SRAMIN);                /* 初始化内部SRAM内存池 */
    
    freertos_demo();                    /* 运行FreeRTOS例程 */
}

rtos

复制代码
void freertos_demo(void)
{
    lcd_show_string(10, 10, 220, 32, 32, "STM32", RED);
    lcd_show_string(10, 47, 220, 24, 24, "FreeRTOS Porting", RED);
    lcd_show_string(10, 76, 220, 16, 16, "ATOM@ALIENTEK", RED);
    
    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();
}

task

复制代码
void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();           /* 进入临界区 */
    /* 创建任务1 */
    xTaskCreate((TaskFunction_t )task1,
                (const char*    )"task1",
                (uint16_t       )TASK1_STK_SIZE,
                (void*          )NULL,
                (UBaseType_t    )TASK1_PRIO,
                (TaskHandle_t*  )&Task1Task_Handler);
    /* 创建任务2 */
    xTaskCreate((TaskFunction_t )task2,
                (const char*    )"task2",
                (uint16_t       )TASK2_STK_SIZE,
                (void*          )NULL,
                (UBaseType_t    )TASK2_PRIO,
                (TaskHandle_t*  )&Task2Task_Handler);
    vTaskDelete(StartTask_Handler); /* 删除开始任务 */
    taskEXIT_CRITICAL();            /* 退出临界区 */
}

void task1(void *pvParameters)
{
    uint32_t task1_num = 0;
    
    while(1)
    {
        lcd_clear(lcd_discolor[++task1_num % 14]);                      /* 刷新屏幕 */
        lcd_show_string(10, 10, 220, 32, 32, "STM32", RED);
        lcd_show_string(10, 47, 220, 24, 24, "FreeRTOS Porting", RED);
        lcd_show_string(10, 76, 220, 16, 16, "ATOM@ALIENTEK", RED);
        LED0_TOGGLE();                                                  /* LED0闪烁 */
        vTaskDelay(1000);                                               /* 延时1000ticks */
    }
}


void task2(void *pvParameters)
{
    float float_num = 0.0;
    
    while(1)
    {
        float_num += 0.01f;                         /* 更新数值 */
        printf("float_num: %0.4f\r\n", float_num);  /* 打印数值 */
        vTaskDelay(1000);                           /* 延时1000ticks */
    }
}

测试结果

二、中断测试实验

主函数

复制代码
int main(void)
{
    HAL_Init();                         /* 初始化HAL库 */
    sys_stm32_clock_init(336, 8, 2, 7); /* 设置时钟,168Mhz */
    delay_init(168);                    /* 延时初始化 */
    usart_init(115200);                 /* 串口初始化为115200 */
    led_init();                         /* 初始化LED */
    lcd_init();                         /* 初始化LCD */
    key_init();                         /* 初始化按键 */
    my_mem_init(SRAMIN);                /* 初始化内部SRAM内存池 */
    
    freertos_demo();                    /* 运行FreeRTOS例程 */
}

rtos

复制代码
void freertos_demo(void)
{
    lcd_show_string(10, 10, 220, 32, 32, "STM32", RED);
    lcd_show_string(10, 47, 220, 24, 24, "Interrupt", RED);
    lcd_show_string(10, 76, 220, 16, 16, "ATOM@ALIENTEK", RED);
    
    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();
}

task

复制代码
void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();           /* 进入临界区 */
    /* 初始化TIM3、TIM5 */
    btim_tim3_int_init(10000-1, 8400-1);
    btim_tim5_int_init(10000-1, 8400-1);
    /* 创建任务1 */
    xTaskCreate((TaskFunction_t )task1,
                (const char*    )"task1",
                (uint16_t       )TASK1_STK_SIZE,
                (void*          )NULL,
                (UBaseType_t    )TASK1_PRIO,
                (TaskHandle_t*  )&Task1Task_Handler);
    vTaskDelete(StartTask_Handler); /* 删除开始任务 */
    taskEXIT_CRITICAL();            /* 退出临界区 */
}

void task1(void *pvParameters)
{
    uint32_t task1_num = 0;
    
    while (1)
    {
        if (++task1_num == 5)
        {
            printf("FreeRTOS关闭中断\r\n");
            portDISABLE_INTERRUPTS();       /* FreeRTOS关闭中断 */
            delay_ms(5000);
            printf("FreeRTOS打开中断\r\n");
            portENABLE_INTERRUPTS();        /* FreeRTOS打开中断 */
        }
        
        vTaskDelay(1000);
    }
}

测试结果

三、任务创建与删除动态方法实验

主函数

复制代码
int main(void)
{
    HAL_Init();                         /* 初始化HAL库 */
    sys_stm32_clock_init(336, 8, 2, 7); /* 设置时钟,168Mhz */
    delay_init(168);                    /* 延时初始化 */
    usart_init(115200);                 /* 串口初始化为115200 */
    led_init();                         /* 初始化LED */
    lcd_init();                         /* 初始化LCD */
    key_init();                         /* 初始化按键 */
    my_mem_init(SRAMIN);                /* 初始化内部SRAM内存池 */
    
    freertos_demo();                    /* 运行FreeRTOS例程 */
}

rtos

复制代码
void freertos_demo(void)
{
    lcd_show_string(10, 10, 220, 32, 32, "STM32", RED);
    lcd_show_string(10, 47, 220, 24, 24, "Task Create & Del", RED);
    lcd_show_string(10, 76, 220, 16, 16, "ATOM@ALIENTEK", RED);
    
    lcd_draw_rectangle(5, 110, 115, 314, BLACK);
    lcd_draw_rectangle(125, 110, 234, 314, BLACK);
    lcd_draw_line(5, 130, 115, 130, BLACK);
    lcd_draw_line(125, 130, 234, 130, BLACK);
    lcd_show_string(15, 111, 110, 16, 16, "Task1: 000", BLUE);
    lcd_show_string(135, 111, 110, 16, 16, "Task2: 000", BLUE);
    
    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();
}

task

复制代码
void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();           /* 进入临界区 */
    /* 创建任务1 */
    xTaskCreate((TaskFunction_t )task1,                 /* 任务函数 */
                (const char*    )"task1",               /* 任务名称 */
                (uint16_t       )TASK1_STK_SIZE,        /* 任务堆栈大小 */
                (void*          )NULL,                  /* 传入给任务函数的参数 */
                (UBaseType_t    )TASK1_PRIO,            /* 任务优先级 */
                (TaskHandle_t*  )&Task1Task_Handler);   /* 任务句柄 */
    /* 创建任务2 */
    xTaskCreate((TaskFunction_t )task2,                 /* 任务函数 */
                (const char*    )"task2",               /* 任务名称 */
                (uint16_t       )TASK2_STK_SIZE,        /* 任务堆栈大小 */
                (void*          )NULL,                  /* 传入给任务函数的参数 */
                (UBaseType_t    )TASK2_PRIO,            /* 任务优先级 */
                (TaskHandle_t*  )&Task2Task_Handler);   /* 任务句柄 */
    /* 创建任务3 */
    xTaskCreate((TaskFunction_t )task3,                 /* 任务函数 */
                (const char*    )"task3",               /* 任务名称 */
                (uint16_t       )TASK3_STK_SIZE,        /* 任务堆栈大小 */
                (void*          )NULL,                  /* 传入给任务函数的参数 */
                (UBaseType_t    )TASK3_PRIO,            /* 任务优先级 */
                (TaskHandle_t*  )&Task3Task_Handler);   /* 任务句柄 */
    vTaskDelete(StartTask_Handler); /* 删除开始任务 */
    taskEXIT_CRITICAL();            /* 退出临界区 */
}

void task1(void *pvParameters)
{
    uint32_t task1_num = 0;
    
    while (1)
    {
        lcd_fill(6, 131, 114, 313, lcd_discolor[++task1_num % 11]);
        lcd_show_xnum(71, 111, task1_num, 3, 16, 0x80, BLUE);
        
        vTaskDelay(500);
    }
}


void task2(void *pvParameters)
{
    uint32_t task2_num = 0;
    
    while (1)
    {
        lcd_fill(126, 131, 233, 313, lcd_discolor[11 - (++task2_num % 11)]);
        lcd_show_xnum(191, 111, task2_num, 3, 16, 0x80, BLUE);
        
        vTaskDelay(500);
    }
}


void task3(void *pvParameters)
{
    uint8_t key = 0;
    
    while (1)
    {
        key = key_scan(0);
        
        switch (key)
        {
            case KEY0_PRES:                     /* 删除任务1 */
            {
                vTaskDelete(Task1Task_Handler);
                break;
            }
            case KEY1_PRES:                     /* 删除任务2 */
            {
                vTaskDelete(Task2Task_Handler);
                break;
            }
            default:
            {
                break;
            }
        }
        
        vTaskDelay(10);
    }
}

测试结果

四、任务创建与删除静态方法实验

主函数

复制代码
int main(void)
{
    HAL_Init();                         /* 初始化HAL库 */
    sys_stm32_clock_init(336, 8, 2, 7); /* 设置时钟,168Mhz */
    delay_init(168);                    /* 延时初始化 */
    usart_init(115200);                 /* 串口初始化为115200 */
    led_init();                         /* 初始化LED */
    lcd_init();                         /* 初始化LCD */
    key_init();                         /* 初始化按键 */
    my_mem_init(SRAMIN);                /* 初始化内部SRAM内存池 */
    
    freertos_demo();                    /* 运行FreeRTOS例程 */
}

rtos

复制代码
void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, 
                                   StackType_t  **ppxIdleTaskStackBuffer, 
                                   uint32_t     *pulIdleTaskStackSize)
{
    *ppxIdleTaskTCBBuffer   = &IdleTaskTCB;
    *ppxIdleTaskStackBuffer = IdleTaskStack;
    *pulIdleTaskStackSize   = configMINIMAL_STACK_SIZE;
}

void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer,
                                    StackType_t  **ppxTimerTaskStackBuffer,
                                    uint32_t     *pulTimerTaskStackSize)
{
    *ppxTimerTaskTCBBuffer  = &TimerTaskTCB;
    *ppxTimerTaskStackBuffer= TimerTaskStack;
    *pulTimerTaskStackSize  = configTIMER_TASK_STACK_DEPTH;
}

void freertos_demo(void)
{
    lcd_show_string(10, 10, 220, 32, 32, "STM32", RED);
    lcd_show_string(10, 47, 220, 24, 24, "Task Create & Del", RED);
    lcd_show_string(10, 76, 220, 16, 16, "ATOM@ALIENTEK", RED);
    
    lcd_draw_rectangle(5, 110, 115, 314, BLACK);
    lcd_draw_rectangle(125, 110, 234, 314, BLACK);
    lcd_draw_line(5, 130, 115, 130, BLACK);
    lcd_draw_line(125, 130, 234, 130, BLACK);
    lcd_show_string(15, 111, 110, 16, 16, "Task1: 000", BLUE);
    lcd_show_string(135, 111, 110, 16, 16, "Task2: 000", BLUE);
    
    StartTask_Handler = xTaskCreateStatic((TaskFunction_t   )start_task,        /* 任务函数 */
                                          (const char*      )"start_task",      /* 任务名称 */
                                          (uint32_t         )START_STK_SIZE,    /* 任务堆栈大小 */
                                          (void*            )NULL,              /* 传递给任务函数的参数 */
                                          (UBaseType_t      )START_TASK_PRIO,   /* 任务优先级 */
                                          (StackType_t*     )StartTaskStack,    /* 任务堆栈 */
                                          (StaticTask_t*    )&StartTaskTCB);    /* 任务控制块 */
    vTaskStartScheduler();
}

task

复制代码
void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();           /* 进入临界区 */
    /* 创建任务1 */
    Task1Task_Handler = xTaskCreateStatic((TaskFunction_t   )task1,         /* 任务函数 */
                                          (const char*      )"task1",       /* 任务名称 */
                                          (uint32_t         )TASK1_STK_SIZE,/* 任务堆栈大小 */
                                          (void*            )NULL,          /* 传递给任务函数的参数 */
                                          (UBaseType_t      )TASK1_PRIO,    /* 任务优先级 */
                                          (StackType_t*     )Task1TaskStack,/* 任务堆栈 */
                                          (StaticTask_t*    )&Task1TaskTCB);/* 任务控制块 */
    /* 创建任务2 */
    Task2Task_Handler = xTaskCreateStatic((TaskFunction_t   )task2,         /* 任务函数 */
                                          (const char*      )"task2",       /* 任务名称 */
                                          (uint32_t         )TASK2_STK_SIZE,/* 任务堆栈大小 */
                                          (void*            )NULL,          /* 传递给任务函数的参数 */
                                          (UBaseType_t      )TASK2_PRIO,    /* 任务优先级 */
                                          (StackType_t*     )Task2TaskStack,/* 任务堆栈 */
                                          (StaticTask_t*    )&Task2TaskTCB);/* 任务控制块 */
    /* 创建任务3 */
    Task3Task_Handler = xTaskCreateStatic((TaskFunction_t   )task3,         /* 任务函数 */
                                          (const char*      )"task3",       /* 任务名称 */
                                          (uint32_t         )TASK3_STK_SIZE,/* 任务堆栈大小 */
                                          (void*            )NULL,          /* 传递给任务函数的参数 */
                                          (UBaseType_t      )TASK3_PRIO,    /* 任务优先级 */
                                          (StackType_t*     )Task3TaskStack,/* 任务堆栈 */
                                          (StaticTask_t*    )&Task3TaskTCB);/* 任务控制块 */
    vTaskDelete(StartTask_Handler); /* 删除开始任务 */
    taskEXIT_CRITICAL();            /* 退出临界区 */
}

void task1(void *pvParameters)
{
    uint32_t task1_num = 0;
    
    while (1)
    {
        lcd_fill(6, 131, 114, 313, lcd_discolor[++task1_num % 11]);
        lcd_show_xnum(71, 111, task1_num, 3, 16, 0x80, BLUE);
        
        vTaskDelay(500);
    }
}


void task2(void *pvParameters)
{
    uint32_t task2_num = 0;
    
    while (1)
    {
        lcd_fill(126, 131, 233, 313, lcd_discolor[11 - (++task2_num % 11)]);
        lcd_show_xnum(191, 111, task2_num, 3, 16, 0x80, BLUE);
        
        vTaskDelay(500);
    }
}


void task3(void *pvParameters)
{
    uint8_t key = 0;
    
    while (1)
    {
        key = key_scan(0);
        
        switch (key)
        {
            case KEY0_PRES:                     /* 删除任务1 */
            {
                vTaskDelete(Task1Task_Handler);
                break;
            }
            case KEY1_PRES:                     /* 删除任务2 */
            {
                vTaskDelete(Task2Task_Handler);
                break;
            }
            default:
            {
                break;
            }
        }
        
        vTaskDelay(10);
    }
}

测试结果

五、任务挂起与恢复实验

主函数

复制代码
int main(void)
{
    HAL_Init();                         /* 初始化HAL库 */
    sys_stm32_clock_init(336, 8, 2, 7); /* 设置时钟,168Mhz */
    delay_init(168);                    /* 延时初始化 */
    usart_init(115200);                 /* 串口初始化为115200 */
    led_init();                         /* 初始化LED */
    lcd_init();                         /* 初始化LCD */
    key_init();                         /* 初始化按键 */
    my_mem_init(SRAMIN);                /* 初始化内部SRAM内存池 */
    
    freertos_demo();                    /* 运行FreeRTOS例程 */
}

rtos

复制代码
void freertos_demo(void)
{
    lcd_show_string(10, 10, 220, 32, 32, "STM32", RED);
    lcd_show_string(10, 47, 220, 24, 24, "Task Susp & Resum", RED);
    lcd_show_string(10, 76, 220, 16, 16, "ATOM@ALIENTEK", RED);
    
    lcd_draw_rectangle(5, 110, 115, 314, BLACK);
    lcd_draw_rectangle(125, 110, 234, 314, BLACK);
    lcd_draw_line(5, 130, 115, 130, BLACK);
    lcd_draw_line(125, 130, 234, 130, BLACK);
    lcd_show_string(15, 111, 110, 16, 16, "Task1: 000", BLUE);
    lcd_show_string(135, 111, 110, 16, 16, "Task2: 000", BLUE);
    
    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();
}

task

复制代码
void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();           /* 进入临界区 */
    /* 创建任务1 */
    xTaskCreate((TaskFunction_t )task1,
                (const char*    )"task1",
                (uint16_t       )TASK1_STK_SIZE,
                (void*          )NULL,
                (UBaseType_t    )TASK1_PRIO,
                (TaskHandle_t*  )&Task1Task_Handler);
    /* 创建任务2 */
    xTaskCreate((TaskFunction_t )task2,
                (const char*    )"task2",
                (uint16_t       )TASK2_STK_SIZE,
                (void*          )NULL,
                (UBaseType_t    )TASK2_PRIO,
                (TaskHandle_t*  )&Task2Task_Handler);
    /* 创建任务3 */
    xTaskCreate((TaskFunction_t )task3,
                (const char*    )"task3",
                (uint16_t       )TASK3_STK_SIZE,
                (void*          )NULL,
                (UBaseType_t    )TASK3_PRIO,
                (TaskHandle_t*  )&Task3Task_Handler);
    vTaskDelete(StartTask_Handler); /* 删除开始任务 */
    taskEXIT_CRITICAL();            /* 退出临界区 */
}

void task1(void *pvParameters)
{
    uint32_t task1_num = 0;
    
    while (1)
    {
        lcd_fill(6, 131, 114, 313, lcd_discolor[++task1_num % 11]);
        lcd_show_xnum(71, 111, task1_num, 3, 16, 0x80, BLUE);
        
        vTaskDelay(500);
    }
}


void task2(void *pvParameters)
{
    uint32_t task2_num = 0;
    
    while (1)
    {
        lcd_fill(126, 131, 233, 313, lcd_discolor[11 - (++task2_num % 11)]);
        lcd_show_xnum(191, 111, task2_num, 3, 16, 0x80, BLUE);
        
        vTaskDelay(500);
    }
}


void task3(void *pvParameters)
{
    uint8_t key = 0;
    
    while (1)
    {
        key = key_scan(0);
        
        switch (key)
        {
            case KEY0_PRES:                     /* 挂起任务1 */
            {
                vTaskSuspend(Task1Task_Handler);
                break;
            }
            case KEY1_PRES:                     /* 恢复任务1 */
            {
                vTaskResume(Task1Task_Handler);
                break;
            }
            default:
            {
                break;
            }
        }
        
        vTaskDelay(10);
    }
}

测试结果

六、列表项的插入与删除实验

主函数

复制代码
int main(void)
{
    HAL_Init();                         /* 初始化HAL库 */
    sys_stm32_clock_init(336, 8, 2, 7); /* 设置时钟,168Mhz */
    delay_init(168);                    /* 延时初始化 */
    usart_init(115200);                 /* 串口初始化为115200 */
    led_init();                         /* 初始化LED */
    lcd_init();                         /* 初始化LCD */
    key_init();                         /* 初始化按键 */
    my_mem_init(SRAMIN);                /* 初始化内部SRAM内存池 */
    
    freertos_demo();                    /* 运行FreeRTOS例程 */
}

rtos

复制代码
void freertos_demo(void)
{
    lcd_show_string(10, 10, 220, 32, 32, "STM32", RED);
    lcd_show_string(10, 47, 220, 24, 24, "List & ListItem", RED);
    lcd_show_string(10, 76, 220, 16, 16, "ATOM@ALIENTEK", RED);
    
    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();
}

task

复制代码
void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();           /* 进入临界区 */
    /* 创建任务1 */
    xTaskCreate((TaskFunction_t )task1,
                (const char*    )"task1",
                (uint16_t       )TASK1_STK_SIZE,
                (void*          )NULL,
                (UBaseType_t    )TASK1_PRIO,
                (TaskHandle_t*  )&Task1Task_Handler);
    vTaskDelete(StartTask_Handler); /* 删除开始任务 */
    taskEXIT_CRITICAL();            /* 退出临界区 */
}

void task1(void *pvParameters)
{
    /* 第一步:初始化列表和列表项 */
    vListInitialise(&TestList);                 /* 初始化列表 */
    vListInitialiseItem(&ListItem1);            /* 初始化列表项1 */
    vListInitialiseItem(&ListItem2);            /* 初始化列表项2 */
    vListInitialiseItem(&ListItem3);            /* 初始化列表项3 */
    
    /* 第二步:打印列表和其他列表项的地址 */
    printf("/**************第二步:打印列表和列表项的地址**************/\r\n");
    printf("项目\t\t\t地址\r\n");
    printf("TestList\t\t0x%p\t\r\n", &TestList);
    printf("TestList->pxIndex\t0x%p\t\r\n", TestList.pxIndex);
    printf("TestList->xListEnd\t0x%p\t\r\n", (&TestList.xListEnd));
    printf("ListItem1\t\t0x%p\t\r\n", &ListItem1);
    printf("ListItem2\t\t0x%p\t\r\n", &ListItem2);
    printf("ListItem3\t\t0x%p\t\r\n", &ListItem3);
    printf("/**************************结束***************************/\r\n");
    printf("按下KEY0键继续!\r\n\r\n\r\n");
    while (key_scan(0) != KEY0_PRES)
    {
        vTaskDelay(10);
    }
    
    /* 第三步:列表项1插入列表 */
    printf("/*****************第三步:列表项1插入列表******************/\r\n");
    vListInsert((List_t*    )&TestList,         /* 列表 */
                (ListItem_t*)&ListItem1);       /* 列表项 */
    printf("项目\t\t\t\t地址\r\n");
    printf("TestList->xListEnd->pxNext\t0x%p\r\n", (TestList.xListEnd.pxNext));
    printf("ListItem1->pxNext\t\t0x%p\r\n", (ListItem1.pxNext));
    printf("TestList->xListEnd->pxPrevious\t0x%p\r\n", (TestList.xListEnd.pxPrevious));
    printf("ListItem1->pxPrevious\t\t0x%p\r\n", (ListItem1.pxPrevious));
    printf("/**************************结束***************************/\r\n");
    printf("按下KEY0键继续!\r\n\r\n\r\n");
    while (key_scan(0) != KEY0_PRES)
    {
        vTaskDelay(10);
    }
    
    /* 第四步:列表项2插入列表 */
    printf("/*****************第四步:列表项2插入列表******************/\r\n");
    vListInsert((List_t*    )&TestList,         /* 列表 */
                (ListItem_t*)&ListItem2);       /* 列表项 */
    printf("项目\t\t\t\t地址\r\n");
    printf("TestList->xListEnd->pxNext\t0x%p\r\n", (TestList.xListEnd.pxNext));
    printf("ListItem1->pxNext\t\t0x%p\r\n", (ListItem1.pxNext));
    printf("ListItem2->pxNext\t\t0x%p\r\n", (ListItem2.pxNext));
    printf("TestList->xListEnd->pxPrevious\t0x%p\r\n", (TestList.xListEnd.pxPrevious));
    printf("ListItem1->pxPrevious\t\t0x%p\r\n", (ListItem1.pxPrevious));
    printf("ListItem2->pxPrevious\t\t0x%p\r\n", (ListItem2.pxPrevious));
    printf("/**************************结束***************************/\r\n");
    printf("按下KEY0键继续!\r\n\r\n\r\n");
    while (key_scan(0) != KEY0_PRES)
    {
        vTaskDelay(10);
    }
    
    /* 第五步:列表项3插入列表 */
    printf("/*****************第五步:列表项3插入列表******************/\r\n");
    vListInsert((List_t*    )&TestList,         /* 列表 */
                (ListItem_t*)&ListItem3);       /* 列表项 */
    printf("项目\t\t\t\t地址\r\n");
    printf("TestList->xListEnd->pxNext\t0x%p\r\n", (TestList.xListEnd.pxNext));
    printf("ListItem1->pxNext\t\t0x%p\r\n", (ListItem1.pxNext));
    printf("ListItem2->pxNext\t\t0x%p\r\n", (ListItem2.pxNext));
    printf("ListItem3->pxNext\t\t0x%p\r\n", (ListItem3.pxNext));
    printf("TestList->xListEnd->pxPrevious\t0x%p\r\n", (TestList.xListEnd.pxPrevious));
    printf("ListItem1->pxPrevious\t\t0x%p\r\n", (ListItem1.pxPrevious));
    printf("ListItem2->pxPrevious\t\t0x%p\r\n", (ListItem2.pxPrevious));
    printf("ListItem3->pxPrevious\t\t0x%p\r\n", (ListItem3.pxPrevious));
    printf("/**************************结束***************************/\r\n");
    printf("按下KEY0键继续!\r\n\r\n\r\n");
    while (key_scan(0) != KEY0_PRES)
    {
        vTaskDelay(10);
    }
    
    /* 第六步:移除列表项2 */
    printf("/*******************第六步:移除列表项2********************/\r\n");
    uxListRemove((ListItem_t*   )&ListItem2);   /* 移除列表项 */
    printf("项目\t\t\t\t地址\r\n");
    printf("TestList->xListEnd->pxNext\t0x%p\r\n", (TestList.xListEnd.pxNext));
    printf("ListItem1->pxNext\t\t0x%p\r\n", (ListItem1.pxNext));
    printf("ListItem3->pxNext\t\t0x%p\r\n", (ListItem3.pxNext));
    printf("TestList->xListEnd->pxPrevious\t0x%p\r\n", (TestList.xListEnd.pxPrevious));
    printf("ListItem1->pxPrevious\t\t0x%p\r\n", (ListItem1.pxPrevious));
    printf("ListItem3->pxPrevious\t\t0x%p\r\n", (ListItem3.pxPrevious));
    printf("/**************************结束***************************/\r\n");
    printf("按下KEY0键继续!\r\n\r\n\r\n");
    while (key_scan(0) != KEY0_PRES)
    {
        vTaskDelay(10);
    }
    
    /* 第七步:列表末尾添加列表项2 */
    printf("/****************第七步:列表末尾添加列表项2****************/\r\n");
    vListInsertEnd((List_t*     )&TestList,     /* 列表 */
                   (ListItem_t* )&ListItem2);   /* 列表项 */
    printf("项目\t\t\t\t地址\r\n");
    printf("TestList->pxIndex\t\t0x%p\r\n", TestList.pxIndex);
    printf("TestList->xListEnd->pxNext\t0x%p\r\n", (TestList.xListEnd.pxNext));
    printf("ListItem1->pxNext\t\t0x%p\r\n", (ListItem1.pxNext));
    printf("ListItem2->pxNext\t\t0x%p\r\n", (ListItem2.pxNext));
    printf("ListItem3->pxNext\t\t0x%p\r\n", (ListItem3.pxNext));
    printf("TestList->xListEnd->pxPrevious\t0x%p\r\n", (TestList.xListEnd.pxPrevious));
    printf("ListItem1->pxPrevious\t\t0x%p\r\n", (ListItem1.pxPrevious));
    printf("ListItem2->pxPrevious\t\t0x%p\r\n", (ListItem2.pxPrevious));
    printf("ListItem3->pxPrevious\t\t0x%p\r\n", (ListItem3.pxPrevious));
    printf("/************************实验结束***************************/\r\n");
    
    while(1)
    {
        vTaskDelay(10);
    }
}

测试结果

复制代码
[01:18:30.551]收←◆LCD ID:5510

[01:18:30.592]收←◆/**************第二步:打印列表和列表项的地址**************/
项目			地址
TestList		0x200000cc	
TestList->pxIndex	0x200000d4	
TestList->xListEnd	0x200000d4	
ListItem1		0x200000e0	
ListItem2		0x200000f4	
ListItem3		0x20000108	
/**************************结束***************************/
按下KEY0键继续!



[01:18:36.418]收←◆/*****************第三步:列表项1插入列表******************/
项目				地址
TestList->xListEnd->pxNext	0x200000e0
ListItem1->pxNext		0x200000d4
TestList->xListEnd->pxPrevious	0x200000e0
ListItem1->pxPrevious		0x200000d4
/**************************结束***************************/
按下KEY0键继续!



[01:18:46.260]收←◆/*****************第四步:列表项2插入列表******************/
项目				地址
TestList->xListEnd->pxNext	0x200000e0
ListItem1->pxNext		0x200000f4
ListItem2->pxNext		0x200000d4
TestList->xListEnd->pxPrevious	0x200000f4
ListItem1->pxPrevious		0x200000d4
ListItem2->pxPrevious		0x200000e0
/**************************结束***************************/
按下KEY0键继续!



[01:18:48.235]收←◆/*****************第五步:列表项
[01:18:48.261]收←◆3插入列表******************/
项目				地址
TestList->xListEnd->pxNext	0x200000e0
ListItem1->pxNext		0x200000f4
ListItem2->pxNext		0x20000108
ListItem3->pxNext		0x200000d4
TestList->xListEnd->pxPrevious	0x20000108
ListItem1->pxPrevious		0x200000d4
Li
[01:18:48.295]收←◆stItem2->pxPrevious		0x200000e0
ListItem3->pxPrevious		0x200000f4
/**************************结束***************************/
按下KEY0键继续!



[01:18:57.385]收←◆/*******************第六步:移除
[01:18:57.416]收←◆列表项2********************/
项目				地址
TestList->xListEnd->pxNext	0x200000e0
ListItem1->pxNext		0x20000108
ListItem3->pxNext		0x200000d4
TestList->xListEnd->pxPrevious	0x20000108
ListItem1->pxPrevious		0x200000d4
ListItem3->pxPrevious		0x200000e0
/**************************结束***************************/

[01:18:57.450]收←◆按下KEY0键继续!



[01:19:01.241]收←◆/****************第七步:列表末尾添加列表项2****************/
项目				地址
TestList->pxIndex		0x200000d4
TestList->xListEnd->pxNext	0x200000e0
ListItem1->pxNext		0x20000108
ListItem2->pxNext		0x200000d4
ListItem3->pxNext		0x200000f4
TestList->xListEnd->pxPrevious	0x200000f4
ListItem1->pxPrevious		0x200000d4
Li
[01:19:01.306]收←◆stItem2->pxPrevious		0x20000108
ListItem3->pxPrevious		0x200000e0
/************************实验结束***************************/

七、时间片调度实验

主函数

复制代码
int main(void)
{
    HAL_Init();                         /* 初始化HAL库 */
    sys_stm32_clock_init(336, 8, 2, 7); /* 设置时钟,168Mhz */
    delay_init(168);                    /* 延时初始化 */
    usart_init(115200);                 /* 串口初始化为115200 */
    led_init();                         /* 初始化LED */
    lcd_init();                         /* 初始化LCD */
    key_init();                         /* 初始化按键 */
    my_mem_init(SRAMIN);                /* 初始化内部SRAM内存池 */
    
    freertos_demo();                    /* 运行FreeRTOS例程 */
}

rtos

复制代码
void freertos_demo(void)
{
    lcd_show_string(10, 10, 220, 32, 32, "STM32", RED);
    lcd_show_string(10, 47, 220, 24, 24, "FreeRTOS Round Robin", RED);
    lcd_show_string(10, 76, 220, 16, 16, "ATOM@ALIENTEK", RED);
    
    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();
}

task

复制代码
void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();           /* 进入临界区 */
    /* 创建任务1 */
    xTaskCreate((TaskFunction_t )task1,
                (const char*    )"task1",
                (uint16_t       )TASK1_STK_SIZE,
                (void*          )NULL,
                (UBaseType_t    )TASK1_PRIO,
                (TaskHandle_t*  )&Task1Task_Handler);
    /* 创建任务2 */
    xTaskCreate((TaskFunction_t )task2,
                (const char*    )"task2",
                (uint16_t       )TASK2_STK_SIZE,
                (void*          )NULL,
                (UBaseType_t    )TASK2_PRIO,
                (TaskHandle_t*  )&Task2Task_Handler);
    vTaskDelete(StartTask_Handler); /* 删除开始任务 */
    taskEXIT_CRITICAL();            /* 退出临界区 */
}

void task1(void *pvParameters)
{
    uint32_t task1_num = 0;
    
    while (1)
    {
        taskENTER_CRITICAL();
        printf("任务1运行次数: %d\r\n", ++task1_num);
        taskEXIT_CRITICAL();
    }
}


void task2(void *pvParameters)
{
    uint32_t task2_num = 0;
    
    while (1)
    {
        taskENTER_CRITICAL();
        printf("任务2运行次数: %d\r\n", ++task2_num);
        taskEXIT_CRITICAL();
    }
}

测试结果