FreeRTOS学习笔记——互斥型信号量
来源:互联网 发布:域名城,潇湘华 编辑:程序博客网 时间:2024/05/08 11:14
0.前言
在嵌入式操作系统中互斥型信号量是任务间资源保护的重要手段。下面结合一个具体例子说明FreeRTOS中的互斥型信号量如何使用。
【FreeRTOS STM32移植笔记】
【FreeRTOS学习笔记——任务间使用队列同步数据】
【FreeRTOS学习笔记——二值型信号量】
【如何在FreeRTOS下实现低功耗——MSP430F5438平台】
【代码链接】——示例代码存于百度网盘
互斥型信号量的使用方法如图1所示。在多数情况下,互斥型信号量和二值型信号非常相似,但是从功能上二值型信号量用于同步,而互斥型信号量用于资源保护。互斥型信号量和二值型信号量还有一个最大的区别,互斥型信号量可以有效解决优先级反转现象。
图1 互斥型信号量使用方法
本例具有两个任务,两个任务都试图通过串口打印内容,此时串口就好比一个“资源”,某个任务使用串口资源时必须保护该资源,使用完串口之后在释放资源。保护和释放动作便对应互斥型信号量的两个基本操作,xSemaphoreTake和xSemaphoreGive。
【代码】
/* 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 Tx@PA9的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 Rx@PA10的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;}
SemaphoreHandle_t xSemaphore = NULL;
申明互斥型信号量,在FreeRTOS中二值型信号量和互斥型信号量类型完全相同。
xSemaphore = xSemaphoreCreateMutex(); 创建互斥型信号量。
xSemaphoreTake( xSemaphore, portMAX_DELAY ); 获得资源的使用权,此处的等待时间为portMAX_DELAY(挂起最大时间),如果任务无法获得资源的使用权,任务会处于挂起状态。
xSemaphoreGive( xSemaphore ); 释放资源的使用权。
互斥型信号量和二值型信号量使用方法相似,但二值型信号量用于同步而互斥型信号量用于资源保护。
3 0
- FreeRTOS学习笔记——互斥型信号量
- FreeRTOS学习笔记——二值型信号量
- FreeRTOS学习笔记——链表
- FreeRTOS学习笔记——创建任务
- FreeRTOS学习笔记——任务延时
- FreeRTOS学习笔记——SysTick中断
- FreeRTOS学习笔记——精准延时
- FreeRTOS学习------信号量(实践)
- FreeRTOS学习笔记——任务删除 vTaskDelete() API
- FreeRTOS 学习笔记 2 —— 创建任务
- FreeRTOS 学习笔记 3 —— 任务状态机之阻塞
- FreeRTOS 学习笔记 4 —— API 使用指南
- FreeRTOS 学习笔记 5 —— 调度算法.简述
- FreeRTOS 信号量
- FreeRTOS 信号量
- FreeRTOS 信号量
- FreeRTOS 学习五:信号量和互斥锁
- FreeRTOS学习3--二值信号量
- 《STL源码解析》读书笔记之allocator(1)
- 基础篇-5.26-回文素数,准确对齐(2/4更新)
- STL: sort
- 视听类--听闻
- 2月三号 集训第三天
- FreeRTOS学习笔记——互斥型信号量
- 利用StringEscapeUtils对字符串进行各种转义与反转义(Java)
- Yii 用户身份验证
- Linux下Perl的安装
- [IOS]手势识别(双击、捏、旋转、拖动、划动、长按)
- LoadRunner中参数化技术详解
- 嵌入式 fprintf和fscanf函数
- 第二章 表达式与运算符
- Super Jumping! Jumping! Jumping!