1. 程式人生 > >FreeRTOS學習筆記——互斥型訊號量

FreeRTOS學習筆記——互斥型訊號量

/* Standard includes. */
#include <stdio.h>
#include <string.h>

/* Scheduler includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"

/* Library includes. */
#include "stm32f10x.h"

#define LED0_ON()   GPIO_SetBits(GPIOB,GPIO_Pin_5);
#define LED0_OFF()  GPIO_ResetBits(GPIOB,GPIO_Pin_5);

static void Setup(void);
void TaskA( void *pvParameters );
void TaskB( void *pvParameters );

void LedInit(void);
void UART1Init(void);

/* 互斥訊號量控制代碼 */
SemaphoreHandle_t xSemaphore = NULL;

int main(void)
{
    /* 初始化硬體平臺 */
    Setup();
    /* 建立互斥訊號量 */
    xSemaphore = xSemaphoreCreateMutex();
    /* 建立任務 */
    xTaskCreate( TaskA, "TaskA", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY+3, NULL );
    xTaskCreate( TaskB, "TaskB", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY+4, NULL );
    /* 啟動OS */
    vTaskStartScheduler();
    
    return 0;
}

void TaskA( void *pvParameters )
{
    for( ;; )
    {
        xSemaphoreTake( xSemaphore, portMAX_DELAY );
        {
            printf("Task A\r\n");
        }
        xSemaphoreGive( xSemaphore );
        vTaskDelay( 2000/portTICK_RATE_MS );
    }
}

void TaskB( void *pvParameters )
{
    for( ;; )
    {
        xSemaphoreTake( xSemaphore, portMAX_DELAY );
        {
            printf("Task B\r\n");
        }
        xSemaphoreGive( xSemaphore );
        vTaskDelay( 1000/portTICK_RATE_MS );
    }
}

static void Setup( void )
{
    LedInit();
    UART1Init();
}

void LedInit( void )
{
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE );
    /*LED0 @ GPIOB.5*/
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init( GPIOB, &GPIO_InitStructure );    
}

void UART1Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    
    /* 第1步:開啟GPIO和USART時鐘 */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE);
    
    /* 第2步:將USART1 
[email protected]
的GPIO配置為推輓複用模式 */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); /* 第3步:將USART1 [email protected]的GPIO配置為浮空輸入模式 */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); /* 第4步:配置USART1引數 波特率 = 9600 資料長度 = 8 停止位 = 1 校驗位 = No 禁止硬體流控(即禁止RTS和CTS) 使能接收和傳送 */ USART_InitStructure.USART_BaudRate = 9600; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(USART1, &USART_InitStructure); /* 第5步:使能 USART1, 配置完畢 */ USART_Cmd(USART1, ENABLE); /* 清除傳送完成標誌 */ USART_ClearFlag(USART1, USART_FLAG_TC); /* 使能USART1傳送中斷和接收中斷,並設定優先順序 */ NVIC_InitTypeDef NVIC_InitStructure; // NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); /* 設定USART1 中斷優先順序 */ NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = configLIBRARY_KERNEL_INTERRUPT_PRIORITY; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); /* 使能接收中斷 */ // USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); } int fputc(int ch, FILE *f) { /* 寫一個位元組到USART1 */ USART_SendData(USART1, (uint8_t) ch); /* 等待發送結束 */ while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET) {} return ch; }