📄 hal_diag.c
字号:
//=============================================================================
//
// hal_diag.c
//
// HAL diagnostic output code
//
//=============================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos 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 General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//=============================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): ysato
// Contributors: ysato, Uwe Kindler
// Date: 2003-12-06
// Purpose: HAL diagnostic output
// Description: Implementations of HAL diagnostic output support.
//
//####DESCRIPTIONEND####
//
//=============================================================================
//=============================================================================
// DOXYGEN FILE HEADER
/// \file hal_diag.c
/// \brief HAL diagnostic output
/// \author Yoshinori Sato, Uwe Kindler
/// \date 2003-12-06
///
/// Implementations of HAL diagnostic output support.
//=============================================================================
//=============================================================================
// INCLUDES
//=============================================================================
#include <pkgconf/hal.h>
#include <cyg/hal/hal_diag.h>
#include <cyg/hal/var_intr.h>
#include <cyg/hal/h8s_sci.h>
//===========================================================================
// DEFINES
//===========================================================================
//===========================================================================
// GLOBALS
//===========================================================================
//--------------------------------------------------------------------------
// These macros simplify entries into hal_int_conf_tbl[]
//
#define CHAN_TBL_ENTRY(base, timeout, baud, vect) \
{(cyg_uint8 *)base, (cyg_uint32)timeout, baud, vect}
//
// CYGSEM_HAL_VIRTUAL_VECTOR_DIAG
//
// Virtual vector support allows the HAL to let the ROM monitor handle
// certain operations. The virtual vector table defines a calling interface
// between applications running in RAM and the ROM monitor.
//
#if defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG)
//============================================================================
// INITIALIZE SERIAL VIRTUAL VECTOR COMM CHANNEL
///
/// Initializes diagnostic channel.
/// Initialisation of one diagnostic channel and setting the of COMM table
/// for this channel if virtual vectors are used.
///
/// \param pchan Points to buffer holding channel configuration data
/// \param chan_no Number of virtual vector channel
//============================================================================
void hal_console_comm_init(channel_data_t *pchan, cyg_uint8 chan_no)
{
hal_virtual_comm_table_t *pvcomm_tbl;
int cur;
//
// first save the current console channel settings
//
cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
//
// Now we we initailise the channel an store there patrameters into
// tom COMM tables of the virtual vector calling interface
//
HAL_INTERRUPT_MASK(pchan->isr_vector); // Disable interrupts
hal_sci_init_channel((void *)pchan); // Init channel
//
// Setup procs in the vector table
// Initialize channel procs
//
CYGACC_CALL_IF_SET_CONSOLE_COMM(chan_no);
pvcomm_tbl = CYGACC_CALL_IF_CONSOLE_PROCS();
CYGACC_COMM_IF_CH_DATA_SET(*pvcomm_tbl, pchan);
CYGACC_COMM_IF_WRITE_SET(*pvcomm_tbl, hal_sci_write);
CYGACC_COMM_IF_READ_SET(*pvcomm_tbl, hal_sci_read);
CYGACC_COMM_IF_PUTC_SET(*pvcomm_tbl, hal_sci_putc);
CYGACC_COMM_IF_GETC_SET(*pvcomm_tbl, hal_sci_getc);
CYGACC_COMM_IF_CONTROL_SET(*pvcomm_tbl, hal_sci_control);
CYGACC_COMM_IF_DBG_ISR_SET(*pvcomm_tbl, hal_sci_isr);
CYGACC_COMM_IF_GETC_TIMEOUT_SET(*pvcomm_tbl, hal_sci_getc_timeout);
//
// Now we restore the original console which was saved previously
//
CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
}
#endif // #if defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG)
//
// When vector table console code is not used, the we must map the
// HAL_DIAG_INIT, HAL_DIAG_WRITE_CHAR and HAL_DIAG_READ_CHAR macros
// directly to the low-level IO functions, hardwired to use at compile-time
// configured channel.
//
#if !defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG) || defined(CYGBLD_HAL_H8S_ADDITIONAL_DIAG_CODE)
static channel_data_t *pchannel; // points to hardwired serial channel provided by platform
//=============================================================================
// INITIALIZE DIAGNOSTIC DEVICE
///
/// Initialize dignostic device manually (no virtual vector support).
/// If we do not use virtual vector comm channels then we have to
/// initialize the hardwired debug channel manually.
///
/// \param pchan_arg Points to channel configuration data
//=============================================================================
void hal_diag_init(channel_data_t *pchan_arg)
{
pchannel = pchan_arg;
hal_sci_init_channel((void *)pchannel);
}
//=============================================================================
// WRITE CHAR TO DIAGNOSTIC DEVICE
///
/// Write char to diagnostic device.
/// If we do not use virtual vector comm channels then we have to
/// use this function.
///
/// \param c Char to be written to diagostic device
//=============================================================================
void hal_diag_write_char(char c )
{
hal_sci_putc((void *)pchannel, c);
}
//=============================================================================
// READ CHAR FROM DIAGNOSTIC DEVICE
///
/// Read character from diagnostic device.
/// If we do not use virtual vector comm channels then we have to
/// use this function.
///
/// \param c Stores received character
//=============================================================================
void hal_diag_read_char(char *c)
{
*c = (char) hal_sci_getc((void *)pchannel);
}
//============================================================================
// SEND BUFFER
///
/// Outputs a buffer of len_in bytes via diagnostic device
///
/// \param pbuf_in Points to buffer with date to be sent
/// \param len_in Number of bytes to be sent
///
/// \return A simple checksum.
//============================================================================
int hal_diag_put_buf(const char *pbuf_in, int len_in)
{
unsigned char sum;
sum = 0;
while (len_in--)
{
sum += *(unsigned char*)pbuf_in;
hal_diag_write_char(*pbuf_in++);
}
return sum;
}
//============================================================================
// SEND ZERO TERMINATED STRING
///
/// Sends zero terminated string through diagnostic device
///
/// \param pstr_in Pointer to zero terminated string
//============================================================================
void hal_diag_put_string (unsigned char *pstr_in)
{
while (*pstr_in != '\0') // repeat until detection of terminating zero
{
hal_diag_write_char(*pstr_in++);
}
}
//============================================================================
// SEND LONG
///
/// Send long value through diagnostic serial channel.
/// Converts long number into a number string and sends it through
/// serial channel.
///
/// \param l_in Long number to be send
//============================================================================
void hal_diag_put_long(unsigned long l_in)
{
unsigned char charbuf[10];
unsigned char i;
//
// A zero value is a special case - we send zero char and leave
//
if (l_in == 0)
{
hal_diag_write_char('0');
return;
}
//
// Here we calculate the entries for the char buffer. We start with
// the least significant number and devide by 10 until l_in = zero.
// An ASCII offset is added to get a char from a numeric value.
//
i = 9;
while (l_in > 0)
{
charbuf[i] = (l_in % 10) + '0';
i--;
l_in = l_in / 10;
}
//
// This part sends the content of the charbuffer out through serial
// interface
//
i++;
while (i < 10)
{
hal_diag_write_char(charbuf[i]);
i++;
}
}
//============================================================================
// CONVERT LOW NIBBLE OF BYTE TO HEX CHAR
///
/// Converts low nibble of byte into hex char
///
/// \param n_in Number to be converted
///
/// \return Converted hex char
//============================================================================
static char hal_lnibble_to_hex(char n_in)
{
static const char lnibble_to_hex_tbl[] = "0123456789abcdef";
return lnibble_to_hex_tbl[n_in & 0xf];
}
//============================================================================
// CONVERT LONG INTO HEX STRING
///
/// Converts long into hex string
///
/// \param l_in Long number to be converted
/// \param phexbuf_out Stores hex string
///
/// \return Number of char written into phexbuf_out
//============================================================================
static unsigned char hal_long_to_hexbuf(long l_in, char *phexbuf_out)
{
typedef union
{
long lbuf;
short sbuf;
char cbuf[sizeof(long)];
} lsc_buf_t;
lsc_buf_t lscbuf;
unsigned char ret;
unsigned char i;
ret = 0;
lscbuf.lbuf = l_in;
//
// Now we convert the value in lscbuf into hex chars and store
// them into phexbuf_out
//
for (i = 0; i < sizeof(long); i++)
{
*phexbuf_out++ = hal_lnibble_to_hex(lscbuf.cbuf[i] >> 4); // high nibble
*phexbuf_out++ = hal_lnibble_to_hex(lscbuf.cbuf[i]); // low nibble
ret += 2; // inc. counter for chars in buf
}
return ret;
}
//============================================================================
// SEND LONG AS ASCII STRING
///
/// Converts long into hex string and sends it through diagnostic device
///
/// \param l_in Long number to be sent
//============================================================================
void hal_diag_put_long_hex(long l_in)
{
unsigned char hexbuf[10] = "0x";
unsigned char len = 2;
len += hal_long_to_hexbuf(l_in, &hexbuf[2]);
hal_diag_put_buf(hexbuf, len);
}
#endif // #if !defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG) || defined(CYGBLD_HAL_ADDITIONAL_DIAG_CODE)
//----------------------------------------------------------------------------
// EOF hal_diag.c
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -