]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_M4_ATSAM4L_Atmel_Studio/src/main_low_power.c
8369c1390e665e2ea5f7aae7e3df95dd9f0cee4d
[freertos] / FreeRTOS / Demo / CORTEX_M4_ATSAM4L_Atmel_Studio / src / main_low_power.c
1 /*\r
2     FreeRTOS V8.2.0rc1 - Copyright (C) 2014 Real Time Engineers Ltd.\r
3     All rights reserved\r
4 \r
5     VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
6 \r
7     This file is part of the FreeRTOS distribution.\r
8 \r
9     FreeRTOS is free software; you can redistribute it and/or modify it under\r
10     the terms of the GNU General Public License (version 2) as published by the\r
11     Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.\r
12 \r
13     >>!   NOTE: The modification to the GPL is included to allow you to     !<<\r
14     >>!   distribute a combined work that includes FreeRTOS without being   !<<\r
15     >>!   obliged to provide the source code for proprietary components     !<<\r
16     >>!   outside of the FreeRTOS kernel.                                   !<<\r
17 \r
18     FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
19     WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
20     FOR A PARTICULAR PURPOSE.  Full license text is available on the following\r
21     link: http://www.freertos.org/a00114.html\r
22 \r
23     1 tab == 4 spaces!\r
24 \r
25     ***************************************************************************\r
26      *                                                                       *\r
27      *    Having a problem?  Start by reading the FAQ "My application does   *\r
28      *    not run, what could be wrong?".  Have you defined configASSERT()?  *\r
29      *                                                                       *\r
30      *    http://www.FreeRTOS.org/FAQHelp.html                               *\r
31      *                                                                       *\r
32     ***************************************************************************\r
33 \r
34     ***************************************************************************\r
35      *                                                                       *\r
36      *    FreeRTOS provides completely free yet professionally developed,    *\r
37      *    robust, strictly quality controlled, supported, and cross          *\r
38      *    platform software that is more than just the market leader, it     *\r
39      *    is the industry's de facto standard.                               *\r
40      *                                                                       *\r
41      *    Help yourself get started quickly while simultaneously helping     *\r
42      *    to support the FreeRTOS project by purchasing a FreeRTOS           *\r
43      *    tutorial book, reference manual, or both:                          *\r
44      *    http://www.FreeRTOS.org/Documentation                              *\r
45      *                                                                       *\r
46     ***************************************************************************\r
47 \r
48     ***************************************************************************\r
49      *                                                                       *\r
50      *   Investing in training allows your team to be as productive as       *\r
51      *   possible as early as possible, lowering your overall development    *\r
52      *   cost, and enabling you to bring a more robust product to market     *\r
53      *   earlier than would otherwise be possible.  Richard Barry is both    *\r
54      *   the architect and key author of FreeRTOS, and so also the world's   *\r
55      *   leading authority on what is the world's most popular real time     *\r
56      *   kernel for deeply embedded MCU designs.  Obtaining your training    *\r
57      *   from Richard ensures your team will gain directly from his in-depth *\r
58      *   product knowledge and years of usage experience.  Contact Real Time *\r
59      *   Engineers Ltd to enquire about the FreeRTOS Masterclass, presented  *\r
60      *   by Richard Barry:  http://www.FreeRTOS.org/contact\r
61      *                                                                       *\r
62     ***************************************************************************\r
63 \r
64     ***************************************************************************\r
65      *                                                                       *\r
66      *    You are receiving this top quality software for free.  Please play *\r
67      *    fair and reciprocate by reporting any suspected issues and         *\r
68      *    participating in the community forum:                              *\r
69      *    http://www.FreeRTOS.org/support                                    *\r
70      *                                                                       *\r
71      *    Thank you!                                                         *\r
72      *                                                                       *\r
73     ***************************************************************************\r
74 \r
75     http://www.FreeRTOS.org - Documentation, books, training, latest versions,\r
76     license and Real Time Engineers Ltd. contact details.\r
77 \r
78     http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
79     including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
80     compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
81 \r
82     http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.\r
83     Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.\r
84 \r
85     http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High\r
86     Integrity Systems ltd. to sell under the OpenRTOS brand.  Low cost OpenRTOS\r
87     licenses offer ticketed support, indemnification and commercial middleware.\r
88 \r
89     http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
90     engineered and independently SIL3 certified version for use in safety and\r
91     mission critical applications that require provable dependability.\r
92 \r
93     1 tab == 4 spaces!\r
94 */\r
95 \r
96 /* ****************************************************************************\r
97  * When configCREATE_LOW_POWER_DEMO is set to 1 in FreeRTOSConfig.h main() will\r
98  * call main_low_power(), which is defined in this file.  main_low_power()\r
99  * demonstrates FreeRTOS tick suppression being used to allow the MCU to be\r
100  * placed into the Retention low power mode.  When configCREATE_LOW_POWER_DEMO\r
101  * is set to 0 main will instead call main_full(), which is a more comprehensive\r
102  * RTOS demonstration.\r
103  * ****************************************************************************\r
104  *\r
105  * This application demonstrates the FreeRTOS tickless idle mode (tick\r
106  * suppression).  See http://www.freertos.org/low-power-tickless-rtos.html\r
107  * The demo is configured to execute on the SAM4L-EK.\r
108  *\r
109  * Functionality:\r
110  *\r
111  *  + Two tasks are created, an Rx task and a Tx task.\r
112  *\r
113  *  + The Rx task blocks on a queue to wait for data, blipping an LED each time\r
114  *    data is received (turning it on and then off again) before returning to\r
115  *    block on the queue once more.\r
116  *\r
117  *  + The Tx task repeatedly enters the Blocked state for 500ms.  On exiting the\r
118  *    blocked state the Tx task sends a value through the queue to the Rx task\r
119  *    (causing the Rx task to exit the blocked state and blip the LED).\r
120  *\r
121  *    Blocking for a finite period allows the kernel to stop the tick interrupt\r
122  *    and place the SAM4L into Retention mode - the lowest power mode possible\r
123  *    that allows the CPU registers and RAM to retain their state.\r
124  *\r
125  * Observed behaviour:\r
126  *\r
127  * For correct results the SAM4L-EK must be connected (and powered) using only\r
128  * the JTAG USB connector, but the debugger must not be connected (the\r
129  * application must be executed 'stand alone').\r
130  *\r
131  * The MCU spends most of its time in the Retention low power state, during\r
132  * which times the current monitor (built onto the SAM4L-EK) will show a low\r
133  * current reading.\r
134  *\r
135  * Every 500ms the MCU will come out of the low power state to turn the LED on,\r
136  * then return to the low power state for 20ms before leaving the low power\r
137  * state again to turn the LED off.  This will be observed as a fast blipping\r
138  * on the LED, and two very brief dots appearing on the current monitor graph\r
139  * (often observed as a single dot).\r
140  *\r
141  * The RTOS tick is suppressed while the MCU is in its low power state.\r
142  *\r
143  */\r
144 \r
145 /* ASF includes. */\r
146 #include <asf.h>\r
147 \r
148 /* Kernel includes. */\r
149 #include "FreeRTOS.h"\r
150 #include "task.h"\r
151 #include "queue.h"\r
152 \r
153 /* Common demo includes. */\r
154 #include "partest.h"\r
155 \r
156 /* Priorities at which the Rx and Tx tasks are created. */\r
157 #define configQUEUE_RECEIVE_TASK_PRIORITY       ( tskIDLE_PRIORITY + 1 )\r
158 #define configQUEUE_SEND_TASK_PRIORITY          ( tskIDLE_PRIORITY + 2 )\r
159 \r
160 /* The number of items the queue can hold.  This is 1 as the Rx task will\r
161 remove items as they are added so the Tx task should always find the queue\r
162 empty. */\r
163 #define mainQUEUE_LENGTH                                        ( 1 )\r
164 \r
165 /* The LED used to indicate that a value has been received on the queue. */\r
166 #define mainQUEUE_LED                                           ( 0 )\r
167 \r
168 /* The rate at which the Tx task sends to the queue. */\r
169 #define mainTX_DELAY                                            ( 500UL / portTICK_PERIOD_MS )\r
170 \r
171 /* A block time of zero simply means "don't block". */\r
172 #define mainDONT_BLOCK                                          ( 0 )\r
173 \r
174 /* The value that is sent from the Tx task to the Rx task on the queue. */\r
175 #define mainQUEUED_VALUE                                        ( 100UL )\r
176 \r
177 /* The length of time the LED will remain on for.  It is on just long enough\r
178 to be able to see with the human eye so as not to distort the power readings too\r
179 much. */\r
180 #define mainLED_TOGGLE_DELAY                            ( 20 / portTICK_PERIOD_MS )\r
181 \r
182 /*-----------------------------------------------------------*/\r
183 \r
184 /*\r
185  * The Rx and Tx tasks as described at the top of this file.\r
186  */\r
187 static void prvQueueReceiveTask( void *pvParameters );\r
188 static void prvQueueSendTask( void *pvParameters );\r
189 \r
190 /*-----------------------------------------------------------*/\r
191 \r
192 /* The queue to pass data from the Tx task to the Rx task. */\r
193 static QueueHandle_t xQueue = NULL;\r
194 \r
195 /*-----------------------------------------------------------*/\r
196 \r
197 void main_low_power( void )\r
198 {\r
199         /* Create the queue. */\r
200         xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( unsigned long ) );\r
201         configASSERT( xQueue );\r
202 \r
203         /* Start the two tasks as described at the top of this file. */\r
204         xTaskCreate( prvQueueReceiveTask, "Rx", configMINIMAL_STACK_SIZE, NULL, configQUEUE_RECEIVE_TASK_PRIORITY, NULL );\r
205         xTaskCreate( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE, NULL, configQUEUE_SEND_TASK_PRIORITY, NULL );\r
206 \r
207         /* Start the scheduler running running. */\r
208         vTaskStartScheduler();\r
209 \r
210         /* If all is well the next line of code will not be reached as the\r
211         scheduler will be running.  If the next line is reached then it is likely\r
212         there was insufficient FreeRTOS heap available for the idle task and/or\r
213         timer task to be created.  See http://www.freertos.org/a00111.html. */\r
214         for( ;; );\r
215 }\r
216 /*-----------------------------------------------------------*/\r
217 \r
218 static void prvQueueSendTask( void *pvParameters )\r
219 {\r
220 const unsigned long ulValueToSend = mainQUEUED_VALUE;\r
221 \r
222         /* Remove compiler warning about unused parameter. */\r
223         ( void ) pvParameters;\r
224 \r
225         for( ;; )\r
226         {\r
227                 /* Place this task into the blocked state until it is time to run again.\r
228                 The kernel will place the MCU into the Retention low power sleep state\r
229                 when the idle task next runs. */\r
230                 vTaskDelay( mainTX_DELAY );\r
231 \r
232                 /* Send to the queue - causing the queue receive task to flash its LED.\r
233                 It should not be necessary to block on the queue send because the Rx\r
234                 task will already have removed the last queued item. */\r
235                 xQueueSend( xQueue, &ulValueToSend, mainDONT_BLOCK );\r
236         }\r
237 }\r
238 /*-----------------------------------------------------------*/\r
239 \r
240 static void prvQueueReceiveTask( void *pvParameters )\r
241 {\r
242 unsigned long ulReceivedValue;\r
243 \r
244         /* Remove compiler warning about unused parameter. */\r
245         ( void ) pvParameters;\r
246 \r
247         for( ;; )\r
248         {\r
249                 /* Wait until something arrives in the queue. */\r
250                 xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );\r
251 \r
252                 /*  To get here something must have arrived, but is it the expected\r
253                 value?  If it is, turn the LED on for a short while. */\r
254                 if( ulReceivedValue == mainQUEUED_VALUE )\r
255                 {\r
256                         vParTestSetLED( mainQUEUE_LED, pdTRUE );\r
257                         vTaskDelay( mainLED_TOGGLE_DELAY );\r
258                         vParTestSetLED( mainQUEUE_LED, pdFALSE );\r
259                 }\r
260         }\r
261 }\r
262 /*-----------------------------------------------------------*/\r
263 \r
264 void vPreSleepProcessing( unsigned long ulExpectedIdleTime )\r
265 {\r
266         /* Called by the kernel before it places the MCU into a sleep mode because\r
267         configPRE_SLEEP_PROCESSING() is #defined to vPreSleepProcessing().\r
268 \r
269         NOTE:  Additional actions can be taken here to get the power consumption\r
270         even lower.  For example, peripherals can be turned     off here, and then back\r
271         on again in the post sleep processing function.  For maximum power saving\r
272         ensure all unused pins are in their lowest power state. */\r
273 \r
274         /* Avoid compiler warnings about the unused parameter. */\r
275         ( void ) ulExpectedIdleTime;\r
276 }\r
277 /*-----------------------------------------------------------*/\r
278 \r
279 void vPostSleepProcessing( unsigned long ulExpectedIdleTime )\r
280 {\r
281         /* Called by the kernel when the MCU exits a sleep mode because\r
282         configPOST_SLEEP_PROCESSING is #defined to vPostSleepProcessing(). */\r
283 \r
284         /* Avoid compiler warnings about the unused parameter. */\r
285         ( void ) ulExpectedIdleTime;\r
286 }\r
287 /*-----------------------------------------------------------*/\r
288 \r