diff --git a/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/.cproject b/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/.cproject
index bf4326f6c..3b5e4b445 100644
--- a/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/.cproject
+++ b/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/.cproject
@@ -32,8 +32,9 @@
diff --git a/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/.project b/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/.project
index 4431c9a66..dc088d707 100644
--- a/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/.project
+++ b/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/.project
@@ -25,40 +25,58 @@
- src/FreeRTOS-Plus-CLI
+ src/FreeRTOS_Source2
- FREERTOS_ROOT/FreeRTOS-Plus/Source/FreeRTOS-Plus-CLI
+ FREERTOS_ROOT/FreeRTOS/Source
- src/FreeRTOS_Source
+ src/Full_Demo/FreeRTOS-Plus-CLI2
- FREERTOS_ROOT/FreeRTOS/Source
+ FREERTOS_ROOT/FreeRTOS-Plus/Source/FreeRTOS-Plus-CLI
- src/Sample-CLI-commands.c
+ src/Full_Demo/Sample-CLI-commands.c1FREERTOS_ROOT/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_CLI_Demos/Sample-CLI-commands.c
- src/Standard_Demo_Tasks
+ src/Full_Demo/Standard_Demo_Tasks2FREERTOS_ROOT/FreeRTOS/Demo/Common
- src/UARTCommandConsole.c
+ src/Full_Demo/UARTCommandConsole.c1FREERTOS_ROOT/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_CLI_Demos/UARTCommandConsole.c
- src/Standard_Demo_Tasks/IntQueue.c
+ src/Full_Demo/Standard_Demo_Tasks/IntQueue.c1FREERTOS_ROOT/FreeRTOS/Demo/Common/Minimal/IntQueue.c
- 1390227891704
- src/Standard_Demo_Tasks
+ 1390074074500
+ src/FreeRTOS_Source/portable
+ 9
+
+ org.eclipse.ui.ide.multiFilter
+ 1.0-name-matches-false-false-MemMang
+
+
+
+ 1390074074500
+ src/FreeRTOS_Source/portable
+ 9
+
+ org.eclipse.ui.ide.multiFilter
+ 1.0-name-matches-false-false-GCC
+
+
+
+ 0
+ src/Full_Demo/Standard_Demo_Tasks9org.eclipse.ui.ide.multiFilter
@@ -66,8 +84,8 @@
- 1390227891720
- src/Standard_Demo_Tasks
+ 0
+ src/Full_Demo/Standard_Demo_Tasks9org.eclipse.ui.ide.multiFilter
@@ -75,26 +93,26 @@
- 1390074074500
- src/FreeRTOS_Source/portable
+ 1390074123406
+ src/FreeRTOS_Source/portable/GCC9org.eclipse.ui.ide.multiFilter
- 1.0-name-matches-false-false-MemMang
+ 1.0-name-matches-false-false-ARM_CA9
- 1390074074500
- src/FreeRTOS_Source/portable
- 9
+ 1390074099015
+ src/FreeRTOS_Source/portable/MemMang
+ 5org.eclipse.ui.ide.multiFilter
- 1.0-name-matches-false-false-GCC
+ 1.0-name-matches-false-false-heap_4.c
- 1390228639904
- src/Standard_Demo_Tasks/Minimal
+ 0
+ src/Full_Demo/Standard_Demo_Tasks/Minimal6org.eclipse.ui.ide.multiFilter
@@ -102,8 +120,8 @@
- 1390228639904
- src/Standard_Demo_Tasks/Minimal
+ 0
+ src/Full_Demo/Standard_Demo_Tasks/Minimal6org.eclipse.ui.ide.multiFilter
@@ -111,8 +129,8 @@
- 1390228639904
- src/Standard_Demo_Tasks/Minimal
+ 0
+ src/Full_Demo/Standard_Demo_Tasks/Minimal6org.eclipse.ui.ide.multiFilter
@@ -120,8 +138,8 @@
- 1390228639904
- src/Standard_Demo_Tasks/Minimal
+ 0
+ src/Full_Demo/Standard_Demo_Tasks/Minimal6org.eclipse.ui.ide.multiFilter
@@ -129,8 +147,8 @@
- 1390228639904
- src/Standard_Demo_Tasks/Minimal
+ 0
+ src/Full_Demo/Standard_Demo_Tasks/Minimal6org.eclipse.ui.ide.multiFilter
@@ -138,30 +156,21 @@
- 1390227918703
- src/Standard_Demo_Tasks/include
+ 0
+ src/Full_Demo/Standard_Demo_Tasks/Minimal6org.eclipse.ui.ide.multiFilter
- 1.0-name-matches-false-false-alt*.*
+ 1.0-name-matches-false-false-copy*.*
- 1390074123406
- src/FreeRTOS_Source/portable/GCC
- 9
-
- org.eclipse.ui.ide.multiFilter
- 1.0-name-matches-false-false-ARM_CA9
-
-
-
- 1390074099015
- src/FreeRTOS_Source/portable/MemMang
- 5
+ 0
+ src/Full_Demo/Standard_Demo_Tasks/include
+ 6org.eclipse.ui.ide.multiFilter
- 1.0-name-matches-false-false-heap_4.c
+ 1.0-name-matches-false-false-alt*.*
diff --git a/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/main_blinky.c b/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/Blinky_Demo/main_blinky.c
similarity index 100%
rename from FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/main_blinky.c
rename to FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/Blinky_Demo/main_blinky.c
diff --git a/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/FreeRTOSConfig.h b/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/FreeRTOSConfig.h
index 9130dc805..b37a4e40f 100644
--- a/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/FreeRTOSConfig.h
+++ b/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/FreeRTOSConfig.h
@@ -115,7 +115,7 @@
#define configUSE_PREEMPTION 1
#define configUSE_IDLE_HOOK 1
#define configUSE_TICK_HOOK 1
-#define configMAX_PRIORITIES ( 5 )
+#define configMAX_PRIORITIES ( 7 )
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 160 )
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 51200 ) )
#define configMAX_TASK_NAME_LEN ( 10 )
@@ -151,7 +151,7 @@ to exclude the API function. */
#define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1
#define INCLUDE_eTaskGetState 1
-#define INCLUDE_xTimerPendFunctionCall 1
+#define INCLUDE_xTimerPendFunctionCall 1
/* This demo makes use of one or more example stats formatting functions. These
format the raw data provided by the uxTaskGetSystemState() function in to human
diff --git a/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/FreeRTOS_tick_config.c b/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/FreeRTOS_tick_config.c
index 0134d31d7..fb2796f19 100644
--- a/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/FreeRTOS_tick_config.c
+++ b/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/FreeRTOS_tick_config.c
@@ -150,11 +150,12 @@ const XScuGic_VectorTableEntry *pxVectorEntry;
/* The ID of the interrupt is obtained by bitwise anding the ICCIAR value
with 0x3FF. */
ulInterruptID = ulICCIAR & 0x3FFUL;
- configASSERT( ulInterruptID < XSCUGIC_MAX_NUM_INTR_INPUTS );
-
- /* Call the function installed in the array of installed handler functions. */
- pxVectorEntry = &( pxVectorTable[ ulInterruptID ] );
- pxVectorEntry->Handler( pxVectorEntry->CallBackRef );
+ if( ulInterruptID < XSCUGIC_MAX_NUM_INTR_INPUTS )
+ {
+ /* Call the function installed in the array of installed handler functions. */
+ pxVectorEntry = &( pxVectorTable[ ulInterruptID ] );
+ pxVectorEntry->Handler( pxVectorEntry->CallBackRef );
+ }
}
diff --git a/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/IntQueueTimer.c b/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/Full_Demo/IntQueueTimer.c
similarity index 97%
rename from FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/IntQueueTimer.c
rename to FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/Full_Demo/IntQueueTimer.c
index 1a24a4cba..d41e7f1d7 100644
--- a/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/IntQueueTimer.c
+++ b/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/Full_Demo/IntQueueTimer.c
@@ -139,7 +139,8 @@ static const UBaseType_t uxInterruptPriorities[ tmrTIMERS_USED ] =
configMAX_API_CALL_INTERRUPT_PRIORITY + 1,
configMAX_API_CALL_INTERRUPT_PRIORITY,
configMAX_API_CALL_INTERRUPT_PRIORITY - 1
-}
+};
+
static XTtcPs xTimerInstances[ tmrTIMERS_USED ];
/* Used to provide a means of ensuring the intended interrupt nesting depth is
diff --git a/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/IntQueueTimer.h b/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/Full_Demo/IntQueueTimer.h
similarity index 100%
rename from FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/IntQueueTimer.h
rename to FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/Full_Demo/IntQueueTimer.h
diff --git a/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/main_full.c b/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/Full_Demo/main_full.c
similarity index 86%
rename from FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/main_full.c
rename to FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/Full_Demo/main_full.c
index f6f632573..18e359506 100644
--- a/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/main_full.c
+++ b/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/Full_Demo/main_full.c
@@ -74,6 +74,13 @@
* full demo. Generic functions, such FreeRTOS hook functions, and functions
* required to configure the hardware, are defined in main.c.
*
+ * NOTE 3: The full demo includes a test that checks the floating point context
+ * is maintained correctly across task switches. The standard GCC libraries can
+ * use floating point registers and made this test fail (unless the tasks that
+ * use the library are given a floating point context as described on the
+ * documentation page for this demo). printf-stdarg.c is included in this
+ * project to prevent the standard GCC libraries being linked into the project.
+ *
******************************************************************************
*
* main_full() creates all the demo application tasks and software timers, then
@@ -84,22 +91,13 @@
* In addition to the standard demo tasks, the following tasks and tests are
* defined and/or created within this file:
*
- * FreeRTOS+CLI command console. The command console is access through UART2
- * using 115200 baud if mainINCLUDE_FAT_SL_DEMO is set to 1. For reasons of
- * robustness testing the UART driver is deliberately written to be inefficient
- * and should not be used as a template for a production driver. Type "help" to
- * see a list of registered commands. The FreeRTOS+CLI license is different to
- * the FreeRTOS license, see http://www.FreeRTOS.org/cli for license and usage
- * details.
- *
- * FreeRTOS+FAT SL. FreeRTOS+FAT SL is demonstrated using a RAM disk if
- * mainINCLUDE_FAT_SL_DEMO is set to 1. [At the time of writing] The
- * functionality of the file system demo is identical to the functionality of
- * the FreeRTOS Win32 simulator file system demo, with the command console being
- * accessed via the UART (as described above) instead of a network terminal.
- * The FreeRTOS+FAT SL license is different to the FreeRTOS license, see
- * http://www.FreeRTOS.org/fat_sl for license and usage details, and a
- * description of the file system demo functionality.
+ * FreeRTOS+CLI command console. The command console is access through the
+ * UART to USB connector on the ZC702 Zynq development board (marked J2). For
+ * reasons of robustness testing the UART driver is deliberately written to be
+ * inefficient and should not be used as a template for a production driver.
+ * Type "help" to see a list of registered commands. The FreeRTOS+CLI license
+ * is different to the FreeRTOS license, see http://www.FreeRTOS.org/cli for
+ * license and usage details. The default baud rate is 115200.
*
* "Reg test" tasks - These fill both the core and floating point registers with
* known values, then check that each register maintains its expected value for
@@ -146,9 +144,6 @@
#include "QueueOverwrite.h"
#include "IntQueue.h"
-/* FreeRTOS+CLI and FreeRTOS+FAT SL includes. */
-//#include "UARTCommandConsole.h"
-
/* Priorities for the demo application tasks. */
#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1UL )
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2UL )
@@ -168,20 +163,15 @@
/* A block time of zero simply means "don't block". */
#define mainDONT_BLOCK ( 0UL )
-/* In this example the baud rate is hard coded and there is no LED for use by
-the COM test tasks, so just set both to invalid values. */
-#define mainCOM_TEST_LED ( 100 )
-#define mainBAUD_RATE ( 0 )
-
/* The period after which the check timer will expire, in ms, 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 mainNO_ERROR_CHECK_TASK_PERIOD ( 3000UL / portTICK_RATE_MS )
+equivalent in ticks using the portTICK_PERIOD_MS constant. */
+#define mainNO_ERROR_CHECK_TASK_PERIOD ( 3000UL / portTICK_PERIOD_MS )
/* The period at which the check timer will expire, in ms, 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_TASK_PERIOD ( 200UL / portTICK_RATE_MS )
+in ticks using the portTICK_PERIOD_MS constant. */
+#define mainERROR_CHECK_TASK_PERIOD ( 200UL / portTICK_PERIOD_MS )
/* Parameters that are passed into the register check tasks solely for the
purpose of ensuring parameters are passed into tasks correctly. */
@@ -191,12 +181,6 @@ purpose of ensuring parameters are passed into tasks correctly. */
/* The base period used by the timer test tasks. */
#define mainTIMER_TEST_PERIOD ( 50 )
-/* The length of queues used to pass characters into and out of the UART
-interrupt. Note the comments above about the UART driver being implemented in
-this way to test the kernel robustness rather than to provide a template for an
-efficient production driver. */
-#define mainUART_QUEUE_LENGTHS 10
-
/*-----------------------------------------------------------*/
/*
@@ -236,16 +220,16 @@ extern void vUARTCommandConsoleStart( uint16_t usStackSize, UBaseType_t uxPriori
/*-----------------------------------------------------------*/
/* 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. */
+register check tasks to the check task. 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 )
{
- /* Start all the other standard demo/test tasks. The have not particular
+ /* Start all the other standard demo/test tasks. They have not particular
functionality, but do demonstrate how to use the FreeRTOS API and test the
kernel port. */
vStartInterruptQueueTasks();
@@ -267,9 +251,7 @@ void main_full( void )
/* Register the standard CLI commands. */
vRegisterSampleCLICommands();
-
- /* Create the register check tasks, as described at the top of this
- file */
+ /* Create the register check tasks, as described at the top of this file */
xTaskCreate( prvRegTestTaskEntry1, "Reg1", configMINIMAL_STACK_SIZE, mainREG_TEST_TASK_1_PARAMETER, tskIDLE_PRIORITY, NULL );
xTaskCreate( prvRegTestTaskEntry2, "Reg2", configMINIMAL_STACK_SIZE, mainREG_TEST_TASK_2_PARAMETER, tskIDLE_PRIORITY, NULL );
diff --git a/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/reg_test.S b/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/Full_Demo/reg_test.S
similarity index 100%
rename from FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/reg_test.S
rename to FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/Full_Demo/reg_test.S
diff --git a/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/serial.c b/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/Full_Demo/serial.c
similarity index 100%
rename from FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/serial.c
rename to FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/Full_Demo/serial.c
diff --git a/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/main.c b/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/main.c
index f2aff13ab..280f4404f 100644
--- a/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/main.c
+++ b/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/main.c
@@ -74,6 +74,13 @@
* This file implements the code that is not demo specific, including the
* hardware setup and FreeRTOS hook functions.
*
+ * NOTE: The full demo includes a test that checks the floating point context
+ * is maintained correctly across task switches. The standard GCC libraries can
+ * use floating point registers and made this test fail (unless the tasks that
+ * use the library are given a floating point context as described on the
+ * documentation page for this demo). printf-stdarg.c is included in this
+ * project to prevent the standard GCC libraries being linked into the project.
+ *
* ENSURE TO READ THE DOCUMENTATION PAGE FOR THIS PORT AND DEMO APPLICATION ON
* THE http://www.FreeRTOS.org WEB SITE FOR FULL INFORMATION ON USING THIS DEMO
* APPLICATION, AND ITS ASSOCIATE FreeRTOS ARCHITECTURE PORT!
@@ -128,6 +135,10 @@ void vApplicationIdleHook( void );
void vApplicationStackOverflowHook( xTaskHandle pxTask, char *pcTaskName );
void vApplicationTickHook( void );
+/*-----------------------------------------------------------*/
+
+/* The interrupt controller is initialised in this file, and made available to
+other modules. */
XScuGic xInterruptController;
/*-----------------------------------------------------------*/
@@ -149,6 +160,7 @@ int main( void )
}
#endif
+ /* Don't expect to reach here. */
return 0;
}
/*-----------------------------------------------------------*/
diff --git a/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/printf-stdarg.c b/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/printf-stdarg.c
new file mode 100644
index 000000000..b5ac41be7
--- /dev/null
+++ b/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/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;
+}
+