freertos-two value signal volume

Source: Internet
Author: User

Original address: http://blog.csdn.net/xukai871105/article/details/43153177

1. Foreword in embedded operating system, the two-valued signal is an important means to synchronize between tasks and interrupts. FreeRTOS's two-value signal is easy to use, with a specific example below to illustrate how the two-value semaphore in FreeRTOS is used.
2. In particular , the use of the two value-type semaphore is shown in Figure 1, the value of the binary signal can be understood as between the task and interrupt or between two tasks, the flag is not "full" is "empty". The send operation quite puts the flag "full", and the receive operation is related to "empty" the flag, and the send and receive operations synchronize tasks with interrupts or between two tasks.

Fig. 12 schematic diagram of value-type semaphore usage
"Special Instructions" V7. There is a slight difference between the X version and the semaphore operation of the v8.x V7. Using the Vsemaphorecreatebinary function in version x, the initial semaphore created with this function is "full" and the receive operation returns immediately.     Related code see the article at the end of the supplementary Code 1, from the supplementary Code 1 can be found that the semaphore is created immediately after the call to the Xsemaphoregive function, so that the semaphore from "empty" to "full". V8. The Xsemaphorecreatebinary function is used in the X version to create a semaphore with an initial value of "null", and the receive operation does not return immediately.
3. The Reference Code sample code has a 128-byte serial receive buffer, in the serial interrupt to the received characters in the buffer, once the carriage return to the line (\ r \ n), the signal by XSEMAPHOREGIVEFROMISR the volume "full",     The print task uses Xsemaphoretake to implement the interrupt receive function synchronization, xsemaphoretake the task hangs, once the query to the semaphore is "full", through the serial port to print the end to the content, and empties the buffer. "Sample Code"

/* 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);

static void Printtask (void *pvparameters);
void Ledinit (void);

void Uart1init (void);
uint8_t rxbuffer[128];

__io uint8_t rxcounter = 0;

semaphorehandle_t Xsemaphore;
    
    int main (void) {/* Initialize hardware platform */Setup ();
    /* Create semaphore */Xsemaphore = Xsemaphorecreatebinary ();
    /* Create print Task */xtaskcreate (Printtask, "Print task", configminimal_stack_size, NULL, tskidle_priority+4, NULL);
    
    /* Start OS */Vtaskstartscheduler ();
return 0;
    } void Printtask (void *pvparameters) {for (;;) {if (Xsemaphoretake (Xsemaphore, portmax_delay) = = pdtrue) {printf ("receive:%s", RxbufFER);
            memset (Rxbuffer, 0x00, 128);
        Rxcounter = 0;
    }}}} 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; /* 1th step: Open Gpio and Usart clock */rcc_apb2periphclockcmd (Rcc_apb2periph_gpioa |
    
    Rcc_apb2periph_usart1, ENABLE);
    /* 2nd step: Configure USART1 tx@pa9 GPIO as push-pull multiplexing mode */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); /* 3rd Step: The UThe GPIO of the SART1 RX@PA10 is configured as a float input mode */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);
    /* 4th step: Configure the USART1 parameter baud rate = 9600 data length = 8 stop bit = 1 Check bit = no disables hardware flow control (that is, RTS and CTS are forbidden) enable receive and send */
    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);
    
    /* 5th step: Enable USART1, Configuration complete */Usart_cmd (USART1, enable);
    
    /* Clear Send Completion flag */Usart_clearflag (USART1, USART_FLAG_TC); /* Enable USART1 to send interrupts and connectReceive interrupts, and set priority */Nvic_inittypedef nvic_initstructure;
    /* Set USART1 Interrupt priority */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); 
/* Enable receive interrupt */Usart_itconfig (USART1, Usart_it_rxne, enable);
    } int FPUTC (int ch, FILE *f) {/* Write a byte to USART1 */Usart_senddata (USART1, (uint8_t) ch);
/* Wait for Send end */while (Usart_getflagstatus (USART1, usart_flag_txe) = = RESET) {} return ch;
    
    } void Usart1_irqhandler (void) {static basetype_t xhigherprioritytaskwoken;
        if (Usart_getitstatus (USART1, usart_it_rxne)! = RESET) {rxbuffer[rxcounter++] = Usart_receivedata (USART1);
            if (Rxcounter > 2 && rxbuffer[rxcounter-2] = = ' \ r ' && rxbuffer[rxcounter-1] = = ' \ n ') { Send semaphores in interrupts
            XSEMAPHOREGIVEFROMISR (Xsemaphore, &xhigherprioritytaskwoken);
}} PORTYIELD_FROM_ISR (Xhigherprioritytaskwoken);
 }

