/*********************************************************
*Copyright (C), 2018, Shanghai Eastsoft Microelectronics Co., Ltd.
*文件名:  main.c
*作  者:  Jiayc
*版  本:  V1.00
*日  期:  2020/8/24
*描  述:  FreeRTOS_Mutexes演示程序
          MCU：ES8P5088
          FreeRTOS版本：v10.2.1
          创建三个优先级任务，高优先级，中优先级以及低优先级任务
          高优先级任务和低优先级任务共享互斥量
          由于使用互斥量，当低优先级任务运行时，优先级会提高到与高优先级一致，这样，中优先级任务不能打断
          低优先级任务。
          硬件管脚：LED:PA14  UART_TX:PA15 UART_RX:PA16
*备  注:  本软件仅供学习和演示使用，对用户直接引用代码所带来的风险或后果不承担任何法律责任。
**********************************************************/
#include "ES8P508x.h"
#include "stdio.h"
#include "bsp.h"
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"

SemaphoreHandle_t MultexSemaphore = NULL;

static void vMutexHighPriority_Task(void *pvParameters);
static void vMutexMediumPriority_Task(void *pvParameters);
static void vMutexLowPriority_Task(void *pvParameters);


int main()
{
    LED_init();
    UARTInit();

    MultexSemaphore = xSemaphoreCreateMutex();  //创建互斥量

    taskENTER_CRITICAL();                       //进入临界保护

    xTaskCreate(vMutexHighPriority_Task,        //创建任务
                "MutexHighPriority",
                configMINIMAL_STACK_SIZE,
                NULL,
                5,
                NULL);
    xTaskCreate(vMutexMediumPriority_Task,
                "MutexMediumPriority",
                configMINIMAL_STACK_SIZE,
                NULL,
                4,
                NULL);
    xTaskCreate(vMutexLowPriority_Task,
                "MutexLowPriority",
                configMINIMAL_STACK_SIZE,
                NULL,
                3,
                NULL);

    taskEXIT_CRITICAL();                        //退出临界保护

    vTaskStartScheduler();                      //开始任务调度

    for (;;)
    {

    }
}

static void vMutexHighPriority_Task(void *pvParameters)
{
    for (;;)
    {
        if (xSemaphoreTake(MultexSemaphore, portMAX_DELAY) == pdTRUE)       //获取互斥量
        {
            printf("MutexHighPriority_Task takes multex semaphore.\r\n");
            xSemaphoreGive(MultexSemaphore);                                //释放互斥量
        }

        vTaskDelay(1000);
    }
}

void vMutexMediumPriority_Task(void *pvParameters)
{
    for (;;)
    {
        GPIO->PADATABRR.Word = 1U << 14;
        printf("MutexMediumPriority_Task is running.\r\n");
        vTaskDelay(1000);
    }
}

static void vMutexLowPriority_Task(void *pvParameters)
{
    for (;;)
    {
        if (xSemaphoreTake(MultexSemaphore, portMAX_DELAY) == pdTRUE)
        {
            uint32_t i;
            printf("MutexLowPriority_Task takes multex semaphore.\r\n\r\n");

            for (i = 0; i < 100000; i++)        //模拟低优先级任务长时间占用CPU
            {
                taskYIELD();                    //任务调度
            }

            xSemaphoreGive(MultexSemaphore);    //释放信号量
        }

        vTaskDelay(1000);
    }
}

