mirror of
				https://github.com/0xFEEDC0DE64/arduino-esp32.git
				synced 2025-11-04 08:01:38 +01:00 
			
		
		
		
	
		
			
	
	
		
			525 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			525 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
								 | 
							
								/** @file */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// xos.h - XOS API interface and data structures visible to user code.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// 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.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifndef __XOS_H__
							 | 
						||
| 
								 | 
							
								#define __XOS_H__
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef __cplusplus
							 | 
						||
| 
								 | 
							
								extern "C" {
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include "xos_types.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <xtensa/config/core.h>
							 | 
						||
| 
								 | 
							
								#if XCHAL_HAVE_INTERRUPTS
							 | 
						||
| 
								 | 
							
								#include <xtensa/tie/xt_core.h>
							 | 
						||
| 
								 | 
							
								#include <xtensa/tie/xt_interrupt.h>
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include "xos_common.h"
							 | 
						||
| 
								 | 
							
								#include "xos_errors.h"
							 | 
						||
| 
								 | 
							
								#include "xos_regaccess.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//-----------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								// Convert x into a literal string.
							 | 
						||
| 
								 | 
							
								//-----------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								#define _XOS_STR(x)             __XOS_STR(x)
							 | 
						||
| 
								 | 
							
								#define __XOS_STR(x)            #x
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//-----------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								// XOS version.
							 | 
						||
| 
								 | 
							
								//-----------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								#define XOS_VERSION_MAJOR       1
							 | 
						||
| 
								 | 
							
								#define XOS_VERSION_MINOR       10
							 | 
						||
| 
								 | 
							
								#define XOS_VERSION_STRING      "1.10"      ///< XOS version string.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//-----------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								// Runtime error handling.
							 | 
						||
| 
								 | 
							
								//-----------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//-----------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								///  Reports a fatal error and halts XOS operation, i.e. halts the system. This
							 | 
						||
| 
								 | 
							
								///  function will call a user-registered error handler (if one has been set) 
							 | 
						||
| 
								 | 
							
								///  and then halt the system. The user handler may do system-specific things
							 | 
						||
| 
								 | 
							
								///  such as record the error reason in nonvolatile memory etc.
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								///  \param     errcode         Error code. May be any user defined value < 0.
							 | 
						||
| 
								 | 
							
								///                             Values >=0 are reserved for use by the system.
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								///  \param     errmsg          Optional text string describing the error.
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								///  \return    This function does not return.
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								//-----------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								void
							 | 
						||
| 
								 | 
							
								xos_fatal_error(int32_t errcode, const char * errmsg);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if XOS_DEBUG
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Do not call directly.
							 | 
						||
| 
								 | 
							
								void
							 | 
						||
| 
								 | 
							
								xos_assert(const char * file, int32_t line);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//-----------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								///  Check condition and fail if condition expression is false.
							 | 
						||
| 
								 | 
							
								///  In debug builds, an assertion failure will cause a fatal error to be
							 | 
						||
| 
								 | 
							
								///  reported. In non-debug builds, assertions are compiled out.
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								///  NOTE: Remember that any code in XOS_ASSERT() statements gets compiled out
							 | 
						||
| 
								 | 
							
								///  for non-debug builds.
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								//-----------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define XOS_ASSERT(expr)        if ((expr) == 0) xos_assert(__FILE__, __LINE__)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define XOS_ASSERT(expr)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//-----------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								/// Interrupt handler function pointer type.
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								//-----------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								typedef void    (XosIntFunc)(void * arg);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//-----------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								/// Print handler function pointer type.
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								//-----------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								typedef int32_t (XosPrintFunc)(void * arg, const char * fmt, ...);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//-----------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								/// Fatal error handler function pointer type.
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								//-----------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								typedef void    (XosFatalErrFunc)(int32_t errcode, const char * errmsg);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//-----------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								/// Exception handler function pointer type.
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								//-----------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								typedef void    (XosExcHandlerFunc)(XosExcFrame * frame);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//-----------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								///  Install a user defined exception handler for the specified exception type.
							 | 
						||
| 
								 | 
							
								///  This will override the default XOS exception handler. The handler is a C
							 | 
						||
| 
								 | 
							
								///  function that is passed one parameter -- a pointer to the exception frame.
							 | 
						||
| 
								 | 
							
								///  The exception frame is allocated on the stack of the thread that caused the
							 | 
						||
| 
								 | 
							
								///  exception, and contains saved state and exception information. For details
							 | 
						||
| 
								 | 
							
								///  of the exception frame see the structure XosExcFrame.
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								///  \param     exc             Exception type (number) to override. The exception
							 | 
						||
| 
								 | 
							
								///                             numbers are enumerated in <xtensa/corebits.h>.
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								///  \param     handler         Pointer to handler function to be installed.
							 | 
						||
| 
								 | 
							
								///                             To revert to the default handler, pass NULL.
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								///  \return    Returns a pointer to previous handler installed, if any.
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								//-----------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								XosExcHandlerFunc *
							 | 
						||
| 
								 | 
							
								xos_register_exception_handler(int32_t exc, XosExcHandlerFunc * handler);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//-----------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								///  Install a user defined fatal error handler. This function will be called if
							 | 
						||
| 
								 | 
							
								///  a fatal error is reported either by user code or by XOS itself. It will be
							 | 
						||
| 
								 | 
							
								///  passed the same arguments that are passed to xos_fatal_error().
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								///  The handler need not return. It should make minimal assumptions about the
							 | 
						||
| 
								 | 
							
								///  state of the system. In particular, it should not assume that further XOS
							 | 
						||
| 
								 | 
							
								///  system calls will succeed.
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								///  \param     handler         Pointer to handler function to be installed.
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								///  \return    Returns a pointer to previous handler installed, if any.
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								//-----------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								XosFatalErrFunc *
							 | 
						||
| 
								 | 
							
								xos_register_fatal_error_handler(XosFatalErrFunc * handler);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef _XOS_INCLUDE_INTERNAL_
							 | 
						||
| 
								 | 
							
								# include "xos_internal.h"
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include "xos_thread.h"
							 | 
						||
| 
								 | 
							
								#include "xos_timer.h"
							 | 
						||
| 
								 | 
							
								#include "xos_cond.h"
							 | 
						||
| 
								 | 
							
								#include "xos_event.h"
							 | 
						||
| 
								 | 
							
								#include "xos_mutex.h"
							 | 
						||
| 
								 | 
							
								#include "xos_msgq.h"
							 | 
						||
| 
								 | 
							
								#include "xos_semaphore.h"
							 | 
						||
| 
								 | 
							
								#include "xos_stopwatch.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//-----------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								///  Register a handler function to call when interrupt "num" occurs.
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								///  For level-triggered and timer interrupts, the handler function will have
							 | 
						||
| 
								 | 
							
								///  to clear the source of the interrupt before returning, to avoid infinitely
							 | 
						||
| 
								 | 
							
								///  retaking the interrupt. Edge-triggered and software interrupts are 
							 | 
						||
| 
								 | 
							
								///  automatically cleared by the OS interrupt dispatcher (see xos_handlers.S).
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								///  \param     num             Xtensa internal interrupt number (0..31). To
							 | 
						||
| 
								 | 
							
								///                             refer to a specific external interrupt number
							 | 
						||
| 
								 | 
							
								///                             (BInterrupt pin), use HAL macro XCHAL_EXTINTx_NUM
							 | 
						||
| 
								 | 
							
								///                             where 'x' is the external number.
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								///  \param     handler         Pointer to handler function.
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								///  \param     arg             Argument passed to handler.
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								///  \return    Returns XOS_OK if successful, else error code.
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								//-----------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								int32_t
							 | 
						||
| 
								 | 
							
								xos_register_interrupt_handler(int32_t num, XosIntFunc * handler, void * arg);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//-----------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								///  Unregister a handler function for interrupt "num". If no handler was 
							 | 
						||
| 
								 | 
							
								///  installed, this function will have no effect.
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								///  \param     num             Xtensa internal interrupt number (0..31). To
							 | 
						||
| 
								 | 
							
								///                             refer to a specific external interrupt number
							 | 
						||
| 
								 | 
							
								///                             (BInterrupt pin), use HAL macro XCHAL_EXTINTx_NUM
							 | 
						||
| 
								 | 
							
								///                             where 'x' is the external number.
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								///  \return    Returns XOS_OK if successful, else error code.
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								//-----------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								int32_t
							 | 
						||
| 
								 | 
							
								xos_unregister_interrupt_handler(int32_t num);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//-----------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								///  Register a high priority interrupt handler for interrupt level "level".
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								///  Unlike low and medium priority interrupt handlers, high priority handlers
							 | 
						||
| 
								 | 
							
								///  are not installed for a specific interrupt number, but for an interrupt
							 | 
						||
| 
								 | 
							
								///  level. The level must be above XCHAL_EXCM_LEVEL. The handler function must
							 | 
						||
| 
								 | 
							
								///  be written in assembly since C handlers are not supported for levels above
							 | 
						||
| 
								 | 
							
								///  XCHAL_EXCM_LEVEL. The handler function must preserve all registers except
							 | 
						||
| 
								 | 
							
								///  a0, and must return to the dispatcher via a "ret" instruction, not "rfi".
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								///  NOTE: This method of dispatch takes a few cycles of overhead. If you wish
							 | 
						||
| 
								 | 
							
								///  to save even these cycles, then you can define your own dispatch function
							 | 
						||
| 
								 | 
							
								///  to override the built-in dispatcher. See xos_handlers.S for more details.
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								///  \param     level           The interrupt level to be handled.
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								///  \param     handler         Pointer to handler function.
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								///  \return    Returns XOS_OK if successful, else error code.
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								//-----------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								int32_t
							 | 
						||
| 
								 | 
							
								xos_register_hp_interrupt_handler(int32_t level, void * handler);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//-----------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								///  Enable a specific interrupt, by interrupt number.
							 | 
						||
| 
								 | 
							
								///  The state (enabled vs. disabled) of individual interrupts is global, i.e.
							 | 
						||
| 
								 | 
							
								///  not associated with any specific thread. Depending on system options and
							 | 
						||
| 
								 | 
							
								///  implementation, this state may be stored in one of two ways:
							 | 
						||
| 
								 | 
							
								///  - directly in the INTENABLE register, or
							 | 
						||
| 
								 | 
							
								///  - in a global variable (this is generally the case when INTENABLE is used
							 | 
						||
| 
								 | 
							
								///    not just to control what interrupts are enabled globally, but also for
							 | 
						||
| 
								 | 
							
								///    software interrupt prioritization within an interrupt level, effectively
							 | 
						||
| 
								 | 
							
								///    providing finer grained levels; in this case XOS takes care to update
							 | 
						||
| 
								 | 
							
								///    INTENABLE whenever either the global enabled-state variable or the 
							 | 
						||
| 
								 | 
							
								///    per-thread fine-grained-level variable change).
							 | 
						||
| 
								 | 
							
								///  Thus it is best to never access the INTENABLE register directly.
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								///  To modify thread-specific interrupt priority level, use one of:
							 | 
						||
| 
								 | 
							
								///    - xos_set_int_pri_level()
							 | 
						||
| 
								 | 
							
								///    - xos_restore_int_pri_level()
							 | 
						||
| 
								 | 
							
								///    - xos_disable_interrupts()
							 | 
						||
| 
								 | 
							
								///    - xos_restore_interrupts()
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								///  NOTE: To refer to a specific external interrupt number (BInterrupt pin),
							 | 
						||
| 
								 | 
							
								///  use HAL macro XCHAL_EXTINTx_NUM where 'x' is the external interrupt
							 | 
						||
| 
								 | 
							
								///  number.  For example, to enable external interrupt 3 (BInterrupt[3]),
							 | 
						||
| 
								 | 
							
								///  you can use:
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								///      xos_interrupt_enable( XCHAL_EXTINT3_NUM );
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								///  \param     intnum          Interrupt number to enable. Must range between 0-31.
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								///  \return    Returns nothing.
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								//-----------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								void
							 | 
						||
| 
								 | 
							
								xos_interrupt_enable(uint32_t intnum);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//-----------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								///  Disable a specific individual interrupt, by interrupt number.
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								///  This is the counterpart to xos_interrupt_enable(). See the description
							 | 
						||
| 
								 | 
							
								///  of xos_interrupt_enable() for further comments and notes.
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								///  \param     intnum          Interrupt number to disable. Must range between 0-31.
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								///  \return    Returns nothing.
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								//-----------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								void
							 | 
						||
| 
								 | 
							
								xos_interrupt_disable(uint32_t intnum);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//-----------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								///  Get the CPU's current interrupt priority level. Interrupts at or below this
							 | 
						||
| 
								 | 
							
								///  priority level are blocked.
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								///  \return    Returns the current IPL, ranging from 0 to XCHAL_NUM_INTLEVELS.
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								//-----------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								static inline uint32_t
							 | 
						||
| 
								 | 
							
								xos_get_int_pri_level(void)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								#if XCHAL_HAVE_INTERRUPTS
							 | 
						||
| 
								 | 
							
								    return XT_RSR_PS() & 0xF;
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								    return 0;
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//-----------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								///  Set the CPU's interrupt priority level to the specified level, but only if
							 | 
						||
| 
								 | 
							
								///  the current IPL is below the one requested. This function will never cause
							 | 
						||
| 
								 | 
							
								///  the interrupt priority level to be lowered from the current level.
							 | 
						||
| 
								 | 
							
								///  Call this function to block interrupts at or below the specified priority
							 | 
						||
| 
								 | 
							
								///  level.
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								///  When setting the IPL temporarily (such as in a critical section), call
							 | 
						||
| 
								 | 
							
								///  xos_set_int_pri_level(), execute the critical code section, and then call
							 | 
						||
| 
								 | 
							
								///  xos_restore_int_pri_level().
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								///  The interrupt priority level is part of the thread context, so it is saved
							 | 
						||
| 
								 | 
							
								///  and restored across context switches. To enable and disable individual
							 | 
						||
| 
								 | 
							
								///  interrupts globally, use the functions xos_interrupt_enable() and
							 | 
						||
| 
								 | 
							
								///  xos_interrupt_disable() instead.
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								///  NOTE: It is usually not required to disable interrupts at a level higher
							 | 
						||
| 
								 | 
							
								///  than that of the highest priority interrupt that interacts with the OS
							 | 
						||
| 
								 | 
							
								///  (i.e. calls into XOS such that threads may be woken / blocked / 
							 | 
						||
| 
								 | 
							
								///  reprioritized / switched, or otherwise access XOS data structures).
							 | 
						||
| 
								 | 
							
								///  In XOS, that maximum level is XOS_MAX_OS_INTLEVEL, which defaults to
							 | 
						||
| 
								 | 
							
								///  XCHAL_EXCM_LEVEL. This may be modified by editing xos_params.h and
							 | 
						||
| 
								 | 
							
								///  rebuilding XOS.
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								///  \param     level           The new interrupt priority level (IPL).
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								///  \return    Returns a value that can be used to restore the previous
							 | 
						||
| 
								 | 
							
								///             priority level by calling xos_restore_int_pri_level(). This
							 | 
						||
| 
								 | 
							
								///             value should be treated as opaque by application code, and
							 | 
						||
| 
								 | 
							
								///             should be passed unchanged to the restore function.
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								//-----------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								__attribute__((always_inline))
							 | 
						||
| 
								 | 
							
								static inline uint32_t
							 | 
						||
| 
								 | 
							
								xos_set_int_pri_level(uint32_t level)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								#if XCHAL_HAVE_INTERRUPTS
							 | 
						||
| 
								 | 
							
								#pragma no_reorder
							 | 
						||
| 
								 | 
							
								    uint32_t ps = XT_RSR_PS();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (level > (ps & 0xF)) {
							 | 
						||
| 
								 | 
							
								        level = (ps & ~0xF) | level;
							 | 
						||
| 
								 | 
							
								        XT_WSR_PS(level);
							 | 
						||
| 
								 | 
							
								        XT_RSYNC();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return ps;
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								    return 0;
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//-----------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								///  Restores the CPU to a previously saved interrupt priority level. This level
							 | 
						||
| 
								 | 
							
								///  must have been obtained by calling xos_set_int_pri_level().
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								///  \param     oldval          Return value from xos_set_int_pri_level().
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								///  \return    Returns nothing.
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								//-----------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								__attribute__((always_inline))
							 | 
						||
| 
								 | 
							
								static inline void
							 | 
						||
| 
								 | 
							
								xos_restore_int_pri_level(const uint32_t oldval)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								#if XCHAL_HAVE_INTERRUPTS
							 | 
						||
| 
								 | 
							
								#pragma no_reorder
							 | 
						||
| 
								 | 
							
								    XT_WSR_PS(oldval);
							 | 
						||
| 
								 | 
							
								    XT_RSYNC();
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								    // Nothing
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//-----------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								///  Disable all interrupts that can interact directly with the OS. This is a
							 | 
						||
| 
								 | 
							
								///  convenience function, shorthand for setting the IPL to XOS_MAX_OS_INTLEVEL.
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								///  Returns: A value that can be used to restore the previous priority level
							 | 
						||
| 
								 | 
							
								///  by calling xos_restore_interrupts(). This value should be treated as
							 | 
						||
| 
								 | 
							
								///  opaque by application code, and should be passed unchanged to the restore
							 | 
						||
| 
								 | 
							
								///  function.
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								//-----------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								static inline uint32_t
							 | 
						||
| 
								 | 
							
								xos_disable_interrupts(void)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    return xos_set_int_pri_level(XOS_MAX_OS_INTLEVEL);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//-----------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								///  Restore the CPU's previously saved interrupt status. This is a convenience
							 | 
						||
| 
								 | 
							
								///  function, the counterpart to xos_disable_interrupts().
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								///  \return    rval            Return value from xos_disable_interrupts().
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								///  \return    Returns nothing.
							 | 
						||
| 
								 | 
							
								///
							 | 
						||
| 
								 | 
							
								//-----------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								static inline void
							 | 
						||
| 
								 | 
							
								xos_restore_interrupts(uint32_t rval)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    xos_restore_int_pri_level(rval);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef _XOS_INCLUDE_INTERNAL_
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//-----------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								//  Enter an OS critical section, i.e. get exclusive access to OS critical 
							 | 
						||
| 
								 | 
							
								//  state and data structures. Code that manipulates the state of OS objects
							 | 
						||
| 
								 | 
							
								//  or modifies internal OS state must call this function first, to ensure
							 | 
						||
| 
								 | 
							
								//  that it has exclusive access. On a single-core system, this is equivalent
							 | 
						||
| 
								 | 
							
								//  to blocking all interrupts that can interact directly with the OS, i.e.
							 | 
						||
| 
								 | 
							
								//  all interrupts at or below XOS_MAX_OS_INTLEVEL. In a multi-core system
							 | 
						||
| 
								 | 
							
								//  this is likely to be implemented differently to achieve the same effect.
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								//  Returns: A value that is to be used to restore the state of the CPU when
							 | 
						||
| 
								 | 
							
								//  exiting the critical section. This must be treated as opaque and passed
							 | 
						||
| 
								 | 
							
								//  unmodified to xos_critical_exit().
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								//  NOTE: This function is meant for use in OS code, not in applications.
							 | 
						||
| 
								 | 
							
								//-----------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								__attribute__((always_inline))
							 | 
						||
| 
								 | 
							
								static inline uint32_t
							 | 
						||
| 
								 | 
							
								xos_critical_enter(void)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								#if XCHAL_HAVE_INTERRUPTS
							 | 
						||
| 
								 | 
							
								    // This function cannot be called by high-level interrupt handlers,
							 | 
						||
| 
								 | 
							
								    // i.e. it can never be called with intlevel > XOS_MAX_OS_INTLEVEL.
							 | 
						||
| 
								 | 
							
								    // So, we do not need to check current intlevel because we will not
							 | 
						||
| 
								 | 
							
								    // ever be lowering it by setting it to XOS_MAX_OS_INTLEVEL.
							 | 
						||
| 
								 | 
							
								    // NOTE: sync after RSIL not needed.
							 | 
						||
| 
								 | 
							
								    return XT_RSIL(XOS_MAX_OS_INTLEVEL);
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								    return 0;
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//-----------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								//  Exit an OS critical section and restore CPU state. See the documentation
							 | 
						||
| 
								 | 
							
								//  for xos_critical_enter().
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								//  cflags              Return value from xos_critical_enter().
							 | 
						||
| 
								 | 
							
								//                      Must be treated as an opaque value.
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								//  Returns: Nothing.
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								//  NOTE: This function is meant for use in OS code, not in applications.
							 | 
						||
| 
								 | 
							
								//-----------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								__attribute__((always_inline))
							 | 
						||
| 
								 | 
							
								static inline void
							 | 
						||
| 
								 | 
							
								xos_critical_exit(uint32_t cflags)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    xos_restore_int_pri_level(cflags);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif // _XOS_INCLUDE_INTERNAL_
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// This file uses things defined above
							 | 
						||
| 
								 | 
							
								#include "xos_syslog.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Misc
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//-----------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								//  Helper function to list all threads in system. Useful for debug.
							 | 
						||
| 
								 | 
							
								//-----------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								void
							 | 
						||
| 
								 | 
							
								xos_display_threads(void * arg, XosPrintFunc * print_fn);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef __cplusplus
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif  // __XOS_H__
							 | 
						||
| 
								 | 
							
								
							 |