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

📄 print.c

📁 CMX990 demonstration board (DE9901)
💻 C
字号:
/****h* DE9901/Print
* FILE NAME
*  print.c
* COPYRIGHT
*  (c) 2004-2005 Mobitex Technology AB - 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 of 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. The name Mobitex Technology AB may not be used to endorse or promote products
*       derived from this software without specific prior written permission.
*
*  THIS SOFTWARE IS PROVIDED BY MOBITEX TECHNOLOGY AB "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 MOBITEX TECHNOLOGY AB 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.
*
* AUTHOR
*  MPN/Kjell Westerberg
* HISTORY
*  Changes in the file are recorded in this list.
*   Ver:  Date:       Responsible:         Comment:
*   R1A01 2005-01-17  Kjell Westerberg     Approved.
*   R1A02 2005-02-07  Kjell Westerberg     Increased buffer size.
*   R1A05 2005-03-17  Kjell Westerberg     Added time stamp to printouts.
*   R1A06 2005-04-22  Kjell Westerberg     Checks string length.
* DESCRIPTION
*  This file implements a print function that writes on the MASC port.
*  The functions Print and PrintEvent can be used to write on the MASC port.
*  They have the same arguments as printf.
*  A thread with low priority is used to do the actual printing.
*  This means that no high priority thread will be delayed due to a printing.
***/

// Functions to print on MASC port when running in test mode.
#include "hel.h"

// Define Print thread data.
#define PRINT_STACK_SIZE CYGNUM_HAL_STACK_SIZE_TYPICAL
static cyg_thread printPCB;
static char printStack[PRINT_STACK_SIZE];
static cyg_handle_t printThread;

// Handle to serial device (MASC port).
static cyg_io_handle_t printHandl;

// Semaphore to trig when to print a string.
static cyg_sem_t printSemaphore;

// Max number of characters in each printed line stored in buffer.
#define STRING_SIZE 80
// Max number of 32-bits arguments for each line.
#define MAX_ARGS 6
// Data structure that holds data for each line to print.
typedef struct {
  bool free;
  OSTICK time;
  char str[STRING_SIZE];
  cyg_uint32 args[MAX_ARGS];
} printData_t;

// Max number of strings stored in buffer.
#define PRINT_BUFFER_SIZE 80
// Print buffer, each line to print is first stored in the buffer.
// The Print thread run when the semaphore indicates that there
// is a line to print. The thread reads the line from the buffer,
// formats the string and print it on the serial port.
static printData_t bufferData[PRINT_BUFFER_SIZE];
static cyg_int32 bufferDataIndex = 0; // Index used to get next free bufferData.
static printData_t *buffer[PRINT_BUFFER_SIZE];
static cyg_int32 readIndex = 0;  // Index used by the thread to read from the buffer.
static cyg_int32 writeIndex = 0; // Index used to put a new string in the buffer.

static cyg_int32 eventCounter  = 0; // Counts the events.

/****f* Print/PrintMain
* DESCRIPTION
* Main task thread for Print.
* All printouts are done through this task.
***/
static void PrintMain(cyg_addrword_t lData) {
  char str[STRING_SIZE*2+10];
  cyg_uint32 len;
  
  printf("Print thread started\n");

  while (1) {
    cyg_semaphore_wait(&printSemaphore);
    snprintf(str, 11, "%9ld:", (u32)(buffer[readIndex]->time));
    snprintf(&(str[10]), STRING_SIZE*2, buffer[readIndex]->str, buffer[readIndex]->args[0],
             buffer[readIndex]->args[1],
             buffer[readIndex]->args[2],
             buffer[readIndex]->args[3],
             buffer[readIndex]->args[4],
             buffer[readIndex]->args[5]);
    buffer[readIndex]->free = TRUE;
    len = strlen(str);
    cyg_io_write(printHandl, str, &len);
    readIndex++;
    if (readIndex >= PRINT_BUFFER_SIZE) {
      readIndex = 0;
    }
  }
}

