mirror of
				https://github.com/0xFEEDC0DE64/arduino-esp32.git
				synced 2025-10-31 14:11:42 +01:00 
			
		
		
		
	
		
			
	
	
		
			331 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			331 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|   | /** @file */ | ||
|  | 
 | ||
|  | // xos_syslog.h - XOS Event logging module.
 | ||
|  | 
 | ||
|  | // Copyright (c) 2003-2015 Cadence Design Systems, Inc.
 | ||
|  | //
 | ||
|  | // Permission is hereby granted, free of charge, to any person obtaining
 | ||
|  | // a copy of this software and associated documentation files (the
 | ||
|  | // "Software"), to deal in the Software without restriction, including
 | ||
|  | // without limitation the rights to use, copy, modify, merge, publish,
 | ||
|  | // distribute, sublicense, and/or sell copies of the Software, and to
 | ||
|  | // permit persons to whom the Software is furnished to do so, subject to
 | ||
|  | // the following conditions:
 | ||
|  | //
 | ||
|  | // The above copyright notice and this permission notice shall be included
 | ||
|  | // in all copies or substantial portions of the Software.
 | ||
|  | //
 | ||
|  | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | ||
|  | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | ||
|  | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 | ||
|  | // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 | ||
|  | // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 | ||
|  | // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 | ||
|  | // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | ||
|  | 
 | ||
|  | // NOTE: Do not include this file directly in your application. Including
 | ||
|  | // xos.h will automatically include this file.
 | ||
|  | 
 | ||
|  | 
 | ||
|  | #ifndef __XOS_SYSLOG_H__
 | ||
|  | #define __XOS_SYSLOG_H__
 | ||
|  | 
 | ||
|  | #include "xos_types.h"
 | ||
|  | 
 | ||
|  | #ifdef __cplusplus
 | ||
