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

📄 pdebug.c

📁 本程序为ST公司开发的源代码
💻 C
字号:
/*******************************************************************************
 *
 *  \par          Change History:
 *
 *  - BB060425    Improved  printf functionality
 *            - added support to directly use printf
 *              (no need to sprintf to buffer than use DEBUG_printf)
 *            - removed unused DEBUG_printf_func_isr
 * - BB060619     Improved printf to not block interrupts
 *
 ******************************************************************************
 *
 * STM CVS Log:
 *
 * $Log: pdebug.c,v $ * Revision 1.9  2006/09/25 13:49:55  belardi * Added #pragma to force ARM compilation , due to inline _asm *
 * Revision 1.8  2006/09/18 09:55:21  belardi
 * Corrected CVS keyword usage
 *
 * Revision 1.7  2006/09/18 09:22:43  belardi
 * Added Log CVS keyword into file header
 *
 * Revision 1.6  2006/09/15 19:38:34  belardi
 * Merged the m8_cav2_cm80506_cs3563.
 * - white-spaces
 *
 *
 ******************************************************************************/

/**************************************************************************
 *    Include files
 **************************************************************************/

#include <stdarg.h>     // va_arg stuff
#include <stdio.h>

#include "gendef.h"     // uint32, t_bool
#include "uart0reg.h"   // UART0_xx
#include "uart1reg.h"   // UART1_xx

#include  "osal.h"

#define PRINTF_DIFF_TIME 1

#ifndef INLINE
  #define INLINE __forceinline
#endif

#ifdef DEBUG_PRINTF_ENABLED

#define DEBUG_PROTECT_ISR_DISABLE

#ifdef DEBUG_PROTECT_ISR_DISABLE
  #define DEBUG_SEM_INIT()    do{}while(0)
  #define DEBUG_SEM_WAIT()    DISABLE_INTERRUPTS()
  #define DEBUG_SEM_SIGNAL()  ENABLE_INTERRUPTS()
#else	 /* BB060619 */
  extern int interruptCount;
  #define interrupt_active (interruptCount>0)

  #define DEBUG_SEM_INIT()    do{}while(0)
  #define DEBUG_SEM_WAIT()    task_lock()
  #define DEBUG_SEM_SIGNAL()  task_unlock()
#endif

/**************************************************************************
 *    Macro's
 **************************************************************************/

#ifdef TRACE_DEBUG
#define DEBUG_NEWLINE   '\n'
#else
#define DEBUG_NEWLINE   '\r'     /* for HyperTerminal and ComView */
                                 /* note: HyperTerminal doesn't like the '\n' */
#endif

#define DEBUG_SIZE   		0x800
#define DEBUG_BAUDRATE	115200

#define PRINTF_UART0

#ifdef PRINTF_UART0
   // uart-0
   #define UARTx_CR           UART0_CR
   #define UARTx_SR           UART0_SR
   #define UARTx_BR           UART0_BR
   #define UARTx_IER          UART0_IER
   #define UARTx_TXRSTR       UART0_TXRSTR
   #define UARTx_RXRSTR       UART0_RXRSTR
   #define UARTx_TXBUF        UART0_TXBUF
#else
   // uart-1
   #define UARTx_CR           UART1_CR
   #define UARTx_SR           UART1_SR
   #define UARTx_BR           UART1_BR
   #define UARTx_IER          UART1_IER
   #define UARTx_TXRSTR       UART1_TXRSTR
   #define UARTx_RXRSTR       UART1_RXRSTR
   #define UARTx_TXBUF        UART1_TXBUF
#endif

#define UARTBR(br) (S_APB_CLK/(16*(br)))

/**************************************************************************
 *    Typedefs
 **************************************************************************/
struct __FILE
{
   char     buf [DEBUG_SIZE];
   int      in;
   int      out;
};

/**************************************************************************
 *    Local variables
 **************************************************************************/

#ifdef DEBUG_MODULE_PRINTF_ENABLED
   /**
   * Administration of the modules
   */
   static t_bool  module_enabled[DEBUG_ID_LAST];

   // add here the module-id whose DEBUG_module_printf() should be on at startup
   static const DEBUG_MODULE_ID_t default_enabled_modules[]=
   {
      DEBUG_MODULE_ID_MAIN
   };

#endif

static FILE debug_stream;

static const uint8 digits[] = "0123456789abcdef";

/**************************************************************************
 *    Private functions
 **************************************************************************/

/*-----------------------------------------------------------------------*/

static void
outint(FILE *f, uint32 len, uint32 num, uint32 base)
{
  uint8 outbuf[10];
  uint8 *cp;

  cp = outbuf;
  do
  {
    *cp++ = digits[(int) (num % base)];
  }
  while ((--len > 0) && ((num /= base) > 0));
  while (len-- > 0)
  {
    *cp++ = '0';
  }
  cp--;

  while (cp >= outbuf)
  {
    (void)fputc(*cp--, f);
  }
}

/*-----------------------------------------------------------------------*/

INLINE static void
debug_add_char (FILE *f, char c)
{
	(void)fputc(c,f);
}

/*-----------------------------------------------------------------------*/

INLINE static void
debug_add_str (FILE *f, char *str)
{
  if (*str != '\0')
  {
    (void)fputc(' ', f);

    while (*str != '\0')
    {
      (void)fputc(*str++, f);
    }
  }
}

/*-----------------------------------------------------------------------*/

INLINE static void
debug_add_int (FILE *f, int size, uint32 v)
{
  (void)fputc(' ', f);

  outint(f, 2 * (size), v, 16);
}

/*-----------------------------------------------------------------------*/

#if (PRINTF_DIFF_TIME)
INLINE static void debug_printf_time(FILE *f)
{
  uint32 time_value;
  int32 dif_time;
  static uint32 last_time;

  time_value = OSAL_time_get();
  dif_time = time_value - last_time;
  last_time = time_value;
  outint(f, 5, dif_time, 10);
}
#else
INLINE static void debug_printf_time(FILE *f)
{
  uint32 time_value;
  time_value = OSAL_time_get();

  outint(f, 5, time_value, 10);
}
#endif
/*-----------------------------------------------------------------------*/

// [RB] this function contains __asm instructions which cannot
// be compiled in Thumb mode
#pragma PUSH
#pragma ARM

static void
debug_send (int nrof_bytes)
{
   int i;
   for (i = 0; (i < nrof_bytes) && (debug_stream.out != debug_stream.in); i++)
   {
#ifdef TRACE_DEBUG
      {
         int temp = debug_stream.buf [debug_stream.out++];
         int DCCStatus;
         do
         {
	   __asm
	   {
	     MRC p14,0,DCCStatus,c0,c0;
	   }
         }while (DCCStatus & DCC_WRITEBUSY);
         __asm
	 {
	   MCR p14,0,temp,c1,c0;
	 }
      }
#else
      UARTx_TXBUF = debug_stream.buf [debug_stream.out++];
#endif
      if (debug_stream.out == DEBUG_SIZE)
      {
         debug_stream.out = 0;
      }
   }
}

#pragma POP
/*-----------------------------------------------------------------------*/

/**************************************************************************
 *    Public functions
 **************************************************************************/

// str  = literal string
// size = 0 => string
// size = 1 => 1 byte
// size = 2 => 2 byte
// size = 4 => 4 byte
// length = 0 => 0 extra parameters
// length = 1 => 1 extra parameters
// length = n => n extra parameters


void
DEBUG_printf_func (char * str, int size, int length, ...)
{
  va_list   list_p;
  uint32    v;
  char *    s;
  int     i;

#ifndef DEBUG_PROTECT_ISR_DISABLE  /* BB060619 */
  if (interrupt_active)
    return;
#endif
  DEBUG_SEM_WAIT();
//ADD for isr  debug_add_char (&debug_stream, '@');
  debug_printf_time(&debug_stream);
  debug_add_str(&debug_stream, str);
  va_start  (list_p,  length);
  for (i =  0;  i < length; i++)
  {
    if  (size ==  0)
    {
      s = va_arg (list_p, char *);
      debug_add_str (&debug_stream, s);
    }
    else
    {
      v = va_arg (list_p, uint32);
      debug_add_int (&debug_stream, size, v);
    }
  }
  va_end (list_p);
  debug_add_char  (&debug_stream, DEBUG_NEWLINE);
  DEBUG_SEM_SIGNAL();
}

/*-----------------------------------------------------------------------*/

void DEBUG_send (void)
{
#ifdef TRACE_DEBUG
   debug_send (1);
#else
   if ((UARTx_SR.field.TxEmpty))
   {
      // empty transmit buffer: 16 places
      debug_send (16);
   }
   else
   {
      if ((UARTx_SR.field.TxHalfEmpty))   
      {
         // half-empty transmit buffer: 8 places
         debug_send (8);
      }
   }
#endif
}

