OpenCores
URL https://opencores.org/ocsvn/neorv32/neorv32/trunk

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [sw/] [example/] [demo_freeRTOS/] [full_demo/] [main_full.c] - Blame information for rev 52

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 36 zero_gravi
/*
2
 * FreeRTOS Kernel V10.3.0
3
 * Copyright (C) 2020 Amazon.com, Inc. or its affiliates.  All Rights Reserved.
4
 *
5
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
6
 * this software and associated documentation files (the "Software"), to deal in
7
 * the Software without restriction, including without limitation the rights to
8
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
 * the Software, and to permit persons to whom the Software is furnished to do so,
10
 * subject to the following conditions:
11
 *
12
 * The above copyright notice and this permission notice shall be included in all
13
 * copies or substantial portions of the Software.
14
 *
15
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
 *
22
 * http://www.FreeRTOS.org
23
 * http://aws.amazon.com/freertos
24
 *
25
 * 1 tab == 4 spaces!
26
 */
27
 
28
/******************************************************************************
29
 * NOTE 1:  This project provides two demo applications.  A simple blinky style
30
 * project, and a more comprehensive test and demo application.  The
31
 * mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting in main.c is used to select
32
 * between the two.  See the notes on using mainCREATE_SIMPLE_BLINKY_DEMO_ONLY
33
 * in main.c.  This file implements the comprehensive test and demo version.
34
 *
35
 * NOTE 2:  This file only contains the source code that is specific to the
36
 * full demo.  Generic functions, such FreeRTOS hook functions, and functions
37
 * required to configure the hardware, are defined in main.c.
38
 *
39
 ******************************************************************************
40
 *
41
 * main_full() creates all the demo application tasks and software timers, then
42
 * starts the scheduler.  The web documentation provides more details of the
43
 * standard demo application tasks, which provide no particular functionality,
44
 * but do provide a good example of how to use the FreeRTOS API.
45
 *
46
 * In addition to the standard demo tasks, the following tasks and tests are
47
 * defined and/or created within this file:
48
 *
49
 * "Reg test" tasks - These fill both the core registers with known values, then
50
 * check that each register maintains its expected value for the lifetime of the
51
 * task.  Each task uses a different set of values.  The reg test tasks execute
52
 * with a very low priority, so get preempted very frequently.  A register
53
 * containing an unexpected value is indicative of an error in the context
54
 * switching mechanism.
55
 *
56
 * "Check" task - The check executes every three seconds.  It checks that all
57
 * the standard demo tasks, and the register check tasks, are not only still
58
 * executing, but are executing without reporting any errors.  The check task
59
 * toggles the LED every three seconds if all the standard demo tasks are
60
 * executing as expected, or every 500ms if a potential error is discovered in
61
 * any task.
62
 */
63
 
64
/* Standard includes. */
65
#include <string.h>
66
#include <unistd.h>
67
 
68
/* NEORV32*/
69
#include <neorv32.h>
70
 
71
/* Kernel includes. */
72
#include <FreeRTOS.h>
73
#include <task.h>
74
#include <timers.h>
75
#include <semphr.h>
76
 
77
/* Standard demo application includes. */
78
#include <dynamic.h>
79
#include <blocktim.h>
80
#include <GenQTest.h>
81
#include <TimerDemo.h>
82
#include <TaskNotify.h>
83
 
84
/* Priorities for the demo application tasks. */
85
#define mainCHECK_TASK_PRIORITY                         ( configMAX_PRIORITIES - 1 )
86
 
87
/* The period of the check task, in ms, converted to ticks using the
88
pdMS_TO_TICKS() macro.  mainNO_ERROR_CHECK_TASK_PERIOD is used if no errors have
89
been found, mainERROR_CHECK_TASK_PERIOD is used if an error has been found. */
90
#define mainNO_ERROR_CHECK_TASK_PERIOD          pdMS_TO_TICKS( 2000UL )
91
#define mainERROR_CHECK_TASK_PERIOD                     pdMS_TO_TICKS( 100UL )
92
 
93
/* Parameters that are passed into the register check tasks solely for the
94
purpose of ensuring parameters are passed into tasks correctly. */
95
#define mainREG_TEST_TASK_1_PARAMETER           ( ( void * ) 0x12345678 )
96
#define mainREG_TEST_TASK_2_PARAMETER           ( ( void * ) 0x87654321 )
97
 
98
/* The base period used by the timer test tasks. */
99
#define mainTIMER_TEST_PERIOD                           ( 50 )
100
 
101
/* The size of the stack allocated to the check task (as described in the
102
comments at the top of this file. */
103
#define mainCHECK_TASK_STACK_SIZE_WORDS 160
104
 
105
/* Size of the stacks to allocated for the register check tasks. */
106
#define mainREG_TEST_STACK_SIZE_WORDS 90
107
 
108
/*-----------------------------------------------------------*/
109
 
110
/*
111
 * Called by main() to run the full demo (as opposed to the blinky demo) when
112
 * mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 0.
113
 */
114
void main_full( void );
115
 
116
/*
117
 * The check task, as described at the top of this file.
118
 */
119
static void prvCheckTask( void *pvParameters );
120
 
121
/*
122
 * Register check tasks as described at the top of this file.  The nature of
123
 * these files necessitates that they are written in an assembly file, but the
124
 * entry points are kept in the C file for the convenience of checking the task
125
 * parameter.
126
 */
127
static void prvRegTestTaskEntry1( void *pvParameters );
128
extern void vRegTest1Implementation( void );
129
static void prvRegTestTaskEntry2( void *pvParameters );
130
extern void vRegTest2Implementation( void );
131
 
132
/*
133
 * IO
134
 */
135
extern void vSendString( const char * pcString );
136
extern void vToggleLED( void );
137
 
138
/*
139
 * Tick hook used by the full demo, which includes code that interacts with
140
 * some of the tests.
141
 */
142
void vFullDemoTickHook( void );
143
 
144
/*-----------------------------------------------------------*/
145
 
146
/* The following two variables are used to communicate the status of the
147
register check tasks to the check task.  If the variables keep incrementing,
148
then the register check tasks have not discovered any errors.  If a variable
149
stops incrementing, then an error has been found. */
150
uint32_t ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL;
151
volatile uint32_t *pulRegTest1LoopCounter = &ulRegTest1LoopCounter;
152
volatile uint32_t *pulRegTest2LoopCounter = &ulRegTest2LoopCounter;
153
/*-----------------------------------------------------------*/
154
 
155
void main_full( void )
156
{
157
 
158
  vSendString("FreeRTOS: Creating tasks...\n");
159
 
160
        /* Start all the other standard demo/test tasks.  They have no particular
161
        functionality, but do demonstrate how to use the FreeRTOS API and test the
162
        kernel port. */
163
 
164
  vSendString("FreeRTOS: Starting <vStartDynamicPriorityTasks>...\n");
165
  vStartDynamicPriorityTasks();
166
 
167
  vSendString("FreeRTOS: Starting <vStartGenericQueueTasks>...\n");
168
        vStartGenericQueueTasks( tskIDLE_PRIORITY );
169
 
170
  vSendString("FreeRTOS: Starting <vStartTimerDemoTask>...\n");
171
  vStartTimerDemoTask( mainTIMER_TEST_PERIOD );
172
 
173
  vSendString("FreeRTOS: Starting <vStartTaskNotifyTask>...\n");
174
  vStartTaskNotifyTask();
175
 
176
 
177
  /* Create the register check tasks, as described at the top of this   file.
178
  Use xTaskCreateStatic() to create a task using only statically allocated
179
  memory. */
180
  vSendString("FreeRTOS: Creating tasks <prvRegTestTaskEntry1>...\n");
181
  xTaskCreate( prvRegTestTaskEntry1,                    /* The function that implements the task. */
182
                         "Reg1",                                                /* The name of the task. */
183
                         mainREG_TEST_STACK_SIZE_WORDS, /* Size of stack to allocate for the task - in words not bytes!. */
184
                         mainREG_TEST_TASK_1_PARAMETER, /* Parameter passed into the task. */
185
                         tskIDLE_PRIORITY,                              /* Priority of the task. */
186
                         NULL );                                                /* Can be used to pass out a handle to the created task. */
187
  vSendString("FreeRTOS: Creating tasks <prvRegTestTaskEntry2>...\n");
188
  xTaskCreate( prvRegTestTaskEntry2, "Reg2", mainREG_TEST_STACK_SIZE_WORDS, mainREG_TEST_TASK_2_PARAMETER, tskIDLE_PRIORITY, NULL );
189
 
190
        /* Create the task that performs the 'check' functionality,     as described at
191
        the top of this file. */
192
        xTaskCreate( prvCheckTask, "Check", mainCHECK_TASK_STACK_SIZE_WORDS, NULL, mainCHECK_TASK_PRIORITY, NULL );
193
 
194
 
195
        /* Start the scheduler. */
196
  vSendString("\nFreeRTOS: Starting scheduler...\n\n");
197
        vTaskStartScheduler();
198
 
199
        /* If all is well, the scheduler will now be running, and the following
200
        line will never be reached.  If the following line does execute, then
201
        there was insufficient FreeRTOS heap memory available for the Idle and/or
202
        timer tasks to be created.  See the memory management section on the
203
        FreeRTOS web site for more details on the FreeRTOS heap
204
        http://www.freertos.org/a00111.html. */
205
        for( ;; );
206
}
207
/*-----------------------------------------------------------*/
208
 