4. Brief descriptionsemaphorehandle_t Xsemaphore;     A semaphore handle, a binary semaphore, a numeric semaphore, and a mutex semaphore are declared with the semaphorehandle_t type Xsemaphore = Xsemaphorecreatebinary (); Create a semaphore, V8. The new function is added in the X version, and the initial value is "null" when creating the semaphore.     XSEMAPHOREGIVEFROMISR (Xsemaphore, &xhigherprioritytaskwoken); When sending semaphores in interrupts, the function with the end of FROMISR has the protection function, if the semaphore is sent in the task can use Xsemaphoregive.     Xsemaphoretake (Xsemaphore, Portmax_delay); Wait for the semaphore, the wait time is the maximum wait time, if the semaphore is "empty" the task will be in the suspended state.
(1) Create a new function for two-value semaphore: xsemaphorecreatebinary () The amount of RAM required for the semaphore is dynamically allocated by the FreeRTOS memory Management section, and this function creates a good two-value semaphore that is empty by default. The newly created two value semaphore using the function Xsemaogoretake () is not available
The old version of the two-value semaphore is created using xsemaphoregive () to release the two-value semaphore, the new version of the function will not be released immediately after the successful creation of the two-value semaphore, that is, the new version of the function to create a two-value semaphore default is invalid, and the old version is valid.
(2) release of the two-value semaphore xsemaphoregive () task-level semaphore release function XSEMAPHOREGIVEFROMISR () interrupt level semaphore release function
(3) Acquisition of two-value semaphore Xsemaphoretake () task-level acquisition of the semaphore function basetype_t Xsemaphoretake (semaphorehandle_t xsemaphore, ticktype_t Xblocktime); Xsemaphore the amount of signal to be acquired; Xblocktime blocking time
XSEMAPHORETAKEFROMISR () function to get the semaphore at interrupt level

5. Use the RTOs API to note points in interrupts"Fromisr" should use XSEMAPHOREGIVEFROMISR instead of xsemaphoregive. "Interrupt priority setting" the serial interrupt priority should be lower than configmax_syscall_interrupt_priority (191, from another angle can be understood as 11) set the highest priority,     The response priority of the UART in this article is configlibrary_kernel_interrupt_priority (the macro has a value of 15, the higher the value, the lower the priority). "MAIN.C"/* Enable USART1 to send interrupts and receive interrupts, and set priority */Nvic_inittypedef nvic_initstructure; /* Set USART1 Interrupt priority */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);
"FreeRTOSConfig.h"/* This is the raw value as per the cortex-m3 NVIC. Values can 255 (lowest) to 0 (1?) (highest). */#define CONFIGKERNEL_INTERRUPT_PRIORITY 255 #define CONFIGMAX_SYSCALL_INTERRUPT_PRIORITY 191/* equivalent to 0xb0 , or Priority 11.  */* This is the value of being used as per the ST library which permits 0 to 15.  This must correspond to the Configkernel_interrupt_priority setting. Here's corresponds to the lowest NVIC value of 255. */#define Configlibrary_kernel_interrupt_priority 15
In view of the characteristics of the cortex M3 Nvic, please refer to "Running M3 on Cortex freertos platform" for details.
5. Summary"1" V8.     The initial value of the semaphore created with Xsemaphorecreatebinary () in X is "empty".     The "2" interrupt sends the semaphore as far as possible using XXXXFROMISR. "3" The priority value of an interrupt should be greater than configmax_syscall_interrupt_priority.
"Supplemental Code 1"--vsemaphorecreatebinary function implementation code
#define Vsemaphorecreatebinary (Xsemaphore) \
    {\
        (xsemaphore) = Xqueuegenericcreate ((unsigned portbase_type ) 1, Semsemaphore_queue_item_length, Queuequeue_type_binary_semaphore); \
        if ((xsemaphore) = NULL) \
        {\
            (void) xsemaphoregive ((xsemaphore)); \
        } \
    }



Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.