📄 print.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 + -