From 937732545797b6bce4402c0170a07df8b4c17bd9 Mon Sep 17 00:00:00 2001 From: richardbarry Date: Tue, 9 Oct 2012 13:04:17 +0000 Subject: [PATCH] RM48 simply blinky demo working. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@1788 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/.cproject | 63 +-- .../{os => }/FreeRTOSConfig.h | 0 .../{os/heap.c => ParTest.c} | 120 ++-- FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/demo/het.c | 121 ++++ FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/demo/het.h | 128 +++++ .../Demo/CORTEX_R4_RM48_CCS5/demo/partest.h | 77 +++ FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/main.c | 519 ++++++++++++------ .../Demo/CORTEX_R4_RM48_CCS5/main_blinky.c | 240 ++++++++ FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/os/heap_4.c | 357 ++++++++++++ .../CORTEX_R4_RM48_CCS5/startup/sys_system.c | 31 -- .../CORTEX_R4_RM48_CCS5/startup/sys_system.h | 2 +- 11 files changed, 1370 insertions(+), 288 deletions(-) rename FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/{os => }/FreeRTOSConfig.h (100%) rename FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/{os/heap.c => ParTest.c} (61%) create mode 100644 FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/demo/het.c create mode 100644 FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/demo/het.h create mode 100644 FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/demo/partest.h create mode 100644 FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/main_blinky.c create mode 100644 FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/os/heap_4.c diff --git a/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/.cproject b/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/.cproject index 438f5cbb0..d62cf321e 100644 --- a/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/.cproject +++ b/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/.cproject @@ -16,8 +16,8 @@ - - - - + + diff --git a/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/os/FreeRTOSConfig.h b/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/FreeRTOSConfig.h similarity index 100% rename from FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/os/FreeRTOSConfig.h rename to FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/FreeRTOSConfig.h diff --git a/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/os/heap.c b/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/ParTest.c similarity index 61% rename from FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/os/heap.c rename to FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/ParTest.c index 57ad6ebed..97c904539 100644 --- a/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/os/heap.c +++ b/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/ParTest.c @@ -64,101 +64,79 @@ the SafeRTOS brand: http://www.SafeRTOS.com. */ +/*----------------------------------------------------------- + * Simple IO routines to control the LEDs. + *-----------------------------------------------------------*/ -/* - * The simplest possible implementation of pvPortMalloc(). Note that this - * implementation does NOT allow allocated memory to be freed again. - * - * See heap_2.c and heap_3.c for alternative implementations, and the memory - * management pages of http://www.FreeRTOS.org for more information. - */ -#include - -/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining -all the API functions to use the MPU wrappers. That should only be done when -task.h is included from an application file. */ -#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE - +/* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" -#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE +/* Demo includes. */ +#include "partest.h" -#pragma DATA_SECTION(xHeap, ".heap") -#pragma DATA_ALIGN(xHeap, 8) +/* Library includes. */ +#include "het.h" -/* Allocate the memory for the heap. The struct is used to force byte -alignment without using any non-portable code. */ -static union xRTOS_HEAP -{ - unsigned char ucHeap[ configTOTAL_HEAP_SIZE ]; -} xHeap; +/* Port bits connected to LEDs. */ +const unsigned long ulLEDBits[] = { 25, 18, 29, /* Bottom row. */ + 17, 31, 0, /* Top row. */ + 2, 5, 20, /* Red1, blue1, green1 */ + 4, 27, 16 }; /* Red2, blue2, green2 */ + +/* 1 turns a white LED on, or a coloured LED off. */ +const unsigned long ulOnStates[] = { 1, 1, 1, + 1, 1, 1, + 0, 0, 0, + 0, 0, 0 }; -static size_t xNextFreeByte = ( size_t ) 0; +const unsigned long ulNumLEDs = sizeof( ulLEDBits ) / sizeof( unsigned long ); /*-----------------------------------------------------------*/ -void *pvPortMalloc( size_t xWantedSize ) +void vParTestInitialise( void ) { -void *pvReturn = NULL; +unsigned long ul; - /* Ensure that blocks are always aligned to the required number of bytes. */ - #if portBYTE_ALIGNMENT != 1 - if( xWantedSize & portBYTE_ALIGNMENT_MASK ) - { - /* Byte alignment required. */ - xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ); - } - #endif + /* Initalise the IO ports that drive the LEDs */ + gioSetDirection( hetPORT, 0xFFFFFFFF ); - vTaskSuspendAll(); + /* Turn all the LEDs off. */ + for( ul = 0; ul < ulNumLEDs; ul++ ) { - /* Check there is enough room left for the allocation. */ - if( ( ( xNextFreeByte + xWantedSize ) < configTOTAL_HEAP_SIZE ) && - ( ( xNextFreeByte + xWantedSize ) > xNextFreeByte ) )/* Check for overflow. */ - { - /* Return the next free byte then increment the index past this - block. */ - pvReturn = &( xHeap.ucHeap[ xNextFreeByte ] ); - xNextFreeByte += xWantedSize; - } + gioSetBit( hetPORT, ulLEDBits[ ul ], !ulOnStates[ ul ] ); } - xTaskResumeAll(); - - #if( configUSE_MALLOC_FAILED_HOOK == 1 ) +} +/*-----------------------------------------------------------*/ + +void vParTestSetLED( unsigned long ulLED, signed long xValue ) +{ + if( ulLED < ulNumLEDs ) { - if( pvReturn == NULL ) + if( xValue == pdFALSE ) { - extern void vApplicationMallocFailedHook( void ); - vApplicationMallocFailedHook(); + xValue = !ulOnStates[ ulLED ]; + } + else + { + xValue = ulOnStates[ ulLED ]; } - } - #endif - - return pvReturn; -} -/*-----------------------------------------------------------*/ -void vPortFree( void *pv ) -{ - /* Memory cannot be freed using this scheme. See heap_2.c and heap_3.c - for alternative implementations, and the memory management pages of - http://www.FreeRTOS.org for more information. */ - ( void ) pv; + gioSetBit( hetPORT, ulLEDBits[ ulLED ], xValue ); + } } /*-----------------------------------------------------------*/ -void vPortInitialiseBlocks( void ) +void vParTestToggleLED( unsigned long ulLED ) { - /* Only required when static memory is not cleared. */ - xNextFreeByte = ( size_t ) 0; -} -/*-----------------------------------------------------------*/ +unsigned long ulBitState; -size_t xPortGetFreeHeapSize( void ) -{ - return ( configTOTAL_HEAP_SIZE - xNextFreeByte ); + if( ulLED < ulNumLEDs ) + { + ulBitState = gioGetBit( hetPORT, ulLEDBits[ ulLED ] ); + gioSetBit( hetPORT, ulLEDBits[ ulLED ], !ulBitState ); + } } - + diff --git a/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/demo/het.c b/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/demo/het.c new file mode 100644 index 000000000..78def3344 --- /dev/null +++ b/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/demo/het.c @@ -0,0 +1,121 @@ +/* + FreeRTOS V7.0.2 - Copyright (C) 2011 Real Time Engineers Ltd. + + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and thank you for your support! * + * * + *************************************************************************** + + + 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. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#include "FreeRTOS.h" +#include "Task.h" +#include "gio.h" +#include "het.h" + +/* + * Task that flashes the LEDS on the USB stick. + * + * This task is also run in Thumb mode to test the ARM/THUMB context switch + */ + +#pragma TASK(vLedTask) +#pragma CODE_STATE(vLedTask, 16) + +void vLedTask(void *pvParameters) +{ + unsigned led = 0; + unsigned count = 0; + unsigned colour = 0; + + /* Initalise the IO ports that drive the LEDs */ + gioSetDirection(hetPORT, 0xFFFFFFFF); + /* switch all leds off */ + gioSetPort(hetPORT, 0x08110034); + + for(;;) + { + /* toggle on/off */ + led ^= 1; + /* switch TOP row */ + gioSetBit(hetPORT, 25, led); + gioSetBit(hetPORT, 18, led); + gioSetBit(hetPORT, 29, led); + /* switch BOTTOM row */ + gioSetBit(hetPORT, 17, led ^ 1); + gioSetBit(hetPORT, 31, led ^ 1); + gioSetBit(hetPORT, 0, led ^ 1); + vTaskDelay(500); + + if (++count > 5) + { + count = 0; + /* both leds to off */ + gioSetBit(hetPORT, 2, 1); gioSetBit(hetPORT, 5, 1); gioSetBit(hetPORT, 20, 1); + gioSetBit(hetPORT, 4, 1); gioSetBit(hetPORT, 27, 1); gioSetBit(hetPORT, 16, 1); + switch(colour) + { + case 0: + gioSetBit(hetPORT, 2, 0); /* red */ + gioSetBit(hetPORT, 4, 0); + colour++; + continue; + case 1: + gioSetBit(hetPORT, 5, 0); /* blue */ + gioSetBit(hetPORT, 27, 0); + colour++; + continue; + case 2: + gioSetBit(hetPORT, 20, 0); /* green */ + gioSetBit(hetPORT, 16, 0); + colour++; + continue; + } + colour = 0; + } + } +} + diff --git a/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/demo/het.h b/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/demo/het.h new file mode 100644 index 000000000..5f0c47cdd --- /dev/null +++ b/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/demo/het.h @@ -0,0 +1,128 @@ +/* + FreeRTOS V7.0.2 - Copyright (C) 2011 Real Time Engineers Ltd. + + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and thank you for your support! * + * * + *************************************************************************** + + + 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. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + + +#ifndef __HET_H__ +#define __HET_H__ + +#include "gio.h" + +/** @struct hetBase +* @brief HET Register Definition +* +* This structure is used to access the HET module egisters. +*/ +/** @typedef hetBASE_t +* @brief HET Register Frame Type Definition +* +* This type is used to access the HET Registers. +*/ +typedef volatile struct hetBase +{ + unsigned GCR; /**< 0x0000: Global control register */ + unsigned PFR; /**< 0x0004: Prescale factor register */ + unsigned ADDR; /**< 0x0008: Current address register */ + unsigned OFF1; /**< 0x000C: Interrupt offset register 1 */ + unsigned OFF2; /**< 0x0010: Interrupt offset register 2 */ + unsigned INTENAS; /**< 0x0014: Interrupt enable set register */ + unsigned INTENAC; /**< 0x0018: Interrupt enable clear register */ + unsigned EXC1; /**< 0x001C: Exeption control register 1 */ + unsigned EXC2; /**< 0x0020: Exeption control register 2 */ + unsigned PRY; /**< 0x0024: Interrupt priority register */ + unsigned FLG; /**< 0x0028: Interrupt flag register */ + unsigned : 32U; /**< 0x002C: Reserved */ + unsigned : 32U; /**< 0x0030: Reserved */ + unsigned HRSH; /**< 0x0034: High resoltion share register */ + unsigned XOR; /**< 0x0038: XOR share register */ + unsigned REQENS; /**< 0x003C: Request enable set register */ + unsigned REQENC; /**< 0x0040: Request enable clear register */ + unsigned REQDS; /**< 0x0044: Request destination select register */ + unsigned : 32U; /**< 0x0048: Reserved */ + unsigned DIR; /**< 0x004C: Direction register */ + unsigned DIN; /**< 0x0050: Data input register */ + unsigned DOUT; /**< 0x0054: Data output register */ + unsigned DSET; /**< 0x0058: Data output set register */ + unsigned DCLR; /**< 0x005C: Data output clear register */ + unsigned PDR; /**< 0x0060: Open drain register */ + unsigned PULDIS; /**< 0x0064: Pull disable register */ + unsigned PSL; /**< 0x0068: Pull select register */ + unsigned : 32U; /**< 0x006C: Reserved */ + unsigned : 32U; /**< 0x0070: Reserved */ + unsigned PCREG; /**< 0x0074: Parity control register */ + unsigned PAR; /**< 0x0078: Parity address register */ + unsigned PPR; /**< 0x007C: Parity pin select register */ + unsigned SFPRLD; /**< 0x0080: Suppression filter preload register */ + unsigned SFENA; /**< 0x0084: Suppression filter enable register */ + unsigned : 32U; /**< 0x0088: Reserved */ + unsigned LBPSEL; /**< 0x008C: Loop back pair select register */ + unsigned LBPDIR; /**< 0x0090: Loop back pair direction register */ +} hetBASE_t; + + +/** @def hetREG +* @brief HET Register Frame Pointer +* +* This pointer is used by the HET driver to access the het module registers. +*/ +#define hetREG ((hetBASE_t *)0xFFF7B800U) + + +/** @def hetPORT +* @brief HET GIO Port Register Pointer +* +* Pointer used by the GIO driver to access I/O PORT of HET +* (use the GIO drivers to access the port pins). +*/ +#define hetPORT ((gioPORT_t *)0xFFF7B84CU) + +#endif diff --git a/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/demo/partest.h b/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/demo/partest.h new file mode 100644 index 000000000..268654ee3 --- /dev/null +++ b/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/demo/partest.h @@ -0,0 +1,77 @@ +/* + FreeRTOS V7.2.0 - Copyright (C) 2012 Real Time Engineers Ltd. + + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and thank you for your support! * + * * + *************************************************************************** + + + 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. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 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, training, latest information, + license and contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool. + + Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell + the code with commercial support, indemnification, and middleware, under + the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also + provide a safety engineered and independently SIL3 certified version under + the SafeRTOS brand: http://www.SafeRTOS.com. +*/ + +#ifndef PARTEST_H +#define PARTEST_H + +#define partstDEFAULT_PORT_ADDRESS ( ( unsigned short ) 0x378 ) + +void vParTestInitialise( void ); +void vParTestSetLED( unsigned portBASE_TYPE uxLED, signed portBASE_TYPE xValue ); +void vParTestToggleLED( unsigned portBASE_TYPE uxLED ); + +#endif + diff --git a/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/main.c b/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/main.c index 11fd02d7a..a7d89977b 100644 --- a/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/main.c +++ b/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/main.c @@ -1,5 +1,295 @@ -/* main.c +#if 1 +/* + FreeRTOS V7.2.0 - Copyright (C) 2012 Real Time Engineers Ltd. + + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and thank you for your support! * + * * + *************************************************************************** + + + 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. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 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, training, latest information, + license and contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool. + + Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell + the code with commercial support, indemnification, and middleware, under + the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also + provide a safety engineered and independently SIL3 certified version under + the SafeRTOS brand: http://www.SafeRTOS.com. +*/ + +/****************************************************************************** + * This project provides two demo applications. A simple blinky style project, + * and a more comprehensive test and demo application. The + * mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting (defined in this file) is used to + * select between the two. The simply blinky demo is implemented and described + * in main_blinky.c. The more comprehensive test and demo application is + * implemented and described in main_full.c. + * + * This file implements the code that is not demo specific, including the + * hardware setup and FreeRTOS hook functions. * + */ + +/* Standard includes. */ +#include + +/* Kernel includes. */ +#include "FreeRTOS.h" +#include "task.h" + +/* Standard demo includes - just needed for the LED (ParTest) initialisation +function. */ +#include "partest.h" + +/* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo, +or 0 to run the more comprehensive test and demo application. */ +#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 1 + +/*-----------------------------------------------------------*/ + +/* + * Set up the hardware ready to run this demo. + */ +static void prvSetupHardware( void ); + +/* + * main_blinky() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 1. + * main_full() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 0. + */ +extern void main_blinky( void ); +extern void main_full( void ); + +/*-----------------------------------------------------------*/ + +/* See the documentation page for this demo on the FreeRTOS.org web site for +full information - including hardware setup requirements. */ + +int main( void ) +{ + /* Prepare the hardware to run this demo. */ + prvSetupHardware(); + + /* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top + of this file. */ + #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 + { + main_blinky(); + } + #else + { + main_full(); + } + #endif + + return 0; +} +/*-----------------------------------------------------------*/ + +static void prvSetupHardware( void ) +{ + /* Perform any configuration necessary to use the ParTest LED output + functions. */ + gioInit(); + vParTestInitialise(); +} +/*-----------------------------------------------------------*/ + +void vApplicationMallocFailedHook( void ) +{ + /* vApplicationMallocFailedHook() will only be called if + configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook + function that will get called if a call to pvPortMalloc() fails. + pvPortMalloc() is called internally by the kernel whenever a task, queue, + timer or semaphore is created. It is also called by various parts of the + demo application. If heap_1.c or heap_2.c are used, then the size of the + heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in + FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used + to query the size of free heap space that remains (although it does not + provide information on how the remaining heap might be fragmented). */ + taskDISABLE_INTERRUPTS(); + for( ;; ); +} +/*-----------------------------------------------------------*/ + +void vApplicationIdleHook( void ) +{ + /* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set + to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle + task. It is essential that code added to this hook function never attempts + to block in any way (for example, call xQueueReceive() with a block time + specified, or call vTaskDelay()). If the application makes use of the + vTaskDelete() API function (as this demo application does) then it is also + important that vApplicationIdleHook() is permitted to return to its calling + function, because it is the responsibility of the idle task to clean up + memory allocated by the kernel to any task that has since been deleted. */ +} +/*-----------------------------------------------------------*/ + +void vApplicationStackOverflowHook( xTaskHandle pxTask, signed char *pcTaskName ) +{ + ( void ) pcTaskName; + ( void ) pxTask; + + /* Run time stack overflow checking is performed if + configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook + function is called if a stack overflow is detected. */ + taskDISABLE_INTERRUPTS(); + for( ;; ); +} +/*-----------------------------------------------------------*/ + +void vApplicationTickHook( void ) +{ + /* This function will be called by each tick interrupt if + configUSE_TICK_HOOK is set to 1 in FreeRTOSConfig.h. User code can be + added here, but the tick hook is called from an interrupt context, so + code must not attempt to block, and only the interrupt safe FreeRTOS API + functions can be used (those that end in FromISR()). */ +} +/*-----------------------------------------------------------*/ + + + + + + + +#else + +/* + FreeRTOS V7.2.0 - Copyright (C) 2012 Real Time Engineers Ltd. + + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and thank you for your support! * + * * + *************************************************************************** + + + 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. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 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, training, latest information, + license and contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool. + + Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell + the code with commercial support, indemnification, and middleware, under + the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also + provide a safety engineered and independently SIL3 certified version under + the SafeRTOS brand: http://www.SafeRTOS.com. +*/ + +/* Standard includes. */ +#include + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "timers.h" +#include "queue.h" + +/* Library includes. */ +#include "gio.h" + +/* Demo application includes. */ +#include "TimerDemo.h" +#include "countsem.h" +#include "GenQTest.h" +#include "dynamic.h" + + +/* * "Check" callback function - Called each time the 'check' timer expires. The * check timer executes every five seconds. Its main function is to check that * all the standard demo tasks are still operational. Each time it executes it @@ -23,101 +313,61 @@ * */ -#include -#include "FreeRTOS.h" -#include "task.h" -#include "timers.h" -#include "queue.h" -#include "gio.h" -#include "TimerDemo.h" -#include "countsem.h" -#include "GenQTest.h" -#include "dynamic.h" - - -/* ----------------------------------------------------------------------------------------------------------- */ - /* Codes sent within messages to the LCD task so the LCD task can interpret exactly what the message it just received was. These are sent in the cMessageID member of the message structure (defined below). */ -//#define mainMESSAGE_BUTTON_UP ( 1 ) -//#define mainMESSAGE_BUTTON_SEL ( 2 ) -#define mainMESSAGE_STATUS ( 3 ) - -/* When the cMessageID member of the message sent to the MSG task is -mainMESSAGE_STATUS then these definitions are sent in the ulMessageValue member -of the same message and indicate what the status actually is. */ #define mainERROR_DYNAMIC_TASKS ( pdPASS + 1 ) -#define mainERROR_COM_TEST ( pdPASS + 2 ) #define mainERROR_GEN_QUEUE_TEST ( pdPASS + 3 ) #define mainERROR_REG_TEST ( pdPASS + 4 ) #define mainERROR_TIMER_TEST ( pdPASS + 5 ) #define mainERROR_COUNT_SEM_TEST ( pdPASS + 6 ) /* Priorities used by the test and demo tasks. */ -#define mainMSG_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) -#define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 ) +#define mainPRINT_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) #define mainGENERIC_QUEUE_TEST_PRIORITY ( tskIDLE_PRIORITY ) +#define mainLED_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 ) +#define mainSTAT_TASK_PRIORITY ( tskIDLE_PRIORITY ) /* Just used to ensure parameters are passed into tasks correctly. */ -#define mainTASK_PARAMETER_CHECK_VALUE ((void *)0xDEAD) +#define mainTASK_PARAMETER_CHECK_VALUE ( ( void * ) 0xDEADBEEF ) /* The length of the queue (the number of items the queue can hold) that is used -to send messages from tasks and interrupts the the MSG task. */ +to send messages from tasks and interrupts the the Print task. */ #define mainQUEUE_LENGTH ( 5 ) /* The base period used by the timer test tasks. */ -#define mainTIMER_TEST_PERIOD ( 50 ) +#define mainTIMER_TEST_PERIOD ( 50 / portTICK_RATE_MS ) /* The frequency at which the check timer (described in the comments at the top of this file) will call its callback function. */ #define mainCHECK_TIMER_PERIOD ( 5000UL / ( unsigned long ) portTICK_RATE_MS ) -/* Misc. */ +/* A block time of 0 simply means "don't block". */ #define mainDONT_BLOCK ( 0 ) - -/* ----------------------------------------------------------------------------------------------------------- */ -/* external regsiter check tasks, this checks that the context store/restore works */ - +/* + * The register check tasks, as decribed in the comments at the top of this + * file. The nature of the tasks necessitates that they are written in + * assembler. + */ extern void vRegTestTask1(void *pvParameters); extern void vRegTestTask2(void *pvParameters); /* - * Definition of the MSG/controller task described in the comments at the top - * of this file. + * Definition of the Print task described in the comments at the top of this + * file. */ -static void prvMsgTask( void *pvParameters ); - -/* - * Converts a status message value into an appropriate string for display on - * the LCD. The string is written to pcBuffer. - */ -static void prvGenerateStatusMessage( char *pcBuffer, unsigned long ulStatusValue ); +static void prvPrintTask( void *pvParameters ); /* * Defines the 'check' functionality as described at the top of this file. This * function is the callback function for the 'check' timer. */ static void vCheckTimerCallback( xTimerHandle xTimer ); +extern void vLedTask( void * pvParameters ); +void vStatsTask(void *pvParameters); -/* ----------------------------------------------------------------------------------------------------------- */ - -static signed char buffer[1024]; - -void vStatsTask(void *pvParameters) -{ - printf("**** Task Statistics Started\n"); - for (;;) - { - vTaskDelay(15000); - vTaskGetRunTimeStats(buffer); - printf("%s\n", buffer); - } -} - - -/* ----------------------------------------------------------------------------------------------------------- */ +/*-----------------------------------------------------------*/ /* variable incremente in the IDLE hook */ volatile unsigned usIdleCounter = 0; @@ -129,41 +379,33 @@ stops incrementing then it is likely that its associate task has stalled. */ volatile unsigned usRegTest1Counter = 0, usRegTest2Counter = 0; /* The handle of the queue used to send messages from tasks and interrupts to - the MSG task. */ -static xQueueHandle xMsgQueue = NULL; + the Print task. */ +static xQueueHandle xPrintQueue = NULL; /* The 'check' timer, as described at the top of this file. */ static xTimerHandle xCheckTimer = NULL; -/* The definition of each message sent from tasks and interrupts to the MSG -task. */ -typedef struct -{ - char cMessageID; /* << States what the message is. */ - unsigned ulMessageValue; /* << States the message value (can be an integer, string pointer, etc. depending on the value of cMessageID). */ -} xQueueMessage; - -/* ----------------------------------------------------------------------------------------------------------- */ +/*-----------------------------------------------------------*/ void main() { /* initalise DIO ports */ gioInit(); - - gioSetBit(gioPORTA, 0, 1); - gioSetBit(gioPORTA, 0, 0); - - /* Create the queue used by tasks and interrupts to send strings to the MSG task. */ - xMsgQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( xQueueMessage ) ); + /* Create the queue used by tasks and interrupts to send strings to the + print task. */ + xPrintQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( unsigned long ) ); /* If the queue could not be created then don't create any tasks that might attempt to use the queue. */ - if( xMsgQueue != NULL ) + if( xPrintQueue != NULL ) { /* Create STATS task, this prints out a summary of running tasks every 15s */ - xTaskCreate(vStatsTask, (signed char *)"STATS..", 600, NULL, 6, NULL); + xTaskCreate(vStatsTask, (signed char *)"STATS..", 600, NULL, mainSTAT_TASK_PRIORITY, NULL); + + /* Create LED task, this will flash the LEDs on the USB stick */ + xTaskCreate(vLedTask, (signed char *)"LEDS...", configMINIMAL_STACK_SIZE, NULL, mainLED_TASK_PRIORITY, NULL); /* Create the standard demo tasks. */ vStartDynamicPriorityTasks(); @@ -178,12 +420,11 @@ void main() queue, freeing up space for more commands to be received). */ vStartTimerDemoTask(mainTIMER_TEST_PERIOD); - /* Create the MSGl and register test tasks. */ - xTaskCreate(prvMsgTask, (signed char *)"MSG....", 500, mainTASK_PARAMETER_CHECK_VALUE, mainMSG_TASK_PRIORITY, NULL ); + /* Create the Print and register test tasks. */ + xTaskCreate(prvPrintTask, (signed char *)"Print..", 500, mainTASK_PARAMETER_CHECK_VALUE, mainPRINT_TASK_PRIORITY, NULL ); xTaskCreate(vRegTestTask1, (signed char *)"REG1...", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL); xTaskCreate(vRegTestTask2, (signed char *)"REG2...", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL); - /* Create the 'check' timer - the timer that periodically calls the check function as described at the top of this file. Note that, for the reasons stated in the comments above the call to @@ -201,16 +442,31 @@ void main() hook function, if one is configured. */ for (;;); } +/*-----------------------------------------------------------*/ +void vStatsTask(void *pvParameters) +{ +/* Buffer used to hold the table of run time statistics. This is static so it +does not overflow the task stack. */ +static signed char cStatsBuffer[ 1024 ]; +const portTickType x15Seconds = 15000 / portTICK_RATE_MS; -/* ----------------------------------------------------------------------------------------------------------- */ + printf("**** Task Statistics Started\n"); + for (;;) + { + vTaskDelay( x15Seconds ); + vTaskGetRunTimeStats( cStatsBuffer ); + printf("%s\n", cStatsBuffer ); + } +} +/*-----------------------------------------------------------*/ -static void prvMsgTask( void *pvParameters ) +static void prvPrintTask( void *pvParameters ) { - xQueueMessage xReceivedMessage; - static char cBuffer[50]; +unsigned long ulReceivedMessage; +static signed char cPrintBuffer[ 50 ]; - printf("**** Msg Task Started\n"); + printf( "**** Print Task Started\n" ); /* Now the scheduler has been started (it must have been for this task to be running), start the check timer too. The call to xTimerStart() will @@ -224,7 +480,7 @@ static void prvMsgTask( void *pvParameters ) is done after a short delay to ensure all the demo tasks have created all the objects they are going to use. */ vTaskDelay( mainTIMER_TEST_PERIOD * 10 ); - printf("**** %d heap free\n", (int)xPortGetFreeHeapSize()); + printf( "**** %d heap free\n", ( int ) xPortGetFreeHeapSize() ); /* Just as a test of the port, and for no functional reason, check the task parameter contains its expected value. */ @@ -240,73 +496,33 @@ static void prvMsgTask( void *pvParameters ) set to 1 in FreeRTOSConfig.h, therefore there is no need to check the function return value and the function will only return when a value has been received. */ - xQueueReceive( xMsgQueue, &xReceivedMessage, portMAX_DELAY ); + xQueueReceive( xPrintQueue, &ulReceivedMessage, portMAX_DELAY ); /* What is this message? What does it contain? */ - switch( xReceivedMessage.cMessageID ) + switch( ulReceivedMessage ) { -#if 0 - case mainMESSAGE_BUTTON_UP : /* The button poll task has just - informed this task that the up - button on the joystick input has - been pressed or released. */ - sprintf( cBuffer, "Button up = %d", ( int ) xReceivedMessage.ulMessageValue ); + case pdPASS : sprintf( ( char * ) cPrintBuffer, "Status = PASS" ); break; - - case mainMESSAGE_BUTTON_SEL : /* The select button interrupt - just informed this task that the - select button has been pressed. - In this case the pointer to the - string to print is sent directly - in the ulMessageValue member of - the message. This just - demonstrates a different - communication technique. */ - sprintf( cBuffer, "%s", ( char * ) xReceivedMessage.ulMessageValue ); + case mainERROR_DYNAMIC_TASKS : sprintf( ( char * ) cPrintBuffer, "Err: Dynamic tsks" ); + break; + case mainERROR_GEN_QUEUE_TEST : sprintf( ( char * ) cPrintBuffer, "Error: Gen Q test" ); + break; + case mainERROR_REG_TEST : sprintf( ( char * ) cPrintBuffer, "Error: Reg test" ); + break; + case mainERROR_TIMER_TEST : sprintf( ( char * ) cPrintBuffer, "Error: Tmr test" ); break; -#endif - case mainMESSAGE_STATUS : /* The tick interrupt hook - function has just informed this - task of the system status. - Generate a string in accordance - with the status value. */ - prvGenerateStatusMessage( cBuffer, xReceivedMessage.ulMessageValue ); + case mainERROR_COUNT_SEM_TEST : sprintf( ( char * ) cPrintBuffer, "Error: Count sem" ); break; - - default : sprintf( cBuffer, "Unknown message" ); + default : sprintf( ( char * ) cPrintBuffer, "Unknown status" ); break; } /* Output the message that was placed into the cBuffer array within the switch statement above, then move onto the next line ready for the next message to arrive on the queue. */ - printf("**** Message Received: %s\n", cBuffer); + printf( "**** Message Received: %s\n", cPrintBuffer ); } } -static void prvGenerateStatusMessage(char *pcBuffer, unsigned long ulStatusValue) -{ - /* Just a utility function to convert a status value into a meaningful - string for output. */ - switch( ulStatusValue ) - { - case pdPASS : sprintf( pcBuffer, "Status = PASS" ); - break; - case mainERROR_DYNAMIC_TASKS : sprintf( pcBuffer, "Err: Dynamic tsks" ); - break; - case mainERROR_COM_TEST : sprintf( pcBuffer, "Err: COM test" ); - break; - case mainERROR_GEN_QUEUE_TEST : sprintf( pcBuffer, "Error: Gen Q test" ); - break; - case mainERROR_REG_TEST : sprintf( pcBuffer, "Error: Reg test" ); - break; - case mainERROR_TIMER_TEST : sprintf( pcBuffer, "Error: Tmr test" ); - break; - case mainERROR_COUNT_SEM_TEST : sprintf( pcBuffer, "Error: Count sem" ); - break; - default : sprintf( pcBuffer, "Unknown status" ); - break; - } -} /* ----------------------------------------------------------------------------------------------------------- */ @@ -316,7 +532,7 @@ static void vCheckTimerCallback( xTimerHandle xTimer ) /* Define the status message that is sent to the LCD task. By default the status is PASS. */ - static xQueueMessage xStatusMessage = { mainMESSAGE_STATUS, pdPASS }; + unsigned long ulStatus = pdPASS; /* This is the callback function used by the 'check' timer, as described at the top of this file. */ @@ -327,49 +543,43 @@ static void vCheckTimerCallback( xTimerHandle xTimer ) /* See if the standard demo tasks are executing as expected, changing the message that is sent to the LCD task from PASS to an error code if any tasks set reports an error. */ -#if 0 - if( xAreComTestTasksStillRunning() != pdPASS ) - { - xStatusMessage.ulMessageValue = mainERROR_COM_TEST; - } -#endif if( xAreDynamicPriorityTasksStillRunning() != pdPASS ) { - xStatusMessage.ulMessageValue = mainERROR_DYNAMIC_TASKS; + ulStatus = mainERROR_DYNAMIC_TASKS; } if( xAreGenericQueueTasksStillRunning() != pdPASS ) { - xStatusMessage.ulMessageValue = mainERROR_GEN_QUEUE_TEST; + ulStatus = mainERROR_GEN_QUEUE_TEST; } if( xAreCountingSemaphoreTasksStillRunning() != pdPASS ) { - xStatusMessage.ulMessageValue = mainERROR_COUNT_SEM_TEST; + ulStatus = mainERROR_COUNT_SEM_TEST; } if( xAreTimerDemoTasksStillRunning( ( portTickType ) mainCHECK_TIMER_PERIOD ) != pdPASS ) { - xStatusMessage.ulMessageValue = mainERROR_TIMER_TEST; + ulStatus = mainERROR_TIMER_TEST; } /* Check the reg test tasks are still cycling. They will stop incrementing their loop counters if they encounter an error. */ if( usRegTest1Counter == usLastRegTest1Counter ) { - xStatusMessage.ulMessageValue = mainERROR_REG_TEST; + ulStatus = mainERROR_REG_TEST; } if( usRegTest2Counter == usLastRegTest2Counter ) { - xStatusMessage.ulMessageValue = mainERROR_REG_TEST; + ulStatus = mainERROR_REG_TEST; } usLastRegTest1Counter = usRegTest1Counter; usLastRegTest2Counter = usRegTest2Counter; /* This is called from a timer callback so must not block! */ - xQueueSendToBack( xMsgQueue, &xStatusMessage, mainDONT_BLOCK ); + xQueueSendToBack( xPrintQueue, &ulStatus, mainDONT_BLOCK ); } @@ -425,5 +635,6 @@ void vApplicationIdleHook(void) /* ----------------------------------------------------------------------------------------------------------- */ +#endif diff --git a/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/main_blinky.c b/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/main_blinky.c new file mode 100644 index 000000000..1beca1666 --- /dev/null +++ b/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/main_blinky.c @@ -0,0 +1,240 @@ +volatile unsigned long ulRx = 0, ulTx = 0; +/* + FreeRTOS V7.2.0 - Copyright (C) 2012 Real Time Engineers Ltd. + + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and thank you for your support! * + * * + *************************************************************************** + + + 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. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 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, training, latest information, + license and contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool. + + Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell + the code with commercial support, indemnification, and middleware, under + the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also + provide a safety engineered and independently SIL3 certified version under + the SafeRTOS brand: http://www.SafeRTOS.com. +*/ + +/****************************************************************************** + * NOTE 1: This project provides two demo applications. A simple blinky style + * project, and a more comprehensive test and demo application. The + * mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting in main.c is used to select + * between the two. See the notes on using mainCREATE_SIMPLE_BLINKY_DEMO_ONLY + * in main.c. This file implements the simply blinky style version. + * + * NOTE 2: This file only contains the source code that is specific to the + * basic demo. Generic functions, such FreeRTOS hook functions, and functions + * required to configure the hardware, are defined in main.c. + ****************************************************************************** + * + * main_blinky() creates one queue, and two tasks. It then starts the + * scheduler. + * + * The Queue Send Task: + * The queue send task is implemented by the prvQueueSendTask() function in + * this file. prvQueueSendTask() sits in a loop that causes it to repeatedly + * block for 200 milliseconds, before sending the value 100 to the queue that + * was created within main_blinky(). Once the value is sent, the task loops + * back around to block for another 200 milliseconds. + * + * The Queue Receive Task: + * The queue receive task is implemented by the prvQueueReceiveTask() function + * in this file. prvQueueReceiveTask() sits in a loop where it repeatedly + * blocks on attempts to read data from the queue that was created within + * main_blinky(). When data is received, the task checks the value of the + * data, and if the value equals the expected 100, toggles the LED. The 'block + * time' parameter passed to the queue receive function specifies that the + * task should be held in the Blocked state indefinitely to wait for data to + * be available on the queue. The queue receive task will only leave the + * Blocked state when the queue send task writes to the queue. As the queue + * send task writes to the queue every 200 milliseconds, the queue receive + * task leaves the Blocked state every 200 milliseconds, and therefore toggles + * the LED every 200 milliseconds. + */ + +/* Standard includes. */ +#include + +/* Kernel includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "semphr.h" + +/* Common demo includes. */ +#include "partest.h" + +/* Priorities at which the tasks are created. */ +#define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 ) +#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) + +/* The rate at which data is sent to the queue. The 200ms value is converted +to ticks using the portTICK_RATE_MS constant. */ +#define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_RATE_MS ) + +/* The number of items the queue can hold. This is 1 as the receive task +will remove items as they are added, meaning the send task should always find +the queue empty. */ +#define mainQUEUE_LENGTH ( 1 ) + +/* Values passed to the two tasks just to check the task parameter +functionality. */ +#define mainQUEUE_SEND_PARAMETER ( 0x1111UL ) +#define mainQUEUE_RECEIVE_PARAMETER ( 0x22UL ) + +/*-----------------------------------------------------------*/ + +/* + * The tasks as described in the comments at the top of this file. + */ +static void prvQueueReceiveTask( void *pvParameters ); +static void prvQueueSendTask( void *pvParameters ); + +/* + * Called by main() to create the simply blinky style application if + * mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 1. + */ +void main_blinky( void ); + +/*-----------------------------------------------------------*/ + +/* The queue used by both tasks. */ +static xQueueHandle xQueue = NULL; + +/*-----------------------------------------------------------*/ + +void main_blinky( void ) +{ + /* Create the queue. */ + xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( unsigned long ) ); + + if( xQueue != NULL ) + { + /* Start the two tasks as described in the comments at the top of this + file. */ + xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */ + ( signed char * ) "Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */ + configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */ + ( void * ) mainQUEUE_RECEIVE_PARAMETER, /* The parameter passed to the task - just to check the functionality. */ + mainQUEUE_RECEIVE_TASK_PRIORITY, /* The priority assigned to the task. */ + NULL ); /* The task handle is not required, so NULL is passed. */ + + xTaskCreate( prvQueueSendTask, ( signed char * ) "TX", configMINIMAL_STACK_SIZE, ( void * ) mainQUEUE_SEND_PARAMETER, mainQUEUE_SEND_TASK_PRIORITY, NULL ); + + /* Start the tasks and timer running. */ + 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 prvQueueSendTask( void *pvParameters ) +{ +portTickType xNextWakeTime; +const unsigned long ulValueToSend = 100UL; + + /* Check the task parameter is as expected. */ + configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_SEND_PARAMETER ); + + /* Initialise xNextWakeTime - this only needs to be done once. */ + xNextWakeTime = xTaskGetTickCount(); + + for( ;; ) + { + /* Place this task in the blocked state until it is time to run again. + The block time is specified in ticks, the constant used converts ticks + to ms. While in the Blocked state this task will not consume any CPU + time. */ + vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS ); + + /* Send to the queue - causing the queue receive task to unblock and + toggle the LED. 0 is used as the block time so the sending operation + will not block - it shouldn't need to block as the queue should always + be empty at this point in the code. */ + xQueueSend( xQueue, &ulValueToSend, 0U ); +ulTx++; + } +} +/*-----------------------------------------------------------*/ + +static void prvQueueReceiveTask( void *pvParameters ) +{ +unsigned long ulReceivedValue; + + /* Check the task parameter is as expected. */ + configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_RECEIVE_PARAMETER ); + + for( ;; ) + { + /* Wait until something arrives in the queue - this task will block + indefinitely provided INCLUDE_vTaskSuspend is set to 1 in + FreeRTOSConfig.h. */ + xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY ); + + /* To get here something must have been received from the queue, but + is it the expected value? If it is, toggle the LED. */ + if( ulReceivedValue == 100UL ) + { + vParTestToggleLED( 0 ); + ulReceivedValue = 0U; +ulRx++; + } + } +} +/*-----------------------------------------------------------*/ + diff --git a/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/os/heap_4.c b/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/os/heap_4.c new file mode 100644 index 000000000..3210b3ce3 --- /dev/null +++ b/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/os/heap_4.c @@ -0,0 +1,357 @@ +/* + FreeRTOS V7.2.0 - Copyright (C) 2012 Real Time Engineers Ltd. + + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and thank you for your support! * + * * + *************************************************************************** + + + 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. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 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, training, latest information, + license and contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool. + + Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell + the code with commercial support, indemnification, and middleware, under + the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also + provide a safety engineered and independently SIL3 certified version under + the SafeRTOS brand: http://www.SafeRTOS.com. +*/ + +/* + * A sample implementation of pvPortMalloc() and vPortFree() that combines + * (coalescences) adjacent memory blocks as they are freed, and in so doing + * limits memory fragmentation. + * + * See heap_1.c, heap_2.c and heap_3.c for alternative implementations, and the + * memory management pages of http://www.FreeRTOS.org for more information. + */ +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#include "FreeRTOS.h" +#include "task.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* Block sizes must not get too small. */ +#define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( heapSTRUCT_SIZE * 2 ) ) + +/* Allocate the memory for the heap. The struct is used to force byte +alignment without using any non-portable code. */ +static union xRTOS_HEAP +{ + #if portBYTE_ALIGNMENT == 8 + volatile portDOUBLE dDummy; + #else + volatile unsigned long ulDummy; + #endif + unsigned char ucHeap[ configTOTAL_HEAP_SIZE ]; +} xHeap; + +/* Define the linked list structure. This is used to link free blocks in order +of their memory address. */ +typedef struct A_BLOCK_LINK +{ + struct A_BLOCK_LINK *pxNextFreeBlock; /*<< The next free block in the list. */ + size_t xBlockSize; /*<< The size of the free block. */ +} xBlockLink; + +/*-----------------------------------------------------------*/ + +/* + * Inserts a block of memory that is being freed into the correct position in + * the list of free memory blocks. The block being freed will be merged with + * the block in front it and/or the block behind it if the memory blocks are + * adjacent to each other. + */ +static void prvInsertBlockIntoFreeList( xBlockLink *pxBlockToInsert ); + +/* + * Called automatically to setup the required heap structures the first time + * pvPortMalloc() is called. + */ +static void prvHeapInit( void ); + +/*-----------------------------------------------------------*/ + +/* The size of the structure placed at the beginning of each allocated memory +block must by correctly byte aligned. */ +static const unsigned short heapSTRUCT_SIZE = ( sizeof( xBlockLink ) + portBYTE_ALIGNMENT - ( sizeof( xBlockLink ) % portBYTE_ALIGNMENT ) ); + +/* Ensure the pxEnd pointer will end up on the correct byte alignment. */ +static const size_t xTotalHeapSize = ( ( size_t ) configTOTAL_HEAP_SIZE ) & ( ( size_t ) ~portBYTE_ALIGNMENT_MASK ); + +/* Create a couple of list links to mark the start and end of the list. */ +static xBlockLink xStart, *pxEnd = NULL; + +/* Keeps track of the number of free bytes remaining, but says nothing about +fragmentation. */ +static size_t xFreeBytesRemaining = ( ( size_t ) configTOTAL_HEAP_SIZE ) & ( ( size_t ) ~portBYTE_ALIGNMENT_MASK ); + +/* STATIC FUNCTIONS ARE DEFINED AS MACROS TO MINIMIZE THE FUNCTION CALL DEPTH. */ + +/*-----------------------------------------------------------*/ + +void *pvPortMalloc( size_t xWantedSize ) +{ +xBlockLink *pxBlock, *pxPreviousBlock, *pxNewBlockLink; +void *pvReturn = NULL; + + vTaskSuspendAll(); + { + /* If this is the first call to malloc then the heap will require + initialisation to setup the list of free blocks. */ + if( pxEnd == NULL ) + { + prvHeapInit(); + } + + /* The wanted size is increased so it can contain a xBlockLink + structure in addition to the requested amount of bytes. */ + if( xWantedSize > 0 ) + { + xWantedSize += heapSTRUCT_SIZE; + + /* Ensure that blocks are always aligned to the required number of + bytes. */ + if( xWantedSize & portBYTE_ALIGNMENT_MASK ) + { + /* Byte alignment required. */ + xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ); + } + } + + if( ( xWantedSize > 0 ) && ( xWantedSize < xTotalHeapSize ) ) + { + /* Traverse the list from the start (lowest address) block until one + of adequate size is found. */ + pxPreviousBlock = &xStart; + pxBlock = xStart.pxNextFreeBlock; + while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) ) + { + pxPreviousBlock = pxBlock; + pxBlock = pxBlock->pxNextFreeBlock; + } + + /* If the end marker was reached then a block of adequate size was + not found. */ + if( pxBlock != pxEnd ) + { + /* Return the memory space - jumping over the xBlockLink structure + at its start. */ + pvReturn = ( void * ) ( ( ( unsigned char * ) pxPreviousBlock->pxNextFreeBlock ) + heapSTRUCT_SIZE ); + + /* This block is being returned for use so must be taken out of + the list of free blocks. */ + pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock; + + /* If the block is larger than required it can be split into two. */ + if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE ) + { + /* This block is to be split into two. Create a new block + following the number of bytes requested. The void cast is + used to prevent byte alignment warnings from the compiler. */ + pxNewBlockLink = ( void * ) ( ( ( unsigned char * ) pxBlock ) + xWantedSize ); + + /* Calculate the sizes of two blocks split from the single + block. */ + pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize; + pxBlock->xBlockSize = xWantedSize; + + /* Insert the new block into the list of free blocks. */ + prvInsertBlockIntoFreeList( ( pxNewBlockLink ) ); + } + + xFreeBytesRemaining -= pxBlock->xBlockSize; + } + } + } + xTaskResumeAll(); + + #if( configUSE_MALLOC_FAILED_HOOK == 1 ) + { + if( pvReturn == NULL ) + { + extern void vApplicationMallocFailedHook( void ); + vApplicationMallocFailedHook(); + } + } + #endif + + return pvReturn; +} +/*-----------------------------------------------------------*/ + +void vPortFree( void *pv ) +{ +unsigned char *puc = ( unsigned char * ) pv; +xBlockLink *pxLink; + + if( pv != NULL ) + { + /* The memory being freed will have an xBlockLink structure immediately + before it. */ + puc -= heapSTRUCT_SIZE; + + /* This casting is to keep the compiler from issuing warnings. */ + pxLink = ( void * ) puc; + + vTaskSuspendAll(); + { + /* Add this block to the list of free blocks. */ + xFreeBytesRemaining += pxLink->xBlockSize; + prvInsertBlockIntoFreeList( ( ( xBlockLink * ) pxLink ) ); + } + xTaskResumeAll(); + } +} +/*-----------------------------------------------------------*/ + +size_t xPortGetFreeHeapSize( void ) +{ + return xFreeBytesRemaining; +} +/*-----------------------------------------------------------*/ + +void vPortInitialiseBlocks( void ) +{ + /* This just exists to keep the linker quiet. */ +} +/*-----------------------------------------------------------*/ + +static void prvHeapInit( void ) +{ +xBlockLink *pxFirstFreeBlock; +unsigned char *pucHeapEnd; + + /* Ensure the start of the heap is aligned. */ + configASSERT( ( ( ( unsigned long ) xHeap.ucHeap ) & ( ( unsigned long ) portBYTE_ALIGNMENT_MASK ) ) == 0UL ); + + /* xStart is used to hold a pointer to the first item in the list of free + blocks. The void cast is used to prevent compiler warnings. */ + xStart.pxNextFreeBlock = ( void * ) xHeap.ucHeap; + xStart.xBlockSize = ( size_t ) 0; + + /* pxEnd is used to mark the end of the list of free blocks and is inserted + at the end of the heap space. */ + pucHeapEnd = xHeap.ucHeap + xTotalHeapSize; + pucHeapEnd -= heapSTRUCT_SIZE; + pxEnd = ( void * ) pucHeapEnd; + configASSERT( ( ( ( unsigned long ) pxEnd ) & ( ( unsigned long ) portBYTE_ALIGNMENT_MASK ) ) == 0UL ); + pxEnd->xBlockSize = 0; + pxEnd->pxNextFreeBlock = NULL; + + /* To start with there is a single free block that is sized to take up the + entire heap space, minus the space taken by pxEnd. */ + pxFirstFreeBlock = ( void * ) xHeap.ucHeap; + pxFirstFreeBlock->xBlockSize = xTotalHeapSize - heapSTRUCT_SIZE; + pxFirstFreeBlock->pxNextFreeBlock = pxEnd; + + /* The heap now contains pxEnd. */ + xFreeBytesRemaining -= heapSTRUCT_SIZE; +} +/*-----------------------------------------------------------*/ + +static void prvInsertBlockIntoFreeList( xBlockLink *pxBlockToInsert ) +{ +xBlockLink *pxIterator; +unsigned char *puc; + + /* Iterate through the list until a block is found that has a higher address + than the block being inserted. */ + for( pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock ) + { + /* Nothing to do here, just iterate to the right position. */ + } + + /* Do the block being inserted, and the block it is being inserted after + make a contiguous block of memory? */ + puc = ( unsigned char * ) pxIterator; + if( ( puc + pxIterator->xBlockSize ) == ( unsigned char * ) pxBlockToInsert ) + { + pxIterator->xBlockSize += pxBlockToInsert->xBlockSize; + pxBlockToInsert = pxIterator; + } + + /* Do the block being inserted, and the block it is being inserted before + make a contiguous block of memory? */ + puc = ( unsigned char * ) pxBlockToInsert; + if( ( puc + pxBlockToInsert->xBlockSize ) == ( unsigned char * ) pxIterator->pxNextFreeBlock ) + { + if( pxIterator->pxNextFreeBlock != pxEnd ) + { + /* Form one big block from the two blocks. */ + pxBlockToInsert->xBlockSize += pxIterator->pxNextFreeBlock->xBlockSize; + pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock->pxNextFreeBlock; + } + else + { + pxBlockToInsert->pxNextFreeBlock = pxEnd; + } + } + else + { + pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; + } + + /* If the block being inserted plugged a gab, so was merged with the block + before and the block after, then it's pxNextFreeBlock pointer will have + already been set, and should not be set here as that would make it point + to itself. */ + if( pxIterator != pxBlockToInsert ) + { + pxIterator->pxNextFreeBlock = pxBlockToInsert; + } +} + diff --git a/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/startup/sys_system.c b/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/startup/sys_system.c index df0674db4..d5cb9003a 100644 --- a/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/startup/sys_system.c +++ b/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/startup/sys_system.c @@ -34,37 +34,6 @@ void systemInit(void) | (3U << 8U) | (1U << 4U) | 1U; -#if 0 - /** - Setup flash bank power modes */ - flashWREG->FBFALLBACK = 0x05050000 - | (SYS_ACTIVE << 14U) - | (SYS_SLEEP << 12U) - | (SYS_SLEEP << 10U) - | (SYS_SLEEP << 8U) - | (SYS_SLEEP << 6U) - | (SYS_SLEEP << 4U) - | (SYS_ACTIVE << 2U) - | SYS_ACTIVE; - - /** @b Initialize @b Lpo: */ - - { - unsigned trim = *(volatile unsigned short *)0xF00801B4; - - if (trim != 0xFFFF) - { - systemREG1->LPOMONCTL = (1U << 24U) - | (0U << 16U) - | trim; - } - else - { - systemREG1->LPOMONCTL = (1U << 24U) - | (0U << 16U) - | (systemREG1->LPOMONCTL & 0xFFFF); - } - } -#endif /** @b Initialize @b Pll: */ /** - Setup pll control register 1: diff --git a/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/startup/sys_system.h b/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/startup/sys_system.h index b0cbe9107..fde102984 100644 --- a/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/startup/sys_system.h +++ b/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/startup/sys_system.h @@ -166,7 +166,7 @@ typedef volatile struct systemBase1 unsigned BMMCR1; /* 0x00C4 */ unsigned BMMCR2; /* 0x00C8 */ unsigned MMUGCR; /* 0x00CC */ -#ifdef _little_endian__ +#ifdef __little_endian__ unsigned : 8U; /* 0x00D0 */ unsigned PENA : 1U; /* 0x00D0 */ unsigned : 7U; /* 0x00D0 */ -- 2.39.5