#!/bin/sh # This is a shell archive (produced by GNU sharutils 4.1). # To extract the files from this archive, save it to some FILE, remove # everything before the `!/bin/sh' line above, then type `sh FILE'. # # Made on 1996-08-16 09:47 MDT by . # Source directory was `/a/stout-78/global/ftp/pub/vxworks/vx'. # # Existing files will *not* be overwritten unless `-c' is specified. # # This shar contains: # length mode name # ------ ---------- ------------------------------------------ # 2170 -rw-r--r-- nvLogLib/README # 7752 -rw-r--r-- nvLogLib/nvLogLib.c # 2170 -rw-r--r-- nvLogLib/README # 7752 -rw-r--r-- nvLogLib/nvLogLib.c # touch -am 1231235999 $$.touch >/dev/null 2>&1 if test ! -f 1231235999 && test -f $$.touch; then shar_touch=touch else shar_touch=: echo echo 'WARNING: not restoring timestamps. Consider getting and' echo "installing GNU \`touch', distributed in GNU File Utilities..." echo fi rm -f 1231235999 $$.touch # # ============= nvLogLib/README ============== if test ! -d 'nvLogLib'; then echo 'x - creating directory nvLogLib' mkdir 'nvLogLib' fi if test -f 'nvLogLib/README' && test X"$1" != X"-c"; then echo 'x - skipping nvLogLib/README (file already exists)' else echo 'x - extracting nvLogLib/README (text)' sed 's/^X//' << 'SHAR_EOF' > 'nvLogLib/README' && README for nvLogLib.c X X This is the README file for the NvLogLib. For those of you with NVRAM X in your targets you might find useful. I've written something I call X nvLogLib, which allows you to log messages into your NVRAM and then X retreive them. This faciliy uses sysNvRamSet and sysNvRamGet so you'd X better have those symbols before linking this into your code. X X It works almost exactly like logMsg(). There are three calls, X nvLogInit, nvLogMsg, and nvLogShow. X X nvLogInit takes two numbers, a base address (really the offset X into NVRAM at which you want to start writing) and the total size of X your NVRAM. For instance, on my mv147 I have 2040 bytes of NVRAM, X and my bootline starts at 0x100 (256 in decimal). The bootline can X be a max of 255 so I chose to start writing at 512. When I want to X start, or reset, logging I do the following: X X -> nvLogInit (512, 2040) X X Now that logging is turned on I can have code like this in my X routines: X X nvLogMsg("Received %d bytes in lnRecv.\n", packetSize, 2, 3, 4, 5, 6); X X This works just as logMsg would except that the line is written X to NVRAM. X X When my target hangs, or I just want to see what's been going X on I call the Show routine with the original base address. I need X to supply this since a reboot may have occurred and the variable X that I stored the base address in will have been wiped out. The X output looks like: X -> nvLogShow (512) 2281 0x3bb0f8 (tNetTask): Got an interrupt! 2282 0x3bb0f8 (tNetTask): Got an interrupt! 2342 0x3bb0f8 (tNetTask): Got an interrupt! 2342 0x3bb0f8 (tNetTask): Got an interrupt! 2464 0x3bb0f8 (tNetTask): Got an interrupt! X X X The unfamiliar number in column 1 is the time (using tickGet()) X that the message was logged at. This is a little extra that I X added. X X This code can be called from interrupt level. X When the code comes up against the end of NVRAM it just X resets and starts running from the beginning. A more complex ring X type thing could be done, but this was just something to make X debugging easier. X X Anyways, I hope y'all find this useful. X Later, George X SHAR_EOF $shar_touch -am 0813135496 'nvLogLib/README' && chmod 0644 'nvLogLib/README' || echo 'restore of nvLogLib/README failed' shar_count="`wc -c < 'nvLogLib/README'`" test 2170 -eq "$shar_count" || echo "nvLogLib/README: original size 2170, current size $shar_count" fi # ============= nvLogLib/nvLogLib.c ============== if test -f 'nvLogLib/nvLogLib.c' && test X"$1" != X"-c"; then echo 'x - skipping nvLogLib/nvLogLib.c (file already exists)' else echo 'x - extracting nvLogLib/nvLogLib.c (text)' sed 's/^X//' << 'SHAR_EOF' > 'nvLogLib/nvLogLib.c' && /* nvLogLib.c - a logging facility that writes to NV ram */ X /************************************************************************ X Copyright 1996 by Wind River Systems, Inc. X X All Rights Reserved X Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appears in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of WRS not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. X WRS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL WRS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. X Wind River Systems, Inc. 1010 Atlantic Avenue, Alameda, California 94501 ************************************************************************/ X X /* modification history -------------------- 01b,13aug96,gnn Added disclaimer for use in the FTP archives. 01a,29jul96,gnn written. X */ X /* DESCRIPTION This is a special message logging library that allows a programmer to store arbitrary strings into non-volatile ram. This is very useful when debugging device drivers and ISRs as it allows post-mortem recovery of events that led up to a hard reset. X The routine nvLogMsg() takes the same arguments as logMsg() but instead of writing the message to a message queue for later processing stores it in non-volatile RAM. Each subsequent call to nvLogMsg() appends a new message after the last one written. X An added feature of nvLogMsg() is timestamping information. Not only is the message stored, as well as the task number and the usual logMsg() information but the kernel's tick counter, gotten using tickGet(), at the time the message was recorded is stored with the message. X To read out the messages stored in non-volatile ram the routine nvLogDump() is used. This lists out all of the messages that have been written to non-volatile ram. X INITIALIZATION To initialize the message logging facilities, the routine nvLogInit() must be called before calling any other routine in this module. X INCLUDE FILES: taskLib.h stdio.h stdlib.h sysLib.h tickLib.h string.h ioLib.h */ X /* includes */ #include "vxWorks.h" #include "taskLib.h" #include "stdio.h" #include "stdlib.h" #include "sysLib.h" #include "tickLib.h" #include "string.h" #include "ioLib.h" X /* defints */ #define NV_MSG_LEN 64 /* Maximum single message. */ #define NV_NUM_LEN 8 /* How long is a number string? */ X /* typedefs */ X /* globals */ X /* locals */ LOCAL BOOL nvLogFlag = FALSE; LOCAL int nvIndex; /* Index into the non-volatile ram */ LOCAL int nvOrigin; /* Where we started writing. */ LOCAL int nvTotal; /* The total size we can write to. */ X X /* forward declarations */ X /******************************************************************************* * * nvLogInit - initialize the NVRAM message logging library * * This routine initializes some global variables used by the nvLogLib. * The NVRAM region must be specified in this call. * * This routine must be called before any other routine in nvLogLib. * This is done by the root task, usrRoot(), in usrConfig.c. * * RETURNS: OK or ERROR if non-volatile ram is not available. */ X STATUS nvLogInit X ( X int baseAddr, /* Base of where to write in non-volatile RAM */ X int size /* Size of NVRAM that we are using. */ X ) X { X X extern int nvIndex; X extern int nvOrigin; X extern int nvTotal; X char buffer[NV_NUM_LEN]; X X nvOrigin = baseAddr; X nvIndex = baseAddr; X X sprintf(buffer, "%d", nvIndex); X sysNvRamSet(buffer, NV_NUM_LEN, baseAddr); X X /* Write all data after the index. */ X nvIndex += NV_NUM_LEN; X X nvTotal = size - baseAddr; X X return (OK); X } X /******************************************************************************* * * nvLogMsg - log a formatted error message to non-volatile RAM * * This routine logs a specified message to non-volatile RAM. This * routine's syntax is similar to printf() -- a format string is followed * by arguments to format. However, the logMsg() routine * requires a fixed number of arguments (6). * * The task ID of the caller is prepended to the specified message. * * The current tick is also stored with the message. * * SPECIAL CONSIDERATIONS * Because nvLogMsg() does not actually perform the output directly to the * logging streams, but instead stores the message in non-volatile RAM, * nvLogMsg() can be called from interrupt service routines. * * The string stored is limited to NV_MSG_LEN bytes to save on memory. * * EXAMPLE * If the following code were executed by task 20: * .CS * { * name = "GRONK"; * num = 123; * * nvLogMsg ("ERROR - name = %s, num = %d.\en", name, num, 0, 0, 0, 0); * } * .CE * the following error message would appear on the system log: * .CS * Tick: 586, 0x180400 (t20): ERROR - name = GRONK, num = 123. * .CE * * RETURNS: OK or ERROR if someone else is currently in this routine. * * SEE ALSO: printf(), logTask() */ X int nvLogMsg X ( X char *fmt, /* Format string */ X int arg1, /* Arguments to be formatted. */ X int arg2, X int arg3, X int arg4, X int arg5, X int arg6 X ) X { X X char message[NV_MSG_LEN]; X char index[NV_NUM_LEN]; X extern BOOL nvLogFlag; X extern int nvOrigin; X X /* Make sure that we're not about to stomp on someone else. */ X X if (nvLogFlag == TRUE) X return (ERROR); X X /* Entering critical section */ X nvLogFlag = TRUE; X X /* Discover who we are. */ X if (taskIdSelf() < 0) X sprintf(message, "%ld interrupt: ", tickGet()); X else X sprintf(message, "%ld %#x (%s): ", tickGet(), taskIdSelf(), X taskName(taskIdSelf())); X X sprintf(message + strlen(message), fmt, arg1, arg2, arg3, arg4, arg5, arg6); X X /* If we're about to go too far then reset to the beginning. */ X if ((nvIndex + strlen(message)) > nvTotal) X nvIndex = nvOrigin + NV_NUM_LEN; X X /* Actually store the data. */ X sysNvRamSet(message, strlen(message), nvIndex); X X /* Update our index. */ X nvIndex += strlen(message); X X /* Increment our stored counter and store it at the base address. */ X sprintf(index, "%d", nvIndex); X sysNvRamSet(index, NV_NUM_LEN, nvOrigin); X X /* Leaving critical section */ X nvLogFlag = FALSE; X X return (OK); X } X /******************************************************************************* X * X * nvLogShow - show the non-volatile RAM log X * X * This routine will show all of the messages that have been stored in X * non-volatile ram by nvLogMsg up until the current point in time. X * X * RETURNS: OK or ERROR if we cannot malloc enough memory to store the X * non-volatile log. X * X */ int nvLogShow X ( X int baseAddr /* The base address in non-volatile RAM that was */ X /* used in the nvLogInit() call. */ X ) X { X X int nvIndex; X char *buffer; /* Where we're going to print the log from. */ X char index[NV_NUM_LEN]; X X sysNvRamGet(index, NV_NUM_LEN, baseAddr); X X nvIndex = atoi(index); X buffer = malloc(nvIndex - (baseAddr + NV_NUM_LEN)); X X if (buffer == NULL) X return (ERROR); X X sysNvRamGet(buffer, nvIndex - (baseAddr + NV_NUM_LEN), X baseAddr + NV_NUM_LEN); X X /* Write to the standard output. */ X write(1, buffer, nvIndex - (baseAddr + NV_NUM_LEN)); X X free(buffer); X X return (OK); X } SHAR_EOF $shar_touch -am 0813134596 'nvLogLib/nvLogLib.c' && chmod 0644 'nvLogLib/nvLogLib.c' || echo 'restore of nvLogLib/nvLogLib.c failed' shar_count="`wc -c < 'nvLogLib/nvLogLib.c'`" test 7752 -eq "$shar_count" || echo "nvLogLib/nvLogLib.c: original size 7752, current size $shar_count" fi # ============= nvLogLib/README ============== if test -f 'nvLogLib/README' && test X"$1" != X"-c"; then echo 'x - skipping nvLogLib/README (file already exists)' else echo 'x - extracting nvLogLib/README (text)' sed 's/^X//' << 'SHAR_EOF' > 'nvLogLib/README' && README for nvLogLib.c X X This is the README file for the NvLogLib. For those of you with NVRAM X in your targets you might find useful. I've written something I call X nvLogLib, which allows you to log messages into your NVRAM and then X retreive them. This faciliy uses sysNvRamSet and sysNvRamGet so you'd X better have those symbols before linking this into your code. X X It works almost exactly like logMsg(). There are three calls, X nvLogInit, nvLogMsg, and nvLogShow. X X nvLogInit takes two numbers, a base address (really the offset X into NVRAM at which you want to start writing) and the total size of X your NVRAM. For instance, on my mv147 I have 2040 bytes of NVRAM, X and my bootline starts at 0x100 (256 in decimal). The bootline can X be a max of 255 so I chose to start writing at 512. When I want to X start, or reset, logging I do the following: X X -> nvLogInit (512, 2040) X X Now that logging is turned on I can have code like this in my X routines: X X nvLogMsg("Received %d bytes in lnRecv.\n", packetSize, 2, 3, 4, 5, 6); X X This works just as logMsg would except that the line is written X to NVRAM. X X When my target hangs, or I just want to see what's been going X on I call the Show routine with the original base address. I need X to supply this since a reboot may have occurred and the variable X that I stored the base address in will have been wiped out. The X output looks like: X -> nvLogShow (512) 2281 0x3bb0f8 (tNetTask): Got an interrupt! 2282 0x3bb0f8 (tNetTask): Got an interrupt! 2342 0x3bb0f8 (tNetTask): Got an interrupt! 2342 0x3bb0f8 (tNetTask): Got an interrupt! 2464 0x3bb0f8 (tNetTask): Got an interrupt! X X X The unfamiliar number in column 1 is the time (using tickGet()) X that the message was logged at. This is a little extra that I X added. X X This code can be called from interrupt level. X When the code comes up against the end of NVRAM it just X resets and starts running from the beginning. A more complex ring X type thing could be done, but this was just something to make X debugging easier. X X Anyways, I hope y'all find this useful. X Later, George X SHAR_EOF $shar_touch -am 0813135496 'nvLogLib/README' && chmod 0644 'nvLogLib/README' || echo 'restore of nvLogLib/README failed' shar_count="`wc -c < 'nvLogLib/README'`" test 2170 -eq "$shar_count" || echo "nvLogLib/README: original size 2170, current size $shar_count" fi # ============= nvLogLib/nvLogLib.c ============== if test -f 'nvLogLib/nvLogLib.c' && test X"$1" != X"-c"; then echo 'x - skipping nvLogLib/nvLogLib.c (file already exists)' else echo 'x - extracting nvLogLib/nvLogLib.c (text)' sed 's/^X//' << 'SHAR_EOF' > 'nvLogLib/nvLogLib.c' && /* nvLogLib.c - a logging facility that writes to NV ram */ X /************************************************************************ X Copyright 1996 by Wind River Systems, Inc. X X All Rights Reserved X Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appears in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of WRS not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. X WRS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL WRS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. X Wind River Systems, Inc. 1010 Atlantic Avenue, Alameda, California 94501 ************************************************************************/ X X /* modification history -------------------- 01b,13aug96,gnn Added disclaimer for use in the FTP archives. 01a,29jul96,gnn written. X */ X /* DESCRIPTION This is a special message logging library that allows a programmer to store arbitrary strings into non-volatile ram. This is very useful when debugging device drivers and ISRs as it allows post-mortem recovery of events that led up to a hard reset. X The routine nvLogMsg() takes the same arguments as logMsg() but instead of writing the message to a message queue for later processing stores it in non-volatile RAM. Each subsequent call to nvLogMsg() appends a new message after the last one written. X An added feature of nvLogMsg() is timestamping information. Not only is the message stored, as well as the task number and the usual logMsg() information but the kernel's tick counter, gotten using tickGet(), at the time the message was recorded is stored with the message. X To read out the messages stored in non-volatile ram the routine nvLogDump() is used. This lists out all of the messages that have been written to non-volatile ram. X INITIALIZATION To initialize the message logging facilities, the routine nvLogInit() must be called before calling any other routine in this module. X INCLUDE FILES: taskLib.h stdio.h stdlib.h sysLib.h tickLib.h string.h ioLib.h */ X /* includes */ #include "vxWorks.h" #include "taskLib.h" #include "stdio.h" #include "stdlib.h" #include "sysLib.h" #include "tickLib.h" #include "string.h" #include "ioLib.h" X /* defints */ #define NV_MSG_LEN 64 /* Maximum single message. */ #define NV_NUM_LEN 8 /* How long is a number string? */ X /* typedefs */ X /* globals */ X /* locals */ LOCAL BOOL nvLogFlag = FALSE; LOCAL int nvIndex; /* Index into the non-volatile ram */ LOCAL int nvOrigin; /* Where we started writing. */ LOCAL int nvTotal; /* The total size we can write to. */ X X /* forward declarations */ X /******************************************************************************* * * nvLogInit - initialize the NVRAM message logging library * * This routine initializes some global variables used by the nvLogLib. * The NVRAM region must be specified in this call. * * This routine must be called before any other routine in nvLogLib. * This is done by the root task, usrRoot(), in usrConfig.c. * * RETURNS: OK or ERROR if non-volatile ram is not available. */ X STATUS nvLogInit X ( X int baseAddr, /* Base of where to write in non-volatile RAM */ X int size /* Size of NVRAM that we are using. */ X ) X { X X extern int nvIndex; X extern int nvOrigin; X extern int nvTotal; X char buffer[NV_NUM_LEN]; X X nvOrigin = baseAddr; X nvIndex = baseAddr; X X sprintf(buffer, "%d", nvIndex); X sysNvRamSet(buffer, NV_NUM_LEN, baseAddr); X X /* Write all data after the index. */ X nvIndex += NV_NUM_LEN; X X nvTotal = size - baseAddr; X X return (OK); X } X /******************************************************************************* * * nvLogMsg - log a formatted error message to non-volatile RAM * * This routine logs a specified message to non-volatile RAM. This * routine's syntax is similar to printf() -- a format string is followed * by arguments to format. However, the logMsg() routine * requires a fixed number of arguments (6). * * The task ID of the caller is prepended to the specified message. * * The current tick is also stored with the message. * * SPECIAL CONSIDERATIONS * Because nvLogMsg() does not actually perform the output directly to the * logging streams, but instead stores the message in non-volatile RAM, * nvLogMsg() can be called from interrupt service routines. * * The string stored is limited to NV_MSG_LEN bytes to save on memory. * * EXAMPLE * If the following code were executed by task 20: * .CS * { * name = "GRONK"; * num = 123; * * nvLogMsg ("ERROR - name = %s, num = %d.\en", name, num, 0, 0, 0, 0); * } * .CE * the following error message would appear on the system log: * .CS * Tick: 586, 0x180400 (t20): ERROR - name = GRONK, num = 123. * .CE * * RETURNS: OK or ERROR if someone else is currently in this routine. * * SEE ALSO: printf(), logTask() */ X int nvLogMsg X ( X char *fmt, /* Format string */ X int arg1, /* Arguments to be formatted. */ X int arg2, X int arg3, X int arg4, X int arg5, X int arg6 X ) X { X X char message[NV_MSG_LEN]; X char index[NV_NUM_LEN]; X extern BOOL nvLogFlag; X extern int nvOrigin; X X /* Make sure that we're not about to stomp on someone else. */ X X if (nvLogFlag == TRUE) X return (ERROR); X X /* Entering critical section */ X nvLogFlag = TRUE; X X /* Discover who we are. */ X if (taskIdSelf() < 0) X sprintf(message, "%ld interrupt: ", tickGet()); X else X sprintf(message, "%ld %#x (%s): ", tickGet(), taskIdSelf(), X taskName(taskIdSelf())); X X sprintf(message + strlen(message), fmt, arg1, arg2, arg3, arg4, arg5, arg6); X X /* If we're about to go too far then reset to the beginning. */ X if ((nvIndex + strlen(message)) > nvTotal) X nvIndex = nvOrigin + NV_NUM_LEN; X X /* Actually store the data. */ X sysNvRamSet(message, strlen(message), nvIndex); X X /* Update our index. */ X nvIndex += strlen(message); X X /* Increment our stored counter and store it at the base address. */ X sprintf(index, "%d", nvIndex); X sysNvRamSet(index, NV_NUM_LEN, nvOrigin); X X /* Leaving critical section */ X nvLogFlag = FALSE; X X return (OK); X } X /******************************************************************************* X * X * nvLogShow - show the non-volatile RAM log X * X * This routine will show all of the messages that have been stored in X * non-volatile ram by nvLogMsg up until the current point in time. X * X * RETURNS: OK or ERROR if we cannot malloc enough memory to store the X * non-volatile log. X * X */ int nvLogShow X ( X int baseAddr /* The base address in non-volatile RAM that was */ X /* used in the nvLogInit() call. */ X ) X { X X int nvIndex; X char *buffer; /* Where we're going to print the log from. */ X char index[NV_NUM_LEN]; X X sysNvRamGet(index, NV_NUM_LEN, baseAddr); X X nvIndex = atoi(index); X buffer = malloc(nvIndex - (baseAddr + NV_NUM_LEN)); X X if (buffer == NULL) X return (ERROR); X X sysNvRamGet(buffer, nvIndex - (baseAddr + NV_NUM_LEN), X baseAddr + NV_NUM_LEN); X X /* Write to the standard output. */ X write(1, buffer, nvIndex - (baseAddr + NV_NUM_LEN)); X X free(buffer); X X return (OK); X } SHAR_EOF $shar_touch -am 0813134596 'nvLogLib/nvLogLib.c' && chmod 0644 'nvLogLib/nvLogLib.c' || echo 'restore of nvLogLib/nvLogLib.c failed' shar_count="`wc -c < 'nvLogLib/nvLogLib.c'`" test 7752 -eq "$shar_count" || echo "nvLogLib/nvLogLib.c: original size 7752, current size $shar_count" fi exit 0