/*-----------------------------------------------------------------------*/


#ifdef DEBUG_MODULE_PRINTF_ENABLED

   t_bool 
   DEBUG_is_module_enabled (DEBUG_MODULE_ID_t module_id)
   {
      return (module_enabled[module_id]);
   }                    

   /*-----------------------------------------------------------------------*/
   
   void 
   DEBUG_set_debug_info(DEBUG_MODULE_ID_t module_id, t_bool enable)
   {
      if (module_id >= DEBUG_ID_LAST)
      {
         DEBUG_printf (("DEBUG mod-id", 4, 1, module_id));
         return;
      }

      module_enabled [module_id] = enable;
   }

#endif

/*-----------------------------------------------------------------------*/

void DEBUG_start(void)
{
   int   i;

#ifndef TRACE_DEBUG
   // assumption: relevant GPIO's are already configured!
   UARTx_CR.all               = 0;
   UARTx_CR.field.FifoEnable  = 1;
   UARTx_CR.field.RxEnable    = 1;
   UARTx_CR.field.StopBits    = 3;   // 3 == 2 stop bits
   UARTx_CR.field.Mode        = 1;   // 1 == 8 bits data
   UARTx_BR                   = UARTBR(DEBUG_BAUDRATE);
   UARTx_IER.all              = 0;
   UARTx_TXRSTR               = 0;
   UARTx_RXRSTR               = 0;

   UARTx_CR.field.Run         = 1;
#endif
   debug_stream.out  = 0;
   debug_stream.in   = 0;

   DEBUG_SEM_INIT();

#ifdef DEBUG_MODULE_PRINTF_ENABLED
   // Set default enabled debug modules
   for (i = 0; i < DEBUG_ID_LAST; i++)
   {
      DEBUG_set_debug_info (i, FALSE);
   }

   for (i = 0; i < sizeof (default_enabled_modules) / sizeof (default_enabled_modules[0]); i++)
   {
      DEBUG_set_debug_info (default_enabled_modules[i], TRUE);
   }
#endif

}

/*-----------------------------------------------------------------------*/

/* Replaced fputc. */
int fputc(int ch, FILE *f)
{
   int   free;

  if (f->in >= f->out)
  {
    //  normal situation
    free = DEBUG_SIZE - (f->in  - f->out);
  }
  else
  {
    //  d->in already wrapped-around
    free = f->out - f->in;
  }

  #ifndef TRACE_DEBUG
  if  ('\n' ==  ch)
  {
    ch  = '\r';
  }
  #endif


  if  (free >=  4)
  {
    if  (free ==  4)
    {
      //  NOT enough free space: add  overlfow  character
      ch  = '#';
    }
    //  else: (i.e. "free > 4"): enough free space: add original  char

      f->buf [(f->in)++] = ch;
      if (f->in == DEBUG_SIZE)
      {
         // wrap-around
         f->in = 0;
      }
   }
   // else (i.e. "free < 4"): NOT enough free space: skip
   return ch;
}

/*-----------------------------------------------------------------------*/

/* Replaced ferror. */
int ferror(FILE *f)
{
  return EOF;
}

/*-----------------------------------------------------------------------*/

void dprintf(const char *format, ...)
{
  va_list __arg;

#ifndef DEBUG_PROTECT_ISR_DISABLE  /* BB060619 */
  if (interrupt_active)
    return;
#endif
  DEBUG_SEM_WAIT();
  debug_printf_time(&debug_stream);
  (void)fputc(' ', &debug_stream);

  va_start(__arg, format);
  (void)_vfprintf(&debug_stream, format, __arg);
  va_end();
  DEBUG_SEM_SIGNAL();
}

/*-----------------------------------------------------------------------*/

/* Replaced printf. Be sure that we compile with -Ono_fp_formats */
int printf(const char *format, ...)
{
  int ret;
  va_list __arg;

#ifndef DEBUG_PROTECT_ISR_DISABLE  /* BB060619 */
  if (interrupt_active)
    return 0;
#endif
  DEBUG_SEM_WAIT();

  va_start(__arg, format);
  ret = _vfprintf(&debug_stream, format, __arg);
  va_end();
  DEBUG_SEM_SIGNAL();
  return  ret;
}
#else

#ifndef TRACE_DEBUG
int printf(const char *format, ...)
{
  return 0;
}
#endif


#endif   // DEBUG_PRINTF_ENABLED

/*-----------------------------------------------------------------------*/

⌨️ 快捷键说明

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