mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-19 21:11:57 -04:00
Complete SAMD20 demo - still needs tidy up.
Add comments to the XMC1000 reg test files.
This commit is contained in:
parent
0c56f5018d
commit
41a1dc62b7
Binary file not shown.
|
@ -403,6 +403,7 @@
|
||||||
<Value>../../../../Source/include</Value>
|
<Value>../../../../Source/include</Value>
|
||||||
<Value>../../../../Source/portable/GCC/ARM_CM0</Value>
|
<Value>../../../../Source/portable/GCC/ARM_CM0</Value>
|
||||||
<Value>../../../../../FreeRTOS-Plus/Source/FreeRTOS-Plus-CLI</Value>
|
<Value>../../../../../FreeRTOS-Plus/Source/FreeRTOS-Plus-CLI</Value>
|
||||||
|
<Value>../../../Common/include</Value>
|
||||||
</ListValues>
|
</ListValues>
|
||||||
</armgcc.compiler.directories.IncludePaths>
|
</armgcc.compiler.directories.IncludePaths>
|
||||||
<armgcc.compiler.optimization.OtherFlags>-fdata-sections</armgcc.compiler.optimization.OtherFlags>
|
<armgcc.compiler.optimization.OtherFlags>-fdata-sections</armgcc.compiler.optimization.OtherFlags>
|
||||||
|
@ -498,6 +499,49 @@
|
||||||
<GenerateEepFile>True</GenerateEepFile>
|
<GenerateEepFile>True</GenerateEepFile>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="..\..\Common\Minimal\blocktim.c">
|
||||||
|
<SubType>compile</SubType>
|
||||||
|
<Link>src\Common-Demo-Tasks\blocktim.c</Link>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="..\..\Common\Minimal\countsem.c">
|
||||||
|
<SubType>compile</SubType>
|
||||||
|
<Link>src\Common-Demo-Tasks\countsem.c</Link>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="..\..\Common\Minimal\dynamic.c">
|
||||||
|
<SubType>compile</SubType>
|
||||||
|
<Link>src\Common-Demo-Tasks\dynamic.c</Link>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="..\..\Common\Minimal\GenQTest.c">
|
||||||
|
<SubType>compile</SubType>
|
||||||
|
<Link>src\Common-Demo-Tasks\GenQTest.c</Link>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="..\..\Common\Minimal\QueueOverwrite.c">
|
||||||
|
<SubType>compile</SubType>
|
||||||
|
<Link>src\Common-Demo-Tasks\QueueOverwrite.c</Link>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="..\..\Common\Minimal\QueueSet.c">
|
||||||
|
<SubType>compile</SubType>
|
||||||
|
<Link>src\Common-Demo-Tasks\QueueSet.c</Link>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="..\..\Common\Minimal\recmutex.c">
|
||||||
|
<SubType>compile</SubType>
|
||||||
|
<Link>src\Common-Demo-Tasks\recmutex.c</Link>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="src\Common-Demo-Tasks\QPeek.c">
|
||||||
|
<SubType>compile</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="src\main-blinky.c">
|
||||||
|
<SubType>compile</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="src\main-full.c">
|
||||||
|
<SubType>compile</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="src\printf-stdarg.c">
|
||||||
|
<SubType>compile</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="src\RegTest.c">
|
||||||
|
<SubType>compile</SubType>
|
||||||
|
</Compile>
|
||||||
<Compile Include="src\Sample-CLI-commands.c">
|
<Compile Include="src\Sample-CLI-commands.c">
|
||||||
<SubType>compile</SubType>
|
<SubType>compile</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
@ -651,9 +695,9 @@
|
||||||
<Compile Include="src\ASF\sam0\utils\cmsis\samd20\source\system_samd20.c">
|
<Compile Include="src\ASF\sam0\utils\cmsis\samd20\source\system_samd20.c">
|
||||||
<SubType>compile</SubType>
|
<SubType>compile</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="src\ASF\sam0\utils\syscalls\gcc\syscalls.c">
|
<None Include="src\ASF\sam0\utils\syscalls\gcc\syscalls.c">
|
||||||
<SubType>compile</SubType>
|
<SubType>compile</SubType>
|
||||||
</Compile>
|
</None>
|
||||||
<None Include="src\asf.h">
|
<None Include="src\asf.h">
|
||||||
<SubType>compile</SubType>
|
<SubType>compile</SubType>
|
||||||
</None>
|
</None>
|
||||||
|
@ -1055,6 +1099,7 @@
|
||||||
<Folder Include="src\FreeRTOS-Source\include" />
|
<Folder Include="src\FreeRTOS-Source\include" />
|
||||||
<Folder Include="src\FreeRTOS-Source\portable" />
|
<Folder Include="src\FreeRTOS-Source\portable" />
|
||||||
<Folder Include="src\FreeRTOS-CLI" />
|
<Folder Include="src\FreeRTOS-CLI" />
|
||||||
|
<Folder Include="src\Common-Demo-Tasks" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(AVRSTUDIO_EXE_PATH)\\Vs\\Compiler.targets" />
|
<Import Project="$(AVRSTUDIO_EXE_PATH)\\Vs\\Compiler.targets" />
|
||||||
</Project>
|
</Project>
|
|
@ -59,6 +59,7 @@ static void (*_sercom_interrupt_handlers[SERCOM_INST_NUM])(const uint8_t instanc
|
||||||
static void _sercom_default_handler(
|
static void _sercom_default_handler(
|
||||||
const uint8_t instance)
|
const uint8_t instance)
|
||||||
{
|
{
|
||||||
|
( void ) instance;
|
||||||
Assert(false);
|
Assert(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -482,8 +482,11 @@ void _usart_interrupt_handler(
|
||||||
module->tx_status = STATUS_OK;
|
module->tx_status = STATUS_OK;
|
||||||
|
|
||||||
/* Run callback if registered and enabled */
|
/* Run callback if registered and enabled */
|
||||||
if (callback_status & (1 << USART_CALLBACK_BUFFER_TRANSMITTED)) {
|
if( module->remaining_tx_buffer_length == 0 ) /* Added by _RB_ */
|
||||||
(*(module->callback[USART_CALLBACK_BUFFER_TRANSMITTED]))(module);
|
{
|
||||||
|
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
|
/* Check if the Receive Complete interrupt has occurred, and that
|
||||||
|
|
|
@ -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"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -78,17 +78,16 @@
|
||||||
* See http://www.freertos.org/a00110.html.
|
* See http://www.freertos.org/a00110.html.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <asf.h>
|
||||||
extern uint32_t SystemCoreClock;
|
|
||||||
|
|
||||||
#define configUSE_PREEMPTION 1
|
#define configUSE_PREEMPTION 1
|
||||||
#define configUSE_IDLE_HOOK 0
|
#define configUSE_IDLE_HOOK 0
|
||||||
#define configUSE_TICK_HOOK 1
|
#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 configTICK_RATE_HZ ( ( portTickType ) 500 )
|
||||||
#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 5 )
|
#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 5 )
|
||||||
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 60 )
|
#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 configMAX_TASK_NAME_LEN ( 5 )
|
||||||
#define configUSE_TRACE_FACILITY 1
|
#define configUSE_TRACE_FACILITY 1
|
||||||
#define configUSE_16_BIT_TICKS 0
|
#define configUSE_16_BIT_TICKS 0
|
||||||
|
|
|
@ -47,7 +47,7 @@
|
||||||
|
|
||||||
/* System clock bus configuration */
|
/* System clock bus configuration */
|
||||||
# define CONF_CLOCK_CPU_CLOCK_FAILURE_DETECT true
|
# 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_CPU_DIVIDER SYSTEM_MAIN_CLOCK_DIV_1
|
||||||
# define CONF_CLOCK_APBA_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
|
# define CONF_CLOCK_APBB_DIVIDER SYSTEM_MAIN_CLOCK_DIV_1
|
||||||
|
@ -86,8 +86,8 @@
|
||||||
# define CONF_CLOCK_OSC32K_RUN_IN_STANDBY false
|
# define CONF_CLOCK_OSC32K_RUN_IN_STANDBY false
|
||||||
|
|
||||||
/* SYSTEM_CLOCK_SOURCE_DFLL configuration - Digital Frequency Locked Loop */
|
/* SYSTEM_CLOCK_SOURCE_DFLL configuration - Digital Frequency Locked Loop */
|
||||||
# define CONF_CLOCK_DFLL_ENABLE false
|
# define CONF_CLOCK_DFLL_ENABLE true
|
||||||
# define CONF_CLOCK_DFLL_LOOP_MODE SYSTEM_CLOCK_DFLL_LOOP_MODE_OPEN
|
# define CONF_CLOCK_DFLL_LOOP_MODE SYSTEM_CLOCK_DFLL_LOOP_MODE_CLOSED
|
||||||
# define CONF_CLOCK_DFLL_ON_DEMAND false
|
# define CONF_CLOCK_DFLL_ON_DEMAND false
|
||||||
# define CONF_CLOCK_DFLL_RUN_IN_STANDBY false
|
# define CONF_CLOCK_DFLL_RUN_IN_STANDBY false
|
||||||
|
|
||||||
|
@ -113,12 +113,12 @@
|
||||||
/* Configure GCLK generator 0 (Main Clock) */
|
/* Configure GCLK generator 0 (Main Clock) */
|
||||||
# define CONF_CLOCK_GCLK_0_ENABLE true
|
# define CONF_CLOCK_GCLK_0_ENABLE true
|
||||||
# define CONF_CLOCK_GCLK_0_RUN_IN_STANDBY false
|
# 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_PRESCALER 1
|
||||||
# define CONF_CLOCK_GCLK_0_OUTPUT_ENABLE false
|
# define CONF_CLOCK_GCLK_0_OUTPUT_ENABLE false
|
||||||
|
|
||||||
/* Configure GCLK generator 1 */
|
/* 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_RUN_IN_STANDBY false
|
||||||
# define CONF_CLOCK_GCLK_1_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC8M
|
# define CONF_CLOCK_GCLK_1_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC8M
|
||||||
# define CONF_CLOCK_GCLK_1_PRESCALER 1
|
# define CONF_CLOCK_GCLK_1_PRESCALER 1
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
|
@ -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 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
|
@ -62,6 +62,22 @@
|
||||||
1 tab == 4 spaces!
|
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. */
|
/* FreeRTOS includes. */
|
||||||
#include "FreeRTOS.h"
|
#include "FreeRTOS.h"
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
|
@ -69,13 +85,21 @@
|
||||||
/* Demo app includes. */
|
/* Demo app includes. */
|
||||||
#include "UARTCommandConsole.h"
|
#include "UARTCommandConsole.h"
|
||||||
|
|
||||||
|
/* Demo application include. */
|
||||||
|
#include "QueueSet.h"
|
||||||
|
|
||||||
/* Library includes. */
|
/* Library includes. */
|
||||||
#include <asf.h>
|
#include <asf.h>
|
||||||
|
|
||||||
|
/* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo,
|
||||||
|
or 0 to run the more comprehensive test and demo application. */
|
||||||
|
#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 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 );
|
static void prvSetupHardware( void );
|
||||||
|
|
||||||
|
@ -88,6 +112,13 @@ void vApplicationIdleHook( void );
|
||||||
void vApplicationStackOverflowHook( xTaskHandle pxTask, signed char *pcTaskName );
|
void vApplicationStackOverflowHook( xTaskHandle pxTask, signed char *pcTaskName );
|
||||||
void vApplicationTickHook( void );
|
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. */
|
/* Used in the run time stats calculations. */
|
||||||
|
@ -97,23 +128,26 @@ static unsigned long ulClocksPer10thOfAMilliSecond = 0UL;
|
||||||
|
|
||||||
int main (void)
|
int main (void)
|
||||||
{
|
{
|
||||||
|
/* Prepare the hardware for the demo. */
|
||||||
prvSetupHardware();
|
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
|
/* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top
|
||||||
will never be reached. If the following line does execute, then there was
|
of this file. */
|
||||||
insufficient FreeRTOS heap memory available for the idle and/or timer tasks
|
#if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1
|
||||||
to be created. See the memory management section on the FreeRTOS web site
|
{
|
||||||
for more details. */
|
main_blinky();
|
||||||
for( ;; );
|
}
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
main_full();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static void prvSetupHardware( void )
|
static void prvSetupHardware( void )
|
||||||
{
|
{
|
||||||
|
/* Initialisation is performed by the Atmel board support package. */
|
||||||
system_init();
|
system_init();
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -168,7 +202,22 @@ void vApplicationTickHook( void )
|
||||||
configUSE_TICK_HOOK is set to 1 in FreeRTOSConfig.h. User code can be
|
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
|
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
|
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 */
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
|
@ -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 <stdarg.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -62,6 +62,15 @@
|
||||||
1 tab == 4 spaces!
|
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 vRegTest1Task( void ) __attribute__((naked));
|
||||||
void vRegTest2Task( void ) __attribute__((naked));
|
void vRegTest2Task( void ) __attribute__((naked));
|
||||||
|
|
||||||
|
|
|
@ -62,6 +62,15 @@
|
||||||
1 tab == 4 spaces!
|
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)
|
RSEG CODE:CODE(2)
|
||||||
thumb
|
thumb
|
||||||
|
|
||||||
|
|
|
@ -62,6 +62,15 @@
|
||||||
; 1 tab == 4 spaces!
|
; 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
|
PRESERVE8
|
||||||
THUMB
|
THUMB
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue