⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xllp_logmessage.c

📁 Intel PXA270底层设备驱动代码
💻 C
字号:
/*
** INTEL CONFIDENTIAL
** Copyright 2005 Intel Corporation All Rights Reserved.
**
** The source code contained or described herein and all documents
** related to the source code (Material) are owned by Intel Corporation
** or its suppliers or licensors.  Title to the Material remains with
** Intel Corporation or its suppliers and licensors. The Material contains
** trade secrets and proprietary and confidential information of Intel
** or its suppliers and licensors. The Material is protected by worldwide
** copyright and trade secret laws and treaty provisions. No part of the
** Material may be used, copied, reproduced, modified, published, uploaded,
** posted, transmitted, distributed, or disclosed in any way without Intel抯
** prior express written permission.
**
** No license under any patent, copyright, trade secret or other intellectual
** property right is granted to or conferred upon you by disclosure or
** delivery of the Materials, either expressly, by implication, inducement,
** estoppel or otherwise. Any license under such intellectual property rights
** must be express and approved by Intel in writing.
*/
//************************************************************************************************************
//
// Formatting and Message logging functions.
//
// The code in this module performs printf-like formatting.
// It is somewhat simplistic and doesn't handle many traditional format options.
// The intent is just to provide an implementation that accommodates common devloper usage.
// Format specifications supported are...
//         x : 32-bit hex number
//         X : 32-bit hex number
//         h : 16-bit hex number
//         H : 16-bit hex number
//         b : 8-bit  hex number
//         B : 8-bit  hex number
//         u : unsigned decimal
//         d : signed decimal
//         c : 8 bit ASCII character
//         s : string
// Format specifications like %#04x are supported to some extent.
// The 'h' and 'b' options exist to enable this module to be a drop-in replacement for 
// similar functions in EBOOT if that becomes desirable.
//
// The functions in this module accept and produce 8 bit ascii messages.
// They can generate messages up to a maximum size (currently 128-4 bytes)
// and protect against buffer overflow due to longer messages. 
// Actual output (eg. via a serial port) is likely to be OS dependent.
// OS dependence is handled by requiring a simple string output function be provided by the host environment.
// An implementation of that function could be as simple as 'printf("%s", pMsg)'
extern void OSD_LogMessage(unsigned char *pMsg);

#include "xllp_logmessage.h"

#define XLLP_LOGMESSAGE_MAX_BYTES 128

typedef struct
{
    unsigned long max_bytes;
    unsigned long current_bytes;
    unsigned char *p;
} BUFFER_DESCRIPTOR;

typedef int bool;

static unsigned long PutByte(unsigned char c, BUFFER_DESCRIPTOR *pBD)
    {
    if (pBD->current_bytes >= pBD->max_bytes)
        return(0);
    pBD->p[pBD->current_bytes++] = c;
    return(1);
    }

static const unsigned char HexCharsLC[] = "0123456789abcdef";
static const unsigned char HexCharsUC[] = "0123456789ABCDEF";

static void PutHex(unsigned long n, unsigned long out_chars, bool upcase, unsigned char fill, BUFFER_DESCRIPTOR *pBD)
    {
        unsigned char tb[8];
        const unsigned char *phc;
        int i;

    phc = upcase ? HexCharsUC : HexCharsLC;
    // put significant digits in temp buffer (from right to left)
    i = sizeof(tb)-1;
    while(1)
        {
        tb[i] = phc[n & 0xf];
        n >>= 4;
        if (n == 0)
            break;
        if (i > 0)
            i--;
        else
            break;
        }
    // i now points to the first non-zero hex char in hb[]
    if (out_chars != 0)
        {
            int z;
        if (out_chars > sizeof(tb))
            out_chars = sizeof(tb);
        if (fill == '\0')
            fill = '0';
        // calulate number of leading zeroes required 
        z = out_chars - (sizeof(tb) - i);
        // output leading zeroes
        while (z-- > 0)
            PutByte(fill, pBD);
        }
    // output the hex chars
    while (i < sizeof(tb))
        PutByte(tb[i++], pBD);
    
    return;
    }

static void PutDecimal(unsigned long n, unsigned long out_chars, unsigned char fill, BUFFER_DESCRIPTOR *pBD)
    {
        unsigned char tb[10];
        int i;

    // put significant digits in temp buffer (from right to left)
    i = sizeof(tb)-1;
    while(1)
        {
        tb[i] = (unsigned char)('0' + (n % 10));
        n /= 10;
        if (n == 0)
            break;
        if (i > 0)
            i--;
        else
            break;
        }
    // i now points to the first non-zero decimal char in hb[]
    if (out_chars != 0)
        {
            int z;
        if (out_chars > sizeof(tb))
            out_chars = sizeof(tb);
        if (fill == '\0')
            fill = ' ';
        // calulate number of leading fill chars required 
        z = out_chars - (sizeof(tb) - i);
        // output leading fill
        while (z-- > 0)
            PutByte(fill, pBD);
        }
    // output the decimal chars
    while (i < sizeof(tb))
        PutByte(tb[i++], pBD);
    
    return;
    }

static unsigned long PutString(const unsigned char *s, BUFFER_DESCRIPTOR *pBD)
    {
        unsigned long idcb = pBD->current_bytes;
    while (*s)
        {
        if (PutByte(*s++, pBD) == 0)
            break;
        }
    return(pBD->current_bytes - idcb);
    }

unsigned long xllp_vsnprintf(unsigned char *pBuf, unsigned long max_bytes, const unsigned char *pFormat, va_list ap)
    {
        unsigned char        c;
        unsigned char        fill_c;
		unsigned long        width;
        const unsigned char *pf = pFormat;
        va_list              valist = ap;
        BUFFER_DESCRIPTOR    BD;
        BUFFER_DESCRIPTOR   *pBD = &BD;

    pBD->current_bytes = 0;
    pBD->max_bytes     = max_bytes - 4;  // leave room for '\0' and overflow markers.
    pBD->p             = pBuf;

    while (*pf)
        {
        if (pBD->current_bytes >= pBD->max_bytes)
            break;
        c = *pf++;
        switch (c)
            {
            case '%':
                width = 0;
                fill_c = '\0';
				c = *pf++;
				// # spec is currently not implemented but recognized and silently ignored
                if (c == '#')
                    c = *pf++;
                if (c == '0')
                    {
                    fill_c = c;
                    c = *pf++;
                    }
                // Leading zero and width spec is implemented only for x, u, & d formats.
                // It is recognized but silently ignored for other formats.
				while ((c >= '0') && (c <= '9'))
                    {
                    width = (width*10) + (c & 0xf);
					c = *pf++;
                    }
                switch (c)
                    {
                    case 'x':
                        PutHex(va_arg(valist, unsigned long), width, 0, fill_c, pBD);
                        break;
                    case 'X':
                        PutHex(va_arg(valist, unsigned long), width, 1, fill_c, pBD);
                        break;
                    case 'b':
                        PutHex(va_arg(valist, unsigned long), 2, 0, fill_c, pBD);
                        break;
                    case 'B':
                        PutHex(va_arg(valist, unsigned long), 2, 1, fill_c, pBD);
                        break;
                    case 'h':
                        PutHex(va_arg(valist, unsigned long), 4, 0, fill_c, pBD);
                        break;
                    case 'H':
                        PutHex(va_arg(valist, unsigned long), 4, 1, fill_c, pBD);
                        break;
                    case 'd':
                        {
                            long d;
                        d = va_arg(valist, long);
                        if (d < 0)
                            {
                            PutByte('-', pBD);
                            d = d * -1;
                            }
                        else
                        if (width != 0)
                            PutByte(' ', pBD);
                        PutDecimal((unsigned long)d, width, fill_c, pBD);
                        }
                        break;
                    case 'u':
                        PutDecimal(va_arg(valist, unsigned long), width, fill_c, pBD);
                        break;
                    case 's':
                        PutString(va_arg(valist, char *), pBD);
                        break;
                    case '%':
                        PutByte('%', pBD);
                        break;
                    case 'c':
                        c = va_arg(valist, unsigned char);
                        PutByte(c, pBD);
                        break;
                    default:
                        PutByte('%', pBD);
                        PutByte(c, pBD);
                        // ignore the value argument too so any remaining items aren't messed up
                        va_arg(valist, unsigned long); 
                        break;
                    }
                break;
            default:
                PutByte(c, pBD);
                break;
            }
        }
    if (pBD->current_bytes == pBD->max_bytes)
        {
        pBD->p[pBD->current_bytes++] = '>';
        pBD->p[pBD->current_bytes++] = '\r';
        pBD->p[pBD->current_bytes++] = '\n';
        }
    pBD->p[pBD->current_bytes] = '\0';
    return(pBD->current_bytes);
    } // xllp_vsnprintf

unsigned long xllp_snprintf(unsigned char *pBuf, unsigned long max_bytes, const unsigned char *pFormat, ...)
    {
        va_list         valist;
        unsigned long   ret;
    va_start(valist, pFormat);
    ret = xllp_vsnprintf(pBuf, max_bytes, pFormat, valist);
    va_end(valist);
    return(ret);
    } // xllp_snprintf

unsigned long xllp_LogMessage(const unsigned char *pFormat, ...)
    {
        unsigned char   MsgBuf[XLLP_LOGMESSAGE_MAX_BYTES + 4];
        va_list         valist;
        unsigned long   ret;

    va_start(valist, pFormat);
    ret = xllp_vsnprintf(MsgBuf, sizeof(MsgBuf), pFormat, valist);
    OSD_LogMessage(MsgBuf);
    va_end(valist);
    return(ret);
    } // xllp_LogMessage

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -