From: richardbarry Date: Tue, 8 Oct 2013 15:56:06 +0000 (+0000) Subject: Complete SAMD20 demo - still needs tidy up. X-Git-Tag: V7.5.3~8 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=effd9e575f09c05ffb0817f5cad143dfac8df6c0;p=freertos Complete SAMD20 demo - still needs tidy up. Add comments to the XMC1000 reg test files. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@2058 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- diff --git a/FreeRTOS/Demo/CORTEX_M0+_Atmel_SAMD20_XPlained/RTOSDemo.atsuo b/FreeRTOS/Demo/CORTEX_M0+_Atmel_SAMD20_XPlained/RTOSDemo.atsuo index c05015591..deb7a887d 100644 Binary files a/FreeRTOS/Demo/CORTEX_M0+_Atmel_SAMD20_XPlained/RTOSDemo.atsuo and b/FreeRTOS/Demo/CORTEX_M0+_Atmel_SAMD20_XPlained/RTOSDemo.atsuo differ diff --git a/FreeRTOS/Demo/CORTEX_M0+_Atmel_SAMD20_XPlained/RTOSDemo/RTOSDemo.cproj b/FreeRTOS/Demo/CORTEX_M0+_Atmel_SAMD20_XPlained/RTOSDemo/RTOSDemo.cproj index e3144d198..8bd150753 100644 --- a/FreeRTOS/Demo/CORTEX_M0+_Atmel_SAMD20_XPlained/RTOSDemo/RTOSDemo.cproj +++ b/FreeRTOS/Demo/CORTEX_M0+_Atmel_SAMD20_XPlained/RTOSDemo/RTOSDemo.cproj @@ -403,6 +403,7 @@ ../../../../Source/include ../../../../Source/portable/GCC/ARM_CM0 ../../../../../FreeRTOS-Plus/Source/FreeRTOS-Plus-CLI + ../../../Common/include -fdata-sections @@ -498,6 +499,49 @@ True + + compile + src\Common-Demo-Tasks\blocktim.c + + + compile + src\Common-Demo-Tasks\countsem.c + + + compile + src\Common-Demo-Tasks\dynamic.c + + + compile + src\Common-Demo-Tasks\GenQTest.c + + + compile + src\Common-Demo-Tasks\QueueOverwrite.c + + + compile + src\Common-Demo-Tasks\QueueSet.c + + + compile + src\Common-Demo-Tasks\recmutex.c + + + compile + + + compile + + + compile + + + compile + + + compile + compile @@ -651,9 +695,9 @@ compile - + compile - + compile @@ -1055,6 +1099,7 @@ + \ No newline at end of file diff --git a/FreeRTOS/Demo/CORTEX_M0+_Atmel_SAMD20_XPlained/RTOSDemo/src/ASF/sam0/drivers/sercom/sercom_interrupt.c b/FreeRTOS/Demo/CORTEX_M0+_Atmel_SAMD20_XPlained/RTOSDemo/src/ASF/sam0/drivers/sercom/sercom_interrupt.c index 042e5b30d..5de0a7261 100644 --- a/FreeRTOS/Demo/CORTEX_M0+_Atmel_SAMD20_XPlained/RTOSDemo/src/ASF/sam0/drivers/sercom/sercom_interrupt.c +++ b/FreeRTOS/Demo/CORTEX_M0+_Atmel_SAMD20_XPlained/RTOSDemo/src/ASF/sam0/drivers/sercom/sercom_interrupt.c @@ -59,6 +59,7 @@ static void (*_sercom_interrupt_handlers[SERCOM_INST_NUM])(const uint8_t instanc static void _sercom_default_handler( const uint8_t instance) { + ( void ) instance; Assert(false); } diff --git a/FreeRTOS/Demo/CORTEX_M0+_Atmel_SAMD20_XPlained/RTOSDemo/src/ASF/sam0/drivers/sercom/usart/usart_interrupt.c b/FreeRTOS/Demo/CORTEX_M0+_Atmel_SAMD20_XPlained/RTOSDemo/src/ASF/sam0/drivers/sercom/usart/usart_interrupt.c index e0dec61a0..acf7f1807 100644 --- a/FreeRTOS/Demo/CORTEX_M0+_Atmel_SAMD20_XPlained/RTOSDemo/src/ASF/sam0/drivers/sercom/usart/usart_interrupt.c +++ b/FreeRTOS/Demo/CORTEX_M0+_Atmel_SAMD20_XPlained/RTOSDemo/src/ASF/sam0/drivers/sercom/usart/usart_interrupt.c @@ -482,8 +482,11 @@ void _usart_interrupt_handler( module->tx_status = STATUS_OK; /* Run callback if registered and enabled */ - if (callback_status & (1 << USART_CALLBACK_BUFFER_TRANSMITTED)) { - (*(module->callback[USART_CALLBACK_BUFFER_TRANSMITTED]))(module); + if( module->remaining_tx_buffer_length == 0 ) /* Added by _RB_ */ + { + if (callback_status & (1 << USART_CALLBACK_BUFFER_TRANSMITTED)) { + (*(module->callback[USART_CALLBACK_BUFFER_TRANSMITTED]))(module); + } } /* Check if the Receive Complete interrupt has occurred, and that diff --git a/FreeRTOS/Demo/CORTEX_M0+_Atmel_SAMD20_XPlained/RTOSDemo/src/RegTest.c b/FreeRTOS/Demo/CORTEX_M0+_Atmel_SAMD20_XPlained/RTOSDemo/src/RegTest.c new file mode 100644 index 000000000..dfe459020 --- /dev/null +++ b/FreeRTOS/Demo/CORTEX_M0+_Atmel_SAMD20_XPlained/RTOSDemo/src/RegTest.c @@ -0,0 +1,248 @@ +/* + FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd. + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to distribute + >>! a combined work that includes FreeRTOS without being obliged to provide + >>! the source code for proprietary components outside of the FreeRTOS + >>! kernel. + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/* + * "Reg test" tasks - These fill the registers with known values, then check + * that each register maintains its expected value for the lifetime of the + * task. Each task uses a different set of values. The reg test tasks execute + * with a very low priority, so get preempted very frequently. A register + * containing an unexpected value is indicative of an error in the context + * switching mechanism. + */ + +void vRegTest1Task( void ) __attribute__((naked)); +void vRegTest2Task( void ) __attribute__((naked)); + +void vRegTest1Task( void ) +{ + __asm volatile + ( + ".extern ulRegTest1LoopCounter \n" + " \n" + " /* Fill the core registers with known values. */ \n" + " movs r1, #101 \n" + " movs r2, #102 \n" + " movs r3, #103 \n" + " movs r4, #104 \n" + " movs r5, #105 \n" + " movs r6, #106 \n" + " movs r7, #107 \n" + " movs r0, #108 \n" + " mov r8, r0 \n" + " movs r0, #109 \n" + " mov r9, r0 \n" + " movs r0, #110 \n" + " mov r10, r0 \n" + " movs r0, #111 \n" + " mov r11, r0 \n" + " movs r0, #112 \n" + " mov r12, r0 \n" + " movs r0, #100 \n" + " \n" + "reg1_loop: \n" + " \n" + " cmp r0, #100 \n" + " bne reg1_error_loop \n" + " cmp r1, #101 \n" + " bne reg1_error_loop \n" + " cmp r2, #102 \n" + " bne reg1_error_loop \n" + " cmp r3, #103 \n" + " bne reg1_error_loop \n" + " cmp r4, #104 \n" + " bne reg1_error_loop \n" + " cmp r5, #105 \n" + " bne reg1_error_loop \n" + " cmp r6, #106 \n" + " bne reg1_error_loop \n" + " cmp r7, #107 \n" + " bne reg1_error_loop \n" + " movs r0, #108 \n" + " cmp r8, r0 \n" + " bne reg1_error_loop \n" + " movs r0, #109 \n" + " cmp r9, r0 \n" + " bne reg1_error_loop \n" + " movs r0, #110 \n" + " cmp r10, r0 \n" + " bne reg1_error_loop \n" + " movs r0, #111 \n" + " cmp r11, r0 \n" + " bne reg1_error_loop \n" + " movs r0, #112 \n" + " cmp r12, r0 \n" + " bne reg1_error_loop \n" + " \n" + " /* Everything passed, increment the loop counter. */ \n" + " push { r1 } \n" + " ldr r0, =ulRegTest1LoopCounter \n" + " ldr r1, [r0] \n" + " add r1, r1, #1 \n" + " str r1, [r0] \n" + " \n" + " /* Yield to increase test coverage. */ \n" + " movs r0, #0x01 \n" + " ldr r1, =0xe000ed04 \n" /*NVIC_INT_CTRL */ + " lsl r0, #28 \n" /* Shift to PendSV bit */ + " str r0, [r1] \n" + " dsb \n" + " pop { r1 } \n" + " \n" + " /* Start again. */ \n" + " movs r0, #100 \n" + " b reg1_loop \n" + " \n" + "reg1_error_loop: \n" + " /* If this line is hit then there was an error in a core register value. \n" + " The loop ensures the loop counter stops incrementing. */ \n" + " b reg1_error_loop \n" + " nop \n" + ); +} +/*-----------------------------------------------------------*/ + +void vRegTest2Task( void ) +{ + __asm volatile + ( + ".extern ulRegTest2LoopCounter \n" + " \n" + " /* Fill the core registers with known values. */ \n" + " movs r1, #1 \n" + " movs r2, #2 \n" + " movs r3, #3 \n" + " movs r4, #4 \n" + " movs r5, #5 \n" + " movs r6, #6 \n" + " movs r7, #7 \n" + " movs r0, #8 \n" + " movs r8, r0 \n" + " movs r0, #9 \n" + " mov r9, r0 \n" + " movs r0, #10 \n" + " mov r10, r0 \n" + " movs r0, #11 \n" + " mov r11, r0 \n" + " movs r0, #12 \n" + " mov r12, r0 \n" + " movs r0, #10 \n" + " \n" + "reg2_loop: \n" + " \n" + " cmp r0, #10 \n" + " bne reg2_error_loop \n" + " cmp r1, #1 \n" + " bne reg2_error_loop \n" + " cmp r2, #2 \n" + " bne reg2_error_loop \n" + " cmp r3, #3 \n" + " bne reg2_error_loop \n" + " cmp r4, #4 \n" + " bne reg2_error_loop \n" + " cmp r5, #5 \n" + " bne reg2_error_loop \n" + " cmp r6, #6 \n" + " bne reg2_error_loop \n" + " cmp r7, #7 \n" + " bne reg2_error_loop \n" + " movs r0, #8 \n" + " cmp r8, r0 \n" + " bne reg2_error_loop \n" + " movs r0, #9 \n" + " cmp r9, r0 \n" + " bne reg2_error_loop \n" + " movs r0, #10 \n" + " cmp r10, r0 \n" + " bne reg2_error_loop \n" + " movs r0, #11 \n" + " cmp r11, r0 \n" + " bne reg2_error_loop \n" + " movs r0, #12 \n" + " cmp r12, r0 \n" + " bne reg2_error_loop \n" + " \n" + " /* Everything passed, increment the loop counter. */ \n" + " push { r1 } \n" + " ldr r0, =ulRegTest2LoopCounter \n" + " ldr r1, [r0] \n" + " add r1, r1, #1 \n" + " str r1, [r0] \n" + " pop { r1 } \n" + " \n" + " /* Start again. */ \n" + " movs r0, #10 \n" + " b reg2_loop \n" + " \n" + "reg2_error_loop: \n" + " /* If this line is hit then there was an error in a core register value. \n" + " The loop ensures the loop counter stops incrementing. */ \n" + " b reg2_error_loop \n" + " nop \n" + ); +} +/*-----------------------------------------------------------*/ + + + + diff --git a/FreeRTOS/Demo/CORTEX_M0+_Atmel_SAMD20_XPlained/RTOSDemo/src/config/FreeRTOSConfig.h b/FreeRTOS/Demo/CORTEX_M0+_Atmel_SAMD20_XPlained/RTOSDemo/src/config/FreeRTOSConfig.h index 9ce799cd3..ca79bcc0c 100644 --- a/FreeRTOS/Demo/CORTEX_M0+_Atmel_SAMD20_XPlained/RTOSDemo/src/config/FreeRTOSConfig.h +++ b/FreeRTOS/Demo/CORTEX_M0+_Atmel_SAMD20_XPlained/RTOSDemo/src/config/FreeRTOSConfig.h @@ -78,17 +78,16 @@ * See http://www.freertos.org/a00110.html. *----------------------------------------------------------*/ -#include -extern uint32_t SystemCoreClock; +#include #define configUSE_PREEMPTION 1 #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 1 -#define configCPU_CLOCK_HZ ( SystemCoreClock ) +#define configCPU_CLOCK_HZ ( system_clock_source_get_hz( SYSTEM_CLOCK_SOURCE_DFLL ) ) #define configTICK_RATE_HZ ( ( portTickType ) 500 ) #define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 5 ) #define configMINIMAL_STACK_SIZE ( ( unsigned short ) 60 ) -#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 11000 ) ) +#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 16000 ) ) #define configMAX_TASK_NAME_LEN ( 5 ) #define configUSE_TRACE_FACILITY 1 #define configUSE_16_BIT_TICKS 0 diff --git a/FreeRTOS/Demo/CORTEX_M0+_Atmel_SAMD20_XPlained/RTOSDemo/src/config/conf_clocks.h b/FreeRTOS/Demo/CORTEX_M0+_Atmel_SAMD20_XPlained/RTOSDemo/src/config/conf_clocks.h index faed281d5..2da2cbedf 100644 --- a/FreeRTOS/Demo/CORTEX_M0+_Atmel_SAMD20_XPlained/RTOSDemo/src/config/conf_clocks.h +++ b/FreeRTOS/Demo/CORTEX_M0+_Atmel_SAMD20_XPlained/RTOSDemo/src/config/conf_clocks.h @@ -47,7 +47,7 @@ /* System clock bus configuration */ # define CONF_CLOCK_CPU_CLOCK_FAILURE_DETECT true -# define CONF_CLOCK_FLASH_WAIT_STATES 0 +# define CONF_CLOCK_FLASH_WAIT_STATES 2 # define CONF_CLOCK_CPU_DIVIDER SYSTEM_MAIN_CLOCK_DIV_1 # define CONF_CLOCK_APBA_DIVIDER SYSTEM_MAIN_CLOCK_DIV_1 # define CONF_CLOCK_APBB_DIVIDER SYSTEM_MAIN_CLOCK_DIV_1 @@ -86,8 +86,8 @@ # define CONF_CLOCK_OSC32K_RUN_IN_STANDBY false /* SYSTEM_CLOCK_SOURCE_DFLL configuration - Digital Frequency Locked Loop */ -# define CONF_CLOCK_DFLL_ENABLE false -# define CONF_CLOCK_DFLL_LOOP_MODE SYSTEM_CLOCK_DFLL_LOOP_MODE_OPEN +# define CONF_CLOCK_DFLL_ENABLE true +# define CONF_CLOCK_DFLL_LOOP_MODE SYSTEM_CLOCK_DFLL_LOOP_MODE_CLOSED # define CONF_CLOCK_DFLL_ON_DEMAND false # define CONF_CLOCK_DFLL_RUN_IN_STANDBY false @@ -113,12 +113,12 @@ /* Configure GCLK generator 0 (Main Clock) */ # define CONF_CLOCK_GCLK_0_ENABLE true # define CONF_CLOCK_GCLK_0_RUN_IN_STANDBY false -# define CONF_CLOCK_GCLK_0_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC8M +# define CONF_CLOCK_GCLK_0_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_DFLL # define CONF_CLOCK_GCLK_0_PRESCALER 1 # define CONF_CLOCK_GCLK_0_OUTPUT_ENABLE false /* Configure GCLK generator 1 */ -# define CONF_CLOCK_GCLK_1_ENABLE false +# define CONF_CLOCK_GCLK_1_ENABLE true # define CONF_CLOCK_GCLK_1_RUN_IN_STANDBY false # define CONF_CLOCK_GCLK_1_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC8M # define CONF_CLOCK_GCLK_1_PRESCALER 1 diff --git a/FreeRTOS/Demo/CORTEX_M0+_Atmel_SAMD20_XPlained/RTOSDemo/src/main-blinky.c b/FreeRTOS/Demo/CORTEX_M0+_Atmel_SAMD20_XPlained/RTOSDemo/src/main-blinky.c new file mode 100644 index 000000000..7f866c6ca --- /dev/null +++ b/FreeRTOS/Demo/CORTEX_M0+_Atmel_SAMD20_XPlained/RTOSDemo/src/main-blinky.c @@ -0,0 +1,231 @@ +/* + FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd. + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to distribute + >>! a combined work that includes FreeRTOS without being obliged to provide + >>! the source code for proprietary components outside of the FreeRTOS + >>! kernel. + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/****************************************************************************** + * NOTE 1: This project provides two demo applications. A simple blinky style + * project, and a more comprehensive test and demo application. The + * mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting in main.c is used to select + * between the two. See the notes on using mainCREATE_SIMPLE_BLINKY_DEMO_ONLY + * in main.c. This file implements the simply blinky style version. + * + * NOTE 2: This file only contains the source code that is specific to the + * basic demo. Generic functions, such FreeRTOS hook functions, and functions + * required to configure the hardware, are defined in main.c. + ****************************************************************************** + * + * main_blinky() creates one queue, and two tasks. It then starts the + * scheduler. + * + * The Queue Send Task: + * The queue send task is implemented by the prvQueueSendTask() function in + * this file. prvQueueSendTask() sits in a loop that causes it to repeatedly + * block for 200 milliseconds before sending the value 100 to the queue that + * was created within main_blinky(). Once the value is sent, the task loops + * back around to block for another 200 milliseconds. + * + * The Queue Receive Task: + * The queue receive task is implemented by the prvQueueReceiveTask() function + * in this file. prvQueueReceiveTask() sits in a loop where it repeatedly + * blocks on attempts to read data from the queue that was created within + * main_blinky(). When data is received, the task checks the value of the + * data, and if the value equals the expected 100, toggles the LED. The 'block + * time' parameter passed to the queue receive function specifies that the + * task should be held in the Blocked state indefinitely to wait for data to + * be available on the queue. The queue receive task will only leave the + * Blocked state when the queue send task writes to the queue. As the queue + * send task writes to the queue every 200 milliseconds, the queue receive + * task leaves the Blocked state every 200 milliseconds, and therefore toggles + * the LED every 200 milliseconds. + */ + +/* Kernel includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" + +/* Priorities at which the tasks are created. */ +#define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 ) +#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) + +/* The rate at which data is sent to the queue. The 200ms value is converted +to ticks using the portTICK_RATE_MS constant. */ +#define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_RATE_MS ) + +/* The number of items the queue can hold. This is 1 as the receive task +will remove items as they are added, meaning the send task should always find +the queue empty. */ +#define mainQUEUE_LENGTH ( 1 ) + +/* Values passed to the two tasks just to check the task parameter +functionality. */ +#define mainQUEUE_SEND_PARAMETER ( 0x1111UL ) +#define mainQUEUE_RECEIVE_PARAMETER ( 0x22UL ) + + +/*-----------------------------------------------------------*/ + +/* + * The tasks as described in the comments at the top of this file. + */ +static void prvQueueReceiveTask( void *pvParameters ); +static void prvQueueSendTask( void *pvParameters ); + +/* + * Called by main() to create the simply blinky style application if + * mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 1. + */ +void main_blinky( void ); + +/*-----------------------------------------------------------*/ + +/* The queue used by both tasks. */ +static xQueueHandle xQueue = NULL; + +/*-----------------------------------------------------------*/ + +void main_blinky( void ) +{ + /* Create the queue. */ + xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( unsigned long ) ); + + if( xQueue != NULL ) + { + /* Start the two tasks as described in the comments at the top of this + file. */ + xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */ + ( signed char * ) "Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */ + configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */ + ( void * ) mainQUEUE_RECEIVE_PARAMETER, /* The parameter passed to the task - just to check the functionality. */ + mainQUEUE_RECEIVE_TASK_PRIORITY, /* The priority assigned to the task. */ + NULL ); /* The task handle is not required, so NULL is passed. */ + + xTaskCreate( prvQueueSendTask, ( signed char * ) "TX", configMINIMAL_STACK_SIZE, ( void * ) mainQUEUE_SEND_PARAMETER, mainQUEUE_SEND_TASK_PRIORITY, NULL ); + + /* Start the tasks and timer running. */ + vTaskStartScheduler(); + } + + /* If all is well, the scheduler will now be running, and the following + line will never be reached. If the following line does execute, then + there was insufficient FreeRTOS heap memory available for the idle and/or + timer tasks to be created. See the memory management section on the + FreeRTOS web site for more details. */ + for( ;; ); +} +/*-----------------------------------------------------------*/ + +static void prvQueueSendTask( void *pvParameters ) +{ +portTickType xNextWakeTime; +const unsigned long ulValueToSend = 100UL; + + /* Check the task parameter is as expected. */ + configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_SEND_PARAMETER ); + + /* Initialise xNextWakeTime - this only needs to be done once. */ + xNextWakeTime = xTaskGetTickCount(); + + for( ;; ) + { + /* Place this task in the blocked state until it is time to run again. + The block time is specified in ticks, the constant used converts ticks + to ms. While in the Blocked state this task will not consume any CPU + time. */ + vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS ); + + /* Send to the queue - causing the queue receive task to unblock and + toggle the LED. 0 is used as the block time so the sending operation + will not block - it shouldn't need to block as the queue should always + be empty at this point in the code. */ + xQueueSend( xQueue, &ulValueToSend, 0U ); + } +} +/*-----------------------------------------------------------*/ + +static void prvQueueReceiveTask( void *pvParameters ) +{ +unsigned long ulReceivedValue; + + /* Check the task parameter is as expected. */ + configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_RECEIVE_PARAMETER ); + + for( ;; ) + { + /* Wait until something arrives in the queue - this task will block + indefinitely provided INCLUDE_vTaskSuspend is set to 1 in + FreeRTOSConfig.h. */ + xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY ); + + /* To get here something must have been received from the queue, but + is it the expected value? If it is, toggle the LED. */ + if( ulReceivedValue == 100UL ) + { + /* Toggle the LED. */ + port_pin_toggle_output_level( LED_0_PIN ); + ulReceivedValue = 0U; + } + } +} +/*-----------------------------------------------------------*/ + diff --git a/FreeRTOS/Demo/CORTEX_M0+_Atmel_SAMD20_XPlained/RTOSDemo/src/main-full.c b/FreeRTOS/Demo/CORTEX_M0+_Atmel_SAMD20_XPlained/RTOSDemo/src/main-full.c new file mode 100644 index 000000000..618bd8a83 --- /dev/null +++ b/FreeRTOS/Demo/CORTEX_M0+_Atmel_SAMD20_XPlained/RTOSDemo/src/main-full.c @@ -0,0 +1,327 @@ +/* + FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd. + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to distribute + >>! a combined work that includes FreeRTOS without being obliged to provide + >>! the source code for proprietary components outside of the FreeRTOS + >>! kernel. + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/****************************************************************************** + * NOTE 1: This project provides two demo applications. A simple blinky style + * project, and a more comprehensive test and demo application. The + * mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting in main.c is used to select + * between the two. See the notes on using mainCREATE_SIMPLE_BLINKY_DEMO_ONLY + * in main.c. This file implements the comprehensive test and demo version. + * + * NOTE 2: This file only contains the source code that is specific to the + * full demo. Generic functions, such FreeRTOS hook functions, and functions + * required to configure the hardware, are defined in main.c. + ****************************************************************************** + * + * main_full() creates a set of standard demo tasks, some application specific + * tasks, and a timer. It then starts the scheduler. The web documentation + * provides more details of the standard demo application tasks, which provide + * no particular functionality, but do provide a good example of how to use the + * FreeRTOS API. + * + * In addition to the standard demo tasks, the following tasks and timer are + * defined and/or created within this file: + * + * "Reg test" tasks - These fill the registers with known values, then check + * that each register maintains its expected value for the lifetime of the + * task. Each task uses a different set of values. The reg test tasks execute + * with a very low priority, so get preempted very frequently. A register + * containing an unexpected value is indicative of an error in the context + * switching mechanism. + * + * "Check" software timer - The check timer period is initially set to three + * seconds. Its callback function checks that all the standard demo tasks, and + * the register check tasks, are not only still executing, but are executing + * without reporting any errors. If the check timer callback discovers that a + * task has either stalled, or reported an error, then it changes the period of + * the check timer from the initial three seconds, to just 200ms. The callback + * function also toggles the LED each time it is called. This provides a + * visual indication of the system status: If the LED toggles every three + * seconds then no issues have been discovered. If the LED toggles every 200ms, + * then an issue has been discovered with at least one task. + */ + +/* Kernel includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "semphr.h" +#include "timers.h" + +/* Common demo includes. */ +#include "blocktim.h" +#include "countsem.h" +#include "recmutex.h" +#include "ParTest.h" +#include "dynamic.h" +#include "QueueOverwrite.h" +#include "QueueSet.h" +#include "GenQTest.h" +#include "QPeek.h" + +/* The period after which the check timer will expire provided no errors have +been reported by any of the standard demo tasks. ms are converted to the +equivalent in ticks using the portTICK_RATE_MS constant. */ +#define mainCHECK_TIMER_PERIOD_MS ( 3000UL / portTICK_RATE_MS ) + +/* The period at which the check timer will expire if an error has been +reported in one of the standard demo tasks. ms are converted to the equivalent +in ticks using the portTICK_RATE_MS constant. */ +#define mainERROR_CHECK_TIMER_PERIOD_MS ( 200UL / portTICK_RATE_MS ) + +/* A block time of zero simply means "don't block". */ +#define mainDONT_BLOCK ( 0UL ) + + +/*-----------------------------------------------------------*/ + +/* + * Register check tasks, as described at the top of this file. The nature of + * these files necessitates that they are written in an assembly. + */ +extern void vRegTest1Task( void *pvParameters ); +extern void vRegTest2Task( void *pvParameters ); + +/* + * Function that starts the command console. + */ +extern void vUARTCommandConsoleStart( uint16_t usStackSize, unsigned portBASE_TYPE uxPriority ); + +/* + * The check timer callback function, as described at the top of this file. + */ +static void prvCheckTimerCallback( xTimerHandle xTimer ); + +/* + * Called by main() to create the comprehensive test/demo application if + * mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is not set to 1. + */ +void main_full( void ); + +/*-----------------------------------------------------------*/ + +/* The following two variables are used to communicate the status of the +register check tasks to the check software timer. If the variables keep +incrementing, then the register check tasks has not discovered any errors. If +a variable stops incrementing, then an error has been found. */ +volatile unsigned long ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL; + +/*-----------------------------------------------------------*/ + +void main_full( void ) +{ +xTimerHandle xTimer = NULL; + +/* The register test tasks are asm functions that don't use a stack. The +stack allocated just has to be large enough to hold the task context, and +for the additional required for the stack overflow checking to work (if +configured). */ +const size_t xRegTestStackSize = 25U; + + /* Create the standard demo tasks */ + vCreateBlockTimeTasks(); + vStartDynamicPriorityTasks(); + vStartCountingSemaphoreTasks(); + vStartRecursiveMutexTasks(); + vStartQueueOverwriteTask( tskIDLE_PRIORITY ); + vStartQueueSetTasks(); + vStartGenericQueueTasks( tskIDLE_PRIORITY ); + vStartQueuePeekTasks(); + + /* Start the task that manages the command console for FreeRTOS+CLI. */ + vUARTCommandConsoleStart( ( configMINIMAL_STACK_SIZE * 3 ), tskIDLE_PRIORITY ); + + /* Create the register test tasks as described at the top of this file. + These are naked functions that don't use any stack. A stack still has + to be allocated to hold the task context. */ + xTaskCreate( vRegTest1Task, /* Function that implements the task. */ + ( signed char * ) "Reg1", /* Text name of the task. */ + xRegTestStackSize, /* Stack allocated to the task. */ + NULL, /* The task parameter is not used. */ + tskIDLE_PRIORITY, /* The priority to assign to the task. */ + NULL ); /* Don't receive a handle back, it is not needed. */ + + xTaskCreate( vRegTest2Task, /* Function that implements the task. */ + ( signed char * ) "Reg2", /* Text name of the task. */ + xRegTestStackSize, /* Stack allocated to the task. */ + NULL, /* The task parameter is not used. */ + tskIDLE_PRIORITY, /* The priority to assign to the task. */ + NULL ); /* Don't receive a handle back, it is not needed. */ + + /* Create the software timer that performs the 'check' functionality, + as described at the top of this file. */ + xTimer = xTimerCreate( ( const signed char * ) "CheckTimer",/* A text name, purely to help debugging. */ + ( mainCHECK_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */ + pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */ + ( void * ) 0, /* The ID is not used, so can be set to anything. */ + prvCheckTimerCallback /* The callback function that inspects the status of all the other tasks. */ + ); + + /* If the software timer was created successfully, start it. It won't + actually start running until the scheduler starts. A block time of + zero is used in this call, although any value could be used as the block + time will be ignored because the scheduler has not started yet. */ + if( xTimer != NULL ) + { + xTimerStart( xTimer, mainDONT_BLOCK ); + } + + /* Start the kernel. From here on, only tasks and interrupts will run. */ + vTaskStartScheduler(); + + /* If all is well, the scheduler will now be running, and the following + line will never be reached. If the following line does execute, then there + was insufficient FreeRTOS heap memory available for the idle and/or timer + tasks to be created. See the memory management section on the FreeRTOS web + site, or the FreeRTOS tutorial books for more details. */ + for( ;; ); +} +/*-----------------------------------------------------------*/ + +/* See the description at the top of this file. */ +static void prvCheckTimerCallback( xTimerHandle xTimer ) +{ +static long lChangedTimerPeriodAlready = pdFALSE; +static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0; +unsigned long ulErrorFound = pdFALSE; + + /* Check all the demo and test tasks to ensure that they are all still + running, and that none have detected an error. */ + if( xAreDynamicPriorityTasksStillRunning() != pdPASS ) + { + ulErrorFound |= ( 0x01UL << 0UL ); + } + + if( xAreBlockTimeTestTasksStillRunning() != pdPASS ) + { + ulErrorFound |= ( 0x01UL << 1UL ); + } + + if( xAreCountingSemaphoreTasksStillRunning() != pdPASS ) + { + ulErrorFound |= ( 0x01UL << 2UL ); + } + + if( xAreRecursiveMutexTasksStillRunning() != pdPASS ) + { + ulErrorFound |= ( 0x01UL << 3UL ); + } + + /* Check that the register test 1 task is still running. */ + if( ulLastRegTest1Value == ulRegTest1LoopCounter ) + { + ulErrorFound |= ( 0x01UL << 4UL ); + } + ulLastRegTest1Value = ulRegTest1LoopCounter; + + /* Check that the register test 2 task is still running. */ + if( ulLastRegTest2Value == ulRegTest2LoopCounter ) + { + ulErrorFound |= ( 0x01UL << 5UL ); + } + ulLastRegTest2Value = ulRegTest2LoopCounter; + + if( xAreQueueSetTasksStillRunning() != pdPASS ) + { + ulErrorFound |= ( 0x01UL << 6UL ); + } + + if( xIsQueueOverwriteTaskStillRunning() != pdPASS ) + { + ulErrorFound |= ( 0x01UL << 7UL ); + } + + if( xAreGenericQueueTasksStillRunning() != pdPASS ) + { + ulErrorFound |= ( 0x01UL << 8UL ); + } + + if( xAreQueuePeekTasksStillRunning() != pdPASS ) + { + ulErrorFound |= ( 0x01UL << 9UL ); + } + + /* Toggle the check LED to give an indication of the system status. If + the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then + everything is ok. A faster toggle indicates an error. */ + port_pin_toggle_output_level( LED_0_PIN ); + + /* Have any errors been latched in ulErrorFound? If so, shorten the + period of the check timer to mainERROR_CHECK_TIMER_PERIOD_MS milliseconds. + This will result in an increase in the rate at which the LED toggles. */ + if( ulErrorFound != pdFALSE ) + { + if( lChangedTimerPeriodAlready == pdFALSE ) + { + lChangedTimerPeriodAlready = pdTRUE; + + /* This call to xTimerChangePeriod() uses a zero block time. + Functions called from inside of a timer callback function must + *never* attempt to block. */ + xTimerChangePeriod( xTimer, ( mainERROR_CHECK_TIMER_PERIOD_MS ), mainDONT_BLOCK ); + } + } +} +/*-----------------------------------------------------------*/ + diff --git a/FreeRTOS/Demo/CORTEX_M0+_Atmel_SAMD20_XPlained/RTOSDemo/src/main.c b/FreeRTOS/Demo/CORTEX_M0+_Atmel_SAMD20_XPlained/RTOSDemo/src/main.c index b916b791e..080586c31 100644 --- a/FreeRTOS/Demo/CORTEX_M0+_Atmel_SAMD20_XPlained/RTOSDemo/src/main.c +++ b/FreeRTOS/Demo/CORTEX_M0+_Atmel_SAMD20_XPlained/RTOSDemo/src/main.c @@ -62,6 +62,22 @@ 1 tab == 4 spaces! */ +/****************************************************************************** + * This project provides two demo applications. A simple blinky style project, + * and a more comprehensive test and demo application. The + * mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting (defined in this file) is used to + * select between the two. The simply blinky demo is implemented and described + * in main_blinky.c. The more comprehensive test and demo application is + * implemented and described in main_full.c. + * + * This file implements the code that is not demo specific, including the + * hardware setup and FreeRTOS hook functions. It also contains a dummy + * interrupt service routine called Dummy_IRQHandler() that is provided as an + * example of how to use interrupt safe FreeRTOS API functions (those that end + * in "FromISR"). + * + *****************************************************************************/ + /* FreeRTOS includes. */ #include "FreeRTOS.h" #include "task.h" @@ -69,13 +85,21 @@ /* Demo app includes. */ #include "UARTCommandConsole.h" +/* Demo application include. */ +#include "QueueSet.h" + /* Library includes. */ #include +/* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo, +or 0 to run the more comprehensive test and demo application. */ +#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 0 + /*-----------------------------------------------------------*/ /* - * Hardware and driver initialisation can be done in this function. + * Perform any application specific hardware configuration. The clocks, + * memory, etc. are configured before main() is called. */ static void prvSetupHardware( void ); @@ -88,6 +112,13 @@ void vApplicationIdleHook( void ); void vApplicationStackOverflowHook( xTaskHandle pxTask, signed char *pcTaskName ); void vApplicationTickHook( void ); +/* + * main_blinky() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 1. + * main_full() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 0. + */ +extern void main_blinky( void ); +extern void main_full( void ); + /*-----------------------------------------------------------*/ /* Used in the run time stats calculations. */ @@ -97,23 +128,26 @@ static unsigned long ulClocksPer10thOfAMilliSecond = 0UL; int main (void) { + /* Prepare the hardware for the demo. */ prvSetupHardware(); - vUARTCommandConsoleStart( ( configMINIMAL_STACK_SIZE * 3 ), tskIDLE_PRIORITY ); - - /* Start the scheduler. */ - vTaskStartScheduler(); - - /* If all is well, the scheduler will now be running, and the following line - will never be reached. If the following line does execute, then there was - insufficient FreeRTOS heap memory available for the idle and/or timer tasks - to be created. See the memory management section on the FreeRTOS web site - for more details. */ - for( ;; ); + + /* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top + of this file. */ + #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 + { + main_blinky(); + } + #else + { + main_full(); + } + #endif } /*-----------------------------------------------------------*/ static void prvSetupHardware( void ) { + /* Initialisation is performed by the Atmel board support package. */ system_init(); } /*-----------------------------------------------------------*/ @@ -168,7 +202,22 @@ void vApplicationTickHook( void ) configUSE_TICK_HOOK is set to 1 in FreeRTOSConfig.h. User code can be added here, but the tick hook is called from an interrupt context, so code must not attempt to block, and only the interrupt safe FreeRTOS API - functions can be used (those that end in FromISR()). */ + functions can be used (those that end in FromISR()). The code in this + tick hook implementation is for demonstration only - it has no real + purpose. It just gives a semaphore every 50ms. The semaphore unblocks a + task that then toggles an LED. Additionally, the call to + vQueueSetAccessQueueSetFromISR() is part of the "standard demo tasks" + functionality. */ + + /* The semaphore and associated task are not created when the simple blinky + demo is used. */ + #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0 + { + /* Write to a queue that is in use as part of the queue set demo to + demonstrate using queue sets from an ISR. */ + vQueueSetAccessQueueSetFromISR(); + } + #endif /* mainCREATE_SIMPLE_BLINKY_DEMO_ONLY */ } /*-----------------------------------------------------------*/ diff --git a/FreeRTOS/Demo/CORTEX_M0+_Atmel_SAMD20_XPlained/RTOSDemo/src/printf-stdarg.c b/FreeRTOS/Demo/CORTEX_M0+_Atmel_SAMD20_XPlained/RTOSDemo/src/printf-stdarg.c new file mode 100644 index 000000000..b5ac41be7 --- /dev/null +++ b/FreeRTOS/Demo/CORTEX_M0+_Atmel_SAMD20_XPlained/RTOSDemo/src/printf-stdarg.c @@ -0,0 +1,293 @@ +/* + 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 void printchar(char **str, int c) +{ + //extern int putchar(int c); + + if (str) { + **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) +{ + 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); + ++pc; + } + } + for ( ; *string ; ++string) { + printchar (out, *string); + ++pc; + } + for ( ; width > 0; --width) { + printchar (out, padchar); + ++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 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); + } + + 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, '-'); + ++pc; + --width; + } + else { + *--s = '-'; + } + } + + return pc + prints (out, s, width, pad); +} + +static int print( char **out, const char *format, va_list args ) +{ + register int width, pad; + register int pc = 0; + char scr[2]; + + 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); + continue; + } + if( *format == 'd' ) { + pc += printi (out, va_arg( args, int ), 10, 1, width, pad, 'a'); + continue; + } + if( *format == 'x' ) { + pc += printi (out, va_arg( args, int ), 16, 0, width, pad, 'a'); + continue; + } + if( *format == 'X' ) { + pc += printi (out, va_arg( args, int ), 16, 0, width, pad, 'A'); + continue; + } + if( *format == 'u' ) { + pc += printi (out, va_arg( args, int ), 10, 0, width, pad, 'a'); + 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); + continue; + } + } + else { + out: + printchar (out, *format); + ++pc; + } + } + if (out) **out = '\0'; + va_end( args ); + return pc; +} + +int printf(const char *format, ...) +{ + va_list args; + + va_start( args, format ); + return print( 0, format, args ); +} + +int sprintf(char *out, const char *format, ...) +{ + va_list args; + + va_start( args, format ); + return print( &out, format, args ); +} + + +int snprintf( char *buf, unsigned int count, const char *format, ... ) +{ + va_list args; + + ( void ) count; + + va_start( args, format ); + return print( &buf, format, args ); +} + + +#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_M0_Infineon_XMC1000_IAR_Keil_GCC/Atollic_Specific/RegTest.c b/FreeRTOS/Demo/CORTEX_M0_Infineon_XMC1000_IAR_Keil_GCC/Atollic_Specific/RegTest.c index f0bbd2bdb..5faf19e59 100644 --- a/FreeRTOS/Demo/CORTEX_M0_Infineon_XMC1000_IAR_Keil_GCC/Atollic_Specific/RegTest.c +++ b/FreeRTOS/Demo/CORTEX_M0_Infineon_XMC1000_IAR_Keil_GCC/Atollic_Specific/RegTest.c @@ -62,6 +62,15 @@ 1 tab == 4 spaces! */ +/* + * "Reg test" tasks - These fill the registers with known values, then check + * that each register maintains its expected value for the lifetime of the + * task. Each task uses a different set of values. The reg test tasks execute + * with a very low priority, so get preempted very frequently. A register + * containing an unexpected value is indicative of an error in the context + * switching mechanism. + */ + void vRegTest1Task( void ) __attribute__((naked)); void vRegTest2Task( void ) __attribute__((naked)); diff --git a/FreeRTOS/Demo/CORTEX_M0_Infineon_XMC1000_IAR_Keil_GCC/IAR_Specific/RegTest_IAR.s b/FreeRTOS/Demo/CORTEX_M0_Infineon_XMC1000_IAR_Keil_GCC/IAR_Specific/RegTest_IAR.s index b22027bc4..606587a01 100644 --- a/FreeRTOS/Demo/CORTEX_M0_Infineon_XMC1000_IAR_Keil_GCC/IAR_Specific/RegTest_IAR.s +++ b/FreeRTOS/Demo/CORTEX_M0_Infineon_XMC1000_IAR_Keil_GCC/IAR_Specific/RegTest_IAR.s @@ -62,6 +62,15 @@ 1 tab == 4 spaces! */ +/* + * "Reg test" tasks - These fill the registers with known values, then check + * that each register maintains its expected value for the lifetime of the + * task. Each task uses a different set of values. The reg test tasks execute + * with a very low priority, so get preempted very frequently. A register + * containing an unexpected value is indicative of an error in the context + * switching mechanism. + */ + RSEG CODE:CODE(2) thumb diff --git a/FreeRTOS/Demo/CORTEX_M0_Infineon_XMC1000_IAR_Keil_GCC/Keil_Specific/RegTest_Keil.s b/FreeRTOS/Demo/CORTEX_M0_Infineon_XMC1000_IAR_Keil_GCC/Keil_Specific/RegTest_Keil.s index a51261c15..7bddfb51a 100644 --- a/FreeRTOS/Demo/CORTEX_M0_Infineon_XMC1000_IAR_Keil_GCC/Keil_Specific/RegTest_Keil.s +++ b/FreeRTOS/Demo/CORTEX_M0_Infineon_XMC1000_IAR_Keil_GCC/Keil_Specific/RegTest_Keil.s @@ -62,6 +62,15 @@ ; 1 tab == 4 spaces! ;*/ +;/* +; * "Reg test" tasks - These fill the registers with known values, then check +; * that each register maintains its expected value for the lifetime of the +; * task. Each task uses a different set of values. The reg test tasks execute +; * with a very low priority, so get preempted very frequently. A register +; * containing an unexpected value is indicative of an error in the context +; * switching mechanism. +; */ + PRESERVE8 THUMB