/****f* Print/GetPrintBuffer
* DESCRIPTION
* Allocate and return a buffer to store a string to be printed.
***/
static printData_t* GetPrintBuffer(cyg_int32 *e) {
  printData_t *buf = NULL;
  DISABLE_THREADS(); {
    if (e != 0) {
      *e = ++eventCounter;
    }
    if (bufferData[bufferDataIndex].free) {
      bufferData[bufferDataIndex].free = FALSE;
      buf = &bufferData[bufferDataIndex];
      bufferDataIndex++;
      if (bufferDataIndex >= PRINT_BUFFER_SIZE) {
        bufferDataIndex = 0;
      }
    }
  } ENABLE_THREADS();
  return buf;
}

/****f* Print/PutBuffer
* DESCRIPTION
* Puts a buffer in print queue.
***/
static void PutBuffer(printData_t *buf) {
  DISABLE_THREADS(); {
    buffer[writeIndex] = buf;
    writeIndex++;
    if (writeIndex >= PRINT_BUFFER_SIZE) {
      writeIndex = 0;
    }
  } ENABLE_THREADS();
  cyg_semaphore_post(&printSemaphore);
}

/****f* Print/PrintInit
* DESCRIPTION
* Initializes the Print function and starts the thread.
* The MASC port is setup to write CR LF at end of each line.
***/
void PrintInit(void) {
  int err, i;
  cyg_tty_info_t ttyInfo;
  //cyg_serial_info_t serInfo;
  cyg_uint32 len;
  
  for (i=0; i<PRINT_BUFFER_SIZE; i++) {
    bufferData[i].free = TRUE;
  }

  cyg_semaphore_init(&printSemaphore, 0);

  cyg_thread_create(PRINT_THREAD_PRIO, PrintMain, (cyg_addrword_t) 0,
                    "Print", (void *)&printStack, PRINT_STACK_SIZE,
                    &printThread, &printPCB);

  cyg_thread_resume(printThread);

  err = cyg_io_lookup("/dev/tty0", &printHandl);
  if (err) {
    diag_printf("ERROR opening device tty0.\n");
  }
  /* Setup tty masc port */
  ttyInfo.tty_in_flags = CYG_TTY_IN_FLAGS_BINARY | CYG_TTY_IN_FLAGS_CRLF;
  ttyInfo.tty_out_flags = CYG_TTY_OUT_FLAGS_CRLF;
  len = sizeof(ttyInfo);
  cyg_io_set_config(printHandl, CYG_IO_SET_CONFIG_TTY_INFO, &ttyInfo, &len);
}

/****f* Print/Print
* DESCRIPTION
* This function prints a string to the MASC port.
* The string and some arguments is stored in the buffer
* and the semaphore is posted to tell the Print thread that
* a line is ready to be printed.
* RETURN VALUE
* The function returns 1 if the line is put in the buffer.
* If the buffer is full the return value is 0. 
***/
int Print(char *str, ...) {
  cyg_int32 i;
  va_list ap;
  printData_t *buf;

  buf = GetPrintBuffer(0);
  if (buf == NULL) {
    return 0;
  }

  buf->time = OS_GetTicks();
  strncpy(buf->str, str, STRING_SIZE-1);
  buf->str[STRING_SIZE-1] = '\0';
  va_start(ap, str);
  for (i=0; i<MAX_ARGS; i++) {
    buf->args[i] = va_arg(ap, cyg_uint32);
  }
  va_end(ap);

  PutBuffer(buf);
  return 1;
}

/****f* Print/PrintEvent
* DESCRIPTION
* This function prints a string to the MASC port as an event string.
* Some header data is appended to the string and a LF is added to end of the line.
* This function can be called from DSR functions in interrupt context.
* Two 32 bits arguments can be passed.
* RETURN VALUE
* The function returns 1 if the line is put in the buffer.
* If the buffer is full the return value is 0. 
***/
int PrintEvent(char *str, cyg_uint32 a, cyg_uint32 b) {
  printData_t *buf;
  cyg_int32 e;

  buf = GetPrintBuffer(&e);
  if (buf == NULL) {
    return 0;
  }

  if (strlen(str) > STRING_SIZE-12) {
    diag_printf(str);
    CYG_FAIL("PrintEvent: String too long.");
  }

  buf->time = OS_GetTicks();
  strcpy(buf->str, "E:%d<");
  strcpy(&(buf->str[5]), str);
  strcpy(&(buf->str[strlen(str)+5]), ">****\n");
  buf->args[0] = e;
  buf->args[1] = a;
  buf->args[2] = b;

  PutBuffer(buf);
  return 1;
}

⌨️ 快捷键说明

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