209
static void prvCheckTask( void *pvParameters )
210
{
211
TickType_t xDelayPeriod = mainNO_ERROR_CHECK_TASK_PERIOD;
212
TickType_t xLastExecutionTime;
213
uint32_t ulLastRegTest1Value = 0, ulLastRegTest2Value = 0;
214
char * const pcPassMessage = ".";
215
char * pcStatusMessage = pcPassMessage;
216
 
217
        /* Just to stop compiler warnings. */
218
        ( void ) pvParameters;
219
 
220
        /* Initialise xLastExecutionTime so the first call to vTaskDelayUntil()
221
        works correctly. */
222
        xLastExecutionTime = xTaskGetTickCount();
223
 
224
        /* Cycle for ever, delaying then checking all the other tasks are still
225
        operating without error.  The onboard LED is toggled on each iteration.
226
        If an error is detected then the delay period is decreased from
227
        mainNO_ERROR_CHECK_TASK_PERIOD to mainERROR_CHECK_TASK_PERIOD.  This has the
228
        effect of increasing the rate at which the onboard LED toggles, and in so
229
        doing gives visual feedback of the system status. */
230
        for( ;; )
231
        {
232
                /* Delay until it is time to execute again. */
233
                vTaskDelayUntil( &xLastExecutionTime, xDelayPeriod );
234
 
235
                /* Check all the demo tasks (other than the flash tasks) to ensure
236
                that they are all still running, and that none have detected an error. */
237
                if( xAreDynamicPriorityTasksStillRunning() == pdFALSE )
238
                {
239
                        pcStatusMessage = "ERROR: Dynamic priority demo/tests.\n";
240
                }
241
 
242
    if( xAreTimerDemoTasksStillRunning( ( TickType_t ) xDelayPeriod ) == pdFALSE )
243
    {
244
        pcStatusMessage = "ERROR: Timer demo/tests.\n";
245
    }
246
 
247
                if( xAreGenericQueueTasksStillRunning() == pdFALSE )
248
                {
249
                        pcStatusMessage = "ERROR: Generic queue demo/tests.\n";
250
                }
251
 
252
                if( xAreTaskNotificationTasksStillRunning() == pdFALSE )
253
                {
254
                        pcStatusMessage = "ERROR: Task notification demo/tests.\n";
255
                }
256
 
257
    if( ulLastRegTest1Value == ulRegTest1LoopCounter )
258
    {
259
        pcStatusMessage = "ERROR: Register test 1.\n";
260
    }
261
    ulLastRegTest1Value = ulRegTest1LoopCounter;
262
 
263
    if( ulLastRegTest2Value == ulRegTest2LoopCounter )
264
    {
265
        pcStatusMessage = "ERROR: Register test 2.\n";
266
    }
267
    ulLastRegTest2Value = ulRegTest2LoopCounter;
268
 
269
                /* Write the status message to the UART. */
270
                vSendString( pcStatusMessage );
271
 
272
                /* Toggle the LED to show the system status */
273
                vToggleLED();
274
 
275
                /* If an error has been found then increase the LED toggle rate by
276
                increasing the cycle frequency. */
277
                if( pcStatusMessage != pcPassMessage )
278
                {
279
                        xDelayPeriod = mainERROR_CHECK_TASK_PERIOD;
280
                }
281
        }
282
}
283
/*-----------------------------------------------------------*/
284
 
285
static void prvRegTestTaskEntry1( void *pvParameters )
286
{
287
        /* Although the regtest task is written in assembler, its entry point is
288
        written in C for convenience of checking the task parameter is being passed
289
        in correctly. */
290
        if( pvParameters == mainREG_TEST_TASK_1_PARAMETER )
291
        {
292
                /* Start the part of the test that is written in assembler. */
293
                vRegTest1Implementation();
294
        }
295
 
296
        /* The following line will only execute if the task parameter is found to
297
        be incorrect.  The check task will detect that the regtest loop counter is
298
        not being incremented and flag an error. */
299
        vTaskDelete( NULL );
300
}
301
/*-----------------------------------------------------------*/
302
 
303
static void prvRegTestTaskEntry2( void *pvParameters )
304
{
305
        /* Although the regtest task is written in assembler, its entry point is
306
        written in C for convenience of checking the task parameter is being passed
307
        in correctly. */
308
        if( pvParameters == mainREG_TEST_TASK_2_PARAMETER )
309
        {
310
                /* Start the part of the test that is written in assembler. */
311
                vRegTest2Implementation();
312
        }
313
 
314
        /* The following line will only execute if the task parameter is found to
315
        be incorrect.  The check task will detect that the regtest loop counter is
316
        not being incremented and flag an error. */
317
        vTaskDelete( NULL );
318
}
319
/*-----------------------------------------------------------*/
320
 
321
void vFullDemoTickHook( void )
322
{
323
        /* Called from vApplicationTickHook() when the project is configured to
324
        build the full test/demo applications. */
325
 
326
        /* Use task notifications from an interrupt. */
327
        xNotifyTaskFromISR();
328
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.