|  | extern "C" { | ||
|  | #endif
 | ||
|  | 
 | ||
|  | 
 | ||
|  | //-----------------------------------------------------------------------------
 | ||
|  | //  The XOS system log is an array of fixed size entries. The size of the log
 | ||
|  | //  is determined by the application, and memory for the log must be provided
 | ||
|  | //  at init time. Every time the log function is called, an entry is made in
 | ||
|  | //  the log and the next pointer advanced. When the log is full, it will wrap
 | ||
|  | //  around and start overwriting the oldest entries.
 | ||
|  | //  Logging can be done from C/C++ code as well as assembly code, and at any
 | ||
|  | //  interrupt level, even from high level interrupt handlers.
 | ||
|  | //-----------------------------------------------------------------------------
 | ||
|  | 
 | ||
|  | 
 | ||
|  | //-----------------------------------------------------------------------------
 | ||
|  | //  Defines.
 | ||
|  | //-----------------------------------------------------------------------------
 | ||
|  | #define XOS_SYSLOG_ENABLED              0x0001
 | ||
|  | 
 | ||
|  | 
 | ||
|  | ///----------------------------------------------------------------------------
 | ||
|  | ///
 | ||
|  | /// Use this macro to compute how much memory to allocate for the syslog.
 | ||
|  | ///
 | ||
|  | ///----------------------------------------------------------------------------
 | ||
|  | #define XOS_SYSLOG_SIZE(num_entries) \
 | ||
|  |     ( sizeof(XosSysLog) + ((num_entries - 1) * sizeof(XosSysLogEntry)) ) | ||
|  | 
 | ||
|  | 
 | ||
|  | ///----------------------------------------------------------------------------
 | ||
|  | ///
 | ||
|  | ///  System log entry structure.
 | ||
|  | ///
 | ||
|  | ///----------------------------------------------------------------------------
 | ||
|  | typedef struct XosSysLogEntry { | ||
|  |     uint32_t                timestamp;  ///< Timestamp in clock cycles
 | ||
|  |     uint32_t                param1;     ///< User defined value
 | ||
|  |     uint32_t                param2;     ///< User defined value
 | ||
|  |     struct XosSysLogEntry * next;       ///< Link to next entry
 | ||
|  | } XosSysLogEntry; | ||
|  | 
 | ||
|  | 
 | ||
|  | ///----------------------------------------------------------------------------
 | ||
|  | ///
 | ||
|  | ///  System log structure.
 | ||
|  | ///
 | ||
|  | ///----------------------------------------------------------------------------
 | ||
|  | typedef struct XosSysLog { | ||
|  |     uint16_t         flags;             ///< Flags
 | ||
|  |     uint16_t         size;              ///< Number of entries
 | ||
|  |     XosSysLogEntry * next;              ///< Next write position
 | ||
|  |     XosSysLogEntry   entries[1];        ///< First entry
 | ||
|  | } XosSysLog; | ||
|  | 
 | ||
|  | 
 | ||
|  | //-----------------------------------------------------------------------------
 | ||
|  | //  Pointer to syslog area.
 | ||
|  | //-----------------------------------------------------------------------------
 | ||
|  | extern XosSysLog * xos_syslog; | ||
|  | 
 | ||
|  | 
 | ||
|  | //----------------------------------------------------------------------------
 | ||
|  | ///
 | ||
|  | ///  Initialize the syslog. Initializing the log also enables it. The system
 | ||
|  | ///  log always wraps around when full and overwrites the oldest entries.
 | ||
|  | ///
 | ||
|  | ///  \param     log_mem         Pointer to allocated memory for the log.
 | ||
|  | ///
 | ||
|  | ///  \param     num_entries     The number of entries that the log can contain.
 | ||
|  | ///
 | ||
|  | ///  \return Returns nothing.
 | ||
|  | ///
 | ||
|  | //----------------------------------------------------------------------------
 | ||
|  | static inline void | ||
|  | xos_syslog_init(void * log_mem, uint16_t num_entries) | ||
|  | { | ||
|  |     uint16_t i; | ||
|  | 
 | ||
|  |     xos_syslog = (XosSysLog *) log_mem; | ||
|  |     xos_syslog->size = num_entries; | ||
|  |     xos_syslog->next = xos_syslog->entries; | ||
|  | 
 | ||
|  |     for (i = 0; i < num_entries - 1; i++) { | ||
|  |         xos_syslog->entries[i].next = &(xos_syslog->entries[i+1]); | ||
|  |         xos_syslog->entries[i].timestamp = 0; | ||
|  |     } | ||
|  |     xos_syslog->entries[i].next = xos_syslog->entries; | ||
|  |     xos_syslog->entries[i].timestamp = 0; | ||
|  | 
 | ||
|  |     xos_syslog->flags = XOS_SYSLOG_ENABLED; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | ///----------------------------------------------------------------------------
 | ||
|  | ///
 | ||
|  | ///  Reset the syslog. All entries made up to now are abandoned and the write
 | ||
|  | ///  pointer is set to the first entry location.
 | ||
|  | ///
 | ||
|  | ///  No parameters.
 | ||
|  | ///
 | ||
|  | ///  \return Returns nothing.
 | ||
|  | ///
 | ||
|  | ///----------------------------------------------------------------------------
 | ||
|  | static inline void | ||
|  | xos_syslog_clear() | ||
|  | { | ||
|  | #if XCHAL_HAVE_INTERRUPTS
 | ||
|  |     uint32_t ps = XT_RSIL(XCHAL_NUM_INTLEVELS); | ||
|  | #endif
 | ||
|  | 
 | ||
|  |     xos_syslog_init(xos_syslog, xos_syslog->size); | ||
|  | #if XCHAL_HAVE_INTERRUPTS
 | ||
|  |     xos_restore_int_pri_level(ps); | ||
|  | #endif
 | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | ///----------------------------------------------------------------------------
 | ||
|  | ///
 | ||
|  | ///  Enable logging to the syslog. This function needs to be called only if
 | ||
|  | ///  logging had been previously disabled via xos_syslog_disable(), since
 | ||
|  | ///  initializing the syslog automatically enables it.
 | ||
|  | ///
 | ||
|  | ///  No parameters.
 | ||
|  | ///
 | ||
|  | ///  \return Returns nothing.
 | ||
|  | ///
 | ||
|  | ///----------------------------------------------------------------------------
 | ||
|  | static inline void | ||
|  | xos_syslog_enable()  | ||
|  | { | ||
|  | #if XCHAL_HAVE_INTERRUPTS
 | ||
|  |     uint32_t ps = XT_RSIL(XCHAL_NUM_INTLEVELS); | ||
|  | #endif
 | ||
|  | 
 | ||
|  |     xos_syslog->flags |= XOS_SYSLOG_ENABLED; | ||
|  | #if XCHAL_HAVE_INTERRUPTS
 | ||
|  |     xos_restore_int_pri_level(ps); | ||
|  | #endif
 | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | ///----------------------------------------------------------------------------
 | ||
|  | ///
 | ||
|  | ///  Disable logging to the syslog. It is sometimes useful to disable logging
 | ||
|  | ///  while the log is being examined or dumped.
 | ||
|  | ///
 | ||
|  | ///  No parameters.
 | ||
|  | ///
 | ||
|  | ///  \return Returns nothing.
 | ||
|  | ///
 | ||
|  | ///----------------------------------------------------------------------------
 | ||
|  | static inline void | ||
|  | xos_syslog_disable() | ||
|  | { | ||
|  | #if XCHAL_HAVE_INTERRUPTS
 | ||
|  |     uint32_t ps = XT_RSIL(XCHAL_NUM_INTLEVELS); | ||
|  | #endif
 | ||
|  |     xos_syslog->flags &= ~XOS_SYSLOG_ENABLED; | ||
|  | #if XCHAL_HAVE_INTERRUPTS
 | ||
|  |     xos_restore_int_pri_level(ps); | ||
|  | #endif
 | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | ///----------------------------------------------------------------------------
 | ||
|  | ///
 | ||
|  | ///  Write an entry into the syslog. This function does disable all interrupts
 | ||
|  | ///  since logging can be done from interrupt handlers as well. It will write
 | ||
|  | ///  into the log only if the log exists and is enabled.
 | ||
|  | ///
 | ||
|  | ///  \param     param1              User defined value.
 | ||
|  | ///
 | ||
|  | ///  \param     param2              User defined value.
 | ||
|  | ///
 | ||
|  | ///  \return Returns nothing.
 | ||
|  | ///
 | ||
|  | ///----------------------------------------------------------------------------
 | ||
|  | static inline void | ||
|  | xos_syslog_write(uint32_t param1, uint32_t param2) | ||
|  | { | ||
|  |     if (xos_syslog != XOS_NULL) { | ||
|  | #if XCHAL_HAVE_INTERRUPTS
 | ||
|  |         uint32_t ps = XT_RSIL(XCHAL_NUM_INTLEVELS); | ||
|  | #endif
 | ||
|  | 
 | ||
|  |         if ((xos_syslog->flags & XOS_SYSLOG_ENABLED) != 0) { | ||
|  |             XosSysLogEntry * next = xos_syslog->next; | ||
|  | 
 | ||
|  |             next->timestamp = xos_get_ccount(); | ||
|  |             next->param1    = param1; | ||
|  |             next->param2    = param2; | ||
|  | 
 | ||
|  |             xos_syslog->next = next->next; | ||
|  |         } | ||
|  | 
 | ||
|  | #if XCHAL_HAVE_INTERRUPTS
 | ||
|  |         xos_restore_int_pri_level(ps); | ||
|  | #endif
 | ||
|  |     } | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | ///----------------------------------------------------------------------------
 | ||
|  | ///
 | ||
|  | ///  Read the first (oldest) entry in the syslog. Will return an error if the
 | ||
|  | ///  log has not been created or is empty. Storage to copy the entry must be
 | ||
|  | ///  provided by the caller.
 | ||
|  | ///
 | ||
|  | ///  \param     entry       Pointer to storage where the entry data will be
 | ||
|  | ///                         copied. This pointer must be passed to 
 | ||
|  | ///                         xos_syslog_get_next().
 | ||
|  | ///
 | ||
|  | ///  \return Returns XOS_OK on success, else error code.
 | ||
|  | ///
 | ||
|  | ///----------------------------------------------------------------------------
 | ||
|  | static inline int32_t | ||
|  | xos_syslog_get_first(XosSysLogEntry * entry) | ||
|  | { | ||
|  |     if (xos_syslog == XOS_NULL) { | ||
|  |         return XOS_ERR_NOT_FOUND; | ||
|  |     } | ||
|  | 
 | ||
|  |     if (entry != XOS_NULL) { | ||
|  | #if XCHAL_HAVE_INTERRUPTS
 | ||
|  |         uint32_t         ps   = XT_RSIL(XCHAL_NUM_INTLEVELS); | ||
|  | #endif
 | ||
|  |         XosSysLogEntry * next = xos_syslog->next; | ||
|  | 
 | ||
|  |         // 'next' should be pointing to the next entry to be overwritten, if we
 | ||
|  |         // have wrapped. This means it is the oldest entry. However if this entry
 | ||
|  |         // has a zero timestamp then we have not wrapped, in which case we must
 | ||
|  |         // look at the first entry in the list.
 | ||
|  |         if (next->timestamp == 0) { | ||
|  |             next = xos_syslog->entries; | ||
|  |         } | ||
|  | 
 | ||
|  |         *entry = *next; | ||
|  | #if XCHAL_HAVE_INTERRUPTS
 | ||
|  |         xos_restore_int_pri_level(ps); | ||
|  | #endif
 | ||
|  |         return entry->timestamp ? XOS_OK : XOS_ERR_NOT_FOUND; | ||
|  |     } | ||
|  | 
 | ||
|  |     return XOS_ERR_INVALID_PARAMETER; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | ///----------------------------------------------------------------------------
 | ||
|  | ///
 | ||
|  | ///  Get the next sequential entry from the syslog. This function must be called
 | ||
|  | ///  only after xos_syslog_get_first() has been called.
 | ||
|  | ///
 | ||
|  | ///  \param     entry       Pointer to storage where entry data will be copied.
 | ||
|  | ///                         Must be the same pointer that was passed in the call
 | ||
|  | ///                         to xos_syslog_get_first(), as it is used to keep track
 | ||
|  | ///                         of the current position.
 | ||
|  | ///
 | ||
|  | ///  \return Returns XOS_OK on success, else error code.
 | ||
|  | ///
 | ||
|  | ///----------------------------------------------------------------------------
 | ||
|  | static inline int32_t | ||
|  | xos_syslog_get_next(XosSysLogEntry * entry) | ||
|  | { | ||
|  |     if (entry != XOS_NULL) { | ||
|  | #if XCHAL_HAVE_INTERRUPTS
 | ||
|  |         uint32_t         ps   = XT_RSIL(XCHAL_NUM_INTLEVELS); | ||
|  | #endif
 | ||
|  |         XosSysLogEntry * next = entry->next; | ||
|  |         int32_t          ret  = XOS_OK; | ||
|  | 
 | ||
|  |         // Make sure we're not pointing past the last entry.
 | ||
|  |         if ((next != XOS_NULL) && (next != xos_syslog->next) && (next->timestamp != 0)) { | ||
|  |             *entry = *next; | ||
|  |         } | ||
|  |         else { | ||
|  |             ret = XOS_ERR_NOT_FOUND; | ||
|  |         } | ||
|  | #if XCHAL_HAVE_INTERRUPTS
 | ||
|  |         xos_restore_int_pri_level(ps); | ||
|  | #endif
 | ||
|  |         return ret; | ||
|  |     } | ||
|  | 
 | ||
|  |     return XOS_ERR_INVALID_PARAMETER; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | #ifdef __cplusplus
 | ||
|  | } | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #endif // __XOS_SYSLOG_H__
 | ||
|  | 
 |