Browse Source
* microblaze/configure.in: Add target_makefile_frag. * microblaze/configure: Regenerate. * microblaze/xil_printf.c: Add new file.callout
5 changed files with 1529 additions and 1733 deletions
File diff suppressed because it is too large
@ -0,0 +1,284 @@ |
|||
/* Copyright (c) 1995-2013 Xilinx, Inc. All rights reserved.
|
|||
* |
|||
* Redistribution and use in source and binary forms, with or without |
|||
* modification, are permitted provided that the following conditions are |
|||
* met: |
|||
* |
|||
* 1. Redistributions source code must retain the above copyright notice, |
|||
* this list of conditions and the following disclaimer. |
|||
* |
|||
* 2. Redistributions in binary form must reproduce the above copyright |
|||
* notice, this list of conditions and the following disclaimer in the |
|||
* documentation and/or other materials provided with the distribution. |
|||
* |
|||
* 3. Neither the name of Xilinx nor the names of its contributors may be |
|||
* used to endorse or promote products derived from this software without |
|||
* specific prior written permission. |
|||
* |
|||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS |
|||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
|||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A |
|||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
|||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED |
|||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
|||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
|||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
|||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
|||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|||
*/ |
|||
|
|||
#include <ctype.h> |
|||
#include <string.h> |
|||
#include <stdarg.h> |
|||
|
|||
extern void outbyte (char); |
|||
|
|||
/*----------------------------------------------------*/ |
|||
/* Use the following parameter passing structure to */ |
|||
/* make xil_printf re-entrant. */ |
|||
/*----------------------------------------------------*/ |
|||
typedef struct params_s { |
|||
int len; |
|||
int num1; |
|||
int num2; |
|||
char pad_character; |
|||
int do_padding; |
|||
int left_flag; |
|||
} params_t; |
|||
|
|||
/*---------------------------------------------------*/ |
|||
/* The purpose of this routine is to output data the */ |
|||
/* same as the standard printf function without the */ |
|||
/* overhead most run-time libraries involve. Usually */ |
|||
/* the printf brings in many kilobytes of code and */ |
|||
/* that is unacceptable in most embedded systems. */ |
|||
/*---------------------------------------------------*/ |
|||
|
|||
typedef char* charptr; |
|||
typedef int (*func_ptr)(int c); |
|||
|
|||
/*---------------------------------------------------*/ |
|||
/* */ |
|||
/* This routine puts pad characters into the output */ |
|||
/* buffer. */ |
|||
/* */ |
|||
static void padding( const int l_flag, params_t *par) |
|||
{ |
|||
int i; |
|||
|
|||
if (par->do_padding && l_flag && (par->len < par->num1)) |
|||
for (i=par->len; i<par->num1; i++) |
|||
outbyte( par->pad_character); |
|||
} |
|||
|
|||
/*---------------------------------------------------*/ |
|||
/* */ |
|||
/* This routine moves a string to the output buffer */ |
|||
/* as directed by the padding and positioning flags. */ |
|||
/* */ |
|||
static void outs( charptr lp, params_t *par) |
|||
{ |
|||
/* pad on left if needed */ |
|||
par->len = strlen( lp); |
|||
padding( !(par->left_flag), par); |
|||
|
|||
/* Move string to the buffer */ |
|||
while (*lp && (par->num2)--) |
|||
outbyte( *lp++); |
|||
|
|||
/* Pad on right if needed */ |
|||
/* CR 439175 - elided next stmt. Seemed bogus. */ |
|||
/* par->len = strlen( lp); */ |
|||
padding( par->left_flag, par); |
|||
} |
|||
|
|||
/*---------------------------------------------------*/ |
|||
/* */ |
|||
/* This routine moves a number to the output buffer */ |
|||
/* as directed by the padding and positioning flags. */ |
|||
/* */ |
|||
|
|||
static void outnum( const long n, const long base, params_t *par) |
|||
{ |
|||
charptr cp; |
|||
int negative; |
|||
char outbuf[32]; |
|||
const char digits[] = "0123456789ABCDEF"; |
|||
unsigned long num; |
|||
|
|||
/* Check if number is negative */ |
|||
if (base == 10 && n < 0L) { |
|||
negative = 1; |
|||
num = -(n); |
|||
} |
|||
else{ |
|||
num = (n); |
|||
negative = 0; |
|||
} |
|||
|
|||
/* Build number (backwards) in outbuf */ |
|||
cp = outbuf; |
|||
do { |
|||
*cp++ = digits[(int)(num % base)]; |
|||
} while ((num /= base) > 0); |
|||
if (negative) |
|||
*cp++ = '-'; |
|||
*cp-- = 0; |
|||
|
|||
/* Move the converted number to the buffer and */ |
|||
/* add in the padding where needed. */ |
|||
par->len = strlen(outbuf); |
|||
padding( !(par->left_flag), par); |
|||
while (cp >= outbuf) |
|||
outbyte( *cp--); |
|||
padding( par->left_flag, par); |
|||
} |
|||
|
|||
/*---------------------------------------------------*/ |
|||
/* */ |
|||
/* This routine gets a number from the format */ |
|||
/* string. */ |
|||
/* */ |
|||
static int getnum( charptr* linep) |
|||
{ |
|||
int n; |
|||
charptr cp; |
|||
|
|||
n = 0; |
|||
cp = *linep; |
|||
while (isdigit(*cp)) |
|||
n = n*10 + ((*cp++) - '0'); |
|||
*linep = cp; |
|||
return(n); |
|||
} |
|||
|
|||
/*---------------------------------------------------*/ |
|||
/* */ |
|||
/* This routine operates just like a printf/sprintf */ |
|||
/* routine. It outputs a set of data under the */ |
|||
/* control of a formatting string. Not all of the */ |
|||
/* standard C format control are supported. The ones */ |
|||
/* provided are primarily those needed for embedded */ |
|||
/* systems work. Primarily the floaing point */ |
|||
/* routines are omitted. Other formats could be */ |
|||
/* added easily by following the examples shown for */ |
|||
/* the supported formats. */ |
|||
/* */ |
|||
|
|||
/* void esp_printf( const func_ptr f_ptr,
|
|||
const charptr ctrl1, ...) */ |
|||
void xil_printf( const charptr ctrl1, ...) |
|||
{ |
|||
|
|||
int long_flag; |
|||
int dot_flag; |
|||
|
|||
params_t par; |
|||
|
|||
char ch; |
|||
va_list argp; |
|||
charptr ctrl = ctrl1; |
|||
|
|||
va_start( argp, ctrl1); |
|||
|
|||
for ( ; *ctrl; ctrl++) { |
|||
|
|||
/* move format string chars to buffer until a */ |
|||
/* format control is found. */ |
|||
if (*ctrl != '%') { |
|||
outbyte(*ctrl); |
|||
continue; |
|||
} |
|||
|
|||
/* initialize all the flags for this format. */ |
|||
dot_flag = long_flag = par.left_flag = par.do_padding = 0; |
|||
par.pad_character = ' '; |
|||
par.num2=32767; |
|||
|
|||
try_next: |
|||
ch = *(++ctrl); |
|||
|
|||
if (isdigit(ch)) { |
|||
if (dot_flag) |
|||
par.num2 = getnum(&ctrl); |
|||
else { |
|||
if (ch == '0') |
|||
par.pad_character = '0'; |
|||
|
|||
par.num1 = getnum(&ctrl); |
|||
par.do_padding = 1; |
|||
} |
|||
ctrl--; |
|||
goto try_next; |
|||
} |
|||
|
|||
switch (tolower(ch)) { |
|||
case '%': |
|||
outbyte( '%'); |
|||
continue; |
|||
|
|||
case '-': |
|||
par.left_flag = 1; |
|||
break; |
|||
|
|||
case '.': |
|||
dot_flag = 1; |
|||
break; |
|||
|
|||
case 'l': |
|||
long_flag = 1; |
|||
break; |
|||
|
|||
case 'd': |
|||
if (long_flag || ch == 'D') { |
|||
outnum( va_arg(argp, long), 10L, &par); |
|||
continue; |
|||
} |
|||
else { |
|||
outnum( va_arg(argp, int), 10L, &par); |
|||
continue; |
|||
} |
|||
case 'x': |
|||
outnum((long)va_arg(argp, int), 16L, &par); |
|||
continue; |
|||
|
|||
case 's': |
|||
outs( va_arg( argp, charptr), &par); |
|||
continue; |
|||
|
|||
case 'c': |
|||
outbyte( va_arg( argp, int)); |
|||
continue; |
|||
|
|||
case '\\': |
|||
switch (*ctrl) { |
|||
case 'a': |
|||
outbyte( 0x07); |
|||
break; |
|||
case 'h': |
|||
outbyte( 0x08); |
|||
break; |
|||
case 'r': |
|||
outbyte( 0x0D); |
|||
break; |
|||
case 'n': |
|||
outbyte( 0x0D); |
|||
outbyte( 0x0A); |
|||
break; |
|||
default: |
|||
outbyte( *ctrl); |
|||
break; |
|||
} |
|||
ctrl++; |
|||
break; |
|||
|
|||
default: |
|||
continue; |
|||
} |
|||
goto try_next; |
|||
} |
|||
va_end( argp); |
|||
} |
|||
|
|||
/*---------------------------------------------------*/ |
|||
Loading…
Reference in new issue