diff --git a/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/.cproject b/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/.cproject new file mode 100644 index 000000000..11906a4e1 --- /dev/null +++ b/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/.cproject @@ -0,0 +1,229 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/.project b/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/.project new file mode 100644 index 000000000..1251c8e88 --- /dev/null +++ b/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/.project @@ -0,0 +1,223 @@ + + + RTOSDemo + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + CommonDemoFiles + 2 + FREERTOS_ROOT/FreeRTOS/Demo/Common/Minimal + + + FreeRTOS+Trace Recorder + 2 + FREERTOS_ROOT/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace + + + FreeRTOS_Source + 2 + FREERTOS_ROOT/FreeRTOS/Source + + + LegacyDrivers + 2 + FREERTOS_ROOT/FreeRTOS/Demo/Common/drivers/LuminaryMicro + + + CommonDemoFiles/include + 2 + FREERTOS_ROOT/FreeRTOS/Demo/Common/include + + + + + 1595186095257 + CommonDemoFiles + 5 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-IntQueue.c + + + + 1595186095263 + CommonDemoFiles + 5 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-recmutex.c + + + + 1595186095270 + CommonDemoFiles + 5 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-blocktim.c + + + + 1595186095276 + CommonDemoFiles + 5 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-semtest.c + + + + 1595186095310 + CommonDemoFiles + 5 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-QPeek.c + + + + 1595186095317 + CommonDemoFiles + 5 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-QueueSet.c + + + + 1595186095323 + CommonDemoFiles + 5 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-EventGroupsDemo.c + + + + 1595186095329 + CommonDemoFiles + 5 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-MessageBufferDemo.c + + + + 1595186095335 + CommonDemoFiles + 5 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-StreamBufferDemo.c + + + + 1595186095356 + CommonDemoFiles + 5 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-death.c + + + + 1595791773655 + FreeRTOS+Trace Recorder + 9 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-Include + + + + 1595791773708 + FreeRTOS+Trace Recorder + 5 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-trcKernelPort.c + + + + 1595791773801 + FreeRTOS+Trace Recorder + 5 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-trcSnapshotRecorder.c + + + + 1590288652117 + FreeRTOS_Source + 5 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.c + + + + 1590288057189 + FreeRTOS_Source/portable + 9 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-GCC + + + + 1590288057198 + FreeRTOS_Source/portable + 9 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-MemMang + + + + 1590288101945 + FreeRTOS_Source/portable/GCC + 9 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-ARM_CM3 + + + + 1590288021187 + FreeRTOS_Source/portable/MemMang + 5 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-heap_4.c + + + + + + FREERTOS_ROOT + $%7BPARENT-3-PROJECT_LOC%7D + + + diff --git a/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/.settings/language.settings.xml b/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/.settings/language.settings.xml new file mode 100644 index 000000000..fe0e11ea4 --- /dev/null +++ b/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/.settings/language.settings.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/FreeRTOSConfig.h b/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/FreeRTOSConfig.h new file mode 100644 index 000000000..d5cb0e376 --- /dev/null +++ b/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/FreeRTOSConfig.h @@ -0,0 +1,123 @@ +/* + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html + *----------------------------------------------------------*/ + +#define configUSE_PREEMPTION 1 +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 1 +#define configCPU_CLOCK_HZ ( ( unsigned long ) 50000000 ) +#define configTICK_RATE_HZ ( ( TickType_t ) 1000 ) +#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 90 ) +#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 50 * 1024 ) ) +#define configMAX_TASK_NAME_LEN ( 12 ) +#define configUSE_TRACE_FACILITY 1 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 0 +#define configUSE_CO_ROUTINES 0 +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configCHECK_FOR_STACK_OVERFLOW 2 +#define configUSE_QUEUE_SETS 1 +#define configUSE_COUNTING_SEMAPHORES 1 + +#define configMAX_PRIORITIES ( 6UL ) +#define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) +#define configQUEUE_REGISTRY_SIZE 10 +#define configSUPPORT_STATIC_ALLOCATION 1 + +/* Timer related defines. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY 2 +#define configTIMER_QUEUE_LENGTH 20 +#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE ) + +/* Set the following definitions to 1 to include the API function, or zero +to exclude the API function. */ + +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskCleanUpResources 0 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 1 +#define INCLUDE_xTaskGetSchedulerState 1 +#define INCLUDE_xTimerGetTimerDaemonTaskHandle 1 +#define INCLUDE_xTaskGetIdleTaskHandle 1 +#define INCLUDE_xSemaphoreGetMutexHolder 1 +#define INCLUDE_eTaskGetState 1 +#define INCLUDE_xTimerPendFunctionCall 1 + +/* This demo makes use of one or more example stats formatting functions. These +format the raw data provided by the uxTaskGetSystemState() function in to human +readable ASCII form. See the notes in the implementation of vTaskList() within +FreeRTOS/Source/tasks.c for limitations. */ +#define configUSE_STATS_FORMATTING_FUNCTIONS 1 + +#define configKERNEL_INTERRUPT_PRIORITY ( 255 ) /* All eight bits as QEMU doesn't model the priority bits. */ +/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! +See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ +#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( 5 ) + +/* Use the Cortex-M3 optimised task selection rather than the generic C code +version. */ +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 + +/* The test that checks the trigger level on stream buffers requires an +allowable margin of error on slower processors (slower than the Win32 +machine on which the test is developed). */ +#define configSTREAM_BUFFER_TRIGGER_LEVEL_TEST_MARGIN ( 1 ) + +/* Override locally defined test task stack sizes as appropriate for this +demo. */ +#define configMESSAGE_BUFFER_BLOCK_TASK_STACK_SIZE ( 110 ) +#define configSTREAM_BUFFER_SENDER_TASK_STACK_SIZE ( 180 ) +#define configSTREAM_BUFFER_SMALLER_TASK_STACK_SIZE ( 110 ) + +void vAssertCalled( const char *pcFile, unsigned long ulLine ); +#define configASSERT( x ) if( ( x ) == 0 ) vAssertCalled( __FILE__, __LINE__ ); + +/* Include the FreeRTOS+Trace FreeRTOS trace macro definitions. See the comments +at the top of main.c for enabling the trace recorder. +#include "trcRecorder.h" */ + +#endif /* FREERTOS_CONFIG_H */ diff --git a/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/LocalDemoFiles/IntQueueTimer.c b/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/LocalDemoFiles/IntQueueTimer.c new file mode 100644 index 000000000..6b8d30b19 --- /dev/null +++ b/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/LocalDemoFiles/IntQueueTimer.c @@ -0,0 +1,95 @@ +/* + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/* Scheduler includes. */ +#include "FreeRTOS.h" + +/* Demo includes. */ +#include "IntQueueTimer.h" +#include "IntQueue.h" + +/* Library includes. */ +#include "hw_ints.h" +#include "hw_memmap.h" +#include "hw_types.h" +#include "interrupt.h" +#include "sysctl.h" +#include "lmi_timer.h" + +#define tmrTIMER_2_FREQUENCY ( 2000UL ) +#define tmrTIMER_3_FREQUENCY ( 2001UL ) + +void vInitialiseTimerForIntQueueTest( void ) +{ +uint32_t ulFrequency; + + /* Timer 2 and 3 are utilised for this test. */ + SysCtlPeripheralEnable( SYSCTL_PERIPH_TIMER2 ); + SysCtlPeripheralEnable( SYSCTL_PERIPH_TIMER3 ); + TimerConfigure( TIMER2_BASE, TIMER_CFG_32_BIT_PER ); + TimerConfigure( TIMER3_BASE, TIMER_CFG_32_BIT_PER ); + + /* Set the timer interrupts to be above the kernel. The interrupts are + assigned different priorities so they nest with each other. */ + IntPrioritySet( INT_TIMER2A, configMAX_SYSCALL_INTERRUPT_PRIORITY + ( 1 << 5 ) ); /* Shift left 5 as only the top 3 bits are implemented. */ + IntPrioritySet( INT_TIMER3A, configMAX_SYSCALL_INTERRUPT_PRIORITY ); + + /* Ensure interrupts do not start until the scheduler is running. */ + portDISABLE_INTERRUPTS(); + + /* The rate at which the timers will interrupt. */ + ulFrequency = configCPU_CLOCK_HZ / tmrTIMER_2_FREQUENCY; + TimerLoadSet( TIMER2_BASE, TIMER_A, ulFrequency ); + IntEnable( INT_TIMER2A ); + TimerIntEnable( TIMER2_BASE, TIMER_TIMA_TIMEOUT ); + + /* The rate at which the timers will interrupt. */ + ulFrequency = configCPU_CLOCK_HZ / tmrTIMER_3_FREQUENCY; + TimerLoadSet( TIMER3_BASE, TIMER_A, ulFrequency ); + IntEnable( INT_TIMER3A ); + TimerIntEnable( TIMER3_BASE, TIMER_TIMA_TIMEOUT ); + + /* Enable both timers. */ + TimerEnable( TIMER2_BASE, TIMER_A ); + TimerEnable( TIMER3_BASE, TIMER_A ); +} +/*-----------------------------------------------------------*/ + +void vT2InterruptHandler( void ) +{ + TimerIntClear( TIMER2_BASE, TIMER_TIMA_TIMEOUT ); + portEND_SWITCHING_ISR( xFirstTimerHandler() ); +} +/*-----------------------------------------------------------*/ + +void vT3InterruptHandler( void ) +{ + TimerIntClear( TIMER3_BASE, TIMER_TIMA_TIMEOUT ); + portEND_SWITCHING_ISR( xSecondTimerHandler() ); +} + + diff --git a/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/LocalDemoFiles/IntQueueTimer.h b/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/LocalDemoFiles/IntQueueTimer.h new file mode 100644 index 000000000..0f0f2f0b4 --- /dev/null +++ b/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/LocalDemoFiles/IntQueueTimer.h @@ -0,0 +1,36 @@ +/* + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#ifndef INT_QUEUE_TIMER_H +#define INT_QUEUE_TIMER_H + +void vInitialiseTimerForIntQueueTest( void ); +BaseType_t xTimer0Handler( void ); +BaseType_t xTimer1Handler( void ); + +#endif + diff --git a/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/LocalDemoFiles/bitmap.h b/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/LocalDemoFiles/bitmap.h new file mode 100644 index 000000000..2660b2616 --- /dev/null +++ b/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/LocalDemoFiles/bitmap.h @@ -0,0 +1,336 @@ +#ifndef BITMAP_H +#define BITMAP_H + +#define bmpBITMAP_HEIGHT 50 +#define bmpBITMAP_WIDTH 128 + +const unsigned char pucBasicBitmap[] = +{ +0x00, 0x0a, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, +0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, +0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, +0xaa, 0xaa, 0xaa, 0x00, 0x0a, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, +0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, +0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, +0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xa0, 0x0a, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, +0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, +0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, +0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0xaf, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa, 0xaa, +0xaa, 0xaf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xfa, 0xaa, 0xaa, 0xaf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa, 0xaa, 0xaa, 0xaf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa, 0xaa, 0xaa, 0xaf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, +0x00, 0x8f, 0xff, 0xff, 0xf8, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x88, 0x88, 0x88, +0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x88, 0x77, 0x77, 0x78, 0x8f, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x88, 0x77, 0x77, 0x88, 0x8f, 0xff, 0xff, 0xff, 0xfa, 0xaa, 0xaa, 0xaf, 0xff, 0xff, +0xff, 0xff, 0xf0, 0x00, 0x00, 0x8f, 0x00, 0xff, 0x87, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0xff, 0xff, +0xf7, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0xff, 0xff, 0xff, 0x87, 0x77, 0x77, 0x77, 0x77, 0x77, +0x77, 0x77, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x7f, 0xff, 0xff, 0xfa, 0xaa, +0xaa, 0xaf, 0xff, 0xff, 0xff, 0xff, 0x70, 0x00, 0x00, 0x8f, 0x00, 0xff, 0x87, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, +0x77, 0x77, 0xff, 0xff, 0xf7, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0xff, 0xff, 0xf8, 0x77, 0x77, +0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0xff, 0xff, 0xff, 0xff, 0x87, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x8f, +0xff, 0xff, 0xfa, 0xaa, 0xaa, 0xaf, 0xff, 0xff, 0xff, 0xff, 0x70, 0x08, 0x00, 0x8f, 0x00, 0xff, 0x87, 0x77, 0x77, 0x77, +0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x8f, 0xff, 0xf7, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0xff, +0xff, 0x87, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x8f, 0xff, 0xff, 0xf8, 0x77, 0x77, 0x77, 0x77, 0x77, +0x77, 0x77, 0x77, 0x8f, 0xff, 0xff, 0xfa, 0xaa, 0xaa, 0xaf, 0xff, 0xff, 0xff, 0xff, 0x00, 0x0f, 0x00, 0x8f, 0x00, 0xff, +0x87, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0xff, 0xf7, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, +0x77, 0x77, 0x78, 0xff, 0xf8, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0xff, 0xff, 0xf8, 0x77, +0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x8f, 0xff, 0xff, 0xfa, 0xaa, 0xaa, 0xaf, 0xff, 0xff, 0xff, 0xff, 0x70, 0x07, +0x00, 0x70, 0x00, 0xff, 0x87, 0x77, 0x77, 0x77, 0xff, 0xff, 0xf8, 0x77, 0x77, 0x77, 0x77, 0xff, 0xff, 0xff, 0xff, 0xff, +0x77, 0x77, 0x77, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x87, 0x77, 0x77, 0x77, 0x78, 0xff, 0xff, 0xf8, 0x77, 0x77, 0x77, 0x77, +0xff, 0xff, 0x87, 0x77, 0x77, 0x77, 0x8f, 0xff, 0xff, 0xff, 0x88, 0x8f, 0xff, 0xff, 0xfa, 0xaa, 0xaa, 0xaf, 0xff, 0xff, +0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x07, 0xff, 0x87, 0x77, 0x77, 0x77, 0xff, 0xff, 0xff, 0x87, 0x77, 0x77, 0x77, 0xff, +0xff, 0xff, 0xff, 0xff, 0x77, 0x77, 0x77, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x77, 0x77, 0x77, 0x77, 0xff, 0xff, 0xff, 0xff, +0x87, 0x77, 0x77, 0x77, 0xff, 0xff, 0x77, 0x77, 0x77, 0x77, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa, 0xaa, +0xaa, 0xaf, 0xff, 0xff, 0xff, 0xff, 0xf7, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x87, 0x77, 0x77, 0x77, 0xff, 0xff, 0xff, 0xf8, +0x77, 0x77, 0x77, 0xff, 0xff, 0xff, 0xff, 0xff, 0x77, 0x77, 0x77, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x77, 0x77, 0x77, 0x77, +0xff, 0xff, 0xff, 0xff, 0xf7, 0x77, 0x77, 0x77, 0x8f, 0xff, 0x77, 0x77, 0x77, 0x77, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xfa, 0xaa, 0xaa, 0xaf, 0xff, 0xff, 0xff, 0xff, 0xff, 0x70, 0x00, 0x00, 0xff, 0xff, 0x87, 0x77, 0x77, 0x77, +0xff, 0xff, 0xff, 0xf8, 0x77, 0x77, 0x77, 0xff, 0xff, 0xff, 0xff, 0xff, 0x77, 0x77, 0x77, 0x7f, 0xff, 0xff, 0xff, 0xff, +0x77, 0x77, 0x77, 0x78, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x77, 0x77, 0x77, 0x8f, 0xff, 0x77, 0x77, 0x77, 0x77, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa, 0xaa, 0xaa, 0xaf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0x87, 0x77, 0x77, 0x77, 0xff, 0xff, 0xff, 0xf7, 0x77, 0x77, 0x78, 0xff, 0xff, 0xff, 0xff, 0xff, 0x77, 0x77, 0x77, 0x7f, +0xff, 0xff, 0xff, 0xf8, 0x77, 0x77, 0x77, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0x77, 0x77, 0x78, 0xff, 0x87, 0x77, +0x77, 0x77, 0x78, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa, 0xaa, 0xaa, 0xaf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0x88, 0xff, 0xff, 0xff, 0x87, 0x77, 0x77, 0x77, 0xff, 0xff, 0xf8, 0x87, 0x77, 0x77, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, +0x77, 0x77, 0x77, 0x7f, 0xff, 0xff, 0xff, 0xf8, 0x77, 0x77, 0x77, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0x77, 0x77, +0x78, 0xff, 0x87, 0x77, 0x77, 0x77, 0x77, 0x77, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa, 0xaa, 0xaa, 0xaf, 0xff, 0xff, +0xff, 0xff, 0xff, 0x80, 0x00, 0x8f, 0x8f, 0xff, 0x87, 0x77, 0x77, 0x77, 0x88, 0x88, 0x77, 0x77, 0x77, 0x77, 0x8f, 0xff, +0xff, 0xff, 0xff, 0xff, 0x77, 0x77, 0x77, 0x7f, 0xff, 0xff, 0xff, 0xf8, 0x77, 0x77, 0x77, 0x8f, 0xff, 0xff, 0xff, 0xff, +0xff, 0x87, 0x77, 0x77, 0x78, 0xff, 0xf7, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x88, 0xff, 0xff, 0xff, 0xff, 0xfa, 0xaa, +0xaa, 0xaf, 0xff, 0xff, 0xff, 0xff, 0xf7, 0x00, 0x00, 0x8f, 0x07, 0xff, 0x87, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, +0x77, 0x77, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x77, 0x77, 0x77, 0x7f, 0xff, 0xff, 0xff, 0xf8, 0x77, 0x77, 0x77, 0x8f, +0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0x77, 0x77, 0x78, 0xff, 0xf8, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x8f, 0xff, +0xff, 0xff, 0xfa, 0xaa, 0xaa, 0xaf, 0xff, 0xff, 0xff, 0xff, 0x70, 0x07, 0x00, 0x8f, 0x00, 0xff, 0x87, 0x77, 0x77, 0x77, +0x77, 0x77, 0x77, 0x77, 0x88, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x77, 0x77, 0x77, 0x7f, 0xff, 0xff, 0xff, 0xf8, +0x77, 0x77, 0x77, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0x77, 0x77, 0x78, 0xff, 0xff, 0xf8, 0x77, 0x77, 0x77, 0x77, +0x77, 0x77, 0x77, 0x8f, 0xff, 0xff, 0xfa, 0xaa, 0xaa, 0xaf, 0xff, 0xff, 0xff, 0xff, 0x70, 0x0f, 0x00, 0x8f, 0x00, 0xff, +0x87, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x77, 0x77, 0x77, 0x7f, +0xff, 0xff, 0xff, 0xf8, 0x77, 0x77, 0x77, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0x77, 0x77, 0x78, 0xff, 0xff, 0xff, +0x87, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0xff, 0xff, 0xfa, 0xaa, 0xaa, 0xaf, 0xff, 0xff, 0xff, 0xff, 0x00, 0x0f, +0x00, 0x8f, 0x00, 0xff, 0x87, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0x77, 0x77, 0x77, 0x7f, 0xff, 0xff, 0xff, 0xf8, 0x77, 0x77, 0x77, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0x77, 0x77, +0x78, 0xff, 0xff, 0xff, 0xff, 0x88, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0xff, 0xff, 0xfa, 0xaa, 0xaa, 0xaf, 0xff, 0xff, +0xff, 0xff, 0x70, 0x08, 0x00, 0x88, 0x00, 0xff, 0x87, 0x77, 0x77, 0x77, 0x88, 0x88, 0x77, 0x77, 0x77, 0x78, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0x77, 0x77, 0x77, 0x7f, 0xff, 0xff, 0xff, 0xf8, 0x77, 0x77, 0x77, 0x8f, 0xff, 0xff, 0xff, 0xff, +0xff, 0x87, 0x77, 0x77, 0x78, 0xff, 0xff, 0xff, 0xff, 0xff, 0x88, 0x77, 0x77, 0x77, 0x77, 0x77, 0xff, 0xff, 0xfa, 0xaa, +0xaa, 0xaf, 0xff, 0xff, 0xff, 0xff, 0x70, 0x00, 0x00, 0x70, 0x07, 0xff, 0x87, 0x77, 0x77, 0x77, 0xff, 0xff, 0x77, 0x77, +0x77, 0x77, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x77, 0x77, 0x77, 0x7f, 0xff, 0xff, 0xff, 0xf8, 0x77, 0x77, 0x77, 0x7f, +0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0x77, 0x77, 0x78, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x77, 0x77, 0x77, 0x77, +0xff, 0xff, 0xfa, 0xaa, 0xaa, 0xaf, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x7f, 0xff, 0x87, 0x77, 0x77, 0x77, +0xff, 0xff, 0xf7, 0x77, 0x77, 0x77, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x77, 0x77, 0x77, 0x7f, 0xff, 0xff, 0xff, 0xff, +0x77, 0x77, 0x77, 0x78, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x77, 0x77, 0x77, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0x87, 0x77, 0x77, 0x77, 0xff, 0xff, 0xfa, 0xaa, 0xaa, 0xaf, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0xff, 0xff, +0x87, 0x77, 0x77, 0x77, 0xff, 0xff, 0xf8, 0x77, 0x77, 0x77, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x77, 0x77, 0x77, 0x7f, +0xff, 0xff, 0xff, 0xff, 0x77, 0x77, 0x77, 0x77, 0xff, 0xff, 0xff, 0xff, 0xf7, 0x77, 0x77, 0x77, 0x8f, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0x87, 0x77, 0x77, 0x77, 0xff, 0xff, 0xfa, 0xaa, 0xaa, 0xaf, 0xff, 0xff, 0xff, 0xff, 0x87, 0x88, +0x88, 0x8f, 0xff, 0xff, 0x87, 0x77, 0x77, 0x77, 0xff, 0xff, 0xff, 0x77, 0x77, 0x77, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, +0x77, 0x77, 0x77, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x77, 0x77, 0x77, 0x77, 0xff, 0xff, 0xff, 0xff, 0x87, 0x77, 0x77, 0x77, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0x77, 0x77, 0x77, 0xff, 0xff, 0xfa, 0xaa, 0xaa, 0xaf, 0xff, 0xff, +0xff, 0xff, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0x87, 0x77, 0x77, 0x77, 0xff, 0xff, 0xff, 0x87, 0x77, 0x77, 0x7f, 0xff, +0xff, 0xff, 0xff, 0xff, 0x77, 0x77, 0x77, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x87, 0x77, 0x77, 0x77, 0x8f, 0xff, 0xff, 0xff, +0x77, 0x77, 0x77, 0x77, 0xff, 0xff, 0xf7, 0x88, 0xff, 0xff, 0xff, 0xff, 0x87, 0x77, 0x77, 0x77, 0xff, 0xff, 0xfa, 0xaa, +0xaa, 0xaf, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0xff, 0xff, 0xff, 0xff, 0x87, 0x77, 0x77, 0x77, 0xff, 0xff, 0xff, 0xf7, +0x77, 0x77, 0x78, 0xff, 0xff, 0xff, 0xff, 0xff, 0x77, 0x77, 0x77, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x77, 0x77, 0x77, +0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0xff, 0xff, 0x87, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, +0xff, 0xff, 0xfa, 0xaa, 0xaa, 0xaf, 0xff, 0xff, 0xff, 0xff, 0xf7, 0x00, 0x88, 0x88, 0x88, 0xff, 0x87, 0x77, 0x77, 0x77, +0xff, 0xff, 0xff, 0xf8, 0x77, 0x77, 0x77, 0xff, 0xff, 0xff, 0xff, 0xff, 0x77, 0x77, 0x77, 0x7f, 0xff, 0xff, 0xff, 0xff, +0xff, 0x87, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x8f, 0xff, 0xff, 0x87, 0x77, 0x77, 0x77, 0x77, 0x77, +0x77, 0x77, 0x77, 0x7f, 0xff, 0xff, 0xfa, 0xaa, 0xaa, 0xaf, 0xff, 0xff, 0xff, 0xff, 0x70, 0x00, 0x00, 0x00, 0x00, 0xff, +0x87, 0x77, 0x77, 0x77, 0xff, 0xff, 0xff, 0xf8, 0x77, 0x77, 0x77, 0x8f, 0xff, 0xff, 0xff, 0xff, 0x77, 0x77, 0x77, 0x7f, +0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x78, 0xff, 0xff, 0xff, 0x87, 0x77, +0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0xff, 0xff, 0xff, 0xfa, 0xaa, 0xaa, 0xaf, 0xff, 0xff, 0xff, 0xff, 0x70, 0x00, +0x00, 0x00, 0x00, 0xff, 0x87, 0x77, 0x77, 0x77, 0xff, 0xff, 0xff, 0xff, 0x77, 0x77, 0x77, 0x7f, 0xff, 0xff, 0xff, 0xff, +0x77, 0x77, 0x77, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x8f, 0xff, +0xff, 0xff, 0x87, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x8f, 0xff, 0xff, 0xff, 0xfa, 0xaa, 0xaa, 0xaf, 0xff, 0xff, +0xff, 0xff, 0x70, 0x00, 0x00, 0x00, 0x07, 0xff, 0x88, 0x88, 0x88, 0x88, 0xff, 0xff, 0xff, 0xff, 0x88, 0x88, 0x88, 0x88, +0xff, 0xff, 0xff, 0xff, 0x88, 0x88, 0x88, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x87, 0x77, 0x77, 0x77, +0x88, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x88, 0x77, 0x77, 0x77, 0x77, 0x88, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xfa, 0xaa, +0xaa, 0xaf, 0xff, 0xff, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xfa, 0xaa, 0xaa, 0xaf, 0xff, 0xff, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa, 0xaa, 0xaa, 0xaf, 0xff, 0xff, 0x00, 0x0f, 0x70, 0x08, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa, 0xaa, 0xaa, 0xaf, 0xff, 0xff, 0x00, 0x07, 0x70, 0x07, +0x88, 0x88, 0x88, 0xff, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, +0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, +0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0xff, 0xff, 0xfa, 0xaa, 0xaa, 0xaf, 0xff, 0xff, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfa, 0xaa, +0xaa, 0xaf, 0xff, 0xff, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xff, 0xff, 0xfa, 0xaa, 0xaa, 0xaf, 0xff, 0xff, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x70, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfa, 0xaa, 0xaa, 0xaf, 0xff, 0xff, 0xff, 0xff, 0x70, 0x08, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa, 0xaa, 0xaa, 0xaf, 0xff, 0xff, 0xff, 0xff, 0x70, 0x08, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa, 0xaa, 0xaa, 0xaf, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa, 0xaa, +0xaa, 0xaf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xfa, 0xaa, 0xaa, 0xaa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, +0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, +0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, +0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x0a, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, +0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, +0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, +0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xa0, 0x00, 0xaa, 0xaa, 0xaa, +0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, +0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, +0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, +0x00 }; + +const unsigned char pucGrLibBitmap[] = +{ + IMAGE_FMT_4BPP_COMP, + 124, 0, + 49, 0, + + 15, + 0x00, 0x00, 0x00, + 0x00, 0x0c, 0x00, + 0x20, 0x44, 0x20, + 0x00, 0x75, 0x00, + 0x69, 0x69, 0x69, + 0x00, 0xc2, 0x00, + 0x00, 0xd2, 0x00, + 0x38, 0xb6, 0x38, + 0x00, 0xea, 0x00, + 0x00, 0xf2, 0x00, + 0xaa, 0xb2, 0xaa, + 0x65, 0xff, 0x65, + 0x69, 0xff, 0x69, + 0x6d, 0xff, 0x6d, + 0x71, 0xff, 0x71, + 0xff, 0xff, 0xff, + + 0x03, 0x21, 0x33, 0x53, 0x33, 0x33, 0x33, 0xe9, 0xd4, 0xf8, 0xa7, 0x5f, + 0x17, 0x07, 0x06, 0x35, 0x33, 0x12, 0x03, 0x23, 0x96, 0x68, 0x88, 0x88, + 0x88, 0xe9, 0xd4, 0xf8, 0xa7, 0x5f, 0x17, 0x07, 0x06, 0x86, 0x69, 0x32, + 0x03, 0x29, 0x66, 0x65, 0x66, 0x66, 0x66, 0xe9, 0xd4, 0xf8, 0xa7, 0x5f, + 0x17, 0x07, 0x06, 0x56, 0x66, 0x92, 0x07, 0x78, 0x63, 0x11, 0x11, 0x11, + 0xe9, 0xd4, 0xa7, 0xf0, 0x5f, 0x17, 0x07, 0x07, 0x11, 0x36, 0x87, 0x78, + 0x0f, 0x63, 0x00, 0x00, 0x00, 0xe9, 0xd4, 0xa7, 0x5f, 0xe0, 0x17, 0x07, + 0x07, 0x00, 0x36, 0x87, 0x78, 0x63, 0xfe, 0x07, 0x07, 0x77, 0x2f, 0x07, + 0x07, 0x02, 0x36, 0x1e, 0x87, 0x78, 0x63, 0x07, 0x07, 0x77, 0x2f, 0x00, + 0x10, 0x01, 0x22, 0x20, 0x07, 0x00, 0x00, 0x22, 0x21, 0x84, 0x03, 0x36, + 0x87, 0x78, 0x63, 0x02, 0x02, 0xaa, 0x01, 0xa2, 0x22, 0x20, 0x02, 0x77, + 0x77, 0x77, 0xe9, 0x3a, 0x22, 0x22, 0x7a, 0xa4, 0x71, 0x20, 0x0a, 0x27, + 0xb8, 0x29, 0x72, 0xb2, 0x9e, 0x93, 0x36, 0x87, 0x78, 0x40, 0x63, 0x62, + 0x2a, 0xff, 0xf2, 0xaa, 0x40, 0x07, 0x08, 0xad, 0xdd, 0xdd, 0xdd, 0xe9, + 0xd7, 0x72, 0x00, 0x40, 0x00, 0xa6, 0xdd, 0xda, 0x70, 0x00, 0x00, 0x02, + 0x00, 0x77, 0xdd, 0xdc, 0xcc, 0xcd, 0xde, 0xc7, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x27, 0xde, 0xdc, 0x08, 0xcc, 0xcc, 0xdd, 0xea, 0x99, + 0x36, 0x87, 0x78, 0x40, 0x63, 0x69, 0x02, 0xaf, 0xaa, 0xf2, 0x2f, 0xa0, + 0x04, 0x02, 0xdb, 0xbb, 0xbb, 0xbb, 0xe9, 0xbc, 0xe7, 0x10, 0x20, 0x00, + 0x07, 0xa5, 0xbb, 0xbd, 0x70, 0x00, 0x10, 0x00, 0x27, 0xec, 0x3b, 0xcd, + 0xd7, 0x00, 0x00, 0x80, 0x9f, 0xbd, 0x20, 0x00, 0x00, 0x36, 0x87, 0x78, + 0x40, 0x63, 0x69, 0x02, 0xfa, 0x2a, 0xf2, 0x2f, 0xa0, 0x31, 0x02, 0xdb, + 0x43, 0x31, 0x42, 0x00, 0x07, 0xa7, 0x0a, 0x70, 0x00, 0x02, 0xdd, 0x41, + 0xcc, 0x21, 0xce, 0x04, 0x70, 0x00, 0x00, 0x02, 0x7d, 0x39, 0xbc, 0xcb, + 0x00, 0xbb, 0xbd, 0x20, 0x00, 0x00, 0x36, 0x87, 0x78, 0x20, 0x63, 0x00, + 0x69, 0xfa, 0x0a, 0xf2, 0x2f, 0xa0, 0x01, 0x02, 0xdb, 0xbb, 0xbb, 0xdd, + 0xdd, 0xdc, 0x11, 0x08, 0xe7, 0x00, 0x07, 0xad, 0xbb, 0xcd, 0xdd, 0xda, + 0x09, 0x70, 0x00, 0x2d, 0xcb, 0x41, 0xcc, 0xdd, 0xd1, 0x04, 0xe7, 0x00, + 0x00, 0x07, 0xeb, 0x51, 0xdc, 0xcd, 0x00, 0xdd, 0xdd, 0x20, 0x00, 0x00, + 0x36, 0x87, 0x78, 0x00, 0x63, 0x00, 0x00, 0x00, 0x02, 0xfa, 0x2a, 0xf2, + 0x00, 0xaf, 0xa0, 0x02, 0xdb, 0xbb, 0xbd, 0x72, 0x22, 0x00, 0x77, 0xdc, + 0xbb, 0xbb, 0xc7, 0x20, 0x07, 0x77, 0x04, 0x77, 0x77, 0xcb, 0xbb, 0xbc, + 0xd1, 0x20, 0x01, 0x28, 0x7d, 0xbb, 0x42, 0x27, 0x41, 0xcd, 0x20, 0x00, + 0x40, 0x27, 0x51, 0x72, 0x22, 0x22, 0x27, 0x7c, 0x20, 0x00, 0x00, 0x00, + 0x36, 0x87, 0x78, 0x63, 0x00, 0x00, 0x00, 0x00, 0x02, 0xaf, 0xaa, 0xfa, + 0xff, 0x20, 0x02, 0x10, 0xdb, 0xbb, 0xbe, 0x61, 0x2d, 0xbb, 0xbb, 0xcc, + 0xa8, 0x29, 0x00, 0x89, 0xbd, 0xc3, 0xeb, 0xbb, 0xbb, 0x00, 0xd7, 0x10, + 0x00, 0x00, 0x2c, 0xcb, 0xbb, 0xbd, 0x58, 0x70, 0x12, 0xc7, 0x13, 0x29, + 0x36, 0x87, 0x78, 0x40, 0x63, 0xa9, 0x00, 0xaf, 0xff, 0xff, 0xfa, 0x20, + 0x08, 0x02, 0xdb, 0xbb, 0xbd, 0x39, 0x07, 0xdb, 0xbb, 0x72, 0xcc, 0x03, + 0x8c, 0x82, 0xbd, 0x70, 0x84, 0xbc, 0x03, 0xd2, 0x00, 0x2d, 0xbb, 0xbb, + 0xd7, 0x19, 0x01, 0x02, 0x00, 0x00, 0x36, 0x87, 0x78, 0x63, 0xa2, 0x0a, + 0x10, 0xaf, 0xff, 0xa2, 0x0a, 0xbd, 0x20, 0x00, 0x00, 0x0c, 0x07, 0xdb, + 0xbb, 0xc7, 0xc9, 0x8e, 0x00, 0x2c, 0x40, 0xcb, 0xc4, 0x00, 0x7c, 0xbb, + 0xbb, 0xe7, 0x00, 0x06, 0x2d, 0xbb, 0xbb, 0xc7, 0x10, 0x92, 0x31, 0x36, + 0x10, 0x87, 0x78, 0x63, 0xab, 0x22, 0x22, 0x00, 0x00, 0x00, 0x02, 0xdb, + 0xbb, 0xbd, 0x20, 0x00, 0x00, 0x07, 0x18, 0xcb, 0xbb, 0xd7, 0x0a, 0x8d, + 0x00, 0x2d, 0xbb, 0x23, 0xbb, 0xc7, 0x82, 0x00, 0x2e, 0xbb, 0x39, 0x91, + 0x20, 0xbd, 0x72, 0x8b, 0x00, 0x00, 0x36, 0x87, 0x78, 0x48, 0x63, 0x33, + 0x02, 0x20, 0xe1, 0xdb, 0xbb, 0xbd, 0x01, 0x20, 0x00, 0x02, 0x7d, 0xbb, + 0xbb, 0xe2, 0x6b, 0x94, 0x8b, 0x00, 0x00, 0x81, 0xd7, 0x82, 0x00, 0x2d, + 0x00, 0xbb, 0xbb, 0xc7, 0x20, 0x2c, 0xcb, 0xbb, 0xbb, 0x10, 0xdd, 0x77, + 0x22, 0x7b, 0x36, 0x87, 0x78, 0x63, 0x80, 0x32, 0x02, 0xaa, 0xf2, 0x22, + 0x20, 0x02, 0xdb, 0x00, 0xbb, 0xbc, 0x77, 0x77, 0x77, 0xdb, 0xbb, 0xce, + 0x42, 0x71, 0x63, 0xdb, 0xbb, 0xbd, 0x20, 0x19, 0x7d, 0x10, 0xbb, 0xbb, + 0xd2, 0x82, 0x00, 0x27, 0xcb, 0xbb, 0x00, 0xc7, 0x20, 0x07, 0xeb, 0xbb, + 0xbb, 0xbb, 0xcd, 0x21, 0xd7, 0x72, 0x72, 0x36, 0x87, 0x78, 0x63, 0x32, + 0x01, 0x4f, 0xff, 0xf2, 0xaf, 0xa0, 0x02, 0xdb, 0x41, 0x03, 0xdd, 0xdc, + 0xbb, 0xbc, 0xd7, 0x20, 0x22, 0x89, 0x42, 0xbd, 0xba, 0x7d, 0xbb, 0xbb, + 0xd2, 0x82, 0x00, 0x02, 0x27, 0xcb, 0xbb, 0xcc, 0x20, 0x02, 0x89, 0xbb, + 0x08, 0xbb, 0xbc, 0xdd, 0x72, 0x31, 0x36, 0x87, 0x78, 0x40, 0x63, 0x31, + 0x02, 0xaf, 0xaa, 0xf2, 0x2f, 0xa0, 0x21, 0x02, 0xdb, 0x3a, 0xbb, 0xbb, + 0xc7, 0x20, 0x31, 0x88, 0x59, 0xdb, 0xbb, 0xbd, 0xb2, 0x7d, 0xbb, 0xbb, + 0x40, 0xd2, 0x7b, 0x27, 0xcb, 0xbb, 0xcc, 0x20, 0x00, 0x00, 0x27, 0xec, + 0xbb, 0xbb, 0xbb, 0xbb, 0xbc, 0xe7, 0x84, 0x29, 0x36, 0x87, 0x78, 0x63, + 0x31, 0x02, 0xfa, 0x02, 0x0a, 0xf2, 0x2f, 0xa0, 0x02, 0xdb, 0x42, 0xbb, + 0x31, 0xbb, 0xc7, 0x39, 0x5a, 0xdb, 0xbb, 0xbd, 0xb2, 0x08, 0x7d, 0xbb, + 0xbb, 0xd2, 0x7b, 0x27, 0xcb, 0xbb, 0x00, 0xcc, 0x20, 0x00, 0x02, 0x77, + 0xed, 0xcb, 0xbb, 0x00, 0xbb, 0xbb, 0xbd, 0x71, 0x00, 0x00, 0x36, 0x87, + 0x20, 0x78, 0x63, 0x31, 0x02, 0xfa, 0x0a, 0xf2, 0x2f, 0x00, 0xa0, 0x02, + 0xdb, 0xbb, 0xbb, 0xcd, 0xdd, 0xcb, 0x18, 0xbb, 0xbc, 0xe2, 0x69, 0x59, + 0xdb, 0xbb, 0xbd, 0x42, 0x20, 0x19, 0x7d, 0xbb, 0xbb, 0xd2, 0x7b, 0x27, + 0x10, 0xcb, 0xbb, 0xcb, 0x79, 0x02, 0x27, 0x7d, 0xdc, 0x00, 0xbb, 0xbb, + 0xbb, 0xe2, 0x00, 0x00, 0x36, 0x87, 0x20, 0x78, 0x63, 0x31, 0x02, 0xfa, + 0x2a, 0xf2, 0xaf, 0x00, 0xa0, 0x02, 0xdb, 0xbb, 0xbd, 0x72, 0x27, 0x4c, + 0x1d, 0xbb, 0xbb, 0xd7, 0x69, 0x59, 0x89, 0x20, 0x19, 0x42, 0x7d, 0x7e, + 0x2c, 0xbb, 0xbb, 0xc7, 0x7a, 0x00, 0x10, 0x22, 0x7c, 0xcb, 0x63, 0x36, + 0x87, 0x78, 0x63, 0x80, 0x31, 0x02, 0xaf, 0xfa, 0xff, 0xff, 0x20, 0x02, + 0x00, 0xdb, 0xbb, 0xbd, 0x20, 0x00, 0x2c, 0xcb, 0xbb, 0x28, 0xcb, 0x20, + 0x61, 0x00, 0x8c, 0x00, 0x00, 0x2d, 0x12, 0xbb, 0xbb, 0xd7, 0x82, 0x00, + 0x2e, 0xbe, 0x00, 0x21, 0x02, 0x7c, 0x63, 0x36, 0x87, 0x78, 0x63, 0x32, + 0x00, 0x2f, 0xff, 0xff, 0xfa, 0x00, 0x02, 0xdb, 0xbb, 0x00, 0xbd, 0x20, + 0x00, 0x07, 0xdb, 0xbb, 0xbe, 0x20, 0xc2, 0x62, 0x8c, 0x00, 0x00, 0x2c, + 0xcb, 0xc4, 0x00, 0x0c, 0x7d, 0xbb, 0xbb, 0xe7, 0x3a, 0x19, 0x2d, 0xbb, + 0x00, 0xbb, 0xc7, 0x00, 0x00, 0x36, 0x87, 0x78, 0x63, 0x80, 0x3a, 0x02, + 0xaa, 0xaa, 0x40, 0x00, 0x02, 0xdb, 0x00, 0xbb, 0xbd, 0x20, 0x00, 0x02, + 0xcc, 0xbb, 0xbd, 0x63, 0x70, 0x63, 0x8b, 0x00, 0x00, 0x07, 0x49, 0x7a, + 0x98, 0x09, 0xbb, 0xd2, 0x3a, 0x19, 0x2d, 0xbb, 0xbb, 0x01, 0xd7, 0x00, + 0x00, 0x36, 0x87, 0x78, 0x63, 0x3a, 0x14, 0xaa, 0x22, 0x20, 0x0b, 0xbd, + 0xc9, 0x7d, 0xbb, 0x30, 0xbb, 0xd2, 0x61, 0x8e, 0x00, 0x02, 0xeb, 0xbb, + 0x20, 0xbb, 0xd7, 0x79, 0x27, 0xcb, 0xbb, 0xbd, 0x70, 0x24, 0x00, 0x02, + 0x6a, 0x00, 0x7d, 0x6b, 0x36, 0x87, 0x24, 0x78, 0x63, 0x39, 0x02, 0xff, + 0x62, 0x02, 0xdb, 0x21, 0xbb, 0xbd, 0x21, 0x2e, 0xbb, 0xbb, 0xe7, 0x61, + 0x80, 0x8e, 0x00, 0x02, 0x7d, 0xbb, 0xbb, 0xbd, 0x72, 0x00, 0x22, 0x27, + 0xcc, 0xbb, 0xbb, 0xcd, 0x20, 0x00, 0x08, 0x07, 0xe7, 0x72, 0x22, 0xa3, + 0xe2, 0x00, 0x00, 0x00, 0x36, 0x87, 0x78, 0x63, 0x00, 0x00, 0x00, 0x02, + 0x20, 0xaf, 0xa0, 0xd2, 0xdb, 0xbb, 0xbd, 0x20, 0x00, 0x03, 0x00, 0x2b, + 0xcb, 0xbb, 0xc7, 0x10, 0x8f, 0x11, 0x01, 0x2d, 0xcb, 0xbb, 0xbb, 0xdd, + 0xb7, 0xcd, 0xd1, 0x00, 0xe7, 0x00, 0x00, 0x07, 0xdc, 0xdd, 0xcb, 0x7b, + 0x00, 0xdd, 0xcb, 0xbb, 0xbc, 0x72, 0x00, 0x00, 0x36, 0x10, 0x87, 0x78, + 0x63, 0x01, 0x00, 0x2a, 0xfa, 0x42, 0x01, 0x22, 0x20, 0x02, 0xdb, 0xbb, + 0xbd, 0x20, 0x01, 0xb0, 0xcc, 0x00, 0x8d, 0xb9, 0xec, 0xbb, 0xbb, 0xbb, + 0x00, 0xcc, 0xcb, 0xbb, 0xbb, 0xbe, 0x71, 0x00, 0x00, 0x05, 0x27, 0xcb, + 0xbb, 0xcc, 0xcc, 0x81, 0xce, 0x29, 0x08, 0x36, 0x87, 0x78, 0x63, 0x02, + 0xaa, 0xff, 0xff, 0x02, 0xff, 0xa0, 0x02, 0xdb, 0xbb, 0xbd, 0x61, 0x02, + 0x0e, 0xeb, 0xbb, 0xbd, 0x70, 0x5a, 0x8c, 0x09, 0x27, 0x00, 0xec, 0xbb, + 0xbb, 0xbb, 0xbb, 0xbb, 0xbd, 0xd7, 0x54, 0x10, 0xa1, 0xcb, 0xa4, 0xd2, + 0x31, 0x36, 0x87, 0x20, 0x78, 0x63, 0x01, 0x02, 0xff, 0xff, 0xff, 0xff, + 0x02, 0xa0, 0x07, 0xad, 0xdd, 0xda, 0x20, 0x99, 0xde, 0x1c, 0xdd, 0xde, + 0xc2, 0x21, 0x8d, 0x0a, 0x7c, 0xed, 0x04, 0xcc, 0xcc, 0xcc, 0xde, 0xd7, + 0x92, 0x2c, 0xed, 0x40, 0xdc, 0xa7, 0x36, 0x87, 0x78, 0x63, 0x00, 0x02, + 0x00, 0x22, 0x02, 0xaa, 0xaa, 0xaa, 0xaa, 0x20, 0x02, 0x1b, 0x77, 0x77, + 0x77, 0x5a, 0xc9, 0x72, 0x21, 0x8e, 0x88, 0xaa, 0x27, 0x77, 0x7b, 0x9d, + 0x12, 0x27, 0x77, 0x20, 0x77, 0xb7, 0x3d, 0x36, 0x87, 0x78, 0x63, 0x00, + 0x3e, 0x02, 0xaa, 0x43, 0x22, 0xc6, 0x87, 0x3e, 0x12, 0x21, 0x22, 0x22, + 0x06, 0x01, 0x22, 0x22, 0x21, 0x04, 0x00, 0x36, 0x87, 0x78, 0x63, 0x00, + 0x02, 0xfa, 0x22, 0x3f, 0xaa, 0x20, 0x26, 0xc6, 0x87, 0x3f, 0x07, 0x07, + 0x00, 0x36, 0x87, 0x78, 0x63, 0x00, 0x02, 0xfa, 0x02, 0x7e, 0xff, 0x07, + 0x07, 0x77, 0x2f, 0x07, 0x06, 0x36, 0x00, 0x87, 0x78, 0x63, 0x00, 0x02, + 0xff, 0xaa, 0xfa, 0x07, 0x44, 0x44, 0x44, 0x20, 0x02, 0xd9, 0xc1, 0xd4, + 0xf0, 0xa7, 0x5f, 0x17, 0x04, 0x42, 0x00, 0x00, 0x36, 0x00, 0x87, 0x78, + 0x63, 0x00, 0x02, 0xff, 0xff, 0xff, 0x9f, 0xe9, 0xa0, 0x0a, 0xc4, 0x94, + 0xa7, 0x5f, 0x17, 0x80, 0x04, 0xfa, 0x20, 0x00, 0x36, 0x87, 0x78, 0x63, + 0x13, 0x00, 0x00, 0xaf, 0x03, 0xa0, 0x0a, 0x07, 0xbf, 0xe0, 0x77, 0x2f, + 0x07, 0xfa, 0x20, 0x00, 0x36, 0x87, 0x00, 0x78, 0x63, 0x00, 0x00, 0x02, + 0xaa, 0xfa, 0xaa, 0x0f, 0xaa, 0xaa, 0x20, 0x02, 0xd9, 0xc1, 0xd4, 0xa7, + 0xe0, 0x5f, 0x17, 0x05, 0x00, 0x00, 0x36, 0x87, 0x78, 0x03, 0x63, 0x00, + 0x00, 0x00, 0x02, 0xff, 0xd9, 0xc1, 0xfc, 0xd4, 0xa7, 0x5f, 0x17, 0x07, + 0x03, 0x36, 0x87, 0x23, 0x78, 0x63, 0x01, 0x02, 0x44, 0x20, 0x07, 0x07, + 0xf0, 0x77, 0x2f, 0x07, 0x05, 0x36, 0x87, 0x78, 0x63, 0xfe, 0x07, 0x07, + 0x77, 0x2f, 0x07, 0x07, 0x02, 0x36, 0x1f, 0x87, 0x78, 0x63, 0x07, 0x07, + 0x77, 0x2f, 0x07, 0xc0, 0x07, 0x02, 0x36, 0x87, 0x78, 0x63, 0x11, 0x11, + 0x7f, 0x11, 0xe9, 0xd4, 0xa7, 0x5f, 0x17, 0x07, 0x07, 0x00, 0x11, 0x36, + 0x87, 0x29, 0x66, 0x55, 0x55, 0x55, 0xfe, 0xe9, 0xd4, 0xa7, 0x5f, 0x17, + 0x07, 0x07, 0x55, 0x00, 0x66, 0x92, 0x23, 0x96, 0x68, 0x88, 0x88, 0x88, + 0xfe, 0xe9, 0xd4, 0xa7, 0x5f, 0x17, 0x07, 0x06, 0x86, 0x01, 0x69, 0x32, + 0x21, 0x33, 0x55, 0x55, 0x55, 0xe9, 0xfc, 0xd4, 0xa7, 0x5f, 0x17, 0x07, + 0x07, 0x55, 0x33, 0x00, 0x12, +}; + + +#endif diff --git a/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/LocalDemoFiles/osram128x64x4.c b/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/LocalDemoFiles/osram128x64x4.c new file mode 100644 index 000000000..6a72285ac --- /dev/null +++ b/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/LocalDemoFiles/osram128x64x4.c @@ -0,0 +1,933 @@ +//***************************************************************************** +// +// osram128x64x4.c - Driver for the OSRAM 128x64x4 graphical OLED display. +// +// Copyright (c) 2006-2007 Luminary Micro, Inc. All rights reserved. +// +// Software License Agreement +// +// Luminary Micro, Inc. (LMI) is supplying this software for use solely and +// exclusively on LMI's microcontroller products. +// +// The software is owned by LMI and/or its suppliers, and is protected under +// applicable copyright laws. All rights are reserved. Any use in violation +// of the foregoing restrictions may subject the user to criminal sanctions +// under applicable laws, as well as to civil liability for the breach of the +// terms and conditions of this license. +// +// THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED +// OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. +// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR +// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 1408 of the Stellaris Peripheral Driver Library. +// +//***************************************************************************** + +//***************************************************************************** +// +//! \addtogroup ek_lm3sx965_api +//! @{ +// +//***************************************************************************** + +#include "hw_ssi.h" +#include "hw_memmap.h" +#include "hw_sysctl.h" +#include "hw_types.h" +#include "debug.h" +#include "gpio.h" +#include "ssi.h" +#include "sysctl.h" +#include "osram128x64x4.h" + +//***************************************************************************** +// +// Flag to indicate if SSI port is enabled for OSRAM usage. +// +//***************************************************************************** +static volatile tBoolean g_bSSIEnabled = false; + +//***************************************************************************** +// +// Define the OSRAM 128x64x4 Remap Setting(s). This will be used in +// several places in the code to switch between vertical and horizontal +// address incrementing. +// +// The Remap Command (0xA0) takes one 8-bit parameter. The parameter is +// defined as follows. +// +// Bit 7: Reserved +// Bit 6: Disable(0)/Enable(1) COM Split Odd Even +// When enabled, the COM signals are split Odd on one side, even on +// the other. Otherwise, they are split 0-39 on one side, 40-79 on +// the other. +// Bit 5: Reserved +// Bit 4: Disable(0)/Enable(1) COM Remap +// When Enabled, ROW 0-79 map to COM 79-0 (i.e. reverse row order) +// Bit 3: Reserved +// Bit 2: Horizontal(0)/Vertical(1) Address Increment +// When set, data RAM address will increment along the column rather +// than along the row. +// Bit 1: Disable(0)/Enable(1) Nibble Remap +// When enabled, the upper and lower nibbles in the DATA bus for access +// to the data RAM are swapped. +// Bit 0: Disable(0)/Enable(1) Column Address Remap +// When enabled, DATA RAM columns 0-63 are remapped to Segment Columns +// 127-0. +// +//***************************************************************************** +#define OSRAM_INIT_REMAP 0x52 +#define OSRAM_INIT_OFFSET 0x4C +static const unsigned char g_pucOSRAM128x64x4VerticalInc[] = { 0xA0, 0x56 }; +static const unsigned char g_pucOSRAM128x64x4HorizontalInc[] = { 0xA0, 0x52 }; + +//***************************************************************************** +// +// A 5x7 font (in a 6x8 cell, where the sixth column is omitted from this +// table) for displaying text on the OLED display. The data is organized as +// bytes from the left column to the right column, with each byte containing +// the top row in the LSB and the bottom row in the MSB. +// +// Note: This is the same font data that is used in the EK-LM3S811 +// osram96x16x1 driver. The single bit-per-pixel is expaned in the StringDraw +// function to the appropriate four bit-per-pixel gray scale format. +// +//***************************************************************************** +static const unsigned char g_pucFont[96][5] = +{ + { 0x00, 0x00, 0x00, 0x00, 0x00 }, // " " + { 0x00, 0x00, 0x4f, 0x00, 0x00 }, // ! + { 0x00, 0x07, 0x00, 0x07, 0x00 }, // " + { 0x14, 0x7f, 0x14, 0x7f, 0x14 }, // # + { 0x24, 0x2a, 0x7f, 0x2a, 0x12 }, // $ + { 0x23, 0x13, 0x08, 0x64, 0x62 }, // % + { 0x36, 0x49, 0x55, 0x22, 0x50 }, // & + { 0x00, 0x05, 0x03, 0x00, 0x00 }, // ' + { 0x00, 0x1c, 0x22, 0x41, 0x00 }, // ( + { 0x00, 0x41, 0x22, 0x1c, 0x00 }, // ) + { 0x14, 0x08, 0x3e, 0x08, 0x14 }, // * + { 0x08, 0x08, 0x3e, 0x08, 0x08 }, // + + { 0x00, 0x50, 0x30, 0x00, 0x00 }, // , + { 0x08, 0x08, 0x08, 0x08, 0x08 }, // - + { 0x00, 0x60, 0x60, 0x00, 0x00 }, // . + { 0x20, 0x10, 0x08, 0x04, 0x02 }, // / + { 0x3e, 0x51, 0x49, 0x45, 0x3e }, // 0 + { 0x00, 0x42, 0x7f, 0x40, 0x00 }, // 1 + { 0x42, 0x61, 0x51, 0x49, 0x46 }, // 2 + { 0x21, 0x41, 0x45, 0x4b, 0x31 }, // 3 + { 0x18, 0x14, 0x12, 0x7f, 0x10 }, // 4 + { 0x27, 0x45, 0x45, 0x45, 0x39 }, // 5 + { 0x3c, 0x4a, 0x49, 0x49, 0x30 }, // 6 + { 0x01, 0x71, 0x09, 0x05, 0x03 }, // 7 + { 0x36, 0x49, 0x49, 0x49, 0x36 }, // 8 + { 0x06, 0x49, 0x49, 0x29, 0x1e }, // 9 + { 0x00, 0x36, 0x36, 0x00, 0x00 }, // : + { 0x00, 0x56, 0x36, 0x00, 0x00 }, // ; + { 0x08, 0x14, 0x22, 0x41, 0x00 }, // < + { 0x14, 0x14, 0x14, 0x14, 0x14 }, // = + { 0x00, 0x41, 0x22, 0x14, 0x08 }, // > + { 0x02, 0x01, 0x51, 0x09, 0x06 }, // ? + { 0x32, 0x49, 0x79, 0x41, 0x3e }, // @ + { 0x7e, 0x11, 0x11, 0x11, 0x7e }, // A + { 0x7f, 0x49, 0x49, 0x49, 0x36 }, // B + { 0x3e, 0x41, 0x41, 0x41, 0x22 }, // C + { 0x7f, 0x41, 0x41, 0x22, 0x1c }, // D + { 0x7f, 0x49, 0x49, 0x49, 0x41 }, // E + { 0x7f, 0x09, 0x09, 0x09, 0x01 }, // F + { 0x3e, 0x41, 0x49, 0x49, 0x7a }, // G + { 0x7f, 0x08, 0x08, 0x08, 0x7f }, // H + { 0x00, 0x41, 0x7f, 0x41, 0x00 }, // I + { 0x20, 0x40, 0x41, 0x3f, 0x01 }, // J + { 0x7f, 0x08, 0x14, 0x22, 0x41 }, // K + { 0x7f, 0x40, 0x40, 0x40, 0x40 }, // L + { 0x7f, 0x02, 0x0c, 0x02, 0x7f }, // M + { 0x7f, 0x04, 0x08, 0x10, 0x7f }, // N + { 0x3e, 0x41, 0x41, 0x41, 0x3e }, // O + { 0x7f, 0x09, 0x09, 0x09, 0x06 }, // P + { 0x3e, 0x41, 0x51, 0x21, 0x5e }, // Q + { 0x7f, 0x09, 0x19, 0x29, 0x46 }, // R + { 0x46, 0x49, 0x49, 0x49, 0x31 }, // S + { 0x01, 0x01, 0x7f, 0x01, 0x01 }, // T + { 0x3f, 0x40, 0x40, 0x40, 0x3f }, // U + { 0x1f, 0x20, 0x40, 0x20, 0x1f }, // V + { 0x3f, 0x40, 0x38, 0x40, 0x3f }, // W + { 0x63, 0x14, 0x08, 0x14, 0x63 }, // X + { 0x07, 0x08, 0x70, 0x08, 0x07 }, // Y + { 0x61, 0x51, 0x49, 0x45, 0x43 }, // Z + { 0x00, 0x7f, 0x41, 0x41, 0x00 }, // [ + { 0x02, 0x04, 0x08, 0x10, 0x20 }, // "\" + { 0x00, 0x41, 0x41, 0x7f, 0x00 }, // ] + { 0x04, 0x02, 0x01, 0x02, 0x04 }, // ^ + { 0x40, 0x40, 0x40, 0x40, 0x40 }, // _ + { 0x00, 0x01, 0x02, 0x04, 0x00 }, // ` + { 0x20, 0x54, 0x54, 0x54, 0x78 }, // a + { 0x7f, 0x48, 0x44, 0x44, 0x38 }, // b + { 0x38, 0x44, 0x44, 0x44, 0x20 }, // c + { 0x38, 0x44, 0x44, 0x48, 0x7f }, // d + { 0x38, 0x54, 0x54, 0x54, 0x18 }, // e + { 0x08, 0x7e, 0x09, 0x01, 0x02 }, // f + { 0x0c, 0x52, 0x52, 0x52, 0x3e }, // g + { 0x7f, 0x08, 0x04, 0x04, 0x78 }, // h + { 0x00, 0x44, 0x7d, 0x40, 0x00 }, // i + { 0x20, 0x40, 0x44, 0x3d, 0x00 }, // j + { 0x7f, 0x10, 0x28, 0x44, 0x00 }, // k + { 0x00, 0x41, 0x7f, 0x40, 0x00 }, // l + { 0x7c, 0x04, 0x18, 0x04, 0x78 }, // m + { 0x7c, 0x08, 0x04, 0x04, 0x78 }, // n + { 0x38, 0x44, 0x44, 0x44, 0x38 }, // o + { 0x7c, 0x14, 0x14, 0x14, 0x08 }, // p + { 0x08, 0x14, 0x14, 0x18, 0x7c }, // q + { 0x7c, 0x08, 0x04, 0x04, 0x08 }, // r + { 0x48, 0x54, 0x54, 0x54, 0x20 }, // s + { 0x04, 0x3f, 0x44, 0x40, 0x20 }, // t + { 0x3c, 0x40, 0x40, 0x20, 0x7c }, // u + { 0x1c, 0x20, 0x40, 0x20, 0x1c }, // v + { 0x3c, 0x40, 0x30, 0x40, 0x3c }, // w + { 0x44, 0x28, 0x10, 0x28, 0x44 }, // x + { 0x0c, 0x50, 0x50, 0x50, 0x3c }, // y + { 0x44, 0x64, 0x54, 0x4c, 0x44 }, // z + { 0x00, 0x08, 0x36, 0x41, 0x00 }, // { + { 0x00, 0x00, 0x7f, 0x00, 0x00 }, // | + { 0x00, 0x41, 0x36, 0x08, 0x00 }, // } + { 0x02, 0x01, 0x02, 0x04, 0x02 }, // ~ + { 0x02, 0x01, 0x02, 0x04, 0x02 }, // ~ +}; + +//***************************************************************************** +// +// The sequence of commands used to initialize the SSD0303 controller. Each +// command is described as follows: there is a byte specifying the number of +// bytes in the command sequence, followed by that many bytes of command data. +// Note: This initialization sequence is derived from OSRAM App Note AN018. +// +//***************************************************************************** +static const unsigned char g_pucOSRAM128x64x4Init[] = +{ + // + // Column Address + // + 4, 0x15, 0, 63, 0xe3, + + // + // Row Address + // + 4, 0x75, 0, 63, 0xe3, + + // + // Contrast Control + // + 3, 0x81, 50, 0xe3, + + // + // Half Current Range + // + 2, 0x85, 0xe3, + + // + // Display Re-map + // + 3, 0xA0, OSRAM_INIT_REMAP, 0xe3, + + // + // Display Start Line + // + 3, 0xA1, 0, 0xe3, + + // + // Display Offset + // + 3, 0xA2, OSRAM_INIT_OFFSET, 0xe3, + + // + // Display Mode Normal + // + 2, 0xA4, 0xe3, + + // + // Multiplex Ratio + // + 3, 0xA8, 63, 0xe3, + + // + // Phase Length + // + 3, 0xB1, 0x22, 0xe3, + + // + // Row Period + // + 3, 0xB2, 70, 0xe3, + + // + // Display Clock Divide + // + 3, 0xB3, 0xF1, 0xe3, + + // + // VSL + // + 3, 0xBF, 0x0D, 0xe3, + + // + // VCOMH + // + 3, 0xBE, 0x02, 0xe3, + + // + // VP + // + 3, 0xBC, 0x10, 0xe3, + + // + // Gamma + // + 10, 0xB8, 0x01, 0x11, 0x22, 0x32, 0x43, 0x54, 0x65, 0x76, 0xe3, + + // + // Set DC-DC + 3, 0xAD, 0x03, 0xe3, + + // + // Display ON/OFF + // + 2, 0xAF, 0xe3, +}; + +//***************************************************************************** +// +//! \internal +//! +//! Write a sequence of command bytes to the SSD0323 controller. +//! +//! The data is written in a polled fashion; this function will not return +//! until the entire byte sequence has been written to the controller. +//! +//! \return None. +// +//***************************************************************************** +static void +OSRAMWriteCommand(const unsigned char *pucBuffer, unsigned long ulCount) +{ + unsigned long ulTemp; + + // + // Return iff SSI port is not enabled for OSRAM. + // + if(!g_bSSIEnabled) + { + return; + } + + // + // Clear the command/control bit to enable command mode. + // + GPIOPinWrite(GPIO_PORTC_BASE, GPIO_PIN_7, 0); + + // + // Loop while there are more bytes left to be transferred. + // + while(ulCount != 0) + { + // + // Write the next byte to the controller. + // + SSIDataPut(SSI0_BASE, *pucBuffer++); + + // + // Dummy read to drain the fifo and time the GPIO signal. + // + SSIDataGet(SSI0_BASE, &ulTemp); + + // + // Decrement the BYTE counter. + // + ulCount--; + } +} + +//***************************************************************************** +// +//! \internal +//! +//! Write a sequence of data bytes to the SSD0323 controller. +//! +//! The data is written in a polled fashion; this function will not return +//! until the entire byte sequence has been written to the controller. +//! +//! \return None. +// +//***************************************************************************** +static void +OSRAMWriteData(const unsigned char *pucBuffer, unsigned long ulCount) +{ + unsigned long ulTemp; + + // + // Return iff SSI port is not enabled for OSRAM. + // + if(!g_bSSIEnabled) + { + return; + } + + // + // Set the command/control bit to enable data mode. + // + GPIOPinWrite(GPIO_PORTC_BASE, GPIO_PIN_7, GPIO_PIN_7); + + // + // Loop while there are more bytes left to be transferred. + // + while(ulCount != 0) + { + // + // Write the next byte to the controller. + // + SSIDataPut(SSI0_BASE, *pucBuffer++); + + // + // Dummy read to drain the fifo and time the GPIO signal. + // + SSIDataGet(SSI0_BASE, &ulTemp); + + // + // Decrement the BYTE counter. + // + ulCount--; + } +} + +//***************************************************************************** +// +//! Clears the OLED display. +//! +//! This function will clear the display RAM. All pixels in the display will +//! be turned off. +//! +//! This function is contained in osram128x64x4.c, with +//! osram128x64x4.h containing the API definition for use by +//! applications. +//! +//! \return None. +// +//***************************************************************************** +void +OSRAM128x64x4Clear(void) +{ + static const unsigned char pucCommand1[] = { 0x15, 0, 63 }; + static const unsigned char pucCommand2[] = { 0x75, 0, 79 }; + unsigned long ulRow, ulColumn; + static unsigned char pucZeroBuffer[8] = { 0, 0, 0, 0, 0, 0, 0, 0}; + + // + // Set the window to fill the entire display. + // + OSRAMWriteCommand(pucCommand1, sizeof(pucCommand1)); + OSRAMWriteCommand(pucCommand2, sizeof(pucCommand2)); + OSRAMWriteCommand(g_pucOSRAM128x64x4VerticalInc, + sizeof(g_pucOSRAM128x64x4VerticalInc)); + + // + // In vertical address increment mode, loop through each column, filling + // each row with 0. + // + for(ulColumn = 0; ulColumn < (128/2); ulColumn++) + { + // + // 8 rows (bytes) per row of text. + // + for(ulRow = 0; ulRow < 80; ulRow += 8) + { + OSRAMWriteData(pucZeroBuffer, sizeof(pucZeroBuffer)); + } + } +} + +//***************************************************************************** +// +//! Displays a string on the OLED display. +//! +//! \param pcStr is a pointer to the string to display. +//! \param ulX is the horizontal position to display the string, specified in +//! columns from the left edge of the display. +//! \param ulY is the vertical position to display the string, specified in +//! rows from the top edge of the display. +//! \param ucLevel is the 4-bit grey scale value to be used for displayed text. +//! +//! This function will draw a string on the display. Only the ASCII characters +//! between 32 (space) and 126 (tilde) are supported; other characters will +//! result in random data being draw on the display (based on whatever appears +//! before/after the font in memory). The font is mono-spaced, so characters +//! such as "i" and "l" have more white space around them than characters such +//! as "m" or "w". +//! +//! If the drawing of the string reaches the right edge of the display, no more +//! characters will be drawn. Therefore, special care is not required to avoid +//! supplying a string that is "too long" to display. +//! +//! This function is contained in osram128x64x4.c, with +//! osram128x64x4.h containing the API definition for use by +//! applications. +//! +//! \note Because the OLED display packs 2 pixels of data in a single byte, the +//! parameter \e ulX must be an even column number (e.g. 0, 2, 4, etc). +//! +//! \return None. +// +//***************************************************************************** +void +OSRAM128x64x4StringDraw(const char *pcStr, unsigned long ulX, + unsigned long ulY, unsigned char ucLevel) +{ + static unsigned char pucBuffer[8]; + unsigned long ulIdx1, ulIdx2; + unsigned char ucTemp; + + // + // Check the arguments. + // + ASSERT(ulX < 128); + ASSERT((ulX & 1) == 0); + ASSERT(ulY < 64); + ASSERT(ucLevel < 16); + + // + // Setup a window starting at the specified column and row, ending + // at the right edge of the display and 8 rows down (single character row). + // + pucBuffer[0] = 0x15; + pucBuffer[1] = ulX / 2; + pucBuffer[2] = 63; + OSRAMWriteCommand(pucBuffer, 3); + pucBuffer[0] = 0x75; + pucBuffer[1] = ulY; + pucBuffer[2] = ulY + 7; + OSRAMWriteCommand(pucBuffer, 3); + OSRAMWriteCommand(g_pucOSRAM128x64x4VerticalInc, + sizeof(g_pucOSRAM128x64x4VerticalInc)); + + // + // Loop while there are more characters in the string. + // + while(*pcStr != 0) + { + // + // Get a working copy of the current character and convert to an + // index into the character bit-map array. + // + ucTemp = *pcStr; + ucTemp &= 0x7F; + if(ucTemp < ' ') + { + ucTemp = ' '; + } + else + { + ucTemp -= ' '; + } + + // + // Build and display the character buffer. + // + for(ulIdx1 = 0; ulIdx1 < 3; ulIdx1++) + { + // + // Convert two columns of 1-bit font data into a single data + // byte column of 4-bit font data. + // + for(ulIdx2 = 0; ulIdx2 < 8; ulIdx2++) + { + pucBuffer[ulIdx2] = 0; + if(g_pucFont[ucTemp][ulIdx1*2] & (1 << ulIdx2)) + { + pucBuffer[ulIdx2] = ((ucLevel << 4) & 0xf0); + } + if((ulIdx1 < 2) && + (g_pucFont[ucTemp][ulIdx1*2+1] & (1 << ulIdx2))) + { + pucBuffer[ulIdx2] |= ((ucLevel << 0) & 0x0f); + } + } + + // + // If there is room, dump the single data byte column to the + // display. Otherwise, bail out. + // + if(ulX < 126) + { + OSRAMWriteData(pucBuffer, 8); + ulX += 2; + } + else + { + return; + } + } + + // + // Advance to the next character. + // + pcStr++; + } +} + +//***************************************************************************** +// +//! Displays an image on the OLED display. +//! +//! \param pucImage is a pointer to the image data. +//! \param ulX is the horizontal position to display this image, specified in +//! columns from the left edge of the display. +//! \param ulY is the vertical position to display this image, specified in +//! rows from the top of the display. +//! \param ulWidth is the width of the image, specified in columns. +//! \param ulHeight is the height of the image, specified in rows. +//! +//! This function will display a bitmap graphic on the display. Because of the +//! format of the display RAM, the starting column (/e ulX) and the number of +//! columns (/e ulWidth) must be an integer multiple of two. +//! +//! The image data is organized with the first row of image data appearing left +//! to right, followed immediately by the second row of image data. Each byte +//! contains the data for two columns in the current row, with the leftmost +//! column being contained in bits 7:4 and the rightmost column being contained +//! in bits 3:0. +//! +//! For example, an image six columns wide and seven scan lines tall would +//! be arranged as follows (showing how the twenty one bytes of the image would +//! appear on the display): +//! +//! \verbatim +//! +-------------------+-------------------+-------------------+ +//! | Byte 0 | Byte 1 | Byte 2 | +//! +---------+---------+---------+---------+---------+---------+ +//! | 7 6 5 4 | 3 2 1 0 | 7 6 5 4 | 3 2 1 0 | 7 6 5 4 | 3 2 1 0 | +//! +---------+---------+---------+---------+---------+---------+ +//! | Byte 3 | Byte 4 | Byte 5 | +//! +---------+---------+---------+---------+---------+---------+ +//! | 7 6 5 4 | 3 2 1 0 | 7 6 5 4 | 3 2 1 0 | 7 6 5 4 | 3 2 1 0 | +//! +---------+---------+---------+---------+---------+---------+ +//! | Byte 6 | Byte 7 | Byte 8 | +//! +---------+---------+---------+---------+---------+---------+ +//! | 7 6 5 4 | 3 2 1 0 | 7 6 5 4 | 3 2 1 0 | 7 6 5 4 | 3 2 1 0 | +//! +---------+---------+---------+---------+---------+---------+ +//! | Byte 9 | Byte 10 | Byte 11 | +//! +---------+---------+---------+---------+---------+---------+ +//! | 7 6 5 4 | 3 2 1 0 | 7 6 5 4 | 3 2 1 0 | 7 6 5 4 | 3 2 1 0 | +//! +---------+---------+---------+---------+---------+---------+ +//! | Byte 12 | Byte 13 | Byte 14 | +//! +---------+---------+---------+--3------+---------+---------+ +//! | 7 6 5 4 | 3 2 1 0 | 7 6 5 4 | 3 2 1 0 | 7 6 5 4 | 3 2 1 0 | +//! +---------+---------+---------+---------+---------+---------+ +//! | Byte 15 | Byte 16 | Byte 17 | +//! +---------+---------+---------+---------+---------+---------+ +//! | 7 6 5 4 | 3 2 1 0 | 7 6 5 4 | 3 2 1 0 | 7 6 5 4 | 3 2 1 0 | +//! +---------+---------+---------+---------+---------+---------+ +//! | Byte 18 | Byte 19 | Byte 20 | +//! +---------+---------+---------+---------+---------+---------+ +//! | 7 6 5 4 | 3 2 1 0 | 7 6 5 4 | 3 2 1 0 | 7 6 5 4 | 3 2 1 0 | +//! +---------+---------+---------+---------+---------+---------+ +//! \endverbatim +//! +//! This function is contained in osram128x64x4.c, with +//! osram128x64x4.h containing the API definition for use by` +//! applications. +//! +//! \return None. +// +//***************************************************************************** +void +OSRAM128x64x4ImageDraw(const unsigned char *pucImage, unsigned long ulX, + unsigned long ulY, unsigned long ulWidth, + unsigned long ulHeight) +{ + static unsigned char pucBuffer[8]; + + // + // Check the arguments. + // + ASSERT(ulX < 128); + ASSERT((ulX & 1) == 0); + ASSERT(ulY < 64); + ASSERT((ulX + ulWidth) <= 128); + ASSERT((ulY + ulHeight) <= 64); + ASSERT((ulWidth & 1) == 0); + + // + // Setup a window starting at the specified column and row, and ending + // at the column + width and row+height. + // + pucBuffer[0] = 0x15; + pucBuffer[1] = ulX / 2; + pucBuffer[2] = (ulX + ulWidth - 2) / 2; + OSRAMWriteCommand(pucBuffer, 3); + pucBuffer[0] = 0x75; + pucBuffer[1] = ulY; + pucBuffer[2] = ulY + ulHeight - 1; + OSRAMWriteCommand(pucBuffer, 3); + OSRAMWriteCommand(g_pucOSRAM128x64x4HorizontalInc, + sizeof(g_pucOSRAM128x64x4HorizontalInc)); + + // + // Loop while there are more rows to display. + // + while(ulHeight--) + { + // + // Write this row of image data. + // + OSRAMWriteData(pucImage, (ulWidth / 2)); + + // + // Advance to the next row of the image. + // + pucImage += (ulWidth / 2); + } +} + +//***************************************************************************** +// +//! Enable the SSI component of the OLED display driver. +//! +//! \param ulFrequency specifies the SSI Clock Frequency to be used. +//! +//! This function initializes the SSI interface to the OLED display. +//! +//! This function is contained in osram128x64x4.c, with +//! osram128x64x4.h containing the API definition for use by +//! applications. +//! +//! \return None. +// +//***************************************************************************** +void +OSRAM128x64x4Enable(unsigned long ulFrequency) +{ + unsigned long ulTemp; + + // + // Disable the SSI port. + // + SSIDisable(SSI0_BASE); + + // + // Configure the SSI0 port for master mode. + // + SSIConfig(SSI0_BASE, SSI_FRF_MOTO_MODE_2, SSI_MODE_MASTER, ulFrequency, 8); + + // + // (Re)Enable SSI control of the FSS pin. + // + GPIOPinTypeSSI(GPIO_PORTA_BASE, GPIO_PIN_3); + GPIOPadConfigSet(GPIO_PORTA_BASE, GPIO_PIN_3, GPIO_STRENGTH_8MA, + GPIO_PIN_TYPE_STD_WPU); + + // + // Enable the SSI port. + // + SSIEnable(SSI0_BASE); + + // + // Drain the receive fifo. + // + while(SSIDataNonBlockingGet(SSI0_BASE, &ulTemp) != 0) + { + } + + // + // Indicate that the OSRAM driver can use the SSI Port. + // + g_bSSIEnabled = true; +} + +//***************************************************************************** +// +//! Enable the SSI component of the OLED display driver. +//! +//! \param ulFrequency specifies the SSI Clock Frequency to be used. +//! +//! This function initializes the SSI interface to the OLED display. +//! +//! This function is contained in osram128x64x4.c, with +//! osram128x64x4.h containing the API definition for use by +//! applications. +//! +//! \return None. +// +//***************************************************************************** +void +OSRAM128x64x4Disable(void) +{ + unsigned long ulTemp; + + // + // Indicate that the OSRAM driver can no longer use the SSI Port. + // + g_bSSIEnabled = false; + + // + // Drain the receive fifo. + // + while(SSIDataNonBlockingGet(SSI0_BASE, &ulTemp) != 0) + { + } + + // + // Disable the SSI port. + // + SSIDisable(SSI0_BASE); + + // + // Disable SSI control of the FSS pin. + // + GPIODirModeSet(GPIO_PORTA_BASE, GPIO_PIN_3, GPIO_DIR_MODE_OUT); + GPIOPadConfigSet(GPIO_PORTA_BASE, GPIO_PIN_3, GPIO_STRENGTH_8MA, + GPIO_PIN_TYPE_STD_WPU); + GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_3, GPIO_PIN_3); + +} + +//***************************************************************************** +// +//! Initialize the OLED display. +//! +//! \param ulFrequency specifies the SSI Clock Frequency to be used. +//! +//! This function initializes the SSI interface to the OLED display and +//! configures the SSD0323 controller on the panel. +//! +//! This function is contained in osram128x64x4.c, with +//! osram128x64x4.h containing the API definition for use by +//! applications. +//! +//! \return None. +// +//***************************************************************************** +void +OSRAM128x64x4Init(unsigned long ulFrequency) +{ + unsigned long ulIdx; + + // + // Enable the SSI0 and GPIO port blocks as they are needed by this driver. + // + SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI0); + SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); + SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC); + + // + // Configure the SSI0CLK and SSIOTX pins for SSI operation. + // + GPIOPinTypeSSI(GPIO_PORTA_BASE, GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_5); + GPIOPadConfigSet(GPIO_PORTA_BASE, GPIO_PIN_2, GPIO_STRENGTH_8MA, + GPIO_PIN_TYPE_STD_WPU); + GPIOPadConfigSet(GPIO_PORTA_BASE, GPIO_PIN_3, GPIO_STRENGTH_8MA, + GPIO_PIN_TYPE_STD_WPU); + GPIOPadConfigSet(GPIO_PORTA_BASE, GPIO_PIN_5, GPIO_STRENGTH_8MA, + GPIO_PIN_TYPE_STD_WPU); + + // + // Configure the PC7 pin as a D/Cn signal for OLED device. + // + GPIODirModeSet(GPIO_PORTC_BASE, GPIO_PIN_7, GPIO_DIR_MODE_OUT); + GPIOPadConfigSet(GPIO_PORTC_BASE, GPIO_PIN_7, GPIO_STRENGTH_8MA, + GPIO_PIN_TYPE_STD); + GPIOPinWrite(GPIO_PORTC_BASE, GPIO_PIN_7, GPIO_PIN_7); + + // + // Configure and enable the SSI0 port for master mode. + // + OSRAM128x64x4Enable(ulFrequency); + + // + // Clear the frame buffer. + // + OSRAM128x64x4Clear(); + + // + // Initialize the SSD0323 controller. Loop through the initialization + // sequence array, sending each command "string" to the controller. + // + for(ulIdx = 0; ulIdx < sizeof(g_pucOSRAM128x64x4Init); + ulIdx += g_pucOSRAM128x64x4Init[ulIdx] + 1) + { + // + // Send this command. + // + OSRAMWriteCommand(g_pucOSRAM128x64x4Init + ulIdx + 1, + g_pucOSRAM128x64x4Init[ulIdx] - 1); + } +} + +//***************************************************************************** +// +//! Turns on the OLED display. +//! +//! This function will turn on the OLED display, causing it to display the +//! contents of its internal frame buffer. +//! +//! This function is contained in osram128x64x4.c, with +//! osram128x64x4.h containing the API definition for use by +//! applications. +//! +//! \return None. +// +//***************************************************************************** +void +OSRAM128x64x4DisplayOn(void) +{ + unsigned long ulIdx; + + // + // Initialize the SSD0323 controller. Loop through the initialization + // sequence array, sending each command "string" to the controller. + // + for(ulIdx = 0; ulIdx < sizeof(g_pucOSRAM128x64x4Init); + ulIdx += g_pucOSRAM128x64x4Init[ulIdx] + 1) + { + // + // Send this command. + // + OSRAMWriteCommand(g_pucOSRAM128x64x4Init + ulIdx + 1, + g_pucOSRAM128x64x4Init[ulIdx] - 1); + } +} + +//***************************************************************************** +// +//! Turns off the OLED display. +//! +//! This function will turn off the OLED display. This will stop the scanning +//! of the panel and turn off the on-chip DC-DC converter, preventing damage to +//! the panel due to burn-in (it has similar characters to a CRT in this +//! respect). +//! +//! This function is contained in osram128x64x4.c, with +//! osram128x64x4.h containing the API definition for use by +//! applications. +//! +//! \return None. +// +//***************************************************************************** +void +OSRAM128x64x4DisplayOff(void) +{ + static const unsigned char pucCommand1[] = + { + 0xAE, 0xAD, 0x02 + }; + + // + // Turn off the DC-DC converter and the display. + // + OSRAMWriteCommand(pucCommand1, sizeof(pucCommand1)); +} + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** diff --git a/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/LocalDemoFiles/osram128x64x4.h b/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/LocalDemoFiles/osram128x64x4.h new file mode 100644 index 000000000..0055a5366 --- /dev/null +++ b/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/LocalDemoFiles/osram128x64x4.h @@ -0,0 +1,63 @@ +//***************************************************************************** +// +// osram128x64x4.h - Prototypes for the driver for the OSRAM 128x64x4 graphical +// OLED display. +// +// Copyright (c) 2006-2007 Luminary Micro, Inc. All rights reserved. +// +// Software License Agreement +// +// Luminary Micro, Inc. (LMI) is supplying this software for use solely and +// exclusively on LMI's microcontroller products. +// +// The software is owned by LMI and/or its suppliers, and is protected under +// applicable copyright laws. All rights are reserved. Any use in violation +// of the foregoing restrictions may subject the user to criminal sanctions +// under applicable laws, as well as to civil liability for the breach of the +// terms and conditions of this license. +// +// THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED +// OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. +// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR +// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 1408 of the Stellaris Peripheral Driver Library. +// +//***************************************************************************** + +#ifndef __OSRAM128X64X4_H__ +#define __OSRAM128X64X4_H__ + +//***************************************************************************** +// +// Prototypes for the driver APIs. +// +//***************************************************************************** +extern void OSRAM128x64x4Clear(void); +extern void OSRAM128x64x4StringDraw(const char *pcStr, + unsigned long ulX, + unsigned long ulY, + unsigned char ucLevel); +extern void OSRAM128x64x4ImageDraw(const unsigned char *pucImage, + unsigned long ulX, + unsigned long ulY, + unsigned long ulWidth, + unsigned long ulHeight); +extern void OSRAM128x64x4Init(unsigned long ulFrequency); +extern void OSRAM128x64x4Enable(unsigned long ulFrequency); +extern void OSRAM128x64x4Disable(void); +extern void OSRAM128x64x4DisplayOn(void); +extern void OSRAM128x64x4DisplayOff(void); + +//***************************************************************************** +// +// The following macro(s) map old names for the OSRAM functions to the new +// names. In new code, the new names should be used in favor of the old names. +// +//***************************************************************************** +#ifndef DEPRECATED +#define OSRAM128x64x1InitSSI OSRAM128x64x4Enable +#endif + +#endif // __OSRAM128X64X4_H__ diff --git a/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/LocalDemoFiles/printf-stdarg.c b/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/LocalDemoFiles/printf-stdarg.c new file mode 100644 index 000000000..59b0293bf --- /dev/null +++ b/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/LocalDemoFiles/printf-stdarg.c @@ -0,0 +1,312 @@ +/* + Copyright 2001, 2002 Georges Menie (www.menie.org) + stdarg version contributed by Christian Ettinger + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* + putchar is the only external dependency for this file, + if you have a working putchar, leave it commented out. + If not, uncomment the define below and + replace outbyte(c) by your own function call. + +*/ + +#define putchar(c) c + +#include + +static int tiny_print( char **out, const char *format, va_list args, unsigned int buflen ); + +static void printchar(char **str, int c, char *buflimit) +{ + //extern int putchar(int c); + + if (str) { + if( buflimit == ( char * ) 0 ) { + /* Limit of buffer not known, write charater to buffer. */ + **str = (char)c; + ++(*str); + } + else if( ( ( unsigned long ) *str ) < ( ( unsigned long ) buflimit ) ) { + /* Withing known limit of buffer, write character. */ + **str = (char)c; + ++(*str); + } + } + else + { + (void)putchar(c); + } +} + +#define PAD_RIGHT 1 +#define PAD_ZERO 2 + +static int prints(char **out, const char *string, int width, int pad, char *buflimit) +{ + register int pc = 0, padchar = ' '; + + if (width > 0) { + register int len = 0; + register const char *ptr; + for (ptr = string; *ptr; ++ptr) ++len; + if (len >= width) width = 0; + else width -= len; + if (pad & PAD_ZERO) padchar = '0'; + } + if (!(pad & PAD_RIGHT)) { + for ( ; width > 0; --width) { + printchar (out, padchar, buflimit); + ++pc; + } + } + for ( ; *string ; ++string) { + printchar (out, *string, buflimit); + ++pc; + } + for ( ; width > 0; --width) { + printchar (out, padchar, buflimit); + ++pc; + } + + return pc; +} + +/* the following should be enough for 32 bit int */ +#define PRINT_BUF_LEN 12 + +static int printi(char **out, int i, int b, int sg, int width, int pad, int letbase, char *buflimit) +{ + char print_buf[PRINT_BUF_LEN]; + register char *s; + register int t, neg = 0, pc = 0; + register unsigned int u = (unsigned int)i; + + if (i == 0) { + print_buf[0] = '0'; + print_buf[1] = '\0'; + return prints (out, print_buf, width, pad, buflimit); + } + + if (sg && b == 10 && i < 0) { + neg = 1; + u = (unsigned int)-i; + } + + s = print_buf + PRINT_BUF_LEN-1; + *s = '\0'; + + while (u) { + t = (unsigned int)u % b; + if( t >= 10 ) + t += letbase - '0' - 10; + *--s = (char)(t + '0'); + u /= b; + } + + if (neg) { + if( width && (pad & PAD_ZERO) ) { + printchar (out, '-', buflimit); + ++pc; + --width; + } + else { + *--s = '-'; + } + } + + return pc + prints (out, s, width, pad, buflimit); +} + +static int tiny_print( char **out, const char *format, va_list args, unsigned int buflen ) +{ + register int width, pad; + register int pc = 0; + char scr[2], *buflimit; + + if( buflen == 0 ){ + buflimit = ( char * ) 0; + } + else { + /* Calculate the last valid buffer space, leaving space for the NULL + terminator. */ + buflimit = ( *out ) + ( buflen - 1 ); + } + + for (; *format != 0; ++format) { + if (*format == '%') { + ++format; + width = pad = 0; + if (*format == '\0') break; + if (*format == '%') goto out; + if (*format == '-') { + ++format; + pad = PAD_RIGHT; + } + while (*format == '0') { + ++format; + pad |= PAD_ZERO; + } + for ( ; *format >= '0' && *format <= '9'; ++format) { + width *= 10; + width += *format - '0'; + } + if( *format == 's' ) { + register char *s = (char *)va_arg( args, int ); + pc += prints (out, s?s:"(null)", width, pad, buflimit); + continue; + } + if( *format == 'd' ) { + pc += printi (out, va_arg( args, int ), 10, 1, width, pad, 'a', buflimit); + continue; + } + if( *format == 'x' ) { + pc += printi (out, va_arg( args, int ), 16, 0, width, pad, 'a', buflimit); + continue; + } + if( *format == 'X' ) { + pc += printi (out, va_arg( args, int ), 16, 0, width, pad, 'A', buflimit); + continue; + } + if( *format == 'u' ) { + pc += printi (out, va_arg( args, int ), 10, 0, width, pad, 'a', buflimit); + continue; + } + if( *format == 'c' ) { + /* char are converted to int then pushed on the stack */ + scr[0] = (char)va_arg( args, int ); + scr[1] = '\0'; + pc += prints (out, scr, width, pad, buflimit); + continue; + } + } + else { + out: + printchar (out, *format, buflimit); + ++pc; + } + } + if (out) **out = '\0'; + va_end( args ); + return pc; +} + +int printf(const char *format, ...) +{ + va_list args; + + va_start( args, format ); + return tiny_print( 0, format, args, 0 ); +} + +int sprintf(char *out, const char *format, ...) +{ + va_list args; + + va_start( args, format ); + return tiny_print( &out, format, args, 0 ); +} + + +int snprintf( char *buf, unsigned int count, const char *format, ... ) +{ + va_list args; + + ( void ) count; + + va_start( args, format ); + return tiny_print( &buf, format, args, count ); +} + + +#ifdef TEST_PRINTF +int main(void) +{ + char *ptr = "Hello world!"; + char *np = 0; + int i = 5; + unsigned int bs = sizeof(int)*8; + int mi; + char buf[80]; + + mi = (1 << (bs-1)) + 1; + printf("%s\n", ptr); + printf("printf test\n"); + printf("%s is null pointer\n", np); + printf("%d = 5\n", i); + printf("%d = - max int\n", mi); + printf("char %c = 'a'\n", 'a'); + printf("hex %x = ff\n", 0xff); + printf("hex %02x = 00\n", 0); + printf("signed %d = unsigned %u = hex %x\n", -3, -3, -3); + printf("%d %s(s)%", 0, "message"); + printf("\n"); + printf("%d %s(s) with %%\n", 0, "message"); + sprintf(buf, "justif: \"%-10s\"\n", "left"); printf("%s", buf); + sprintf(buf, "justif: \"%10s\"\n", "right"); printf("%s", buf); + sprintf(buf, " 3: %04d zero padded\n", 3); printf("%s", buf); + sprintf(buf, " 3: %-4d left justif.\n", 3); printf("%s", buf); + sprintf(buf, " 3: %4d right justif.\n", 3); printf("%s", buf); + sprintf(buf, "-3: %04d zero padded\n", -3); printf("%s", buf); + sprintf(buf, "-3: %-4d left justif.\n", -3); printf("%s", buf); + sprintf(buf, "-3: %4d right justif.\n", -3); printf("%s", buf); + + return 0; +} + +/* + * if you compile this file with + * gcc -Wall $(YOUR_C_OPTIONS) -DTEST_PRINTF -c printf.c + * you will get a normal warning: + * printf.c:214: warning: spurious trailing `%' in format + * this line is testing an invalid % at the end of the format string. + * + * this should display (on 32bit int machine) : + * + * Hello world! + * printf test + * (null) is null pointer + * 5 = 5 + * -2147483647 = - max int + * char a = 'a' + * hex ff = ff + * hex 00 = 00 + * signed -3 = unsigned 4294967293 = hex fffffffd + * 0 message(s) + * 0 message(s) with % + * justif: "left " + * justif: " right" + * 3: 0003 zero padded + * 3: 3 left justif. + * 3: 3 right justif. + * -3: -003 zero padded + * -3: -3 left justif. + * -3: -3 right justif. + */ + +#endif + + +/* To keep linker happy. */ +int write( int i, char* c, int n) +{ + (void)i; + (void)n; + (void)c; + return 0; +} + diff --git a/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/LocalDemoFiles/timertest.c b/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/LocalDemoFiles/timertest.c new file mode 100644 index 000000000..5d7a60ce4 --- /dev/null +++ b/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/LocalDemoFiles/timertest.c @@ -0,0 +1,132 @@ +/* + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/* High speed timer test as described in main.c. */ + +/* Scheduler includes. */ +#include "FreeRTOS.h" + +/* Library includes. */ +#include "hw_ints.h" +#include "hw_memmap.h" +#include "hw_types.h" +#include "interrupt.h" +#include "sysctl.h" +#include "lmi_timer.h" +#include "hw_timer.h" + +/* The set frequency of the interrupt. Deviations from this are measured as +the jitter. */ +#define timerINTERRUPT_FREQUENCY ( 20000UL ) + +/* The expected time between each of the timer interrupts - if the jitter was +zero. */ +#define timerEXPECTED_DIFFERENCE_VALUE ( configCPU_CLOCK_HZ / timerINTERRUPT_FREQUENCY ) + +/* The highest available interrupt priority. */ +#define timerHIGHEST_PRIORITY ( 0 ) + +/* Misc defines. */ +#define timerMAX_32BIT_VALUE ( 0xffffffffUL ) +#define timerTIMER_1_COUNT_VALUE ( * ( ( volatile uint32_t * ) ( ( uint32_t ) TIMER1_BASE + 0x48UL ) ) ) + +/*-----------------------------------------------------------*/ + +/* Interrupt handler in which the jitter is measured. */ +void Timer0IntHandler( void ); + +/* Stores the value of the maximum recorded jitter between interrupts. */ +volatile uint32_t ulMaxJitter = 0; + +/*-----------------------------------------------------------*/ + +void vSetupHighFrequencyTimer( void ) +{ +uint32_t ulFrequency; + + /* Timer zero is used to generate the interrupts, and timer 1 is used + to measure the jitter. */ + SysCtlPeripheralEnable( SYSCTL_PERIPH_TIMER0 ); + SysCtlPeripheralEnable( SYSCTL_PERIPH_TIMER1 ); + TimerConfigure( TIMER0_BASE, TIMER_CFG_32_BIT_PER ); + TimerConfigure( TIMER1_BASE, TIMER_CFG_32_BIT_PER ); + + /* Set the timer interrupt to be above the kernel - highest. */ + IntPrioritySet( INT_TIMER0A, timerHIGHEST_PRIORITY ); + + /* Just used to measure time. */ + TimerLoadSet(TIMER1_BASE, TIMER_A, timerMAX_32BIT_VALUE ); + + /* Ensure interrupts do not start until the scheduler is running. */ + portDISABLE_INTERRUPTS(); + + /* The rate at which the timer will interrupt. */ + ulFrequency = configCPU_CLOCK_HZ / timerINTERRUPT_FREQUENCY; + TimerLoadSet( TIMER0_BASE, TIMER_A, ulFrequency ); + IntEnable( INT_TIMER0A ); + TimerIntEnable( TIMER0_BASE, TIMER_TIMA_TIMEOUT ); + + /* Enable both timers. */ + TimerEnable( TIMER0_BASE, TIMER_A ); + TimerEnable( TIMER1_BASE, TIMER_A ); +} +/*-----------------------------------------------------------*/ + +void Timer0IntHandler( void ) +{ +uint32_t ulDifference; +volatile uint32_t ulCurrentCount; +static uint32_t ulMaxDifference = 0, ulLastCount = 0; + + /* We use the timer 1 counter value to measure the clock cycles between + the timer 0 interrupts. */ + ulCurrentCount = timerTIMER_1_COUNT_VALUE; + + TimerIntClear( TIMER0_BASE, TIMER_TIMA_TIMEOUT ); + + if( ulCurrentCount < ulLastCount ) + { + /* How many times has timer 1 counted since the last interrupt? */ + ulDifference = ulLastCount - ulCurrentCount; + + /* Is this the largest difference we have measured yet? */ + if( ulDifference > ulMaxDifference ) + { + ulMaxDifference = ulDifference; + ulMaxJitter = ulMaxDifference - timerEXPECTED_DIFFERENCE_VALUE; + } + } + + ulLastCount = ulCurrentCount; +} + + + + + + + diff --git a/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/RTOSDemo Debug.launch b/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/RTOSDemo Debug.launch new file mode 100644 index 000000000..8833e2ab5 --- /dev/null +++ b/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/RTOSDemo Debug.launch @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/StartQEMU.bat b/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/StartQEMU.bat new file mode 100644 index 000000000..cfd44b480 --- /dev/null +++ b/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/StartQEMU.bat @@ -0,0 +1,2 @@ +qemu-system-arm -machine lm3s6965evb -s -S -kernel ./debug/RTOSDemo.elf + diff --git a/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/Start_QEMU.launch b/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/Start_QEMU.launch new file mode 100644 index 000000000..e4866e50d --- /dev/null +++ b/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/Start_QEMU.launch @@ -0,0 +1,5 @@ + + + + + diff --git a/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/main.c b/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/main.c new file mode 100644 index 000000000..13443156d --- /dev/null +++ b/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/main.c @@ -0,0 +1,470 @@ +/* + * FreeRTOS Kernel V10.3.1 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +/* + * Creates all the demo application tasks, then starts the scheduler. The WEB + * documentation provides more details of the standard demo application tasks. + * In addition to the standard demo tasks, the following tasks and tests are + * defined and/or created within this file: + * + * "OLED" task - the OLED task is a 'gatekeeper' task. It is the only task that + * is permitted to access the display directly. Other tasks wishing to write a + * message to the OLED send the message on a queue to the OLED task instead of + * accessing the OLED themselves. The OLED task just blocks on the queue waiting + * for messages - waking and displaying the messages as they arrive. + * + * "Check" hook - This only executes every five seconds from the tick hook. + * Its main function is to check that all the standard demo tasks are still + * operational. Should any unexpected behaviour within a demo task be discovered + * the tick hook will write an error to the OLED (via the OLED task). If all the + * demo tasks are executing with their expected behaviour then the check task + * writes PASS to the OLED (again via the OLED task), as described above. + * + * Use the following command to start running the application in QEMU, pausing + * to wait for a debugger connection: + * "qemu-system-arm -machine lm3s6965evb -s -S -kernel [pat_to]\RTOSDemo.elf" + * + * To enable FreeRTOS+Trace: + * 1) Add #include "trcRecorder.h" to the bottom of FreeRTOSConfig.h. + * 2) Call vTraceEnable( TRC_START ); at the top of main. + * 3) Ensure the "FreeRTOS+Trace Recorder" folder in the Project Explorer + * window is not excluded from the build. + * + * To retrieve the trace files: + * 1) Use the Memory windows in the Debug perspective to dump RAM from the + * RecorderData variable. + */ + +/************************************************************************* + * Please ensure to read http://www.freertos.org/portlm3sx965.html + * which provides information on configuring and running this demo for the + * various Luminary Micro EKs. + *************************************************************************/ + +/* Standard includes. */ +#include +#include + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "semphr.h" + +/* Hardware library includes. */ +#include "hw_memmap.h" +#include "hw_types.h" +#include "hw_sysctl.h" +#include "hw_uart.h" +#include "sysctl.h" +#include "gpio.h" +#include "grlib.h" +#include "osram128x64x4.h" +#include "uart.h" + +/* Demo app includes. */ +#include "death.h" +#include "blocktim.h" +#include "semtest.h" +#include "bitmap.h" +#include "QPeek.h" +#include "recmutex.h" +#include "QueueSet.h" +#include "EventGroupsDemo.h" +#include "MessageBufferDemo.h" +#include "StreamBufferDemo.h" + +/*-----------------------------------------------------------*/ + +/* The time between cycles of the 'check' functionality (defined within the +tick hook. */ +#define mainCHECK_DELAY ( ( TickType_t ) 5000 / portTICK_PERIOD_MS ) + +/* Task stack sizes. */ +#define mainOLED_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE + 40 ) +#define mainMESSAGE_BUFFER_TASKS_STACK_SIZE ( 100 ) + +/* Task priorities. */ +#define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 ) +#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 ) +#define mainCREATOR_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 ) +#define mainGEN_QUEUE_TASK_PRIORITY ( tskIDLE_PRIORITY ) + +/* The maximum number of message that can be waiting for display at any one +time. */ +#define mainOLED_QUEUE_SIZE ( 3 ) + +/* Dimensions the buffer into which the jitter time is written. */ +#define mainMAX_MSG_LEN 25 + +/* The period of the system clock in nano seconds. This is used to calculate +the jitter time in nano seconds. */ +#define mainNS_PER_CLOCK ( ( uint32_t ) ( ( 1.0 / ( double ) configCPU_CLOCK_HZ ) * 1000000000.0 ) ) + +/* Constants used when writing strings to the display. */ +#define mainCHARACTER_HEIGHT ( 9 ) +#define mainMAX_ROWS_128 ( mainCHARACTER_HEIGHT * 14 ) +#define mainMAX_ROWS_96 ( mainCHARACTER_HEIGHT * 10 ) +#define mainMAX_ROWS_64 ( mainCHARACTER_HEIGHT * 7 ) +#define mainFULL_SCALE ( 15 ) +#define ulSSI_FREQUENCY ( 3500000UL ) + +/*-----------------------------------------------------------*/ + +/* + * The display is written two by more than one task so is controlled by a + * 'gatekeeper' task. This is the only task that is actually permitted to + * access the display directly. Other tasks wanting to display a message send + * the message to the gatekeeper. + */ +static void prvOLEDTask( void *pvParameters ); + +/* + * Configure the hardware for the demo. + */ +static void prvSetupHardware( void ); + +/* + * Configures the high frequency timers - those used to measure the timing + * jitter while the real time kernel is executing. + */ +extern void vSetupHighFrequencyTimer( void ); + +/* + * Hook functions that can get called by the kernel. + */ +void vApplicationStackOverflowHook( TaskHandle_t *pxTask, signed char *pcTaskName ); +void vApplicationTickHook( void ); + +/* + * Basic polling UART write function. + */ +static void prvPrintString( const char * pcString ); + +/*-----------------------------------------------------------*/ + +/* The queue used to send messages to the OLED task. */ +static QueueHandle_t xOLEDQueue; + +/* The welcome text. */ +const char * const pcWelcomeMessage = " www.FreeRTOS.org"; + +/*-----------------------------------------------------------*/ + +/************************************************************************* + * Please ensure to read http://www.freertos.org/portlm3sx965.html + * which provides information on configuring and running this demo for the + * various Luminary Micro EKs. + *************************************************************************/ +int main( void ) +{ + /* Initialise the trace recorder. Use of the trace recorder is optional. + See http://www.FreeRTOS.org/trace for more information and the comments at + the top of this file regarding enabling trace in this demo. + vTraceEnable( TRC_START ); */ + + prvSetupHardware(); + + /* Create the queue used by the OLED task. Messages for display on the OLED + are received via this queue. */ + xOLEDQueue = xQueueCreate( mainOLED_QUEUE_SIZE, sizeof( char * ) ); + + /* Start the standard demo tasks. */ + vStartRecursiveMutexTasks(); + vCreateBlockTimeTasks(); + vStartSemaphoreTasks( mainSEM_TEST_PRIORITY ); + vStartQueuePeekTasks(); + vStartQueueSetTasks(); + vStartEventGroupTasks(); + vStartMessageBufferTasks( mainMESSAGE_BUFFER_TASKS_STACK_SIZE ); + vStartStreamBufferTasks(); + + /* Start the tasks defined within this file/specific to this demo. */ + xTaskCreate( prvOLEDTask, "OLED", mainOLED_TASK_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); + + /* The suicide tasks must be created last as they need to know how many + tasks were running prior to their creation in order to ascertain whether + or not the correct/expected number of tasks are running at any given time. */ + vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY ); + + /* Uncomment the following line to configure the high frequency interrupt + used to measure the interrupt jitter time. + vSetupHighFrequencyTimer(); */ + + /* Start the scheduler. */ + vTaskStartScheduler(); + + /* Will only get here if there was insufficient memory to create the idle + task. */ + for( ;; ); +} +/*-----------------------------------------------------------*/ + +void prvSetupHardware( void ) +{ + /* If running on Rev A2 silicon, turn the LDO voltage up to 2.75V. This is + a workaround to allow the PLL to operate reliably. */ + if( DEVICE_IS_REVA2 ) + { + SysCtlLDOSet( SYSCTL_LDO_2_75V ); + } + + /* Set the clocking to run from the PLL at 50 MHz */ + SysCtlClockSet( SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_8MHZ ); + + /* Initialise the UART - QEMU usage does not seem to require this + initialisation. */ + SysCtlPeripheralEnable( SYSCTL_PERIPH_UART0 ); + UARTEnable( UART0_BASE ); +} +/*-----------------------------------------------------------*/ + +void vApplicationTickHook( void ) +{ +static const char * pcMessage = "PASS"; +static uint32_t ulTicksSinceLastDisplay = 0; +BaseType_t xHigherPriorityTaskWoken = pdFALSE; + + /* Called from every tick interrupt. Have enough ticks passed to make it + time to perform our health status check again? */ + ulTicksSinceLastDisplay++; + if( ulTicksSinceLastDisplay >= mainCHECK_DELAY ) + { + ulTicksSinceLastDisplay = 0; + + /* Has an error been found in any task? */ + if( xAreStreamBufferTasksStillRunning() != pdTRUE ) + { + pcMessage = "ERROR IN STRM"; + } + else if( xAreMessageBufferTasksStillRunning() != pdTRUE ) + { + pcMessage = "ERROR IN MSG"; + } + else if( xIsCreateTaskStillRunning() != pdTRUE ) + { + pcMessage = "ERROR IN CREATE"; + } + else if( xAreBlockTimeTestTasksStillRunning() != pdTRUE ) + { + pcMessage = "ERROR IN BLOCK TIME"; + } + else if( xAreSemaphoreTasksStillRunning() != pdTRUE ) + { + pcMessage = "ERROR IN SEMAPHORE"; + } + else if( xAreQueuePeekTasksStillRunning() != pdTRUE ) + { + pcMessage = "ERROR IN PEEK Q"; + } + else if( xAreRecursiveMutexTasksStillRunning() != pdTRUE ) + { + pcMessage = "ERROR IN REC MUTEX"; + } + else if( xAreQueueSetTasksStillRunning() != pdPASS ) + { + pcMessage = "ERROR IN Q SET"; + } + else if( xAreEventGroupTasksStillRunning() != pdTRUE ) + { + pcMessage = "ERROR IN EVNT GRP"; + } + + /* Send the message to the OLED gatekeeper for display. */ + xHigherPriorityTaskWoken = pdFALSE; + xQueueSendFromISR( xOLEDQueue, &pcMessage, &xHigherPriorityTaskWoken ); + } + + /* Write to a queue that is in use as part of the queue set demo to + demonstrate using queue sets from an ISR. */ + vQueueSetAccessQueueSetFromISR(); + + /* Call the event group ISR tests. */ + vPeriodicEventGroupsProcessing(); + + /* Exercise stream buffers from interrupts. */ + vPeriodicStreamBufferProcessing(); +} +/*-----------------------------------------------------------*/ + +static void prvPrintString( const char * pcString ) +{ + while( *pcString != 0x00 ) + { + UARTCharPut( UART0_BASE, *pcString ); + pcString++; + } +} +/*-----------------------------------------------------------*/ + +void prvOLEDTask( void *pvParameters ) +{ +const char *pcMessage; +uint32_t ulY, ulMaxY; +static char cMessage[ mainMAX_MSG_LEN ]; +const unsigned char *pucImage; + +/* Functions to access the OLED. The one used depends on the dev kit +being used. */ +void ( *vOLEDInit )( uint32_t ) = NULL; +void ( *vOLEDStringDraw )( const char *, uint32_t, uint32_t, unsigned char ) = NULL; +void ( *vOLEDImageDraw )( const unsigned char *, uint32_t, uint32_t, uint32_t, uint32_t ) = NULL; +void ( *vOLEDClear )( void ) = NULL; + + /* Prevent warnings about unused parameters. */ + ( void ) pvParameters; + + /* Map the OLED access functions to the driver functions that are appropriate + for the evaluation kit being used. */ + configASSERT( ( HWREG( SYSCTL_DID1 ) & SYSCTL_DID1_PRTNO_MASK ) == SYSCTL_DID1_PRTNO_6965 ); + vOLEDInit = OSRAM128x64x4Init; + vOLEDStringDraw = OSRAM128x64x4StringDraw; + vOLEDImageDraw = OSRAM128x64x4ImageDraw; + vOLEDClear = OSRAM128x64x4Clear; + ulMaxY = mainMAX_ROWS_64; + pucImage = pucBasicBitmap; + ulY = ulMaxY; + + /* Initialise the OLED and display a startup message. */ + vOLEDInit( ulSSI_FREQUENCY ); + vOLEDStringDraw( "POWERED BY FreeRTOS", 0, 0, mainFULL_SCALE ); + vOLEDImageDraw( pucImage, 0, mainCHARACTER_HEIGHT + 1, bmpBITMAP_WIDTH, bmpBITMAP_HEIGHT ); + + for( ;; ) + { + /* Wait for a message to arrive that requires displaying. */ + xQueueReceive( xOLEDQueue, &pcMessage, portMAX_DELAY ); + + /* Write the message on the next available row. */ + ulY += mainCHARACTER_HEIGHT; + if( ulY >= ulMaxY ) + { + ulY = mainCHARACTER_HEIGHT; + vOLEDClear(); + vOLEDStringDraw( pcWelcomeMessage, 0, 0, mainFULL_SCALE ); + } + + /* Display the message along with the maximum jitter time from the + high priority time test. */ + sprintf( cMessage, "%s %u", pcMessage, ( unsigned int ) xTaskGetTickCount() ); + vOLEDStringDraw( cMessage, 0, ulY, mainFULL_SCALE ); + prvPrintString( cMessage ); + prvPrintString( "\r\n" ); + } +} +/*-----------------------------------------------------------*/ + +volatile signed char *pcOverflowedTask = NULL; /* Prevent task name being optimised away. */ +void vApplicationStackOverflowHook( TaskHandle_t *pxTask, signed char *pcTaskName ) +{ + ( void ) pxTask; + pcOverflowedTask = pcTaskName; + vAssertCalled( __FILE__, __LINE__ ); + for( ;; ); +} +/*-----------------------------------------------------------*/ + +void vAssertCalled( const char *pcFile, uint32_t ulLine ) +{ +volatile uint32_t ulSetTo1InDebuggerToExit = 0; + + taskENTER_CRITICAL(); + { + while( ulSetTo1InDebuggerToExit == 0 ) + { + /* Nothing to do here. Set the loop variable to a non zero value in + the debugger to step out of this function to the point that caused + the assertion. */ + ( void ) pcFile; + ( void ) ulLine; + } + } + taskEXIT_CRITICAL(); +} + +/* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an +implementation of vApplicationGetIdleTaskMemory() to provide the memory that is +used by the Idle task. */ +void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize ) +{ +/* If the buffers to be provided to the Idle task are declared inside this +function then they must be declared static - otherwise they will be allocated on +the stack and so not exists after this function exits. */ +static StaticTask_t xIdleTaskTCB; +static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ]; + + /* Pass out a pointer to the StaticTask_t structure in which the Idle task's + state will be stored. */ + *ppxIdleTaskTCBBuffer = &xIdleTaskTCB; + + /* Pass out the array that will be used as the Idle task's stack. */ + *ppxIdleTaskStackBuffer = uxIdleTaskStack; + + /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer. + Note that, as the array is necessarily of type StackType_t, + configMINIMAL_STACK_SIZE is specified in words, not bytes. */ + *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE; +} +/*-----------------------------------------------------------*/ + +/* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the +application must provide an implementation of vApplicationGetTimerTaskMemory() +to provide the memory that is used by the Timer service task. */ +void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize ) +{ +/* If the buffers to be provided to the Timer task are declared inside this +function then they must be declared static - otherwise they will be allocated on +the stack and so not exists after this function exits. */ +static StaticTask_t xTimerTaskTCB; +static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ]; + + /* Pass out a pointer to the StaticTask_t structure in which the Timer + task's state will be stored. */ + *ppxTimerTaskTCBBuffer = &xTimerTaskTCB; + + /* Pass out the array that will be used as the Timer task's stack. */ + *ppxTimerTaskStackBuffer = uxTimerTaskStack; + + /* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer. + Note that, as the array is necessarily of type StackType_t, + configMINIMAL_STACK_SIZE is specified in words, not bytes. */ + *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; +} +/*-----------------------------------------------------------*/ + +char * _sbrk_r (struct _reent *r, int incr) +{ + /* Just to keep the linker quiet. */ + ( void ) r; + ( void ) incr; + + /* Check this function is never called by forcing an assert() if it is. */ + configASSERT( incr == -1 ); + + return NULL; +} diff --git a/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/standalone.ld b/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/standalone.ld new file mode 100644 index 000000000..26e07b2ee --- /dev/null +++ b/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/standalone.ld @@ -0,0 +1,60 @@ +/****************************************************************************** + * + * standalone.ld - Linker script for applications using startup.c and + * DriverLib. + * + * Copyright (c) 2005-2007 Luminary Micro, Inc. All rights reserved. + * + * Software License Agreement + * + * Luminary Micro, Inc. (LMI) is supplying this software for use solely and + * exclusively on LMI's microcontroller products. + * + * The software is owned by LMI and/or its suppliers, and is protected under + * applicable copyright laws. All rights are reserved. Any use in violation + * of the foregoing restrictions may subject the user to criminal sanctions + * under applicable laws, as well as to civil liability for the breach of the + * terms and conditions of this license. + * + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR + * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + * + * This is part of revision 1392 of the Stellaris Peripheral Driver Library. + * + *****************************************************************************/ + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 256K + SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 64K +} + +SECTIONS +{ + .text : + { + KEEP(*(.isr_vector)) + *(.text*) + *(.rodata*) + _etext = .; + } > FLASH + + .data : AT (ADDR(.text) + SIZEOF(.text)) + { + _data = .; + *(vtable) + *(.data*) + _edata = .; + } > SRAM + + .bss : + { + _bss = .; + *(.bss*) + *(COMMON) + _ebss = .; + } > SRAM +} diff --git a/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/start_quem_and_debug.launch b/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/start_quem_and_debug.launch new file mode 100644 index 000000000..fc9a04a68 --- /dev/null +++ b/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/start_quem_and_debug.launch @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/startup.c b/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/startup.c new file mode 100644 index 000000000..ad2f87391 --- /dev/null +++ b/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/startup.c @@ -0,0 +1,255 @@ +//***************************************************************************** +// +// startup.c - Boot code for Stellaris. +// +// Copyright (c) 2005-2007 Luminary Micro, Inc. All rights reserved. +// +// Software License Agreement +// +// Luminary Micro, Inc. (LMI) is supplying this software for use solely and +// exclusively on LMI's microcontroller products. +// +// The software is owned by LMI and/or its suppliers, and is protected under +// applicable copyright laws. All rights are reserved. Any use in violation +// of the foregoing restrictions may subject the user to criminal sanctions +// under applicable laws, as well as to civil liability for the breach of the +// terms and conditions of this license. +// +// THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED +// OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. +// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR +// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 1392 of the Stellaris Peripheral Driver Library. +// +//***************************************************************************** + +//***************************************************************************** +// +// Forward declaration of the default fault handlers. +// +//***************************************************************************** +void ResetISR(void); +static void NmiSR(void); +static void FaultISR(void); +static void IntDefaultHandler(void); + +//***************************************************************************** +// +// The entry point for the application. +// +//***************************************************************************** +extern int main(void); +extern void xPortPendSVHandler(void); +extern void xPortSysTickHandler(void); +extern void vPortSVCHandler( void ); +extern void Timer0IntHandler( void ); +extern void vT2InterruptHandler( void ); +extern void vT3InterruptHandler( void ); +void vAssertCalled( const char *pcFile, unsigned long ulLine ); + +//***************************************************************************** +// +// Reserve space for the system stack. +// +//***************************************************************************** +#ifndef STACK_SIZE +#define STACK_SIZE 120 +#endif +static unsigned long pulStack[STACK_SIZE]; + +//***************************************************************************** +// +// The minimal vector table for a Cortex-M3. Note that the proper constructs +// must be placed on this to ensure that it ends up at physical address +// 0x0000.0000. +// +//***************************************************************************** +__attribute__ ((section(".isr_vector"))) +void (* const g_pfnVectors[])(void) = +{ + (void (*)(void))((unsigned long)pulStack + sizeof(pulStack)), + // The initial stack pointer + ResetISR, // The reset handler + NmiSR, // The NMI handler + FaultISR, // The hard fault handler + IntDefaultHandler, // The MPU fault handler + IntDefaultHandler, // The bus fault handler + IntDefaultHandler, // The usage fault handler + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + vPortSVCHandler, // SVCall handler + IntDefaultHandler, // Debug monitor handler + 0, // Reserved + xPortPendSVHandler, // The PendSV handler + xPortSysTickHandler, // The SysTick handler + IntDefaultHandler, // GPIO Port A + IntDefaultHandler, // GPIO Port B + IntDefaultHandler, // GPIO Port C + IntDefaultHandler, // GPIO Port D + IntDefaultHandler, // GPIO Port E + IntDefaultHandler, // UART0 Rx and Tx + IntDefaultHandler, // UART1 Rx and Tx + IntDefaultHandler, // SSI Rx and Tx + IntDefaultHandler, // I2C Master and Slave + IntDefaultHandler, // PWM Fault + IntDefaultHandler, // PWM Generator 0 + IntDefaultHandler, // PWM Generator 1 + IntDefaultHandler, // PWM Generator 2 + IntDefaultHandler, // Quadrature Encoder + IntDefaultHandler, // ADC Sequence 0 + IntDefaultHandler, // ADC Sequence 1 + IntDefaultHandler, // ADC Sequence 2 + IntDefaultHandler, // ADC Sequence 3 + IntDefaultHandler, // Watchdog timer + Timer0IntHandler, // Timer 0 subtimer A + IntDefaultHandler, // Timer 0 subtimer B + IntDefaultHandler, // Timer 1 subtimer A + IntDefaultHandler, // Timer 1 subtimer B + vT2InterruptHandler, // Timer 2 subtimer A + IntDefaultHandler, // Timer 2 subtimer B + IntDefaultHandler, // Analog Comparator 0 + IntDefaultHandler, // Analog Comparator 1 + IntDefaultHandler, // Analog Comparator 2 + IntDefaultHandler, // System Control (PLL, OSC, BO) + IntDefaultHandler, // FLASH Control + IntDefaultHandler, // GPIO Port F + IntDefaultHandler, // GPIO Port G + IntDefaultHandler, // GPIO Port H + IntDefaultHandler, // UART2 Rx and Tx + IntDefaultHandler, // SSI1 Rx and Tx + vT3InterruptHandler, // Timer 3 subtimer A + IntDefaultHandler, // Timer 3 subtimer B + IntDefaultHandler, // I2C1 Master and Slave + IntDefaultHandler, // Quadrature Encoder 1 + IntDefaultHandler, // CAN0 + IntDefaultHandler, // CAN1 + 0, // Reserved + IntDefaultHandler, // Ethernet + IntDefaultHandler // Hibernate +}; + +//***************************************************************************** +// +// The following are constructs created by the linker, indicating where the +// the "data" and "bss" segments reside in memory. The initializers for the +// for the "data" segment resides immediately following the "text" segment. +// +//***************************************************************************** +extern unsigned long _etext; +extern unsigned long _data; +extern unsigned long _edata; +extern unsigned long _bss; +extern unsigned long _ebss; + +//***************************************************************************** +// +// This is the code that gets called when the processor first starts execution +// following a reset event. Only the absolutely necessary set is performed, +// after which the application supplied main() routine is called. Any fancy +// actions (such as making decisions based on the reset cause register, and +// resetting the bits in that register) are left solely in the hands of the +// application. +// +//***************************************************************************** +void +ResetISR(void) +{ + register unsigned long *pulSrc, *pulDest; + + // + // Copy the data segment initializers from flash to SRAM. + // + pulSrc = &_etext; + for(pulDest = &_data; pulDest < &_edata; ) + { + *pulDest++ = *pulSrc++; + } + + // + // Zero fill the bss segment. + // + for(pulDest = &_bss; pulDest < &_ebss; ) + { + *pulDest++ = 0; + } + + // + // Call the application's entry point. + // + main(); +} + +//***************************************************************************** +// +// This is the code that gets called when the processor receives a NMI. This +// simply enters an infinite loop, preserving the system state for examination +// by a debugger. +// +//***************************************************************************** +static void +NmiSR(void) +{ + // + // Enter an infinite loop. + // + while(1) + { + vAssertCalled( __FILE__, __LINE__ ); + } +} + +//***************************************************************************** +// +// This is the code that gets called when the processor receives a fault +// interrupt. This simply enters an infinite loop, preserving the system state +// for examination by a debugger. +// +//***************************************************************************** +static void +FaultISR(void) +{ + // + // Enter an infinite loop. + // + while(1) + { + vAssertCalled( __FILE__, __LINE__ ); + } +} + +//***************************************************************************** +// +// This is the code that gets called when the processor receives an unexpected +// interrupt. This simply enters an infinite loop, preserving the system state +// for examination by a debugger. +// +//***************************************************************************** +static void +IntDefaultHandler(void) +{ + // + // Go into an infinite loop. + // + while(1) + { + vAssertCalled( __FILE__, __LINE__ ); + } +} + +//***************************************************************************** +// +// A dummy printf function to satisfy the calls to printf from uip. This +// avoids pulling in the run-time library. +// +//***************************************************************************** +int +uipprintf(const char *fmt, ...) +{ + ( void ) fmt; + return(0); +} + diff --git a/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/trcConfig.h b/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/trcConfig.h new file mode 100644 index 000000000..979631529 --- /dev/null +++ b/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/trcConfig.h @@ -0,0 +1,320 @@ +/******************************************************************************* + * Trace Recorder Library for Tracealyzer v3.1.2 + * Percepio AB, www.percepio.com + * + * trcConfig.h + * + * Main configuration parameters for the trace recorder library. + * More settings can be found in trcStreamingConfig.h and trcSnapshotConfig.h. + * + * Read more at http://percepio.com/2016/10/05/rtos-tracing/ + * + * Terms of Use + * This file is part of the trace recorder library (RECORDER), which is the + * intellectual property of Percepio AB (PERCEPIO) and provided under a + * license as follows. + * The RECORDER may be used free of charge for the purpose of recording data + * intended for analysis in PERCEPIO products. It may not be used or modified + * for other purposes without explicit permission from PERCEPIO. + * You may distribute the RECORDER in its original source code form, assuming + * this text (terms of use, disclaimer, copyright notice) is unchanged. You are + * allowed to distribute the RECORDER with minor modifications intended for + * configuration or porting of the RECORDER, e.g., to allow using it on a + * specific processor, processor family or with a specific communication + * interface. Any such modifications should be documented directly below + * this comment block. + * + * Disclaimer + * The RECORDER is being delivered to you AS IS and PERCEPIO makes no warranty + * as to its use or performance. PERCEPIO does not and cannot warrant the + * performance or results you may obtain by using the RECORDER or documentation. + * PERCEPIO make no warranties, express or implied, as to noninfringement of + * third party rights, merchantability, or fitness for any particular purpose. + * In no event will PERCEPIO, its technology partners, or distributors be liable + * to you for any consequential, incidental or special damages, including any + * lost profits or lost savings, even if a representative of PERCEPIO has been + * advised of the possibility of such damages, or for any claim by any third + * party. Some jurisdictions do not allow the exclusion or limitation of + * incidental, consequential or special damages, or the exclusion of implied + * warranties or limitations on how long an implied warranty may last, so the + * above limitations may not apply to you. + * + * Tabs are used for indent in this file (1 tab = 4 spaces) + * + * Copyright Percepio AB, 2016. + * www.percepio.com + ******************************************************************************/ + +#ifndef TRC_CONFIG_H +#define TRC_CONFIG_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "trcPortDefines.h" + +/****************************************************************************** + * Include of processor header file + * + * Here you may need to include the header file for your processor. This is + * required at least for the ARM Cortex-M port, that uses the ARM CMSIS API. + * Try that in case of build problems. Otherwise, remove the #error line below. + *****************************************************************************/ +/* Definitions that would come from the processor header file. */ +#define __CORTEX_M (0x03) +#define __CM3_REV 0x0202 +#define __MPU_PRESENT 1 +#define __NVIC_PRIO_BITS 8 /* Silicon has three, QEMU has 8. */ + +__attribute__( ( always_inline ) ) static inline uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __asm volatile ("MRS %0, primask" : "=r" (result) ); + return(result); +} + +__attribute__( ( always_inline ) ) static inline void __set_PRIMASK(uint32_t priMask) +{ + __asm volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); +} + + +/******************************************************************************* + * Configuration Macro: TRC_CFG_HARDWARE_PORT + * + * Specify what hardware port to use (i.e., the "timestamping driver"). + * + * All ARM Cortex-M MCUs are supported by "TRC_HARDWARE_PORT_ARM_Cortex_M". + * This port uses the DWT cycle counter for Cortex-M3/M4/M7 devices, which is + * available on most such devices. In case your device don't have DWT support, + * you will get an error message opening the trace. In that case, you may + * force the recorder to use SysTick timestamping instead, using this define: + * + * #define TRC_CFG_ARM_CM_USE_SYSTICK + * + * For ARM Cortex-M0/M0+ devices, SysTick mode is used automatically. + * + * See trcHardwarePort.h for available ports and information on how to + * define your own port, if not already present. + ******************************************************************************/ +#define TRC_CFG_HARDWARE_PORT TRC_HARDWARE_PORT_ARM_Cortex_M +#define TRC_CFG_ARM_CM_USE_SYSTICK + +/******************************************************************************* + * Configuration Macro: TRC_CFG_RECORDER_MODE + * + * Specify what recording mode to use. Snapshot means that the data is saved in + * an internal RAM buffer, for later upload. Streaming means that the data is + * transferred continuously to the host PC. + * + * For more information, see http://percepio.com/2016/10/05/rtos-tracing/ + * and the Tracealyzer User Manual. + * + * Values: + * TRC_RECORDER_MODE_SNAPSHOT + * TRC_RECORDER_MODE_STREAMING + ******************************************************************************/ +#define TRC_CFG_RECORDER_MODE TRC_RECORDER_MODE_SNAPSHOT + +/****************************************************************************** + * TRC_CFG_FREERTOS_VERSION + * + * Specify what version of FreeRTOS that is used (don't change unless using the + * trace recorder library with an older version of FreeRTOS). + * + * TRC_FREERTOS_VERSION_7_3 If using FreeRTOS v7.3.x + * TRC_FREERTOS_VERSION_7_4 If using FreeRTOS v7.4.x + * TRC_FREERTOS_VERSION_7_5_OR_7_6 If using FreeRTOS v7.5.0 - v7.6.0 + * TRC_FREERTOS_VERSION_8_X If using FreeRTOS v8.X.X + * TRC_FREERTOS_VERSION_9_0_0 If using FreeRTOS v9.0.0 + * TRC_FREERTOS_VERSION_9_0_1 If using FreeRTOS v9.0.1 + * TRC_FREERTOS_VERSION_9_0_2 If using FreeRTOS v9.0.2 + * TRC_FREERTOS_VERSION_10_0_0 If using FreeRTOS v10.0.0 or later + *****************************************************************************/ +#define TRC_CFG_FREERTOS_VERSION TRC_FREERTOS_VERSION_10_0_0 + +/******************************************************************************* + * TRC_CFG_SCHEDULING_ONLY + * + * Macro which should be defined as an integer value. + * + * If this setting is enabled (= 1), only scheduling events are recorded. + * If disabled (= 0), all events are recorded (unless filtered in other ways). + * + * Default value is 0 (= include additional events). + ******************************************************************************/ +#define TRC_CFG_SCHEDULING_ONLY 0 + + /****************************************************************************** + * TRC_CFG_INCLUDE_MEMMANG_EVENTS + * + * Macro which should be defined as either zero (0) or one (1). + * + * This controls if malloc and free calls should be traced. Set this to zero (0) + * to exclude malloc/free calls, or one (1) to include such events in the trace. + * + * Default value is 1. + *****************************************************************************/ +#define TRC_CFG_INCLUDE_MEMMANG_EVENTS 1 + + /****************************************************************************** + * TRC_CFG_INCLUDE_USER_EVENTS + * + * Macro which should be defined as either zero (0) or one (1). + * + * If this is zero (0), all code related to User Events is excluded in order + * to reduce code size. Any attempts of storing User Events are then silently + * ignored. + * + * User Events are application-generated events, like "printf" but for the + * trace log, generated using vTracePrint and vTracePrintF. + * The formatting is done on host-side, by Tracealyzer. User Events are + * therefore much faster than a console printf and can often be used + * in timing critical code without problems. + * + * Note: In streaming mode, User Events are used to provide error messages + * and warnings from the recorder (in case of incorrect configuration) for + * display in Tracealyzer. Disabling user events will also disable these + * warnings. You can however still catch them by calling xTraceGetLastError + * or by putting breakpoints in prvTraceError and prvTraceWarning. + * + * Default value is 1. + *****************************************************************************/ +#define TRC_CFG_INCLUDE_USER_EVENTS 0 + + /***************************************************************************** + * TRC_CFG_INCLUDE_ISR_TRACING + * + * Macro which should be defined as either zero (0) or one (1). + * + * If this is zero (0), the code for recording Interrupt Service Routines is + * excluded, in order to reduce code size. + * + * Default value is 1. + * + * Note: tracing ISRs requires that you insert calls to vTraceStoreISRBegin + * and vTraceStoreISREnd in your interrupt handlers. + *****************************************************************************/ +#define TRC_CFG_INCLUDE_ISR_TRACING 1 + + /***************************************************************************** + * TRC_CFG_INCLUDE_READY_EVENTS + * + * Macro which should be defined as either zero (0) or one (1). + * + * If one (1), events are recorded when tasks enter scheduling state "ready". + * This allows Tracealyzer to show the initial pending time before tasks enter + * the execution state, and present accurate response times. + * If zero (0), "ready events" are not created, which allows for recording + * longer traces in the same amount of RAM. + * + * Default value is 1. + *****************************************************************************/ +#define TRC_CFG_INCLUDE_READY_EVENTS 1 + + /***************************************************************************** + * TRC_CFG_INCLUDE_OSTICK_EVENTS + * + * Macro which should be defined as either zero (0) or one (1). + * + * If this is one (1), events will be generated whenever the OS clock is + * increased. If zero (0), OS tick events are not generated, which allows for + * recording longer traces in the same amount of RAM. + * + * Default value is 1. + *****************************************************************************/ +#define TRC_CFG_INCLUDE_OSTICK_EVENTS 1 + + /***************************************************************************** + * TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS + * + * Macro which should be defined as either zero (0) or one (1). + * + * If this is zero (0), the trace will exclude any "event group" events. + * + * Default value is 0 (excluded) since dependent on event_groups.c + *****************************************************************************/ +#define TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS 1 + + /***************************************************************************** + * TRC_CFG_INCLUDE_TIMER_EVENTS + * + * Macro which should be defined as either zero (0) or one (1). + * + * If this is zero (0), the trace will exclude any Timer events. + * + * Default value is 0 since dependent on timers.c + *****************************************************************************/ +#define TRC_CFG_INCLUDE_TIMER_EVENTS 1 + + /***************************************************************************** + * TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS + * + * Macro which should be defined as either zero (0) or one (1). + * + * If this is zero (0), the trace will exclude any "pending function call" + * events, such as xTimerPendFunctionCall(). + * + * Default value is 0 since dependent on timers.c + *****************************************************************************/ +#define TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS 1 + +/******************************************************************************* + * Configuration Macro: TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS + * + * Macro which should be defined as either zero (0) or one (1). + * + * If this is zero (0), the trace will exclude any stream buffer or message + * buffer events. + * + * Default value is 0 since dependent on stream_buffer.c (new in FreeRTOS v10) + ******************************************************************************/ +#define TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS 1 + +/******************************************************************************* + * Configuration Macro: TRC_CFG_RECORDER_BUFFER_ALLOCATION + * + * Specifies how the recorder buffer is allocated (also in case of streaming, in + * port using the recorder's internal temporary buffer) + * + * Values: + * TRC_RECORDER_BUFFER_ALLOCATION_STATIC - Static allocation (internal) + * TRC_RECORDER_BUFFER_ALLOCATION_DYNAMIC - Malloc in vTraceEnable + * TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM - Use vTraceSetRecorderDataBuffer + * + * Static and dynamic mode does the allocation for you, either in compile time + * (static) or in runtime (malloc). + * The custom mode allows you to control how and where the allocation is made, + * for details see TRC_ALLOC_CUSTOM_BUFFER and vTraceSetRecorderDataBuffer(). + ******************************************************************************/ +#define TRC_CFG_RECORDER_BUFFER_ALLOCATION TRC_RECORDER_BUFFER_ALLOCATION_STATIC + +/****************************************************************************** + * TRC_CFG_MAX_ISR_NESTING + * + * Defines how many levels of interrupt nesting the recorder can handle, in + * case multiple ISRs are traced and ISR nesting is possible. If this + * is exceeded, the particular ISR will not be traced and the recorder then + * logs an error message. This setting is used to allocate an internal stack + * for keeping track of the previous execution context (4 byte per entry). + * + * This value must be a non-zero positive constant, at least 1. + * + * Default value: 8 + *****************************************************************************/ +#define TRC_CFG_MAX_ISR_NESTING 4 + +/* Specific configuration, depending on Streaming/Snapshot mode */ +#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT) +#include "trcSnapshotConfig.h" +#elif (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) +#include "trcStreamingConfig.h" +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _TRC_CONFIG_H */ diff --git a/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/trcSnapshotConfig.h b/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/trcSnapshotConfig.h new file mode 100644 index 000000000..2329f1f2e --- /dev/null +++ b/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/trcSnapshotConfig.h @@ -0,0 +1,378 @@ +/******************************************************************************* + * Trace Recorder Library for Tracealyzer v4.1.4 + * Percepio AB, www.percepio.com + * + * trcSnapshotConfig.h + * + * Configuration parameters for trace recorder library in snapshot mode. + * Read more at http://percepio.com/2016/10/05/rtos-tracing/ + * + * Terms of Use + * This file is part of the trace recorder library (RECORDER), which is the + * intellectual property of Percepio AB (PERCEPIO) and provided under a + * license as follows. + * The RECORDER may be used free of charge for the purpose of recording data + * intended for analysis in PERCEPIO products. It may not be used or modified + * for other purposes without explicit permission from PERCEPIO. + * You may distribute the RECORDER in its original source code form, assuming + * this text (terms of use, disclaimer, copyright notice) is unchanged. You are + * allowed to distribute the RECORDER with minor modifications intended for + * configuration or porting of the RECORDER, e.g., to allow using it on a + * specific processor, processor family or with a specific communication + * interface. Any such modifications should be documented directly below + * this comment block. + * + * Disclaimer + * The RECORDER is being delivered to you AS IS and PERCEPIO makes no warranty + * as to its use or performance. PERCEPIO does not and cannot warrant the + * performance or results you may obtain by using the RECORDER or documentation. + * PERCEPIO make no warranties, express or implied, as to noninfringement of + * third party rights, merchantability, or fitness for any particular purpose. + * In no event will PERCEPIO, its technology partners, or distributors be liable + * to you for any consequential, incidental or special damages, including any + * lost profits or lost savings, even if a representative of PERCEPIO has been + * advised of the possibility of such damages, or for any claim by any third + * party. Some jurisdictions do not allow the exclusion or limitation of + * incidental, consequential or special damages, or the exclusion of implied + * warranties or limitations on how long an implied warranty may last, so the + * above limitations may not apply to you. + * + * Tabs are used for indent in this file (1 tab = 4 spaces) + * + * Copyright Percepio AB, 2018. + * www.percepio.com + ******************************************************************************/ + +#ifndef TRC_SNAPSHOT_CONFIG_H +#define TRC_SNAPSHOT_CONFIG_H + +#define TRC_SNAPSHOT_MODE_RING_BUFFER (0x01) +#define TRC_SNAPSHOT_MODE_STOP_WHEN_FULL (0x02) + +/****************************************************************************** + * TRC_CFG_SNAPSHOT_MODE + * + * Macro which should be defined as one of: + * - TRC_SNAPSHOT_MODE_RING_BUFFER + * - TRC_SNAPSHOT_MODE_STOP_WHEN_FULL + * Default is TRC_SNAPSHOT_MODE_RING_BUFFER. + * + * With TRC_CFG_SNAPSHOT_MODE set to TRC_SNAPSHOT_MODE_RING_BUFFER, the + * events are stored in a ring buffer, i.e., where the oldest events are + * overwritten when the buffer becomes full. This allows you to get the last + * events leading up to an interesting state, e.g., an error, without having + * to store the whole run since startup. + * + * When TRC_CFG_SNAPSHOT_MODE is TRC_SNAPSHOT_MODE_STOP_WHEN_FULL, the + * recording is stopped when the buffer becomes full. This is useful for + * recording events following a specific state, e.g., the startup sequence. + *****************************************************************************/ +#define TRC_CFG_SNAPSHOT_MODE TRC_SNAPSHOT_MODE_RING_BUFFER + +/******************************************************************************* + * TRC_CFG_EVENT_BUFFER_SIZE + * + * Macro which should be defined as an integer value. + * + * This defines the capacity of the event buffer, i.e., the number of records + * it may store. Most events use one record (4 byte), although some events + * require multiple 4-byte records. You should adjust this to the amount of RAM + * available in the target system. + * + * Default value is 1000, which means that 4000 bytes is allocated for the + * event buffer. + ******************************************************************************/ +#define TRC_CFG_EVENT_BUFFER_SIZE 1000 + +/******************************************************************************* + * TRC_CFG_NTASK, TRC_CFG_NISR, TRC_CFG_NQUEUE, TRC_CFG_NSEMAPHORE... + * + * A group of macros which should be defined as integer values, zero or larger. + * + * These define the capacity of the Object Property Table, i.e., the maximum + * number of objects active at any given point, within each object class (e.g., + * task, queue, semaphore, ...). + * + * If tasks or other objects are deleted in your system, this + * setting does not limit the total amount of objects created, only the number + * of objects that have been successfully created but not yet deleted. + * + * Using too small values will cause vTraceError to be called, which stores an + * error message in the trace that is shown when opening the trace file. The + * error message can also be retrieved using xTraceGetLastError. + * + * It can be wise to start with large values for these constants, + * unless you are very confident on these numbers. Then do a recording and + * check the actual usage by selecting View menu -> Trace Details -> + * Resource Usage -> Object Table. + ******************************************************************************/ +#define TRC_CFG_NTASK 60 +#define TRC_CFG_NISR 10 +#define TRC_CFG_NQUEUE 15 +#define TRC_CFG_NSEMAPHORE 15 +#define TRC_CFG_NMUTEX 15 +#define TRC_CFG_NTIMER 5 +#define TRC_CFG_NEVENTGROUP 6 +#define TRC_CFG_NSTREAMBUFFER 15 +#define TRC_CFG_NMESSAGEBUFFER 15 + + +/****************************************************************************** + * TRC_CFG_INCLUDE_FLOAT_SUPPORT + * + * Macro which should be defined as either zero (0) or one (1). + * + * If this is zero (0), the support for logging floating point values in + * vTracePrintF is stripped out, in case floating point values are not used or + * supported by the platform used. + * + * Floating point values are only used in vTracePrintF and its subroutines, to + * allow for storing float (%f) or double (%lf) arguments. + * + * vTracePrintF can be used with integer and string arguments in either case. + * + * Default value is 0. + *****************************************************************************/ +#define TRC_CFG_INCLUDE_FLOAT_SUPPORT 0 + +/******************************************************************************* + * TRC_CFG_SYMBOL_TABLE_SIZE + * + * Macro which should be defined as an integer value. + * + * This defines the capacity of the symbol table, in bytes. This symbol table + * stores User Events labels and names of deleted tasks, queues, or other kernel + * objects. If you don't use User Events or delete any kernel + * objects you set this to a very low value. The minimum recommended value is 4. + * A size of zero (0) is not allowed since a zero-sized array may result in a + * 32-bit pointer, i.e., using 4 bytes rather than 0. + * + * Default value is 800. + ******************************************************************************/ +#define TRC_CFG_SYMBOL_TABLE_SIZE 800 + +#if (TRC_CFG_SYMBOL_TABLE_SIZE == 0) +#error "TRC_CFG_SYMBOL_TABLE_SIZE may not be zero!" +#endif + +/****************************************************************************** + * TRC_CFG_NAME_LEN_TASK, TRC_CFG_NAME_LEN_QUEUE, ... + * + * Macros that specify the maximum lengths (number of characters) for names of + * kernel objects, such as tasks and queues. If longer names are used, they will + * be truncated when stored in the recorder. + *****************************************************************************/ +#define TRC_CFG_NAME_LEN_TASK 15 +#define TRC_CFG_NAME_LEN_ISR 15 +#define TRC_CFG_NAME_LEN_QUEUE 15 +#define TRC_CFG_NAME_LEN_SEMAPHORE 15 +#define TRC_CFG_NAME_LEN_MUTEX 15 +#define TRC_CFG_NAME_LEN_TIMER 15 +#define TRC_CFG_NAME_LEN_EVENTGROUP 15 +#define TRC_CFG_NAME_LEN_STREAMBUFFER 15 +#define TRC_CFG_NAME_LEN_MESSAGEBUFFER 15 + +/****************************************************************************** + *** ADVANCED SETTINGS ******************************************************** + ****************************************************************************** + * The remaining settings are not necessary to modify but allows for optimizing + * the recorder setup for your specific needs, e.g., to exclude events that you + * are not interested in, in order to get longer traces. + *****************************************************************************/ + +/****************************************************************************** +* TRC_CFG_HEAP_SIZE_BELOW_16M +* +* An integer constant that can be used to reduce the buffer usage of memory +* allocation events (malloc/free). This value should be 1 if the heap size is +* below 16 MB (2^24 byte), and you can live with reported addresses showing the +* lower 24 bits only. If 0, you get the full 32-bit addresses. +* +* Default value is 0. +******************************************************************************/ +#define TRC_CFG_HEAP_SIZE_BELOW_16M 0 + +/****************************************************************************** + * TRC_CFG_USE_IMPLICIT_IFE_RULES + * + * Macro which should be defined as either zero (0) or one (1). + * Default is 1. + * + * Tracealyzer groups the events into "instances" based on Instance Finish + * Events (IFEs), produced either by default rules or calls to the recorder + * functions vTraceInstanceFinishedNow and vTraceInstanceFinishedNext. + * + * If TRC_CFG_USE_IMPLICIT_IFE_RULES is one (1), the default IFE rules is + * used, resulting in a "typical" grouping of events into instances. + * If these rules don't give appropriate instances in your case, you can + * override the default rules using vTraceInstanceFinishedNow/Next for one + * or several tasks. The default IFE rules are then disabled for those tasks. + * + * If TRC_CFG_USE_IMPLICIT_IFE_RULES is zero (0), the implicit IFE rules are + * disabled globally. You must then call vTraceInstanceFinishedNow or + * vTraceInstanceFinishedNext to manually group the events into instances, + * otherwise the tasks will appear a single long instance. + * + * The default IFE rules count the following events as "instance finished": + * - Task delay, delay until + * - Task suspend + * - Blocking on "input" operations, i.e., when the task is waiting for the + * next a message/signal/event. But only if this event is blocking. + * + * For details, see trcSnapshotKernelPort.h and look for references to the + * macro trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED. + *****************************************************************************/ +#define TRC_CFG_USE_IMPLICIT_IFE_RULES 1 + +/****************************************************************************** + * TRC_CFG_USE_16BIT_OBJECT_HANDLES + * + * Macro which should be defined as either zero (0) or one (1). + * + * If set to 0 (zero), the recorder uses 8-bit handles to identify kernel + * objects such as tasks and queues. This limits the supported number of + * concurrently active objects to 255 of each type (tasks, queues, mutexes, + * etc.) Note: 255, not 256, since handle 0 is reserved. + * + * If set to 1 (one), the recorder uses 16-bit handles to identify kernel + * objects such as tasks and queues. This limits the supported number of + * concurrent objects to 65535 of each type (object class). However, since the + * object property table is limited to 64 KB, the practical limit is about + * 3000 objects in total. + * + * Default is 0 (8-bit handles) + * + * NOTE: An object with handle above 255 will use an extra 4-byte record in + * the event buffer whenever the object is referenced. Moreover, some internal + * tables in the recorder gets slightly larger when using 16-bit handles. + *****************************************************************************/ +#define TRC_CFG_USE_16BIT_OBJECT_HANDLES 0 + +/****************************************************************************** + * TRC_CFG_USE_TRACE_ASSERT + * + * Macro which should be defined as either zero (0) or one (1). + * Default is 1. + * + * If this is one (1), the TRACE_ASSERT macro (used at various locations in the + * trace recorder) will verify that a relevant condition is true. + * If the condition is false, prvTraceError() will be called, which stops the + * recording and stores an error message that is displayed when opening the + * trace in Tracealyzer. + * + * This is used on several places in the recorder code for sanity checks on + * parameters. Can be switched off to reduce the footprint of the tracing, but + * we recommend to have it enabled initially. + *****************************************************************************/ +#define TRC_CFG_USE_TRACE_ASSERT 1 + +/******************************************************************************* + * TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER + * + * Macro which should be defined as an integer value. + * + * Set TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER to 1 to enable the + * separate user event buffer (UB). + * In this mode, user events are stored separately from other events, + * e.g., RTOS events. Thereby you can get a much longer history of + * user events as they don't need to share the buffer space with more + * frequent events. + * + * The UB is typically used with the snapshot ring-buffer mode, so the + * recording can continue when the main buffer gets full. And since the + * main buffer then overwrites the earliest events, Tracealyzer displays + * "Unknown Actor" instead of task scheduling for periods with UB data only. + * + * In UB mode, user events are structured as UB channels, which contains + * a channel name and a default format string. Register a UB channel using + * xTraceRegisterUBChannel. + * + * Events and data arguments are written using vTraceUBEvent and + * vTraceUBData. They are designed to provide efficient logging of + * repeating events, using the same format string within each channel. + * + * Examples: + * + * traceString chn1 = xTraceRegisterString("Channel 1"); + * traceString fmt1 = xTraceRegisterString("Event!"); + * traceUBChannel UBCh1 = xTraceRegisterUBChannel(chn1, fmt1); + * + * traceString chn2 = xTraceRegisterString("Channel 2"); + * traceString fmt2 = xTraceRegisterString("X: %d, Y: %d"); + * traceUBChannel UBCh2 = xTraceRegisterUBChannel(chn2, fmt2); + * + * // Result in "[Channel 1] Event!" + * vTraceUBEvent(UBCh1); + * + * // Result in "[Channel 2] X: 23, Y: 19" + * vTraceUBData(UBCh2, 23, 19); + * + * You can also use the other user event functions, like vTracePrintF. + * as they are then rerouted to the UB instead of the main event buffer. + * vTracePrintF then looks up the correct UB channel based on the + * provided channel name and format string, or creates a new UB channel + * if no match is found. The format string should therefore not contain + * "random" messages but mainly format specifiers. Random strings should + * be stored using %s and with the string as an argument. + * + * // Creates a new UB channel ("Channel 2", "%Z: %d") + * vTracePrintF(chn2, "%Z: %d", value1); + * + * // Finds the existing UB channel + * vTracePrintF(chn2, "%Z: %d", value2); + + ******************************************************************************/ +#define TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER 0 + +/******************************************************************************* + * TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE + * + * Macro which should be defined as an integer value. + * + * This defines the capacity of the user event buffer (UB), in number of slots. + * A single user event can use multiple slots, depending on the arguments. + * + * Only applicable if TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER is 1. + ******************************************************************************/ +#define TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE 200 + +/******************************************************************************* + * TRC_CFG_UB_CHANNELS + * + * Macro which should be defined as an integer value. + * + * This defines the number of User Event Buffer Channels (UB channels). + * These are used to structure the events when using the separate user + * event buffer, and contains both a User Event Channel (the name) and + * a default format string for the channel. + * + * Only applicable if TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER is 1. + ******************************************************************************/ +#define TRC_CFG_UB_CHANNELS 32 + +/******************************************************************************* + * TRC_CFG_ISR_TAILCHAINING_THRESHOLD + * + * Macro which should be defined as an integer value. + * + * If tracing multiple ISRs, this setting allows for accurate display of the + * context-switching also in cases when the ISRs execute in direct sequence. + * + * vTraceStoreISREnd normally assumes that the ISR returns to the previous + * context, i.e., a task or a preempted ISR. But if another traced ISR + * executes in direct sequence, Tracealyzer may incorrectly display a minimal + * fragment of the previous context in between the ISRs. + * + * By using TRC_CFG_ISR_TAILCHAINING_THRESHOLD you can avoid this. This is + * however a threshold value that must be measured for your specific setup. + * See http://percepio.com/2014/03/21/isr_tailchaining_threshold/ + * + * The default setting is 0, meaning "disabled" and that you may get an + * extra fragments of the previous context in between tail-chained ISRs. + * + * Note: This setting has separate definitions in trcSnapshotConfig.h and + * trcStreamingConfig.h, since it is affected by the recorder mode. + ******************************************************************************/ +#define TRC_CFG_ISR_TAILCHAINING_THRESHOLD 0 + +#endif /*TRC_SNAPSHOT_CONFIG_H*/ diff --git a/FreeRTOS/Demo/Common/Minimal/MessageBufferDemo.c b/FreeRTOS/Demo/Common/Minimal/MessageBufferDemo.c index 73f392b1e..bf352ae61 100644 --- a/FreeRTOS/Demo/Common/Minimal/MessageBufferDemo.c +++ b/FreeRTOS/Demo/Common/Minimal/MessageBufferDemo.c @@ -129,7 +129,11 @@ void vStartMessageBufferTasks( configSTACK_DEPTH_TYPE xStackSize ) { MessageBufferHandle_t xMessageBuffer; +#ifndef configMESSAGE_BUFFER_BLOCK_TASK_STACK_SIZE xBlockingStackSize = ( xStackSize + ( xStackSize >> 1U ) ); +#else + xBlockingStackSize = configMESSAGE_BUFFER_BLOCK_TASK_STACK_SIZE; +#endif /* The echo servers sets up the message buffers before creating the echo client tasks. One set of tasks has the server as the higher priority, and @@ -543,6 +547,7 @@ char cRxString[ 12 ]; char cTxString[ 12 ]; /* Large enough to hold a 32 number in ASCII. */ const TickType_t xTicksToWait = mbRX_TX_BLOCK_TIME, xShortDelay = pdMS_TO_TICKS( 50 ); StaticMessageBuffer_t xStaticMessageBuffer; + size_t xBytesSent; /* The task's priority is used as an index into the loop counters used to @@ -583,7 +588,11 @@ char cRxString[ 12 ]; then overflows. */ memset( cTxString, 0x00, sizeof( cTxString ) ); sprintf( cTxString, "%d", ( int ) iDataToSend ); - xMessageBufferSend( xMessageBuffer, ( void * ) cTxString, strlen( cTxString ), xTicksToWait ); + + do + { + xBytesSent = xMessageBufferSend( xMessageBuffer, ( void * ) cTxString, strlen( cTxString ), xTicksToWait ); + } while ( xBytesSent == 0 ); /* Buffer may become full when receiver is running at the idle priority. */ iDataToSend++; diff --git a/FreeRTOS/Demo/Common/Minimal/StreamBufferDemo.c b/FreeRTOS/Demo/Common/Minimal/StreamBufferDemo.c index 49546ce96..eb39713e6 100644 --- a/FreeRTOS/Demo/Common/Minimal/StreamBufferDemo.c +++ b/FreeRTOS/Demo/Common/Minimal/StreamBufferDemo.c @@ -69,7 +69,17 @@ the Blocked state so it can read the bytes. */ /* The size of the stack allocated to the tasks that run as part of this demo/ test. The stack size is over generous in most cases. */ -#define sbSTACK_SIZE ( configMINIMAL_STACK_SIZE + ( configMINIMAL_STACK_SIZE >> 1 ) ) +#ifndef configSTREAM_BUFFER_SENDER_TASK_STACK_SIZE + #define sbSTACK_SIZE ( configMINIMAL_STACK_SIZE + ( configMINIMAL_STACK_SIZE >> 1 ) ) +#else + #define sbSTACK_SIZE configSTREAM_BUFFER_SENDER_TASK_STACK_SIZE +#endif + +#ifndef configSTREAM_BUFFER_SMALLER_TASK_STACK_SIZE + #define sbSMALLER_STACK_SIZE sbSTACK_SIZE +#else + #define sbSMALLER_STACK_SIZE configSTREAM_BUFFER_SMALLER_TASK_STACK_SIZE +#endif /*-----------------------------------------------------------*/ @@ -148,7 +158,7 @@ static volatile StreamBufferHandle_t xInterruptStreamBuffer = NULL; /* The data sent from the tick interrupt to the task that tests the trigger level functionality. */ -static const char *pcDataSentFromInterrupt = "12345678"; +static const char *pcDataSentFromInterrupt = "0123456789"; /* Data that is longer than the buffer that is sent to the buffers as a stream of bytes. Parts of which are written to the stream buffer to test writing @@ -171,8 +181,8 @@ StreamBufferHandle_t xStreamBuffer; /* The echo servers sets up the stream buffers before creating the echo client tasks. One set of tasks has the server as the higher priority, and the other has the client as the higher priority. */ - xTaskCreate( prvEchoServer, "1StrEchoServer", sbSTACK_SIZE, NULL, sbHIGHER_PRIORITY, NULL ); - xTaskCreate( prvEchoServer, "2StrEchoServer", sbSTACK_SIZE, NULL, sbLOWER_PRIORITY, NULL ); + xTaskCreate( prvEchoServer, "1StrEchoServer", sbSMALLER_STACK_SIZE, NULL, sbHIGHER_PRIORITY, NULL ); + xTaskCreate( prvEchoServer, "2StrEchoServer", sbSMALLER_STACK_SIZE, NULL, sbLOWER_PRIORITY, NULL ); /* The non blocking tasks run continuously and will interleave with each other, so must be created at the lowest priority. The stream buffer they @@ -192,8 +202,8 @@ StreamBufferHandle_t xStreamBuffer; /* The sender tasks set up the stream buffers before creating the receiver tasks. Priorities must be 0 and 1 as the priority is used to index into the xStaticStreamBuffers and ucBufferStorage arrays. */ - xTaskCreate( prvSenderTask, "Str1Sender", sbSTACK_SIZE, NULL, sbHIGHER_PRIORITY, NULL ); - xTaskCreate( prvSenderTask, "Str2Sender", sbSTACK_SIZE, NULL, sbLOWER_PRIORITY, NULL ); + xTaskCreate( prvSenderTask, "Str1Sender", sbSMALLER_STACK_SIZE, NULL, sbHIGHER_PRIORITY, NULL ); + xTaskCreate( prvSenderTask, "Str2Sender", sbSMALLER_STACK_SIZE, NULL, sbLOWER_PRIORITY, NULL ); } #endif /* configSUPPORT_STATIC_ALLOCATION */ } @@ -599,11 +609,11 @@ BaseType_t xNonBlockingReceiveError = pdFALSE; /* Here prvSingleTaskTests() performs various tests on a stream buffer that was created statically. */ prvSingleTaskTests( xStreamBuffer ); - xTaskCreate( prvReceiverTask, "StrReceiver", sbSTACK_SIZE, ( void * ) xStreamBuffer, sbHIGHER_PRIORITY, NULL ); + xTaskCreate( prvReceiverTask, "StrReceiver", sbSMALLER_STACK_SIZE, ( void * ) xStreamBuffer, sbHIGHER_PRIORITY, NULL ); } else { - xTaskCreate( prvReceiverTask, "StrReceiver", sbSTACK_SIZE, ( void * ) xStreamBuffer, sbLOWER_PRIORITY, NULL ); + xTaskCreate( prvReceiverTask, "StrReceiver", sbSMALLER_STACK_SIZE, ( void * ) xStreamBuffer, sbLOWER_PRIORITY, NULL ); } for( ;; ) @@ -770,7 +780,6 @@ EchoStreamBuffers_t *pxStreamBuffers = ( EchoStreamBuffers_t * ) pvParameters; /* This stream buffer is just created and deleted to ensure no memory leaks. */ xTempStreamBuffer = xStreamBufferCreate( sbSTREAM_BUFFER_LENGTH_BYTES, sbTRIGGER_LEVEL_1 ); - prvSingleTaskTests( xTempStreamBuffer ); vStreamBufferDelete( xTempStreamBuffer ); /* The following are tests for a stream buffer of size one. */ @@ -856,14 +865,14 @@ const TickType_t xTicksToBlock = pdMS_TO_TICKS( 350UL ); priority then the client task is created at the higher priority. */ if( uxTaskPriorityGet( NULL ) == sbLOWER_PRIORITY ) { - xTaskCreate( prvEchoClient, "EchoClient", sbSTACK_SIZE, ( void * ) &xStreamBuffers, sbHIGHER_PRIORITY, NULL ); + xTaskCreate( prvEchoClient, "EchoClient", sbSMALLER_STACK_SIZE, ( void * ) &xStreamBuffers, sbHIGHER_PRIORITY, NULL ); } else { /* Here prvSingleTaskTests() performs various tests on a stream buffer that was created dynamically. */ prvSingleTaskTests( xStreamBuffers.xEchoClientBuffer ); - xTaskCreate( prvEchoClient, "EchoClient", sbSTACK_SIZE, ( void * ) &xStreamBuffers, sbLOWER_PRIORITY, NULL ); + xTaskCreate( prvEchoClient, "EchoClient", sbSMALLER_STACK_SIZE, ( void * ) &xStreamBuffers, sbLOWER_PRIORITY, NULL ); } for( ;; ) @@ -914,14 +923,14 @@ static void prvInterruptTriggerLevelTest( void *pvParameters ) { StreamBufferHandle_t xStreamBuffer; size_t xTriggerLevel = 1, xBytesReceived; -const size_t xStreamBufferSizeBytes = ( size_t ) 8, xMaxTriggerLevel = ( size_t ) 6, xMinTriggerLevel = ( size_t ) 1; -const TickType_t xReadBlockTime = 4, xCycleBlockTime = pdMS_TO_TICKS( 100 ); -uint8_t ucRxData[ 8 ]; +const size_t xStreamBufferSizeBytes = ( size_t ) 9, xMaxTriggerLevel = ( size_t ) 7, xMinTriggerLevel = ( size_t ) 2; +const TickType_t xReadBlockTime = 5, xCycleBlockTime = pdMS_TO_TICKS( 100 ); +uint8_t ucRxData[ 9 ]; BaseType_t xErrorDetected = pdFALSE; #ifndef configSTREAM_BUFFER_TRIGGER_LEVEL_TEST_MARGIN - const size_t xAllowableMargin = ( size_t ) 0; + const size_t xAllowableMargin = ( size_t ) 0; #else - const size_t xAllowableMargin = ( size_t ) configSTREAM_BUFFER_TRIGGER_LEVEL_TEST_MARGIN; + const size_t xAllowableMargin = ( size_t ) configSTREAM_BUFFER_TRIGGER_LEVEL_TEST_MARGIN; #endif /* Remove compiler warning about unused parameter. */ @@ -931,6 +940,12 @@ BaseType_t xErrorDetected = pdFALSE; { for( xTriggerLevel = xMinTriggerLevel; xTriggerLevel < xMaxTriggerLevel; xTriggerLevel++ ) { + /* This test is very time sensitive so delay at the beginning to ensure + the rest of the system is up and running before starting. Delay between + each loop to ensure the interrupt that sends to the stream buffer + detects it needs to start sending from the start of the strin again.. */ + vTaskDelay( xCycleBlockTime ); + /* Create the stream buffer that will be used from inside the tick interrupt. */ memset( ucRxData, 0x00, sizeof( ucRxData ) ); @@ -963,9 +978,27 @@ BaseType_t xErrorDetected = pdFALSE; { /* Trigger level was greater than the block time so expect to time out having received xReadBlockTime bytes. */ - if( ( xReadBlockTime - xBytesReceived ) > xAllowableMargin ) + if( xBytesReceived > xReadBlockTime ) { - xErrorDetected = pdTRUE; + /* Received more bytes than expected. That could happen if + this task unblocked at the right time, but an interrupt + added another byte to the stream buffer before this task was + able to run. */ + if( ( xBytesReceived - xReadBlockTime ) > xAllowableMargin ) + { + xErrorDetected = pdTRUE; + } + } + else if( xReadBlockTime != xBytesReceived ) + { + /* It is possible the interrupt placed an item in the stream + buffer before this task called xStreamBufferReceive(), but + if that is the case then xBytesReceived will only every be + 0 as the interrupt will only have executed once. */ + if( xBytesReceived != 1 ) + { + xErrorDetected = pdTRUE; + } } } else if( xTriggerLevel < xReadBlockTime ) @@ -973,19 +1006,43 @@ BaseType_t xErrorDetected = pdFALSE; /* Trigger level was less than the block time so we expect to have received the trigger level number of bytes - could be more though depending on other activity between the task being - unblocked and the task reading the number of bytes received. */ - if( ( xBytesReceived - xTriggerLevel ) > xAllowableMargin ) + unblocked and the task reading the number of bytes received. It + could also be less if the interrupt already put something in the + stream buffer before this task attempted to read it - in which + case the task would have returned the available bytes immediately + without ever blocking - in that case the bytes received will + only ever be 1 as the interrupt would not have executed more + than one in that time unless this task has too low a priority. */ + if( xBytesReceived < xTriggerLevel ) + { + if( xBytesReceived != 1 ) + { + xErrorDetected = pdTRUE; + } + } + else if( ( xBytesReceived - xTriggerLevel ) > xAllowableMargin ) { xErrorDetected = pdTRUE; } } else { - /* The trigger level equaled the block time, so expect to - receive no greater than the block time, but one or two less is - ok due to variations in how far through the time slice the - functions get executed. */ - if( ( xBytesReceived - xReadBlockTime ) > xAllowableMargin ) + /* The trigger level equalled the block time, so expect to + receive no greater than the block time. It could also be less + if the interrupt already put something in the stream buffer + before this task attempted to read it - in which case the task + would have returned the available bytes immediately without ever + blocking - in that case the bytes received would only ever be 1 + because the interrupt is not going to execute twice in that time + unless this task is running a too low a priority. */ + if( xBytesReceived < xReadBlockTime ) + { + if( xBytesReceived != 1 ) + { + xErrorDetected = pdTRUE; + } + } + else if( ( xBytesReceived - xReadBlockTime ) > xAllowableMargin ) { xErrorDetected = pdTRUE; } @@ -1010,7 +1067,6 @@ BaseType_t xErrorDetected = pdFALSE; /* Tidy up ready for the next loop. */ vStreamBufferDelete( xStreamBuffer ); - vTaskDelay( xCycleBlockTime ); } } } diff --git a/FreeRTOS/Demo/WIN32-MSVC/Trace_Recorder_Configuration/trcConfig.h b/FreeRTOS/Demo/WIN32-MSVC/Trace_Recorder_Configuration/trcConfig.h index 610b0d97e..c8690d710 100644 --- a/FreeRTOS/Demo/WIN32-MSVC/Trace_Recorder_Configuration/trcConfig.h +++ b/FreeRTOS/Demo/WIN32-MSVC/Trace_Recorder_Configuration/trcConfig.h @@ -113,7 +113,7 @@ extern "C" { * TRC_FREERTOS_VERSION_9_0_2 If using FreeRTOS v9.0.2 * TRC_FREERTOS_VERSION_10_0_0 If using FreeRTOS v10.0.0 or later *****************************************************************************/ -#define TRC_CFG_FREERTOS_VERSION TRC_FREERTOS_VERSION_10_0_0 +#define TRC_CFG_FREERTOS_VERSION TRC_FREERTOS_VERSION_10_4_0 /******************************************************************************* * TRC_CFG_SCHEDULING_ONLY