]> begriffs open source - cmsis-freertos/blob - Demo/NEC_78K0R_IAR/main.c
Update cmsis_os2.c
[cmsis-freertos] / Demo / NEC_78K0R_IAR / main.c
1 /*
2     FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
3     All rights reserved
4
5     VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
6
7     This file is part of the FreeRTOS distribution.
8
9     FreeRTOS is free software; you can redistribute it and/or modify it under
10     the terms of the GNU General Public License (version 2) as published by the
11     Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
12
13     ***************************************************************************
14     >>!   NOTE: The modification to the GPL is included to allow you to     !<<
15     >>!   distribute a combined work that includes FreeRTOS without being   !<<
16     >>!   obliged to provide the source code for proprietary components     !<<
17     >>!   outside of the FreeRTOS kernel.                                   !<<
18     ***************************************************************************
19
20     FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
21     WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
22     FOR A PARTICULAR PURPOSE.  Full license text is available on the following
23     link: http://www.freertos.org/a00114.html
24
25     ***************************************************************************
26      *                                                                       *
27      *    FreeRTOS provides completely free yet professionally developed,    *
28      *    robust, strictly quality controlled, supported, and cross          *
29      *    platform software that is more than just the market leader, it     *
30      *    is the industry's de facto standard.                               *
31      *                                                                       *
32      *    Help yourself get started quickly while simultaneously helping     *
33      *    to support the FreeRTOS project by purchasing a FreeRTOS           *
34      *    tutorial book, reference manual, or both:                          *
35      *    http://www.FreeRTOS.org/Documentation                              *
36      *                                                                       *
37     ***************************************************************************
38
39     http://www.FreeRTOS.org/FAQHelp.html - Having a problem?  Start by reading
40     the FAQ page "My application does not run, what could be wrong?".  Have you
41     defined configASSERT()?
42
43     http://www.FreeRTOS.org/support - In return for receiving this top quality
44     embedded software for free we request you assist our global community by
45     participating in the support forum.
46
47     http://www.FreeRTOS.org/training - Investing in training allows your team to
48     be as productive as possible as early as possible.  Now you can receive
49     FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
50     Ltd, and the world's leading authority on the world's leading RTOS.
51
52     http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
53     including FreeRTOS+Trace - an indispensable productivity tool, a DOS
54     compatible FAT file system, and our tiny thread aware UDP/IP stack.
55
56     http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
57     Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
58
59     http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
60     Integrity Systems ltd. to sell under the OpenRTOS brand.  Low cost OpenRTOS
61     licenses offer ticketed support, indemnification and commercial middleware.
62
63     http://www.SafeRTOS.com - High Integrity Systems also provide a safety
64     engineered and independently SIL3 certified version for use in safety and
65     mission critical applications that require provable dependability.
66
67     1 tab == 4 spaces!
68 */
69
70 /*
71  * Creates all the demo application tasks, then starts the scheduler.  The WEB
72  * documentation provides more details of the standard demo application tasks.
73  * In addition to the standard demo tasks, the following tasks and tests are
74  * defined and/or created within this file:
75  *
76  * "Check" task -  This only executes every three seconds but has a high priority
77  * to ensure it gets processor time.  Its main function is to check that all the
78  * standard demo tasks are still operational.  If everything is running as
79  * expected then the check task will toggle an LED every 3 seconds.  An error
80  * being discovered in any task will cause the toggle rate to increase to 500ms.
81  *
82  * "Reg test" tasks - These fill the registers with known values, then check
83  * that each register still contains its expected value.  Each task uses
84  * different values.  The tasks run with very low priority so get preempted very
85  * frequently.  A register containing an unexpected value is indicative of an
86  * error in the context switching mechanism.
87  *
88  *
89  * Also in addition to the standard demo tasks is a button push task.  This is
90  * a very basic task that is included as an example of how to write an interrupt
91  * service routine that interacts with a task.  The button on the target board
92  * is used to generate an interrupt that 'gives' a semaphore in order to unblock
93  * a task.  In doing so the task is synchronised with the interrupt.  Each time
94  * the task unblocks it simply toggles an LED before entering the Blocked state
95  * again to wait for the next button push.
96  */
97
98 /* Standard includes. */
99 #include <stdlib.h>
100 #include <string.h>
101
102 /* Scheduler include files. */
103 #include "FreeRTOS.h"
104 #include "task.h"
105
106 /* Standard demo file headers. */
107 #include "PollQ.h"
108 #include "semtest.h"
109 #include "GenQTest.h"
110 #include "dynamic.h"
111 #include "blocktim.h"
112
113 /*
114  * Priority definitions for most of the tasks in the demo application.  Some
115  * tasks just use the idle priority.
116  */
117 #define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
118 #define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 1 )
119 #define mainSEMTEST_PRIORITY    ( tskIDLE_PRIORITY + 1 )
120 #define mainBUTTON_PRIORITY             ( configMAX_PRIORITIES - 1 )
121 #define mainGEN_QUEUE_PRIORITY  ( tskIDLE_PRIORITY )
122
123 /* The period between executions of the check task. */
124 #define mainNO_ERROR_TOGGLE_PERIOD      ( ( TickType_t ) 3000 / portTICK_PERIOD_MS  )
125 #define mainERROR_TOGGLE_PERIOD         ( ( TickType_t ) 500 / portTICK_PERIOD_MS  )
126
127 /* The LED toggled by the check task. */
128 #define mainLED_0   P7_bit.no6
129
130 /* A value that is passed in as the parameter to the 'check' task.  This is done
131 purely to check that the parameter passing mechanism is functioning correctly. */
132 #define mainCHECK_PARAMETER_VALUE       ( 0x5678 )
133
134 /*-----------------------------------------------------------*/
135
136 /*
137  * The function that defines the 'check' task as described at the top of this
138  * file.
139  */
140 static void vErrorChecks( void *pvParameters );
141
142
143 /*
144  * This function is called from the C startup routine to setup the processor -
145  * in particular the clock source.
146  */
147 int __low_level_init(void);
148
149 /*
150  * Functions that define the RegTest tasks as described at the top of this file.
151  */
152 extern void vRegTest1( void *pvParameters );
153 extern void vRegTest2( void *pvParameters );
154
155 /*
156  * Function that defines the button push task as described at the top of this
157  * file.
158  */
159 extern void vButtonTask( void *pvParameters );
160
161 /*-----------------------------------------------------------*/
162
163 /* If an error is discovered by one of the RegTest tasks then this flag is set
164 to pdFAIL.  The 'check' task then inspects this flag to detect errors within
165 the RegTest tasks. */
166 static short sRegTestStatus = pdPASS;
167
168 /* 78K0R Option Byte Definition. Watchdog disabled, LVI enabled, OCD interface
169 enabled. */
170 __root __far const unsigned char OptionByte[] @ 0x00C0 =
171 {
172         WATCHDOG_DISABLED, LVI_ENABLED, RESERVED_FF, OCD_ENABLED
173 };
174
175 /* Security byte definition */
176 __root __far const unsigned char SecuIDCode[]  @ 0x00C4 =
177 {
178         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
179 };
180
181
182 /*-----------------------------------------------------------*/
183
184 short main( void )
185 {
186         /* Creates all the tasks, then starts the scheduler. */
187
188         /* First create the 'standard demo' tasks.  These are used to demonstrate
189         API functions being used and also to test the kernel port.  More information
190         is provided on the FreeRTOS.org WEB site. */
191         vStartDynamicPriorityTasks();
192
193         /* Create the RegTest tasks as described at the top of this file. */
194         xTaskCreate( vRegTest1, "Reg1", configMINIMAL_STACK_SIZE, NULL, 0, NULL );
195         xTaskCreate( vRegTest2, "Reg2", configMINIMAL_STACK_SIZE, NULL, 0, NULL );      
196         
197         /* Create the button push task as described at the top of this file. */
198         xTaskCreate( vButtonTask, "Button", configMINIMAL_STACK_SIZE, NULL, mainBUTTON_PRIORITY, NULL );                
199         
200         /* Create the 'check' task as described at the top of this file. */
201         xTaskCreate( vErrorChecks, "Check", configMINIMAL_STACK_SIZE, ( void* )mainCHECK_PARAMETER_VALUE, mainCHECK_TASK_PRIORITY, NULL );
202
203         #ifdef __IAR_78K0R_Kx3__
204         {
205                 /* The Kx3 has enough RAM to create more of the standard demo tasks. */
206                 vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
207                 vStartSemaphoreTasks(mainSEMTEST_PRIORITY);
208                 vStartGenericQueueTasks( mainGEN_QUEUE_PRIORITY );
209                 vCreateBlockTimeTasks();
210         }
211         #endif
212         
213         /* Finally start the scheduler running. */
214         vTaskStartScheduler();
215
216         /* If this line is reached then vTaskStartScheduler() returned because there
217         was insufficient heap memory remaining for the idle task to be created. */
218         for( ;; );
219 }
220 /*-----------------------------------------------------------*/
221
222 static void vErrorChecks( void *pvParameters )
223 {
224 TickType_t xToggleRate = mainNO_ERROR_TOGGLE_PERIOD, xLastWakeTime;
225
226         /* Ensure the parameter was passed in as expected.  This is just a test of
227         the kernel port, the parameter is not actually used for anything.  The
228         pointer will only actually be either 3 or 2 bytes, depending on the memory
229         model. */
230         if( pvParameters != ( void * ) mainCHECK_PARAMETER_VALUE )
231         {
232                 xToggleRate = mainERROR_TOGGLE_PERIOD;
233         }
234
235         /* Initialise xLastWakeTime before it is used.  After this point it is not
236         written to directly. */
237         xLastWakeTime = xTaskGetTickCount();
238
239         /* Cycle for ever, delaying then checking all the other tasks are still
240         operating without error. */
241         for( ;; )
242         {
243                 /* Wait until it is time to check all the other tasks again. */
244                 vTaskDelayUntil( &xLastWakeTime, xToggleRate );
245
246                 if( xAreDynamicPriorityTasksStillRunning() != pdTRUE )
247                 {
248                         xToggleRate = mainERROR_TOGGLE_PERIOD;
249                 }
250
251                 if( sRegTestStatus != pdPASS )
252                 {
253                         xToggleRate = mainERROR_TOGGLE_PERIOD;
254                 }
255
256                 #ifdef __IAR_78K0R_Kx3__
257                 {
258                         /* Only the Kx3 runs all the tasks. */
259                         if( xArePollingQueuesStillRunning() != pdTRUE)
260                         {
261                                 xToggleRate = mainERROR_TOGGLE_PERIOD;
262                         }
263                 
264                         if( xAreSemaphoreTasksStillRunning() != pdTRUE)
265                         {
266                                 xToggleRate = mainERROR_TOGGLE_PERIOD;
267                         }
268                         
269                         if( xAreGenericQueueTasksStillRunning() != pdTRUE )
270                         {
271                                 xToggleRate = mainERROR_TOGGLE_PERIOD;
272                         }       
273                 
274                         if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
275                         {
276                                 xToggleRate = mainERROR_TOGGLE_PERIOD;
277                         }                       
278                 }
279                 #endif
280                 
281                 /* Toggle the LED.  The toggle rate will depend on whether or not an
282                 error has been found in any tasks. */
283                 mainLED_0 = !mainLED_0;
284         }
285 }
286 /*-----------------------------------------------------------*/
287
288 int __low_level_init(void)
289 {
290 unsigned char ucResetFlag = RESF;
291
292         portDISABLE_INTERRUPTS();
293
294         /* Clock Configuration:
295         In this port, to use the internal high speed clock source of the microcontroller
296         define the configCLOCK_SOURCE as 1 in FreeRTOSConfig.h.  To use an external
297         clock define configCLOCK_SOURCE as 0. */
298         #if configCLOCK_SOURCE == 1
299         {
300                 /* Set XT1 and XT2 in Input Port Mode
301                    Set X1  and X2  in Input Port Mode
302                    High speed oscillator frequency 2MHz <= fMX <= 10MHz */
303                 CMC = 0x00;
304
305                 /* X1 external oszillation stopped. */
306                 MSTOP = 1;
307
308                 /* Enable internal high speed oszillation. */
309                 HIOSTOP = 0;
310                 MCM0 = 0;
311
312                 /* Stop internal subsystem clock. */
313                 XTSTOP = 1;
314
315                 /* Set clock speed. */
316                 CSS = 0;
317                 CKC &= (unsigned char)~0x07;
318                 CKC |= 0x00;
319         }
320         #else
321         {
322                 /* XT1 and XT2 pin in input port mode
323                    X1  and X2  pin in crystal resonator mode
324                    High speed oszillation frequency 10MHz < fMX <= 20MHz */
325                 CMC   = 0x41;
326                 
327                 /* Set oscillation stabilization time. */
328                 OSTS  = 0x07;
329                 
330                 /* Set speed mode: fMX > 10MHz for Flash memory high speed operation. */
331                 OSMC  = 0x01;
332                 
333                 /* Start up X1 oscillator operation
334                    Internal high-speed oscillator operating. */
335                 MSTOP = 0;
336                 
337                 /* Check oscillation stabilization time status. */
338                 while(OSTC < 0x07)
339                 {
340                         /* Wait until X1 clock stabilization time. */
341                         portNOP();
342                 }
343                 
344                 /* Switch CPU clock to X1 oscillator. */
345                 MCM0 = 1;
346                 while(MCS != 1)
347                 {
348                         /* Wait until CPU and peripherals operate with fX1 clock. */
349                         portNOP();
350                 }
351
352                 /* Stop the internal high-speed oscillator operation. */
353                 HIOSTOP = 1;
354                 
355                 /* Stop the XT1 oscillator operation. */
356                 XTSTOP  = 1;
357                 
358                 /* Operating frequency f = fx
359                    Change clock generator setting, if necessary. */
360                 CKC &= 0xF8;
361
362                 /* From here onwards the X1 oscillator is supplied to the CPU. */
363         }
364         #endif
365         
366         /* LED port initialization - set port register. */
367         P7  = 0x80;
368         
369         /* Set port mode register. */
370         PM7 = 0x3F;
371         
372         /* Switch pin initialization - enable pull-up resistor. */
373         PU12_bit.no0  = 1;
374
375         /* INTP0 is used by the button on the target board. */
376         
377         /* INTP0 disable. */
378         PMK0 = 1;                       
379         
380         /* INTP0 IF clear. */
381         PIF0 = 0;                       
382         EGN0_bit.no0  = 1;
383         
384         /* INTP0 priority low. */
385         PPR10 = 0;
386         PPR00 = 1;
387         
388         /* Enable ext. INTP0 interrupt */
389         PMK0  = 0;      
390
391         return pdTRUE;
392 }
393 /*-----------------------------------------------------------*/
394
395 void vRegTestError( void )
396 {
397         /* Called by the RegTest tasks if an error is found.  lRegTestStatus is
398         inspected by the check task. */
399         sRegTestStatus = pdFAIL;
400
401         /* Do not return from here as the reg test tasks clobber all registers so
402         function calls may not function correctly. */
403         for( ;; );
404 }
405 /*-----------------------------------------------------------*/
406
407 void vApplicationStackOverflowHook( void )
408 {
409         /* This will get called if an overflow is detected in the stack of a task.
410         Inspect pxCurrentTCB to see which was the offending task. */
411         for( ;; );
412 }
413