Tidy up STM32L low power demo and add 'comprehensive demo' option.
parent
5638fe28a2
commit
751103d848
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,263 @@
|
||||
/*
|
||||
FreeRTOS V7.6.0 - Copyright (C) 2013 Real Time Engineers Ltd.
|
||||
All rights reserved
|
||||
|
||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* FreeRTOS provides completely free yet professionally developed, *
|
||||
* robust, strictly quality controlled, supported, and cross *
|
||||
* platform software that has become a de facto standard. *
|
||||
* *
|
||||
* Help yourself get started quickly and support the FreeRTOS *
|
||||
* project by purchasing a FreeRTOS tutorial book, reference *
|
||||
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
||||
* *
|
||||
* Thank you! *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
This file is part of the FreeRTOS distribution.
|
||||
|
||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License (version 2) as published by the
|
||||
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
||||
|
||||
>>! NOTE: The modification to the GPL is included to allow you to distribute
|
||||
>>! a combined work that includes FreeRTOS without being obliged to provide
|
||||
>>! the source code for proprietary components outside of the FreeRTOS
|
||||
>>! kernel.
|
||||
|
||||
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. Full license text is available from the following
|
||||
link: http://www.freertos.org/a00114.html
|
||||
|
||||
1 tab == 4 spaces!
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* Having a problem? Start by reading the FAQ "My application does *
|
||||
* not run, what could be wrong?" *
|
||||
* *
|
||||
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
http://www.FreeRTOS.org - Documentation, books, training, latest versions,
|
||||
license and Real Time Engineers Ltd. contact details.
|
||||
|
||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||
|
||||
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
||||
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||
licenses offer ticketed support, indemnification and middleware.
|
||||
|
||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||
engineered and independently SIL3 certified version for use in safety and
|
||||
mission critical applications that require provable dependability.
|
||||
|
||||
1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
* NOTE 1: This project provides two demo applications. A low power tickless
|
||||
* project, and a more comprehensive test and demo application. The
|
||||
* configCREATE_LOW_POWER_DEMO setting in FreeRTOSConfig.h is used to
|
||||
* select between the two. See the notes on using
|
||||
* configCREATE_LOW_POWER_DEMO in FreeRTOSConfig.h. This file implements
|
||||
* the comprehensive test and demo version.
|
||||
*
|
||||
* NOTE 2: This file only contains the source code that is specific to the
|
||||
* full demo. Generic functions, such FreeRTOS hook functions, and functions
|
||||
* required to configure the hardware, are defined in main.c.
|
||||
******************************************************************************
|
||||
*
|
||||
* main_full() creates all the demo application tasks and a software timer, then
|
||||
* starts the scheduler. The web documentation provides more details of the
|
||||
* standard demo application tasks, which provide no particular functionality,
|
||||
* but do provide a good example of how to use the FreeRTOS API.
|
||||
*
|
||||
* In addition to the standard demo tasks, the following tasks and tests are
|
||||
* defined and/or created within this file:
|
||||
*
|
||||
* "Check" timer - The check software timer period is initially set to three
|
||||
* seconds. The callback function associated with the check software timer
|
||||
* checks that all the standard demo tasks are not only still executing, but
|
||||
* are executing without reporting any errors. If the check software timer
|
||||
* discovers that a task has either stalled, or reported an error, then it
|
||||
* changes its own execution period from the initial three seconds, to just
|
||||
* 200ms. The check software timer callback function also toggles an LED each
|
||||
* time it is called. This provides a visual indication of the system status:
|
||||
* If the LED toggles every three seconds, then no issues have been discovered.
|
||||
* If the LED toggles every 200ms, then an issue has been discovered with at
|
||||
* least one task.
|
||||
*
|
||||
* See the documentation page for this demo on the FreeRTOS.org web site for
|
||||
* full information, including hardware setup requirements.
|
||||
*/
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdio.h>
|
||||
|
||||
/* Kernel includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "timers.h"
|
||||
#include "semphr.h"
|
||||
|
||||
/* Standard demo application includes. */
|
||||
#include "PollQ.h"
|
||||
#include "semtest.h"
|
||||
#include "dynamic.h"
|
||||
#include "BlockQ.h"
|
||||
#include "blocktim.h"
|
||||
#include "countsem.h"
|
||||
#include "GenQTest.h"
|
||||
#include "recmutex.h"
|
||||
|
||||
/* ST library functions. */
|
||||
#include "stm32l1xx.h"
|
||||
#include "discover_board.h"
|
||||
#include "discover_functions.h"
|
||||
#include "stm32l_discovery_lcd.h"
|
||||
|
||||
/* Priorities for the demo application tasks. */
|
||||
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2UL )
|
||||
#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1UL )
|
||||
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2UL )
|
||||
|
||||
/* A block time of zero simply means "don't block". */
|
||||
#define mainDONT_BLOCK ( 0UL )
|
||||
|
||||
/* The period after which the check timer will expire providing no errors
|
||||
have been reported by any of the standard demo tasks. ms are converted to the
|
||||
equivalent in ticks using the portTICK_RATE_MS constant. */
|
||||
#define mainCHECK_TIMER_PERIOD_MS ( 3000UL / portTICK_RATE_MS )
|
||||
|
||||
/* The period at which the check timer will expire, in ms, if an error has been
|
||||
reported in one of the standard demo tasks. ms are converted to the equivalent
|
||||
in ticks using the portTICK_RATE_MS constant. */
|
||||
#define mainERROR_CHECK_TIMER_PERIOD_MS ( 200UL / portTICK_RATE_MS )
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* The check timer callback function, as described at the top of this file.
|
||||
*/
|
||||
static void prvCheckTimerCallback( xTimerHandle xTimer );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void main_full( void )
|
||||
{
|
||||
xTimerHandle xCheckTimer = NULL;
|
||||
|
||||
/* Start all the other standard demo/test tasks. They have not particular
|
||||
functionality, but do demonstrate how to use the FreeRTOS API and test the
|
||||
kernel port. */
|
||||
vStartDynamicPriorityTasks();
|
||||
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
|
||||
vCreateBlockTimeTasks();
|
||||
vStartCountingSemaphoreTasks();
|
||||
vStartGenericQueueTasks( tskIDLE_PRIORITY );
|
||||
vStartRecursiveMutexTasks();
|
||||
vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
|
||||
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
|
||||
|
||||
/* Create the software timer that performs the 'check' functionality,
|
||||
as described at the top of this file. */
|
||||
xCheckTimer = xTimerCreate( ( const signed char * ) "CheckTimer",/* A text name, purely to help debugging. */
|
||||
( mainCHECK_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */
|
||||
pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */
|
||||
( void * ) 0, /* The ID is not used, so can be set to anything. */
|
||||
prvCheckTimerCallback /* The callback function that inspects the status of all the other tasks. */
|
||||
);
|
||||
|
||||
if( xCheckTimer != NULL )
|
||||
{
|
||||
xTimerStart( xCheckTimer, mainDONT_BLOCK );
|
||||
}
|
||||
|
||||
/* Start the scheduler. */
|
||||
vTaskStartScheduler();
|
||||
|
||||
/* If all is well, the scheduler will now be running, and the following line
|
||||
will never be reached. If the following line does execute, then there was
|
||||
insufficient FreeRTOS heap memory available for the idle and/or timer tasks
|
||||
to be created. See the memory management section on the FreeRTOS web site
|
||||
for more details. */
|
||||
for( ;; );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvCheckTimerCallback( xTimerHandle xTimer )
|
||||
{
|
||||
static long lChangedTimerPeriodAlready = pdFALSE;
|
||||
unsigned long ulErrorFound = pdFALSE;
|
||||
|
||||
/* Check all the demo tasks to ensure they are all still running, and that
|
||||
none have detected an error. */
|
||||
|
||||
if( xAreDynamicPriorityTasksStillRunning() != pdTRUE )
|
||||
{
|
||||
ulErrorFound = pdTRUE;
|
||||
}
|
||||
|
||||
if( xAreBlockingQueuesStillRunning() != pdTRUE )
|
||||
{
|
||||
ulErrorFound = pdTRUE;
|
||||
}
|
||||
|
||||
if ( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
|
||||
{
|
||||
ulErrorFound = pdTRUE;
|
||||
}
|
||||
|
||||
if ( xAreGenericQueueTasksStillRunning() != pdTRUE )
|
||||
{
|
||||
ulErrorFound = pdTRUE;
|
||||
}
|
||||
|
||||
if ( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
|
||||
{
|
||||
ulErrorFound = pdTRUE;
|
||||
}
|
||||
|
||||
if( xArePollingQueuesStillRunning() != pdTRUE )
|
||||
{
|
||||
ulErrorFound = pdTRUE;
|
||||
}
|
||||
|
||||
if( xAreSemaphoreTasksStillRunning() != pdTRUE )
|
||||
{
|
||||
ulErrorFound = pdTRUE;
|
||||
}
|
||||
|
||||
/* Toggle the check LED to give an indication of the system status. If
|
||||
the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then
|
||||
everything is ok. A faster toggle indicates an error. */
|
||||
GPIO_TOGGLE( LD_GPIO_PORT, LD_GREEN_GPIO_PIN );
|
||||
|
||||
/* Have any errors been latch in ulErrorFound? If so, shorten the
|
||||
period of the check timer to mainERROR_CHECK_TIMER_PERIOD_MS milliseconds.
|
||||
This will result in an increase in the rate at which mainCHECK_LED
|
||||
toggles. */
|
||||
if( ulErrorFound != pdFALSE )
|
||||
{
|
||||
if( lChangedTimerPeriodAlready == pdFALSE )
|
||||
{
|
||||
lChangedTimerPeriodAlready = pdTRUE;
|
||||
|
||||
/* This call to xTimerChangePeriod() uses a zero block time.
|
||||
Functions called from inside of a timer callback function must
|
||||
*never* attempt to block. */
|
||||
xTimerChangePeriod( xTimer, ( mainERROR_CHECK_TIMER_PERIOD_MS ), mainDONT_BLOCK );
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
@ -0,0 +1,337 @@
|
||||
/*
|
||||
FreeRTOS V7.6.0 - Copyright (C) 2013 Real Time Engineers Ltd.
|
||||
All rights reserved
|
||||
|
||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* FreeRTOS provides completely free yet professionally developed, *
|
||||
* robust, strictly quality controlled, supported, and cross *
|
||||
* platform software that has become a de facto standard. *
|
||||
* *
|
||||
* Help yourself get started quickly and support the FreeRTOS *
|
||||
* project by purchasing a FreeRTOS tutorial book, reference *
|
||||
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
||||
* *
|
||||
* Thank you! *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
This file is part of the FreeRTOS distribution.
|
||||
|
||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License (version 2) as published by the
|
||||
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
||||
|
||||
>>! NOTE: The modification to the GPL is included to allow you to distribute
|
||||
>>! a combined work that includes FreeRTOS without being obliged to provide
|
||||
>>! the source code for proprietary components outside of the FreeRTOS
|
||||
>>! kernel.
|
||||
|
||||
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. Full license text is available from the following
|
||||
link: http://www.freertos.org/a00114.html
|
||||
|
||||
1 tab == 4 spaces!
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* Having a problem? Start by reading the FAQ "My application does *
|
||||
* not run, what could be wrong?" *
|
||||
* *
|
||||
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
http://www.FreeRTOS.org - Documentation, books, training, latest versions,
|
||||
license and Real Time Engineers Ltd. contact details.
|
||||
|
||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||
|
||||
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
||||
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||
licenses offer ticketed support, indemnification and middleware.
|
||||
|
||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||
engineered and independently SIL3 certified version for use in safety and
|
||||
mission critical applications that require provable dependability.
|
||||
|
||||
1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
/* ****************************************************************************
|
||||
* When configCREATE_LOW_POWER_DEMO is set to 1 in FreeRTOSConfig.h main() will
|
||||
* call main_low_power(), which is defined in this file. main_low_power()
|
||||
* demonstrates FreeRTOS tick suppression being used to allow the MCU to be
|
||||
* placed into the Sleep, Low Power Sleep and Stop low power modes. When
|
||||
* configCREATE_LOW_POWER_DEMO is set to 0 main will instead call main_full(),
|
||||
* which is a more comprehensive RTOS demonstration.
|
||||
* ****************************************************************************
|
||||
*
|
||||
* This application demonstrates the FreeRTOS tickless idle mode (tick
|
||||
* suppression) being used to allow the STM32L to enter various low power modes
|
||||
* during extended idle periods. See
|
||||
* http://www.freertos.org/low-power-tickless-rtos.html for information on
|
||||
* tickless operation.
|
||||
*
|
||||
* Deeper low power modes have longer wake up periods that lighter low power
|
||||
* modes, and power is also used simply entering and especially exiting the low
|
||||
* power modes. How the low power modes are used therefore requires careful
|
||||
* consideration to ensure power consumption is truly minimised and that the
|
||||
* embedded device meets its real time requirements. This demo is configured to
|
||||
* select between four different modes depending on the anticipated idle period.
|
||||
* Note the time thresholds used to decide which low power mode to enter are
|
||||
* purely for convenience of demonstration and are not intended to represent
|
||||
* optimal values for any particular application.
|
||||
*
|
||||
* The STM32L specific part of the tickless operation is implemented in
|
||||
* STM32L_low_power_tick_management.c.
|
||||
*
|
||||
* The demo is configured to execute on the STM32L Discovery board.
|
||||
*
|
||||
* Functionality:
|
||||
*
|
||||
* + Two tasks are created, an Rx task and a Tx task. A queue is created to
|
||||
* pass a message from the Tx task to the Rx task.
|
||||
*
|
||||
* + The Rx task blocks on a queue to wait for data, blipping an LED each time
|
||||
* data is received (turning it on and then off again) before returning to
|
||||
* block on the queue once more.
|
||||
*
|
||||
* + The Tx task repeatedly blocks on an attempt to obtain a semaphore, and
|
||||
* unblocks if either the semaphore is received or its block time expires.
|
||||
* After leaving the blocked state the Tx task uses the queue to send a
|
||||
* value to the Rx task, which in turn causes the Rx task to exit the
|
||||
* Blocked state and blip the LED. The rate at which the LED is seen to blip
|
||||
* is therefore dependent on the block time.
|
||||
*
|
||||
* + The Tx task's block time is changed by the interrupt service routine that
|
||||
* executes when the USER button is pressed. The low power mode entered
|
||||
* depends on the block time (as described in the Observed Behaviour section
|
||||
* below). Four block times are used: short, medium, long and infinite.
|
||||
*
|
||||
* Observed behaviour:
|
||||
*
|
||||
* 1) The block time used by the Tx task is initialised to its 'short' value,
|
||||
* so when the Tx task blocks on the semaphore it times-out quickly, resulting
|
||||
* in the LED toggling rapidly. The timeout period is less than the value of
|
||||
* configEXPECTED_IDLE_TIME_BEFORE_SLEEP (set in FreeRTOSConfig.h), so the
|
||||
* initial state does not suppress the tick interrupt or enter a low power mode.
|
||||
*
|
||||
* 2) When the button is pressed the block time used by the Tx task is increased
|
||||
* to its 'medium' value. The longer block time results in a slowing of the
|
||||
* rate at which the LED toggles. The time the Tx task spends in the blocked
|
||||
* state is now greater than configEXPECTED_IDLE_TIME_BEFORE_SLEEP, so the tick
|
||||
* is suppressed. The MCU is placed into the 'Sleep' low power state while the
|
||||
* tick is suppressed.
|
||||
*
|
||||
* 3) When the button is pressed again the block time used by the Tx task is
|
||||
* increased to its 'long' value, so the rate at which the LED is observed to
|
||||
* blip gets even slow. When the 'long' block time is used the MCU is placed
|
||||
* into its 'Low Power Sleep' low power state.
|
||||
*
|
||||
* 4) The next time the button is pressed the block time used by the Tx task is
|
||||
* set to infinite, so the Tx task does not time out when it attempts to obtain
|
||||
* the semaphore, and therefore the LED stops blipping completely. Both tasks
|
||||
* are not blocked indefinitely and the MCU is placed into its 'Stop' low power
|
||||
* state.
|
||||
*
|
||||
* 5) Pressing the button one final time results in the semaphore being 'given'
|
||||
* to unblock the Tx task, the CPU clocks being returned to their pre-stop
|
||||
* state, and the block time being reset to its 'short' time. The system is
|
||||
* then back to its initial condition with the LED blipping rapidly.
|
||||
*
|
||||
*/
|
||||
|
||||
/* Kernel includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "queue.h"
|
||||
#include "semphr.h"
|
||||
|
||||
/* ST library functions. */
|
||||
#include "stm32l1xx.h"
|
||||
#include "discover_board.h"
|
||||
#include "discover_functions.h"
|
||||
#include "stm32l_discovery_lcd.h"
|
||||
|
||||
/* Priorities at which the Rx and Tx tasks are created. */
|
||||
#define configQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
|
||||
#define configQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
|
||||
|
||||
/* The number of items the queue can hold. This is 1 as the Rx task will
|
||||
remove items as they are added so the Tx task should always find the queue
|
||||
empty. */
|
||||
#define mainQUEUE_LENGTH ( 1 )
|
||||
|
||||
/* A block time of zero simply means "don't block". */
|
||||
#define mainDONT_BLOCK ( 0 )
|
||||
|
||||
/* The value that is sent from the Tx task to the Rx task on the queue. */
|
||||
#define mainQUEUED_VALUE ( 100UL )
|
||||
|
||||
/* The length of time the LED will remain on for. */
|
||||
#define mainLED_TOGGLE_DELAY ( 10 / portTICK_RATE_MS )
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* The Rx and Tx tasks as described at the top of this file.
|
||||
*/
|
||||
static void prvQueueReceiveTask( void *pvParameters );
|
||||
static void prvQueueSendTask( void *pvParameters );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* The queue used to pass data from the Tx task to the Rx task. */
|
||||
static xQueueHandle xQueue = NULL;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Holds the block time used by the Tx task. */
|
||||
portTickType xSendBlockTime = ( 100UL / portTICK_RATE_MS );
|
||||
|
||||
/* The lower an upper limits of the block time. An infinite block time is used
|
||||
if xSendBlockTime is incremented past xMaxBlockTime. */
|
||||
static const portTickType xMaxBlockTime = ( 500L / portTICK_RATE_MS ), xMinBlockTime = ( 100L / portTICK_RATE_MS );
|
||||
|
||||
/* The semaphore on which the Tx task blocks. */
|
||||
static xSemaphoreHandle xTxSemaphore = NULL;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* See the comments at the top of the file. */
|
||||
void main_low_power( void )
|
||||
{
|
||||
/* Create the semaphore as described at the top of this file. */
|
||||
xTxSemaphore = xSemaphoreCreateBinary();
|
||||
configASSERT( xTxSemaphore );
|
||||
|
||||
/* Create the queue as described at the top of this file. */
|
||||
xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( unsigned long ) );
|
||||
configASSERT( xQueue );
|
||||
|
||||
/* Start the two tasks as described at the top of this file. */
|
||||
xTaskCreate( prvQueueReceiveTask, ( const signed char * const ) "Rx", configMINIMAL_STACK_SIZE, NULL, configQUEUE_RECEIVE_TASK_PRIORITY, NULL );
|
||||
xTaskCreate( prvQueueSendTask, ( const signed char * const ) "TX", configMINIMAL_STACK_SIZE, NULL, configQUEUE_SEND_TASK_PRIORITY, NULL );
|
||||
|
||||
/* Start the scheduler running running. */
|
||||
vTaskStartScheduler();
|
||||
|
||||
/* If all is well the next line of code will not be reached as the
|
||||
scheduler will be running. If the next line is reached then it is likely
|
||||
there was insufficient FreeRTOS heap available for the idle task and/or
|
||||
timer task to be created. See http://www.freertos.org/a00111.html. */
|
||||
for( ;; );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvQueueSendTask( void *pvParameters )
|
||||
{
|
||||
const unsigned long ulValueToSend = mainQUEUED_VALUE;
|
||||
|
||||
/* Remove compiler warning about unused parameter. */
|
||||
( void ) pvParameters;
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
/* Enter the Blocked state to wait for the semaphore. The task will
|
||||
leave the Blocked state if either the semaphore is received or
|
||||
xSendBlockTime ticks pass without the semaphore being received. */
|
||||
xSemaphoreTake( xTxSemaphore, xSendBlockTime );
|
||||
|
||||
/* Send to the queue - causing the Tx task to flash its LED. */
|
||||
xQueueSend( xQueue, &ulValueToSend, mainDONT_BLOCK );
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvQueueReceiveTask( void *pvParameters )
|
||||
{
|
||||
unsigned long ulReceivedValue;
|
||||
|
||||
/* Remove compiler warning about unused parameter. */
|
||||
( void ) pvParameters;
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
/* Wait until something arrives in the queue. */
|
||||
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
|
||||
|
||||
/* To get here something must have arrived, but is it the expected
|
||||
value? If it is, turn the LED on for a short while. */
|
||||
if( ulReceivedValue == mainQUEUED_VALUE )
|
||||
{
|
||||
/* LED on... */
|
||||
GPIO_HIGH( LD_GPIO_PORT, LD_GREEN_GPIO_PIN );
|
||||
|
||||
/* ... short delay ... */
|
||||
vTaskDelay( mainLED_TOGGLE_DELAY );
|
||||
|
||||
/* ... LED off again. */
|
||||
GPIO_LOW( LD_GPIO_PORT, LD_GREEN_GPIO_PIN );
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Handles interrupts generated by pressing the USER button. */
|
||||
void EXTI0_IRQHandler(void)
|
||||
{
|
||||
static const portTickType xIncrement = 200UL / portTICK_RATE_MS;
|
||||
|
||||
/* If xSendBlockTime is already portMAX_DELAY then the Tx task was blocked
|
||||
indefinitely, and this interrupt is bringing the MCU out of STOP low power
|
||||
mode. */
|
||||
if( xSendBlockTime == portMAX_DELAY )
|
||||
{
|
||||
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
|
||||
|
||||
/* Unblock the Tx task. */
|
||||
xSemaphoreGiveFromISR( xTxSemaphore, &xHigherPriorityTaskWoken );
|
||||
|
||||
/* Start over with the 'short' block time as described at the top of
|
||||
this file. */
|
||||
xSendBlockTime = xMinBlockTime;
|
||||
|
||||
/* Request a yield if calling xSemaphoreGiveFromISR() caused a task to
|
||||
leave the Blocked state (which it will have done) and the task that left
|
||||
the Blocked state has a priority higher than the currently running task
|
||||
(which it will have). */
|
||||
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Increase the block time used by the Tx task, as described at the top
|
||||
of this file. */
|
||||
xSendBlockTime += xIncrement;
|
||||
|
||||
/* If the block time has gone over the configured maximum then set it to
|
||||
an infinite block time to allow the MCU to go into its STOP low power
|
||||
mode. */
|
||||
if( xSendBlockTime > xMaxBlockTime )
|
||||
{
|
||||
xSendBlockTime = portMAX_DELAY;
|
||||
}
|
||||
}
|
||||
|
||||
EXTI_ClearITPendingBit( EXTI_Line0 );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* The configPOST_STOP_PROCESSING() macro is called when the MCU leaves its
|
||||
STOP low power mode. The macro is set in FreeRTOSConfig.h to call
|
||||
vMainPostStopProcessing(). */
|
||||
void vMainPostStopProcessing( void )
|
||||
{
|
||||
extern void SetSysClock( void );
|
||||
|
||||
/* The STOP low power mode has been exited. Reconfigure the system clocks
|
||||
ready for normally running again. */
|
||||
SetSysClock();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
Loading…
Reference in New Issue