mirror of
				https://github.com/pvvx/rtl00TstMinAmebaV35a.git
				synced 2025-07-31 20:31:06 +00:00 
			
		
		
		
	first commit
This commit is contained in:
		
						commit
						c399bf5be0
					
				
					 806 changed files with 421674 additions and 0 deletions
				
			
		
							
								
								
									
										1394
									
								
								component/os/freertos/cmsis_os.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1394
									
								
								component/os/freertos/cmsis_os.c
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										816
									
								
								component/os/freertos/cmsis_os.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										816
									
								
								component/os/freertos/cmsis_os.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,816 @@
 | 
			
		|||
/* ----------------------------------------------------------------------
 | 
			
		||||
 * $Date:        5. February 2013
 | 
			
		||||
 * $Revision:    V1.02
 | 
			
		||||
 *
 | 
			
		||||
 * Project:      CMSIS-RTOS API
 | 
			
		||||
 * Title:        cmsis_os.h template header file
 | 
			
		||||
 *
 | 
			
		||||
 * Version 0.02
 | 
			
		||||
 *    Initial Proposal Phase
 | 
			
		||||
 * Version 0.03
 | 
			
		||||
 *    osKernelStart added, optional feature: main started as thread
 | 
			
		||||
 *    osSemaphores have standard behavior
 | 
			
		||||
 *    osTimerCreate does not start the timer, added osTimerStart
 | 
			
		||||
 *    osThreadPass is renamed to osThreadYield
 | 
			
		||||
  * Version 1.01
 | 
			
		||||
 *    Support for C++ interface
 | 
			
		||||
 *     - const attribute removed from the osXxxxDef_t typedef's
 | 
			
		||||
 *     - const attribute added to the osXxxxDef macros
 | 
			
		||||
 *    Added: osTimerDelete, osMutexDelete, osSemaphoreDelete
 | 
			
		||||
 *    Added: osKernelInitialize
 | 
			
		||||
 * Version 1.02
 | 
			
		||||
 *    Control functions for short timeouts in microsecond resolution:
 | 
			
		||||
 *    Added: osKernelSysTick, osKernelSysTickFrequency, osKernelSysTickMicroSec
 | 
			
		||||
 *    Removed: osSignalGet 
 | 
			
		||||
 *----------------------------------------------------------------------------
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2013 ARM LIMITED
 | 
			
		||||
 * All rights reserved.
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 *  - Redistributions of source code must retain the above copyright
 | 
			
		||||
 *    notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 *  - 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.
 | 
			
		||||
 *  - Neither the name of ARM  nor the names of its contributors may be used
 | 
			
		||||
 *    to endorse or promote products derived from this software without
 | 
			
		||||
 *    specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDERS AND CONTRIBUTORS 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.
 | 
			
		||||
 *---------------------------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
#include "FreeRTOS.h"
 | 
			
		||||
#include "task.h"
 | 
			
		||||
#include "timers.h"
 | 
			
		||||
#include "queue.h"
 | 
			
		||||
#include "semphr.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define FREERTOS_VERSION        0x00080001  // bits[31:16] main version, bits[15:0] sub-version
 | 
			
		||||
 | 
			
		||||
#if FREERTOS_VERSION >= 0x00080000
 | 
			
		||||
#define configSignalManagementSupport       1
 | 
			
		||||
#else
 | 
			
		||||
#define configSignalManagementSupport       0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if configSignalManagementSupport
 | 
			
		||||
#include "event_groups.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
\page cmsis_os_h Header File Template: cmsis_os.h
 | 
			
		||||
 | 
			
		||||
The file \b cmsis_os.h is a template header file for a CMSIS-RTOS compliant Real-Time Operating System (RTOS).
 | 
			
		||||
Each RTOS that is compliant with CMSIS-RTOS shall provide a specific \b cmsis_os.h header file that represents
 | 
			
		||||
its implementation.
 | 
			
		||||
 | 
			
		||||
The file cmsis_os.h contains:
 | 
			
		||||
 - CMSIS-RTOS API function definitions
 | 
			
		||||
 - struct definitions for parameters and return types
 | 
			
		||||
 - status and priority values used by CMSIS-RTOS API functions
 | 
			
		||||
 - macros for defining threads and other kernel objects
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<b>Name conventions and header file modifications</b>
 | 
			
		||||
 | 
			
		||||
All definitions are prefixed with \b os to give an unique name space for CMSIS-RTOS functions.
 | 
			
		||||
Definitions that are prefixed \b os_ are not used in the application code but local to this header file.
 | 
			
		||||
All definitions and functions that belong to a module are grouped and have a common prefix, i.e. \b osThread.
 | 
			
		||||
 | 
			
		||||
Definitions that are marked with <b>CAN BE CHANGED</b> can be adapted towards the needs of the actual CMSIS-RTOS implementation.
 | 
			
		||||
These definitions can be specific to the underlying RTOS kernel.
 | 
			
		||||
 | 
			
		||||
Definitions that are marked with <b>MUST REMAIN UNCHANGED</b> cannot be altered. Otherwise the CMSIS-RTOS implementation is no longer
 | 
			
		||||
compliant to the standard. Note that some functions are optional and need not to be provided by every CMSIS-RTOS implementation.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<b>Function calls from interrupt service routines</b>
 | 
			
		||||
 | 
			
		||||
The following CMSIS-RTOS functions can be called from threads and interrupt service routines (ISR):
 | 
			
		||||
  - \ref osSignalSet
 | 
			
		||||
  - \ref osSemaphoreRelease
 | 
			
		||||
  - \ref osPoolAlloc, \ref osPoolCAlloc, \ref osPoolFree
 | 
			
		||||
  - \ref osMessagePut, \ref osMessageGet
 | 
			
		||||
  - \ref osMailAlloc, \ref osMailCAlloc, \ref osMailGet, \ref osMailPut, \ref osMailFree
 | 
			
		||||
 | 
			
		||||
Functions that cannot be called from an ISR are verifying the interrupt status and return in case that they are called
 | 
			
		||||
from an ISR context the status code \b osErrorISR. In some implementations this condition might be caught using the HARD FAULT vector.
 | 
			
		||||
 | 
			
		||||
Some CMSIS-RTOS implementations support CMSIS-RTOS function calls from multiple ISR at the same time.
 | 
			
		||||
If this is impossible, the CMSIS-RTOS rejects calls by nested ISR functions with the status code \b osErrorISRRecursive.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<b>Define and reference object definitions</b>
 | 
			
		||||
 | 
			
		||||
With <b>\#define osObjectsExternal</b> objects are defined as external symbols. This allows to create a consistent header file
 | 
			
		||||
that is used throughout a project as shown below:
 | 
			
		||||
 | 
			
		||||
<i>Header File</i>
 | 
			
		||||
\code
 | 
			
		||||
#include <cmsis_os.h>                                         // CMSIS RTOS header file
 | 
			
		||||
 | 
			
		||||
// Thread definition
 | 
			
		||||
extern void thread_sample (void const *argument);             // function prototype
 | 
			
		||||
osThreadDef (thread_sample, osPriorityBelowNormal, 1, 100);
 | 
			
		||||
 | 
			
		||||
// Pool definition
 | 
			
		||||
osPoolDef(MyPool, 10, long);
 | 
			
		||||
\endcode
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
This header file defines all objects when included in a C/C++ source file. When <b>\#define osObjectsExternal</b> is
 | 
			
		||||
present before the header file, the objects are defined as external symbols. A single consistent header file can therefore be
 | 
			
		||||
used throughout the whole project.
 | 
			
		||||
 | 
			
		||||
<i>Example</i>
 | 
			
		||||
\code
 | 
			
		||||
#include "osObjects.h"     // Definition of the CMSIS-RTOS objects
 | 
			
		||||
\endcode
 | 
			
		||||
 | 
			
		||||
\code
 | 
			
		||||
#define osObjectExternal   // Objects will be defined as external symbols
 | 
			
		||||
#include "osObjects.h"     // Reference to the CMSIS-RTOS objects
 | 
			
		||||
\endcode
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef _CMSIS_OS_H
 | 
			
		||||
#define _CMSIS_OS_H
 | 
			
		||||
 | 
			
		||||
/// \note MUST REMAIN UNCHANGED: \b osCMSIS identifies the CMSIS-RTOS API version.
 | 
			
		||||
#define osCMSIS           0x10002      ///< API version (main [31:16] .sub [15:0])
 | 
			
		||||
 | 
			
		||||
/// \note CAN BE CHANGED: \b osCMSIS_KERNEL identifies the underlying RTOS kernel and version number.
 | 
			
		||||
#define osCMSIS_KERNEL    0x10000	   ///< RTOS identification and version (main [31:16] .sub [15:0])
 | 
			
		||||
 | 
			
		||||
/// \note MUST REMAIN UNCHANGED: \b osKernelSystemId shall be consistent in every CMSIS-RTOS.
 | 
			
		||||
#define osKernelSystemId "KERNEL V1.00"   ///< RTOS identification string
 | 
			
		||||
 | 
			
		||||
/// \note MUST REMAIN UNCHANGED: \b osFeature_xxx shall be consistent in every CMSIS-RTOS.
 | 
			
		||||
#define osFeature_MainThread   1       ///< main thread      1=main can be thread, 0=not available
 | 
			
		||||
#define osFeature_Pool         1       ///< Memory Pools:    1=available, 0=not available
 | 
			
		||||
#define osFeature_MailQ        1       ///< Mail Queues:     1=available, 0=not available
 | 
			
		||||
#define osFeature_MessageQ     1       ///< Message Queues:  1=available, 0=not available
 | 
			
		||||
#define osFeature_Signals      8       ///< maximum number of Signal Flags available per thread
 | 
			
		||||
#define osFeature_Semaphore    30      ///< maximum count for \ref osSemaphoreCreate function
 | 
			
		||||
#define osFeature_Wait         1       ///< osWait function: 1=available, 0=not available
 | 
			
		||||
#define osFeature_SysTick      1       ///< osKernelSysTick functions: 1=available, 0=not available
 | 
			
		||||
 | 
			
		||||
//#include <stdint.h>
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
 | 
			
		||||
#ifdef  __cplusplus
 | 
			
		||||
extern "C"
 | 
			
		||||
{
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// ==== Enumeration, structures, defines ====
 | 
			
		||||
 | 
			
		||||
/// Priority used for thread control.
 | 
			
		||||
/// \note MUST REMAIN UNCHANGED: \b osPriority shall be consistent in every CMSIS-RTOS.
 | 
			
		||||
typedef enum  {
 | 
			
		||||
  osPriorityIdle          = -3,          ///< priority: idle (lowest)
 | 
			
		||||
  osPriorityLow           = -2,          ///< priority: low
 | 
			
		||||
  osPriorityBelowNormal   = -1,          ///< priority: below normal
 | 
			
		||||
  osPriorityNormal        =  0,          ///< priority: normal (default)
 | 
			
		||||
  osPriorityAboveNormal   = +1,          ///< priority: above normal
 | 
			
		||||
  osPriorityHigh          = +2,          ///< priority: high
 | 
			
		||||
  osPriorityRealtime      = +3,          ///< priority: realtime (highest)
 | 
			
		||||
  osPriorityError         =  0x84        ///< system cannot determine priority or thread has illegal priority
 | 
			
		||||
} osPriority;
 | 
			
		||||
 | 
			
		||||
/// Timeout value.
 | 
			
		||||
/// \note MUST REMAIN UNCHANGED: \b osWaitForever shall be consistent in every CMSIS-RTOS.
 | 
			
		||||
#define osWaitForever     0xFFFFFFFF     ///< wait forever timeout value
 | 
			
		||||
 | 
			
		||||
/// Status code values returned by CMSIS-RTOS functions.
 | 
			
		||||
/// \note MUST REMAIN UNCHANGED: \b osStatus shall be consistent in every CMSIS-RTOS.
 | 
			
		||||
typedef enum {
 | 
			
		||||
  osOK                    =     0,       ///< function completed; no error or event occurred.
 | 
			
		||||
  osEventSignal           =  0x08,       ///< function completed; signal event occurred.
 | 
			
		||||
  osEventMessage          =  0x10,       ///< function completed; message event occurred.
 | 
			
		||||
  osEventMail             =  0x20,       ///< function completed; mail event occurred.
 | 
			
		||||
  osEventTimeout          =  0x40,       ///< function completed; timeout occurred.
 | 
			
		||||
  osErrorParameter        =  0x80,       ///< parameter error: a mandatory parameter was missing or specified an incorrect object.
 | 
			
		||||
  osErrorResource         =  0x81,       ///< resource not available: a specified resource was not available.
 | 
			
		||||
  osErrorTimeoutResource  =  0xC1,       ///< resource not available within given time: a specified resource was not available within the timeout period.
 | 
			
		||||
  osErrorISR              =  0x82,       ///< not allowed in ISR context: the function cannot be called from interrupt service routines.
 | 
			
		||||
  osErrorISRRecursive     =  0x83,       ///< function called multiple times from ISR with same object.
 | 
			
		||||
  osErrorPriority         =  0x84,       ///< system cannot determine priority or thread has illegal priority.
 | 
			
		||||
  osErrorNoMemory         =  0x85,       ///< system is out of memory: it was impossible to allocate or reserve memory for the operation.
 | 
			
		||||
  osErrorValue            =  0x86,       ///< value of a parameter is out of range.
 | 
			
		||||
  osErrorOS               =  0xFF,       ///< unspecified RTOS error: run-time error but no other error message fits.
 | 
			
		||||
  os_status_reserved      =  0x7FFFFFFF  ///< prevent from enum down-size compiler optimization.
 | 
			
		||||
} osStatus;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/// Timer type value for the timer definition.
 | 
			
		||||
/// \note MUST REMAIN UNCHANGED: \b os_timer_type shall be consistent in every CMSIS-RTOS.
 | 
			
		||||
typedef enum   {
 | 
			
		||||
  osTimerOnce             =     0,       ///< one-shot timer
 | 
			
		||||
  osTimerPeriodic         =     1        ///< repeating timer
 | 
			
		||||
} os_timer_type;
 | 
			
		||||
 | 
			
		||||
/// Entry point of a thread.
 | 
			
		||||
/// \note MUST REMAIN UNCHANGED: \b os_pthread shall be consistent in every CMSIS-RTOS.
 | 
			
		||||
typedef void (*os_pthread) (void const *argument);
 | 
			
		||||
 | 
			
		||||
/// Entry point of a timer call back function.
 | 
			
		||||
/// \note MUST REMAIN UNCHANGED: \b os_ptimer shall be consistent in every CMSIS-RTOS.
 | 
			
		||||
typedef void (*os_ptimer) (void const *argument);
 | 
			
		||||
 | 
			
		||||
// >>> the following data type definitions may shall adapted towards a specific RTOS
 | 
			
		||||
 | 
			
		||||
/// Thread ID identifies the thread (pointer to a thread control block).
 | 
			
		||||
/// \note CAN BE CHANGED: \b os_thread_cb is implementation specific in every CMSIS-RTOS.
 | 
			
		||||
typedef xTaskHandle osThreadId;
 | 
			
		||||
 | 
			
		||||
/// Timer ID identifies the timer (pointer to a timer control block).
 | 
			
		||||
/// \note CAN BE CHANGED: \b os_timer_cb is implementation specific in every CMSIS-RTOS.
 | 
			
		||||
typedef xTimerHandle osTimerId;
 | 
			
		||||
 | 
			
		||||
/// Mutex ID identifies the mutex (pointer to a mutex control block).
 | 
			
		||||
/// \note CAN BE CHANGED: \b os_mutex_cb is implementation specific in every CMSIS-RTOS.
 | 
			
		||||
typedef xSemaphoreHandle osMutexId;
 | 
			
		||||
 | 
			
		||||
/// Semaphore ID identifies the semaphore (pointer to a semaphore control block).
 | 
			
		||||
/// \note CAN BE CHANGED: \b os_semaphore_cb is implementation specific in every CMSIS-RTOS.
 | 
			
		||||
typedef xSemaphoreHandle osSemaphoreId;
 | 
			
		||||
 | 
			
		||||
/// Pool ID identifies the memory pool (pointer to a memory pool control block).
 | 
			
		||||
/// \note CAN BE CHANGED: \b os_pool_cb is implementation specific in every CMSIS-RTOS.
 | 
			
		||||
typedef struct os_pool_cb *osPoolId;
 | 
			
		||||
 | 
			
		||||
/// Message ID identifies the message queue (pointer to a message queue control block).
 | 
			
		||||
/// \note CAN BE CHANGED: \b os_messageQ_cb is implementation specific in every CMSIS-RTOS.
 | 
			
		||||
typedef xQueueHandle osMessageQId;
 | 
			
		||||
 | 
			
		||||
/// Mail ID identifies the mail queue (pointer to a mail queue control block).
 | 
			
		||||
/// \note CAN BE CHANGED: \b os_mailQ_cb is implementation specific in every CMSIS-RTOS.
 | 
			
		||||
typedef struct os_mailQ_cb *osMailQId;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/// Thread Definition structure contains startup information of a thread.
 | 
			
		||||
/// \note CAN BE CHANGED: \b os_thread_def is implementation specific in every CMSIS-RTOS.
 | 
			
		||||
typedef struct os_thread_def  {
 | 
			
		||||
  os_pthread             pthread;    ///< start address of thread function
 | 
			
		||||
  osPriority             tpriority;    ///< initial thread priority
 | 
			
		||||
  uint32_t               instances;    ///< maximum number of instances of that thread function
 | 
			
		||||
  uint32_t               stacksize;    ///< stack size requirements in bytes; 0 is default stack size
 | 
			
		||||
  char *                 name;
 | 
			
		||||
} osThreadDef_t;
 | 
			
		||||
 | 
			
		||||
/// Timer Definition structure contains timer parameters.
 | 
			
		||||
/// \note CAN BE CHANGED: \b os_timer_def is implementation specific in every CMSIS-RTOS.
 | 
			
		||||
struct os_timer_custom {
 | 
			
		||||
    void *argument;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct os_timer_def  {
 | 
			
		||||
  os_ptimer                 ptimer;    ///< start address of a timer function
 | 
			
		||||
  struct os_timer_custom    *custom;
 | 
			
		||||
} osTimerDef_t;
 | 
			
		||||
 | 
			
		||||
/// Mutex Definition structure contains setup information for a mutex.
 | 
			
		||||
/// \note CAN BE CHANGED: \b os_mutex_def is implementation specific in every CMSIS-RTOS.
 | 
			
		||||
typedef struct os_mutex_def  {
 | 
			
		||||
  uint32_t                   dummy;    ///< dummy value.
 | 
			
		||||
} osMutexDef_t;
 | 
			
		||||
 | 
			
		||||
/// Semaphore Definition structure contains setup information for a semaphore.
 | 
			
		||||
/// \note CAN BE CHANGED: \b os_semaphore_def is implementation specific in every CMSIS-RTOS.
 | 
			
		||||
typedef struct os_semaphore_def  {
 | 
			
		||||
  uint32_t                   dummy;    ///< dummy value.
 | 
			
		||||
} osSemaphoreDef_t;
 | 
			
		||||
 | 
			
		||||
/// Definition structure for memory block allocation
 | 
			
		||||
/// \note CAN BE CHANGED: \b os_pool_def is implementation specific in every CMSIS-RTOS.
 | 
			
		||||
typedef struct os_pool_def  {
 | 
			
		||||
  uint32_t                 pool_sz;    ///< number of items (elements) in the pool
 | 
			
		||||
  uint32_t                 item_sz;    ///< size of an item
 | 
			
		||||
  void                     *pool;    ///< pointer to memory for pool
 | 
			
		||||
} osPoolDef_t;
 | 
			
		||||
 | 
			
		||||
/// Definition structure for message queue.
 | 
			
		||||
/// \note CAN BE CHANGED: \b os_messageQ_def is implementation specific in every CMSIS-RTOS.
 | 
			
		||||
typedef struct os_messageQ_def  {
 | 
			
		||||
  uint32_t                queue_sz;    ///< number of elements in the queue
 | 
			
		||||
  uint32_t                 item_sz;    ///< size of an item
 | 
			
		||||
  void                       *pool;    ///< memory array for messages
 | 
			
		||||
} osMessageQDef_t;
 | 
			
		||||
 | 
			
		||||
/// Definition structure for mail queue
 | 
			
		||||
/// \note CAN BE CHANGED: \b os_mailQ_def is implementation specific in every CMSIS-RTOS.
 | 
			
		||||
typedef struct os_mailQ_def  {
 | 
			
		||||
  uint32_t                queue_sz;    ///< number of elements in the queue
 | 
			
		||||
  uint32_t                 item_sz;    ///< size of an item
 | 
			
		||||
  struct os_mailQ_cb **cb;
 | 
			
		||||
} osMailQDef_t;
 | 
			
		||||
 | 
			
		||||
/// Event structure contains detailed information about an event.
 | 
			
		||||
/// \note MUST REMAIN UNCHANGED: \b os_event shall be consistent in every CMSIS-RTOS.
 | 
			
		||||
///       However the struct may be extended at the end.
 | 
			
		||||
typedef struct  {
 | 
			
		||||
  osStatus                 status;     ///< status code: event or error information
 | 
			
		||||
  union  {
 | 
			
		||||
    uint32_t                    v;     ///< message as 32-bit value
 | 
			
		||||
    void                       *p;     ///< message or mail as void pointer
 | 
			
		||||
    int32_t               signals;     ///< signal flags
 | 
			
		||||
  } value;                             ///< event value
 | 
			
		||||
  union  {
 | 
			
		||||
    osMailQId             mail_id;     ///< mail id obtained by \ref osMailCreate
 | 
			
		||||
    osMessageQId       message_id;     ///< message id obtained by \ref osMessageCreate
 | 
			
		||||
  } def;                               ///< event definition
 | 
			
		||||
} osEvent;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//  ==== Kernel Control Functions ====
 | 
			
		||||
 | 
			
		||||
/// Initialize the RTOS Kernel for creating objects.
 | 
			
		||||
/// \return status code that indicates the execution status of the function.
 | 
			
		||||
/// \note MUST REMAIN UNCHANGED: \b osKernelInitialize shall be consistent in every CMSIS-RTOS.
 | 
			
		||||
osStatus osKernelInitialize (void);
 | 
			
		||||
 | 
			
		||||
/// Start the RTOS Kernel.
 | 
			
		||||
/// \return status code that indicates the execution status of the function.
 | 
			
		||||
/// \note MUST REMAIN UNCHANGED: \b osKernelStart shall be consistent in every CMSIS-RTOS.
 | 
			
		||||
osStatus osKernelStart (void);
 | 
			
		||||
 | 
			
		||||
/// Check if the RTOS kernel is already started.
 | 
			
		||||
/// \note MUST REMAIN UNCHANGED: \b osKernelRunning shall be consistent in every CMSIS-RTOS.
 | 
			
		||||
/// \return 0 RTOS is not started, 1 RTOS is started.
 | 
			
		||||
int32_t osKernelRunning(void);
 | 
			
		||||
 | 
			
		||||
#if (defined (osFeature_SysTick)  &&  (osFeature_SysTick != 0))     // System Timer available
 | 
			
		||||
 | 
			
		||||
/// Get the RTOS kernel system timer counter 
 | 
			
		||||
/// \note MUST REMAIN UNCHANGED: \b osKernelSysTick shall be consistent in every CMSIS-RTOS.
 | 
			
		||||
/// \return RTOS kernel system timer as 32-bit value 
 | 
			
		||||
uint32_t osKernelSysTick (void);
 | 
			
		||||
 | 
			
		||||
/// The RTOS kernel system timer frequency in Hz
 | 
			
		||||
/// \note Reflects the system timer setting and is typically defined in a configuration file.
 | 
			
		||||
#define osKernelSysTickFrequency configTICK_RATE_HZ
 | 
			
		||||
 | 
			
		||||
/// Convert a microseconds value to a RTOS kernel system timer value.
 | 
			
		||||
/// \param         microsec     time value in microseconds.
 | 
			
		||||
/// \return time value normalized to the \ref osKernelSysTickFrequency
 | 
			
		||||
#define osKernelSysTickMicroSec(microsec) (((uint64_t)microsec * (osKernelSysTickFrequency)) / 1000000)
 | 
			
		||||
 | 
			
		||||
#endif    // System Timer available
 | 
			
		||||
 | 
			
		||||
//  ==== Thread Management ====
 | 
			
		||||
 | 
			
		||||
/// Create a Thread Definition with function, priority, and stack requirements.
 | 
			
		||||
/// \param         name         name of the thread function.
 | 
			
		||||
/// \param         priority     initial priority of the thread function.
 | 
			
		||||
/// \param         instances    number of possible thread instances.
 | 
			
		||||
/// \param         stacksz      stack size (in bytes) requirements for the thread function.
 | 
			
		||||
/// \note CAN BE CHANGED: The parameters to \b osThreadDef shall be consistent but the
 | 
			
		||||
///       macro body is implementation specific in every CMSIS-RTOS.
 | 
			
		||||
#if defined (osObjectsExternal)  // object is external
 | 
			
		||||
#define osThreadDef(name, priority, instances, stacksz)  \
 | 
			
		||||
extern const osThreadDef_t os_thread_def_##name
 | 
			
		||||
#else                            // define the object
 | 
			
		||||
#define osThreadDef(name, priority, instances, stacksz)  \
 | 
			
		||||
const osThreadDef_t os_thread_def_##name = \
 | 
			
		||||
{ (name), (priority), (instances), (stacksz), #name  }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/// Access a Thread definition.
 | 
			
		||||
/// \param         name          name of the thread definition object.
 | 
			
		||||
/// \note CAN BE CHANGED: The parameter to \b osThread shall be consistent but the
 | 
			
		||||
///       macro body is implementation specific in every CMSIS-RTOS.
 | 
			
		||||
#define osThread(name)  \
 | 
			
		||||
&os_thread_def_##name
 | 
			
		||||
 | 
			
		||||
/// Create a thread and add it to Active Threads and set it to state READY.
 | 
			
		||||
/// \param[in]     thread_def    thread definition referenced with \ref osThread.
 | 
			
		||||
/// \param[in]     argument      pointer that is passed to the thread function as start argument.
 | 
			
		||||
/// \return thread ID for reference by other functions or NULL in case of error.
 | 
			
		||||
/// \note MUST REMAIN UNCHANGED: \b osThreadCreate shall be consistent in every CMSIS-RTOS.
 | 
			
		||||
osThreadId osThreadCreate (const osThreadDef_t *thread_def, void *argument);
 | 
			
		||||
 | 
			
		||||
/// Return the thread ID of the current running thread.
 | 
			
		||||
/// \return thread ID for reference by other functions or NULL in case of error.
 | 
			
		||||
/// \note MUST REMAIN UNCHANGED: \b osThreadGetId shall be consistent in every CMSIS-RTOS.
 | 
			
		||||
osThreadId osThreadGetId (void);
 | 
			
		||||
 | 
			
		||||
/// Terminate execution of a thread and remove it from Active Threads.
 | 
			
		||||
/// \param[in]     thread_id   thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
 | 
			
		||||
/// \return status code that indicates the execution status of the function.
 | 
			
		||||
/// \note MUST REMAIN UNCHANGED: \b osThreadTerminate shall be consistent in every CMSIS-RTOS.
 | 
			
		||||
osStatus osThreadTerminate (osThreadId thread_id);
 | 
			
		||||
 | 
			
		||||
/// Pass control to next thread that is in state \b READY.
 | 
			
		||||
/// \return status code that indicates the execution status of the function.
 | 
			
		||||
/// \note MUST REMAIN UNCHANGED: \b osThreadYield shall be consistent in every CMSIS-RTOS.
 | 
			
		||||
osStatus osThreadYield (void);
 | 
			
		||||
 | 
			
		||||
/// Change priority of an active thread.
 | 
			
		||||
/// \param[in]     thread_id     thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
 | 
			
		||||
/// \param[in]     priority      new priority value for the thread function.
 | 
			
		||||
/// \return status code that indicates the execution status of the function.
 | 
			
		||||
/// \note MUST REMAIN UNCHANGED: \b osThreadSetPriority shall be consistent in every CMSIS-RTOS.
 | 
			
		||||
osStatus osThreadSetPriority (osThreadId thread_id, osPriority priority);
 | 
			
		||||
 | 
			
		||||
/// Get current priority of an active thread.
 | 
			
		||||
/// \param[in]     thread_id     thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
 | 
			
		||||
/// \return current priority value of the thread function.
 | 
			
		||||
/// \note MUST REMAIN UNCHANGED: \b osThreadGetPriority shall be consistent in every CMSIS-RTOS.
 | 
			
		||||
osPriority osThreadGetPriority (osThreadId thread_id);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//  ==== Generic Wait Functions ====
 | 
			
		||||
 | 
			
		||||
/// Wait for Timeout (Time Delay).
 | 
			
		||||
/// \param[in]     millisec      time delay value
 | 
			
		||||
/// \return status code that indicates the execution status of the function.
 | 
			
		||||
osStatus osDelay (uint32_t millisec);
 | 
			
		||||
 | 
			
		||||
#if (defined (osFeature_Wait)  &&  (osFeature_Wait != 0))     // Generic Wait available
 | 
			
		||||
 | 
			
		||||
/// Wait for Signal, Message, Mail, or Timeout.
 | 
			
		||||
/// \param[in] millisec          timeout value or 0 in case of no time-out
 | 
			
		||||
/// \return event that contains signal, message, or mail information or error code.
 | 
			
		||||
/// \note MUST REMAIN UNCHANGED: \b osWait shall be consistent in every CMSIS-RTOS.
 | 
			
		||||
osEvent osWait (uint32_t millisec);
 | 
			
		||||
 | 
			
		||||
#endif  // Generic Wait available
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//  ==== Timer Management Functions ====
 | 
			
		||||
/// Define a Timer object.
 | 
			
		||||
/// \param         name          name of the timer object.
 | 
			
		||||
/// \param         function      name of the timer call back function.
 | 
			
		||||
/// \note CAN BE CHANGED: The parameter to \b osTimerDef shall be consistent but the
 | 
			
		||||
///       macro body is implementation specific in every CMSIS-RTOS.
 | 
			
		||||
#if defined (osObjectsExternal)  // object is external
 | 
			
		||||
#define osTimerDef(name, function)  \
 | 
			
		||||
extern const osTimerDef_t os_timer_def_##name; \
 | 
			
		||||
extern struct os_timer_custom os_timer_custome_##name
 | 
			
		||||
#else                            // define the object
 | 
			
		||||
#define osTimerDef(name, function)  \
 | 
			
		||||
struct os_timer_custom os_timer_custom_##name; \
 | 
			
		||||
const osTimerDef_t os_timer_def_##name = \
 | 
			
		||||
{ (function), (&os_timer_custom_##name) }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/// Access a Timer definition.
 | 
			
		||||
/// \param         name          name of the timer object.
 | 
			
		||||
/// \note CAN BE CHANGED: The parameter to \b osTimer shall be consistent but the
 | 
			
		||||
///       macro body is implementation specific in every CMSIS-RTOS.
 | 
			
		||||
#define osTimer(name) \
 | 
			
		||||
&os_timer_def_##name
 | 
			
		||||
 | 
			
		||||
/// Create a timer.
 | 
			
		||||
/// \param[in]     timer_def     timer object referenced with \ref osTimer.
 | 
			
		||||
/// \param[in]     type          osTimerOnce for one-shot or osTimerPeriodic for periodic behavior.
 | 
			
		||||
/// \param[in]     argument      argument to the timer call back function.
 | 
			
		||||
/// \return timer ID for reference by other functions or NULL in case of error.
 | 
			
		||||
/// \note MUST REMAIN UNCHANGED: \b osTimerCreate shall be consistent in every CMSIS-RTOS.
 | 
			
		||||
osTimerId osTimerCreate (const osTimerDef_t *timer_def, os_timer_type type, void *argument);
 | 
			
		||||
 | 
			
		||||
/// Start or restart a timer.
 | 
			
		||||
/// \param[in]     timer_id      timer ID obtained by \ref osTimerCreate.
 | 
			
		||||
/// \param[in]     millisec      time delay value of the timer.
 | 
			
		||||
/// \return status code that indicates the execution status of the function.
 | 
			
		||||
/// \note MUST REMAIN UNCHANGED: \b osTimerStart shall be consistent in every CMSIS-RTOS.
 | 
			
		||||
osStatus osTimerStart (osTimerId timer_id, uint32_t millisec);
 | 
			
		||||
 | 
			
		||||
/// Stop the timer.
 | 
			
		||||
/// \param[in]     timer_id      timer ID obtained by \ref osTimerCreate.
 | 
			
		||||
/// \return status code that indicates the execution status of the function.
 | 
			
		||||
/// \note MUST REMAIN UNCHANGED: \b osTimerStop shall be consistent in every CMSIS-RTOS.
 | 
			
		||||
osStatus osTimerStop (osTimerId timer_id);
 | 
			
		||||
 | 
			
		||||
/// Delete a timer that was created by \ref osTimerCreate.
 | 
			
		||||
/// \param[in]     timer_id      timer ID obtained by \ref osTimerCreate.
 | 
			
		||||
/// \return status code that indicates the execution status of the function.
 | 
			
		||||
/// \note MUST REMAIN UNCHANGED: \b osTimerDelete shall be consistent in every CMSIS-RTOS.
 | 
			
		||||
osStatus osTimerDelete (osTimerId timer_id);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//  ==== Signal Management ====
 | 
			
		||||
 | 
			
		||||
/// Set the specified Signal Flags of an active thread.
 | 
			
		||||
/// \param[in]     thread_id     thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
 | 
			
		||||
/// \param[in]     signals       specifies the signal flags of the thread that should be set.
 | 
			
		||||
/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters.
 | 
			
		||||
/// \note MUST REMAIN UNCHANGED: \b osSignalSet shall be consistent in every CMSIS-RTOS.
 | 
			
		||||
int32_t osSignalSet (osThreadId thread_id, int32_t signals);
 | 
			
		||||
 | 
			
		||||
/// Clear the specified Signal Flags of an active thread.
 | 
			
		||||
/// \param[in]     thread_id     thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
 | 
			
		||||
/// \param[in]     signals       specifies the signal flags of the thread that shall be cleared.
 | 
			
		||||
/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters.
 | 
			
		||||
/// \note MUST REMAIN UNCHANGED: \b osSignalClear shall be consistent in every CMSIS-RTOS.
 | 
			
		||||
int32_t osSignalClear (osThreadId thread_id, int32_t signals);
 | 
			
		||||
 | 
			
		||||
/// Wait for one or more Signal Flags to become signaled for the current \b RUNNING thread.
 | 
			
		||||
/// \param[in]     signals       wait until all specified signal flags set or 0 for any single signal flag.
 | 
			
		||||
/// \param[in]     millisec      timeout value or 0 in case of no time-out.
 | 
			
		||||
/// \return event flag information or error code.
 | 
			
		||||
/// \note MUST REMAIN UNCHANGED: \b osSignalWait shall be consistent in every CMSIS-RTOS.
 | 
			
		||||
osEvent osSignalWait (int32_t signals, uint32_t millisec);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//  ==== Mutex Management ====
 | 
			
		||||
 | 
			
		||||
/// Define a Mutex.
 | 
			
		||||
/// \param         name          name of the mutex object.
 | 
			
		||||
/// \note CAN BE CHANGED: The parameter to \b osMutexDef shall be consistent but the
 | 
			
		||||
///       macro body is implementation specific in every CMSIS-RTOS.
 | 
			
		||||
#if defined (osObjectsExternal)  // object is external
 | 
			
		||||
#define osMutexDef(name)  \
 | 
			
		||||
extern const osMutexDef_t os_mutex_def_##name
 | 
			
		||||
#else                            // define the object
 | 
			
		||||
#define osMutexDef(name)  \
 | 
			
		||||
const osMutexDef_t os_mutex_def_##name = { 0 }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/// Access a Mutex definition.
 | 
			
		||||
/// \param         name          name of the mutex object.
 | 
			
		||||
/// \note CAN BE CHANGED: The parameter to \b osMutex shall be consistent but the
 | 
			
		||||
///       macro body is implementation specific in every CMSIS-RTOS.
 | 
			
		||||
#define osMutex(name)  \
 | 
			
		||||
&os_mutex_def_##name
 | 
			
		||||
 | 
			
		||||
/// Create and Initialize a Mutex object.
 | 
			
		||||
/// \param[in]     mutex_def     mutex definition referenced with \ref osMutex.
 | 
			
		||||
/// \return mutex ID for reference by other functions or NULL in case of error.
 | 
			
		||||
/// \note MUST REMAIN UNCHANGED: \b osMutexCreate shall be consistent in every CMSIS-RTOS.
 | 
			
		||||
osMutexId osMutexCreate (const osMutexDef_t *mutex_def);
 | 
			
		||||
 | 
			
		||||
/// Wait until a Mutex becomes available.
 | 
			
		||||
/// \param[in]     mutex_id      mutex ID obtained by \ref osMutexCreate.
 | 
			
		||||
/// \param[in]     millisec      timeout value or 0 in case of no time-out.
 | 
			
		||||
/// \return status code that indicates the execution status of the function.
 | 
			
		||||
/// \note MUST REMAIN UNCHANGED: \b osMutexWait shall be consistent in every CMSIS-RTOS.
 | 
			
		||||
osStatus osMutexWait (osMutexId mutex_id, uint32_t millisec);
 | 
			
		||||
 | 
			
		||||
/// Release a Mutex that was obtained by \ref osMutexWait.
 | 
			
		||||
/// \param[in]     mutex_id      mutex ID obtained by \ref osMutexCreate.
 | 
			
		||||
/// \return status code that indicates the execution status of the function.
 | 
			
		||||
/// \note MUST REMAIN UNCHANGED: \b osMutexRelease shall be consistent in every CMSIS-RTOS.
 | 
			
		||||
osStatus osMutexRelease (osMutexId mutex_id);
 | 
			
		||||
 | 
			
		||||
/// Delete a Mutex that was created by \ref osMutexCreate.
 | 
			
		||||
/// \param[in]     mutex_id      mutex ID obtained by \ref osMutexCreate.
 | 
			
		||||
/// \return status code that indicates the execution status of the function.
 | 
			
		||||
/// \note MUST REMAIN UNCHANGED: \b osMutexDelete shall be consistent in every CMSIS-RTOS.
 | 
			
		||||
osStatus osMutexDelete (osMutexId mutex_id);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//  ==== Semaphore Management Functions ====
 | 
			
		||||
 | 
			
		||||
#if (defined (osFeature_Semaphore)  &&  (osFeature_Semaphore != 0))     // Semaphore available
 | 
			
		||||
 | 
			
		||||
/// Define a Semaphore object.
 | 
			
		||||
/// \param         name          name of the semaphore object.
 | 
			
		||||
/// \note CAN BE CHANGED: The parameter to \b osSemaphoreDef shall be consistent but the
 | 
			
		||||
///       macro body is implementation specific in every CMSIS-RTOS.
 | 
			
		||||
#if defined (osObjectsExternal)  // object is external
 | 
			
		||||
#define osSemaphoreDef(name)  \
 | 
			
		||||
extern const osSemaphoreDef_t os_semaphore_def_##name
 | 
			
		||||
#else                            // define the object
 | 
			
		||||
#define osSemaphoreDef(name)  \
 | 
			
		||||
const osSemaphoreDef_t os_semaphore_def_##name = { 0 }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/// Access a Semaphore definition.
 | 
			
		||||
/// \param         name          name of the semaphore object.
 | 
			
		||||
/// \note CAN BE CHANGED: The parameter to \b osSemaphore shall be consistent but the
 | 
			
		||||
///       macro body is implementation specific in every CMSIS-RTOS.
 | 
			
		||||
#define osSemaphore(name)  \
 | 
			
		||||
&os_semaphore_def_##name
 | 
			
		||||
 | 
			
		||||
/// Create and Initialize a Semaphore object used for managing resources.
 | 
			
		||||
/// \param[in]     semaphore_def semaphore definition referenced with \ref osSemaphore.
 | 
			
		||||
/// \param[in]     count         number of available resources.
 | 
			
		||||
/// \return semaphore ID for reference by other functions or NULL in case of error.
 | 
			
		||||
/// \note MUST REMAIN UNCHANGED: \b osSemaphoreCreate shall be consistent in every CMSIS-RTOS.
 | 
			
		||||
osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t count);
 | 
			
		||||
 | 
			
		||||
/// Wait until a Semaphore token becomes available.
 | 
			
		||||
/// \param[in]     semaphore_id  semaphore object referenced with \ref osSemaphoreCreate.
 | 
			
		||||
/// \param[in]     millisec      timeout value or 0 in case of no time-out.
 | 
			
		||||
/// \return number of available tokens, or -1 in case of incorrect parameters.
 | 
			
		||||
/// \note MUST REMAIN UNCHANGED: \b osSemaphoreWait shall be consistent in every CMSIS-RTOS.
 | 
			
		||||
int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec);
 | 
			
		||||
 | 
			
		||||
/// Release a Semaphore token.
 | 
			
		||||
/// \param[in]     semaphore_id  semaphore object referenced with \ref osSemaphoreCreate.
 | 
			
		||||
/// \return status code that indicates the execution status of the function.
 | 
			
		||||
/// \note MUST REMAIN UNCHANGED: \b osSemaphoreRelease shall be consistent in every CMSIS-RTOS.
 | 
			
		||||
osStatus osSemaphoreRelease (osSemaphoreId semaphore_id);
 | 
			
		||||
 | 
			
		||||
/// Delete a Semaphore that was created by \ref osSemaphoreCreate.
 | 
			
		||||
/// \param[in]     semaphore_id  semaphore object referenced with \ref osSemaphoreCreate.
 | 
			
		||||
/// \return status code that indicates the execution status of the function.
 | 
			
		||||
/// \note MUST REMAIN UNCHANGED: \b osSemaphoreDelete shall be consistent in every CMSIS-RTOS.
 | 
			
		||||
osStatus osSemaphoreDelete (osSemaphoreId semaphore_id);
 | 
			
		||||
 | 
			
		||||
#endif     // Semaphore available
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//  ==== Memory Pool Management Functions ====
 | 
			
		||||
 | 
			
		||||
#if (defined (osFeature_Pool)  &&  (osFeature_Pool != 0))  // Memory Pool Management available
 | 
			
		||||
 | 
			
		||||
/// \brief Define a Memory Pool.
 | 
			
		||||
/// \param         name          name of the memory pool.
 | 
			
		||||
/// \param         no            maximum number of blocks (objects) in the memory pool.
 | 
			
		||||
/// \param         type          data type of a single block (object).
 | 
			
		||||
/// \note CAN BE CHANGED: The parameter to \b osPoolDef shall be consistent but the
 | 
			
		||||
///       macro body is implementation specific in every CMSIS-RTOS.
 | 
			
		||||
#if defined (osObjectsExternal)  // object is external
 | 
			
		||||
#define osPoolDef(name, no, type)   \
 | 
			
		||||
extern const osPoolDef_t os_pool_def_##name
 | 
			
		||||
#else                            // define the object
 | 
			
		||||
#define osPoolDef(name, no, type)   \
 | 
			
		||||
const osPoolDef_t os_pool_def_##name = \
 | 
			
		||||
{ (no), sizeof(type), NULL }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/// \brief Access a Memory Pool definition.
 | 
			
		||||
/// \param         name          name of the memory pool
 | 
			
		||||
/// \note CAN BE CHANGED: The parameter to \b osPool shall be consistent but the
 | 
			
		||||
///       macro body is implementation specific in every CMSIS-RTOS.
 | 
			
		||||
#define osPool(name) \
 | 
			
		||||
&os_pool_def_##name
 | 
			
		||||
 | 
			
		||||
/// Create and Initialize a memory pool.
 | 
			
		||||
/// \param[in]     pool_def      memory pool definition referenced with \ref osPool.
 | 
			
		||||
/// \return memory pool ID for reference by other functions or NULL in case of error.
 | 
			
		||||
/// \note MUST REMAIN UNCHANGED: \b osPoolCreate shall be consistent in every CMSIS-RTOS.
 | 
			
		||||
osPoolId osPoolCreate (const osPoolDef_t *pool_def);
 | 
			
		||||
 | 
			
		||||
/// Allocate a memory block from a memory pool.
 | 
			
		||||
/// \param[in]     pool_id       memory pool ID obtain referenced with \ref osPoolCreate.
 | 
			
		||||
/// \return address of the allocated memory block or NULL in case of no memory available.
 | 
			
		||||
/// \note MUST REMAIN UNCHANGED: \b osPoolAlloc shall be consistent in every CMSIS-RTOS.
 | 
			
		||||
void *osPoolAlloc (osPoolId pool_id);
 | 
			
		||||
 | 
			
		||||
/// Allocate a memory block from a memory pool and set memory block to zero.
 | 
			
		||||
/// \param[in]     pool_id       memory pool ID obtain referenced with \ref osPoolCreate.
 | 
			
		||||
/// \return address of the allocated memory block or NULL in case of no memory available.
 | 
			
		||||
/// \note MUST REMAIN UNCHANGED: \b osPoolCAlloc shall be consistent in every CMSIS-RTOS.
 | 
			
		||||
void *osPoolCAlloc (osPoolId pool_id);
 | 
			
		||||
 | 
			
		||||
/// Return an allocated memory block back to a specific memory pool.
 | 
			
		||||
/// \param[in]     pool_id       memory pool ID obtain referenced with \ref osPoolCreate.
 | 
			
		||||
/// \param[in]     block         address of the allocated memory block that is returned to the memory pool.
 | 
			
		||||
/// \return status code that indicates the execution status of the function.
 | 
			
		||||
/// \note MUST REMAIN UNCHANGED: \b osPoolFree shall be consistent in every CMSIS-RTOS.
 | 
			
		||||
osStatus osPoolFree (osPoolId pool_id, void *block);
 | 
			
		||||
 | 
			
		||||
#endif   // Memory Pool Management available
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//  ==== Message Queue Management Functions ====
 | 
			
		||||
 | 
			
		||||
#if (defined (osFeature_MessageQ)  &&  (osFeature_MessageQ != 0))     // Message Queues available
 | 
			
		||||
 | 
			
		||||
/// \brief Create a Message Queue Definition.
 | 
			
		||||
/// \param         name          name of the queue.
 | 
			
		||||
/// \param         queue_sz      maximum number of messages in the queue.
 | 
			
		||||
/// \param         type          data type of a single message element (for debugger).
 | 
			
		||||
/// \note CAN BE CHANGED: The parameter to \b osMessageQDef shall be consistent but the
 | 
			
		||||
///       macro body is implementation specific in every CMSIS-RTOS.
 | 
			
		||||
#if defined (osObjectsExternal)  // object is external
 | 
			
		||||
#define osMessageQDef(name, queue_sz, type)   \
 | 
			
		||||
extern const osMessageQDef_t os_messageQ_def_##name
 | 
			
		||||
#else                            // define the object
 | 
			
		||||
#define osMessageQDef(name, queue_sz, type)   \
 | 
			
		||||
const osMessageQDef_t os_messageQ_def_##name = \
 | 
			
		||||
{ (queue_sz), sizeof (type)  }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/// \brief Access a Message Queue Definition.
 | 
			
		||||
/// \param         name          name of the queue
 | 
			
		||||
/// \note CAN BE CHANGED: The parameter to \b osMessageQ shall be consistent but the
 | 
			
		||||
///       macro body is implementation specific in every CMSIS-RTOS.
 | 
			
		||||
#define osMessageQ(name) \
 | 
			
		||||
&os_messageQ_def_##name
 | 
			
		||||
 | 
			
		||||
/// Create and Initialize a Message Queue.
 | 
			
		||||
/// \param[in]     queue_def     queue definition referenced with \ref osMessageQ.
 | 
			
		||||
/// \param[in]     thread_id     thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL.
 | 
			
		||||
/// \return message queue ID for reference by other functions or NULL in case of error.
 | 
			
		||||
/// \note MUST REMAIN UNCHANGED: \b osMessageCreate shall be consistent in every CMSIS-RTOS.
 | 
			
		||||
osMessageQId osMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id);
 | 
			
		||||
 | 
			
		||||
/// Put a Message to a Queue.
 | 
			
		||||
/// \param[in]     queue_id      message queue ID obtained with \ref osMessageCreate.
 | 
			
		||||
/// \param[in]     info          message information.
 | 
			
		||||
/// \param[in]     millisec      timeout value or 0 in case of no time-out.
 | 
			
		||||
/// \return status code that indicates the execution status of the function.
 | 
			
		||||
/// \note MUST REMAIN UNCHANGED: \b osMessagePut shall be consistent in every CMSIS-RTOS.
 | 
			
		||||
osStatus osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec);
 | 
			
		||||
 | 
			
		||||
/// Get a Message or Wait for a Message from a Queue.
 | 
			
		||||
/// \param[in]     queue_id      message queue ID obtained with \ref osMessageCreate.
 | 
			
		||||
/// \param[in]     millisec      timeout value or 0 in case of no time-out.
 | 
			
		||||
/// \return event information that includes status code.
 | 
			
		||||
/// \note MUST REMAIN UNCHANGED: \b osMessageGet shall be consistent in every CMSIS-RTOS.
 | 
			
		||||
osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec);
 | 
			
		||||
 | 
			
		||||
#endif     // Message Queues available
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//  ==== Mail Queue Management Functions ====
 | 
			
		||||
 | 
			
		||||
#if (defined (osFeature_MailQ)  &&  (osFeature_MailQ != 0))     // Mail Queues available
 | 
			
		||||
 | 
			
		||||
/// \brief Create a Mail Queue Definition.
 | 
			
		||||
/// \param         name          name of the queue
 | 
			
		||||
/// \param         queue_sz      maximum number of messages in queue
 | 
			
		||||
/// \param         type          data type of a single message element
 | 
			
		||||
/// \note CAN BE CHANGED: The parameter to \b osMailQDef shall be consistent but the
 | 
			
		||||
///       macro body is implementation specific in every CMSIS-RTOS.
 | 
			
		||||
#if defined (osObjectsExternal)  // object is external
 | 
			
		||||
#define osMailQDef(name, queue_sz, type) \
 | 
			
		||||
extern struct os_mailQ_cb *os_mailQ_cb_##name; \
 | 
			
		||||
extern const osMailQDef_t os_mailQ_def_##name;
 | 
			
		||||
#else                            // define the object
 | 
			
		||||
#define osMailQDef(name, queue_sz, type) \
 | 
			
		||||
struct os_mailQ_cb *os_mailQ_cb_##name; \
 | 
			
		||||
const osMailQDef_t os_mailQ_def_##name =  \
 | 
			
		||||
{ (queue_sz), sizeof (type), (&os_mailQ_cb_##name) }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/// \brief Access a Mail Queue Definition.
 | 
			
		||||
/// \param         name          name of the queue
 | 
			
		||||
/// \note CAN BE CHANGED: The parameter to \b osMailQ shall be consistent but the
 | 
			
		||||
///       macro body is implementation specific in every CMSIS-RTOS.
 | 
			
		||||
#define osMailQ(name)  \
 | 
			
		||||
&os_mailQ_def_##name
 | 
			
		||||
 | 
			
		||||
/// Create and Initialize mail queue.
 | 
			
		||||
/// \param[in]     queue_def     reference to the mail queue definition obtain with \ref osMailQ
 | 
			
		||||
/// \param[in]     thread_id     thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL.
 | 
			
		||||
/// \return mail queue ID for reference by other functions or NULL in case of error.
 | 
			
		||||
/// \note MUST REMAIN UNCHANGED: \b osMailCreate shall be consistent in every CMSIS-RTOS.
 | 
			
		||||
osMailQId osMailCreate (const osMailQDef_t *queue_def, osThreadId thread_id);
 | 
			
		||||
 | 
			
		||||
/// Allocate a memory block from a mail.
 | 
			
		||||
/// \param[in]     queue_id      mail queue ID obtained with \ref osMailCreate.
 | 
			
		||||
/// \param[in]     millisec      timeout value or 0 in case of no time-out
 | 
			
		||||
/// \return pointer to memory block that can be filled with mail or NULL in case of error.
 | 
			
		||||
/// \note MUST REMAIN UNCHANGED: \b osMailAlloc shall be consistent in every CMSIS-RTOS.
 | 
			
		||||
void *osMailAlloc (osMailQId queue_id, uint32_t millisec);
 | 
			
		||||
 | 
			
		||||
/// Allocate a memory block from a mail and set memory block to zero.
 | 
			
		||||
/// \param[in]     queue_id      mail queue ID obtained with \ref osMailCreate.
 | 
			
		||||
/// \param[in]     millisec      timeout value or 0 in case of no time-out
 | 
			
		||||
/// \return pointer to memory block that can be filled with mail or NULL in case of error.
 | 
			
		||||
/// \note MUST REMAIN UNCHANGED: \b osMailCAlloc shall be consistent in every CMSIS-RTOS.
 | 
			
		||||
void *osMailCAlloc (osMailQId queue_id, uint32_t millisec);
 | 
			
		||||
 | 
			
		||||
/// Put a mail to a queue.
 | 
			
		||||
/// \param[in]     queue_id      mail queue ID obtained with \ref osMailCreate.
 | 
			
		||||
/// \param[in]     mail          memory block previously allocated with \ref osMailAlloc or \ref osMailCAlloc.
 | 
			
		||||
/// \return status code that indicates the execution status of the function.
 | 
			
		||||
/// \note MUST REMAIN UNCHANGED: \b osMailPut shall be consistent in every CMSIS-RTOS.
 | 
			
		||||
osStatus osMailPut (osMailQId queue_id, void *mail);
 | 
			
		||||
 | 
			
		||||
/// Get a mail from a queue.
 | 
			
		||||
/// \param[in]     queue_id      mail queue ID obtained with \ref osMailCreate.
 | 
			
		||||
/// \param[in]     millisec      timeout value or 0 in case of no time-out
 | 
			
		||||
/// \return event that contains mail information or error code.
 | 
			
		||||
/// \note MUST REMAIN UNCHANGED: \b osMailGet shall be consistent in every CMSIS-RTOS.
 | 
			
		||||
osEvent osMailGet (osMailQId queue_id, uint32_t millisec);
 | 
			
		||||
 | 
			
		||||
/// Free a memory block from a mail.
 | 
			
		||||
/// \param[in]     queue_id      mail queue ID obtained with \ref osMailCreate.
 | 
			
		||||
/// \param[in]     mail          pointer to the memory block that was obtained with \ref osMailGet.
 | 
			
		||||
/// \return status code that indicates the execution status of the function.
 | 
			
		||||
/// \note MUST REMAIN UNCHANGED: \b osMailFree shall be consistent in every CMSIS-RTOS.
 | 
			
		||||
osStatus osMailFree (osMailQId queue_id, void *mail);
 | 
			
		||||
 | 
			
		||||
#endif  // Mail Queues available
 | 
			
		||||
 | 
			
		||||
#define malloc(size)            pvPortMalloc(size)
 | 
			
		||||
#define free(pbuf)              vPortFree(pbuf)
 | 
			
		||||
extern void *calloc_freertos(size_t nelements, size_t elementSize);
 | 
			
		||||
#define calloc(nelements, elementSize) calloc_freertos(nelements, elementSize)
 | 
			
		||||
 | 
			
		||||
#ifdef  __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif  // _CMSIS_OS_H
 | 
			
		||||
							
								
								
									
										300
									
								
								component/os/freertos/freertos_pmu.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										300
									
								
								component/os/freertos/freertos_pmu.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,300 @@
 | 
			
		|||
#include "FreeRTOS.h"
 | 
			
		||||
 | 
			
		||||
#include "freertos_pmu.h"
 | 
			
		||||
 | 
			
		||||
#include <platform_opts.h>
 | 
			
		||||
 | 
			
		||||
#include "platform_autoconf.h"
 | 
			
		||||
#include "sys_api.h"
 | 
			
		||||
#include "sleep_ex_api.h"
 | 
			
		||||
#include "gpio_api.h"
 | 
			
		||||
 | 
			
		||||
#ifndef portNVIC_SYSTICK_CURRENT_VALUE_REG
 | 
			
		||||
#define portNVIC_SYSTICK_CURRENT_VALUE_REG	( * ( ( volatile uint32_t * ) 0xe000e018 ) )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
uint32_t missing_tick = 0;
 | 
			
		||||
 | 
			
		||||
#define FREERTOS_PMU_DISABLE_LOGUART_IN_TICKLESS (0)
 | 
			
		||||
 | 
			
		||||
static uint32_t wakelock     = DEFAULT_WAKELOCK;
 | 
			
		||||
static uint32_t wakeup_event = DEFAULT_WAKEUP_EVENT;
 | 
			
		||||
 | 
			
		||||
freertos_sleep_callback pre_sleep_callback[32] = {NULL};
 | 
			
		||||
freertos_sleep_callback post_sleep_callback[32] = {NULL};
 | 
			
		||||
 | 
			
		||||
#if (configGENERATE_RUN_TIME_STATS == 1)
 | 
			
		||||
static u8 last_wakelock_state[32] = {
 | 
			
		||||
    DEFAULT_WAKELOCK & 0x01, 0, 0, 0, 0, 0, 0, 0,
 | 
			
		||||
    0, 0, 0, 0, 0, 0, 0, 0,
 | 
			
		||||
    0, 0, 0, 0, 0, 0, 0, 0,
 | 
			
		||||
    0, 0, 0, 0, 0, 0, 0, 0
 | 
			
		||||
};
 | 
			
		||||
static u32 last_acquire_wakelock_time[32] = {0};
 | 
			
		||||
static u32 hold_wakelock_time[32] = {0};
 | 
			
		||||
static u32 base_sys_time = 0;
 | 
			
		||||
static u32 sys_sleep_time = 0;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(FREERTOS_PMU_TICKLESS_PLL_RESERVED) && (FREERTOS_PMU_TICKLESS_PLL_RESERVED==1)
 | 
			
		||||
unsigned char reserve_pll = 1;
 | 
			
		||||
#else
 | 
			
		||||
unsigned char reserve_pll = 0;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* ++++++++ FreeRTOS macro implementation ++++++++ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 *  It is called in idle task.
 | 
			
		||||
 *
 | 
			
		||||
 *  @return  true  : System is ready to check conditions that if it can enter sleep.
 | 
			
		||||
 *           false : System keep awake.
 | 
			
		||||
 **/
 | 
			
		||||
int freertos_ready_to_sleep() {
 | 
			
		||||
    return wakelock == 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 *  It is called when freertos is going to sleep.
 | 
			
		||||
 *  At this moment, all sleep conditons are satisfied. All freertos' sleep pre-processing are done.
 | 
			
		||||
 *
 | 
			
		||||
 *  @param  expected_idle_time : The time that FreeRTOS expect to sleep.
 | 
			
		||||
 *                               If we set this value to 0 then FreeRTOS will do nothing in its sleep function.
 | 
			
		||||
 **/
 | 
			
		||||
void freertos_pre_sleep_processing(unsigned int *expected_idle_time) {
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_SOC_PS_MODULE
 | 
			
		||||
 | 
			
		||||
    uint32_t i;
 | 
			
		||||
    uint32_t stime;
 | 
			
		||||
    uint32_t tick_before_sleep;
 | 
			
		||||
    uint32_t tick_after_sleep;
 | 
			
		||||
    uint32_t tick_passed;
 | 
			
		||||
    uint32_t backup_systick_reg;
 | 
			
		||||
    unsigned char IsDramOn = 1;
 | 
			
		||||
    unsigned char suspend_sdram = 1;
 | 
			
		||||
 | 
			
		||||
#if (configGENERATE_RUN_TIME_STATS == 1)
 | 
			
		||||
	uint32_t kernel_tick_before_sleep;
 | 
			
		||||
	uint32_t kernel_tick_after_sleep;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    /* To disable freertos sleep function and use our sleep function, 
 | 
			
		||||
     * we can set original expected idle time to 0. */
 | 
			
		||||
    stime = *expected_idle_time;
 | 
			
		||||
    *expected_idle_time = 0;
 | 
			
		||||
 | 
			
		||||
    for (i=0; i<32; i++) {
 | 
			
		||||
        if ( pre_sleep_callback[i] != NULL) {
 | 
			
		||||
            pre_sleep_callback[i]( stime );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if (configGENERATE_RUN_TIME_STATS == 1)
 | 
			
		||||
	kernel_tick_before_sleep = osKernelSysTick();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    // Store gtimer timestamp before sleep
 | 
			
		||||
    tick_before_sleep = us_ticker_read();
 | 
			
		||||
 | 
			
		||||
    if ( sys_is_sdram_power_on() == 0 ) {
 | 
			
		||||
        IsDramOn = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (IsDramOn) {
 | 
			
		||||
#if defined(FREERTOS_PMU_TICKLESS_SUSPEND_SDRAM) && (FREERTOS_PMU_TICKLESS_SUSPEND_SDRAM==0)
 | 
			
		||||
        // sdram is turned on, and we don't want suspend sdram
 | 
			
		||||
        suspend_sdram = 0;
 | 
			
		||||
#endif
 | 
			
		||||
    } else {
 | 
			
		||||
        // sdram didn't turned on, we should not suspend it
 | 
			
		||||
        suspend_sdram = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if (FREERTOS_PMU_DISABLE_LOGUART_IN_TICKLESS)
 | 
			
		||||
    // config gpio on log uart tx for pull ctrl
 | 
			
		||||
    HAL_GPIO_PIN gpio_log_uart_tx;
 | 
			
		||||
    gpio_log_uart_tx.pin_name = gpio_set(PB_0);
 | 
			
		||||
    gpio_log_uart_tx.pin_mode = DOUT_PUSH_PULL;
 | 
			
		||||
    HAL_GPIO_Init(&gpio_log_uart_tx);
 | 
			
		||||
    GpioFunctionChk(PB_0, ENABLE);
 | 
			
		||||
 | 
			
		||||
    sys_log_uart_off();
 | 
			
		||||
    HAL_GPIO_WritePin(&gpio_log_uart_tx, 1); // pull up log uart tx to avoid power lekage
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    backup_systick_reg = portNVIC_SYSTICK_CURRENT_VALUE_REG;
 | 
			
		||||
 | 
			
		||||
    // sleep
 | 
			
		||||
    sleep_ex_selective(wakeup_event, stime, reserve_pll, suspend_sdram);
 | 
			
		||||
 | 
			
		||||
    portNVIC_SYSTICK_CURRENT_VALUE_REG = backup_systick_reg;
 | 
			
		||||
 | 
			
		||||
#if (FREERTOS_PMU_DISABLE_LOGUART_IN_TICKLESS)
 | 
			
		||||
    sys_log_uart_off();
 | 
			
		||||
    sys_log_uart_on();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    // update kernel tick by calculating passed tick from gtimer
 | 
			
		||||
    {
 | 
			
		||||
        // get current gtimer timestamp
 | 
			
		||||
        tick_after_sleep = us_ticker_read();
 | 
			
		||||
 | 
			
		||||
        // calculated passed time
 | 
			
		||||
        if (tick_after_sleep > tick_before_sleep) {
 | 
			
		||||
            tick_passed = tick_after_sleep - tick_before_sleep;
 | 
			
		||||
        } else {
 | 
			
		||||
            // overflow
 | 
			
		||||
            tick_passed = (0xffffffff - tick_before_sleep) + tick_after_sleep;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* If there is a rapid interrupt (<1ms), it makes tick_passed less than 1ms.
 | 
			
		||||
         * The tick_passed would be rounded and make OS can't step tick.
 | 
			
		||||
         * We collect the rounded tick_passed into missing_tick and step tick properly.
 | 
			
		||||
         * */
 | 
			
		||||
        tick_passed += missing_tick;
 | 
			
		||||
        if (tick_passed > stime * 1000) {
 | 
			
		||||
            missing_tick = tick_passed - stime * 1000;
 | 
			
		||||
            tick_passed = stime * 1000;
 | 
			
		||||
        } else {
 | 
			
		||||
            missing_tick = tick_passed % 1000;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // update kernel tick
 | 
			
		||||
        vTaskStepTick( tick_passed/1000 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if (configGENERATE_RUN_TIME_STATS == 1)
 | 
			
		||||
	kernel_tick_after_sleep = osKernelSysTick();
 | 
			
		||||
	sys_sleep_time += (kernel_tick_after_sleep - kernel_tick_before_sleep);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    for (i=0; i<32; i++) {
 | 
			
		||||
        if ( post_sleep_callback[i] != NULL) {
 | 
			
		||||
            post_sleep_callback[i]( stime );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
    // If PS is not enabled, then use freertos sleep function
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void freertos_post_sleep_processing(unsigned int *expected_idle_time) {
 | 
			
		||||
#ifndef configSYSTICK_CLOCK_HZ
 | 
			
		||||
	*expected_idle_time = 1 + ( portNVIC_SYSTICK_CURRENT_VALUE_REG / ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) );
 | 
			
		||||
#else
 | 
			
		||||
	*expected_idle_time = 1 + ( portNVIC_SYSTICK_CURRENT_VALUE_REG / ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) );
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
/* -------- FreeRTOS macro implementation -------- */
 | 
			
		||||
 | 
			
		||||
void acquire_wakelock(uint32_t lock_id) {
 | 
			
		||||
 | 
			
		||||
    wakelock |= lock_id;
 | 
			
		||||
 | 
			
		||||
#if (configGENERATE_RUN_TIME_STATS == 1)
 | 
			
		||||
    u32 i;
 | 
			
		||||
    u32 current_timestamp = osKernelSysTick();
 | 
			
		||||
    for (i=0; i<32; i++) {
 | 
			
		||||
        if ( (1<<i & lock_id) && (last_wakelock_state[i] == 0) ) {
 | 
			
		||||
            last_acquire_wakelock_time[i] = current_timestamp;
 | 
			
		||||
            last_wakelock_state[i] = 1;            
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void release_wakelock(uint32_t lock_id) {
 | 
			
		||||
    wakelock &= ~lock_id;
 | 
			
		||||
 | 
			
		||||
#if (configGENERATE_RUN_TIME_STATS == 1)
 | 
			
		||||
    u32 i;
 | 
			
		||||
    u32 current_timestamp = osKernelSysTick();
 | 
			
		||||
    for (i=0; i<32; i++) {
 | 
			
		||||
        if ( (1<<i & lock_id) && (last_wakelock_state[i] == 1) ) {
 | 
			
		||||
            hold_wakelock_time[i] += current_timestamp - last_acquire_wakelock_time[i];
 | 
			
		||||
            last_wakelock_state[i] = 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t get_wakelock_status() {
 | 
			
		||||
    return wakelock;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if (configGENERATE_RUN_TIME_STATS == 1)
 | 
			
		||||
void get_wakelock_hold_stats( char *pcWriteBuffer ) {
 | 
			
		||||
    u32 i;
 | 
			
		||||
    u32 current_timestamp = osKernelSysTick();
 | 
			
		||||
 | 
			
		||||
    *pcWriteBuffer = 0x00;
 | 
			
		||||
 | 
			
		||||
    // print header
 | 
			
		||||
    sprintf(pcWriteBuffer, "wakelock_id\tholdtime\r\n");
 | 
			
		||||
    pcWriteBuffer += strlen( pcWriteBuffer );
 | 
			
		||||
 | 
			
		||||
    for (i=0; i<32; i++) {
 | 
			
		||||
        if (last_wakelock_state[i] == 1) {
 | 
			
		||||
            sprintf(pcWriteBuffer, "%x\t\t%d\r\n", i, hold_wakelock_time[i] + (current_timestamp - last_acquire_wakelock_time[i]));
 | 
			
		||||
        } else {
 | 
			
		||||
            if (hold_wakelock_time[i] > 0) {
 | 
			
		||||
                sprintf(pcWriteBuffer, "%x\t\t%d\r\n", i, hold_wakelock_time[i]);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        pcWriteBuffer += strlen( pcWriteBuffer );
 | 
			
		||||
    }
 | 
			
		||||
    sprintf(pcWriteBuffer, "time passed: %d ms, system sleep %d ms\r\n", current_timestamp - base_sys_time, sys_sleep_time);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void clean_wakelock_stat() {
 | 
			
		||||
    u32 i;
 | 
			
		||||
    base_sys_time = osKernelSysTick();
 | 
			
		||||
    for (i=0; i<32; i++) {
 | 
			
		||||
        hold_wakelock_time[i] = 0;
 | 
			
		||||
        if (last_wakelock_state[i] == 1) {
 | 
			
		||||
            last_acquire_wakelock_time[i] = base_sys_time;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
	sys_sleep_time = 0;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void add_wakeup_event(uint32_t event) {
 | 
			
		||||
    wakeup_event |= event;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void del_wakeup_event(uint32_t event) {
 | 
			
		||||
    wakeup_event &= ~event;
 | 
			
		||||
    // To fulfill tickless design, system timer is required to be wakeup event
 | 
			
		||||
    wakeup_event |= SLEEP_WAKEUP_BY_STIMER;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void register_sleep_callback_by_module( unsigned char is_pre_sleep, freertos_sleep_callback sleep_cb, uint32_t module ) {
 | 
			
		||||
    u32 i;
 | 
			
		||||
    for (i=0; i<32; i++) {
 | 
			
		||||
        if ( module & BIT(i) ) {
 | 
			
		||||
            if (is_pre_sleep) {
 | 
			
		||||
                pre_sleep_callback[i] = sleep_cb;
 | 
			
		||||
            } else {
 | 
			
		||||
                post_sleep_callback[i] = sleep_cb;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void register_pre_sleep_callback( freertos_sleep_callback pre_sleep_cb ) {
 | 
			
		||||
    register_sleep_callback_by_module(1, pre_sleep_cb, 0x00008000);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void register_post_sleep_callback( freertos_sleep_callback post_sleep_cb ) {
 | 
			
		||||
    register_sleep_callback_by_module(0, post_sleep_cb, 0x00008000);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void set_pll_reserved(unsigned char reserve) {
 | 
			
		||||
    reserve_pll = reserve;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										116
									
								
								component/os/freertos/freertos_pmu.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								component/os/freertos/freertos_pmu.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,116 @@
 | 
			
		|||
#ifndef __FREERTOS_PMU_H_
 | 
			
		||||
#define __FREERTOS_PMU_H_
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_PLATFORM_8195A
 | 
			
		||||
#include "sleep_ex_api.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef BIT
 | 
			
		||||
#define BIT(n)                   (1<<n)
 | 
			
		||||
#endif
 | 
			
		||||
// wakelock for system usage
 | 
			
		||||
#define WAKELOCK_OS              BIT(0)
 | 
			
		||||
#define WAKELOCK_WLAN            BIT(1)
 | 
			
		||||
#define WAKELOCK_LOGUART         BIT(2)
 | 
			
		||||
#define WAKELOCK_SDIO_DEVICE     BIT(3)
 | 
			
		||||
 | 
			
		||||
// wakelock for user defined
 | 
			
		||||
#define WAKELOCK_USER_BASE       BIT(16)
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
#define DEFAULT_WAKELOCK         (0)
 | 
			
		||||
#else
 | 
			
		||||
// default locked by OS and not to sleep until OS release wakelock in somewhere
 | 
			
		||||
#define DEFAULT_WAKELOCK         (WAKELOCK_OS)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define DEFAULT_WAKEUP_EVENT (SLEEP_WAKEUP_BY_STIMER | SLEEP_WAKEUP_BY_GTIMER | SLEEP_WAKEUP_BY_GPIO_INT | SLEEP_WAKEUP_BY_WLAN)
 | 
			
		||||
 | 
			
		||||
typedef void (*freertos_sleep_callback)( unsigned int );
 | 
			
		||||
 | 
			
		||||
/** Acquire wakelock
 | 
			
		||||
 *
 | 
			
		||||
 *  A wakelock is a 32-bit map. Each module own 1 bit in this bit map.
 | 
			
		||||
 *  FreeRTOS tickless reference the wakelock and decide that if it can or cannot enter sleep state.
 | 
			
		||||
 *  If any module acquire and hold a bit in wakelock, then the whole system won't enter sleep state.
 | 
			
		||||
 *
 | 
			
		||||
 *  If wakelock is not equals to 0, then the system won't enter sleep.
 | 
			
		||||
 *
 | 
			
		||||
 *  @param lock_id        : The bit which is attempt to add into wakelock
 | 
			
		||||
 */
 | 
			
		||||
void acquire_wakelock(uint32_t lock_id);
 | 
			
		||||
 | 
			
		||||
/** Release wakelock
 | 
			
		||||
 *
 | 
			
		||||
 *  If wakelock equals to 0, then the system may enter sleep state if it is in idle state.
 | 
			
		||||
 *
 | 
			
		||||
 *  @param lock_id        : The bit which is attempt to remove from wakelock
 | 
			
		||||
 */
 | 
			
		||||
void release_wakelock(uint32_t lock_id);
 | 
			
		||||
 | 
			
		||||
/** Get current wakelock bit map value
 | 
			
		||||
 *
 | 
			
		||||
 *  @return               : the current wakelock bit map value
 | 
			
		||||
 */
 | 
			
		||||
uint32_t get_wakelock_status();
 | 
			
		||||
 | 
			
		||||
#if (configGENERATE_RUN_TIME_STATS == 1)
 | 
			
		||||
 | 
			
		||||
/** Get text report that contain the statics of wakelock holding time
 | 
			
		||||
 *
 | 
			
		||||
 *  Each time a module acquries or releases wakelock, a holding time is calculated and sum up to a table.
 | 
			
		||||
 *  It is for debug that which module is power saving killer.
 | 
			
		||||
 *
 | 
			
		||||
 *  @param pcWriteBuffer  : The char buffer that contain the report
 | 
			
		||||
 */
 | 
			
		||||
void get_wakelock_hold_stats( char *pcWriteBuffer );
 | 
			
		||||
 | 
			
		||||
/** Recalculate the wakelock statics
 | 
			
		||||
 *
 | 
			
		||||
 *  By default the wakelock statics is calculated from system boot up.
 | 
			
		||||
 *  If we want to debug power saving killer from a specified timestamp, we can reset the statics.
 | 
			
		||||
 */
 | 
			
		||||
void clean_wakelock_stat();
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void add_wakeup_event(uint32_t event);
 | 
			
		||||
void del_wakeup_event(uint32_t event);
 | 
			
		||||
 | 
			
		||||
/** Register sleep callback
 | 
			
		||||
 *
 | 
			
		||||
 *  Pre-sleep callbacks are called before entering sleep.
 | 
			
		||||
 *  Post-sleep callbacks are called after resume.
 | 
			
		||||
 *
 | 
			
		||||
 *  @param is_pre_sleep   : Indicate the sleep_cb is for pre-sleep or post-sleep
 | 
			
		||||
 *  @param sleep_cb       : The callback function which is called before/after sleep
 | 
			
		||||
 *  @param module         : The callback is assigned according to the bit specify in bit field of param module
 | 
			
		||||
 *                          The bit 15 (0x00008000) is used for unspecified callback.
 | 
			
		||||
 */
 | 
			
		||||
void register_sleep_callback_by_module( unsigned char is_pre_sleep, freertos_sleep_callback sleep_cb, uint32_t module );
 | 
			
		||||
 | 
			
		||||
/** Register unspecified pre sleep callback
 | 
			
		||||
 *
 | 
			
		||||
 *  Pre-sleep callbacks are called before entering sleep.
 | 
			
		||||
 *
 | 
			
		||||
 *  @param pre_sleep_cb   : The callback function which is called before sleep
 | 
			
		||||
 *                          It is registed in bit 15 (0x00008000) of module list
 | 
			
		||||
 */
 | 
			
		||||
void register_pre_sleep_callback( freertos_sleep_callback pre_sleep_cb );
 | 
			
		||||
 | 
			
		||||
/** Register unspecified post sleep callback
 | 
			
		||||
 *
 | 
			
		||||
 *  Post-sleep callbacks are called before entering sleep.
 | 
			
		||||
 *
 | 
			
		||||
 *  @param post_sleep_cb  : The callback function which is called after sleep
 | 
			
		||||
 *                          It is registed in bit 15 (0x00008000) of module list
 | 
			
		||||
 */
 | 
			
		||||
void register_post_sleep_callback( freertos_sleep_callback post_sleep_cb );
 | 
			
		||||
 | 
			
		||||
/** Set PLL reserved or not when sleep is called
 | 
			
		||||
 *
 | 
			
		||||
 *  @param reserve: true for sleep with PLL reserve
 | 
			
		||||
 */
 | 
			
		||||
void set_pll_reserved(unsigned char reserve);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										761
									
								
								component/os/freertos/freertos_service.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										761
									
								
								component/os/freertos/freertos_service.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,761 @@
 | 
			
		|||
/* FreeRTOS includes */
 | 
			
		||||
#include <FreeRTOS.h>
 | 
			
		||||
#include <task.h>
 | 
			
		||||
#include <timers.h>
 | 
			
		||||
#include <semphr.h>
 | 
			
		||||
//#include <autoconf.h>
 | 
			
		||||
#include <osdep_service.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <freertos_pmu.h>
 | 
			
		||||
//#include <tcm_heap.h>
 | 
			
		||||
/********************* os depended utilities ********************/
 | 
			
		||||
 | 
			
		||||
#ifndef USE_MUTEX_FOR_SPINLOCK
 | 
			
		||||
#define USE_MUTEX_FOR_SPINLOCK 1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//----- ------------------------------------------------------------------
 | 
			
		||||
// Misc Function
 | 
			
		||||
//----- ------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
void save_and_cli()
 | 
			
		||||
{
 | 
			
		||||
	taskENTER_CRITICAL();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void restore_flags()
 | 
			
		||||
{
 | 
			
		||||
	taskEXIT_CRITICAL();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cli()
 | 
			
		||||
{
 | 
			
		||||
	taskDISABLE_INTERRUPTS();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Not needed on 64bit architectures */
 | 
			
		||||
static unsigned int __div64_32(u64 *n, unsigned int base)
 | 
			
		||||
{
 | 
			
		||||
	u64 rem = *n;
 | 
			
		||||
	u64 b = base;
 | 
			
		||||
	u64 res, d = 1;
 | 
			
		||||
	unsigned int high = rem >> 32;
 | 
			
		||||
 | 
			
		||||
	/* Reduce the thing a bit first */
 | 
			
		||||
	res = 0;
 | 
			
		||||
	if (high >= base) {
 | 
			
		||||
		high /= base;
 | 
			
		||||
		res = (u64) high << 32;
 | 
			
		||||
		rem -= (u64) (high * base) << 32;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	while ((u64)b > 0 && b < rem) {
 | 
			
		||||
		b = b+b;
 | 
			
		||||
		d = d+d;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	do {
 | 
			
		||||
		if (rem >= b) {
 | 
			
		||||
			rem -= b;
 | 
			
		||||
			res += d;
 | 
			
		||||
		}
 | 
			
		||||
		b >>= 1;
 | 
			
		||||
		d >>= 1;
 | 
			
		||||
	} while (d);
 | 
			
		||||
 | 
			
		||||
	*n = res;
 | 
			
		||||
	return rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/********************* os depended service ********************/
 | 
			
		||||
 | 
			
		||||
u8* _freertos_malloc(u32 sz)
 | 
			
		||||
{
 | 
			
		||||
	return pvPortMalloc(sz);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
u8* _freertos_zmalloc(u32 sz)
 | 
			
		||||
{
 | 
			
		||||
	u8 *pbuf = _freertos_malloc(sz);
 | 
			
		||||
 | 
			
		||||
	if (pbuf != NULL)
 | 
			
		||||
		memset(pbuf, 0, sz);
 | 
			
		||||
 | 
			
		||||
	return pbuf;	
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void _freertos_mfree(u8 *pbuf, u32 sz)
 | 
			
		||||
{
 | 
			
		||||
	vPortFree(pbuf);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _freertos_memcpy(void* dst, void* src, u32 sz)
 | 
			
		||||
{
 | 
			
		||||
	memcpy(dst, src, sz);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _freertos_memcmp(void *dst, void *src, u32 sz)
 | 
			
		||||
{
 | 
			
		||||
//under Linux/GNU/GLibc, the return value of memcmp for two same mem. chunk is 0
 | 
			
		||||
	if (!(memcmp(dst, src, sz)))
 | 
			
		||||
		return 1;
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _freertos_memset(void *pbuf, int c, u32 sz)
 | 
			
		||||
{
 | 
			
		||||
	memset(pbuf, c, sz);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _freertos_init_sema(_sema *sema, int init_val)
 | 
			
		||||
{
 | 
			
		||||
	*sema = xSemaphoreCreateCounting(0xffffffff, init_val);	//Set max count 0xffffffff
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _freertos_free_sema(_sema *sema)
 | 
			
		||||
{
 | 
			
		||||
	if(*sema != NULL)
 | 
			
		||||
		vSemaphoreDelete(*sema);
 | 
			
		||||
 | 
			
		||||
	*sema = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _freertos_up_sema(_sema *sema)
 | 
			
		||||
{
 | 
			
		||||
	xSemaphoreGive(*sema);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _freertos_up_sema_from_isr(_sema *sema)
 | 
			
		||||
{
 | 
			
		||||
	portBASE_TYPE taskWoken = pdFALSE;
 | 
			
		||||
	xSemaphoreGiveFromISR(*sema, &taskWoken);
 | 
			
		||||
	portEND_SWITCHING_ISR(taskWoken);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static u32 _freertos_down_sema(_sema *sema, u32 timeout)
 | 
			
		||||
{
 | 
			
		||||
	if(timeout == RTW_MAX_DELAY) {
 | 
			
		||||
		timeout = portMAX_DELAY;
 | 
			
		||||
	} else {
 | 
			
		||||
		timeout = rtw_ms_to_systime(timeout);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if(xSemaphoreTake(*sema, timeout) != pdTRUE) {
 | 
			
		||||
		return pdFALSE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return pdTRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _freertos_mutex_init(_mutex *pmutex)
 | 
			
		||||
{
 | 
			
		||||
	*pmutex = xSemaphoreCreateMutex();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _freertos_mutex_free(_mutex *pmutex)
 | 
			
		||||
{
 | 
			
		||||
	if(*pmutex != NULL)
 | 
			
		||||
		vSemaphoreDelete(*pmutex);
 | 
			
		||||
 | 
			
		||||
	*pmutex = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _freertos_mutex_get(_lock *plock)
 | 
			
		||||
{
 | 
			
		||||
	while(xSemaphoreTake(*plock, 60 * 1000 / portTICK_RATE_MS) != pdTRUE)
 | 
			
		||||
		DBG_ERR("[%s] %s(%p) failed, retry\n", pcTaskGetTaskName(NULL), __FUNCTION__, plock);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _freertos_mutex_get_timeout(_lock *plock, u32 timeout_ms)
 | 
			
		||||
{
 | 
			
		||||
	if(xSemaphoreTake(*plock, timeout_ms / portTICK_RATE_MS) != pdTRUE){
 | 
			
		||||
		DBG_ERR("[%s] %s(%p) failed, retry\n", pcTaskGetTaskName(NULL), __FUNCTION__, plock);
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _freertos_mutex_put(_lock *plock)
 | 
			
		||||
{
 | 
			
		||||
	xSemaphoreGive(*plock);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _freertos_enter_critical(_lock *plock, _irqL *pirqL)
 | 
			
		||||
{
 | 
			
		||||
	taskENTER_CRITICAL();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _freertos_exit_critical(_lock *plock, _irqL *pirqL)
 | 
			
		||||
{
 | 
			
		||||
	taskEXIT_CRITICAL();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static u32 uxSavedInterruptStatus = 0;
 | 
			
		||||
static void _freertos_enter_critical_from_isr(_lock *plock, _irqL *pirqL)
 | 
			
		||||
{
 | 
			
		||||
    portASSERT_IF_INTERRUPT_PRIORITY_INVALID();
 | 
			
		||||
 | 
			
		||||
    uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _freertos_exit_critical_from_isr(_lock *plock, _irqL *pirqL)
 | 
			
		||||
{
 | 
			
		||||
	portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _freertos_enter_critical_mutex(_mutex *pmutex, _irqL *pirqL)
 | 
			
		||||
{
 | 
			
		||||
	int ret = 0;
 | 
			
		||||
 | 
			
		||||
	while(xSemaphoreTake(*pmutex, 60 * 1000 / portTICK_RATE_MS) != pdTRUE)
 | 
			
		||||
		printf("\n\r[%s] %s(%p) failed, retry\n", pcTaskGetTaskName(NULL), __FUNCTION__, pmutex);
 | 
			
		||||
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _freertos_exit_critical_mutex(_mutex *pmutex, _irqL *pirqL)
 | 
			
		||||
{
 | 
			
		||||
	xSemaphoreGive(*pmutex);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _freertos_spinlock_init(_lock *plock)
 | 
			
		||||
{
 | 
			
		||||
#if USE_MUTEX_FOR_SPINLOCK
 | 
			
		||||
	*plock = xSemaphoreCreateMutex();
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _freertos_spinlock_free(_lock *plock)
 | 
			
		||||
{
 | 
			
		||||
#if USE_MUTEX_FOR_SPINLOCK
 | 
			
		||||
	if(*plock != NULL)
 | 
			
		||||
		vSemaphoreDelete(*plock);
 | 
			
		||||
 | 
			
		||||
	*plock = NULL;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _freertos_spinlock(_lock *plock)
 | 
			
		||||
{
 | 
			
		||||
#if USE_MUTEX_FOR_SPINLOCK
 | 
			
		||||
	while(xSemaphoreTake(*plock, 60 * 1000 / portTICK_RATE_MS) != pdTRUE)
 | 
			
		||||
		DBG_ERR("[%s] %s(%p) failed, retry\n", pcTaskGetTaskName(NULL), __FUNCTION__, plock);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _freertos_spinunlock(_lock *plock)
 | 
			
		||||
{
 | 
			
		||||
#if USE_MUTEX_FOR_SPINLOCK
 | 
			
		||||
	xSemaphoreGive(*plock);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _freertos_spinlock_irqsave(_lock *plock, _irqL *irqL)
 | 
			
		||||
{
 | 
			
		||||
	taskENTER_CRITICAL();
 | 
			
		||||
#if USE_MUTEX_FOR_SPINLOCK
 | 
			
		||||
	while(xSemaphoreTake(*plock, 60 * 1000 / portTICK_RATE_MS) != pdTRUE)
 | 
			
		||||
		DBG_ERR("[%s] %s(%p) failed, retry\n", pcTaskGetTaskName(NULL), __FUNCTION__, plock);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _freertos_spinunlock_irqsave(_lock *plock, _irqL *irqL)
 | 
			
		||||
{
 | 
			
		||||
#if USE_MUTEX_FOR_SPINLOCK
 | 
			
		||||
	xSemaphoreGive(*plock);
 | 
			
		||||
#endif
 | 
			
		||||
	taskEXIT_CRITICAL();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _freertos_init_xqueue( _xqueue* queue, const char* name, u32 message_size, u32 number_of_messages )
 | 
			
		||||
{
 | 
			
		||||
    if ( ( *queue = xQueueCreate( number_of_messages, message_size ) ) == NULL )
 | 
			
		||||
    {
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _freertos_push_to_xqueue( _xqueue* queue, void* message, u32 timeout_ms )
 | 
			
		||||
{
 | 
			
		||||
	if(timeout_ms == RTW_MAX_DELAY) {
 | 
			
		||||
	      timeout_ms = portMAX_DELAY;
 | 
			
		||||
	} else {
 | 
			
		||||
	      timeout_ms = rtw_ms_to_systime(timeout_ms);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    if ( xQueueSendToBack( *queue, message, timeout_ms ) != pdPASS )
 | 
			
		||||
    {
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _freertos_pop_from_xqueue( _xqueue* queue, void* message, u32 timeout_ms )
 | 
			
		||||
{
 | 
			
		||||
	if(timeout_ms == RTW_WAIT_FOREVER) {
 | 
			
		||||
		timeout_ms = portMAX_DELAY;
 | 
			
		||||
	} else {
 | 
			
		||||
		timeout_ms = rtw_ms_to_systime(timeout_ms);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    if ( xQueueReceive( *queue, message, timeout_ms ) != pdPASS )
 | 
			
		||||
    {
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _freertos_deinit_xqueue( _xqueue* queue )
 | 
			
		||||
{
 | 
			
		||||
    int result = 0;
 | 
			
		||||
 | 
			
		||||
	  if( uxQueueMessagesWaiting( queue ) )
 | 
			
		||||
	  {
 | 
			
		||||
	  	  result = -1;
 | 
			
		||||
	  }
 | 
			
		||||
    vQueueDelete( *queue );
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static u32 _freertos_get_current_time(void)
 | 
			
		||||
{
 | 
			
		||||
	return xTaskGetTickCount();	//The count of ticks since vTaskStartScheduler was called.
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static u32 _freertos_systime_to_ms(u32 systime)
 | 
			
		||||
{
 | 
			
		||||
	return systime * portTICK_RATE_MS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static u32 _freertos_systime_to_sec(u32 systime)
 | 
			
		||||
{
 | 
			
		||||
	return systime / configTICK_RATE_HZ;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static u32 _freertos_ms_to_systime(u32 ms)
 | 
			
		||||
{
 | 
			
		||||
	return ms / portTICK_RATE_MS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static u32 _freertos_sec_to_systime(u32 sec)
 | 
			
		||||
{
 | 
			
		||||
	return sec * configTICK_RATE_HZ;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _freertos_msleep_os(int ms)
 | 
			
		||||
{
 | 
			
		||||
	vTaskDelay(ms / portTICK_RATE_MS);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _freertos_usleep_os(int us)
 | 
			
		||||
{
 | 
			
		||||
#if defined(STM32F2XX) || defined(STM32F4XX) || defined(STM32F10X_XL)
 | 
			
		||||
	// FreeRTOS does not provide us level delay. Use busy wait
 | 
			
		||||
	WLAN_BSP_UsLoop(us);
 | 
			
		||||
#elif defined(CONFIG_PLATFORM_8195A) || defined(CONFIG_PLATFORM_8711B)
 | 
			
		||||
	//DBG_ERR("%s: Please Implement micro-second delay\n", __FUNCTION__);
 | 
			
		||||
#else
 | 
			
		||||
	#error "Please implement hardware dependent micro second level sleep here"
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _freertos_mdelay_os(int ms)
 | 
			
		||||
{
 | 
			
		||||
	vTaskDelay(ms / portTICK_RATE_MS);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _freertos_udelay_os(int us)
 | 
			
		||||
{
 | 
			
		||||
#if defined(STM32F2XX)	|| defined(STM32F4XX) || defined(STM32F10X_XL)
 | 
			
		||||
	// FreeRTOS does not provide us level delay. Use busy wait
 | 
			
		||||
	WLAN_BSP_UsLoop(us);
 | 
			
		||||
#elif defined(CONFIG_PLATFORM_8195A) || defined(CONFIG_PLATFORM_8711B)
 | 
			
		||||
	RtlUdelayOS(us);
 | 
			
		||||
#else
 | 
			
		||||
	#error "Please implement hardware dependent micro second level sleep here"
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _freertos_yield_os(void)
 | 
			
		||||
{
 | 
			
		||||
	taskYIELD();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _freertos_ATOMIC_SET(ATOMIC_T *v, int i)
 | 
			
		||||
{
 | 
			
		||||
	atomic_set(v,i);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _freertos_ATOMIC_READ(ATOMIC_T *v)
 | 
			
		||||
{
 | 
			
		||||
	return atomic_read(v);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _freertos_ATOMIC_ADD(ATOMIC_T *v, int i)
 | 
			
		||||
{
 | 
			
		||||
	save_and_cli();
 | 
			
		||||
	v->counter += i;
 | 
			
		||||
	restore_flags();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _freertos_ATOMIC_SUB(ATOMIC_T *v, int i)
 | 
			
		||||
{
 | 
			
		||||
	save_and_cli();
 | 
			
		||||
	v->counter -= i;
 | 
			
		||||
	restore_flags();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _freertos_ATOMIC_INC(ATOMIC_T *v)
 | 
			
		||||
{
 | 
			
		||||
	_freertos_ATOMIC_ADD(v, 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _freertos_ATOMIC_DEC(ATOMIC_T *v)
 | 
			
		||||
{
 | 
			
		||||
	_freertos_ATOMIC_SUB(v, 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _freertos_ATOMIC_ADD_RETURN(ATOMIC_T *v, int i)
 | 
			
		||||
{
 | 
			
		||||
	int temp;
 | 
			
		||||
 | 
			
		||||
	save_and_cli();
 | 
			
		||||
	temp = v->counter;
 | 
			
		||||
	temp += i;
 | 
			
		||||
	v->counter = temp;
 | 
			
		||||
	restore_flags();
 | 
			
		||||
 | 
			
		||||
	return temp;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _freertos_ATOMIC_SUB_RETURN(ATOMIC_T *v, int i)
 | 
			
		||||
{
 | 
			
		||||
	int temp;
 | 
			
		||||
 | 
			
		||||
	save_and_cli();
 | 
			
		||||
	temp = v->counter;
 | 
			
		||||
	temp -= i;
 | 
			
		||||
	v->counter = temp;
 | 
			
		||||
	restore_flags();
 | 
			
		||||
 | 
			
		||||
	return temp;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _freertos_ATOMIC_INC_RETURN(ATOMIC_T *v)
 | 
			
		||||
{
 | 
			
		||||
	return _freertos_ATOMIC_ADD_RETURN(v, 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _freertos_ATOMIC_DEC_RETURN(ATOMIC_T *v)
 | 
			
		||||
{
 | 
			
		||||
	return _freertos_ATOMIC_SUB_RETURN(v, 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static u64 _freertos_modular64(u64 n, u64 base)
 | 
			
		||||
{
 | 
			
		||||
	unsigned int __base = (base);
 | 
			
		||||
	unsigned int __rem;
 | 
			
		||||
 | 
			
		||||
	if (((n) >> 32) == 0) {
 | 
			
		||||
		__rem = (unsigned int)(n) % __base;
 | 
			
		||||
		(n) = (unsigned int)(n) / __base;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
		__rem = __div64_32(&(n), __base);
 | 
			
		||||
	
 | 
			
		||||
	return __rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Refer to ecos bsd tcpip codes */
 | 
			
		||||
static int _freertos_arc4random(void)
 | 
			
		||||
{
 | 
			
		||||
	u32 res = xTaskGetTickCount();
 | 
			
		||||
	static unsigned long seed = 0xDEADB00B;
 | 
			
		||||
	seed = ((seed & 0x007F00FF) << 7) ^
 | 
			
		||||
	    ((seed & 0x0F80FF00) >> 8) ^ // be sure to stir those low bits
 | 
			
		||||
	    (res << 13) ^ (res >> 9);    // using the clock too!
 | 
			
		||||
	return (int)seed;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int _freertos_get_random_bytes(void *buf, size_t len)
 | 
			
		||||
{
 | 
			
		||||
#if 1 //becuase of 4-byte align, we use the follow code style.
 | 
			
		||||
	unsigned int ranbuf;
 | 
			
		||||
	unsigned int *lp;
 | 
			
		||||
	int i, count;
 | 
			
		||||
	count = len / sizeof(unsigned int);
 | 
			
		||||
	lp = (unsigned int *) buf;
 | 
			
		||||
 | 
			
		||||
	for(i = 0; i < count; i ++) {
 | 
			
		||||
		lp[i] = _freertos_arc4random();  
 | 
			
		||||
		len -= sizeof(unsigned int);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if(len > 0) {
 | 
			
		||||
		ranbuf = _freertos_arc4random();
 | 
			
		||||
		_freertos_memcpy(&lp[i], &ranbuf, len);
 | 
			
		||||
	}
 | 
			
		||||
	return 0;
 | 
			
		||||
#else
 | 
			
		||||
	unsigned long ranbuf, *lp;
 | 
			
		||||
	lp = (unsigned long *)buf;
 | 
			
		||||
	while (len > 0) {
 | 
			
		||||
		ranbuf = _freertos_arc4random();
 | 
			
		||||
		*lp++ = ranbuf; //this op need the pointer is 4Byte-align!
 | 
			
		||||
		len -= sizeof(ranbuf);
 | 
			
		||||
	}
 | 
			
		||||
	return 0;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static u32 _freertos_GetFreeHeapSize(void)
 | 
			
		||||
{
 | 
			
		||||
	return (u32)xPortGetFreeHeapSize();
 | 
			
		||||
}
 | 
			
		||||
void *tcm_heap_malloc(int size);
 | 
			
		||||
static int _freertos_create_task(struct task_struct *ptask, const char *name,
 | 
			
		||||
	u32  stack_size, u32 priority, thread_func_t func, void *thctx)
 | 
			
		||||
{
 | 
			
		||||
	thread_func_t task_func = NULL;
 | 
			
		||||
	void *task_ctx = NULL;
 | 
			
		||||
	int ret = 0;
 | 
			
		||||
 | 
			
		||||
	ptask->task_name = name;
 | 
			
		||||
	ptask->blocked = 0;
 | 
			
		||||
	ptask->callback_running = 0;
 | 
			
		||||
	
 | 
			
		||||
	_freertos_init_sema(&ptask->wakeup_sema, 0);
 | 
			
		||||
	_freertos_init_sema(&ptask->terminate_sema, 0);
 | 
			
		||||
	//rtw_init_queue(&wq->work_queue);
 | 
			
		||||
 | 
			
		||||
	if(func){
 | 
			
		||||
		task_func = func;
 | 
			
		||||
		task_ctx = thctx;
 | 
			
		||||
	}
 | 
			
		||||
	//else{
 | 
			
		||||
	//	task_func = freertos_wq_thread_handler;
 | 
			
		||||
	//	task_ctx = wq;
 | 
			
		||||
	//}
 | 
			
		||||
 | 
			
		||||
	priority += tskIDLE_PRIORITY + PRIORITIE_OFFSET;
 | 
			
		||||
 | 
			
		||||
#if CONFIG_USE_TCM_HEAP
 | 
			
		||||
	void *stack_addr = tcm_heap_malloc(stack_size*sizeof(int));
 | 
			
		||||
	//void *stack_addr = rtw_malloc(stack_size*sizeof(int));
 | 
			
		||||
	if(stack_addr == NULL){
 | 
			
		||||
		DBG_INFO("Out of TCM heap in \"%s\" ", ptask->task_name);
 | 
			
		||||
	}
 | 
			
		||||
	ret = xTaskGenericCreate(
 | 
			
		||||
			task_func,
 | 
			
		||||
			(const char *)name,
 | 
			
		||||
			stack_size,
 | 
			
		||||
			task_ctx,
 | 
			
		||||
			priority,
 | 
			
		||||
			&ptask->task,
 | 
			
		||||
			stack_addr,
 | 
			
		||||
			NULL);
 | 
			
		||||
#else							 
 | 
			
		||||
	ret = xTaskCreate(
 | 
			
		||||
			task_func,
 | 
			
		||||
			(const char *)name,
 | 
			
		||||
			stack_size,
 | 
			
		||||
			task_ctx,
 | 
			
		||||
			priority,
 | 
			
		||||
			&ptask->task);
 | 
			
		||||
#endif
 | 
			
		||||
	if(ret != pdPASS){
 | 
			
		||||
		DBG_ERR("Create Task \"%s\" Failed! ret=%d\n", ptask->task_name, ret);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	DBG_TRACE("Create Task \"%s\"\n", ptask->task_name);
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
	
 | 
			
		||||
static void _freertos_delete_task(struct task_struct *ptask)
 | 
			
		||||
{
 | 
			
		||||
	if (!ptask->task){
 | 
			
		||||
		DBG_ERR("_freertos_delete_task(): ptask is NULL!\n");
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ptask->blocked = 1;
 | 
			
		||||
 | 
			
		||||
	_freertos_up_sema(&ptask->wakeup_sema);
 | 
			
		||||
	_freertos_down_sema(&ptask->terminate_sema, TIMER_MAX_DELAY);
 | 
			
		||||
	
 | 
			
		||||
	//rtw_deinit_queue(&wq->work_queue);
 | 
			
		||||
	_freertos_free_sema(&ptask->wakeup_sema);
 | 
			
		||||
	_freertos_free_sema(&ptask->terminate_sema);
 | 
			
		||||
 | 
			
		||||
	ptask->task = 0;
 | 
			
		||||
	
 | 
			
		||||
	DBG_TRACE("Delete Task \"%s\"\n", ptask->task_name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void _freertos_wakeup_task(struct task_struct *ptask)
 | 
			
		||||
{
 | 
			
		||||
	_freertos_up_sema(&ptask->wakeup_sema);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _freertos_thread_enter(char *name)
 | 
			
		||||
{
 | 
			
		||||
	DBG_INFO("\n\rRTKTHREAD %s\n", name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _freertos_thread_exit(void)
 | 
			
		||||
{
 | 
			
		||||
	DBG_INFO("\n\rRTKTHREAD exit %s\n", __FUNCTION__); 
 | 
			
		||||
	vTaskDelete(NULL); 
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
_timerHandle _freertos_timerCreate( const signed char *pcTimerName, 
 | 
			
		||||
							  osdepTickType xTimerPeriodInTicks, 
 | 
			
		||||
							  u32 uxAutoReload, 
 | 
			
		||||
							  void * pvTimerID, 
 | 
			
		||||
							  TIMER_FUN pxCallbackFunction )
 | 
			
		||||
{
 | 
			
		||||
	if(xTimerPeriodInTicks == TIMER_MAX_DELAY) {
 | 
			
		||||
		xTimerPeriodInTicks = portMAX_DELAY;
 | 
			
		||||
	}
 | 
			
		||||
	return xTimerCreate((const char *)pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, pxCallbackFunction);	
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
u32 _freertos_timerDelete( _timerHandle xTimer, 
 | 
			
		||||
							   osdepTickType xBlockTime )
 | 
			
		||||
{
 | 
			
		||||
	return (u32)xTimerDelete(xTimer, xBlockTime);	
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
u32 _freertos_timerIsTimerActive( _timerHandle xTimer )
 | 
			
		||||
{
 | 
			
		||||
	return (u32)xTimerIsTimerActive(xTimer);	
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
u32  _freertos_timerStop( _timerHandle xTimer, 
 | 
			
		||||
							   osdepTickType xBlockTime )
 | 
			
		||||
{
 | 
			
		||||
	return (u32)xTimerStop(xTimer, xBlockTime);	
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
u32  _freertos_timerChangePeriod( _timerHandle xTimer, 
 | 
			
		||||
							   osdepTickType xNewPeriod, 
 | 
			
		||||
							   osdepTickType xBlockTime )
 | 
			
		||||
{
 | 
			
		||||
	if(xNewPeriod == 0)
 | 
			
		||||
		xNewPeriod += 1;
 | 
			
		||||
	return (u32)xTimerChangePeriod(xTimer, xNewPeriod, xBlockTime);	
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void _freertos_acquire_wakelock()
 | 
			
		||||
{
 | 
			
		||||
#if defined(configUSE_WAKELOCK_PMU) && (configUSE_WAKELOCK_PMU == 1)
 | 
			
		||||
    acquire_wakelock(WAKELOCK_WLAN);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void _freertos_release_wakelock()
 | 
			
		||||
{
 | 
			
		||||
#if defined(configUSE_WAKELOCK_PMU) && (configUSE_WAKELOCK_PMU == 1)
 | 
			
		||||
    release_wakelock(WAKELOCK_WLAN);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
u8 _freertos_get_scheduler_state(void)
 | 
			
		||||
{
 | 
			
		||||
	u8 state = xTaskGetSchedulerState();
 | 
			
		||||
	switch(state){
 | 
			
		||||
		case taskSCHEDULER_NOT_STARTED:	state = OS_SCHEDULER_NOT_STARTED;	break;
 | 
			
		||||
		case taskSCHEDULER_RUNNING:		state = OS_SCHEDULER_RUNNING;		break;
 | 
			
		||||
		case taskSCHEDULER_SUSPENDED:	state = OS_SCHEDULER_SUSPENDED;		break;
 | 
			
		||||
	}
 | 
			
		||||
	return state;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
const struct osdep_service_ops osdep_service = {
 | 
			
		||||
	_freertos_malloc,		//rtw_vmalloc
 | 
			
		||||
	_freertos_zmalloc,		//rtw_zvmalloc
 | 
			
		||||
	_freertos_mfree,			//rtw_vmfree
 | 
			
		||||
	_freertos_malloc, //rtw_malloc
 | 
			
		||||
	_freertos_zmalloc, //rtw_zmalloc
 | 
			
		||||
	_freertos_mfree, //rtw_mfree
 | 
			
		||||
	_freertos_memcpy, //rtw_memcpy
 | 
			
		||||
	_freertos_memcmp, //rtw_memcmp
 | 
			
		||||
	_freertos_memset, //rtw_memset
 | 
			
		||||
	_freertos_init_sema, //rtw_init_sema
 | 
			
		||||
	_freertos_free_sema, //rtw_free_sema
 | 
			
		||||
	_freertos_up_sema, //rtw_up_sema
 | 
			
		||||
	_freertos_up_sema_from_isr,//rtw_up_sema_from_isr
 | 
			
		||||
	_freertos_down_sema, //rtw_down_sema
 | 
			
		||||
	_freertos_mutex_init, //rtw_mutex_init
 | 
			
		||||
	_freertos_mutex_free, //rtw_mutex_free
 | 
			
		||||
	_freertos_mutex_get, //rtw_mutex_get
 | 
			
		||||
	_freertos_mutex_get_timeout, //rtw_mutex_get_timeout
 | 
			
		||||
	_freertos_mutex_put, //rtw_mutex_put
 | 
			
		||||
	_freertos_enter_critical,		//rtw_enter_critical
 | 
			
		||||
	_freertos_exit_critical,		//rtw_exit_critical
 | 
			
		||||
	_freertos_enter_critical_from_isr,		//rtw_enter_critical_from_isr
 | 
			
		||||
	_freertos_exit_critical_from_isr,		//rtw_exit_critical_from_isr
 | 
			
		||||
	NULL,		//rtw_enter_critical_bh
 | 
			
		||||
	NULL,		//rtw_exit_critical_bh
 | 
			
		||||
	_freertos_enter_critical_mutex,		//rtw_enter_critical_mutex
 | 
			
		||||
	_freertos_exit_critical_mutex,		//rtw_exit_critical_mutex
 | 
			
		||||
	_freertos_spinlock_init, //rtw_spinlock_init
 | 
			
		||||
	_freertos_spinlock_free, //rtw_spinlock_free
 | 
			
		||||
	_freertos_spinlock, //rtw_spin_lock
 | 
			
		||||
	_freertos_spinunlock, //rtw_spin_unlock
 | 
			
		||||
	_freertos_spinlock_irqsave,	//rtw_spinlock_irqsave
 | 
			
		||||
	_freertos_spinunlock_irqsave,//rtw_spinunlock_irqsave
 | 
			
		||||
	_freertos_init_xqueue,//rtw_init_xqueue
 | 
			
		||||
	_freertos_push_to_xqueue,//rtw_push_to_xqueue
 | 
			
		||||
	_freertos_pop_from_xqueue,//rtw_pop_from_xqueue
 | 
			
		||||
	_freertos_deinit_xqueue,//rtw_deinit_xqueue
 | 
			
		||||
	_freertos_get_current_time, //rtw_get_current_time
 | 
			
		||||
	_freertos_systime_to_ms, //rtw_systime_to_ms
 | 
			
		||||
	_freertos_systime_to_sec, //rtw_systime_to_sec
 | 
			
		||||
	_freertos_ms_to_systime, //rtw_ms_to_systime
 | 
			
		||||
	_freertos_sec_to_systime, //rtw_sec_to_systime
 | 
			
		||||
	_freertos_msleep_os, //rtw_msleep_os
 | 
			
		||||
	_freertos_usleep_os, //rtw_usleep_os
 | 
			
		||||
	_freertos_mdelay_os, //rtw_mdelay_os
 | 
			
		||||
	_freertos_udelay_os, //rtw_udelay_os
 | 
			
		||||
	_freertos_yield_os, //rtw_yield_os
 | 
			
		||||
	
 | 
			
		||||
	_freertos_ATOMIC_SET, //ATOMIC_SET
 | 
			
		||||
	_freertos_ATOMIC_READ, //ATOMIC_READ
 | 
			
		||||
	_freertos_ATOMIC_ADD, //ATOMIC_ADD
 | 
			
		||||
	_freertos_ATOMIC_SUB, //ATOMIC_SUB
 | 
			
		||||
	_freertos_ATOMIC_INC, //ATOMIC_INC
 | 
			
		||||
	_freertos_ATOMIC_DEC, //ATOMIC_DEC
 | 
			
		||||
	_freertos_ATOMIC_ADD_RETURN, //ATOMIC_ADD_RETURN
 | 
			
		||||
	_freertos_ATOMIC_SUB_RETURN, //ATOMIC_SUB_RETURN
 | 
			
		||||
	_freertos_ATOMIC_INC_RETURN, //ATOMIC_INC_RETURN
 | 
			
		||||
	_freertos_ATOMIC_DEC_RETURN, //ATOMIC_DEC_RETURN
 | 
			
		||||
 | 
			
		||||
	_freertos_modular64, //rtw_modular64
 | 
			
		||||
	_freertos_get_random_bytes,			//rtw_get_random_bytes
 | 
			
		||||
	_freertos_GetFreeHeapSize,		//rtw_getFreeHeapSize
 | 
			
		||||
 | 
			
		||||
	_freertos_create_task,		//rtw_create_task
 | 
			
		||||
	_freertos_delete_task,		//rtw_delete_task
 | 
			
		||||
	_freertos_wakeup_task,		//rtw_wakeup_task
 | 
			
		||||
 | 
			
		||||
	_freertos_thread_enter,		//rtw_thread_enter
 | 
			
		||||
	_freertos_thread_exit,		//rtw_thread_exit
 | 
			
		||||
 | 
			
		||||
	_freertos_timerCreate,           //rtw_timerCreate,       
 | 
			
		||||
	_freertos_timerDelete,           //rtw_timerDelete,       
 | 
			
		||||
	_freertos_timerIsTimerActive,    //rtw_timerIsTimerActive,
 | 
			
		||||
	_freertos_timerStop,             //rtw_timerStop,         
 | 
			
		||||
	_freertos_timerChangePeriod,      //rtw_timerChangePeriod  
 | 
			
		||||
 | 
			
		||||
	_freertos_acquire_wakelock,  // rtw_acquire_wakelock
 | 
			
		||||
	_freertos_release_wakelock,  // rtw_release_wakelock
 | 
			
		||||
 | 
			
		||||
	_freertos_get_scheduler_state  // rtw_get_scheduler_state
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										241
									
								
								component/os/freertos/freertos_service.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										241
									
								
								component/os/freertos/freertos_service.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,241 @@
 | 
			
		|||
#ifndef _FREERTOS_SERVICE_H_
 | 
			
		||||
#define _FREERTOS_SERVICE_H_
 | 
			
		||||
 | 
			
		||||
//----- ------------------------------------------------------------------
 | 
			
		||||
// Include Files
 | 
			
		||||
//----- ------------------------------------------------------------------
 | 
			
		||||
//#include "wireless.h"
 | 
			
		||||
#include "dlist.h"
 | 
			
		||||
 | 
			
		||||
// --------------------------------------------
 | 
			
		||||
//	Platform dependent include file
 | 
			
		||||
// --------------------------------------------
 | 
			
		||||
#if defined(CONFIG_PLATFORM_8195A) || defined(CONFIG_PLATFORM_8711B)
 | 
			
		||||
#include "platform/platform_stdlib.h"
 | 
			
		||||
extern VOID RtlUdelayOS(u32 us);
 | 
			
		||||
#else
 | 
			
		||||
// other MCU may use standard library 
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if (defined CONFIG_GSPI_HCI || defined CONFIG_SDIO_HCI) || defined(CONFIG_LX_HCI)
 | 
			
		||||
/* For SPI interface transfer and us delay implementation */
 | 
			
		||||
#if !defined(CONFIG_PLATFORM_8195A) && !defined(CONFIG_PLATFORM_8711B)
 | 
			
		||||
#include <rtwlan_bsp.h>	
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// --------------------------------------------
 | 
			
		||||
//	Platform dependent type define
 | 
			
		||||
// --------------------------------------------
 | 
			
		||||
#if !defined(CONFIG_PLATFORM_8195A) && !defined(CONFIG_PLATFORM_8711B)
 | 
			
		||||
typedef unsigned char		u8;
 | 
			
		||||
typedef unsigned short		u16;
 | 
			
		||||
typedef unsigned int		u32;
 | 
			
		||||
typedef signed char			s8;
 | 
			
		||||
typedef signed short		s16;
 | 
			
		||||
typedef signed int			s32;
 | 
			
		||||
typedef signed long long 	s64;
 | 
			
		||||
typedef unsigned long long	u64;
 | 
			
		||||
typedef unsigned int		uint;
 | 
			
		||||
typedef signed int			sint;
 | 
			
		||||
 | 
			
		||||
#ifndef bool
 | 
			
		||||
typedef int				bool;
 | 
			
		||||
#define  true				1
 | 
			
		||||
#define  false				0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define IN
 | 
			
		||||
#define OUT
 | 
			
		||||
#define VOID void
 | 
			
		||||
#define NDIS_OID uint
 | 
			
		||||
#define NDIS_STATUS uint
 | 
			
		||||
#ifndef	PVOID
 | 
			
		||||
typedef void *		PVOID;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
typedef unsigned int		__kernel_size_t;
 | 
			
		||||
typedef int			__kernel_ssize_t;
 | 
			
		||||
typedef	__kernel_size_t		SIZE_T;	
 | 
			
		||||
typedef	__kernel_ssize_t	SSIZE_T;
 | 
			
		||||
 | 
			
		||||
#endif //CONFIG_PLATFORM_8195A
 | 
			
		||||
 | 
			
		||||
#define FIELD_OFFSET(s,field)	((SSIZE_T)&((s*)(0))->field)
 | 
			
		||||
 | 
			
		||||
// os types
 | 
			
		||||
typedef char			osdepCHAR;
 | 
			
		||||
typedef float			osdepFLOAT;
 | 
			
		||||
typedef double			osdepDOUBLE;
 | 
			
		||||
typedef long			osdepLONG;
 | 
			
		||||
typedef short			osdepSHORT;
 | 
			
		||||
typedef unsigned long	osdepSTACK_TYPE;
 | 
			
		||||
typedef long			osdepBASE_TYPE;
 | 
			
		||||
typedef unsigned long	osdepTickType;
 | 
			
		||||
 | 
			
		||||
typedef void*	_timerHandle;
 | 
			
		||||
typedef void*	_sema;
 | 
			
		||||
typedef void*	_mutex;
 | 
			
		||||
typedef void*	_lock;
 | 
			
		||||
typedef void*	_queueHandle;
 | 
			
		||||
typedef void*	_xqueue;
 | 
			
		||||
typedef struct timer_list	_timer;
 | 
			
		||||
 | 
			
		||||
typedef	struct sk_buff		_pkt;
 | 
			
		||||
typedef unsigned char		_buffer;
 | 
			
		||||
 | 
			
		||||
#ifndef __LIST_H
 | 
			
		||||
#warning "DLIST_NOT_DEFINE!!!!!!"
 | 
			
		||||
struct list_head {
 | 
			
		||||
	struct list_head *next, *prev;
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
struct	__queue	{
 | 
			
		||||
	struct	list_head	queue;
 | 
			
		||||
	_lock			lock;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct	__queue		_queue;
 | 
			
		||||
typedef struct	list_head	_list;
 | 
			
		||||
typedef unsigned long		_irqL;
 | 
			
		||||
 | 
			
		||||
typedef void*			_thread_hdl_;
 | 
			
		||||
typedef void			thread_return;
 | 
			
		||||
typedef void*			thread_context;
 | 
			
		||||
 | 
			
		||||
#define ATOMIC_T atomic_t
 | 
			
		||||
#define HZ configTICK_RATE_HZ
 | 
			
		||||
 | 
			
		||||
#define   KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
 | 
			
		||||
/* emulate a modern version */
 | 
			
		||||
#define LINUX_VERSION_CODE KERNEL_VERSION(2, 6, 17)
 | 
			
		||||
 | 
			
		||||
static __inline _list *get_next(_list	*list)
 | 
			
		||||
{
 | 
			
		||||
	return list->next;
 | 
			
		||||
}	
 | 
			
		||||
 | 
			
		||||
static __inline _list	*get_list_head(_queue	*queue)
 | 
			
		||||
{
 | 
			
		||||
	return (&(queue->queue));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define LIST_CONTAINOR(ptr, type, member) \
 | 
			
		||||
	((type *)((char *)(ptr)-(SIZE_T)((char *)&((type *)ptr)->member - (char *)ptr)))
 | 
			
		||||
//#define container_of(p,t,n) (t*)((p)-&(((t*)0)->n))
 | 
			
		||||
#define container_of(ptr, type, member) \
 | 
			
		||||
			((type *)((char *)(ptr)-(SIZE_T)(&((type *)0)->member)))
 | 
			
		||||
#define TASK_PRORITY_LOW  				1
 | 
			
		||||
#define TASK_PRORITY_MIDDLE   			2
 | 
			
		||||
#define TASK_PRORITY_HIGH    			3
 | 
			
		||||
#define TASK_PRORITY_SUPER    			4
 | 
			
		||||
 | 
			
		||||
#define TIMER_MAX_DELAY    				0xFFFFFFFF
 | 
			
		||||
 | 
			
		||||
void save_and_cli(void);
 | 
			
		||||
void restore_flags(void);
 | 
			
		||||
void cli(void);
 | 
			
		||||
 | 
			
		||||
//----- ------------------------------------------------------------------
 | 
			
		||||
// Common Definition
 | 
			
		||||
//----- ------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
#define __init
 | 
			
		||||
#define __exit
 | 
			
		||||
#define __devinit
 | 
			
		||||
#define __devexit
 | 
			
		||||
 | 
			
		||||
#define KERN_ERR
 | 
			
		||||
#define KERN_INFO
 | 
			
		||||
#define KERN_NOTICE
 | 
			
		||||
 | 
			
		||||
#define GFP_KERNEL			1
 | 
			
		||||
#define GFP_ATOMIC			1
 | 
			
		||||
 | 
			
		||||
#define SET_MODULE_OWNER(some_struct)	do { } while (0)
 | 
			
		||||
#define SET_NETDEV_DEV(dev, obj)	do { } while (0)
 | 
			
		||||
#define register_netdev(dev)		(0)
 | 
			
		||||
#define unregister_netdev(dev)		do { } while (0)
 | 
			
		||||
#define netif_queue_stopped(dev)	(0)
 | 
			
		||||
#define netif_wake_queue(dev)		do { } while (0)
 | 
			
		||||
#define printk				printf
 | 
			
		||||
 | 
			
		||||
#define DBG_ERR(fmt, args...)		printf("\n\r[%s] " fmt, __FUNCTION__, ## args)
 | 
			
		||||
#if WLAN_INTF_DBG
 | 
			
		||||
#define DBG_TRACE(fmt, args...)		printf("\n\r[%s] " fmt, __FUNCTION__, ## args)
 | 
			
		||||
#define DBG_INFO(fmt, args...)		printf("\n\r[%s] " fmt, __FUNCTION__, ## args)
 | 
			
		||||
#else
 | 
			
		||||
#define DBG_TRACE(fmt, args...)
 | 
			
		||||
#define DBG_INFO(fmt, args...)
 | 
			
		||||
#endif
 | 
			
		||||
#define HALT()				do { cli(); for(;;);} while(0)
 | 
			
		||||
#define ASSERT(x)			do { \
 | 
			
		||||
						if((x) == 0) \
 | 
			
		||||
							printf("\n\rAssert(" #x ") failed on line %d in file %s", __LINE__, __FILE__); \
 | 
			
		||||
						HALT(); \
 | 
			
		||||
					} while(0)
 | 
			
		||||
 | 
			
		||||
#undef DBG_ASSERT
 | 
			
		||||
#define DBG_ASSERT(x, msg)		do { \
 | 
			
		||||
						if((x) == 0) \
 | 
			
		||||
							printf("\n\r%s, Assert(" #x ") failed on line %d in file %s", msg, __LINE__, __FILE__); \
 | 
			
		||||
					} while(0)
 | 
			
		||||
 | 
			
		||||
//----- ------------------------------------------------------------------
 | 
			
		||||
// Atomic Operation
 | 
			
		||||
//----- ------------------------------------------------------------------
 | 
			
		||||
#if !defined(CONFIG_PLATFORM_8195A) && !defined(CONFIG_PLATFORM_8711B)	// for 8195A, it is defined in ..system../basic_types.h
 | 
			
		||||
typedef struct { volatile int counter; } atomic_t;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * atomic_read - read atomic variable
 | 
			
		||||
 * @v: pointer of type atomic_t
 | 
			
		||||
 *
 | 
			
		||||
 * Atomically reads the value of @v.  Note that the guaranteed
 | 
			
		||||
 * useful range of an atomic_t is only 24 bits.
 | 
			
		||||
 */
 | 
			
		||||
#define atomic_read(v)  ((v)->counter)
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * atomic_set - set atomic variable
 | 
			
		||||
 * @v: pointer of type atomic_t
 | 
			
		||||
 * @i: required value
 | 
			
		||||
 *
 | 
			
		||||
 * Atomically sets the value of @v to @i.  Note that the guaranteed
 | 
			
		||||
 * useful range of an atomic_t is only 24 bits.
 | 
			
		||||
 */
 | 
			
		||||
#define atomic_set(v,i) ((v)->counter = (i))
 | 
			
		||||
 | 
			
		||||
 /*
 | 
			
		||||
  *      These inlines deal with timer wrapping correctly. You are 
 | 
			
		||||
  *      strongly encouraged to use them
 | 
			
		||||
  *      1. Because people otherwise forget
 | 
			
		||||
  *      2. Because if the timer wrap changes in future you wont have to
 | 
			
		||||
  *         alter your driver code.
 | 
			
		||||
  *
 | 
			
		||||
  * time_after(a,b) returns true if the time a is after time b.
 | 
			
		||||
  *
 | 
			
		||||
  * Do this with "<0" and ">=0" to only test the sign of the result. A
 | 
			
		||||
  * good compiler would generate better code (and a really good compiler
 | 
			
		||||
  * wouldn't care). Gcc is currently neither.
 | 
			
		||||
  */
 | 
			
		||||
 #define time_after(a,b)	((long)(b) - (long)(a) < 0)
 | 
			
		||||
 #define time_before(a,b)	time_after(b,a)
 | 
			
		||||
  
 | 
			
		||||
 #define time_after_eq(a,b)	((long)(a) - (long)(b) >= 0)
 | 
			
		||||
 #define time_before_eq(a,b)	time_after_eq(b,a)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern void	rtw_init_listhead(_list *list);
 | 
			
		||||
extern u32	rtw_is_list_empty(_list *phead);
 | 
			
		||||
extern void	rtw_list_insert_head(_list *plist, _list *phead);
 | 
			
		||||
extern void	rtw_list_insert_tail(_list *plist, _list *phead);
 | 
			
		||||
extern void	rtw_list_delete(_list *plist);
 | 
			
		||||
 | 
			
		||||
#endif /* _FREERTOS_SERVICE_H_ */
 | 
			
		||||
							
								
								
									
										394
									
								
								component/os/freertos/freertos_v8.1.2/License/license.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										394
									
								
								component/os/freertos/freertos_v8.1.2/License/license.txt
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,394 @@
 | 
			
		|||
The FreeRTOS source code is licensed by a *modified* GNU General Public
 | 
			
		||||
License (GPL).  The modification is provided in the form of an exception.
 | 
			
		||||
 | 
			
		||||
NOTE: The modification to the GPL is included to allow you to distribute a
 | 
			
		||||
combined work that includes FreeRTOS without being obliged to provide the source
 | 
			
		||||
code for proprietary components outside of the FreeRTOS kernel.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
The FreeRTOS GPL Exception Text:
 | 
			
		||||
 | 
			
		||||
Any FreeRTOS source code, whether modified or in it's original release form,
 | 
			
		||||
or whether in whole or in part, can only be distributed by you under the terms
 | 
			
		||||
of the GNU General Public License plus this exception. An independent module is
 | 
			
		||||
a module which is not derived from or based on FreeRTOS.
 | 
			
		||||
 | 
			
		||||
Clause 1:
 | 
			
		||||
 | 
			
		||||
Linking FreeRTOS statically or dynamically with other modules is making a
 | 
			
		||||
combined work based on FreeRTOS. Thus, the terms and conditions of the GNU
 | 
			
		||||
General Public License cover the whole combination.
 | 
			
		||||
 | 
			
		||||
As a special exception, the copyright holder of FreeRTOS gives you permission
 | 
			
		||||
to link FreeRTOS with independent modules that communicate with FreeRTOS
 | 
			
		||||
solely through the FreeRTOS API interface, regardless of the license terms of
 | 
			
		||||
these independent modules, and to copy and distribute the resulting combined
 | 
			
		||||
work under terms of your choice, provided that
 | 
			
		||||
 | 
			
		||||
  + Every copy of the combined work is accompanied by a written statement that
 | 
			
		||||
  details to the recipient the version of FreeRTOS used and an offer by yourself
 | 
			
		||||
  to provide the FreeRTOS source code (including any modifications you may have
 | 
			
		||||
  made) should the recipient request it.
 | 
			
		||||
 | 
			
		||||
  + The combined work is not itself an RTOS, scheduler, kernel or related product.
 | 
			
		||||
 | 
			
		||||
  + The independent modules add significant and primary functionality to FreeRTOS
 | 
			
		||||
  and do not merely extend the existing functionality already present in FreeRTOS.
 | 
			
		||||
 | 
			
		||||
Clause 2:
 | 
			
		||||
 | 
			
		||||
FreeRTOS may not be used for any competitive or comparative purpose, including the
 | 
			
		||||
publication of any form of run time or compile time metric, without the express
 | 
			
		||||
permission of Real Time Engineers Ltd. (this is the norm within the industry and
 | 
			
		||||
is intended to ensure information accuracy).
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
--------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
The standard GPL exception text:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		    GNU GENERAL PUBLIC LICENSE
 | 
			
		||||
		       Version 2, June 1991
 | 
			
		||||
 | 
			
		||||
 Copyright (C) 1989, 1991 Free Software Foundation, Inc.
 | 
			
		||||
                       59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 Everyone is permitted to copy and distribute verbatim copies
 | 
			
		||||
 of this license document, but changing it is not allowed.
 | 
			
		||||
 | 
			
		||||
			    Preamble
 | 
			
		||||
 | 
			
		||||
  The licenses for most software are designed to take away your
 | 
			
		||||
freedom to share and change it.  By contrast, the GNU General Public
 | 
			
		||||
License is intended to guarantee your freedom to share and change free
 | 
			
		||||
software--to make sure the software is free for all its users.  This
 | 
			
		||||
General Public License applies to most of the Free Software
 | 
			
		||||
Foundation's software and to any other program whose authors commit to
 | 
			
		||||
using it.  (Some other Free Software Foundation software is covered by
 | 
			
		||||
the GNU Library General Public License instead.)  You can apply it to
 | 
			
		||||
your programs, too.
 | 
			
		||||
 | 
			
		||||
  When we speak of free software, we are referring to freedom, not
 | 
			
		||||
price.  Our General Public Licenses are designed to make sure that you
 | 
			
		||||
have the freedom to distribute copies of free software (and charge for
 | 
			
		||||
this service if you wish), that you receive source code or can get it
 | 
			
		||||
if you want it, that you can change the software or use pieces of it
 | 
			
		||||
in new free programs; and that you know you can do these things.
 | 
			
		||||
 | 
			
		||||
  To protect your rights, we need to make restrictions that forbid
 | 
			
		||||
anyone to deny you these rights or to ask you to surrender the rights.
 | 
			
		||||
These restrictions translate to certain responsibilities for you if you
 | 
			
		||||
distribute copies of the software, or if you modify it.
 | 
			
		||||
 | 
			
		||||
  For example, if you distribute copies of such a program, whether
 | 
			
		||||
gratis or for a fee, you must give the recipients all the rights that
 | 
			
		||||
you have.  You must make sure that they, too, receive or can get the
 | 
			
		||||
source code.  And you must show them these terms so they know their
 | 
			
		||||
rights.
 | 
			
		||||
 | 
			
		||||
  We protect your rights with two steps: (1) copyright the software, and
 | 
			
		||||
(2) offer you this license which gives you legal permission to copy,
 | 
			
		||||
distribute and/or modify the software.
 | 
			
		||||
 | 
			
		||||
  Also, for each author's protection and ours, we want to make certain
 | 
			
		||||
that everyone understands that there is no warranty for this free
 | 
			
		||||
software.  If the software is modified by someone else and passed on, we
 | 
			
		||||
want its recipients to know that what they have is not the original, so
 | 
			
		||||
that any problems introduced by others will not reflect on the original
 | 
			
		||||
authors' reputations.
 | 
			
		||||
 | 
			
		||||
  Finally, any free program is threatened constantly by software
 | 
			
		||||
patents.  We wish to avoid the danger that redistributors of a free
 | 
			
		||||
program will individually obtain patent licenses, in effect making the
 | 
			
		||||
program proprietary.  To prevent this, we have made it clear that any
 | 
			
		||||
patent must be licensed for everyone's free use or not licensed at all.
 | 
			
		||||
 | 
			
		||||
  The precise terms and conditions for copying, distribution and
 | 
			
		||||
modification follow.
 | 
			
		||||
 | 
			
		||||
		    GNU GENERAL PUBLIC LICENSE
 | 
			
		||||
   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
 | 
			
		||||
 | 
			
		||||
  0. This License applies to any program or other work which contains
 | 
			
		||||
a notice placed by the copyright holder saying it may be distributed
 | 
			
		||||
under the terms of this General Public License.  The "Program", below,
 | 
			
		||||
refers to any such program or work, and a "work based on the Program"
 | 
			
		||||
means either the Program or any derivative work under copyright law:
 | 
			
		||||
that is to say, a work containing the Program or a portion of it,
 | 
			
		||||
either verbatim or with modifications and/or translated into another
 | 
			
		||||
language.  (Hereinafter, translation is included without limitation in
 | 
			
		||||
the term "modification".)  Each licensee is addressed as "you".
 | 
			
		||||
 | 
			
		||||
Activities other than copying, distribution and modification are not
 | 
			
		||||
covered by this License; they are outside its scope.  The act of
 | 
			
		||||
running the Program is not restricted, and the output from the Program
 | 
			
		||||
is covered only if its contents constitute a work based on the
 | 
			
		||||
Program (independent of having been made by running the Program).
 | 
			
		||||
Whether that is true depends on what the Program does.
 | 
			
		||||
 | 
			
		||||
  1. You may copy and distribute verbatim copies of the Program's
 | 
			
		||||
source code as you receive it, in any medium, provided that you
 | 
			
		||||
conspicuously and appropriately publish on each copy an appropriate
 | 
			
		||||
copyright notice and disclaimer of warranty; keep intact all the
 | 
			
		||||
notices that refer to this License and to the absence of any warranty;
 | 
			
		||||
and give any other recipients of the Program a copy of this License
 | 
			
		||||
along with the Program.
 | 
			
		||||
 | 
			
		||||
You may charge a fee for the physical act of transferring a copy, and
 | 
			
		||||
you may at your option offer warranty protection in exchange for a fee.
 | 
			
		||||
 | 
			
		||||
  2. You may modify your copy or copies of the Program or any portion
 | 
			
		||||
of it, thus forming a work based on the Program, and copy and
 | 
			
		||||
distribute such modifications or work under the terms of Section 1
 | 
			
		||||
above, provided that you also meet all of these conditions:
 | 
			
		||||
 | 
			
		||||
    a) You must cause the modified files to carry prominent notices
 | 
			
		||||
    stating that you changed the files and the date of any change.
 | 
			
		||||
 | 
			
		||||
    b) You must cause any work that you distribute or publish, that in
 | 
			
		||||
    whole or in part contains or is derived from the Program or any
 | 
			
		||||
    part thereof, to be licensed as a whole at no charge to all third
 | 
			
		||||
    parties under the terms of this License.
 | 
			
		||||
 | 
			
		||||
    c) If the modified program normally reads commands interactively
 | 
			
		||||
    when run, you must cause it, when started running for such
 | 
			
		||||
    interactive use in the most ordinary way, to print or display an
 | 
			
		||||
    announcement including an appropriate copyright notice and a
 | 
			
		||||
    notice that there is no warranty (or else, saying that you provide
 | 
			
		||||
    a warranty) and that users may redistribute the program under
 | 
			
		||||
    these conditions, and telling the user how to view a copy of this
 | 
			
		||||
    License.  (Exception: if the Program itself is interactive but
 | 
			
		||||
    does not normally print such an announcement, your work based on
 | 
			
		||||
    the Program is not required to print an announcement.)
 | 
			
		||||
 | 
			
		||||
These requirements apply to the modified work as a whole.  If
 | 
			
		||||
identifiable sections of that work are not derived from the Program,
 | 
			
		||||
and can be reasonably considered independent and separate works in
 | 
			
		||||
themselves, then this License, and its terms, do not apply to those
 | 
			
		||||
sections when you distribute them as separate works.  But when you
 | 
			
		||||
distribute the same sections as part of a whole which is a work based
 | 
			
		||||
on the Program, the distribution of the whole must be on the terms of
 | 
			
		||||
this License, whose permissions for other licensees extend to the
 | 
			
		||||
entire whole, and thus to each and every part regardless of who wrote it.
 | 
			
		||||
 | 
			
		||||
Thus, it is not the intent of this section to claim rights or contest
 | 
			
		||||
your rights to work written entirely by you; rather, the intent is to
 | 
			
		||||
exercise the right to control the distribution of derivative or
 | 
			
		||||
collective works based on the Program.
 | 
			
		||||
 | 
			
		||||
In addition, mere aggregation of another work not based on the Program
 | 
			
		||||
with the Program (or with a work based on the Program) on a volume of
 | 
			
		||||
a storage or distribution medium does not bring the other work under
 | 
			
		||||
the scope of this License.
 | 
			
		||||
 | 
			
		||||
  3. You may copy and distribute the Program (or a work based on it,
 | 
			
		||||
under Section 2) in object code or executable form under the terms of
 | 
			
		||||
Sections 1 and 2 above provided that you also do one of the following:
 | 
			
		||||
 | 
			
		||||
    a) Accompany it with the complete corresponding machine-readable
 | 
			
		||||
    source code, which must be distributed under the terms of Sections
 | 
			
		||||
    1 and 2 above on a medium customarily used for software interchange; or,
 | 
			
		||||
 | 
			
		||||
    b) Accompany it with a written offer, valid for at least three
 | 
			
		||||
    years, to give any third party, for a charge no more than your
 | 
			
		||||
    cost of physically performing source distribution, a complete
 | 
			
		||||
    machine-readable copy of the corresponding source code, to be
 | 
			
		||||
    distributed under the terms of Sections 1 and 2 above on a medium
 | 
			
		||||
    customarily used for software interchange; or,
 | 
			
		||||
 | 
			
		||||
    c) Accompany it with the information you received as to the offer
 | 
			
		||||
    to distribute corresponding source code.  (This alternative is
 | 
			
		||||
    allowed only for noncommercial distribution and only if you
 | 
			
		||||
    received the program in object code or executable form with such
 | 
			
		||||
    an offer, in accord with Subsection b above.)
 | 
			
		||||
 | 
			
		||||
The source code for a work means the preferred form of the work for
 | 
			
		||||
making modifications to it.  For an executable work, complete source
 | 
			
		||||
code means all the source code for all modules it contains, plus any
 | 
			
		||||
associated interface definition files, plus the scripts used to
 | 
			
		||||
control compilation and installation of the executable.  However, as a
 | 
			
		||||
special exception, the source code distributed need not include
 | 
			
		||||
anything that is normally distributed (in either source or binary
 | 
			
		||||
form) with the major components (compiler, kernel, and so on) of the
 | 
			
		||||
operating system on which the executable runs, unless that component
 | 
			
		||||
itself accompanies the executable.
 | 
			
		||||
 | 
			
		||||
If distribution of executable or object code is made by offering
 | 
			
		||||
access to copy from a designated place, then offering equivalent
 | 
			
		||||
access to copy the source code from the same place counts as
 | 
			
		||||
distribution of the source code, even though third parties are not
 | 
			
		||||
compelled to copy the source along with the object code.
 | 
			
		||||
 | 
			
		||||
  4. You may not copy, modify, sublicense, or distribute the Program
 | 
			
		||||
except as expressly provided under this License.  Any attempt
 | 
			
		||||
otherwise to copy, modify, sublicense or distribute the Program is
 | 
			
		||||
void, and will automatically terminate your rights under this License.
 | 
			
		||||
However, parties who have received copies, or rights, from you under
 | 
			
		||||
this License will not have their licenses terminated so long as such
 | 
			
		||||
parties remain in full compliance.
 | 
			
		||||
 | 
			
		||||
  5. You are not required to accept this License, since you have not
 | 
			
		||||
signed it.  However, nothing else grants you permission to modify or
 | 
			
		||||
distribute the Program or its derivative works.  These actions are
 | 
			
		||||
prohibited by law if you do not accept this License.  Therefore, by
 | 
			
		||||
modifying or distributing the Program (or any work based on the
 | 
			
		||||
Program), you indicate your acceptance of this License to do so, and
 | 
			
		||||
all its terms and conditions for copying, distributing or modifying
 | 
			
		||||
the Program or works based on it.
 | 
			
		||||
 | 
			
		||||
  6. Each time you redistribute the Program (or any work based on the
 | 
			
		||||
Program), the recipient automatically receives a license from the
 | 
			
		||||
original licensor to copy, distribute or modify the Program subject to
 | 
			
		||||
these terms and conditions.  You may not impose any further
 | 
			
		||||
restrictions on the recipients' exercise of the rights granted herein.
 | 
			
		||||
You are not responsible for enforcing compliance by third parties to
 | 
			
		||||
this License.
 | 
			
		||||
 | 
			
		||||
  7. If, as a consequence of a court judgment or allegation of patent
 | 
			
		||||
infringement or for any other reason (not limited to patent issues),
 | 
			
		||||
conditions are imposed on you (whether by court order, agreement or
 | 
			
		||||
otherwise) that contradict the conditions of this License, they do not
 | 
			
		||||
excuse you from the conditions of this License.  If you cannot
 | 
			
		||||
distribute so as to satisfy simultaneously your obligations under this
 | 
			
		||||
License and any other pertinent obligations, then as a consequence you
 | 
			
		||||
may not distribute the Program at all.  For example, if a patent
 | 
			
		||||
license would not permit royalty-free redistribution of the Program by
 | 
			
		||||
all those who receive copies directly or indirectly through you, then
 | 
			
		||||
the only way you could satisfy both it and this License would be to
 | 
			
		||||
refrain entirely from distribution of the Program.
 | 
			
		||||
 | 
			
		||||
If any portion of this section is held invalid or unenforceable under
 | 
			
		||||
any particular circumstance, the balance of the section is intended to
 | 
			
		||||
apply and the section as a whole is intended to apply in other
 | 
			
		||||
circumstances.
 | 
			
		||||
 | 
			
		||||
It is not the purpose of this section to induce you to infringe any
 | 
			
		||||
patents or other property right claims or to contest validity of any
 | 
			
		||||
such claims; this section has the sole purpose of protecting the
 | 
			
		||||
integrity of the free software distribution system, which is
 | 
			
		||||
implemented by public license practices.  Many people have made
 | 
			
		||||
generous contributions to the wide range of software distributed
 | 
			
		||||
through that system in reliance on consistent application of that
 | 
			
		||||
system; it is up to the author/donor to decide if he or she is willing
 | 
			
		||||
to distribute software through any other system and a licensee cannot
 | 
			
		||||
impose that choice.
 | 
			
		||||
 | 
			
		||||
This section is intended to make thoroughly clear what is believed to
 | 
			
		||||
be a consequence of the rest of this License.
 | 
			
		||||
 | 
			
		||||
  8. If the distribution and/or use of the Program is restricted in
 | 
			
		||||
certain countries either by patents or by copyrighted interfaces, the
 | 
			
		||||
original copyright holder who places the Program under this License
 | 
			
		||||
may add an explicit geographical distribution limitation excluding
 | 
			
		||||
those countries, so that distribution is permitted only in or among
 | 
			
		||||
countries not thus excluded.  In such case, this License incorporates
 | 
			
		||||
the limitation as if written in the body of this License.
 | 
			
		||||
 | 
			
		||||
  9. The Free Software Foundation may publish revised and/or new versions
 | 
			
		||||
of the General Public License from time to time.  Such new versions will
 | 
			
		||||
be similar in spirit to the present version, but may differ in detail to
 | 
			
		||||
address new problems or concerns.
 | 
			
		||||
 | 
			
		||||
Each version is given a distinguishing version number.  If the Program
 | 
			
		||||
specifies a version number of this License which applies to it and "any
 | 
			
		||||
later version", you have the option of following the terms and conditions
 | 
			
		||||
either of that version or of any later version published by the Free
 | 
			
		||||
Software Foundation.  If the Program does not specify a version number of
 | 
			
		||||
this License, you may choose any version ever published by the Free Software
 | 
			
		||||
Foundation.
 | 
			
		||||
 | 
			
		||||
  10. If you wish to incorporate parts of the Program into other free
 | 
			
		||||
programs whose distribution conditions are different, write to the author
 | 
			
		||||
to ask for permission.  For software which is copyrighted by the Free
 | 
			
		||||
Software Foundation, write to the Free Software Foundation; we sometimes
 | 
			
		||||
make exceptions for this.  Our decision will be guided by the two goals
 | 
			
		||||
of preserving the free status of all derivatives of our free software and
 | 
			
		||||
of promoting the sharing and reuse of software generally.
 | 
			
		||||
 | 
			
		||||
			    NO WARRANTY
 | 
			
		||||
 | 
			
		||||
  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
 | 
			
		||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
 | 
			
		||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
 | 
			
		||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
 | 
			
		||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 | 
			
		||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
 | 
			
		||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
 | 
			
		||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
 | 
			
		||||
REPAIR OR CORRECTION.
 | 
			
		||||
 | 
			
		||||
  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
 | 
			
		||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
 | 
			
		||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
 | 
			
		||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
 | 
			
		||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
 | 
			
		||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
 | 
			
		||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
 | 
			
		||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
 | 
			
		||||
POSSIBILITY OF SUCH DAMAGES.
 | 
			
		||||
 | 
			
		||||
		     END OF TERMS AND CONDITIONS
 | 
			
		||||
 | 
			
		||||
	    How to Apply These Terms to Your New Programs
 | 
			
		||||
 | 
			
		||||
  If you develop a new program, and you want it to be of the greatest
 | 
			
		||||
possible use to the public, the best way to achieve this is to make it
 | 
			
		||||
free software which everyone can redistribute and change under these terms.
 | 
			
		||||
 | 
			
		||||
  To do so, attach the following notices to the program.  It is safest
 | 
			
		||||
to attach them to the start of each source file to most effectively
 | 
			
		||||
convey the exclusion of warranty; and each file should have at least
 | 
			
		||||
the "copyright" line and a pointer to where the full notice is found.
 | 
			
		||||
 | 
			
		||||
    <one line to give the program's name and a brief idea of what it does.>
 | 
			
		||||
    Copyright (C) <year>  <name of author>
 | 
			
		||||
 | 
			
		||||
    This program is free software; you can redistribute it and/or modify
 | 
			
		||||
    it under the terms of the GNU General Public License** as published by
 | 
			
		||||
    the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
    (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
    This program is distributed in the hope that it will be useful,
 | 
			
		||||
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
    GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
    You should have received a copy of the GNU General Public License
 | 
			
		||||
    along with this program; if not, write to the Free Software
 | 
			
		||||
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Also add information on how to contact you by electronic and paper mail.
 | 
			
		||||
 | 
			
		||||
If the program is interactive, make it output a short notice like this
 | 
			
		||||
when it starts in an interactive mode:
 | 
			
		||||
 | 
			
		||||
    Gnomovision version 69, Copyright (C) year name of author
 | 
			
		||||
    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
 | 
			
		||||
    This is free software, and you are welcome to redistribute it
 | 
			
		||||
    under certain conditions; type `show c' for details.
 | 
			
		||||
 | 
			
		||||
The hypothetical commands `show w' and `show c' should show the appropriate
 | 
			
		||||
parts of the General Public License.  Of course, the commands you use may
 | 
			
		||||
be called something other than `show w' and `show c'; they could even be
 | 
			
		||||
mouse-clicks or menu items--whatever suits your program.
 | 
			
		||||
 | 
			
		||||
You should also get your employer (if you work as a programmer) or your
 | 
			
		||||
school, if any, to sign a "copyright disclaimer" for the program, if
 | 
			
		||||
necessary.  Here is a sample; alter the names:
 | 
			
		||||
 | 
			
		||||
  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
 | 
			
		||||
  `Gnomovision' (which makes passes at compilers) written by James Hacker.
 | 
			
		||||
 | 
			
		||||
  <signature of Ty Coon>, 1 April 1989
 | 
			
		||||
  Ty Coon, President of Vice
 | 
			
		||||
 | 
			
		||||
This General Public License does not permit incorporating your program into
 | 
			
		||||
proprietary programs.  If your program is a subroutine library, you may
 | 
			
		||||
consider it more useful to permit linking proprietary applications with the
 | 
			
		||||
library.  If this is what you want to do, use the GNU Library General
 | 
			
		||||
Public License instead of this License.
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										386
									
								
								component/os/freertos/freertos_v8.1.2/Source/croutine.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										386
									
								
								component/os/freertos/freertos_v8.1.2/Source/croutine.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,386 @@
 | 
			
		|||
/*
 | 
			
		||||
    FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd.
 | 
			
		||||
    All rights reserved
 | 
			
		||||
 | 
			
		||||
    VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
 | 
			
		||||
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    FreeRTOS provides completely free yet professionally developed,    *
 | 
			
		||||
     *    robust, strictly quality controlled, supported, and cross          *
 | 
			
		||||
     *    platform software that has become a de facto standard.             *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    Help yourself get started quickly and support the FreeRTOS         *
 | 
			
		||||
     *    project by purchasing a FreeRTOS tutorial book, reference          *
 | 
			
		||||
     *    manual, or both from: http://www.FreeRTOS.org/Documentation        *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    Thank you!                                                         *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
 | 
			
		||||
    This file is part of the FreeRTOS distribution.
 | 
			
		||||
 | 
			
		||||
    FreeRTOS is free software; you can redistribute it and/or modify it under
 | 
			
		||||
    the terms of the GNU General Public License (version 2) as published by the
 | 
			
		||||
    Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
 | 
			
		||||
 | 
			
		||||
    >>!   NOTE: The modification to the GPL is included to allow you to     !<<
 | 
			
		||||
    >>!   distribute a combined work that includes FreeRTOS without being   !<<
 | 
			
		||||
    >>!   obliged to provide the source code for proprietary components     !<<
 | 
			
		||||
    >>!   outside of the FreeRTOS kernel.                                   !<<
 | 
			
		||||
 | 
			
		||||
    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
 | 
			
		||||
    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
    FOR A PARTICULAR PURPOSE.  Full license text is available from the following
 | 
			
		||||
    link: http://www.freertos.org/a00114.html
 | 
			
		||||
 | 
			
		||||
    1 tab == 4 spaces!
 | 
			
		||||
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    Having a problem?  Start by reading the FAQ "My application does   *
 | 
			
		||||
     *    not run, what could be wrong?"                                     *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    http://www.FreeRTOS.org/FAQHelp.html                               *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
 | 
			
		||||
    http://www.FreeRTOS.org - Documentation, books, training, latest versions,
 | 
			
		||||
    license and Real Time Engineers Ltd. contact details.
 | 
			
		||||
 | 
			
		||||
    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
 | 
			
		||||
    including FreeRTOS+Trace - an indispensable productivity tool, a DOS
 | 
			
		||||
    compatible FAT file system, and our tiny thread aware UDP/IP stack.
 | 
			
		||||
 | 
			
		||||
    http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
 | 
			
		||||
    Integrity Systems to sell under the OpenRTOS brand.  Low cost OpenRTOS
 | 
			
		||||
    licenses offer ticketed support, indemnification and middleware.
 | 
			
		||||
 | 
			
		||||
    http://www.SafeRTOS.com - High Integrity Systems also provide a safety
 | 
			
		||||
    engineered and independently SIL3 certified version for use in safety and
 | 
			
		||||
    mission critical applications that require provable dependability.
 | 
			
		||||
 | 
			
		||||
    1 tab == 4 spaces!
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include "FreeRTOS.h"
 | 
			
		||||
#include "task.h"
 | 
			
		||||
#include "croutine.h"
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Some kernel aware debuggers require data to be viewed to be global, rather
 | 
			
		||||
 * than file scope.
 | 
			
		||||
 */
 | 
			
		||||
#ifdef portREMOVE_STATIC_QUALIFIER
 | 
			
		||||
	#define static
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Lists for ready and blocked co-routines. --------------------*/
 | 
			
		||||
static List_t pxReadyCoRoutineLists[ configMAX_CO_ROUTINE_PRIORITIES ];	/*< Prioritised ready co-routines. */
 | 
			
		||||
static List_t xDelayedCoRoutineList1;									/*< Delayed co-routines. */
 | 
			
		||||
static List_t xDelayedCoRoutineList2;									/*< Delayed co-routines (two lists are used - one for delays that have overflowed the current tick count. */
 | 
			
		||||
static List_t * pxDelayedCoRoutineList;									/*< Points to the delayed co-routine list currently being used. */
 | 
			
		||||
static List_t * pxOverflowDelayedCoRoutineList;							/*< Points to the delayed co-routine list currently being used to hold co-routines that have overflowed the current tick count. */
 | 
			
		||||
static List_t xPendingReadyCoRoutineList;								/*< Holds co-routines that have been readied by an external event.  They cannot be added directly to the ready lists as the ready lists cannot be accessed by interrupts. */
 | 
			
		||||
 | 
			
		||||
/* Other file private variables. --------------------------------*/
 | 
			
		||||
CRCB_t * pxCurrentCoRoutine = NULL;
 | 
			
		||||
static UBaseType_t uxTopCoRoutineReadyPriority = 0;
 | 
			
		||||
static TickType_t xCoRoutineTickCount = 0, xLastTickCount = 0, xPassedTicks = 0;
 | 
			
		||||
 | 
			
		||||
/* The initial state of the co-routine when it is created. */
 | 
			
		||||
#define corINITIAL_STATE	( 0 )
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Place the co-routine represented by pxCRCB into the appropriate ready queue
 | 
			
		||||
 * for the priority.  It is inserted at the end of the list.
 | 
			
		||||
 *
 | 
			
		||||
 * This macro accesses the co-routine ready lists and therefore must not be
 | 
			
		||||
 * used from within an ISR.
 | 
			
		||||
 */
 | 
			
		||||
#define prvAddCoRoutineToReadyQueue( pxCRCB )																		\
 | 
			
		||||
{																													\
 | 
			
		||||
	if( pxCRCB->uxPriority > uxTopCoRoutineReadyPriority )															\
 | 
			
		||||
	{																												\
 | 
			
		||||
		uxTopCoRoutineReadyPriority = pxCRCB->uxPriority;															\
 | 
			
		||||
	}																												\
 | 
			
		||||
	vListInsertEnd( ( List_t * ) &( pxReadyCoRoutineLists[ pxCRCB->uxPriority ] ), &( pxCRCB->xGenericListItem ) );	\
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Utility to ready all the lists used by the scheduler.  This is called
 | 
			
		||||
 * automatically upon the creation of the first co-routine.
 | 
			
		||||
 */
 | 
			
		||||
static void prvInitialiseCoRoutineLists( void );
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Co-routines that are readied by an interrupt cannot be placed directly into
 | 
			
		||||
 * the ready lists (there is no mutual exclusion).  Instead they are placed in
 | 
			
		||||
 * in the pending ready list in order that they can later be moved to the ready
 | 
			
		||||
 * list by the co-routine scheduler.
 | 
			
		||||
 */
 | 
			
		||||
static void prvCheckPendingReadyList( void );
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Macro that looks at the list of co-routines that are currently delayed to
 | 
			
		||||
 * see if any require waking.
 | 
			
		||||
 *
 | 
			
		||||
 * Co-routines are stored in the queue in the order of their wake time -
 | 
			
		||||
 * meaning once one co-routine has been found whose timer has not expired
 | 
			
		||||
 * we need not look any further down the list.
 | 
			
		||||
 */
 | 
			
		||||
static void prvCheckDelayedList( void );
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, UBaseType_t uxPriority, UBaseType_t uxIndex )
 | 
			
		||||
{
 | 
			
		||||
BaseType_t xReturn;
 | 
			
		||||
CRCB_t *pxCoRoutine;
 | 
			
		||||
 | 
			
		||||
	/* Allocate the memory that will store the co-routine control block. */
 | 
			
		||||
	pxCoRoutine = ( CRCB_t * ) pvPortMalloc( sizeof( CRCB_t ) );
 | 
			
		||||
	if( pxCoRoutine )
 | 
			
		||||
	{
 | 
			
		||||
		/* If pxCurrentCoRoutine is NULL then this is the first co-routine to
 | 
			
		||||
		be created and the co-routine data structures need initialising. */
 | 
			
		||||
		if( pxCurrentCoRoutine == NULL )
 | 
			
		||||
		{
 | 
			
		||||
			pxCurrentCoRoutine = pxCoRoutine;
 | 
			
		||||
			prvInitialiseCoRoutineLists();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Check the priority is within limits. */
 | 
			
		||||
		if( uxPriority >= configMAX_CO_ROUTINE_PRIORITIES )
 | 
			
		||||
		{
 | 
			
		||||
			uxPriority = configMAX_CO_ROUTINE_PRIORITIES - 1;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Fill out the co-routine control block from the function parameters. */
 | 
			
		||||
		pxCoRoutine->uxState = corINITIAL_STATE;
 | 
			
		||||
		pxCoRoutine->uxPriority = uxPriority;
 | 
			
		||||
		pxCoRoutine->uxIndex = uxIndex;
 | 
			
		||||
		pxCoRoutine->pxCoRoutineFunction = pxCoRoutineCode;
 | 
			
		||||
 | 
			
		||||
		/* Initialise all the other co-routine control block parameters. */
 | 
			
		||||
		vListInitialiseItem( &( pxCoRoutine->xGenericListItem ) );
 | 
			
		||||
		vListInitialiseItem( &( pxCoRoutine->xEventListItem ) );
 | 
			
		||||
 | 
			
		||||
		/* Set the co-routine control block as a link back from the ListItem_t.
 | 
			
		||||
		This is so we can get back to the containing CRCB from a generic item
 | 
			
		||||
		in a list. */
 | 
			
		||||
		listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xGenericListItem ), pxCoRoutine );
 | 
			
		||||
		listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xEventListItem ), pxCoRoutine );
 | 
			
		||||
 | 
			
		||||
		/* Event lists are always in priority order. */
 | 
			
		||||
		listSET_LIST_ITEM_VALUE( &( pxCoRoutine->xEventListItem ), ( ( TickType_t ) configMAX_CO_ROUTINE_PRIORITIES - ( TickType_t ) uxPriority ) );
 | 
			
		||||
 | 
			
		||||
		/* Now the co-routine has been initialised it can be added to the ready
 | 
			
		||||
		list at the correct priority. */
 | 
			
		||||
		prvAddCoRoutineToReadyQueue( pxCoRoutine );
 | 
			
		||||
 | 
			
		||||
		xReturn = pdPASS;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return xReturn;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay, List_t *pxEventList )
 | 
			
		||||
{
 | 
			
		||||
TickType_t xTimeToWake;
 | 
			
		||||
 | 
			
		||||
	/* Calculate the time to wake - this may overflow but this is
 | 
			
		||||
	not a problem. */
 | 
			
		||||
	xTimeToWake = xCoRoutineTickCount + xTicksToDelay;
 | 
			
		||||
 | 
			
		||||
	/* We must remove ourselves from the ready list before adding
 | 
			
		||||
	ourselves to the blocked list as the same list item is used for
 | 
			
		||||
	both lists. */
 | 
			
		||||
	( void ) uxListRemove( ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) );
 | 
			
		||||
 | 
			
		||||
	/* The list item will be inserted in wake time order. */
 | 
			
		||||
	listSET_LIST_ITEM_VALUE( &( pxCurrentCoRoutine->xGenericListItem ), xTimeToWake );
 | 
			
		||||
 | 
			
		||||
	if( xTimeToWake < xCoRoutineTickCount )
 | 
			
		||||
	{
 | 
			
		||||
		/* Wake time has overflowed.  Place this item in the
 | 
			
		||||
		overflow list. */
 | 
			
		||||
		vListInsert( ( List_t * ) pxOverflowDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) );
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		/* The wake time has not overflowed, so we can use the
 | 
			
		||||
		current block list. */
 | 
			
		||||
		vListInsert( ( List_t * ) pxDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if( pxEventList )
 | 
			
		||||
	{
 | 
			
		||||
		/* Also add the co-routine to an event list.  If this is done then the
 | 
			
		||||
		function must be called with interrupts disabled. */
 | 
			
		||||
		vListInsert( pxEventList, &( pxCurrentCoRoutine->xEventListItem ) );
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
static void prvCheckPendingReadyList( void )
 | 
			
		||||
{
 | 
			
		||||
	/* Are there any co-routines waiting to get moved to the ready list?  These
 | 
			
		||||
	are co-routines that have been readied by an ISR.  The ISR cannot access
 | 
			
		||||
	the	ready lists itself. */
 | 
			
		||||
	while( listLIST_IS_EMPTY( &xPendingReadyCoRoutineList ) == pdFALSE )
 | 
			
		||||
	{
 | 
			
		||||
		CRCB_t *pxUnblockedCRCB;
 | 
			
		||||
 | 
			
		||||
		/* The pending ready list can be accessed by an ISR. */
 | 
			
		||||
		portDISABLE_INTERRUPTS();
 | 
			
		||||
		{
 | 
			
		||||
			pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( (&xPendingReadyCoRoutineList) );
 | 
			
		||||
			( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) );
 | 
			
		||||
		}
 | 
			
		||||
		portENABLE_INTERRUPTS();
 | 
			
		||||
 | 
			
		||||
		( void ) uxListRemove( &( pxUnblockedCRCB->xGenericListItem ) );
 | 
			
		||||
		prvAddCoRoutineToReadyQueue( pxUnblockedCRCB );
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
static void prvCheckDelayedList( void )
 | 
			
		||||
{
 | 
			
		||||
CRCB_t *pxCRCB;
 | 
			
		||||
 | 
			
		||||
	xPassedTicks = xTaskGetTickCount() - xLastTickCount;
 | 
			
		||||
	while( xPassedTicks )
 | 
			
		||||
	{
 | 
			
		||||
		xCoRoutineTickCount++;
 | 
			
		||||
		xPassedTicks--;
 | 
			
		||||
 | 
			
		||||
		/* If the tick count has overflowed we need to swap the ready lists. */
 | 
			
		||||
		if( xCoRoutineTickCount == 0 )
 | 
			
		||||
		{
 | 
			
		||||
			List_t * pxTemp;
 | 
			
		||||
 | 
			
		||||
			/* Tick count has overflowed so we need to swap the delay lists.  If there are
 | 
			
		||||
			any items in pxDelayedCoRoutineList here then there is an error! */
 | 
			
		||||
			pxTemp = pxDelayedCoRoutineList;
 | 
			
		||||
			pxDelayedCoRoutineList = pxOverflowDelayedCoRoutineList;
 | 
			
		||||
			pxOverflowDelayedCoRoutineList = pxTemp;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* See if this tick has made a timeout expire. */
 | 
			
		||||
		while( listLIST_IS_EMPTY( pxDelayedCoRoutineList ) == pdFALSE )
 | 
			
		||||
		{
 | 
			
		||||
			pxCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedCoRoutineList );
 | 
			
		||||
 | 
			
		||||
			if( xCoRoutineTickCount < listGET_LIST_ITEM_VALUE( &( pxCRCB->xGenericListItem ) ) )
 | 
			
		||||
			{
 | 
			
		||||
				/* Timeout not yet expired. */
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			portDISABLE_INTERRUPTS();
 | 
			
		||||
			{
 | 
			
		||||
				/* The event could have occurred just before this critical
 | 
			
		||||
				section.  If this is the case then the generic list item will
 | 
			
		||||
				have been moved to the pending ready list and the following
 | 
			
		||||
				line is still valid.  Also the pvContainer parameter will have
 | 
			
		||||
				been set to NULL so the following lines are also valid. */
 | 
			
		||||
				( void ) uxListRemove( &( pxCRCB->xGenericListItem ) );
 | 
			
		||||
 | 
			
		||||
				/* Is the co-routine waiting on an event also? */
 | 
			
		||||
				if( pxCRCB->xEventListItem.pvContainer )
 | 
			
		||||
				{
 | 
			
		||||
					( void ) uxListRemove( &( pxCRCB->xEventListItem ) );
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			portENABLE_INTERRUPTS();
 | 
			
		||||
 | 
			
		||||
			prvAddCoRoutineToReadyQueue( pxCRCB );
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	xLastTickCount = xCoRoutineTickCount;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
void vCoRoutineSchedule( void )
 | 
			
		||||
{
 | 
			
		||||
	/* See if any co-routines readied by events need moving to the ready lists. */
 | 
			
		||||
	prvCheckPendingReadyList();
 | 
			
		||||
 | 
			
		||||
	/* See if any delayed co-routines have timed out. */
 | 
			
		||||
	prvCheckDelayedList();
 | 
			
		||||
 | 
			
		||||
	/* Find the highest priority queue that contains ready co-routines. */
 | 
			
		||||
	while( listLIST_IS_EMPTY( &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ) )
 | 
			
		||||
	{
 | 
			
		||||
		if( uxTopCoRoutineReadyPriority == 0 )
 | 
			
		||||
		{
 | 
			
		||||
			/* No more co-routines to check. */
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		--uxTopCoRoutineReadyPriority;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the co-routines
 | 
			
		||||
	 of the	same priority get an equal share of the processor time. */
 | 
			
		||||
	listGET_OWNER_OF_NEXT_ENTRY( pxCurrentCoRoutine, &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) );
 | 
			
		||||
 | 
			
		||||
	/* Call the co-routine. */
 | 
			
		||||
	( pxCurrentCoRoutine->pxCoRoutineFunction )( pxCurrentCoRoutine, pxCurrentCoRoutine->uxIndex );
 | 
			
		||||
 | 
			
		||||
	return;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
static void prvInitialiseCoRoutineLists( void )
 | 
			
		||||
{
 | 
			
		||||
UBaseType_t uxPriority;
 | 
			
		||||
 | 
			
		||||
	for( uxPriority = 0; uxPriority < configMAX_CO_ROUTINE_PRIORITIES; uxPriority++ )
 | 
			
		||||
	{
 | 
			
		||||
		vListInitialise( ( List_t * ) &( pxReadyCoRoutineLists[ uxPriority ] ) );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	vListInitialise( ( List_t * ) &xDelayedCoRoutineList1 );
 | 
			
		||||
	vListInitialise( ( List_t * ) &xDelayedCoRoutineList2 );
 | 
			
		||||
	vListInitialise( ( List_t * ) &xPendingReadyCoRoutineList );
 | 
			
		||||
 | 
			
		||||
	/* Start with pxDelayedCoRoutineList using list1 and the
 | 
			
		||||
	pxOverflowDelayedCoRoutineList using list2. */
 | 
			
		||||
	pxDelayedCoRoutineList = &xDelayedCoRoutineList1;
 | 
			
		||||
	pxOverflowDelayedCoRoutineList = &xDelayedCoRoutineList2;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
BaseType_t xCoRoutineRemoveFromEventList( const List_t *pxEventList )
 | 
			
		||||
{
 | 
			
		||||
CRCB_t *pxUnblockedCRCB;
 | 
			
		||||
BaseType_t xReturn;
 | 
			
		||||
 | 
			
		||||
	/* This function is called from within an interrupt.  It can only access
 | 
			
		||||
	event lists and the pending ready list.  This function assumes that a
 | 
			
		||||
	check has already been made to ensure pxEventList is not empty. */
 | 
			
		||||
	pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList );
 | 
			
		||||
	( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) );
 | 
			
		||||
	vListInsertEnd( ( List_t * ) &( xPendingReadyCoRoutineList ), &( pxUnblockedCRCB->xEventListItem ) );
 | 
			
		||||
 | 
			
		||||
	if( pxUnblockedCRCB->uxPriority >= pxCurrentCoRoutine->uxPriority )
 | 
			
		||||
	{
 | 
			
		||||
		xReturn = pdTRUE;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		xReturn = pdFALSE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return xReturn;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										676
									
								
								component/os/freertos/freertos_v8.1.2/Source/event_groups.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										676
									
								
								component/os/freertos/freertos_v8.1.2/Source/event_groups.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,676 @@
 | 
			
		|||
/*
 | 
			
		||||
    FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd.
 | 
			
		||||
    All rights reserved
 | 
			
		||||
 | 
			
		||||
    VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
 | 
			
		||||
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    FreeRTOS provides completely free yet professionally developed,    *
 | 
			
		||||
     *    robust, strictly quality controlled, supported, and cross          *
 | 
			
		||||
     *    platform software that has become a de facto standard.             *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    Help yourself get started quickly and support the FreeRTOS         *
 | 
			
		||||
     *    project by purchasing a FreeRTOS tutorial book, reference          *
 | 
			
		||||
     *    manual, or both from: http://www.FreeRTOS.org/Documentation        *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    Thank you!                                                         *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
 | 
			
		||||
    This file is part of the FreeRTOS distribution.
 | 
			
		||||
 | 
			
		||||
    FreeRTOS is free software; you can redistribute it and/or modify it under
 | 
			
		||||
    the terms of the GNU General Public License (version 2) as published by the
 | 
			
		||||
    Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
 | 
			
		||||
 | 
			
		||||
    >>!   NOTE: The modification to the GPL is included to allow you to     !<<
 | 
			
		||||
    >>!   distribute a combined work that includes FreeRTOS without being   !<<
 | 
			
		||||
    >>!   obliged to provide the source code for proprietary components     !<<
 | 
			
		||||
    >>!   outside of the FreeRTOS kernel.                                   !<<
 | 
			
		||||
 | 
			
		||||
    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
 | 
			
		||||
    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
    FOR A PARTICULAR PURPOSE.  Full license text is available from the following
 | 
			
		||||
    link: http://www.freertos.org/a00114.html
 | 
			
		||||
 | 
			
		||||
    1 tab == 4 spaces!
 | 
			
		||||
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    Having a problem?  Start by reading the FAQ "My application does   *
 | 
			
		||||
     *    not run, what could be wrong?"                                     *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    http://www.FreeRTOS.org/FAQHelp.html                               *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
 | 
			
		||||
    http://www.FreeRTOS.org - Documentation, books, training, latest versions,
 | 
			
		||||
    license and Real Time Engineers Ltd. contact details.
 | 
			
		||||
 | 
			
		||||
    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
 | 
			
		||||
    including FreeRTOS+Trace - an indispensable productivity tool, a DOS
 | 
			
		||||
    compatible FAT file system, and our tiny thread aware UDP/IP stack.
 | 
			
		||||
 | 
			
		||||
    http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
 | 
			
		||||
    Integrity Systems to sell under the OpenRTOS brand.  Low cost OpenRTOS
 | 
			
		||||
    licenses offer ticketed support, indemnification and middleware.
 | 
			
		||||
 | 
			
		||||
    http://www.SafeRTOS.com - High Integrity Systems also provide a safety
 | 
			
		||||
    engineered and independently SIL3 certified version for use in safety and
 | 
			
		||||
    mission critical applications that require provable dependability.
 | 
			
		||||
 | 
			
		||||
    1 tab == 4 spaces!
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/* Standard includes. */
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
 | 
			
		||||
all the API functions to use the MPU wrappers.  That should only be done when
 | 
			
		||||
task.h is included from an application file. */
 | 
			
		||||
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
 | 
			
		||||
 | 
			
		||||
/* FreeRTOS includes. */
 | 
			
		||||
#include "FreeRTOS.h"
 | 
			
		||||
#include "task.h"
 | 
			
		||||
#include "timers.h"
 | 
			
		||||
#include "event_groups.h"
 | 
			
		||||
 | 
			
		||||
/* Lint e961 and e750 are suppressed as a MISRA exception justified because the
 | 
			
		||||
MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined for the
 | 
			
		||||
header files above, but not in this file, in order to generate the correct
 | 
			
		||||
privileged Vs unprivileged linkage and placement. */
 | 
			
		||||
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750. */
 | 
			
		||||
 | 
			
		||||
#if ( INCLUDE_xEventGroupSetBitFromISR == 1 ) && ( configUSE_TIMERS == 0 )
 | 
			
		||||
	#error configUSE_TIMERS must be set to 1 to make the xEventGroupSetBitFromISR() function available.
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if ( INCLUDE_xEventGroupSetBitFromISR == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 0 )
 | 
			
		||||
	#error INCLUDE_xTimerPendFunctionCall must also be set to one to make the xEventGroupSetBitFromISR() function available.
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* The following bit fields convey control information in a task's event list
 | 
			
		||||
item value.  It is important they don't clash with the
 | 
			
		||||
taskEVENT_LIST_ITEM_VALUE_IN_USE definition. */
 | 
			
		||||
#if configUSE_16_BIT_TICKS == 1
 | 
			
		||||
	#define eventCLEAR_EVENTS_ON_EXIT_BIT	0x0100U
 | 
			
		||||
	#define eventUNBLOCKED_DUE_TO_BIT_SET	0x0200U
 | 
			
		||||
	#define eventWAIT_FOR_ALL_BITS			0x0400U
 | 
			
		||||
	#define eventEVENT_BITS_CONTROL_BYTES	0xff00U
 | 
			
		||||
#else
 | 
			
		||||
	#define eventCLEAR_EVENTS_ON_EXIT_BIT	0x01000000UL
 | 
			
		||||
	#define eventUNBLOCKED_DUE_TO_BIT_SET	0x02000000UL
 | 
			
		||||
	#define eventWAIT_FOR_ALL_BITS			0x04000000UL
 | 
			
		||||
	#define eventEVENT_BITS_CONTROL_BYTES	0xff000000UL
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
typedef struct xEventGroupDefinition
 | 
			
		||||
{
 | 
			
		||||
	EventBits_t uxEventBits;
 | 
			
		||||
	List_t xTasksWaitingForBits;		/*< List of tasks waiting for a bit to be set. */
 | 
			
		||||
 | 
			
		||||
	#if( configUSE_TRACE_FACILITY == 1 )
 | 
			
		||||
		UBaseType_t uxEventGroupNumber;
 | 
			
		||||
	#endif
 | 
			
		||||
 | 
			
		||||
} EventGroup_t;
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Test the bits set in uxCurrentEventBits to see if the wait condition is met.
 | 
			
		||||
 * The wait condition is defined by xWaitForAllBits.  If xWaitForAllBits is
 | 
			
		||||
 * pdTRUE then the wait condition is met if all the bits set in uxBitsToWaitFor
 | 
			
		||||
 * are also set in uxCurrentEventBits.  If xWaitForAllBits is pdFALSE then the
 | 
			
		||||
 * wait condition is met if any of the bits set in uxBitsToWait for are also set
 | 
			
		||||
 * in uxCurrentEventBits.
 | 
			
		||||
 */
 | 
			
		||||
static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, const EventBits_t uxBitsToWaitFor, const BaseType_t xWaitForAllBits );
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
EventGroupHandle_t xEventGroupCreate( void )
 | 
			
		||||
{
 | 
			
		||||
EventGroup_t *pxEventBits;
 | 
			
		||||
 | 
			
		||||
	pxEventBits = pvPortMalloc( sizeof( EventGroup_t ) );
 | 
			
		||||
	if( pxEventBits != NULL )
 | 
			
		||||
	{
 | 
			
		||||
		pxEventBits->uxEventBits = 0;
 | 
			
		||||
		vListInitialise( &( pxEventBits->xTasksWaitingForBits ) );
 | 
			
		||||
		traceEVENT_GROUP_CREATE( pxEventBits );
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		traceEVENT_GROUP_CREATE_FAILED();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return ( EventGroupHandle_t ) pxEventBits;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait )
 | 
			
		||||
{
 | 
			
		||||
EventBits_t uxOriginalBitValue, uxReturn;
 | 
			
		||||
EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
 | 
			
		||||
BaseType_t xAlreadyYielded;
 | 
			
		||||
BaseType_t xTimeoutOccurred = pdFALSE;
 | 
			
		||||
 | 
			
		||||
	configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
 | 
			
		||||
	configASSERT( uxBitsToWaitFor != 0 );
 | 
			
		||||
	#if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) )
 | 
			
		||||
	{
 | 
			
		||||
		configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) );
 | 
			
		||||
	}
 | 
			
		||||
	#endif
 | 
			
		||||
 | 
			
		||||
	vTaskSuspendAll();
 | 
			
		||||
	{
 | 
			
		||||
		uxOriginalBitValue = pxEventBits->uxEventBits;
 | 
			
		||||
 | 
			
		||||
		( void ) xEventGroupSetBits( xEventGroup, uxBitsToSet );
 | 
			
		||||
 | 
			
		||||
		if( ( ( uxOriginalBitValue | uxBitsToSet ) & uxBitsToWaitFor ) == uxBitsToWaitFor )
 | 
			
		||||
		{
 | 
			
		||||
			/* All the rendezvous bits are now set - no need to block. */
 | 
			
		||||
			uxReturn = ( uxOriginalBitValue | uxBitsToSet );
 | 
			
		||||
 | 
			
		||||
			/* Rendezvous always clear the bits.  They will have been cleared
 | 
			
		||||
			already unless this is the only task in the rendezvous. */
 | 
			
		||||
			pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
 | 
			
		||||
 | 
			
		||||
			xTicksToWait = 0;
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			if( xTicksToWait != ( TickType_t ) 0 )
 | 
			
		||||
			{
 | 
			
		||||
				traceEVENT_GROUP_SYNC_BLOCK( xEventGroup, uxBitsToSet, uxBitsToWaitFor );
 | 
			
		||||
 | 
			
		||||
				/* Store the bits that the calling task is waiting for in the
 | 
			
		||||
				task's event list item so the kernel knows when a match is
 | 
			
		||||
				found.  Then enter the blocked state. */
 | 
			
		||||
				vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | eventCLEAR_EVENTS_ON_EXIT_BIT | eventWAIT_FOR_ALL_BITS ), xTicksToWait );
 | 
			
		||||
 | 
			
		||||
				/* This assignment is obsolete as uxReturn will get set after
 | 
			
		||||
				the task unblocks, but some compilers mistakenly generate a
 | 
			
		||||
				warning about uxReturn being returned without being set if the
 | 
			
		||||
				assignment is omitted. */
 | 
			
		||||
				uxReturn = 0;
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				/* The rendezvous bits were not set, but no block time was
 | 
			
		||||
				specified - just return the current event bit value. */
 | 
			
		||||
				uxReturn = pxEventBits->uxEventBits;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	xAlreadyYielded = xTaskResumeAll();
 | 
			
		||||
 | 
			
		||||
	if( xTicksToWait != ( TickType_t ) 0 )
 | 
			
		||||
	{
 | 
			
		||||
		if( xAlreadyYielded == pdFALSE )
 | 
			
		||||
		{
 | 
			
		||||
			portYIELD_WITHIN_API();
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* The task blocked to wait for its required bits to be set - at this
 | 
			
		||||
		point either the required bits were set or the block time expired.  If
 | 
			
		||||
		the required bits were set they will have been stored in the task's
 | 
			
		||||
		event list item, and they should now be retrieved then cleared. */
 | 
			
		||||
		uxReturn = uxTaskResetEventItemValue();
 | 
			
		||||
 | 
			
		||||
		if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 )
 | 
			
		||||
		{
 | 
			
		||||
			/* The task timed out, just return the current event bit value. */
 | 
			
		||||
			taskENTER_CRITICAL();
 | 
			
		||||
			{
 | 
			
		||||
				uxReturn = pxEventBits->uxEventBits;
 | 
			
		||||
 | 
			
		||||
				/* Although the task got here because it timed out before the
 | 
			
		||||
				bits it was waiting for were set, it is possible that since it
 | 
			
		||||
				unblocked another task has set the bits.  If this is the case
 | 
			
		||||
				then it needs to clear the bits before exiting. */
 | 
			
		||||
				if( ( uxReturn & uxBitsToWaitFor ) == uxBitsToWaitFor )
 | 
			
		||||
				{
 | 
			
		||||
					pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
				{
 | 
			
		||||
					mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			taskEXIT_CRITICAL();
 | 
			
		||||
 | 
			
		||||
			xTimeoutOccurred = pdTRUE;
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			/* The task unblocked because the bits were set. */
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Control bits might be set as the task had blocked should not be
 | 
			
		||||
		returned. */
 | 
			
		||||
		uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	traceEVENT_GROUP_SYNC_END( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTimeoutOccurred );
 | 
			
		||||
 | 
			
		||||
	return uxReturn;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait )
 | 
			
		||||
{
 | 
			
		||||
EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
 | 
			
		||||
EventBits_t uxReturn, uxControlBits = 0;
 | 
			
		||||
BaseType_t xWaitConditionMet, xAlreadyYielded;
 | 
			
		||||
BaseType_t xTimeoutOccurred = pdFALSE;
 | 
			
		||||
 | 
			
		||||
	/* Check the user is not attempting to wait on the bits used by the kernel
 | 
			
		||||
	itself, and that at least one bit is being requested. */
 | 
			
		||||
	configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
 | 
			
		||||
	configASSERT( uxBitsToWaitFor != 0 );
 | 
			
		||||
	#if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) )
 | 
			
		||||
	{
 | 
			
		||||
		configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) );
 | 
			
		||||
	}
 | 
			
		||||
	#endif
 | 
			
		||||
 | 
			
		||||
	vTaskSuspendAll();
 | 
			
		||||
	{
 | 
			
		||||
		const EventBits_t uxCurrentEventBits = pxEventBits->uxEventBits;
 | 
			
		||||
 | 
			
		||||
		/* Check to see if the wait condition is already met or not. */
 | 
			
		||||
		xWaitConditionMet = prvTestWaitCondition( uxCurrentEventBits, uxBitsToWaitFor, xWaitForAllBits );
 | 
			
		||||
 | 
			
		||||
		if( xWaitConditionMet != pdFALSE )
 | 
			
		||||
		{
 | 
			
		||||
			/* The wait condition has already been met so there is no need to
 | 
			
		||||
			block. */
 | 
			
		||||
			uxReturn = uxCurrentEventBits;
 | 
			
		||||
			xTicksToWait = ( TickType_t ) 0;
 | 
			
		||||
 | 
			
		||||
			/* Clear the wait bits if requested to do so. */
 | 
			
		||||
			if( xClearOnExit != pdFALSE )
 | 
			
		||||
			{
 | 
			
		||||
				pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		else if( xTicksToWait == ( TickType_t ) 0 )
 | 
			
		||||
		{
 | 
			
		||||
			/* The wait condition has not been met, but no block time was
 | 
			
		||||
			specified, so just return the current value. */
 | 
			
		||||
			uxReturn = uxCurrentEventBits;
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			/* The task is going to block to wait for its required bits to be
 | 
			
		||||
			set.  uxControlBits are used to remember the specified behaviour of
 | 
			
		||||
			this call to xEventGroupWaitBits() - for use when the event bits
 | 
			
		||||
			unblock the task. */
 | 
			
		||||
			if( xClearOnExit != pdFALSE )
 | 
			
		||||
			{
 | 
			
		||||
				uxControlBits |= eventCLEAR_EVENTS_ON_EXIT_BIT;
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if( xWaitForAllBits != pdFALSE )
 | 
			
		||||
			{
 | 
			
		||||
				uxControlBits |= eventWAIT_FOR_ALL_BITS;
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			/* Store the bits that the calling task is waiting for in the
 | 
			
		||||
			task's event list item so the kernel knows when a match is
 | 
			
		||||
			found.  Then enter the blocked state. */
 | 
			
		||||
			vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | uxControlBits ), xTicksToWait );
 | 
			
		||||
 | 
			
		||||
			/* This is obsolete as it will get set after the task unblocks, but
 | 
			
		||||
			some compilers mistakenly generate a warning about the variable
 | 
			
		||||
			being returned without being set if it is not done. */
 | 
			
		||||
			uxReturn = 0;
 | 
			
		||||
 | 
			
		||||
			traceEVENT_GROUP_WAIT_BITS_BLOCK( xEventGroup, uxBitsToWaitFor );
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	xAlreadyYielded = xTaskResumeAll();
 | 
			
		||||
 | 
			
		||||
	if( xTicksToWait != ( TickType_t ) 0 )
 | 
			
		||||
	{
 | 
			
		||||
		if( xAlreadyYielded == pdFALSE )
 | 
			
		||||
		{
 | 
			
		||||
			portYIELD_WITHIN_API();
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* The task blocked to wait for its required bits to be set - at this
 | 
			
		||||
		point either the required bits were set or the block time expired.  If
 | 
			
		||||
		the required bits were set they will have been stored in the task's
 | 
			
		||||
		event list item, and they should now be retrieved then cleared. */
 | 
			
		||||
		uxReturn = uxTaskResetEventItemValue();
 | 
			
		||||
 | 
			
		||||
		if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 )
 | 
			
		||||
		{
 | 
			
		||||
			taskENTER_CRITICAL();
 | 
			
		||||
			{
 | 
			
		||||
				/* The task timed out, just return the current event bit value. */
 | 
			
		||||
				uxReturn = pxEventBits->uxEventBits;
 | 
			
		||||
 | 
			
		||||
				/* It is possible that the event bits were updated between this
 | 
			
		||||
				task leaving the Blocked state and running again. */
 | 
			
		||||
				if( prvTestWaitCondition( uxReturn, uxBitsToWaitFor, xWaitForAllBits ) != pdFALSE )
 | 
			
		||||
				{
 | 
			
		||||
					if( xClearOnExit != pdFALSE )
 | 
			
		||||
					{
 | 
			
		||||
						pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
 | 
			
		||||
					}
 | 
			
		||||
					else
 | 
			
		||||
					{
 | 
			
		||||
						mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
				{
 | 
			
		||||
					mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			taskEXIT_CRITICAL();
 | 
			
		||||
 | 
			
		||||
			/* Prevent compiler warnings when trace macros are not used. */
 | 
			
		||||
			xTimeoutOccurred = pdFALSE;
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			/* The task unblocked because the bits were set. */
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* The task blocked so control bits may have been set. */
 | 
			
		||||
		uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES;
 | 
			
		||||
	}
 | 
			
		||||
	traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxBitsToWaitFor, xTimeoutOccurred );
 | 
			
		||||
 | 
			
		||||
	return uxReturn;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear )
 | 
			
		||||
{
 | 
			
		||||
EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
 | 
			
		||||
EventBits_t uxReturn;
 | 
			
		||||
 | 
			
		||||
	/* Check the user is not attempting to clear the bits used by the kernel
 | 
			
		||||
	itself. */
 | 
			
		||||
	configASSERT( ( uxBitsToClear & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
 | 
			
		||||
 | 
			
		||||
	taskENTER_CRITICAL();
 | 
			
		||||
	{
 | 
			
		||||
		traceEVENT_GROUP_CLEAR_BITS( xEventGroup, uxBitsToClear );
 | 
			
		||||
 | 
			
		||||
		/* The value returned is the event group value prior to the bits being
 | 
			
		||||
		cleared. */
 | 
			
		||||
		uxReturn = pxEventBits->uxEventBits;
 | 
			
		||||
 | 
			
		||||
		/* Clear the bits. */
 | 
			
		||||
		pxEventBits->uxEventBits &= ~uxBitsToClear;
 | 
			
		||||
	}
 | 
			
		||||
	taskEXIT_CRITICAL();
 | 
			
		||||
 | 
			
		||||
	return uxReturn;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) )
 | 
			
		||||
 | 
			
		||||
	BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear )
 | 
			
		||||
	{
 | 
			
		||||
		BaseType_t xReturn;
 | 
			
		||||
 | 
			
		||||
		traceEVENT_GROUP_CLEAR_BITS_FROM_ISR( xEventGroup, uxBitsToClear );
 | 
			
		||||
		xReturn = xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL );
 | 
			
		||||
 | 
			
		||||
		return xReturn;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup )
 | 
			
		||||
{
 | 
			
		||||
UBaseType_t uxSavedInterruptStatus;
 | 
			
		||||
EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
 | 
			
		||||
EventBits_t uxReturn;
 | 
			
		||||
 | 
			
		||||
	uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
 | 
			
		||||
	{
 | 
			
		||||
		uxReturn = pxEventBits->uxEventBits;
 | 
			
		||||
	}
 | 
			
		||||
	portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
 | 
			
		||||
 | 
			
		||||
	return uxReturn;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet )
 | 
			
		||||
{
 | 
			
		||||
ListItem_t *pxListItem, *pxNext;
 | 
			
		||||
ListItem_t const *pxListEnd;
 | 
			
		||||
List_t *pxList;
 | 
			
		||||
EventBits_t uxBitsToClear = 0, uxBitsWaitedFor, uxControlBits;
 | 
			
		||||
EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
 | 
			
		||||
BaseType_t xMatchFound = pdFALSE;
 | 
			
		||||
 | 
			
		||||
	/* Check the user is not attempting to set the bits used by the kernel
 | 
			
		||||
	itself. */
 | 
			
		||||
	configASSERT( ( uxBitsToSet & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
 | 
			
		||||
 | 
			
		||||
	pxList = &( pxEventBits->xTasksWaitingForBits );
 | 
			
		||||
	pxListEnd = listGET_END_MARKER( pxList ); /*lint !e826 !e740 The mini list structure is used as the list end to save RAM.  This is checked and valid. */
 | 
			
		||||
	vTaskSuspendAll();
 | 
			
		||||
	{
 | 
			
		||||
		traceEVENT_GROUP_SET_BITS( xEventGroup, uxBitsToSet );
 | 
			
		||||
 | 
			
		||||
		pxListItem = listGET_HEAD_ENTRY( pxList );
 | 
			
		||||
 | 
			
		||||
		/* Set the bits. */
 | 
			
		||||
		pxEventBits->uxEventBits |= uxBitsToSet;
 | 
			
		||||
 | 
			
		||||
		/* See if the new bit value should unblock any tasks. */
 | 
			
		||||
		while( pxListItem != pxListEnd )
 | 
			
		||||
		{
 | 
			
		||||
			pxNext = listGET_NEXT( pxListItem );
 | 
			
		||||
			uxBitsWaitedFor = listGET_LIST_ITEM_VALUE( pxListItem );
 | 
			
		||||
			xMatchFound = pdFALSE;
 | 
			
		||||
 | 
			
		||||
			/* Split the bits waited for from the control bits. */
 | 
			
		||||
			uxControlBits = uxBitsWaitedFor & eventEVENT_BITS_CONTROL_BYTES;
 | 
			
		||||
			uxBitsWaitedFor &= ~eventEVENT_BITS_CONTROL_BYTES;
 | 
			
		||||
 | 
			
		||||
			if( ( uxControlBits & eventWAIT_FOR_ALL_BITS ) == ( EventBits_t ) 0 )
 | 
			
		||||
			{
 | 
			
		||||
				/* Just looking for single bit being set. */
 | 
			
		||||
				if( ( uxBitsWaitedFor & pxEventBits->uxEventBits ) != ( EventBits_t ) 0 )
 | 
			
		||||
				{
 | 
			
		||||
					xMatchFound = pdTRUE;
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
				{
 | 
			
		||||
					mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			else if( ( uxBitsWaitedFor & pxEventBits->uxEventBits ) == uxBitsWaitedFor )
 | 
			
		||||
			{
 | 
			
		||||
				/* All bits are set. */
 | 
			
		||||
				xMatchFound = pdTRUE;
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				/* Need all bits to be set, but not all the bits were set. */
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if( xMatchFound != pdFALSE )
 | 
			
		||||
			{
 | 
			
		||||
				/* The bits match.  Should the bits be cleared on exit? */
 | 
			
		||||
				if( ( uxControlBits & eventCLEAR_EVENTS_ON_EXIT_BIT ) != ( EventBits_t ) 0 )
 | 
			
		||||
				{
 | 
			
		||||
					uxBitsToClear |= uxBitsWaitedFor;
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
				{
 | 
			
		||||
					mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				/* Store the actual event flag value in the task's event list
 | 
			
		||||
				item before removing the task from the event list.  The
 | 
			
		||||
				eventUNBLOCKED_DUE_TO_BIT_SET bit is set so the task knows
 | 
			
		||||
				that is was unblocked due to its required bits matching, rather
 | 
			
		||||
				than because it timed out. */
 | 
			
		||||
				( void ) xTaskRemoveFromUnorderedEventList( pxListItem, pxEventBits->uxEventBits | eventUNBLOCKED_DUE_TO_BIT_SET );
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			/* Move onto the next list item.  Note pxListItem->pxNext is not
 | 
			
		||||
			used here as the list item may have been removed from the event list
 | 
			
		||||
			and inserted into the ready/pending reading list. */
 | 
			
		||||
			pxListItem = pxNext;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Clear any bits that matched when the eventCLEAR_EVENTS_ON_EXIT_BIT
 | 
			
		||||
		bit was set in the control word. */
 | 
			
		||||
		pxEventBits->uxEventBits &= ~uxBitsToClear;
 | 
			
		||||
	}
 | 
			
		||||
	( void ) xTaskResumeAll();
 | 
			
		||||
 | 
			
		||||
	return pxEventBits->uxEventBits;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
void vEventGroupDelete( EventGroupHandle_t xEventGroup )
 | 
			
		||||
{
 | 
			
		||||
EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
 | 
			
		||||
const List_t *pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits );
 | 
			
		||||
 | 
			
		||||
	vTaskSuspendAll();
 | 
			
		||||
	{
 | 
			
		||||
		traceEVENT_GROUP_DELETE( xEventGroup );
 | 
			
		||||
 | 
			
		||||
		while( listCURRENT_LIST_LENGTH( pxTasksWaitingForBits ) > ( UBaseType_t ) 0 )
 | 
			
		||||
		{
 | 
			
		||||
			/* Unblock the task, returning 0 as the event list is being deleted
 | 
			
		||||
			and	cannot therefore have any bits set. */
 | 
			
		||||
			configASSERT( pxTasksWaitingForBits->xListEnd.pxNext != ( ListItem_t * ) &( pxTasksWaitingForBits->xListEnd ) );
 | 
			
		||||
			( void ) xTaskRemoveFromUnorderedEventList( pxTasksWaitingForBits->xListEnd.pxNext, eventUNBLOCKED_DUE_TO_BIT_SET );
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		vPortFree( pxEventBits );
 | 
			
		||||
	}
 | 
			
		||||
	( void ) xTaskResumeAll();
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/* For internal use only - execute a 'set bits' command that was pended from
 | 
			
		||||
an interrupt. */
 | 
			
		||||
void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet )
 | 
			
		||||
{
 | 
			
		||||
	( void ) xEventGroupSetBits( pvEventGroup, ( EventBits_t ) ulBitsToSet );
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/* For internal use only - execute a 'clear bits' command that was pended from
 | 
			
		||||
an interrupt. */
 | 
			
		||||
void vEventGroupClearBitsCallback( void *pvEventGroup, const uint32_t ulBitsToClear )
 | 
			
		||||
{
 | 
			
		||||
	( void ) xEventGroupClearBits( pvEventGroup, ( EventBits_t ) ulBitsToClear );
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, const EventBits_t uxBitsToWaitFor, const BaseType_t xWaitForAllBits )
 | 
			
		||||
{
 | 
			
		||||
BaseType_t xWaitConditionMet = pdFALSE;
 | 
			
		||||
 | 
			
		||||
	if( xWaitForAllBits == pdFALSE )
 | 
			
		||||
	{
 | 
			
		||||
		/* Task only has to wait for one bit within uxBitsToWaitFor to be
 | 
			
		||||
		set.  Is one already set? */
 | 
			
		||||
		if( ( uxCurrentEventBits & uxBitsToWaitFor ) != ( EventBits_t ) 0 )
 | 
			
		||||
		{
 | 
			
		||||
			xWaitConditionMet = pdTRUE;
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		/* Task has to wait for all the bits in uxBitsToWaitFor to be set.
 | 
			
		||||
		Are they set already? */
 | 
			
		||||
		if( ( uxCurrentEventBits & uxBitsToWaitFor ) == uxBitsToWaitFor )
 | 
			
		||||
		{
 | 
			
		||||
			xWaitConditionMet = pdTRUE;
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return xWaitConditionMet;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) )
 | 
			
		||||
 | 
			
		||||
	BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken )
 | 
			
		||||
	{
 | 
			
		||||
	BaseType_t xReturn;
 | 
			
		||||
 | 
			
		||||
		traceEVENT_GROUP_SET_BITS_FROM_ISR( xEventGroup, uxBitsToSet );
 | 
			
		||||
		xReturn = xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken );
 | 
			
		||||
 | 
			
		||||
		return xReturn;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
#if (configUSE_TRACE_FACILITY == 1)
 | 
			
		||||
 | 
			
		||||
	UBaseType_t uxEventGroupGetNumber( void* xEventGroup )
 | 
			
		||||
	{
 | 
			
		||||
	UBaseType_t xReturn;
 | 
			
		||||
	EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
 | 
			
		||||
 | 
			
		||||
		if( xEventGroup == NULL )
 | 
			
		||||
		{
 | 
			
		||||
			xReturn = 0;
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			xReturn = pxEventBits->uxEventGroupNumber;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return xReturn;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										762
									
								
								component/os/freertos/freertos_v8.1.2/Source/include/FreeRTOS.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										762
									
								
								component/os/freertos/freertos_v8.1.2/Source/include/FreeRTOS.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,762 @@
 | 
			
		|||
/*
 | 
			
		||||
    FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd.
 | 
			
		||||
    All rights reserved
 | 
			
		||||
 | 
			
		||||
    VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
 | 
			
		||||
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    FreeRTOS provides completely free yet professionally developed,    *
 | 
			
		||||
     *    robust, strictly quality controlled, supported, and cross          *
 | 
			
		||||
     *    platform software that has become a de facto standard.             *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    Help yourself get started quickly and support the FreeRTOS         *
 | 
			
		||||
     *    project by purchasing a FreeRTOS tutorial book, reference          *
 | 
			
		||||
     *    manual, or both from: http://www.FreeRTOS.org/Documentation        *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    Thank you!                                                         *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
 | 
			
		||||
    This file is part of the FreeRTOS distribution.
 | 
			
		||||
 | 
			
		||||
    FreeRTOS is free software; you can redistribute it and/or modify it under
 | 
			
		||||
    the terms of the GNU General Public License (version 2) as published by the
 | 
			
		||||
    Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
 | 
			
		||||
 | 
			
		||||
    >>!   NOTE: The modification to the GPL is included to allow you to     !<<
 | 
			
		||||
    >>!   distribute a combined work that includes FreeRTOS without being   !<<
 | 
			
		||||
    >>!   obliged to provide the source code for proprietary components     !<<
 | 
			
		||||
    >>!   outside of the FreeRTOS kernel.                                   !<<
 | 
			
		||||
 | 
			
		||||
    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
 | 
			
		||||
    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
    FOR A PARTICULAR PURPOSE.  Full license text is available from the following
 | 
			
		||||
    link: http://www.freertos.org/a00114.html
 | 
			
		||||
 | 
			
		||||
    1 tab == 4 spaces!
 | 
			
		||||
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    Having a problem?  Start by reading the FAQ "My application does   *
 | 
			
		||||
     *    not run, what could be wrong?"                                     *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    http://www.FreeRTOS.org/FAQHelp.html                               *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
 | 
			
		||||
    http://www.FreeRTOS.org - Documentation, books, training, latest versions,
 | 
			
		||||
    license and Real Time Engineers Ltd. contact details.
 | 
			
		||||
 | 
			
		||||
    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
 | 
			
		||||
    including FreeRTOS+Trace - an indispensable productivity tool, a DOS
 | 
			
		||||
    compatible FAT file system, and our tiny thread aware UDP/IP stack.
 | 
			
		||||
 | 
			
		||||
    http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
 | 
			
		||||
    Integrity Systems to sell under the OpenRTOS brand.  Low cost OpenRTOS
 | 
			
		||||
    licenses offer ticketed support, indemnification and middleware.
 | 
			
		||||
 | 
			
		||||
    http://www.SafeRTOS.com - High Integrity Systems also provide a safety
 | 
			
		||||
    engineered and independently SIL3 certified version for use in safety and
 | 
			
		||||
    mission critical applications that require provable dependability.
 | 
			
		||||
 | 
			
		||||
    1 tab == 4 spaces!
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef INC_FREERTOS_H
 | 
			
		||||
#define INC_FREERTOS_H
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Include the generic headers required for the FreeRTOS port being used.
 | 
			
		||||
 */
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * If stdint.h cannot be located then:
 | 
			
		||||
 *   + If using GCC ensure the -nostdint options is *not* being used.
 | 
			
		||||
 *   + Ensure the project's include path includes the directory in which your
 | 
			
		||||
 *     compiler stores stdint.h.
 | 
			
		||||
 *   + Set any compiler options necessary for it to support C99, as technically
 | 
			
		||||
 *     stdint.h is only mandatory with C99 (FreeRTOS does not require C99 in any
 | 
			
		||||
 *     other way).
 | 
			
		||||
 *   + The FreeRTOS download includes a simple stdint.h definition that can be
 | 
			
		||||
 *     used in cases where none is provided by the compiler.  The files only
 | 
			
		||||
 *     contains the typedefs required to build FreeRTOS.  Read the instructions
 | 
			
		||||
 *     in FreeRTOS/source/stdint.readme for more information.
 | 
			
		||||
 */
 | 
			
		||||
#include <stdint.h> /* READ COMMENT ABOVE. */
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Application specific configuration options. */
 | 
			
		||||
#include "FreeRTOSConfig.h"
 | 
			
		||||
 | 
			
		||||
/* Basic FreeRTOS definitions. */
 | 
			
		||||
#include "projdefs.h"
 | 
			
		||||
 | 
			
		||||
/* Definitions specific to the port being used. */
 | 
			
		||||
#include "portable.h"
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Check all the required application specific macros have been defined.
 | 
			
		||||
 * These macros are application specific and (as downloaded) are defined
 | 
			
		||||
 * within FreeRTOSConfig.h.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef configMINIMAL_STACK_SIZE
 | 
			
		||||
	#error Missing definition:  configMINIMAL_STACK_SIZE must be defined in FreeRTOSConfig.h.  configMINIMAL_STACK_SIZE defines the size (in words) of the stack allocated to the idle task.  Refer to the demo project provided for your port for a suitable value.
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef configMAX_PRIORITIES
 | 
			
		||||
	#error Missing definition:  configMAX_PRIORITIES must be defined in FreeRTOSConfig.h.  See the Configuration section of the FreeRTOS API documentation for details.
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef configUSE_PREEMPTION
 | 
			
		||||
	#error Missing definition:  configUSE_PREEMPTION must be defined in FreeRTOSConfig.h as either 1 or 0.  See the Configuration section of the FreeRTOS API documentation for details.
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef configUSE_IDLE_HOOK
 | 
			
		||||
	#error Missing definition:  configUSE_IDLE_HOOK must be defined in FreeRTOSConfig.h as either 1 or 0.  See the Configuration section of the FreeRTOS API documentation for details.
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef configUSE_TICK_HOOK
 | 
			
		||||
	#error Missing definition:  configUSE_TICK_HOOK must be defined in FreeRTOSConfig.h as either 1 or 0.  See the Configuration section of the FreeRTOS API documentation for details.
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef configUSE_CO_ROUTINES
 | 
			
		||||
	#error  Missing definition:  configUSE_CO_ROUTINES must be defined in FreeRTOSConfig.h as either 1 or 0.  See the Configuration section of the FreeRTOS API documentation for details.
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef INCLUDE_vTaskPrioritySet
 | 
			
		||||
	#error Missing definition:  INCLUDE_vTaskPrioritySet must be defined in FreeRTOSConfig.h as either 1 or 0.  See the Configuration section of the FreeRTOS API documentation for details.
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef INCLUDE_uxTaskPriorityGet
 | 
			
		||||
	#error Missing definition:  INCLUDE_uxTaskPriorityGet must be defined in FreeRTOSConfig.h as either 1 or 0.  See the Configuration section of the FreeRTOS API documentation for details.
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef INCLUDE_vTaskDelete
 | 
			
		||||
	#error Missing definition:  INCLUDE_vTaskDelete must be defined in FreeRTOSConfig.h as either 1 or 0.  See the Configuration section of the FreeRTOS API documentation for details.
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef INCLUDE_vTaskSuspend
 | 
			
		||||
	#error Missing definition:  INCLUDE_vTaskSuspend must be defined in FreeRTOSConfig.h as either 1 or 0.  See the Configuration section of the FreeRTOS API documentation for details.
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef INCLUDE_vTaskDelayUntil
 | 
			
		||||
	#error Missing definition:  INCLUDE_vTaskDelayUntil must be defined in FreeRTOSConfig.h as either 1 or 0.  See the Configuration section of the FreeRTOS API documentation for details.
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef INCLUDE_vTaskDelay
 | 
			
		||||
	#error Missing definition:  INCLUDE_vTaskDelay must be defined in FreeRTOSConfig.h as either 1 or 0.  See the Configuration section of the FreeRTOS API documentation for details.
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef configUSE_16_BIT_TICKS
 | 
			
		||||
	#error Missing definition:  configUSE_16_BIT_TICKS must be defined in FreeRTOSConfig.h as either 1 or 0.  See the Configuration section of the FreeRTOS API documentation for details.
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if configUSE_CO_ROUTINES != 0
 | 
			
		||||
	#ifndef configMAX_CO_ROUTINE_PRIORITIES
 | 
			
		||||
		#error configMAX_CO_ROUTINE_PRIORITIES must be greater than or equal to 1.
 | 
			
		||||
	#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef configMAX_PRIORITIES
 | 
			
		||||
	#error configMAX_PRIORITIES must be defined to be greater than or equal to 1.
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef INCLUDE_xTaskGetIdleTaskHandle
 | 
			
		||||
	#define INCLUDE_xTaskGetIdleTaskHandle 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef INCLUDE_xTimerGetTimerDaemonTaskHandle
 | 
			
		||||
	#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef INCLUDE_xQueueGetMutexHolder
 | 
			
		||||
	#define INCLUDE_xQueueGetMutexHolder 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef INCLUDE_xSemaphoreGetMutexHolder
 | 
			
		||||
	#define INCLUDE_xSemaphoreGetMutexHolder INCLUDE_xQueueGetMutexHolder
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef INCLUDE_pcTaskGetTaskName
 | 
			
		||||
	#define INCLUDE_pcTaskGetTaskName 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef configUSE_APPLICATION_TASK_TAG
 | 
			
		||||
	#define configUSE_APPLICATION_TASK_TAG 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef INCLUDE_uxTaskGetStackHighWaterMark
 | 
			
		||||
	#define INCLUDE_uxTaskGetStackHighWaterMark 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef INCLUDE_eTaskGetState
 | 
			
		||||
	#define INCLUDE_eTaskGetState 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef configUSE_RECURSIVE_MUTEXES
 | 
			
		||||
	#define configUSE_RECURSIVE_MUTEXES 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef configUSE_MUTEXES
 | 
			
		||||
	#define configUSE_MUTEXES 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef configUSE_TIMERS
 | 
			
		||||
	#define configUSE_TIMERS 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef configUSE_COUNTING_SEMAPHORES
 | 
			
		||||
	#define configUSE_COUNTING_SEMAPHORES 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef configUSE_ALTERNATIVE_API
 | 
			
		||||
	#define configUSE_ALTERNATIVE_API 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef portCRITICAL_NESTING_IN_TCB
 | 
			
		||||
	#define portCRITICAL_NESTING_IN_TCB 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef configMAX_TASK_NAME_LEN
 | 
			
		||||
	#define configMAX_TASK_NAME_LEN 16
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef configIDLE_SHOULD_YIELD
 | 
			
		||||
	#define configIDLE_SHOULD_YIELD		1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if configMAX_TASK_NAME_LEN < 1
 | 
			
		||||
	#error configMAX_TASK_NAME_LEN must be set to a minimum of 1 in FreeRTOSConfig.h
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef INCLUDE_xTaskResumeFromISR
 | 
			
		||||
	#define INCLUDE_xTaskResumeFromISR 1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef INCLUDE_xEventGroupSetBitFromISR
 | 
			
		||||
	#define INCLUDE_xEventGroupSetBitFromISR 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef INCLUDE_xTimerPendFunctionCall
 | 
			
		||||
	#define INCLUDE_xTimerPendFunctionCall 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef configASSERT
 | 
			
		||||
	#define configASSERT( x )
 | 
			
		||||
	#define configASSERT_DEFINED 0
 | 
			
		||||
#else
 | 
			
		||||
	#define configASSERT_DEFINED 1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* The timers module relies on xTaskGetSchedulerState(). */
 | 
			
		||||
#if configUSE_TIMERS == 1
 | 
			
		||||
 | 
			
		||||
	#ifndef configTIMER_TASK_PRIORITY
 | 
			
		||||
		#error If configUSE_TIMERS is set to 1 then configTIMER_TASK_PRIORITY must also be defined.
 | 
			
		||||
	#endif /* configTIMER_TASK_PRIORITY */
 | 
			
		||||
 | 
			
		||||
	#ifndef configTIMER_QUEUE_LENGTH
 | 
			
		||||
		#error If configUSE_TIMERS is set to 1 then configTIMER_QUEUE_LENGTH must also be defined.
 | 
			
		||||
	#endif /* configTIMER_QUEUE_LENGTH */
 | 
			
		||||
 | 
			
		||||
	#ifndef configTIMER_TASK_STACK_DEPTH
 | 
			
		||||
		#error If configUSE_TIMERS is set to 1 then configTIMER_TASK_STACK_DEPTH must also be defined.
 | 
			
		||||
	#endif /* configTIMER_TASK_STACK_DEPTH */
 | 
			
		||||
 | 
			
		||||
#endif /* configUSE_TIMERS */
 | 
			
		||||
 | 
			
		||||
#ifndef INCLUDE_xTaskGetSchedulerState
 | 
			
		||||
	#define INCLUDE_xTaskGetSchedulerState 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef INCLUDE_xTaskGetCurrentTaskHandle
 | 
			
		||||
	#define INCLUDE_xTaskGetCurrentTaskHandle 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef portSET_INTERRUPT_MASK_FROM_ISR
 | 
			
		||||
	#define portSET_INTERRUPT_MASK_FROM_ISR() 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef portCLEAR_INTERRUPT_MASK_FROM_ISR
 | 
			
		||||
	#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusValue ) ( void ) uxSavedStatusValue
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef portCLEAN_UP_TCB
 | 
			
		||||
	#define portCLEAN_UP_TCB( pxTCB ) ( void ) pxTCB
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef portPRE_TASK_DELETE_HOOK
 | 
			
		||||
	#define portPRE_TASK_DELETE_HOOK( pvTaskToDelete, pxYieldPending )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef portSETUP_TCB
 | 
			
		||||
	#define portSETUP_TCB( pxTCB ) ( void ) pxTCB
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef configQUEUE_REGISTRY_SIZE
 | 
			
		||||
	#define configQUEUE_REGISTRY_SIZE 0U
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if ( configQUEUE_REGISTRY_SIZE < 1 )
 | 
			
		||||
	#define vQueueAddToRegistry( xQueue, pcName )
 | 
			
		||||
	#define vQueueUnregisterQueue( xQueue )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef portPOINTER_SIZE_TYPE
 | 
			
		||||
	#define portPOINTER_SIZE_TYPE uint32_t
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Remove any unused trace macros. */
 | 
			
		||||
#ifndef traceSTART
 | 
			
		||||
	/* Used to perform any necessary initialisation - for example, open a file
 | 
			
		||||
	into which trace is to be written. */
 | 
			
		||||
	#define traceSTART()
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceEND
 | 
			
		||||
	/* Use to close a trace, for example close a file into which trace has been
 | 
			
		||||
	written. */
 | 
			
		||||
	#define traceEND()
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceTASK_SWITCHED_IN
 | 
			
		||||
	/* Called after a task has been selected to run.  pxCurrentTCB holds a pointer
 | 
			
		||||
	to the task control block of the selected task. */
 | 
			
		||||
	#define traceTASK_SWITCHED_IN()
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceINCREASE_TICK_COUNT
 | 
			
		||||
	/* Called before stepping the tick count after waking from tickless idle
 | 
			
		||||
	sleep. */
 | 
			
		||||
	#define traceINCREASE_TICK_COUNT( x )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceLOW_POWER_IDLE_BEGIN
 | 
			
		||||
	/* Called immediately before entering tickless idle. */
 | 
			
		||||
	#define traceLOW_POWER_IDLE_BEGIN()
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef	traceLOW_POWER_IDLE_END
 | 
			
		||||
	/* Called when returning to the Idle task after a tickless idle. */
 | 
			
		||||
	#define traceLOW_POWER_IDLE_END()
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceTASK_SWITCHED_OUT
 | 
			
		||||
	/* Called before a task has been selected to run.  pxCurrentTCB holds a pointer
 | 
			
		||||
	to the task control block of the task being switched out. */
 | 
			
		||||
	#define traceTASK_SWITCHED_OUT()
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceTASK_PRIORITY_INHERIT
 | 
			
		||||
	/* Called when a task attempts to take a mutex that is already held by a
 | 
			
		||||
	lower priority task.  pxTCBOfMutexHolder is a pointer to the TCB of the task
 | 
			
		||||
	that holds the mutex.  uxInheritedPriority is the priority the mutex holder
 | 
			
		||||
	will inherit (the priority of the task that is attempting to obtain the
 | 
			
		||||
	muted. */
 | 
			
		||||
	#define traceTASK_PRIORITY_INHERIT( pxTCBOfMutexHolder, uxInheritedPriority )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceTASK_PRIORITY_DISINHERIT
 | 
			
		||||
	/* Called when a task releases a mutex, the holding of which had resulted in
 | 
			
		||||
	the task inheriting the priority of a higher priority task.
 | 
			
		||||
	pxTCBOfMutexHolder is a pointer to the TCB of the task that is releasing the
 | 
			
		||||
	mutex.  uxOriginalPriority is the task's configured (base) priority. */
 | 
			
		||||
	#define traceTASK_PRIORITY_DISINHERIT( pxTCBOfMutexHolder, uxOriginalPriority )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceBLOCKING_ON_QUEUE_RECEIVE
 | 
			
		||||
	/* Task is about to block because it cannot read from a
 | 
			
		||||
	queue/mutex/semaphore.  pxQueue is a pointer to the queue/mutex/semaphore
 | 
			
		||||
	upon which the read was attempted.  pxCurrentTCB points to the TCB of the
 | 
			
		||||
	task that attempted the read. */
 | 
			
		||||
	#define traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceBLOCKING_ON_QUEUE_SEND
 | 
			
		||||
	/* Task is about to block because it cannot write to a
 | 
			
		||||
	queue/mutex/semaphore.  pxQueue is a pointer to the queue/mutex/semaphore
 | 
			
		||||
	upon which the write was attempted.  pxCurrentTCB points to the TCB of the
 | 
			
		||||
	task that attempted the write. */
 | 
			
		||||
	#define traceBLOCKING_ON_QUEUE_SEND( pxQueue )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef configCHECK_FOR_STACK_OVERFLOW
 | 
			
		||||
	#define configCHECK_FOR_STACK_OVERFLOW 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* The following event macros are embedded in the kernel API calls. */
 | 
			
		||||
 | 
			
		||||
#ifndef traceMOVED_TASK_TO_READY_STATE
 | 
			
		||||
	#define traceMOVED_TASK_TO_READY_STATE( pxTCB )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceQUEUE_CREATE
 | 
			
		||||
	#define traceQUEUE_CREATE( pxNewQueue )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceQUEUE_CREATE_FAILED
 | 
			
		||||
	#define traceQUEUE_CREATE_FAILED( ucQueueType )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceCREATE_MUTEX
 | 
			
		||||
	#define traceCREATE_MUTEX( pxNewQueue )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceCREATE_MUTEX_FAILED
 | 
			
		||||
	#define traceCREATE_MUTEX_FAILED()
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceGIVE_MUTEX_RECURSIVE
 | 
			
		||||
	#define traceGIVE_MUTEX_RECURSIVE( pxMutex )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceGIVE_MUTEX_RECURSIVE_FAILED
 | 
			
		||||
	#define traceGIVE_MUTEX_RECURSIVE_FAILED( pxMutex )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceTAKE_MUTEX_RECURSIVE
 | 
			
		||||
	#define traceTAKE_MUTEX_RECURSIVE( pxMutex )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceTAKE_MUTEX_RECURSIVE_FAILED
 | 
			
		||||
	#define traceTAKE_MUTEX_RECURSIVE_FAILED( pxMutex )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceCREATE_COUNTING_SEMAPHORE
 | 
			
		||||
	#define traceCREATE_COUNTING_SEMAPHORE()
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceCREATE_COUNTING_SEMAPHORE_FAILED
 | 
			
		||||
	#define traceCREATE_COUNTING_SEMAPHORE_FAILED()
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceQUEUE_SEND
 | 
			
		||||
	#define traceQUEUE_SEND( pxQueue )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceQUEUE_SEND_FAILED
 | 
			
		||||
	#define traceQUEUE_SEND_FAILED( pxQueue )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceQUEUE_RECEIVE
 | 
			
		||||
	#define traceQUEUE_RECEIVE( pxQueue )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceQUEUE_PEEK
 | 
			
		||||
	#define traceQUEUE_PEEK( pxQueue )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceQUEUE_PEEK_FROM_ISR
 | 
			
		||||
	#define traceQUEUE_PEEK_FROM_ISR( pxQueue )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceQUEUE_RECEIVE_FAILED
 | 
			
		||||
	#define traceQUEUE_RECEIVE_FAILED( pxQueue )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceQUEUE_SEND_FROM_ISR
 | 
			
		||||
	#define traceQUEUE_SEND_FROM_ISR( pxQueue )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceQUEUE_SEND_FROM_ISR_FAILED
 | 
			
		||||
	#define traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceQUEUE_RECEIVE_FROM_ISR
 | 
			
		||||
	#define traceQUEUE_RECEIVE_FROM_ISR( pxQueue )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceQUEUE_RECEIVE_FROM_ISR_FAILED
 | 
			
		||||
	#define traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceQUEUE_PEEK_FROM_ISR_FAILED
 | 
			
		||||
	#define traceQUEUE_PEEK_FROM_ISR_FAILED( pxQueue )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceQUEUE_DELETE
 | 
			
		||||
	#define traceQUEUE_DELETE( pxQueue )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceTASK_CREATE
 | 
			
		||||
	#define traceTASK_CREATE( pxNewTCB )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceTASK_CREATE_FAILED
 | 
			
		||||
	#define traceTASK_CREATE_FAILED()
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceTASK_DELETE
 | 
			
		||||
	#define traceTASK_DELETE( pxTaskToDelete )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceTASK_DELAY_UNTIL
 | 
			
		||||
	#define traceTASK_DELAY_UNTIL()
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceTASK_DELAY
 | 
			
		||||
	#define traceTASK_DELAY()
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceTASK_PRIORITY_SET
 | 
			
		||||
	#define traceTASK_PRIORITY_SET( pxTask, uxNewPriority )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceTASK_SUSPEND
 | 
			
		||||
	#define traceTASK_SUSPEND( pxTaskToSuspend )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceTASK_RESUME
 | 
			
		||||
	#define traceTASK_RESUME( pxTaskToResume )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceTASK_RESUME_FROM_ISR
 | 
			
		||||
	#define traceTASK_RESUME_FROM_ISR( pxTaskToResume )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceTASK_INCREMENT_TICK
 | 
			
		||||
	#define traceTASK_INCREMENT_TICK( xTickCount )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceTIMER_CREATE
 | 
			
		||||
	#define traceTIMER_CREATE( pxNewTimer )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceTIMER_CREATE_FAILED
 | 
			
		||||
	#define traceTIMER_CREATE_FAILED()
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceTIMER_COMMAND_SEND
 | 
			
		||||
	#define traceTIMER_COMMAND_SEND( xTimer, xMessageID, xMessageValueValue, xReturn )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceTIMER_EXPIRED
 | 
			
		||||
	#define traceTIMER_EXPIRED( pxTimer )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceTIMER_COMMAND_RECEIVED
 | 
			
		||||
	#define traceTIMER_COMMAND_RECEIVED( pxTimer, xMessageID, xMessageValue )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceMALLOC
 | 
			
		||||
    #define traceMALLOC( pvAddress, uiSize )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceFREE
 | 
			
		||||
    #define traceFREE( pvAddress, uiSize )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceEVENT_GROUP_CREATE
 | 
			
		||||
	#define traceEVENT_GROUP_CREATE( xEventGroup )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceEVENT_GROUP_CREATE_FAILED
 | 
			
		||||
	#define traceEVENT_GROUP_CREATE_FAILED()
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceEVENT_GROUP_SYNC_BLOCK
 | 
			
		||||
	#define traceEVENT_GROUP_SYNC_BLOCK( xEventGroup, uxBitsToSet, uxBitsToWaitFor )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceEVENT_GROUP_SYNC_END
 | 
			
		||||
	#define traceEVENT_GROUP_SYNC_END( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTimeoutOccurred ) ( void ) xTimeoutOccurred
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceEVENT_GROUP_WAIT_BITS_BLOCK
 | 
			
		||||
	#define traceEVENT_GROUP_WAIT_BITS_BLOCK( xEventGroup, uxBitsToWaitFor )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceEVENT_GROUP_WAIT_BITS_END
 | 
			
		||||
	#define traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxBitsToWaitFor, xTimeoutOccurred ) ( void ) xTimeoutOccurred
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceEVENT_GROUP_CLEAR_BITS
 | 
			
		||||
	#define traceEVENT_GROUP_CLEAR_BITS( xEventGroup, uxBitsToClear )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceEVENT_GROUP_CLEAR_BITS_FROM_ISR
 | 
			
		||||
	#define traceEVENT_GROUP_CLEAR_BITS_FROM_ISR( xEventGroup, uxBitsToClear )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceEVENT_GROUP_SET_BITS
 | 
			
		||||
	#define traceEVENT_GROUP_SET_BITS( xEventGroup, uxBitsToSet )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceEVENT_GROUP_SET_BITS_FROM_ISR
 | 
			
		||||
	#define traceEVENT_GROUP_SET_BITS_FROM_ISR( xEventGroup, uxBitsToSet )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceEVENT_GROUP_DELETE
 | 
			
		||||
	#define traceEVENT_GROUP_DELETE( xEventGroup )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef tracePEND_FUNC_CALL
 | 
			
		||||
	#define tracePEND_FUNC_CALL(xFunctionToPend, pvParameter1, ulParameter2, ret)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef tracePEND_FUNC_CALL_FROM_ISR
 | 
			
		||||
	#define tracePEND_FUNC_CALL_FROM_ISR(xFunctionToPend, pvParameter1, ulParameter2, ret)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef traceQUEUE_REGISTRY_ADD
 | 
			
		||||
	#define traceQUEUE_REGISTRY_ADD(xQueue, pcQueueName)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef configGENERATE_RUN_TIME_STATS
 | 
			
		||||
	#define configGENERATE_RUN_TIME_STATS 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if ( configGENERATE_RUN_TIME_STATS == 1 )
 | 
			
		||||
 | 
			
		||||
	#ifndef configUSE_STATS_FORMATTING_FUNCTIONS
 | 
			
		||||
		#define configUSE_STATS_FORMATTING_FUNCTIONS 1
 | 
			
		||||
	#endif
 | 
			
		||||
 | 
			
		||||
	#ifndef portCONFIGURE_TIMER_FOR_RUN_TIME_STATS
 | 
			
		||||
		#error If configGENERATE_RUN_TIME_STATS is defined then portCONFIGURE_TIMER_FOR_RUN_TIME_STATS must also be defined.  portCONFIGURE_TIMER_FOR_RUN_TIME_STATS should call a port layer function to setup a peripheral timer/counter that can then be used as the run time counter time base.
 | 
			
		||||
	#endif /* portCONFIGURE_TIMER_FOR_RUN_TIME_STATS */
 | 
			
		||||
 | 
			
		||||
	#ifndef portGET_RUN_TIME_COUNTER_VALUE
 | 
			
		||||
		#ifndef portALT_GET_RUN_TIME_COUNTER_VALUE
 | 
			
		||||
			#error If configGENERATE_RUN_TIME_STATS is defined then either portGET_RUN_TIME_COUNTER_VALUE or portALT_GET_RUN_TIME_COUNTER_VALUE must also be defined.  See the examples provided and the FreeRTOS web site for more information.
 | 
			
		||||
		#endif /* portALT_GET_RUN_TIME_COUNTER_VALUE */
 | 
			
		||||
	#endif /* portGET_RUN_TIME_COUNTER_VALUE */
 | 
			
		||||
 | 
			
		||||
#endif /* configGENERATE_RUN_TIME_STATS */
 | 
			
		||||
 | 
			
		||||
#ifndef portCONFIGURE_TIMER_FOR_RUN_TIME_STATS
 | 
			
		||||
	#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef configUSE_MALLOC_FAILED_HOOK
 | 
			
		||||
	#define configUSE_MALLOC_FAILED_HOOK 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef portPRIVILEGE_BIT
 | 
			
		||||
	#define portPRIVILEGE_BIT ( ( UBaseType_t ) 0x00 )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef portYIELD_WITHIN_API
 | 
			
		||||
	#define portYIELD_WITHIN_API portYIELD
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef pvPortMallocAligned
 | 
			
		||||
	#define pvPortMallocAligned( x, puxStackBuffer ) ( ( ( puxStackBuffer ) == NULL ) ? ( pvPortMalloc( ( x ) ) ) : ( puxStackBuffer ) )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef vPortFreeAligned
 | 
			
		||||
	#define vPortFreeAligned( pvBlockToFree ) vPortFree( pvBlockToFree )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef portSUPPRESS_TICKS_AND_SLEEP
 | 
			
		||||
	#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef configEXPECTED_IDLE_TIME_BEFORE_SLEEP
 | 
			
		||||
	#define configEXPECTED_IDLE_TIME_BEFORE_SLEEP 2
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if configEXPECTED_IDLE_TIME_BEFORE_SLEEP < 2
 | 
			
		||||
	#error configEXPECTED_IDLE_TIME_BEFORE_SLEEP must not be less than 2
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef configUSE_TICKLESS_IDLE
 | 
			
		||||
	#define configUSE_TICKLESS_IDLE 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef configPRE_SLEEP_PROCESSING
 | 
			
		||||
	#define configPRE_SLEEP_PROCESSING( x )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef configPOST_SLEEP_PROCESSING
 | 
			
		||||
	#define configPOST_SLEEP_PROCESSING( x )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef configUSE_QUEUE_SETS
 | 
			
		||||
	#define configUSE_QUEUE_SETS 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef portTASK_USES_FLOATING_POINT
 | 
			
		||||
	#define portTASK_USES_FLOATING_POINT()
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef configUSE_TIME_SLICING
 | 
			
		||||
	#define configUSE_TIME_SLICING 1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS
 | 
			
		||||
	#define configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef configUSE_NEWLIB_REENTRANT
 | 
			
		||||
	#define configUSE_NEWLIB_REENTRANT 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef configUSE_STATS_FORMATTING_FUNCTIONS
 | 
			
		||||
	#define configUSE_STATS_FORMATTING_FUNCTIONS 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef portASSERT_IF_INTERRUPT_PRIORITY_INVALID
 | 
			
		||||
	#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID()
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef configUSE_TRACE_FACILITY
 | 
			
		||||
	#define configUSE_TRACE_FACILITY 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef mtCOVERAGE_TEST_MARKER
 | 
			
		||||
	#define mtCOVERAGE_TEST_MARKER()
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef portASSERT_IF_IN_ISR
 | 
			
		||||
	#define portASSERT_IF_IN_ISR()
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
 | 
			
		||||
	#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Definitions to allow backward compatibility with FreeRTOS versions prior to
 | 
			
		||||
V8 if desired. */
 | 
			
		||||
#ifndef configENABLE_BACKWARD_COMPATIBILITY
 | 
			
		||||
	#define configENABLE_BACKWARD_COMPATIBILITY 1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if configENABLE_BACKWARD_COMPATIBILITY == 1
 | 
			
		||||
	#define eTaskStateGet eTaskGetState
 | 
			
		||||
	#define portTickType TickType_t
 | 
			
		||||
	#define xTaskHandle TaskHandle_t
 | 
			
		||||
	#define xQueueHandle QueueHandle_t
 | 
			
		||||
	#define xSemaphoreHandle SemaphoreHandle_t
 | 
			
		||||
	#define xQueueSetHandle QueueSetHandle_t
 | 
			
		||||
	#define xQueueSetMemberHandle QueueSetMemberHandle_t
 | 
			
		||||
	#define xTimeOutType TimeOut_t
 | 
			
		||||
	#define xMemoryRegion MemoryRegion_t
 | 
			
		||||
	#define xTaskParameters TaskParameters_t
 | 
			
		||||
	#define xTaskStatusType	TaskStatus_t
 | 
			
		||||
	#define xTimerHandle TimerHandle_t
 | 
			
		||||
	#define xCoRoutineHandle CoRoutineHandle_t
 | 
			
		||||
	#define pdTASK_HOOK_CODE TaskHookFunction_t
 | 
			
		||||
	#define portTICK_RATE_MS portTICK_PERIOD_MS
 | 
			
		||||
 | 
			
		||||
	/* Backward compatibility within the scheduler code only - these definitions
 | 
			
		||||
	are not really required but are included for completeness. */
 | 
			
		||||
	#define tmrTIMER_CALLBACK TimerCallbackFunction_t
 | 
			
		||||
	#define pdTASK_CODE TaskFunction_t
 | 
			
		||||
	#define xListItem ListItem_t
 | 
			
		||||
	#define xList List_t
 | 
			
		||||
#endif /* configENABLE_BACKWARD_COMPATIBILITY */
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif /* INC_FREERTOS_H */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,180 @@
 | 
			
		|||
/*
 | 
			
		||||
    FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd.
 | 
			
		||||
    All rights reserved
 | 
			
		||||
 | 
			
		||||
    VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
 | 
			
		||||
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    FreeRTOS provides completely free yet professionally developed,    *
 | 
			
		||||
     *    robust, strictly quality controlled, supported, and cross          *
 | 
			
		||||
     *    platform software that has become a de facto standard.             *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    Help yourself get started quickly and support the FreeRTOS         *
 | 
			
		||||
     *    project by purchasing a FreeRTOS tutorial book, reference          *
 | 
			
		||||
     *    manual, or both from: http://www.FreeRTOS.org/Documentation        *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    Thank you!                                                         *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
 | 
			
		||||
    This file is part of the FreeRTOS distribution.
 | 
			
		||||
 | 
			
		||||
    FreeRTOS is free software; you can redistribute it and/or modify it under
 | 
			
		||||
    the terms of the GNU General Public License (version 2) as published by the
 | 
			
		||||
    Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
 | 
			
		||||
 | 
			
		||||
    >>!   NOTE: The modification to the GPL is included to allow you to     !<<
 | 
			
		||||
    >>!   distribute a combined work that includes FreeRTOS without being   !<<
 | 
			
		||||
    >>!   obliged to provide the source code for proprietary components     !<<
 | 
			
		||||
    >>!   outside of the FreeRTOS kernel.                                   !<<
 | 
			
		||||
 | 
			
		||||
    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
 | 
			
		||||
    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
    FOR A PARTICULAR PURPOSE.  Full license text is available from the following
 | 
			
		||||
    link: http://www.freertos.org/a00114.html
 | 
			
		||||
 | 
			
		||||
    1 tab == 4 spaces!
 | 
			
		||||
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    Having a problem?  Start by reading the FAQ "My application does   *
 | 
			
		||||
     *    not run, what could be wrong?"                                     *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    http://www.FreeRTOS.org/FAQHelp.html                               *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
 | 
			
		||||
    http://www.FreeRTOS.org - Documentation, books, training, latest versions,
 | 
			
		||||
    license and Real Time Engineers Ltd. contact details.
 | 
			
		||||
 | 
			
		||||
    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
 | 
			
		||||
    including FreeRTOS+Trace - an indispensable productivity tool, a DOS
 | 
			
		||||
    compatible FAT file system, and our tiny thread aware UDP/IP stack.
 | 
			
		||||
 | 
			
		||||
    http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
 | 
			
		||||
    Integrity Systems to sell under the OpenRTOS brand.  Low cost OpenRTOS
 | 
			
		||||
    licenses offer ticketed support, indemnification and middleware.
 | 
			
		||||
 | 
			
		||||
    http://www.SafeRTOS.com - High Integrity Systems also provide a safety
 | 
			
		||||
    engineered and independently SIL3 certified version for use in safety and
 | 
			
		||||
    mission critical applications that require provable dependability.
 | 
			
		||||
 | 
			
		||||
    1 tab == 4 spaces!
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef STACK_MACROS_H
 | 
			
		||||
#define STACK_MACROS_H
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Call the stack overflow hook function if the stack of the task being swapped
 | 
			
		||||
 * out is currently overflowed, or looks like it might have overflowed in the
 | 
			
		||||
 * past.
 | 
			
		||||
 *
 | 
			
		||||
 * Setting configCHECK_FOR_STACK_OVERFLOW to 1 will cause the macro to check
 | 
			
		||||
 * the current stack state only - comparing the current top of stack value to
 | 
			
		||||
 * the stack limit.  Setting configCHECK_FOR_STACK_OVERFLOW to greater than 1
 | 
			
		||||
 * will also cause the last few stack bytes to be checked to ensure the value
 | 
			
		||||
 * to which the bytes were set when the task was created have not been
 | 
			
		||||
 * overwritten.  Note this second test does not guarantee that an overflowed
 | 
			
		||||
 * stack will always be recognised.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
#if( configCHECK_FOR_STACK_OVERFLOW == 0 )
 | 
			
		||||
 | 
			
		||||
	/* FreeRTOSConfig.h is not set to check for stack overflows. */
 | 
			
		||||
	#define taskFIRST_CHECK_FOR_STACK_OVERFLOW()
 | 
			
		||||
	#define taskSECOND_CHECK_FOR_STACK_OVERFLOW()
 | 
			
		||||
 | 
			
		||||
#endif /* configCHECK_FOR_STACK_OVERFLOW == 0 */
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
#if( configCHECK_FOR_STACK_OVERFLOW == 1 )
 | 
			
		||||
 | 
			
		||||
	/* FreeRTOSConfig.h is only set to use the first method of
 | 
			
		||||
	overflow checking. */
 | 
			
		||||
	#define taskSECOND_CHECK_FOR_STACK_OVERFLOW()
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
#if( ( configCHECK_FOR_STACK_OVERFLOW > 0 ) && ( portSTACK_GROWTH < 0 ) )
 | 
			
		||||
 | 
			
		||||
	/* Only the current stack state is to be checked. */
 | 
			
		||||
	#define taskFIRST_CHECK_FOR_STACK_OVERFLOW()														\
 | 
			
		||||
	{																									\
 | 
			
		||||
		/* Is the currently saved stack pointer within the stack limit? */								\
 | 
			
		||||
		if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack )										\
 | 
			
		||||
		{																								\
 | 
			
		||||
			vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName );	\
 | 
			
		||||
		}																								\
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#endif /* configCHECK_FOR_STACK_OVERFLOW > 0 */
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
#if( ( configCHECK_FOR_STACK_OVERFLOW > 0 ) && ( portSTACK_GROWTH > 0 ) )
 | 
			
		||||
 | 
			
		||||
	/* Only the current stack state is to be checked. */
 | 
			
		||||
	#define taskFIRST_CHECK_FOR_STACK_OVERFLOW()														\
 | 
			
		||||
	{																									\
 | 
			
		||||
																										\
 | 
			
		||||
		/* Is the currently saved stack pointer within the stack limit? */								\
 | 
			
		||||
		if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack )									\
 | 
			
		||||
		{																								\
 | 
			
		||||
			vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName );	\
 | 
			
		||||
		}																								\
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) )
 | 
			
		||||
 | 
			
		||||
	#define taskSECOND_CHECK_FOR_STACK_OVERFLOW()																						\
 | 
			
		||||
	{																																	\
 | 
			
		||||
	static const uint8_t ucExpectedStackBytes[] = {	tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE,		\
 | 
			
		||||
													tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE,		\
 | 
			
		||||
													tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE,		\
 | 
			
		||||
													tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE,		\
 | 
			
		||||
													tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE };	\
 | 
			
		||||
																																		\
 | 
			
		||||
																																		\
 | 
			
		||||
		/* Has the extremity of the task stack ever been written over? */																\
 | 
			
		||||
		if( memcmp( ( void * ) pxCurrentTCB->pxStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 )			\
 | 
			
		||||
		{																																\
 | 
			
		||||
			vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName );									\
 | 
			
		||||
		}																																\
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) )
 | 
			
		||||
 | 
			
		||||
	#define taskSECOND_CHECK_FOR_STACK_OVERFLOW()																						\
 | 
			
		||||
	{																																	\
 | 
			
		||||
	int8_t *pcEndOfStack = ( int8_t * ) pxCurrentTCB->pxEndOfStack;																		\
 | 
			
		||||
	static const uint8_t ucExpectedStackBytes[] = {	tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE,		\
 | 
			
		||||
													tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE,		\
 | 
			
		||||
													tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE,		\
 | 
			
		||||
													tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE,		\
 | 
			
		||||
													tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE };	\
 | 
			
		||||
																																		\
 | 
			
		||||
																																		\
 | 
			
		||||
		pcEndOfStack -= sizeof( ucExpectedStackBytes );																					\
 | 
			
		||||
																																		\
 | 
			
		||||
		/* Has the extremity of the task stack ever been written over? */																\
 | 
			
		||||
		if( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 )					\
 | 
			
		||||
		{																																\
 | 
			
		||||
			vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName );									\
 | 
			
		||||
		}																																\
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
#endif /* STACK_MACROS_H */
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										758
									
								
								component/os/freertos/freertos_v8.1.2/Source/include/croutine.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										758
									
								
								component/os/freertos/freertos_v8.1.2/Source/include/croutine.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,758 @@
 | 
			
		|||
/*
 | 
			
		||||
    FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd.
 | 
			
		||||
    All rights reserved
 | 
			
		||||
 | 
			
		||||
    VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
 | 
			
		||||
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    FreeRTOS provides completely free yet professionally developed,    *
 | 
			
		||||
     *    robust, strictly quality controlled, supported, and cross          *
 | 
			
		||||
     *    platform software that has become a de facto standard.             *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    Help yourself get started quickly and support the FreeRTOS         *
 | 
			
		||||
     *    project by purchasing a FreeRTOS tutorial book, reference          *
 | 
			
		||||
     *    manual, or both from: http://www.FreeRTOS.org/Documentation        *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    Thank you!                                                         *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
 | 
			
		||||
    This file is part of the FreeRTOS distribution.
 | 
			
		||||
 | 
			
		||||
    FreeRTOS is free software; you can redistribute it and/or modify it under
 | 
			
		||||
    the terms of the GNU General Public License (version 2) as published by the
 | 
			
		||||
    Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
 | 
			
		||||
 | 
			
		||||
    >>!   NOTE: The modification to the GPL is included to allow you to     !<<
 | 
			
		||||
    >>!   distribute a combined work that includes FreeRTOS without being   !<<
 | 
			
		||||
    >>!   obliged to provide the source code for proprietary components     !<<
 | 
			
		||||
    >>!   outside of the FreeRTOS kernel.                                   !<<
 | 
			
		||||
 | 
			
		||||
    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
 | 
			
		||||
    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
    FOR A PARTICULAR PURPOSE.  Full license text is available from the following
 | 
			
		||||
    link: http://www.freertos.org/a00114.html
 | 
			
		||||
 | 
			
		||||
    1 tab == 4 spaces!
 | 
			
		||||
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    Having a problem?  Start by reading the FAQ "My application does   *
 | 
			
		||||
     *    not run, what could be wrong?"                                     *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    http://www.FreeRTOS.org/FAQHelp.html                               *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
 | 
			
		||||
    http://www.FreeRTOS.org - Documentation, books, training, latest versions,
 | 
			
		||||
    license and Real Time Engineers Ltd. contact details.
 | 
			
		||||
 | 
			
		||||
    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
 | 
			
		||||
    including FreeRTOS+Trace - an indispensable productivity tool, a DOS
 | 
			
		||||
    compatible FAT file system, and our tiny thread aware UDP/IP stack.
 | 
			
		||||
 | 
			
		||||
    http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
 | 
			
		||||
    Integrity Systems to sell under the OpenRTOS brand.  Low cost OpenRTOS
 | 
			
		||||
    licenses offer ticketed support, indemnification and middleware.
 | 
			
		||||
 | 
			
		||||
    http://www.SafeRTOS.com - High Integrity Systems also provide a safety
 | 
			
		||||
    engineered and independently SIL3 certified version for use in safety and
 | 
			
		||||
    mission critical applications that require provable dependability.
 | 
			
		||||
 | 
			
		||||
    1 tab == 4 spaces!
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef CO_ROUTINE_H
 | 
			
		||||
#define CO_ROUTINE_H
 | 
			
		||||
 | 
			
		||||
#ifndef INC_FREERTOS_H
 | 
			
		||||
	#error "include FreeRTOS.h must appear in source files before include croutine.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "list.h"
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Used to hide the implementation of the co-routine control block.  The
 | 
			
		||||
control block structure however has to be included in the header due to
 | 
			
		||||
the macro implementation of the co-routine functionality. */
 | 
			
		||||
typedef void * CoRoutineHandle_t;
 | 
			
		||||
 | 
			
		||||
/* Defines the prototype to which co-routine functions must conform. */
 | 
			
		||||
typedef void (*crCOROUTINE_CODE)( CoRoutineHandle_t, UBaseType_t );
 | 
			
		||||
 | 
			
		||||
typedef struct corCoRoutineControlBlock
 | 
			
		||||
{
 | 
			
		||||
	crCOROUTINE_CODE 	pxCoRoutineFunction;
 | 
			
		||||
	ListItem_t			xGenericListItem;	/*< List item used to place the CRCB in ready and blocked queues. */
 | 
			
		||||
	ListItem_t			xEventListItem;		/*< List item used to place the CRCB in event lists. */
 | 
			
		||||
	UBaseType_t 		uxPriority;			/*< The priority of the co-routine in relation to other co-routines. */
 | 
			
		||||
	UBaseType_t 		uxIndex;			/*< Used to distinguish between co-routines when multiple co-routines use the same co-routine function. */
 | 
			
		||||
	uint16_t 			uxState;			/*< Used internally by the co-routine implementation. */
 | 
			
		||||
} CRCB_t; /* Co-routine control block.  Note must be identical in size down to uxPriority with TCB_t. */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * croutine. h
 | 
			
		||||
 *<pre>
 | 
			
		||||
 BaseType_t xCoRoutineCreate(
 | 
			
		||||
                                 crCOROUTINE_CODE pxCoRoutineCode,
 | 
			
		||||
                                 UBaseType_t uxPriority,
 | 
			
		||||
                                 UBaseType_t uxIndex
 | 
			
		||||
                               );</pre>
 | 
			
		||||
 *
 | 
			
		||||
 * Create a new co-routine and add it to the list of co-routines that are
 | 
			
		||||
 * ready to run.
 | 
			
		||||
 *
 | 
			
		||||
 * @param pxCoRoutineCode Pointer to the co-routine function.  Co-routine
 | 
			
		||||
 * functions require special syntax - see the co-routine section of the WEB
 | 
			
		||||
 * documentation for more information.
 | 
			
		||||
 *
 | 
			
		||||
 * @param uxPriority The priority with respect to other co-routines at which
 | 
			
		||||
 *  the co-routine will run.
 | 
			
		||||
 *
 | 
			
		||||
 * @param uxIndex Used to distinguish between different co-routines that
 | 
			
		||||
 * execute the same function.  See the example below and the co-routine section
 | 
			
		||||
 * of the WEB documentation for further information.
 | 
			
		||||
 *
 | 
			
		||||
 * @return pdPASS if the co-routine was successfully created and added to a ready
 | 
			
		||||
 * list, otherwise an error code defined with ProjDefs.h.
 | 
			
		||||
 *
 | 
			
		||||
 * Example usage:
 | 
			
		||||
   <pre>
 | 
			
		||||
 // Co-routine to be created.
 | 
			
		||||
 void vFlashCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
 | 
			
		||||
 {
 | 
			
		||||
 // Variables in co-routines must be declared static if they must maintain value across a blocking call.
 | 
			
		||||
 // This may not be necessary for const variables.
 | 
			
		||||
 static const char cLedToFlash[ 2 ] = { 5, 6 };
 | 
			
		||||
 static const TickType_t uxFlashRates[ 2 ] = { 200, 400 };
 | 
			
		||||
 | 
			
		||||
     // Must start every co-routine with a call to crSTART();
 | 
			
		||||
     crSTART( xHandle );
 | 
			
		||||
 | 
			
		||||
     for( ;; )
 | 
			
		||||
     {
 | 
			
		||||
         // This co-routine just delays for a fixed period, then toggles
 | 
			
		||||
         // an LED.  Two co-routines are created using this function, so
 | 
			
		||||
         // the uxIndex parameter is used to tell the co-routine which
 | 
			
		||||
         // LED to flash and how int32_t to delay.  This assumes xQueue has
 | 
			
		||||
         // already been created.
 | 
			
		||||
         vParTestToggleLED( cLedToFlash[ uxIndex ] );
 | 
			
		||||
         crDELAY( xHandle, uxFlashRates[ uxIndex ] );
 | 
			
		||||
     }
 | 
			
		||||
 | 
			
		||||
     // Must end every co-routine with a call to crEND();
 | 
			
		||||
     crEND();
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
 // Function that creates two co-routines.
 | 
			
		||||
 void vOtherFunction( void )
 | 
			
		||||
 {
 | 
			
		||||
 uint8_t ucParameterToPass;
 | 
			
		||||
 TaskHandle_t xHandle;
 | 
			
		||||
 | 
			
		||||
     // Create two co-routines at priority 0.  The first is given index 0
 | 
			
		||||
     // so (from the code above) toggles LED 5 every 200 ticks.  The second
 | 
			
		||||
     // is given index 1 so toggles LED 6 every 400 ticks.
 | 
			
		||||
     for( uxIndex = 0; uxIndex < 2; uxIndex++ )
 | 
			
		||||
     {
 | 
			
		||||
         xCoRoutineCreate( vFlashCoRoutine, 0, uxIndex );
 | 
			
		||||
     }
 | 
			
		||||
 }
 | 
			
		||||
   </pre>
 | 
			
		||||
 * \defgroup xCoRoutineCreate xCoRoutineCreate
 | 
			
		||||
 * \ingroup Tasks
 | 
			
		||||
 */
 | 
			
		||||
BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, UBaseType_t uxPriority, UBaseType_t uxIndex );
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * croutine. h
 | 
			
		||||
 *<pre>
 | 
			
		||||
 void vCoRoutineSchedule( void );</pre>
 | 
			
		||||
 *
 | 
			
		||||
 * Run a co-routine.
 | 
			
		||||
 *
 | 
			
		||||
 * vCoRoutineSchedule() executes the highest priority co-routine that is able
 | 
			
		||||
 * to run.  The co-routine will execute until it either blocks, yields or is
 | 
			
		||||
 * preempted by a task.  Co-routines execute cooperatively so one
 | 
			
		||||
 * co-routine cannot be preempted by another, but can be preempted by a task.
 | 
			
		||||
 *
 | 
			
		||||
 * If an application comprises of both tasks and co-routines then
 | 
			
		||||
 * vCoRoutineSchedule should be called from the idle task (in an idle task
 | 
			
		||||
 * hook).
 | 
			
		||||
 *
 | 
			
		||||
 * Example usage:
 | 
			
		||||
   <pre>
 | 
			
		||||
 // This idle task hook will schedule a co-routine each time it is called.
 | 
			
		||||
 // The rest of the idle task will execute between co-routine calls.
 | 
			
		||||
 void vApplicationIdleHook( void )
 | 
			
		||||
 {
 | 
			
		||||
	vCoRoutineSchedule();
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
 // Alternatively, if you do not require any other part of the idle task to
 | 
			
		||||
 // execute, the idle task hook can call vCoRoutineScheduler() within an
 | 
			
		||||
 // infinite loop.
 | 
			
		||||
 void vApplicationIdleHook( void )
 | 
			
		||||
 {
 | 
			
		||||
    for( ;; )
 | 
			
		||||
    {
 | 
			
		||||
        vCoRoutineSchedule();
 | 
			
		||||
    }
 | 
			
		||||
 }
 | 
			
		||||
 </pre>
 | 
			
		||||
 * \defgroup vCoRoutineSchedule vCoRoutineSchedule
 | 
			
		||||
 * \ingroup Tasks
 | 
			
		||||
 */
 | 
			
		||||
void vCoRoutineSchedule( void );
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * croutine. h
 | 
			
		||||
 * <pre>
 | 
			
		||||
 crSTART( CoRoutineHandle_t xHandle );</pre>
 | 
			
		||||
 *
 | 
			
		||||
 * This macro MUST always be called at the start of a co-routine function.
 | 
			
		||||
 *
 | 
			
		||||
 * Example usage:
 | 
			
		||||
   <pre>
 | 
			
		||||
 // Co-routine to be created.
 | 
			
		||||
 void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
 | 
			
		||||
 {
 | 
			
		||||
 // Variables in co-routines must be declared static if they must maintain value across a blocking call.
 | 
			
		||||
 static int32_t ulAVariable;
 | 
			
		||||
 | 
			
		||||
     // Must start every co-routine with a call to crSTART();
 | 
			
		||||
     crSTART( xHandle );
 | 
			
		||||
 | 
			
		||||
     for( ;; )
 | 
			
		||||
     {
 | 
			
		||||
          // Co-routine functionality goes here.
 | 
			
		||||
     }
 | 
			
		||||
 | 
			
		||||
     // Must end every co-routine with a call to crEND();
 | 
			
		||||
     crEND();
 | 
			
		||||
 }</pre>
 | 
			
		||||
 * \defgroup crSTART crSTART
 | 
			
		||||
 * \ingroup Tasks
 | 
			
		||||
 */
 | 
			
		||||
#define crSTART( pxCRCB ) switch( ( ( CRCB_t * )( pxCRCB ) )->uxState ) { case 0:
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * croutine. h
 | 
			
		||||
 * <pre>
 | 
			
		||||
 crEND();</pre>
 | 
			
		||||
 *
 | 
			
		||||
 * This macro MUST always be called at the end of a co-routine function.
 | 
			
		||||
 *
 | 
			
		||||
 * Example usage:
 | 
			
		||||
   <pre>
 | 
			
		||||
 // Co-routine to be created.
 | 
			
		||||
 void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
 | 
			
		||||
 {
 | 
			
		||||
 // Variables in co-routines must be declared static if they must maintain value across a blocking call.
 | 
			
		||||
 static int32_t ulAVariable;
 | 
			
		||||
 | 
			
		||||
     // Must start every co-routine with a call to crSTART();
 | 
			
		||||
     crSTART( xHandle );
 | 
			
		||||
 | 
			
		||||
     for( ;; )
 | 
			
		||||
     {
 | 
			
		||||
          // Co-routine functionality goes here.
 | 
			
		||||
     }
 | 
			
		||||
 | 
			
		||||
     // Must end every co-routine with a call to crEND();
 | 
			
		||||
     crEND();
 | 
			
		||||
 }</pre>
 | 
			
		||||
 * \defgroup crSTART crSTART
 | 
			
		||||
 * \ingroup Tasks
 | 
			
		||||
 */
 | 
			
		||||
#define crEND() }
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * These macros are intended for internal use by the co-routine implementation
 | 
			
		||||
 * only.  The macros should not be used directly by application writers.
 | 
			
		||||
 */
 | 
			
		||||
#define crSET_STATE0( xHandle ) ( ( CRCB_t * )( xHandle ) )->uxState = (__LINE__ * 2); return; case (__LINE__ * 2):
 | 
			
		||||
#define crSET_STATE1( xHandle ) ( ( CRCB_t * )( xHandle ) )->uxState = ((__LINE__ * 2)+1); return; case ((__LINE__ * 2)+1):
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * croutine. h
 | 
			
		||||
 *<pre>
 | 
			
		||||
 crDELAY( CoRoutineHandle_t xHandle, TickType_t xTicksToDelay );</pre>
 | 
			
		||||
 *
 | 
			
		||||
 * Delay a co-routine for a fixed period of time.
 | 
			
		||||
 *
 | 
			
		||||
 * crDELAY can only be called from the co-routine function itself - not
 | 
			
		||||
 * from within a function called by the co-routine function.  This is because
 | 
			
		||||
 * co-routines do not maintain their own stack.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xHandle The handle of the co-routine to delay.  This is the xHandle
 | 
			
		||||
 * parameter of the co-routine function.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xTickToDelay The number of ticks that the co-routine should delay
 | 
			
		||||
 * for.  The actual amount of time this equates to is defined by
 | 
			
		||||
 * configTICK_RATE_HZ (set in FreeRTOSConfig.h).  The constant portTICK_PERIOD_MS
 | 
			
		||||
 * can be used to convert ticks to milliseconds.
 | 
			
		||||
 *
 | 
			
		||||
 * Example usage:
 | 
			
		||||
   <pre>
 | 
			
		||||
 // Co-routine to be created.
 | 
			
		||||
 void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
 | 
			
		||||
 {
 | 
			
		||||
 // Variables in co-routines must be declared static if they must maintain value across a blocking call.
 | 
			
		||||
 // This may not be necessary for const variables.
 | 
			
		||||
 // We are to delay for 200ms.
 | 
			
		||||
 static const xTickType xDelayTime = 200 / portTICK_PERIOD_MS;
 | 
			
		||||
 | 
			
		||||
     // Must start every co-routine with a call to crSTART();
 | 
			
		||||
     crSTART( xHandle );
 | 
			
		||||
 | 
			
		||||
     for( ;; )
 | 
			
		||||
     {
 | 
			
		||||
        // Delay for 200ms.
 | 
			
		||||
        crDELAY( xHandle, xDelayTime );
 | 
			
		||||
 | 
			
		||||
        // Do something here.
 | 
			
		||||
     }
 | 
			
		||||
 | 
			
		||||
     // Must end every co-routine with a call to crEND();
 | 
			
		||||
     crEND();
 | 
			
		||||
 }</pre>
 | 
			
		||||
 * \defgroup crDELAY crDELAY
 | 
			
		||||
 * \ingroup Tasks
 | 
			
		||||
 */
 | 
			
		||||
#define crDELAY( xHandle, xTicksToDelay )												\
 | 
			
		||||
	if( ( xTicksToDelay ) > 0 )															\
 | 
			
		||||
	{																					\
 | 
			
		||||
		vCoRoutineAddToDelayedList( ( xTicksToDelay ), NULL );							\
 | 
			
		||||
	}																					\
 | 
			
		||||
	crSET_STATE0( ( xHandle ) );
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * <pre>
 | 
			
		||||
 crQUEUE_SEND(
 | 
			
		||||
                  CoRoutineHandle_t xHandle,
 | 
			
		||||
                  QueueHandle_t pxQueue,
 | 
			
		||||
                  void *pvItemToQueue,
 | 
			
		||||
                  TickType_t xTicksToWait,
 | 
			
		||||
                  BaseType_t *pxResult
 | 
			
		||||
             )</pre>
 | 
			
		||||
 *
 | 
			
		||||
 * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine
 | 
			
		||||
 * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks.
 | 
			
		||||
 *
 | 
			
		||||
 * crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas
 | 
			
		||||
 * xQueueSend() and xQueueReceive() can only be used from tasks.
 | 
			
		||||
 *
 | 
			
		||||
 * crQUEUE_SEND can only be called from the co-routine function itself - not
 | 
			
		||||
 * from within a function called by the co-routine function.  This is because
 | 
			
		||||
 * co-routines do not maintain their own stack.
 | 
			
		||||
 *
 | 
			
		||||
 * See the co-routine section of the WEB documentation for information on
 | 
			
		||||
 * passing data between tasks and co-routines and between ISR's and
 | 
			
		||||
 * co-routines.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xHandle The handle of the calling co-routine.  This is the xHandle
 | 
			
		||||
 * parameter of the co-routine function.
 | 
			
		||||
 *
 | 
			
		||||
 * @param pxQueue The handle of the queue on which the data will be posted.
 | 
			
		||||
 * The handle is obtained as the return value when the queue is created using
 | 
			
		||||
 * the xQueueCreate() API function.
 | 
			
		||||
 *
 | 
			
		||||
 * @param pvItemToQueue A pointer to the data being posted onto the queue.
 | 
			
		||||
 * The number of bytes of each queued item is specified when the queue is
 | 
			
		||||
 * created.  This number of bytes is copied from pvItemToQueue into the queue
 | 
			
		||||
 * itself.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xTickToDelay The number of ticks that the co-routine should block
 | 
			
		||||
 * to wait for space to become available on the queue, should space not be
 | 
			
		||||
 * available immediately. The actual amount of time this equates to is defined
 | 
			
		||||
 * by configTICK_RATE_HZ (set in FreeRTOSConfig.h).  The constant
 | 
			
		||||
 * portTICK_PERIOD_MS can be used to convert ticks to milliseconds (see example
 | 
			
		||||
 * below).
 | 
			
		||||
 *
 | 
			
		||||
 * @param pxResult The variable pointed to by pxResult will be set to pdPASS if
 | 
			
		||||
 * data was successfully posted onto the queue, otherwise it will be set to an
 | 
			
		||||
 * error defined within ProjDefs.h.
 | 
			
		||||
 *
 | 
			
		||||
 * Example usage:
 | 
			
		||||
   <pre>
 | 
			
		||||
 // Co-routine function that blocks for a fixed period then posts a number onto
 | 
			
		||||
 // a queue.
 | 
			
		||||
 static void prvCoRoutineFlashTask( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
 | 
			
		||||
 {
 | 
			
		||||
 // Variables in co-routines must be declared static if they must maintain value across a blocking call.
 | 
			
		||||
 static BaseType_t xNumberToPost = 0;
 | 
			
		||||
 static BaseType_t xResult;
 | 
			
		||||
 | 
			
		||||
    // Co-routines must begin with a call to crSTART().
 | 
			
		||||
    crSTART( xHandle );
 | 
			
		||||
 | 
			
		||||
    for( ;; )
 | 
			
		||||
    {
 | 
			
		||||
        // This assumes the queue has already been created.
 | 
			
		||||
        crQUEUE_SEND( xHandle, xCoRoutineQueue, &xNumberToPost, NO_DELAY, &xResult );
 | 
			
		||||
 | 
			
		||||
        if( xResult != pdPASS )
 | 
			
		||||
        {
 | 
			
		||||
            // The message was not posted!
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Increment the number to be posted onto the queue.
 | 
			
		||||
        xNumberToPost++;
 | 
			
		||||
 | 
			
		||||
        // Delay for 100 ticks.
 | 
			
		||||
        crDELAY( xHandle, 100 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Co-routines must end with a call to crEND().
 | 
			
		||||
    crEND();
 | 
			
		||||
 }</pre>
 | 
			
		||||
 * \defgroup crQUEUE_SEND crQUEUE_SEND
 | 
			
		||||
 * \ingroup Tasks
 | 
			
		||||
 */
 | 
			
		||||
#define crQUEUE_SEND( xHandle, pxQueue, pvItemToQueue, xTicksToWait, pxResult )			\
 | 
			
		||||
{																						\
 | 
			
		||||
	*( pxResult ) = xQueueCRSend( ( pxQueue) , ( pvItemToQueue) , ( xTicksToWait ) );	\
 | 
			
		||||
	if( *( pxResult ) == errQUEUE_BLOCKED )												\
 | 
			
		||||
	{																					\
 | 
			
		||||
		crSET_STATE0( ( xHandle ) );													\
 | 
			
		||||
		*pxResult = xQueueCRSend( ( pxQueue ), ( pvItemToQueue ), 0 );					\
 | 
			
		||||
	}																					\
 | 
			
		||||
	if( *pxResult == errQUEUE_YIELD )													\
 | 
			
		||||
	{																					\
 | 
			
		||||
		crSET_STATE1( ( xHandle ) );													\
 | 
			
		||||
		*pxResult = pdPASS;																\
 | 
			
		||||
	}																					\
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * croutine. h
 | 
			
		||||
 * <pre>
 | 
			
		||||
  crQUEUE_RECEIVE(
 | 
			
		||||
                     CoRoutineHandle_t xHandle,
 | 
			
		||||
                     QueueHandle_t pxQueue,
 | 
			
		||||
                     void *pvBuffer,
 | 
			
		||||
                     TickType_t xTicksToWait,
 | 
			
		||||
                     BaseType_t *pxResult
 | 
			
		||||
                 )</pre>
 | 
			
		||||
 *
 | 
			
		||||
 * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine
 | 
			
		||||
 * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks.
 | 
			
		||||
 *
 | 
			
		||||
 * crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas
 | 
			
		||||
 * xQueueSend() and xQueueReceive() can only be used from tasks.
 | 
			
		||||
 *
 | 
			
		||||
 * crQUEUE_RECEIVE can only be called from the co-routine function itself - not
 | 
			
		||||
 * from within a function called by the co-routine function.  This is because
 | 
			
		||||
 * co-routines do not maintain their own stack.
 | 
			
		||||
 *
 | 
			
		||||
 * See the co-routine section of the WEB documentation for information on
 | 
			
		||||
 * passing data between tasks and co-routines and between ISR's and
 | 
			
		||||
 * co-routines.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xHandle The handle of the calling co-routine.  This is the xHandle
 | 
			
		||||
 * parameter of the co-routine function.
 | 
			
		||||
 *
 | 
			
		||||
 * @param pxQueue The handle of the queue from which the data will be received.
 | 
			
		||||
 * The handle is obtained as the return value when the queue is created using
 | 
			
		||||
 * the xQueueCreate() API function.
 | 
			
		||||
 *
 | 
			
		||||
 * @param pvBuffer The buffer into which the received item is to be copied.
 | 
			
		||||
 * The number of bytes of each queued item is specified when the queue is
 | 
			
		||||
 * created.  This number of bytes is copied into pvBuffer.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xTickToDelay The number of ticks that the co-routine should block
 | 
			
		||||
 * to wait for data to become available from the queue, should data not be
 | 
			
		||||
 * available immediately. The actual amount of time this equates to is defined
 | 
			
		||||
 * by configTICK_RATE_HZ (set in FreeRTOSConfig.h).  The constant
 | 
			
		||||
 * portTICK_PERIOD_MS can be used to convert ticks to milliseconds (see the
 | 
			
		||||
 * crQUEUE_SEND example).
 | 
			
		||||
 *
 | 
			
		||||
 * @param pxResult The variable pointed to by pxResult will be set to pdPASS if
 | 
			
		||||
 * data was successfully retrieved from the queue, otherwise it will be set to
 | 
			
		||||
 * an error code as defined within ProjDefs.h.
 | 
			
		||||
 *
 | 
			
		||||
 * Example usage:
 | 
			
		||||
 <pre>
 | 
			
		||||
 // A co-routine receives the number of an LED to flash from a queue.  It
 | 
			
		||||
 // blocks on the queue until the number is received.
 | 
			
		||||
 static void prvCoRoutineFlashWorkTask( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
 | 
			
		||||
 {
 | 
			
		||||
 // Variables in co-routines must be declared static if they must maintain value across a blocking call.
 | 
			
		||||
 static BaseType_t xResult;
 | 
			
		||||
 static UBaseType_t uxLEDToFlash;
 | 
			
		||||
 | 
			
		||||
    // All co-routines must start with a call to crSTART().
 | 
			
		||||
    crSTART( xHandle );
 | 
			
		||||
 | 
			
		||||
    for( ;; )
 | 
			
		||||
    {
 | 
			
		||||
        // Wait for data to become available on the queue.
 | 
			
		||||
        crQUEUE_RECEIVE( xHandle, xCoRoutineQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
 | 
			
		||||
 | 
			
		||||
        if( xResult == pdPASS )
 | 
			
		||||
        {
 | 
			
		||||
            // We received the LED to flash - flash it!
 | 
			
		||||
            vParTestToggleLED( uxLEDToFlash );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    crEND();
 | 
			
		||||
 }</pre>
 | 
			
		||||
 * \defgroup crQUEUE_RECEIVE crQUEUE_RECEIVE
 | 
			
		||||
 * \ingroup Tasks
 | 
			
		||||
 */
 | 
			
		||||
#define crQUEUE_RECEIVE( xHandle, pxQueue, pvBuffer, xTicksToWait, pxResult )			\
 | 
			
		||||
{																						\
 | 
			
		||||
	*( pxResult ) = xQueueCRReceive( ( pxQueue) , ( pvBuffer ), ( xTicksToWait ) );		\
 | 
			
		||||
	if( *( pxResult ) == errQUEUE_BLOCKED ) 											\
 | 
			
		||||
	{																					\
 | 
			
		||||
		crSET_STATE0( ( xHandle ) );													\
 | 
			
		||||
		*( pxResult ) = xQueueCRReceive( ( pxQueue) , ( pvBuffer ), 0 );				\
 | 
			
		||||
	}																					\
 | 
			
		||||
	if( *( pxResult ) == errQUEUE_YIELD )												\
 | 
			
		||||
	{																					\
 | 
			
		||||
		crSET_STATE1( ( xHandle ) );													\
 | 
			
		||||
		*( pxResult ) = pdPASS;															\
 | 
			
		||||
	}																					\
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * croutine. h
 | 
			
		||||
 * <pre>
 | 
			
		||||
  crQUEUE_SEND_FROM_ISR(
 | 
			
		||||
                            QueueHandle_t pxQueue,
 | 
			
		||||
                            void *pvItemToQueue,
 | 
			
		||||
                            BaseType_t xCoRoutinePreviouslyWoken
 | 
			
		||||
                       )</pre>
 | 
			
		||||
 *
 | 
			
		||||
 * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the
 | 
			
		||||
 * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR()
 | 
			
		||||
 * functions used by tasks.
 | 
			
		||||
 *
 | 
			
		||||
 * crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to
 | 
			
		||||
 * pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and
 | 
			
		||||
 * xQueueReceiveFromISR() can only be used to pass data between a task and and
 | 
			
		||||
 * ISR.
 | 
			
		||||
 *
 | 
			
		||||
 * crQUEUE_SEND_FROM_ISR can only be called from an ISR to send data to a queue
 | 
			
		||||
 * that is being used from within a co-routine.
 | 
			
		||||
 *
 | 
			
		||||
 * See the co-routine section of the WEB documentation for information on
 | 
			
		||||
 * passing data between tasks and co-routines and between ISR's and
 | 
			
		||||
 * co-routines.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xQueue The handle to the queue on which the item is to be posted.
 | 
			
		||||
 *
 | 
			
		||||
 * @param pvItemToQueue A pointer to the item that is to be placed on the
 | 
			
		||||
 * queue.  The size of the items the queue will hold was defined when the
 | 
			
		||||
 * queue was created, so this many bytes will be copied from pvItemToQueue
 | 
			
		||||
 * into the queue storage area.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xCoRoutinePreviouslyWoken This is included so an ISR can post onto
 | 
			
		||||
 * the same queue multiple times from a single interrupt.  The first call
 | 
			
		||||
 * should always pass in pdFALSE.  Subsequent calls should pass in
 | 
			
		||||
 * the value returned from the previous call.
 | 
			
		||||
 *
 | 
			
		||||
 * @return pdTRUE if a co-routine was woken by posting onto the queue.  This is
 | 
			
		||||
 * used by the ISR to determine if a context switch may be required following
 | 
			
		||||
 * the ISR.
 | 
			
		||||
 *
 | 
			
		||||
 * Example usage:
 | 
			
		||||
 <pre>
 | 
			
		||||
 // A co-routine that blocks on a queue waiting for characters to be received.
 | 
			
		||||
 static void vReceivingCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
 | 
			
		||||
 {
 | 
			
		||||
 char cRxedChar;
 | 
			
		||||
 BaseType_t xResult;
 | 
			
		||||
 | 
			
		||||
     // All co-routines must start with a call to crSTART().
 | 
			
		||||
     crSTART( xHandle );
 | 
			
		||||
 | 
			
		||||
     for( ;; )
 | 
			
		||||
     {
 | 
			
		||||
         // Wait for data to become available on the queue.  This assumes the
 | 
			
		||||
         // queue xCommsRxQueue has already been created!
 | 
			
		||||
         crQUEUE_RECEIVE( xHandle, xCommsRxQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
 | 
			
		||||
 | 
			
		||||
         // Was a character received?
 | 
			
		||||
         if( xResult == pdPASS )
 | 
			
		||||
         {
 | 
			
		||||
             // Process the character here.
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
 | 
			
		||||
     // All co-routines must end with a call to crEND().
 | 
			
		||||
     crEND();
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
 // An ISR that uses a queue to send characters received on a serial port to
 | 
			
		||||
 // a co-routine.
 | 
			
		||||
 void vUART_ISR( void )
 | 
			
		||||
 {
 | 
			
		||||
 char cRxedChar;
 | 
			
		||||
 BaseType_t xCRWokenByPost = pdFALSE;
 | 
			
		||||
 | 
			
		||||
     // We loop around reading characters until there are none left in the UART.
 | 
			
		||||
     while( UART_RX_REG_NOT_EMPTY() )
 | 
			
		||||
     {
 | 
			
		||||
         // Obtain the character from the UART.
 | 
			
		||||
         cRxedChar = UART_RX_REG;
 | 
			
		||||
 | 
			
		||||
         // Post the character onto a queue.  xCRWokenByPost will be pdFALSE
 | 
			
		||||
         // the first time around the loop.  If the post causes a co-routine
 | 
			
		||||
         // to be woken (unblocked) then xCRWokenByPost will be set to pdTRUE.
 | 
			
		||||
         // In this manner we can ensure that if more than one co-routine is
 | 
			
		||||
         // blocked on the queue only one is woken by this ISR no matter how
 | 
			
		||||
         // many characters are posted to the queue.
 | 
			
		||||
         xCRWokenByPost = crQUEUE_SEND_FROM_ISR( xCommsRxQueue, &cRxedChar, xCRWokenByPost );
 | 
			
		||||
     }
 | 
			
		||||
 }</pre>
 | 
			
		||||
 * \defgroup crQUEUE_SEND_FROM_ISR crQUEUE_SEND_FROM_ISR
 | 
			
		||||
 * \ingroup Tasks
 | 
			
		||||
 */
 | 
			
		||||
#define crQUEUE_SEND_FROM_ISR( pxQueue, pvItemToQueue, xCoRoutinePreviouslyWoken ) xQueueCRSendFromISR( ( pxQueue ), ( pvItemToQueue ), ( xCoRoutinePreviouslyWoken ) )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * croutine. h
 | 
			
		||||
 * <pre>
 | 
			
		||||
  crQUEUE_SEND_FROM_ISR(
 | 
			
		||||
                            QueueHandle_t pxQueue,
 | 
			
		||||
                            void *pvBuffer,
 | 
			
		||||
                            BaseType_t * pxCoRoutineWoken
 | 
			
		||||
                       )</pre>
 | 
			
		||||
 *
 | 
			
		||||
 * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the
 | 
			
		||||
 * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR()
 | 
			
		||||
 * functions used by tasks.
 | 
			
		||||
 *
 | 
			
		||||
 * crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to
 | 
			
		||||
 * pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and
 | 
			
		||||
 * xQueueReceiveFromISR() can only be used to pass data between a task and and
 | 
			
		||||
 * ISR.
 | 
			
		||||
 *
 | 
			
		||||
 * crQUEUE_RECEIVE_FROM_ISR can only be called from an ISR to receive data
 | 
			
		||||
 * from a queue that is being used from within a co-routine (a co-routine
 | 
			
		||||
 * posted to the queue).
 | 
			
		||||
 *
 | 
			
		||||
 * See the co-routine section of the WEB documentation for information on
 | 
			
		||||
 * passing data between tasks and co-routines and between ISR's and
 | 
			
		||||
 * co-routines.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xQueue The handle to the queue on which the item is to be posted.
 | 
			
		||||
 *
 | 
			
		||||
 * @param pvBuffer A pointer to a buffer into which the received item will be
 | 
			
		||||
 * placed.  The size of the items the queue will hold was defined when the
 | 
			
		||||
 * queue was created, so this many bytes will be copied from the queue into
 | 
			
		||||
 * pvBuffer.
 | 
			
		||||
 *
 | 
			
		||||
 * @param pxCoRoutineWoken A co-routine may be blocked waiting for space to become
 | 
			
		||||
 * available on the queue.  If crQUEUE_RECEIVE_FROM_ISR causes such a
 | 
			
		||||
 * co-routine to unblock *pxCoRoutineWoken will get set to pdTRUE, otherwise
 | 
			
		||||
 * *pxCoRoutineWoken will remain unchanged.
 | 
			
		||||
 *
 | 
			
		||||
 * @return pdTRUE an item was successfully received from the queue, otherwise
 | 
			
		||||
 * pdFALSE.
 | 
			
		||||
 *
 | 
			
		||||
 * Example usage:
 | 
			
		||||
 <pre>
 | 
			
		||||
 // A co-routine that posts a character to a queue then blocks for a fixed
 | 
			
		||||
 // period.  The character is incremented each time.
 | 
			
		||||
 static void vSendingCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
 | 
			
		||||
 {
 | 
			
		||||
 // cChar holds its value while this co-routine is blocked and must therefore
 | 
			
		||||
 // be declared static.
 | 
			
		||||
 static char cCharToTx = 'a';
 | 
			
		||||
 BaseType_t xResult;
 | 
			
		||||
 | 
			
		||||
     // All co-routines must start with a call to crSTART().
 | 
			
		||||
     crSTART( xHandle );
 | 
			
		||||
 | 
			
		||||
     for( ;; )
 | 
			
		||||
     {
 | 
			
		||||
         // Send the next character to the queue.
 | 
			
		||||
         crQUEUE_SEND( xHandle, xCoRoutineQueue, &cCharToTx, NO_DELAY, &xResult );
 | 
			
		||||
 | 
			
		||||
         if( xResult == pdPASS )
 | 
			
		||||
         {
 | 
			
		||||
             // The character was successfully posted to the queue.
 | 
			
		||||
         }
 | 
			
		||||
		 else
 | 
			
		||||
		 {
 | 
			
		||||
			// Could not post the character to the queue.
 | 
			
		||||
		 }
 | 
			
		||||
 | 
			
		||||
         // Enable the UART Tx interrupt to cause an interrupt in this
 | 
			
		||||
		 // hypothetical UART.  The interrupt will obtain the character
 | 
			
		||||
		 // from the queue and send it.
 | 
			
		||||
		 ENABLE_RX_INTERRUPT();
 | 
			
		||||
 | 
			
		||||
		 // Increment to the next character then block for a fixed period.
 | 
			
		||||
		 // cCharToTx will maintain its value across the delay as it is
 | 
			
		||||
		 // declared static.
 | 
			
		||||
		 cCharToTx++;
 | 
			
		||||
		 if( cCharToTx > 'x' )
 | 
			
		||||
		 {
 | 
			
		||||
			cCharToTx = 'a';
 | 
			
		||||
		 }
 | 
			
		||||
		 crDELAY( 100 );
 | 
			
		||||
     }
 | 
			
		||||
 | 
			
		||||
     // All co-routines must end with a call to crEND().
 | 
			
		||||
     crEND();
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
 // An ISR that uses a queue to receive characters to send on a UART.
 | 
			
		||||
 void vUART_ISR( void )
 | 
			
		||||
 {
 | 
			
		||||
 char cCharToTx;
 | 
			
		||||
 BaseType_t xCRWokenByPost = pdFALSE;
 | 
			
		||||
 | 
			
		||||
     while( UART_TX_REG_EMPTY() )
 | 
			
		||||
     {
 | 
			
		||||
         // Are there any characters in the queue waiting to be sent?
 | 
			
		||||
		 // xCRWokenByPost will automatically be set to pdTRUE if a co-routine
 | 
			
		||||
		 // is woken by the post - ensuring that only a single co-routine is
 | 
			
		||||
		 // woken no matter how many times we go around this loop.
 | 
			
		||||
         if( crQUEUE_RECEIVE_FROM_ISR( pxQueue, &cCharToTx, &xCRWokenByPost ) )
 | 
			
		||||
		 {
 | 
			
		||||
			 SEND_CHARACTER( cCharToTx );
 | 
			
		||||
		 }
 | 
			
		||||
     }
 | 
			
		||||
 }</pre>
 | 
			
		||||
 * \defgroup crQUEUE_RECEIVE_FROM_ISR crQUEUE_RECEIVE_FROM_ISR
 | 
			
		||||
 * \ingroup Tasks
 | 
			
		||||
 */
 | 
			
		||||
#define crQUEUE_RECEIVE_FROM_ISR( pxQueue, pvBuffer, pxCoRoutineWoken ) xQueueCRReceiveFromISR( ( pxQueue ), ( pvBuffer ), ( pxCoRoutineWoken ) )
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * This function is intended for internal use by the co-routine macros only.
 | 
			
		||||
 * The macro nature of the co-routine implementation requires that the
 | 
			
		||||
 * prototype appears here.  The function should not be used by application
 | 
			
		||||
 * writers.
 | 
			
		||||
 *
 | 
			
		||||
 * Removes the current co-routine from its ready list and places it in the
 | 
			
		||||
 * appropriate delayed list.
 | 
			
		||||
 */
 | 
			
		||||
void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay, List_t *pxEventList );
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * This function is intended for internal use by the queue implementation only.
 | 
			
		||||
 * The function should not be used by application writers.
 | 
			
		||||
 *
 | 
			
		||||
 * Removes the highest priority co-routine from the event list and places it in
 | 
			
		||||
 * the pending ready list.
 | 
			
		||||
 */
 | 
			
		||||
BaseType_t xCoRoutineRemoveFromEventList( const List_t *pxEventList );
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif /* CO_ROUTINE_H */
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,726 @@
 | 
			
		|||
/*
 | 
			
		||||
    FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd.
 | 
			
		||||
    All rights reserved
 | 
			
		||||
 | 
			
		||||
    VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
 | 
			
		||||
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    FreeRTOS provides completely free yet professionally developed,    *
 | 
			
		||||
     *    robust, strictly quality controlled, supported, and cross          *
 | 
			
		||||
     *    platform software that has become a de facto standard.             *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    Help yourself get started quickly and support the FreeRTOS         *
 | 
			
		||||
     *    project by purchasing a FreeRTOS tutorial book, reference          *
 | 
			
		||||
     *    manual, or both from: http://www.FreeRTOS.org/Documentation        *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    Thank you!                                                         *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
 | 
			
		||||
    This file is part of the FreeRTOS distribution.
 | 
			
		||||
 | 
			
		||||
    FreeRTOS is free software; you can redistribute it and/or modify it under
 | 
			
		||||
    the terms of the GNU General Public License (version 2) as published by the
 | 
			
		||||
    Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
 | 
			
		||||
 | 
			
		||||
    >>!   NOTE: The modification to the GPL is included to allow you to     !<<
 | 
			
		||||
    >>!   distribute a combined work that includes FreeRTOS without being   !<<
 | 
			
		||||
    >>!   obliged to provide the source code for proprietary components     !<<
 | 
			
		||||
    >>!   outside of the FreeRTOS kernel.                                   !<<
 | 
			
		||||
 | 
			
		||||
    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
 | 
			
		||||
    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
    FOR A PARTICULAR PURPOSE.  Full license text is available from the following
 | 
			
		||||
    link: http://www.freertos.org/a00114.html
 | 
			
		||||
 | 
			
		||||
    1 tab == 4 spaces!
 | 
			
		||||
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    Having a problem?  Start by reading the FAQ "My application does   *
 | 
			
		||||
     *    not run, what could be wrong?"                                     *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    http://www.FreeRTOS.org/FAQHelp.html                               *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
 | 
			
		||||
    http://www.FreeRTOS.org - Documentation, books, training, latest versions,
 | 
			
		||||
    license and Real Time Engineers Ltd. contact details.
 | 
			
		||||
 | 
			
		||||
    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
 | 
			
		||||
    including FreeRTOS+Trace - an indispensable productivity tool, a DOS
 | 
			
		||||
    compatible FAT file system, and our tiny thread aware UDP/IP stack.
 | 
			
		||||
 | 
			
		||||
    http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
 | 
			
		||||
    Integrity Systems to sell under the OpenRTOS brand.  Low cost OpenRTOS
 | 
			
		||||
    licenses offer ticketed support, indemnification and middleware.
 | 
			
		||||
 | 
			
		||||
    http://www.SafeRTOS.com - High Integrity Systems also provide a safety
 | 
			
		||||
    engineered and independently SIL3 certified version for use in safety and
 | 
			
		||||
    mission critical applications that require provable dependability.
 | 
			
		||||
 | 
			
		||||
    1 tab == 4 spaces!
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef EVENT_GROUPS_H
 | 
			
		||||
#define EVENT_GROUPS_H
 | 
			
		||||
 | 
			
		||||
#ifndef INC_FREERTOS_H
 | 
			
		||||
	#error "include FreeRTOS.h" must appear in source files before "include event_groups.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "timers.h"
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * An event group is a collection of bits to which an application can assign a
 | 
			
		||||
 * meaning.  For example, an application may create an event group to convey
 | 
			
		||||
 * the status of various CAN bus related events in which bit 0 might mean "A CAN
 | 
			
		||||
 * message has been received and is ready for processing", bit 1 might mean "The
 | 
			
		||||
 * application has queued a message that is ready for sending onto the CAN
 | 
			
		||||
 * network", and bit 2 might mean "It is time to send a SYNC message onto the
 | 
			
		||||
 * CAN network" etc.  A task can then test the bit values to see which events
 | 
			
		||||
 * are active, and optionally enter the Blocked state to wait for a specified
 | 
			
		||||
 * bit or a group of specified bits to be active.  To continue the CAN bus
 | 
			
		||||
 * example, a CAN controlling task can enter the Blocked state (and therefore
 | 
			
		||||
 * not consume any processing time) until either bit 0, bit 1 or bit 2 are
 | 
			
		||||
 * active, at which time the bit that was actually active would inform the task
 | 
			
		||||
 * which action it had to take (process a received message, send a message, or
 | 
			
		||||
 * send a SYNC).
 | 
			
		||||
 *
 | 
			
		||||
 * The event groups implementation contains intelligence to avoid race
 | 
			
		||||
 * conditions that would otherwise occur were an application to use a simple
 | 
			
		||||
 * variable for the same purpose.  This is particularly important with respect
 | 
			
		||||
 * to when a bit within an event group is to be cleared, and when bits have to
 | 
			
		||||
 * be set and then tested atomically - as is the case where event groups are
 | 
			
		||||
 * used to create a synchronisation point between multiple tasks (a
 | 
			
		||||
 * 'rendezvous').
 | 
			
		||||
 *
 | 
			
		||||
 * \defgroup EventGroup
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * event_groups.h
 | 
			
		||||
 *
 | 
			
		||||
 * Type by which event groups are referenced.  For example, a call to
 | 
			
		||||
 * xEventGroupCreate() returns an EventGroupHandle_t variable that can then
 | 
			
		||||
 * be used as a parameter to other event group functions.
 | 
			
		||||
 *
 | 
			
		||||
 * \defgroup EventGroupHandle_t EventGroupHandle_t
 | 
			
		||||
 * \ingroup EventGroup
 | 
			
		||||
 */
 | 
			
		||||
typedef void * EventGroupHandle_t;
 | 
			
		||||
 | 
			
		||||
/* 
 | 
			
		||||
 * The type that holds event bits always matches TickType_t - therefore the
 | 
			
		||||
 * number of bits it holds is set by configUSE_16_BIT_TICKS (16 bits if set to 1,
 | 
			
		||||
 * 32 bits if set to 0. 
 | 
			
		||||
 *
 | 
			
		||||
 * \defgroup EventBits_t EventBits_t
 | 
			
		||||
 * \ingroup EventGroup
 | 
			
		||||
 */
 | 
			
		||||
typedef TickType_t EventBits_t;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * event_groups.h
 | 
			
		||||
 *<pre>
 | 
			
		||||
 EventGroupHandle_t xEventGroupCreate( void );
 | 
			
		||||
 </pre>
 | 
			
		||||
 *
 | 
			
		||||
 * Create a new event group.  This function cannot be called from an interrupt.
 | 
			
		||||
 *
 | 
			
		||||
 * Although event groups are not related to ticks, for internal implementation
 | 
			
		||||
 * reasons the number of bits available for use in an event group is dependent
 | 
			
		||||
 * on the configUSE_16_BIT_TICKS setting in FreeRTOSConfig.h.  If
 | 
			
		||||
 * configUSE_16_BIT_TICKS is 1 then each event group contains 8 usable bits (bit
 | 
			
		||||
 * 0 to bit 7).  If configUSE_16_BIT_TICKS is set to 0 then each event group has
 | 
			
		||||
 * 24 usable bits (bit 0 to bit 23).  The EventBits_t type is used to store
 | 
			
		||||
 * event bits within an event group.
 | 
			
		||||
 *
 | 
			
		||||
 * @return If the event group was created then a handle to the event group is
 | 
			
		||||
 * returned.  If there was insufficient FreeRTOS heap available to create the
 | 
			
		||||
 * event group then NULL is returned.  See http://www.freertos.org/a00111.html
 | 
			
		||||
 *
 | 
			
		||||
 * Example usage:
 | 
			
		||||
   <pre>
 | 
			
		||||
	// Declare a variable to hold the created event group.
 | 
			
		||||
	EventGroupHandle_t xCreatedEventGroup;
 | 
			
		||||
 | 
			
		||||
	// Attempt to create the event group.
 | 
			
		||||
	xCreatedEventGroup = xEventGroupCreate();
 | 
			
		||||
 | 
			
		||||
	// Was the event group created successfully?
 | 
			
		||||
	if( xCreatedEventGroup == NULL )
 | 
			
		||||
	{
 | 
			
		||||
		// The event group was not created because there was insufficient
 | 
			
		||||
		// FreeRTOS heap available.
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		// The event group was created.
 | 
			
		||||
	}
 | 
			
		||||
   </pre>
 | 
			
		||||
 * \defgroup xEventGroupCreate xEventGroupCreate
 | 
			
		||||
 * \ingroup EventGroup
 | 
			
		||||
 */
 | 
			
		||||
EventGroupHandle_t xEventGroupCreate( void ) PRIVILEGED_FUNCTION;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * event_groups.h
 | 
			
		||||
 *<pre>
 | 
			
		||||
	EventBits_t xEventGroupWaitBits( 	EventGroupHandle_t xEventGroup,
 | 
			
		||||
										const EventBits_t uxBitsToWaitFor,
 | 
			
		||||
										const BaseType_t xClearOnExit,
 | 
			
		||||
										const BaseType_t xWaitForAllBits,
 | 
			
		||||
										const TickType_t xTicksToWait );
 | 
			
		||||
 </pre>
 | 
			
		||||
 *
 | 
			
		||||
 * [Potentially] block to wait for one or more bits to be set within a
 | 
			
		||||
 * previously created event group.
 | 
			
		||||
 *
 | 
			
		||||
 * This function cannot be called from an interrupt.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xEventGroup The event group in which the bits are being tested.  The
 | 
			
		||||
 * event group must have previously been created using a call to
 | 
			
		||||
 * xEventGroupCreate().
 | 
			
		||||
 *
 | 
			
		||||
 * @param uxBitsToWaitFor A bitwise value that indicates the bit or bits to test
 | 
			
		||||
 * inside the event group.  For example, to wait for bit 0 and/or bit 2 set
 | 
			
		||||
 * uxBitsToWaitFor to 0x05.  To wait for bits 0 and/or bit 1 and/or bit 2 set
 | 
			
		||||
 * uxBitsToWaitFor to 0x07.  Etc.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xClearOnExit If xClearOnExit is set to pdTRUE then any bits within
 | 
			
		||||
 * uxBitsToWaitFor that are set within the event group will be cleared before
 | 
			
		||||
 * xEventGroupWaitBits() returns if the wait condition was met (if the function
 | 
			
		||||
 * returns for a reason other than a timeout).  If xClearOnExit is set to
 | 
			
		||||
 * pdFALSE then the bits set in the event group are not altered when the call to
 | 
			
		||||
 * xEventGroupWaitBits() returns.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xWaitForAllBits If xWaitForAllBits is set to pdTRUE then
 | 
			
		||||
 * xEventGroupWaitBits() will return when either all the bits in uxBitsToWaitFor
 | 
			
		||||
 * are set or the specified block time expires.  If xWaitForAllBits is set to
 | 
			
		||||
 * pdFALSE then xEventGroupWaitBits() will return when any one of the bits set
 | 
			
		||||
 * in uxBitsToWaitFor is set or the specified block time expires.  The block
 | 
			
		||||
 * time is specified by the xTicksToWait parameter.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xTicksToWait The maximum amount of time (specified in 'ticks') to wait
 | 
			
		||||
 * for one/all (depending on the xWaitForAllBits value) of the bits specified by
 | 
			
		||||
 * uxBitsToWaitFor to become set.
 | 
			
		||||
 *
 | 
			
		||||
 * @return The value of the event group at the time either the bits being waited
 | 
			
		||||
 * for became set, or the block time expired.  Test the return value to know
 | 
			
		||||
 * which bits were set.  If xEventGroupWaitBits() returned because its timeout
 | 
			
		||||
 * expired then not all the bits being waited for will be set.  If
 | 
			
		||||
 * xEventGroupWaitBits() returned because the bits it was waiting for were set
 | 
			
		||||
 * then the returned value is the event group value before any bits were
 | 
			
		||||
 * automatically cleared in the case that xClearOnExit parameter was set to
 | 
			
		||||
 * pdTRUE.
 | 
			
		||||
 *
 | 
			
		||||
 * Example usage:
 | 
			
		||||
   <pre>
 | 
			
		||||
   #define BIT_0	( 1 << 0 )
 | 
			
		||||
   #define BIT_4	( 1 << 4 )
 | 
			
		||||
 | 
			
		||||
   void aFunction( EventGroupHandle_t xEventGroup )
 | 
			
		||||
   {
 | 
			
		||||
   EventBits_t uxBits;
 | 
			
		||||
   const TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS;
 | 
			
		||||
 | 
			
		||||
		// Wait a maximum of 100ms for either bit 0 or bit 4 to be set within
 | 
			
		||||
		// the event group.  Clear the bits before exiting.
 | 
			
		||||
		uxBits = xEventGroupWaitBits(
 | 
			
		||||
					xEventGroup,	// The event group being tested.
 | 
			
		||||
					BIT_0 | BIT_4,	// The bits within the event group to wait for.
 | 
			
		||||
					pdTRUE,			// BIT_0 and BIT_4 should be cleared before returning.
 | 
			
		||||
					pdFALSE,		// Don't wait for both bits, either bit will do.
 | 
			
		||||
					xTicksToWait );	// Wait a maximum of 100ms for either bit to be set.
 | 
			
		||||
 | 
			
		||||
		if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
 | 
			
		||||
		{
 | 
			
		||||
			// xEventGroupWaitBits() returned because both bits were set.
 | 
			
		||||
		}
 | 
			
		||||
		else if( ( uxBits & BIT_0 ) != 0 )
 | 
			
		||||
		{
 | 
			
		||||
			// xEventGroupWaitBits() returned because just BIT_0 was set.
 | 
			
		||||
		}
 | 
			
		||||
		else if( ( uxBits & BIT_4 ) != 0 )
 | 
			
		||||
		{
 | 
			
		||||
			// xEventGroupWaitBits() returned because just BIT_4 was set.
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			// xEventGroupWaitBits() returned because xTicksToWait ticks passed
 | 
			
		||||
			// without either BIT_0 or BIT_4 becoming set.
 | 
			
		||||
		}
 | 
			
		||||
   }
 | 
			
		||||
   </pre>
 | 
			
		||||
 * \defgroup xEventGroupWaitBits xEventGroupWaitBits
 | 
			
		||||
 * \ingroup EventGroup
 | 
			
		||||
 */
 | 
			
		||||
EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * event_groups.h
 | 
			
		||||
 *<pre>
 | 
			
		||||
	EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear );
 | 
			
		||||
 </pre>
 | 
			
		||||
 *
 | 
			
		||||
 * Clear bits within an event group.  This function cannot be called from an
 | 
			
		||||
 * interrupt.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xEventGroup The event group in which the bits are to be cleared.
 | 
			
		||||
 *
 | 
			
		||||
 * @param uxBitsToClear A bitwise value that indicates the bit or bits to clear
 | 
			
		||||
 * in the event group.  For example, to clear bit 3 only, set uxBitsToClear to
 | 
			
		||||
 * 0x08.  To clear bit 3 and bit 0 set uxBitsToClear to 0x09.
 | 
			
		||||
 *
 | 
			
		||||
 * @return The value of the event group before the specified bits were cleared.
 | 
			
		||||
 *
 | 
			
		||||
 * Example usage:
 | 
			
		||||
   <pre>
 | 
			
		||||
   #define BIT_0	( 1 << 0 )
 | 
			
		||||
   #define BIT_4	( 1 << 4 )
 | 
			
		||||
 | 
			
		||||
   void aFunction( EventGroupHandle_t xEventGroup )
 | 
			
		||||
   {
 | 
			
		||||
   EventBits_t uxBits;
 | 
			
		||||
 | 
			
		||||
		// Clear bit 0 and bit 4 in xEventGroup.
 | 
			
		||||
		uxBits = xEventGroupClearBits(
 | 
			
		||||
								xEventGroup,	// The event group being updated.
 | 
			
		||||
								BIT_0 | BIT_4 );// The bits being cleared.
 | 
			
		||||
 | 
			
		||||
		if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
 | 
			
		||||
		{
 | 
			
		||||
			// Both bit 0 and bit 4 were set before xEventGroupClearBits() was
 | 
			
		||||
			// called.  Both will now be clear (not set).
 | 
			
		||||
		}
 | 
			
		||||
		else if( ( uxBits & BIT_0 ) != 0 )
 | 
			
		||||
		{
 | 
			
		||||
			// Bit 0 was set before xEventGroupClearBits() was called.  It will
 | 
			
		||||
			// now be clear.
 | 
			
		||||
		}
 | 
			
		||||
		else if( ( uxBits & BIT_4 ) != 0 )
 | 
			
		||||
		{
 | 
			
		||||
			// Bit 4 was set before xEventGroupClearBits() was called.  It will
 | 
			
		||||
			// now be clear.
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			// Neither bit 0 nor bit 4 were set in the first place.
 | 
			
		||||
		}
 | 
			
		||||
   }
 | 
			
		||||
   </pre>
 | 
			
		||||
 * \defgroup xEventGroupClearBits xEventGroupClearBits
 | 
			
		||||
 * \ingroup EventGroup
 | 
			
		||||
 */
 | 
			
		||||
EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * event_groups.h
 | 
			
		||||
 *<pre>
 | 
			
		||||
	BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );
 | 
			
		||||
 </pre>
 | 
			
		||||
 *
 | 
			
		||||
 * A version of xEventGroupClearBits() that can be called from an interrupt.
 | 
			
		||||
 *
 | 
			
		||||
 * Setting bits in an event group is not a deterministic operation because there
 | 
			
		||||
 * are an unknown number of tasks that may be waiting for the bit or bits being
 | 
			
		||||
 * set.  FreeRTOS does not allow nondeterministic operations to be performed
 | 
			
		||||
 * while interrupts are disabled, so protects event groups that are accessed
 | 
			
		||||
 * from tasks by suspending the scheduler rather than disabling interrupts.  As
 | 
			
		||||
 * a result event groups cannot be accessed directly from an interrupt service
 | 
			
		||||
 * routine.  Therefore xEventGroupClearBitsFromISR() sends a message to the 
 | 
			
		||||
 * timer task to have the clear operation performed in the context of the timer 
 | 
			
		||||
 * task.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xEventGroup The event group in which the bits are to be cleared.
 | 
			
		||||
 *
 | 
			
		||||
 * @param uxBitsToClear A bitwise value that indicates the bit or bits to clear.
 | 
			
		||||
 * For example, to clear bit 3 only, set uxBitsToClear to 0x08.  To clear bit 3
 | 
			
		||||
 * and bit 0 set uxBitsToClear to 0x09.
 | 
			
		||||
 *
 | 
			
		||||
 * @return If the request to execute the function was posted successfully then 
 | 
			
		||||
 * pdPASS is returned, otherwise pdFALSE is returned.  pdFALSE will be returned 
 | 
			
		||||
 * if the timer service queue was full.
 | 
			
		||||
 *
 | 
			
		||||
 * Example usage:
 | 
			
		||||
   <pre>
 | 
			
		||||
   #define BIT_0	( 1 << 0 )
 | 
			
		||||
   #define BIT_4	( 1 << 4 )
 | 
			
		||||
 | 
			
		||||
   // An event group which it is assumed has already been created by a call to
 | 
			
		||||
   // xEventGroupCreate().
 | 
			
		||||
   EventGroupHandle_t xEventGroup;
 | 
			
		||||
 | 
			
		||||
   void anInterruptHandler( void )
 | 
			
		||||
   {
 | 
			
		||||
		// Clear bit 0 and bit 4 in xEventGroup.
 | 
			
		||||
		xResult = xEventGroupClearBitsFromISR(
 | 
			
		||||
							xEventGroup,	 // The event group being updated.
 | 
			
		||||
							BIT_0 | BIT_4 ); // The bits being set.
 | 
			
		||||
 | 
			
		||||
		if( xResult == pdPASS )
 | 
			
		||||
		{
 | 
			
		||||
			// The message was posted successfully.
 | 
			
		||||
		}
 | 
			
		||||
  }
 | 
			
		||||
   </pre>
 | 
			
		||||
 * \defgroup xEventGroupSetBitsFromISR xEventGroupSetBitsFromISR
 | 
			
		||||
 * \ingroup EventGroup
 | 
			
		||||
 */
 | 
			
		||||
#if( configUSE_TRACE_FACILITY == 1 )
 | 
			
		||||
	BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );
 | 
			
		||||
#else
 | 
			
		||||
	#define xEventGroupClearBitsFromISR( xEventGroup, uxBitsToClear ) xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * event_groups.h
 | 
			
		||||
 *<pre>
 | 
			
		||||
	EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );
 | 
			
		||||
 </pre>
 | 
			
		||||
 *
 | 
			
		||||
 * Set bits within an event group.
 | 
			
		||||
 * This function cannot be called from an interrupt.  xEventGroupSetBitsFromISR()
 | 
			
		||||
 * is a version that can be called from an interrupt.
 | 
			
		||||
 *
 | 
			
		||||
 * Setting bits in an event group will automatically unblock tasks that are
 | 
			
		||||
 * blocked waiting for the bits.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xEventGroup The event group in which the bits are to be set.
 | 
			
		||||
 *
 | 
			
		||||
 * @param uxBitsToSet A bitwise value that indicates the bit or bits to set.
 | 
			
		||||
 * For example, to set bit 3 only, set uxBitsToSet to 0x08.  To set bit 3
 | 
			
		||||
 * and bit 0 set uxBitsToSet to 0x09.
 | 
			
		||||
 *
 | 
			
		||||
 * @return The value of the event group at the time the call to
 | 
			
		||||
 * xEventGroupSetBits() returns.  There are two reasons why the returned value
 | 
			
		||||
 * might have the bits specified by the uxBitsToSet parameter cleared.  First,
 | 
			
		||||
 * if setting a bit results in a task that was waiting for the bit leaving the
 | 
			
		||||
 * blocked state then it is possible the bit will be cleared automatically
 | 
			
		||||
 * (see the xClearBitOnExit parameter of xEventGroupWaitBits()).  Second, any
 | 
			
		||||
 * unblocked (or otherwise Ready state) task that has a priority above that of
 | 
			
		||||
 * the task that called xEventGroupSetBits() will execute and may change the
 | 
			
		||||
 * event group value before the call to xEventGroupSetBits() returns.
 | 
			
		||||
 *
 | 
			
		||||
 * Example usage:
 | 
			
		||||
   <pre>
 | 
			
		||||
   #define BIT_0	( 1 << 0 )
 | 
			
		||||
   #define BIT_4	( 1 << 4 )
 | 
			
		||||
 | 
			
		||||
   void aFunction( EventGroupHandle_t xEventGroup )
 | 
			
		||||
   {
 | 
			
		||||
   EventBits_t uxBits;
 | 
			
		||||
 | 
			
		||||
		// Set bit 0 and bit 4 in xEventGroup.
 | 
			
		||||
		uxBits = xEventGroupSetBits(
 | 
			
		||||
							xEventGroup,	// The event group being updated.
 | 
			
		||||
							BIT_0 | BIT_4 );// The bits being set.
 | 
			
		||||
 | 
			
		||||
		if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
 | 
			
		||||
		{
 | 
			
		||||
			// Both bit 0 and bit 4 remained set when the function returned.
 | 
			
		||||
		}
 | 
			
		||||
		else if( ( uxBits & BIT_0 ) != 0 )
 | 
			
		||||
		{
 | 
			
		||||
			// Bit 0 remained set when the function returned, but bit 4 was
 | 
			
		||||
			// cleared.  It might be that bit 4 was cleared automatically as a
 | 
			
		||||
			// task that was waiting for bit 4 was removed from the Blocked
 | 
			
		||||
			// state.
 | 
			
		||||
		}
 | 
			
		||||
		else if( ( uxBits & BIT_4 ) != 0 )
 | 
			
		||||
		{
 | 
			
		||||
			// Bit 4 remained set when the function returned, but bit 0 was
 | 
			
		||||
			// cleared.  It might be that bit 0 was cleared automatically as a
 | 
			
		||||
			// task that was waiting for bit 0 was removed from the Blocked
 | 
			
		||||
			// state.
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			// Neither bit 0 nor bit 4 remained set.  It might be that a task
 | 
			
		||||
			// was waiting for both of the bits to be set, and the bits were
 | 
			
		||||
			// cleared as the task left the Blocked state.
 | 
			
		||||
		}
 | 
			
		||||
   }
 | 
			
		||||
   </pre>
 | 
			
		||||
 * \defgroup xEventGroupSetBits xEventGroupSetBits
 | 
			
		||||
 * \ingroup EventGroup
 | 
			
		||||
 */
 | 
			
		||||
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) PRIVILEGED_FUNCTION;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * event_groups.h
 | 
			
		||||
 *<pre>
 | 
			
		||||
	BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken );
 | 
			
		||||
 </pre>
 | 
			
		||||
 *
 | 
			
		||||
 * A version of xEventGroupSetBits() that can be called from an interrupt.
 | 
			
		||||
 *
 | 
			
		||||
 * Setting bits in an event group is not a deterministic operation because there
 | 
			
		||||
 * are an unknown number of tasks that may be waiting for the bit or bits being
 | 
			
		||||
 * set.  FreeRTOS does not allow nondeterministic operations to be performed in
 | 
			
		||||
 * interrupts or from critical sections.  Therefore xEventGroupSetBitFromISR()
 | 
			
		||||
 * sends a message to the timer task to have the set operation performed in the
 | 
			
		||||
 * context of the timer task - where a scheduler lock is used in place of a
 | 
			
		||||
 * critical section.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xEventGroup The event group in which the bits are to be set.
 | 
			
		||||
 *
 | 
			
		||||
 * @param uxBitsToSet A bitwise value that indicates the bit or bits to set.
 | 
			
		||||
 * For example, to set bit 3 only, set uxBitsToSet to 0x08.  To set bit 3
 | 
			
		||||
 * and bit 0 set uxBitsToSet to 0x09.
 | 
			
		||||
 *
 | 
			
		||||
 * @param pxHigherPriorityTaskWoken As mentioned above, calling this function
 | 
			
		||||
 * will result in a message being sent to the timer daemon task.  If the
 | 
			
		||||
 * priority of the timer daemon task is higher than the priority of the
 | 
			
		||||
 * currently running task (the task the interrupt interrupted) then
 | 
			
		||||
 * *pxHigherPriorityTaskWoken will be set to pdTRUE by
 | 
			
		||||
 * xEventGroupSetBitsFromISR(), indicating that a context switch should be
 | 
			
		||||
 * requested before the interrupt exits.  For that reason
 | 
			
		||||
 * *pxHigherPriorityTaskWoken must be initialised to pdFALSE.  See the
 | 
			
		||||
 * example code below.
 | 
			
		||||
 *
 | 
			
		||||
 * @return If the request to execute the function was posted successfully then 
 | 
			
		||||
 * pdPASS is returned, otherwise pdFALSE is returned.  pdFALSE will be returned 
 | 
			
		||||
 * if the timer service queue was full.
 | 
			
		||||
 *
 | 
			
		||||
 * Example usage:
 | 
			
		||||
   <pre>
 | 
			
		||||
   #define BIT_0	( 1 << 0 )
 | 
			
		||||
   #define BIT_4	( 1 << 4 )
 | 
			
		||||
 | 
			
		||||
   // An event group which it is assumed has already been created by a call to
 | 
			
		||||
   // xEventGroupCreate().
 | 
			
		||||
   EventGroupHandle_t xEventGroup;
 | 
			
		||||
 | 
			
		||||
   void anInterruptHandler( void )
 | 
			
		||||
   {
 | 
			
		||||
   BaseType_t xHigherPriorityTaskWoken, xResult;
 | 
			
		||||
 | 
			
		||||
		// xHigherPriorityTaskWoken must be initialised to pdFALSE.
 | 
			
		||||
		xHigherPriorityTaskWoken = pdFALSE;
 | 
			
		||||
 | 
			
		||||
		// Set bit 0 and bit 4 in xEventGroup.
 | 
			
		||||
		xResult = xEventGroupSetBitsFromISR(
 | 
			
		||||
							xEventGroup,	// The event group being updated.
 | 
			
		||||
							BIT_0 | BIT_4   // The bits being set.
 | 
			
		||||
							&xHigherPriorityTaskWoken );
 | 
			
		||||
 | 
			
		||||
		// Was the message posted successfully?
 | 
			
		||||
		if( xResult == pdPASS )
 | 
			
		||||
		{
 | 
			
		||||
			// If xHigherPriorityTaskWoken is now set to pdTRUE then a context
 | 
			
		||||
			// switch should be requested.  The macro used is port specific and 
 | 
			
		||||
			// will be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() - 
 | 
			
		||||
			// refer to the documentation page for the port being used.
 | 
			
		||||
			portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
 | 
			
		||||
		}
 | 
			
		||||
  }
 | 
			
		||||
   </pre>
 | 
			
		||||
 * \defgroup xEventGroupSetBitsFromISR xEventGroupSetBitsFromISR
 | 
			
		||||
 * \ingroup EventGroup
 | 
			
		||||
 */
 | 
			
		||||
#if( configUSE_TRACE_FACILITY == 1 )
 | 
			
		||||
	BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken );
 | 
			
		||||
#else
 | 
			
		||||
	#define xEventGroupSetBitsFromISR( xEventGroup, uxBitsToSet, pxHigherPriorityTaskWoken ) xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * event_groups.h
 | 
			
		||||
 *<pre>
 | 
			
		||||
	EventBits_t xEventGroupSync(	EventGroupHandle_t xEventGroup,
 | 
			
		||||
									const EventBits_t uxBitsToSet,
 | 
			
		||||
									const EventBits_t uxBitsToWaitFor,
 | 
			
		||||
									TickType_t xTicksToWait );
 | 
			
		||||
 </pre>
 | 
			
		||||
 *
 | 
			
		||||
 * Atomically set bits within an event group, then wait for a combination of
 | 
			
		||||
 * bits to be set within the same event group.  This functionality is typically
 | 
			
		||||
 * used to synchronise multiple tasks, where each task has to wait for the other
 | 
			
		||||
 * tasks to reach a synchronisation point before proceeding.
 | 
			
		||||
 *
 | 
			
		||||
 * This function cannot be used from an interrupt.
 | 
			
		||||
 *
 | 
			
		||||
 * The function will return before its block time expires if the bits specified
 | 
			
		||||
 * by the uxBitsToWait parameter are set, or become set within that time.  In
 | 
			
		||||
 * this case all the bits specified by uxBitsToWait will be automatically
 | 
			
		||||
 * cleared before the function returns.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xEventGroup The event group in which the bits are being tested.  The
 | 
			
		||||
 * event group must have previously been created using a call to
 | 
			
		||||
 * xEventGroupCreate().
 | 
			
		||||
 *
 | 
			
		||||
 * @param uxBitsToSet The bits to set in the event group before determining
 | 
			
		||||
 * if, and possibly waiting for, all the bits specified by the uxBitsToWait
 | 
			
		||||
 * parameter are set.
 | 
			
		||||
 *
 | 
			
		||||
 * @param uxBitsToWaitFor A bitwise value that indicates the bit or bits to test
 | 
			
		||||
 * inside the event group.  For example, to wait for bit 0 and bit 2 set
 | 
			
		||||
 * uxBitsToWaitFor to 0x05.  To wait for bits 0 and bit 1 and bit 2 set
 | 
			
		||||
 * uxBitsToWaitFor to 0x07.  Etc.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xTicksToWait The maximum amount of time (specified in 'ticks') to wait
 | 
			
		||||
 * for all of the bits specified by uxBitsToWaitFor to become set.
 | 
			
		||||
 *
 | 
			
		||||
 * @return The value of the event group at the time either the bits being waited
 | 
			
		||||
 * for became set, or the block time expired.  Test the return value to know
 | 
			
		||||
 * which bits were set.  If xEventGroupSync() returned because its timeout
 | 
			
		||||
 * expired then not all the bits being waited for will be set.  If
 | 
			
		||||
 * xEventGroupSync() returned because all the bits it was waiting for were
 | 
			
		||||
 * set then the returned value is the event group value before any bits were
 | 
			
		||||
 * automatically cleared.
 | 
			
		||||
 *
 | 
			
		||||
 * Example usage:
 | 
			
		||||
 <pre>
 | 
			
		||||
 // Bits used by the three tasks.
 | 
			
		||||
 #define TASK_0_BIT		( 1 << 0 )
 | 
			
		||||
 #define TASK_1_BIT		( 1 << 1 )
 | 
			
		||||
 #define TASK_2_BIT		( 1 << 2 )
 | 
			
		||||
 | 
			
		||||
 #define ALL_SYNC_BITS ( TASK_0_BIT | TASK_1_BIT | TASK_2_BIT )
 | 
			
		||||
 | 
			
		||||
 // Use an event group to synchronise three tasks.  It is assumed this event
 | 
			
		||||
 // group has already been created elsewhere.
 | 
			
		||||
 EventGroupHandle_t xEventBits;
 | 
			
		||||
 | 
			
		||||
 void vTask0( void *pvParameters )
 | 
			
		||||
 {
 | 
			
		||||
 EventBits_t uxReturn;
 | 
			
		||||
 TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS;
 | 
			
		||||
 | 
			
		||||
	 for( ;; )
 | 
			
		||||
	 {
 | 
			
		||||
		// Perform task functionality here.
 | 
			
		||||
 | 
			
		||||
		// Set bit 0 in the event flag to note this task has reached the
 | 
			
		||||
		// sync point.  The other two tasks will set the other two bits defined
 | 
			
		||||
		// by ALL_SYNC_BITS.  All three tasks have reached the synchronisation
 | 
			
		||||
		// point when all the ALL_SYNC_BITS are set.  Wait a maximum of 100ms
 | 
			
		||||
		// for this to happen.
 | 
			
		||||
		uxReturn = xEventGroupSync( xEventBits, TASK_0_BIT, ALL_SYNC_BITS, xTicksToWait );
 | 
			
		||||
 | 
			
		||||
		if( ( uxReturn & ALL_SYNC_BITS ) == ALL_SYNC_BITS )
 | 
			
		||||
		{
 | 
			
		||||
			// All three tasks reached the synchronisation point before the call
 | 
			
		||||
			// to xEventGroupSync() timed out.
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
 void vTask1( void *pvParameters )
 | 
			
		||||
 {
 | 
			
		||||
	 for( ;; )
 | 
			
		||||
	 {
 | 
			
		||||
		// Perform task functionality here.
 | 
			
		||||
 | 
			
		||||
		// Set bit 1 in the event flag to note this task has reached the
 | 
			
		||||
		// synchronisation point.  The other two tasks will set the other two
 | 
			
		||||
		// bits defined by ALL_SYNC_BITS.  All three tasks have reached the
 | 
			
		||||
		// synchronisation point when all the ALL_SYNC_BITS are set.  Wait
 | 
			
		||||
		// indefinitely for this to happen.
 | 
			
		||||
		xEventGroupSync( xEventBits, TASK_1_BIT, ALL_SYNC_BITS, portMAX_DELAY );
 | 
			
		||||
 | 
			
		||||
		// xEventGroupSync() was called with an indefinite block time, so
 | 
			
		||||
		// this task will only reach here if the syncrhonisation was made by all
 | 
			
		||||
		// three tasks, so there is no need to test the return value.
 | 
			
		||||
	 }
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
 void vTask2( void *pvParameters )
 | 
			
		||||
 {
 | 
			
		||||
	 for( ;; )
 | 
			
		||||
	 {
 | 
			
		||||
		// Perform task functionality here.
 | 
			
		||||
 | 
			
		||||
		// Set bit 2 in the event flag to note this task has reached the
 | 
			
		||||
		// synchronisation point.  The other two tasks will set the other two
 | 
			
		||||
		// bits defined by ALL_SYNC_BITS.  All three tasks have reached the
 | 
			
		||||
		// synchronisation point when all the ALL_SYNC_BITS are set.  Wait
 | 
			
		||||
		// indefinitely for this to happen.
 | 
			
		||||
		xEventGroupSync( xEventBits, TASK_2_BIT, ALL_SYNC_BITS, portMAX_DELAY );
 | 
			
		||||
 | 
			
		||||
		// xEventGroupSync() was called with an indefinite block time, so
 | 
			
		||||
		// this task will only reach here if the syncrhonisation was made by all
 | 
			
		||||
		// three tasks, so there is no need to test the return value.
 | 
			
		||||
	}
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
 </pre>
 | 
			
		||||
 * \defgroup xEventGroupSync xEventGroupSync
 | 
			
		||||
 * \ingroup EventGroup
 | 
			
		||||
 */
 | 
			
		||||
EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * event_groups.h
 | 
			
		||||
 *<pre>
 | 
			
		||||
	EventBits_t xEventGroupGetBits( EventGroupHandle_t xEventGroup );
 | 
			
		||||
 </pre>
 | 
			
		||||
 *
 | 
			
		||||
 * Returns the current value of the bits in an event group.  This function
 | 
			
		||||
 * cannot be used from an interrupt.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xEventGroup The event group being queried.
 | 
			
		||||
 *
 | 
			
		||||
 * @return The event group bits at the time xEventGroupGetBits() was called.
 | 
			
		||||
 *
 | 
			
		||||
 * \defgroup xEventGroupGetBits xEventGroupGetBits
 | 
			
		||||
 * \ingroup EventGroup
 | 
			
		||||
 */
 | 
			
		||||
#define xEventGroupGetBits( xEventGroup ) xEventGroupClearBits( xEventGroup, 0 )
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * event_groups.h
 | 
			
		||||
 *<pre>
 | 
			
		||||
	EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup );
 | 
			
		||||
 </pre>
 | 
			
		||||
 *
 | 
			
		||||
 * A version of xEventGroupGetBits() that can be called from an ISR.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xEventGroup The event group being queried.
 | 
			
		||||
 *
 | 
			
		||||
 * @return The event group bits at the time xEventGroupGetBitsFromISR() was called.
 | 
			
		||||
 *
 | 
			
		||||
 * \defgroup xEventGroupGetBitsFromISR xEventGroupGetBitsFromISR
 | 
			
		||||
 * \ingroup EventGroup
 | 
			
		||||
 */
 | 
			
		||||
EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup );
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * event_groups.h
 | 
			
		||||
 *<pre>
 | 
			
		||||
	void xEventGroupDelete( EventGroupHandle_t xEventGroup );
 | 
			
		||||
 </pre>
 | 
			
		||||
 *
 | 
			
		||||
 * Delete an event group that was previously created by a call to
 | 
			
		||||
 * xEventGroupCreate().  Tasks that are blocked on the event group will be
 | 
			
		||||
 * unblocked and obtain 0 as the event group's value.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xEventGroup The event group being deleted.
 | 
			
		||||
 */
 | 
			
		||||
void vEventGroupDelete( EventGroupHandle_t xEventGroup );
 | 
			
		||||
 | 
			
		||||
/* For internal use only. */
 | 
			
		||||
void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet );
 | 
			
		||||
void vEventGroupClearBitsCallback( void *pvEventGroup, const uint32_t ulBitsToClear );
 | 
			
		||||
 | 
			
		||||
#if (configUSE_TRACE_FACILITY == 1)
 | 
			
		||||
	UBaseType_t uxEventGroupGetNumber( void* xEventGroup );
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif /* EVENT_GROUPS_H */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										403
									
								
								component/os/freertos/freertos_v8.1.2/Source/include/list.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										403
									
								
								component/os/freertos/freertos_v8.1.2/Source/include/list.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,403 @@
 | 
			
		|||
/*
 | 
			
		||||
    FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd.
 | 
			
		||||
    All rights reserved
 | 
			
		||||
 | 
			
		||||
    VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
 | 
			
		||||
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    FreeRTOS provides completely free yet professionally developed,    *
 | 
			
		||||
     *    robust, strictly quality controlled, supported, and cross          *
 | 
			
		||||
     *    platform software that has become a de facto standard.             *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    Help yourself get started quickly and support the FreeRTOS         *
 | 
			
		||||
     *    project by purchasing a FreeRTOS tutorial book, reference          *
 | 
			
		||||
     *    manual, or both from: http://www.FreeRTOS.org/Documentation        *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    Thank you!                                                         *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
 | 
			
		||||
    This file is part of the FreeRTOS distribution.
 | 
			
		||||
 | 
			
		||||
    FreeRTOS is free software; you can redistribute it and/or modify it under
 | 
			
		||||
    the terms of the GNU General Public License (version 2) as published by the
 | 
			
		||||
    Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
 | 
			
		||||
 | 
			
		||||
    >>!   NOTE: The modification to the GPL is included to allow you to     !<<
 | 
			
		||||
    >>!   distribute a combined work that includes FreeRTOS without being   !<<
 | 
			
		||||
    >>!   obliged to provide the source code for proprietary components     !<<
 | 
			
		||||
    >>!   outside of the FreeRTOS kernel.                                   !<<
 | 
			
		||||
 | 
			
		||||
    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
 | 
			
		||||
    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
    FOR A PARTICULAR PURPOSE.  Full license text is available from the following
 | 
			
		||||
    link: http://www.freertos.org/a00114.html
 | 
			
		||||
 | 
			
		||||
    1 tab == 4 spaces!
 | 
			
		||||
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    Having a problem?  Start by reading the FAQ "My application does   *
 | 
			
		||||
     *    not run, what could be wrong?"                                     *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    http://www.FreeRTOS.org/FAQHelp.html                               *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
 | 
			
		||||
    http://www.FreeRTOS.org - Documentation, books, training, latest versions,
 | 
			
		||||
    license and Real Time Engineers Ltd. contact details.
 | 
			
		||||
 | 
			
		||||
    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
 | 
			
		||||
    including FreeRTOS+Trace - an indispensable productivity tool, a DOS
 | 
			
		||||
    compatible FAT file system, and our tiny thread aware UDP/IP stack.
 | 
			
		||||
 | 
			
		||||
    http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
 | 
			
		||||
    Integrity Systems to sell under the OpenRTOS brand.  Low cost OpenRTOS
 | 
			
		||||
    licenses offer ticketed support, indemnification and middleware.
 | 
			
		||||
 | 
			
		||||
    http://www.SafeRTOS.com - High Integrity Systems also provide a safety
 | 
			
		||||
    engineered and independently SIL3 certified version for use in safety and
 | 
			
		||||
    mission critical applications that require provable dependability.
 | 
			
		||||
 | 
			
		||||
    1 tab == 4 spaces!
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * This is the list implementation used by the scheduler.  While it is tailored
 | 
			
		||||
 * heavily for the schedulers needs, it is also available for use by
 | 
			
		||||
 * application code.
 | 
			
		||||
 *
 | 
			
		||||
 * list_ts can only store pointers to list_item_ts.  Each ListItem_t contains a
 | 
			
		||||
 * numeric value (xItemValue).  Most of the time the lists are sorted in
 | 
			
		||||
 * descending item value order.
 | 
			
		||||
 *
 | 
			
		||||
 * Lists are created already containing one list item.  The value of this
 | 
			
		||||
 * item is the maximum possible that can be stored, it is therefore always at
 | 
			
		||||
 * the end of the list and acts as a marker.  The list member pxHead always
 | 
			
		||||
 * points to this marker - even though it is at the tail of the list.  This
 | 
			
		||||
 * is because the tail contains a wrap back pointer to the true head of
 | 
			
		||||
 * the list.
 | 
			
		||||
 *
 | 
			
		||||
 * In addition to it's value, each list item contains a pointer to the next
 | 
			
		||||
 * item in the list (pxNext), a pointer to the list it is in (pxContainer)
 | 
			
		||||
 * and a pointer to back to the object that contains it.  These later two
 | 
			
		||||
 * pointers are included for efficiency of list manipulation.  There is
 | 
			
		||||
 * effectively a two way link between the object containing the list item and
 | 
			
		||||
 * the list item itself.
 | 
			
		||||
 *
 | 
			
		||||
 *
 | 
			
		||||
 * \page ListIntroduction List Implementation
 | 
			
		||||
 * \ingroup FreeRTOSIntro
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef LIST_H
 | 
			
		||||
#define LIST_H
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * The list structure members are modified from within interrupts, and therefore
 | 
			
		||||
 * by rights should be declared volatile.  However, they are only modified in a
 | 
			
		||||
 * functionally atomic way (within critical sections of with the scheduler
 | 
			
		||||
 * suspended) and are either passed by reference into a function or indexed via
 | 
			
		||||
 * a volatile variable.  Therefore, in all use cases tested so far, the volatile
 | 
			
		||||
 * qualifier can be omitted in order to provide a moderate performance
 | 
			
		||||
 * improvement without adversely affecting functional behaviour.  The assembly
 | 
			
		||||
 * instructions generated by the IAR, ARM and GCC compilers when the respective
 | 
			
		||||
 * compiler's options were set for maximum optimisation has been inspected and
 | 
			
		||||
 * deemed to be as intended.  That said, as compiler technology advances, and
 | 
			
		||||
 * especially if aggressive cross module optimisation is used (a use case that
 | 
			
		||||
 * has not been exercised to any great extend) then it is feasible that the
 | 
			
		||||
 * volatile qualifier will be needed for correct optimisation.  It is expected
 | 
			
		||||
 * that a compiler removing essential code because, without the volatile
 | 
			
		||||
 * qualifier on the list structure members and with aggressive cross module
 | 
			
		||||
 * optimisation, the compiler deemed the code unnecessary will result in
 | 
			
		||||
 * complete and obvious failure of the scheduler.  If this is ever experienced
 | 
			
		||||
 * then the volatile qualifier can be inserted in the relevant places within the
 | 
			
		||||
 * list structures by simply defining configLIST_VOLATILE to volatile in
 | 
			
		||||
 * FreeRTOSConfig.h (as per the example at the bottom of this comment block).
 | 
			
		||||
 * If configLIST_VOLATILE is not defined then the preprocessor directives below
 | 
			
		||||
 * will simply #define configLIST_VOLATILE away completely.
 | 
			
		||||
 *
 | 
			
		||||
 * To use volatile list structure members then add the following line to
 | 
			
		||||
 * FreeRTOSConfig.h (without the quotes):
 | 
			
		||||
 * "#define configLIST_VOLATILE volatile"
 | 
			
		||||
 */
 | 
			
		||||
#ifndef configLIST_VOLATILE
 | 
			
		||||
	#define configLIST_VOLATILE
 | 
			
		||||
#endif /* configSUPPORT_CROSS_MODULE_OPTIMISATION */
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
/*
 | 
			
		||||
 * Definition of the only type of object that a list can contain.
 | 
			
		||||
 */
 | 
			
		||||
struct xLIST_ITEM
 | 
			
		||||
{
 | 
			
		||||
	configLIST_VOLATILE TickType_t xItemValue;			/*< The value being listed.  In most cases this is used to sort the list in descending order. */
 | 
			
		||||
	struct xLIST_ITEM * configLIST_VOLATILE pxNext;		/*< Pointer to the next ListItem_t in the list. */
 | 
			
		||||
	struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;	/*< Pointer to the previous ListItem_t in the list. */
 | 
			
		||||
	void * pvOwner;										/*< Pointer to the object (normally a TCB) that contains the list item.  There is therefore a two way link between the object containing the list item and the list item itself. */
 | 
			
		||||
	void * configLIST_VOLATILE pvContainer;				/*< Pointer to the list in which this list item is placed (if any). */
 | 
			
		||||
};
 | 
			
		||||
typedef struct xLIST_ITEM ListItem_t;					/* For some reason lint wants this as two separate definitions. */
 | 
			
		||||
 | 
			
		||||
struct xMINI_LIST_ITEM
 | 
			
		||||
{
 | 
			
		||||
	configLIST_VOLATILE TickType_t xItemValue;
 | 
			
		||||
	struct xLIST_ITEM * configLIST_VOLATILE pxNext;
 | 
			
		||||
	struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;
 | 
			
		||||
};
 | 
			
		||||
typedef struct xMINI_LIST_ITEM MiniListItem_t;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Definition of the type of queue used by the scheduler.
 | 
			
		||||
 */
 | 
			
		||||
typedef struct xLIST
 | 
			
		||||
{
 | 
			
		||||
	configLIST_VOLATILE UBaseType_t uxNumberOfItems;
 | 
			
		||||
	ListItem_t * configLIST_VOLATILE pxIndex;		/*< Used to walk through the list.  Points to the last item returned by a call to listGET_OWNER_OF_NEXT_ENTRY (). */
 | 
			
		||||
	MiniListItem_t xListEnd;						/*< List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */
 | 
			
		||||
} List_t;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Access macro to set the owner of a list item.  The owner of a list item
 | 
			
		||||
 * is the object (usually a TCB) that contains the list item.
 | 
			
		||||
 *
 | 
			
		||||
 * \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER
 | 
			
		||||
 * \ingroup LinkedList
 | 
			
		||||
 */
 | 
			
		||||
#define listSET_LIST_ITEM_OWNER( pxListItem, pxOwner )		( ( pxListItem )->pvOwner = ( void * ) ( pxOwner ) )
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Access macro to get the owner of a list item.  The owner of a list item
 | 
			
		||||
 * is the object (usually a TCB) that contains the list item.
 | 
			
		||||
 *
 | 
			
		||||
 * \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER
 | 
			
		||||
 * \ingroup LinkedList
 | 
			
		||||
 */
 | 
			
		||||
#define listGET_LIST_ITEM_OWNER( pxListItem )	( ( pxListItem )->pvOwner )
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Access macro to set the value of the list item.  In most cases the value is
 | 
			
		||||
 * used to sort the list in descending order.
 | 
			
		||||
 *
 | 
			
		||||
 * \page listSET_LIST_ITEM_VALUE listSET_LIST_ITEM_VALUE
 | 
			
		||||
 * \ingroup LinkedList
 | 
			
		||||
 */
 | 
			
		||||
#define listSET_LIST_ITEM_VALUE( pxListItem, xValue )	( ( pxListItem )->xItemValue = ( xValue ) )
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Access macro to retrieve the value of the list item.  The value can
 | 
			
		||||
 * represent anything - for example the priority of a task, or the time at
 | 
			
		||||
 * which a task should be unblocked.
 | 
			
		||||
 *
 | 
			
		||||
 * \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE
 | 
			
		||||
 * \ingroup LinkedList
 | 
			
		||||
 */
 | 
			
		||||
#define listGET_LIST_ITEM_VALUE( pxListItem )	( ( pxListItem )->xItemValue )
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Access macro to retrieve the value of the list item at the head of a given
 | 
			
		||||
 * list.
 | 
			
		||||
 *
 | 
			
		||||
 * \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE
 | 
			
		||||
 * \ingroup LinkedList
 | 
			
		||||
 */
 | 
			
		||||
#define listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxList )	( ( ( pxList )->xListEnd ).pxNext->xItemValue )
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Return the list item at the head of the list.
 | 
			
		||||
 *
 | 
			
		||||
 * \page listGET_HEAD_ENTRY listGET_HEAD_ENTRY
 | 
			
		||||
 * \ingroup LinkedList
 | 
			
		||||
 */
 | 
			
		||||
#define listGET_HEAD_ENTRY( pxList )	( ( ( pxList )->xListEnd ).pxNext )
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Return the list item at the head of the list.
 | 
			
		||||
 *
 | 
			
		||||
 * \page listGET_NEXT listGET_NEXT
 | 
			
		||||
 * \ingroup LinkedList
 | 
			
		||||
 */
 | 
			
		||||
#define listGET_NEXT( pxListItem )	( ( pxListItem )->pxNext )
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Return the list item that marks the end of the list
 | 
			
		||||
 *
 | 
			
		||||
 * \page listGET_END_MARKER listGET_END_MARKER
 | 
			
		||||
 * \ingroup LinkedList
 | 
			
		||||
 */
 | 
			
		||||
#define listGET_END_MARKER( pxList )	( ( ListItem_t const * ) ( &( ( pxList )->xListEnd ) ) )
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Access macro to determine if a list contains any items.  The macro will
 | 
			
		||||
 * only have the value true if the list is empty.
 | 
			
		||||
 *
 | 
			
		||||
 * \page listLIST_IS_EMPTY listLIST_IS_EMPTY
 | 
			
		||||
 * \ingroup LinkedList
 | 
			
		||||
 */
 | 
			
		||||
#define listLIST_IS_EMPTY( pxList )	( ( BaseType_t ) ( ( pxList )->uxNumberOfItems == ( UBaseType_t ) 0 ) )
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Access macro to return the number of items in the list.
 | 
			
		||||
 */
 | 
			
		||||
#define listCURRENT_LIST_LENGTH( pxList )	( ( pxList )->uxNumberOfItems )
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Access function to obtain the owner of the next entry in a list.
 | 
			
		||||
 *
 | 
			
		||||
 * The list member pxIndex is used to walk through a list.  Calling
 | 
			
		||||
 * listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list
 | 
			
		||||
 * and returns that entry's pxOwner parameter.  Using multiple calls to this
 | 
			
		||||
 * function it is therefore possible to move through every item contained in
 | 
			
		||||
 * a list.
 | 
			
		||||
 *
 | 
			
		||||
 * The pxOwner parameter of a list item is a pointer to the object that owns
 | 
			
		||||
 * the list item.  In the scheduler this is normally a task control block.
 | 
			
		||||
 * The pxOwner parameter effectively creates a two way link between the list
 | 
			
		||||
 * item and its owner.
 | 
			
		||||
 *
 | 
			
		||||
 * @param pxTCB pxTCB is set to the address of the owner of the next list item.
 | 
			
		||||
 * @param pxList The list from which the next item owner is to be returned.
 | 
			
		||||
 *
 | 
			
		||||
 * \page listGET_OWNER_OF_NEXT_ENTRY listGET_OWNER_OF_NEXT_ENTRY
 | 
			
		||||
 * \ingroup LinkedList
 | 
			
		||||
 */
 | 
			
		||||
#define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList )										\
 | 
			
		||||
{																							\
 | 
			
		||||
List_t * const pxConstList = ( pxList );													\
 | 
			
		||||
	/* Increment the index to the next item and return the item, ensuring */				\
 | 
			
		||||
	/* we don't return the marker used at the end of the list.  */							\
 | 
			
		||||
	( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext;							\
 | 
			
		||||
	if( ( void * ) ( pxConstList )->pxIndex == ( void * ) &( ( pxConstList )->xListEnd ) )	\
 | 
			
		||||
	{																						\
 | 
			
		||||
		( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext;						\
 | 
			
		||||
	}																						\
 | 
			
		||||
	( pxTCB ) = ( pxConstList )->pxIndex->pvOwner;											\
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Access function to obtain the owner of the first entry in a list.  Lists
 | 
			
		||||
 * are normally sorted in ascending item value order.
 | 
			
		||||
 *
 | 
			
		||||
 * This function returns the pxOwner member of the first item in the list.
 | 
			
		||||
 * The pxOwner parameter of a list item is a pointer to the object that owns
 | 
			
		||||
 * the list item.  In the scheduler this is normally a task control block.
 | 
			
		||||
 * The pxOwner parameter effectively creates a two way link between the list
 | 
			
		||||
 * item and its owner.
 | 
			
		||||
 *
 | 
			
		||||
 * @param pxList The list from which the owner of the head item is to be
 | 
			
		||||
 * returned.
 | 
			
		||||
 *
 | 
			
		||||
 * \page listGET_OWNER_OF_HEAD_ENTRY listGET_OWNER_OF_HEAD_ENTRY
 | 
			
		||||
 * \ingroup LinkedList
 | 
			
		||||
 */
 | 
			
		||||
#define listGET_OWNER_OF_HEAD_ENTRY( pxList )  ( (&( ( pxList )->xListEnd ))->pxNext->pvOwner )
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Check to see if a list item is within a list.  The list item maintains a
 | 
			
		||||
 * "container" pointer that points to the list it is in.  All this macro does
 | 
			
		||||
 * is check to see if the container and the list match.
 | 
			
		||||
 *
 | 
			
		||||
 * @param pxList The list we want to know if the list item is within.
 | 
			
		||||
 * @param pxListItem The list item we want to know if is in the list.
 | 
			
		||||
 * @return pdTRUE if the list item is in the list, otherwise pdFALSE.
 | 
			
		||||
 */
 | 
			
		||||
#define listIS_CONTAINED_WITHIN( pxList, pxListItem ) ( ( BaseType_t ) ( ( pxListItem )->pvContainer == ( void * ) ( pxList ) ) )
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Return the list a list item is contained within (referenced from).
 | 
			
		||||
 *
 | 
			
		||||
 * @param pxListItem The list item being queried.
 | 
			
		||||
 * @return A pointer to the List_t object that references the pxListItem
 | 
			
		||||
 */
 | 
			
		||||
#define listLIST_ITEM_CONTAINER( pxListItem ) ( ( pxListItem )->pvContainer )
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * This provides a crude means of knowing if a list has been initialised, as
 | 
			
		||||
 * pxList->xListEnd.xItemValue is set to portMAX_DELAY by the vListInitialise()
 | 
			
		||||
 * function.
 | 
			
		||||
 */
 | 
			
		||||
#define listLIST_IS_INITIALISED( pxList ) ( ( pxList )->xListEnd.xItemValue == portMAX_DELAY )
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Must be called before a list is used!  This initialises all the members
 | 
			
		||||
 * of the list structure and inserts the xListEnd item into the list as a
 | 
			
		||||
 * marker to the back of the list.
 | 
			
		||||
 *
 | 
			
		||||
 * @param pxList Pointer to the list being initialised.
 | 
			
		||||
 *
 | 
			
		||||
 * \page vListInitialise vListInitialise
 | 
			
		||||
 * \ingroup LinkedList
 | 
			
		||||
 */
 | 
			
		||||
void vListInitialise( List_t * const pxList );
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Must be called before a list item is used.  This sets the list container to
 | 
			
		||||
 * null so the item does not think that it is already contained in a list.
 | 
			
		||||
 *
 | 
			
		||||
 * @param pxItem Pointer to the list item being initialised.
 | 
			
		||||
 *
 | 
			
		||||
 * \page vListInitialiseItem vListInitialiseItem
 | 
			
		||||
 * \ingroup LinkedList
 | 
			
		||||
 */
 | 
			
		||||
void vListInitialiseItem( ListItem_t * const pxItem );
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Insert a list item into a list.  The item will be inserted into the list in
 | 
			
		||||
 * a position determined by its item value (descending item value order).
 | 
			
		||||
 *
 | 
			
		||||
 * @param pxList The list into which the item is to be inserted.
 | 
			
		||||
 *
 | 
			
		||||
 * @param pxNewListItem The item that is to be placed in the list.
 | 
			
		||||
 *
 | 
			
		||||
 * \page vListInsert vListInsert
 | 
			
		||||
 * \ingroup LinkedList
 | 
			
		||||
 */
 | 
			
		||||
void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem );
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Insert a list item into a list.  The item will be inserted in a position
 | 
			
		||||
 * such that it will be the last item within the list returned by multiple
 | 
			
		||||
 * calls to listGET_OWNER_OF_NEXT_ENTRY.
 | 
			
		||||
 *
 | 
			
		||||
 * The list member pvIndex is used to walk through a list.  Calling
 | 
			
		||||
 * listGET_OWNER_OF_NEXT_ENTRY increments pvIndex to the next item in the list.
 | 
			
		||||
 * Placing an item in a list using vListInsertEnd effectively places the item
 | 
			
		||||
 * in the list position pointed to by pvIndex.  This means that every other
 | 
			
		||||
 * item within the list will be returned by listGET_OWNER_OF_NEXT_ENTRY before
 | 
			
		||||
 * the pvIndex parameter again points to the item being inserted.
 | 
			
		||||
 *
 | 
			
		||||
 * @param pxList The list into which the item is to be inserted.
 | 
			
		||||
 *
 | 
			
		||||
 * @param pxNewListItem The list item to be inserted into the list.
 | 
			
		||||
 *
 | 
			
		||||
 * \page vListInsertEnd vListInsertEnd
 | 
			
		||||
 * \ingroup LinkedList
 | 
			
		||||
 */
 | 
			
		||||
void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem );
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Remove an item from a list.  The list item has a pointer to the list that
 | 
			
		||||
 * it is in, so only the list item need be passed into the function.
 | 
			
		||||
 *
 | 
			
		||||
 * @param uxListRemove The item to be removed.  The item will remove itself from
 | 
			
		||||
 * the list pointed to by it's pxContainer parameter.
 | 
			
		||||
 *
 | 
			
		||||
 * @return The number of items that remain in the list after the list item has
 | 
			
		||||
 * been removed.
 | 
			
		||||
 *
 | 
			
		||||
 * \page uxListRemove uxListRemove
 | 
			
		||||
 * \ingroup LinkedList
 | 
			
		||||
 */
 | 
			
		||||
UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove );
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,153 @@
 | 
			
		|||
/*
 | 
			
		||||
    FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd.
 | 
			
		||||
    All rights reserved
 | 
			
		||||
 | 
			
		||||
    VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
 | 
			
		||||
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    FreeRTOS provides completely free yet professionally developed,    *
 | 
			
		||||
     *    robust, strictly quality controlled, supported, and cross          *
 | 
			
		||||
     *    platform software that has become a de facto standard.             *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    Help yourself get started quickly and support the FreeRTOS         *
 | 
			
		||||
     *    project by purchasing a FreeRTOS tutorial book, reference          *
 | 
			
		||||
     *    manual, or both from: http://www.FreeRTOS.org/Documentation        *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    Thank you!                                                         *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
 | 
			
		||||
    This file is part of the FreeRTOS distribution.
 | 
			
		||||
 | 
			
		||||
    FreeRTOS is free software; you can redistribute it and/or modify it under
 | 
			
		||||
    the terms of the GNU General Public License (version 2) as published by the
 | 
			
		||||
    Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
 | 
			
		||||
 | 
			
		||||
    >>!   NOTE: The modification to the GPL is included to allow you to     !<<
 | 
			
		||||
    >>!   distribute a combined work that includes FreeRTOS without being   !<<
 | 
			
		||||
    >>!   obliged to provide the source code for proprietary components     !<<
 | 
			
		||||
    >>!   outside of the FreeRTOS kernel.                                   !<<
 | 
			
		||||
 | 
			
		||||
    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
 | 
			
		||||
    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
    FOR A PARTICULAR PURPOSE.  Full license text is available from the following
 | 
			
		||||
    link: http://www.freertos.org/a00114.html
 | 
			
		||||
 | 
			
		||||
    1 tab == 4 spaces!
 | 
			
		||||
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    Having a problem?  Start by reading the FAQ "My application does   *
 | 
			
		||||
     *    not run, what could be wrong?"                                     *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    http://www.FreeRTOS.org/FAQHelp.html                               *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
 | 
			
		||||
    http://www.FreeRTOS.org - Documentation, books, training, latest versions,
 | 
			
		||||
    license and Real Time Engineers Ltd. contact details.
 | 
			
		||||
 | 
			
		||||
    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
 | 
			
		||||
    including FreeRTOS+Trace - an indispensable productivity tool, a DOS
 | 
			
		||||
    compatible FAT file system, and our tiny thread aware UDP/IP stack.
 | 
			
		||||
 | 
			
		||||
    http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
 | 
			
		||||
    Integrity Systems to sell under the OpenRTOS brand.  Low cost OpenRTOS
 | 
			
		||||
    licenses offer ticketed support, indemnification and middleware.
 | 
			
		||||
 | 
			
		||||
    http://www.SafeRTOS.com - High Integrity Systems also provide a safety
 | 
			
		||||
    engineered and independently SIL3 certified version for use in safety and
 | 
			
		||||
    mission critical applications that require provable dependability.
 | 
			
		||||
 | 
			
		||||
    1 tab == 4 spaces!
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef MPU_WRAPPERS_H
 | 
			
		||||
#define MPU_WRAPPERS_H
 | 
			
		||||
 | 
			
		||||
/* This file redefines API functions to be called through a wrapper macro, but
 | 
			
		||||
only for ports that are using the MPU. */
 | 
			
		||||
#ifdef portUSING_MPU_WRAPPERS
 | 
			
		||||
 | 
			
		||||
	/* MPU_WRAPPERS_INCLUDED_FROM_API_FILE will be defined when this file is
 | 
			
		||||
	included from queue.c or task.c to prevent it from having an effect within
 | 
			
		||||
	those files. */
 | 
			
		||||
	#ifndef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
 | 
			
		||||
 | 
			
		||||
		#define xTaskGenericCreate				MPU_xTaskGenericCreate
 | 
			
		||||
		#define vTaskAllocateMPURegions			MPU_vTaskAllocateMPURegions
 | 
			
		||||
		#define vTaskDelete						MPU_vTaskDelete
 | 
			
		||||
		#define vTaskDelayUntil					MPU_vTaskDelayUntil
 | 
			
		||||
		#define vTaskDelay						MPU_vTaskDelay
 | 
			
		||||
		#define uxTaskPriorityGet				MPU_uxTaskPriorityGet
 | 
			
		||||
		#define vTaskPrioritySet				MPU_vTaskPrioritySet
 | 
			
		||||
		#define eTaskGetState					MPU_eTaskGetState
 | 
			
		||||
		#define vTaskSuspend					MPU_vTaskSuspend
 | 
			
		||||
		#define vTaskResume						MPU_vTaskResume
 | 
			
		||||
		#define vTaskSuspendAll					MPU_vTaskSuspendAll
 | 
			
		||||
		#define xTaskResumeAll					MPU_xTaskResumeAll
 | 
			
		||||
		#define xTaskGetTickCount				MPU_xTaskGetTickCount
 | 
			
		||||
		#define uxTaskGetNumberOfTasks			MPU_uxTaskGetNumberOfTasks
 | 
			
		||||
		#define vTaskList						MPU_vTaskList
 | 
			
		||||
		#define vTaskGetRunTimeStats			MPU_vTaskGetRunTimeStats
 | 
			
		||||
		#define vTaskSetApplicationTaskTag		MPU_vTaskSetApplicationTaskTag
 | 
			
		||||
		#define xTaskGetApplicationTaskTag		MPU_xTaskGetApplicationTaskTag
 | 
			
		||||
		#define xTaskCallApplicationTaskHook	MPU_xTaskCallApplicationTaskHook
 | 
			
		||||
		#define uxTaskGetStackHighWaterMark		MPU_uxTaskGetStackHighWaterMark
 | 
			
		||||
		#define xTaskGetCurrentTaskHandle		MPU_xTaskGetCurrentTaskHandle
 | 
			
		||||
		#define xTaskGetSchedulerState			MPU_xTaskGetSchedulerState
 | 
			
		||||
		#define xTaskGetIdleTaskHandle			MPU_xTaskGetIdleTaskHandle
 | 
			
		||||
		#define uxTaskGetSystemState			MPU_uxTaskGetSystemState
 | 
			
		||||
 | 
			
		||||
		#define xQueueGenericCreate				MPU_xQueueGenericCreate
 | 
			
		||||
		#define xQueueCreateMutex				MPU_xQueueCreateMutex
 | 
			
		||||
		#define xQueueGiveMutexRecursive		MPU_xQueueGiveMutexRecursive
 | 
			
		||||
		#define xQueueTakeMutexRecursive		MPU_xQueueTakeMutexRecursive
 | 
			
		||||
		#define xQueueCreateCountingSemaphore	MPU_xQueueCreateCountingSemaphore
 | 
			
		||||
		#define xQueueGenericSend				MPU_xQueueGenericSend
 | 
			
		||||
		#define xQueueAltGenericSend			MPU_xQueueAltGenericSend
 | 
			
		||||
		#define xQueueAltGenericReceive			MPU_xQueueAltGenericReceive
 | 
			
		||||
		#define xQueueGenericReceive			MPU_xQueueGenericReceive
 | 
			
		||||
		#define uxQueueMessagesWaiting			MPU_uxQueueMessagesWaiting
 | 
			
		||||
		#define vQueueDelete					MPU_vQueueDelete
 | 
			
		||||
		#define xQueueGenericReset				MPU_xQueueGenericReset
 | 
			
		||||
		#define xQueueCreateSet					MPU_xQueueCreateSet
 | 
			
		||||
		#define xQueueSelectFromSet				MPU_xQueueSelectFromSet
 | 
			
		||||
		#define xQueueAddToSet					MPU_xQueueAddToSet
 | 
			
		||||
		#define xQueueRemoveFromSet				MPU_xQueueRemoveFromSet
 | 
			
		||||
		#define xQueuePeekFromISR				MPU_xQueuePeekFromISR
 | 
			
		||||
		#define xQueueGetMutexHolder			MPU_xQueueGetMutexHolder
 | 
			
		||||
 | 
			
		||||
		#define pvPortMalloc					MPU_pvPortMalloc
 | 
			
		||||
		#define vPortFree						MPU_vPortFree
 | 
			
		||||
		#define xPortGetFreeHeapSize			MPU_xPortGetFreeHeapSize
 | 
			
		||||
		#define vPortInitialiseBlocks			MPU_vPortInitialiseBlocks
 | 
			
		||||
 | 
			
		||||
		#if configQUEUE_REGISTRY_SIZE > 0
 | 
			
		||||
			#define vQueueAddToRegistry				MPU_vQueueAddToRegistry
 | 
			
		||||
			#define vQueueUnregisterQueue			MPU_vQueueUnregisterQueue
 | 
			
		||||
		#endif
 | 
			
		||||
 | 
			
		||||
		/* Remove the privileged function macro. */
 | 
			
		||||
		#define PRIVILEGED_FUNCTION
 | 
			
		||||
 | 
			
		||||
	#else /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */
 | 
			
		||||
 | 
			
		||||
		/* Ensure API functions go in the privileged execution section. */
 | 
			
		||||
		#define PRIVILEGED_FUNCTION __attribute__((section("privileged_functions")))
 | 
			
		||||
		#define PRIVILEGED_DATA __attribute__((section("privileged_data")))
 | 
			
		||||
 | 
			
		||||
	#endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */
 | 
			
		||||
 | 
			
		||||
#else /* portUSING_MPU_WRAPPERS */
 | 
			
		||||
 | 
			
		||||
	#define PRIVILEGED_FUNCTION
 | 
			
		||||
	#define PRIVILEGED_DATA
 | 
			
		||||
	#define portUSING_MPU_WRAPPERS 0
 | 
			
		||||
 | 
			
		||||
#endif /* portUSING_MPU_WRAPPERS */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif /* MPU_WRAPPERS_H */
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										426
									
								
								component/os/freertos/freertos_v8.1.2/Source/include/portable.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										426
									
								
								component/os/freertos/freertos_v8.1.2/Source/include/portable.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,426 @@
 | 
			
		|||
/*
 | 
			
		||||
    FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd.
 | 
			
		||||
    All rights reserved
 | 
			
		||||
 | 
			
		||||
    VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
 | 
			
		||||
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    FreeRTOS provides completely free yet professionally developed,    *
 | 
			
		||||
     *    robust, strictly quality controlled, supported, and cross          *
 | 
			
		||||
     *    platform software that has become a de facto standard.             *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    Help yourself get started quickly and support the FreeRTOS         *
 | 
			
		||||
     *    project by purchasing a FreeRTOS tutorial book, reference          *
 | 
			
		||||
     *    manual, or both from: http://www.FreeRTOS.org/Documentation        *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    Thank you!                                                         *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
 | 
			
		||||
    This file is part of the FreeRTOS distribution.
 | 
			
		||||
 | 
			
		||||
    FreeRTOS is free software; you can redistribute it and/or modify it under
 | 
			
		||||
    the terms of the GNU General Public License (version 2) as published by the
 | 
			
		||||
    Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
 | 
			
		||||
 | 
			
		||||
    >>!   NOTE: The modification to the GPL is included to allow you to     !<<
 | 
			
		||||
    >>!   distribute a combined work that includes FreeRTOS without being   !<<
 | 
			
		||||
    >>!   obliged to provide the source code for proprietary components     !<<
 | 
			
		||||
    >>!   outside of the FreeRTOS kernel.                                   !<<
 | 
			
		||||
 | 
			
		||||
    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
 | 
			
		||||
    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
    FOR A PARTICULAR PURPOSE.  Full license text is available from the following
 | 
			
		||||
    link: http://www.freertos.org/a00114.html
 | 
			
		||||
 | 
			
		||||
    1 tab == 4 spaces!
 | 
			
		||||
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    Having a problem?  Start by reading the FAQ "My application does   *
 | 
			
		||||
     *    not run, what could be wrong?"                                     *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    http://www.FreeRTOS.org/FAQHelp.html                               *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
 | 
			
		||||
    http://www.FreeRTOS.org - Documentation, books, training, latest versions,
 | 
			
		||||
    license and Real Time Engineers Ltd. contact details.
 | 
			
		||||
 | 
			
		||||
    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
 | 
			
		||||
    including FreeRTOS+Trace - an indispensable productivity tool, a DOS
 | 
			
		||||
    compatible FAT file system, and our tiny thread aware UDP/IP stack.
 | 
			
		||||
 | 
			
		||||
    http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
 | 
			
		||||
    Integrity Systems to sell under the OpenRTOS brand.  Low cost OpenRTOS
 | 
			
		||||
    licenses offer ticketed support, indemnification and middleware.
 | 
			
		||||
 | 
			
		||||
    http://www.SafeRTOS.com - High Integrity Systems also provide a safety
 | 
			
		||||
    engineered and independently SIL3 certified version for use in safety and
 | 
			
		||||
    mission critical applications that require provable dependability.
 | 
			
		||||
 | 
			
		||||
    1 tab == 4 spaces!
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------
 | 
			
		||||
 * Portable layer API.  Each function must be defined for each port.
 | 
			
		||||
 *----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
#ifndef PORTABLE_H
 | 
			
		||||
#define PORTABLE_H
 | 
			
		||||
 | 
			
		||||
/* Include the macro file relevant to the port being used.
 | 
			
		||||
NOTE:  The following definitions are *DEPRECATED* as it is preferred to instead
 | 
			
		||||
just add the path to the correct portmacro.h header file to the compiler's
 | 
			
		||||
include path. */
 | 
			
		||||
#ifdef OPEN_WATCOM_INDUSTRIAL_PC_PORT
 | 
			
		||||
	#include "..\..\Source\portable\owatcom\16bitdos\pc\portmacro.h"
 | 
			
		||||
	typedef void ( __interrupt __far *pxISR )();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef OPEN_WATCOM_FLASH_LITE_186_PORT
 | 
			
		||||
	#include "..\..\Source\portable\owatcom\16bitdos\flsh186\portmacro.h"
 | 
			
		||||
	typedef void ( __interrupt __far *pxISR )();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef GCC_MEGA_AVR
 | 
			
		||||
	#include "../portable/GCC/ATMega323/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef IAR_MEGA_AVR
 | 
			
		||||
	#include "../portable/IAR/ATMega323/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef MPLAB_PIC24_PORT
 | 
			
		||||
	#include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef MPLAB_DSPIC_PORT
 | 
			
		||||
	#include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef MPLAB_PIC18F_PORT
 | 
			
		||||
	#include "../../Source/portable/MPLAB/PIC18F/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef MPLAB_PIC32MX_PORT
 | 
			
		||||
	#include "../../Source/portable/MPLAB/PIC32MX/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef _FEDPICC
 | 
			
		||||
	#include "libFreeRTOS/Include/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef SDCC_CYGNAL
 | 
			
		||||
	#include "../../Source/portable/SDCC/Cygnal/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef GCC_ARM7
 | 
			
		||||
	#include "../../Source/portable/GCC/ARM7_LPC2000/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef GCC_ARM7_ECLIPSE
 | 
			
		||||
	#include "portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef ROWLEY_LPC23xx
 | 
			
		||||
	#include "../../Source/portable/GCC/ARM7_LPC23xx/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef IAR_MSP430
 | 
			
		||||
	#include "..\..\Source\portable\IAR\MSP430\portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef GCC_MSP430
 | 
			
		||||
	#include "../../Source/portable/GCC/MSP430F449/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef ROWLEY_MSP430
 | 
			
		||||
	#include "../../Source/portable/Rowley/MSP430F449/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef ARM7_LPC21xx_KEIL_RVDS
 | 
			
		||||
	#include "..\..\Source\portable\RVDS\ARM7_LPC21xx\portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef SAM7_GCC
 | 
			
		||||
	#include "../../Source/portable/GCC/ARM7_AT91SAM7S/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef SAM7_IAR
 | 
			
		||||
	#include "..\..\Source\portable\IAR\AtmelSAM7S64\portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef SAM9XE_IAR
 | 
			
		||||
	#include "..\..\Source\portable\IAR\AtmelSAM9XE\portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef LPC2000_IAR
 | 
			
		||||
	#include "..\..\Source\portable\IAR\LPC2000\portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef STR71X_IAR
 | 
			
		||||
	#include "..\..\Source\portable\IAR\STR71x\portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef STR75X_IAR
 | 
			
		||||
	#include "..\..\Source\portable\IAR\STR75x\portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef STR75X_GCC
 | 
			
		||||
	#include "..\..\Source\portable\GCC\STR75x\portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef STR91X_IAR
 | 
			
		||||
	#include "..\..\Source\portable\IAR\STR91x\portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef GCC_H8S
 | 
			
		||||
	#include "../../Source/portable/GCC/H8S2329/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef GCC_AT91FR40008
 | 
			
		||||
	#include "../../Source/portable/GCC/ARM7_AT91FR40008/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef RVDS_ARMCM3_LM3S102
 | 
			
		||||
	#include "../../Source/portable/RVDS/ARM_CM3/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef GCC_ARMCM3_LM3S102
 | 
			
		||||
	#include "../../Source/portable/GCC/ARM_CM3/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef GCC_ARMCM3
 | 
			
		||||
	#include "../../Source/portable/GCC/ARM_CM3/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef IAR_ARM_CM3
 | 
			
		||||
	#include "../../Source/portable/IAR/ARM_CM3/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef IAR_ARMCM3_LM
 | 
			
		||||
	#include "../../Source/portable/IAR/ARM_CM3/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef HCS12_CODE_WARRIOR
 | 
			
		||||
	#include "../../Source/portable/CodeWarrior/HCS12/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef MICROBLAZE_GCC
 | 
			
		||||
	#include "../../Source/portable/GCC/MicroBlaze/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef TERN_EE
 | 
			
		||||
	#include "..\..\Source\portable\Paradigm\Tern_EE\small\portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef GCC_HCS12
 | 
			
		||||
	#include "../../Source/portable/GCC/HCS12/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef GCC_MCF5235
 | 
			
		||||
    #include "../../Source/portable/GCC/MCF5235/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef COLDFIRE_V2_GCC
 | 
			
		||||
	#include "../../../Source/portable/GCC/ColdFire_V2/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef COLDFIRE_V2_CODEWARRIOR
 | 
			
		||||
	#include "../../Source/portable/CodeWarrior/ColdFire_V2/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef GCC_PPC405
 | 
			
		||||
	#include "../../Source/portable/GCC/PPC405_Xilinx/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef GCC_PPC440
 | 
			
		||||
	#include "../../Source/portable/GCC/PPC440_Xilinx/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef _16FX_SOFTUNE
 | 
			
		||||
	#include "..\..\Source\portable\Softune\MB96340\portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef BCC_INDUSTRIAL_PC_PORT
 | 
			
		||||
	/* A short file name has to be used in place of the normal
 | 
			
		||||
	FreeRTOSConfig.h when using the Borland compiler. */
 | 
			
		||||
	#include "frconfig.h"
 | 
			
		||||
	#include "..\portable\BCC\16BitDOS\PC\prtmacro.h"
 | 
			
		||||
    typedef void ( __interrupt __far *pxISR )();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef BCC_FLASH_LITE_186_PORT
 | 
			
		||||
	/* A short file name has to be used in place of the normal
 | 
			
		||||
	FreeRTOSConfig.h when using the Borland compiler. */
 | 
			
		||||
	#include "frconfig.h"
 | 
			
		||||
	#include "..\portable\BCC\16BitDOS\flsh186\prtmacro.h"
 | 
			
		||||
    typedef void ( __interrupt __far *pxISR )();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __GNUC__
 | 
			
		||||
   #ifdef __AVR32_AVR32A__
 | 
			
		||||
	   #include "portmacro.h"
 | 
			
		||||
   #endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __ICCAVR32__
 | 
			
		||||
   #ifdef __CORE__
 | 
			
		||||
      #if __CORE__ == __AVR32A__
 | 
			
		||||
	      #include "portmacro.h"
 | 
			
		||||
      #endif
 | 
			
		||||
   #endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __91467D
 | 
			
		||||
	#include "portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __96340
 | 
			
		||||
	#include "portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef __IAR_V850ES_Fx3__
 | 
			
		||||
	#include "../../Source/portable/IAR/V850ES/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __IAR_V850ES_Jx3__
 | 
			
		||||
	#include "../../Source/portable/IAR/V850ES/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __IAR_V850ES_Jx3_L__
 | 
			
		||||
	#include "../../Source/portable/IAR/V850ES/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __IAR_V850ES_Jx2__
 | 
			
		||||
	#include "../../Source/portable/IAR/V850ES/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __IAR_V850ES_Hx2__
 | 
			
		||||
	#include "../../Source/portable/IAR/V850ES/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __IAR_78K0R_Kx3__
 | 
			
		||||
	#include "../../Source/portable/IAR/78K0R/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __IAR_78K0R_Kx3L__
 | 
			
		||||
	#include "../../Source/portable/IAR/78K0R/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Catch all to ensure portmacro.h is included in the build.  Newer demos
 | 
			
		||||
have the path as part of the project options, rather than as relative from
 | 
			
		||||
the project location.  If portENTER_CRITICAL() has not been defined then
 | 
			
		||||
portmacro.h has not yet been included - as every portmacro.h provides a
 | 
			
		||||
portENTER_CRITICAL() definition.  Check the demo application for your demo
 | 
			
		||||
to find the path to the correct portmacro.h file. */
 | 
			
		||||
#ifndef portENTER_CRITICAL
 | 
			
		||||
	#include "portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if portBYTE_ALIGNMENT == 8
 | 
			
		||||
	#define portBYTE_ALIGNMENT_MASK ( 0x0007U )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if portBYTE_ALIGNMENT == 4
 | 
			
		||||
	#define portBYTE_ALIGNMENT_MASK	( 0x0003 )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if portBYTE_ALIGNMENT == 2
 | 
			
		||||
	#define portBYTE_ALIGNMENT_MASK	( 0x0001 )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if portBYTE_ALIGNMENT == 1
 | 
			
		||||
	#define portBYTE_ALIGNMENT_MASK	( 0x0000 )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef portBYTE_ALIGNMENT_MASK
 | 
			
		||||
	#error "Invalid portBYTE_ALIGNMENT definition"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef portNUM_CONFIGURABLE_REGIONS
 | 
			
		||||
	#define portNUM_CONFIGURABLE_REGIONS 1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "mpu_wrappers.h"
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Setup the stack of a new task so it is ready to be placed under the
 | 
			
		||||
 * scheduler control.  The registers have to be placed on the stack in
 | 
			
		||||
 * the order that the port expects to find them.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
#if( portUSING_MPU_WRAPPERS == 1 )
 | 
			
		||||
	StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged ) PRIVILEGED_FUNCTION;
 | 
			
		||||
#else
 | 
			
		||||
	StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) PRIVILEGED_FUNCTION;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Used by heap_5.c. */
 | 
			
		||||
typedef struct HeapRegion
 | 
			
		||||
{
 | 
			
		||||
	uint8_t *pucStartAddress;
 | 
			
		||||
	size_t xSizeInBytes;
 | 
			
		||||
} HeapRegion_t;
 | 
			
		||||
 | 
			
		||||
/* 
 | 
			
		||||
 * Used to define multiple heap regions for use by heap_5.c.  This function
 | 
			
		||||
 * must be called before any calls to pvPortMalloc() - not creating a task,
 | 
			
		||||
 * queue, semaphore, mutex, software timer, event group, etc. will result in
 | 
			
		||||
 * pvPortMalloc being called.
 | 
			
		||||
 *
 | 
			
		||||
 * pxHeapRegions passes in an array of HeapRegion_t structures - each of which
 | 
			
		||||
 * defines a region of memory that can be used as the heap.  The array is 
 | 
			
		||||
 * terminated by a HeapRegions_t structure that has a size of 0.  The region 
 | 
			
		||||
 * with the lowest start address must appear first in the array.
 | 
			
		||||
 */
 | 
			
		||||
void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions );
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Map to the memory management routines required for the port.
 | 
			
		||||
 */
 | 
			
		||||
void *pvPortMalloc( size_t xSize ) PRIVILEGED_FUNCTION;
 | 
			
		||||
void vPortFree( void *pv ) PRIVILEGED_FUNCTION;
 | 
			
		||||
void vPortInitialiseBlocks( void ) PRIVILEGED_FUNCTION;
 | 
			
		||||
size_t xPortGetFreeHeapSize( void ) PRIVILEGED_FUNCTION;
 | 
			
		||||
size_t xPortGetMinimumEverFreeHeapSize( void ) PRIVILEGED_FUNCTION;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Setup the hardware ready for the scheduler to take control.  This generally
 | 
			
		||||
 * sets up a tick interrupt and sets timers for the correct tick frequency.
 | 
			
		||||
 */
 | 
			
		||||
BaseType_t xPortStartScheduler( void ) PRIVILEGED_FUNCTION;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Undo any hardware/ISR setup that was performed by xPortStartScheduler() so
 | 
			
		||||
 * the hardware is left in its original condition after the scheduler stops
 | 
			
		||||
 * executing.
 | 
			
		||||
 */
 | 
			
		||||
void vPortEndScheduler( void ) PRIVILEGED_FUNCTION;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * The structures and methods of manipulating the MPU are contained within the
 | 
			
		||||
 * port layer.
 | 
			
		||||
 *
 | 
			
		||||
 * Fills the xMPUSettings structure with the memory region information
 | 
			
		||||
 * contained in xRegions.
 | 
			
		||||
 */
 | 
			
		||||
#if( portUSING_MPU_WRAPPERS == 1 )
 | 
			
		||||
	struct xMEMORY_REGION;
 | 
			
		||||
	void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t *pxBottomOfStack, uint16_t usStackDepth ) PRIVILEGED_FUNCTION;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif /* PORTABLE_H */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,94 @@
 | 
			
		|||
/*
 | 
			
		||||
    FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd.
 | 
			
		||||
    All rights reserved
 | 
			
		||||
 | 
			
		||||
    VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
 | 
			
		||||
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    FreeRTOS provides completely free yet professionally developed,    *
 | 
			
		||||
     *    robust, strictly quality controlled, supported, and cross          *
 | 
			
		||||
     *    platform software that has become a de facto standard.             *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    Help yourself get started quickly and support the FreeRTOS         *
 | 
			
		||||
     *    project by purchasing a FreeRTOS tutorial book, reference          *
 | 
			
		||||
     *    manual, or both from: http://www.FreeRTOS.org/Documentation        *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    Thank you!                                                         *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
 | 
			
		||||
    This file is part of the FreeRTOS distribution.
 | 
			
		||||
 | 
			
		||||
    FreeRTOS is free software; you can redistribute it and/or modify it under
 | 
			
		||||
    the terms of the GNU General Public License (version 2) as published by the
 | 
			
		||||
    Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
 | 
			
		||||
 | 
			
		||||
    >>!   NOTE: The modification to the GPL is included to allow you to     !<<
 | 
			
		||||
    >>!   distribute a combined work that includes FreeRTOS without being   !<<
 | 
			
		||||
    >>!   obliged to provide the source code for proprietary components     !<<
 | 
			
		||||
    >>!   outside of the FreeRTOS kernel.                                   !<<
 | 
			
		||||
 | 
			
		||||
    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
 | 
			
		||||
    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
    FOR A PARTICULAR PURPOSE.  Full license text is available from the following
 | 
			
		||||
    link: http://www.freertos.org/a00114.html
 | 
			
		||||
 | 
			
		||||
    1 tab == 4 spaces!
 | 
			
		||||
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    Having a problem?  Start by reading the FAQ "My application does   *
 | 
			
		||||
     *    not run, what could be wrong?"                                     *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    http://www.FreeRTOS.org/FAQHelp.html                               *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
 | 
			
		||||
    http://www.FreeRTOS.org - Documentation, books, training, latest versions,
 | 
			
		||||
    license and Real Time Engineers Ltd. contact details.
 | 
			
		||||
 | 
			
		||||
    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
 | 
			
		||||
    including FreeRTOS+Trace - an indispensable productivity tool, a DOS
 | 
			
		||||
    compatible FAT file system, and our tiny thread aware UDP/IP stack.
 | 
			
		||||
 | 
			
		||||
    http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
 | 
			
		||||
    Integrity Systems to sell under the OpenRTOS brand.  Low cost OpenRTOS
 | 
			
		||||
    licenses offer ticketed support, indemnification and middleware.
 | 
			
		||||
 | 
			
		||||
    http://www.SafeRTOS.com - High Integrity Systems also provide a safety
 | 
			
		||||
    engineered and independently SIL3 certified version for use in safety and
 | 
			
		||||
    mission critical applications that require provable dependability.
 | 
			
		||||
 | 
			
		||||
    1 tab == 4 spaces!
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef PROJDEFS_H
 | 
			
		||||
#define PROJDEFS_H
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Defines the prototype to which task functions must conform.  Defined in this
 | 
			
		||||
 * file to ensure the type is known before portable.h is included.
 | 
			
		||||
 */
 | 
			
		||||
typedef void (*TaskFunction_t)( void * );
 | 
			
		||||
 | 
			
		||||
/* Converts a time in milliseconds to a time in ticks. */
 | 
			
		||||
#define pdMS_TO_TICKS( xTimeInMs ) ( ( ( TickType_t ) ( xTimeInMs ) * configTICK_RATE_HZ ) / ( TickType_t ) 1000 )
 | 
			
		||||
 | 
			
		||||
#define pdFALSE			( ( BaseType_t ) 0 )
 | 
			
		||||
#define pdTRUE			( ( BaseType_t ) 1 )
 | 
			
		||||
 | 
			
		||||
#define pdPASS			( pdTRUE )
 | 
			
		||||
#define pdFAIL			( pdFALSE )
 | 
			
		||||
#define errQUEUE_EMPTY	( ( BaseType_t ) 0 )
 | 
			
		||||
#define errQUEUE_FULL	( ( BaseType_t ) 0 )
 | 
			
		||||
 | 
			
		||||
/* Error definitions. */
 | 
			
		||||
#define errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY	( -1 )
 | 
			
		||||
#define errQUEUE_BLOCKED						( -4 )
 | 
			
		||||
#define errQUEUE_YIELD							( -5 )
 | 
			
		||||
 | 
			
		||||
#endif /* PROJDEFS_H */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										1687
									
								
								component/os/freertos/freertos_v8.1.2/Source/include/queue.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1687
									
								
								component/os/freertos/freertos_v8.1.2/Source/include/queue.h
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										840
									
								
								component/os/freertos/freertos_v8.1.2/Source/include/semphr.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										840
									
								
								component/os/freertos/freertos_v8.1.2/Source/include/semphr.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,840 @@
 | 
			
		|||
/*
 | 
			
		||||
    FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd.
 | 
			
		||||
    All rights reserved
 | 
			
		||||
 | 
			
		||||
    VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
 | 
			
		||||
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    FreeRTOS provides completely free yet professionally developed,    *
 | 
			
		||||
     *    robust, strictly quality controlled, supported, and cross          *
 | 
			
		||||
     *    platform software that has become a de facto standard.             *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    Help yourself get started quickly and support the FreeRTOS         *
 | 
			
		||||
     *    project by purchasing a FreeRTOS tutorial book, reference          *
 | 
			
		||||
     *    manual, or both from: http://www.FreeRTOS.org/Documentation        *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    Thank you!                                                         *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
 | 
			
		||||
    This file is part of the FreeRTOS distribution.
 | 
			
		||||
 | 
			
		||||
    FreeRTOS is free software; you can redistribute it and/or modify it under
 | 
			
		||||
    the terms of the GNU General Public License (version 2) as published by the
 | 
			
		||||
    Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
 | 
			
		||||
 | 
			
		||||
    >>!   NOTE: The modification to the GPL is included to allow you to     !<<
 | 
			
		||||
    >>!   distribute a combined work that includes FreeRTOS without being   !<<
 | 
			
		||||
    >>!   obliged to provide the source code for proprietary components     !<<
 | 
			
		||||
    >>!   outside of the FreeRTOS kernel.                                   !<<
 | 
			
		||||
 | 
			
		||||
    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
 | 
			
		||||
    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
    FOR A PARTICULAR PURPOSE.  Full license text is available from the following
 | 
			
		||||
    link: http://www.freertos.org/a00114.html
 | 
			
		||||
 | 
			
		||||
    1 tab == 4 spaces!
 | 
			
		||||
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    Having a problem?  Start by reading the FAQ "My application does   *
 | 
			
		||||
     *    not run, what could be wrong?"                                     *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    http://www.FreeRTOS.org/FAQHelp.html                               *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
 | 
			
		||||
    http://www.FreeRTOS.org - Documentation, books, training, latest versions,
 | 
			
		||||
    license and Real Time Engineers Ltd. contact details.
 | 
			
		||||
 | 
			
		||||
    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
 | 
			
		||||
    including FreeRTOS+Trace - an indispensable productivity tool, a DOS
 | 
			
		||||
    compatible FAT file system, and our tiny thread aware UDP/IP stack.
 | 
			
		||||
 | 
			
		||||
    http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
 | 
			
		||||
    Integrity Systems to sell under the OpenRTOS brand.  Low cost OpenRTOS
 | 
			
		||||
    licenses offer ticketed support, indemnification and middleware.
 | 
			
		||||
 | 
			
		||||
    http://www.SafeRTOS.com - High Integrity Systems also provide a safety
 | 
			
		||||
    engineered and independently SIL3 certified version for use in safety and
 | 
			
		||||
    mission critical applications that require provable dependability.
 | 
			
		||||
 | 
			
		||||
    1 tab == 4 spaces!
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef SEMAPHORE_H
 | 
			
		||||
#define SEMAPHORE_H
 | 
			
		||||
 | 
			
		||||
#ifndef INC_FREERTOS_H
 | 
			
		||||
	#error "include FreeRTOS.h" must appear in source files before "include semphr.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "queue.h"
 | 
			
		||||
 | 
			
		||||
typedef QueueHandle_t SemaphoreHandle_t;
 | 
			
		||||
 | 
			
		||||
#define semBINARY_SEMAPHORE_QUEUE_LENGTH	( ( uint8_t ) 1U )
 | 
			
		||||
#define semSEMAPHORE_QUEUE_ITEM_LENGTH		( ( uint8_t ) 0U )
 | 
			
		||||
#define semGIVE_BLOCK_TIME					( ( TickType_t ) 0U )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * semphr. h
 | 
			
		||||
 * <pre>vSemaphoreCreateBinary( SemaphoreHandle_t xSemaphore )</pre>
 | 
			
		||||
 *
 | 
			
		||||
 * This old vSemaphoreCreateBinary() macro is now deprecated in favour of the
 | 
			
		||||
 * xSemaphoreCreateBinary() function.  Note that binary semaphores created using
 | 
			
		||||
 * the vSemaphoreCreateBinary() macro are created in a state such that the
 | 
			
		||||
 * first call to 'take' the semaphore would pass, whereas binary semaphores
 | 
			
		||||
 * created using xSemaphoreCreateBinary() are created in a state such that the
 | 
			
		||||
 * the semaphore must first be 'given' before it can be 'taken'.
 | 
			
		||||
 *
 | 
			
		||||
 * <i>Macro</i> that implements a semaphore by using the existing queue mechanism.
 | 
			
		||||
 * The queue length is 1 as this is a binary semaphore.  The data size is 0
 | 
			
		||||
 * as we don't want to actually store any data - we just want to know if the
 | 
			
		||||
 * queue is empty or full.
 | 
			
		||||
 *
 | 
			
		||||
 * This type of semaphore can be used for pure synchronisation between tasks or
 | 
			
		||||
 * between an interrupt and a task.  The semaphore need not be given back once
 | 
			
		||||
 * obtained, so one task/interrupt can continuously 'give' the semaphore while
 | 
			
		||||
 * another continuously 'takes' the semaphore.  For this reason this type of
 | 
			
		||||
 * semaphore does not use a priority inheritance mechanism.  For an alternative
 | 
			
		||||
 * that does use priority inheritance see xSemaphoreCreateMutex().
 | 
			
		||||
 *
 | 
			
		||||
 * @param xSemaphore Handle to the created semaphore.  Should be of type SemaphoreHandle_t.
 | 
			
		||||
 *
 | 
			
		||||
 * Example usage:
 | 
			
		||||
 <pre>
 | 
			
		||||
 SemaphoreHandle_t xSemaphore = NULL;
 | 
			
		||||
 | 
			
		||||
 void vATask( void * pvParameters )
 | 
			
		||||
 {
 | 
			
		||||
    // Semaphore cannot be used before a call to vSemaphoreCreateBinary ().
 | 
			
		||||
    // This is a macro so pass the variable in directly.
 | 
			
		||||
    vSemaphoreCreateBinary( xSemaphore );
 | 
			
		||||
 | 
			
		||||
    if( xSemaphore != NULL )
 | 
			
		||||
    {
 | 
			
		||||
        // The semaphore was created successfully.
 | 
			
		||||
        // The semaphore can now be used.
 | 
			
		||||
    }
 | 
			
		||||
 }
 | 
			
		||||
 </pre>
 | 
			
		||||
 * \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary
 | 
			
		||||
 * \ingroup Semaphores
 | 
			
		||||
 */
 | 
			
		||||
#define vSemaphoreCreateBinary( xSemaphore )																							\
 | 
			
		||||
	{																																	\
 | 
			
		||||
		( xSemaphore ) = xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE );	\
 | 
			
		||||
		if( ( xSemaphore ) != NULL )																									\
 | 
			
		||||
		{																																\
 | 
			
		||||
			( void ) xSemaphoreGive( ( xSemaphore ) );																					\
 | 
			
		||||
		}																																\
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * semphr. h
 | 
			
		||||
 * <pre>SemaphoreHandle_t xSemaphoreCreateBinary( void )</pre>
 | 
			
		||||
 *
 | 
			
		||||
 * The old vSemaphoreCreateBinary() macro is now deprecated in favour of this
 | 
			
		||||
 * xSemaphoreCreateBinary() function.  Note that binary semaphores created using
 | 
			
		||||
 * the vSemaphoreCreateBinary() macro are created in a state such that the
 | 
			
		||||
 * first call to 'take' the semaphore would pass, whereas binary semaphores
 | 
			
		||||
 * created using xSemaphoreCreateBinary() are created in a state such that the
 | 
			
		||||
 * the semaphore must first be 'given' before it can be 'taken'.
 | 
			
		||||
 *
 | 
			
		||||
 * Function that creates a semaphore by using the existing queue mechanism.
 | 
			
		||||
 * The queue length is 1 as this is a binary semaphore.  The data size is 0
 | 
			
		||||
 * as nothing is actually stored - all that is important is whether the queue is
 | 
			
		||||
 * empty or full (the binary semaphore is available or not).
 | 
			
		||||
 *
 | 
			
		||||
 * This type of semaphore can be used for pure synchronisation between tasks or
 | 
			
		||||
 * between an interrupt and a task.  The semaphore need not be given back once
 | 
			
		||||
 * obtained, so one task/interrupt can continuously 'give' the semaphore while
 | 
			
		||||
 * another continuously 'takes' the semaphore.  For this reason this type of
 | 
			
		||||
 * semaphore does not use a priority inheritance mechanism.  For an alternative
 | 
			
		||||
 * that does use priority inheritance see xSemaphoreCreateMutex().
 | 
			
		||||
 *
 | 
			
		||||
 * @return Handle to the created semaphore.
 | 
			
		||||
 *
 | 
			
		||||
 * Example usage:
 | 
			
		||||
 <pre>
 | 
			
		||||
 SemaphoreHandle_t xSemaphore = NULL;
 | 
			
		||||
 | 
			
		||||
 void vATask( void * pvParameters )
 | 
			
		||||
 {
 | 
			
		||||
    // Semaphore cannot be used before a call to vSemaphoreCreateBinary ().
 | 
			
		||||
    // This is a macro so pass the variable in directly.
 | 
			
		||||
    xSemaphore = xSemaphoreCreateBinary();
 | 
			
		||||
 | 
			
		||||
    if( xSemaphore != NULL )
 | 
			
		||||
    {
 | 
			
		||||
        // The semaphore was created successfully.
 | 
			
		||||
        // The semaphore can now be used.
 | 
			
		||||
    }
 | 
			
		||||
 }
 | 
			
		||||
 </pre>
 | 
			
		||||
 * \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary
 | 
			
		||||
 * \ingroup Semaphores
 | 
			
		||||
 */
 | 
			
		||||
#define xSemaphoreCreateBinary() xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE )
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * semphr. h
 | 
			
		||||
 * <pre>xSemaphoreTake(
 | 
			
		||||
 *                   SemaphoreHandle_t xSemaphore,
 | 
			
		||||
 *                   TickType_t xBlockTime
 | 
			
		||||
 *               )</pre>
 | 
			
		||||
 *
 | 
			
		||||
 * <i>Macro</i> to obtain a semaphore.  The semaphore must have previously been
 | 
			
		||||
 * created with a call to vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or
 | 
			
		||||
 * xSemaphoreCreateCounting().
 | 
			
		||||
 *
 | 
			
		||||
 * @param xSemaphore A handle to the semaphore being taken - obtained when
 | 
			
		||||
 * the semaphore was created.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xBlockTime The time in ticks to wait for the semaphore to become
 | 
			
		||||
 * available.  The macro portTICK_PERIOD_MS can be used to convert this to a
 | 
			
		||||
 * real time.  A block time of zero can be used to poll the semaphore.  A block
 | 
			
		||||
 * time of portMAX_DELAY can be used to block indefinitely (provided
 | 
			
		||||
 * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h).
 | 
			
		||||
 *
 | 
			
		||||
 * @return pdTRUE if the semaphore was obtained.  pdFALSE
 | 
			
		||||
 * if xBlockTime expired without the semaphore becoming available.
 | 
			
		||||
 *
 | 
			
		||||
 * Example usage:
 | 
			
		||||
 <pre>
 | 
			
		||||
 SemaphoreHandle_t xSemaphore = NULL;
 | 
			
		||||
 | 
			
		||||
 // A task that creates a semaphore.
 | 
			
		||||
 void vATask( void * pvParameters )
 | 
			
		||||
 {
 | 
			
		||||
    // Create the semaphore to guard a shared resource.
 | 
			
		||||
    vSemaphoreCreateBinary( xSemaphore );
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
 // A task that uses the semaphore.
 | 
			
		||||
 void vAnotherTask( void * pvParameters )
 | 
			
		||||
 {
 | 
			
		||||
    // ... Do other things.
 | 
			
		||||
 | 
			
		||||
    if( xSemaphore != NULL )
 | 
			
		||||
    {
 | 
			
		||||
        // See if we can obtain the semaphore.  If the semaphore is not available
 | 
			
		||||
        // wait 10 ticks to see if it becomes free.
 | 
			
		||||
        if( xSemaphoreTake( xSemaphore, ( TickType_t ) 10 ) == pdTRUE )
 | 
			
		||||
        {
 | 
			
		||||
            // We were able to obtain the semaphore and can now access the
 | 
			
		||||
            // shared resource.
 | 
			
		||||
 | 
			
		||||
            // ...
 | 
			
		||||
 | 
			
		||||
            // We have finished accessing the shared resource.  Release the
 | 
			
		||||
            // semaphore.
 | 
			
		||||
            xSemaphoreGive( xSemaphore );
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            // We could not obtain the semaphore and can therefore not access
 | 
			
		||||
            // the shared resource safely.
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 }
 | 
			
		||||
 </pre>
 | 
			
		||||
 * \defgroup xSemaphoreTake xSemaphoreTake
 | 
			
		||||
 * \ingroup Semaphores
 | 
			
		||||
 */
 | 
			
		||||
#define xSemaphoreTake( xSemaphore, xBlockTime )		xQueueGenericReceive( ( QueueHandle_t ) ( xSemaphore ), NULL, ( xBlockTime ), pdFALSE )
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * semphr. h
 | 
			
		||||
 * xSemaphoreTakeRecursive(
 | 
			
		||||
 *                          SemaphoreHandle_t xMutex,
 | 
			
		||||
 *                          TickType_t xBlockTime
 | 
			
		||||
 *                        )
 | 
			
		||||
 *
 | 
			
		||||
 * <i>Macro</i> to recursively obtain, or 'take', a mutex type semaphore.
 | 
			
		||||
 * The mutex must have previously been created using a call to
 | 
			
		||||
 * xSemaphoreCreateRecursiveMutex();
 | 
			
		||||
 *
 | 
			
		||||
 * configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this
 | 
			
		||||
 * macro to be available.
 | 
			
		||||
 *
 | 
			
		||||
 * This macro must not be used on mutexes created using xSemaphoreCreateMutex().
 | 
			
		||||
 *
 | 
			
		||||
 * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex
 | 
			
		||||
 * doesn't become available again until the owner has called
 | 
			
		||||
 * xSemaphoreGiveRecursive() for each successful 'take' request.  For example,
 | 
			
		||||
 * if a task successfully 'takes' the same mutex 5 times then the mutex will
 | 
			
		||||
 * not be available to any other task until it has also  'given' the mutex back
 | 
			
		||||
 * exactly five times.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xMutex A handle to the mutex being obtained.  This is the
 | 
			
		||||
 * handle returned by xSemaphoreCreateRecursiveMutex();
 | 
			
		||||
 *
 | 
			
		||||
 * @param xBlockTime The time in ticks to wait for the semaphore to become
 | 
			
		||||
 * available.  The macro portTICK_PERIOD_MS can be used to convert this to a
 | 
			
		||||
 * real time.  A block time of zero can be used to poll the semaphore.  If
 | 
			
		||||
 * the task already owns the semaphore then xSemaphoreTakeRecursive() will
 | 
			
		||||
 * return immediately no matter what the value of xBlockTime.
 | 
			
		||||
 *
 | 
			
		||||
 * @return pdTRUE if the semaphore was obtained.  pdFALSE if xBlockTime
 | 
			
		||||
 * expired without the semaphore becoming available.
 | 
			
		||||
 *
 | 
			
		||||
 * Example usage:
 | 
			
		||||
 <pre>
 | 
			
		||||
 SemaphoreHandle_t xMutex = NULL;
 | 
			
		||||
 | 
			
		||||
 // A task that creates a mutex.
 | 
			
		||||
 void vATask( void * pvParameters )
 | 
			
		||||
 {
 | 
			
		||||
    // Create the mutex to guard a shared resource.
 | 
			
		||||
    xMutex = xSemaphoreCreateRecursiveMutex();
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
 // A task that uses the mutex.
 | 
			
		||||
 void vAnotherTask( void * pvParameters )
 | 
			
		||||
 {
 | 
			
		||||
    // ... Do other things.
 | 
			
		||||
 | 
			
		||||
    if( xMutex != NULL )
 | 
			
		||||
    {
 | 
			
		||||
        // See if we can obtain the mutex.  If the mutex is not available
 | 
			
		||||
        // wait 10 ticks to see if it becomes free.
 | 
			
		||||
        if( xSemaphoreTakeRecursive( xSemaphore, ( TickType_t ) 10 ) == pdTRUE )
 | 
			
		||||
        {
 | 
			
		||||
            // We were able to obtain the mutex and can now access the
 | 
			
		||||
            // shared resource.
 | 
			
		||||
 | 
			
		||||
            // ...
 | 
			
		||||
            // For some reason due to the nature of the code further calls to
 | 
			
		||||
			// xSemaphoreTakeRecursive() are made on the same mutex.  In real
 | 
			
		||||
			// code these would not be just sequential calls as this would make
 | 
			
		||||
			// no sense.  Instead the calls are likely to be buried inside
 | 
			
		||||
			// a more complex call structure.
 | 
			
		||||
            xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
 | 
			
		||||
            xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
 | 
			
		||||
 | 
			
		||||
            // The mutex has now been 'taken' three times, so will not be
 | 
			
		||||
			// available to another task until it has also been given back
 | 
			
		||||
			// three times.  Again it is unlikely that real code would have
 | 
			
		||||
			// these calls sequentially, but instead buried in a more complex
 | 
			
		||||
			// call structure.  This is just for illustrative purposes.
 | 
			
		||||
            xSemaphoreGiveRecursive( xMutex );
 | 
			
		||||
			xSemaphoreGiveRecursive( xMutex );
 | 
			
		||||
			xSemaphoreGiveRecursive( xMutex );
 | 
			
		||||
 | 
			
		||||
			// Now the mutex can be taken by other tasks.
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            // We could not obtain the mutex and can therefore not access
 | 
			
		||||
            // the shared resource safely.
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 }
 | 
			
		||||
 </pre>
 | 
			
		||||
 * \defgroup xSemaphoreTakeRecursive xSemaphoreTakeRecursive
 | 
			
		||||
 * \ingroup Semaphores
 | 
			
		||||
 */
 | 
			
		||||
#define xSemaphoreTakeRecursive( xMutex, xBlockTime )	xQueueTakeMutexRecursive( ( xMutex ), ( xBlockTime ) )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * xSemaphoreAltTake() is an alternative version of xSemaphoreTake().
 | 
			
		||||
 *
 | 
			
		||||
 * The source code that implements the alternative (Alt) API is much
 | 
			
		||||
 * simpler	because it executes everything from within a critical section.
 | 
			
		||||
 * This is	the approach taken by many other RTOSes, but FreeRTOS.org has the
 | 
			
		||||
 * preferred fully featured API too.  The fully featured API has more
 | 
			
		||||
 * complex	code that takes longer to execute, but makes much less use of
 | 
			
		||||
 * critical sections.  Therefore the alternative API sacrifices interrupt
 | 
			
		||||
 * responsiveness to gain execution speed, whereas the fully featured API
 | 
			
		||||
 * sacrifices execution speed to ensure better interrupt responsiveness.
 | 
			
		||||
 */
 | 
			
		||||
#define xSemaphoreAltTake( xSemaphore, xBlockTime )		xQueueAltGenericReceive( ( QueueHandle_t ) ( xSemaphore ), NULL, ( xBlockTime ), pdFALSE )
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * semphr. h
 | 
			
		||||
 * <pre>xSemaphoreGive( SemaphoreHandle_t xSemaphore )</pre>
 | 
			
		||||
 *
 | 
			
		||||
 * <i>Macro</i> to release a semaphore.  The semaphore must have previously been
 | 
			
		||||
 * created with a call to vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or
 | 
			
		||||
 * xSemaphoreCreateCounting(). and obtained using sSemaphoreTake().
 | 
			
		||||
 *
 | 
			
		||||
 * This macro must not be used from an ISR.  See xSemaphoreGiveFromISR () for
 | 
			
		||||
 * an alternative which can be used from an ISR.
 | 
			
		||||
 *
 | 
			
		||||
 * This macro must also not be used on semaphores created using
 | 
			
		||||
 * xSemaphoreCreateRecursiveMutex().
 | 
			
		||||
 *
 | 
			
		||||
 * @param xSemaphore A handle to the semaphore being released.  This is the
 | 
			
		||||
 * handle returned when the semaphore was created.
 | 
			
		||||
 *
 | 
			
		||||
 * @return pdTRUE if the semaphore was released.  pdFALSE if an error occurred.
 | 
			
		||||
 * Semaphores are implemented using queues.  An error can occur if there is
 | 
			
		||||
 * no space on the queue to post a message - indicating that the
 | 
			
		||||
 * semaphore was not first obtained correctly.
 | 
			
		||||
 *
 | 
			
		||||
 * Example usage:
 | 
			
		||||
 <pre>
 | 
			
		||||
 SemaphoreHandle_t xSemaphore = NULL;
 | 
			
		||||
 | 
			
		||||
 void vATask( void * pvParameters )
 | 
			
		||||
 {
 | 
			
		||||
    // Create the semaphore to guard a shared resource.
 | 
			
		||||
    vSemaphoreCreateBinary( xSemaphore );
 | 
			
		||||
 | 
			
		||||
    if( xSemaphore != NULL )
 | 
			
		||||
    {
 | 
			
		||||
        if( xSemaphoreGive( xSemaphore ) != pdTRUE )
 | 
			
		||||
        {
 | 
			
		||||
            // We would expect this call to fail because we cannot give
 | 
			
		||||
            // a semaphore without first "taking" it!
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Obtain the semaphore - don't block if the semaphore is not
 | 
			
		||||
        // immediately available.
 | 
			
		||||
        if( xSemaphoreTake( xSemaphore, ( TickType_t ) 0 ) )
 | 
			
		||||
        {
 | 
			
		||||
            // We now have the semaphore and can access the shared resource.
 | 
			
		||||
 | 
			
		||||
            // ...
 | 
			
		||||
 | 
			
		||||
            // We have finished accessing the shared resource so can free the
 | 
			
		||||
            // semaphore.
 | 
			
		||||
            if( xSemaphoreGive( xSemaphore ) != pdTRUE )
 | 
			
		||||
            {
 | 
			
		||||
                // We would not expect this call to fail because we must have
 | 
			
		||||
                // obtained the semaphore to get here.
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 }
 | 
			
		||||
 </pre>
 | 
			
		||||
 * \defgroup xSemaphoreGive xSemaphoreGive
 | 
			
		||||
 * \ingroup Semaphores
 | 
			
		||||
 */
 | 
			
		||||
#define xSemaphoreGive( xSemaphore )		xQueueGenericSend( ( QueueHandle_t ) ( xSemaphore ), NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * semphr. h
 | 
			
		||||
 * <pre>xSemaphoreGiveRecursive( SemaphoreHandle_t xMutex )</pre>
 | 
			
		||||
 *
 | 
			
		||||
 * <i>Macro</i> to recursively release, or 'give', a mutex type semaphore.
 | 
			
		||||
 * The mutex must have previously been created using a call to
 | 
			
		||||
 * xSemaphoreCreateRecursiveMutex();
 | 
			
		||||
 *
 | 
			
		||||
 * configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this
 | 
			
		||||
 * macro to be available.
 | 
			
		||||
 *
 | 
			
		||||
 * This macro must not be used on mutexes created using xSemaphoreCreateMutex().
 | 
			
		||||
 *
 | 
			
		||||
 * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex
 | 
			
		||||
 * doesn't become available again until the owner has called
 | 
			
		||||
 * xSemaphoreGiveRecursive() for each successful 'take' request.  For example,
 | 
			
		||||
 * if a task successfully 'takes' the same mutex 5 times then the mutex will
 | 
			
		||||
 * not be available to any other task until it has also  'given' the mutex back
 | 
			
		||||
 * exactly five times.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xMutex A handle to the mutex being released, or 'given'.  This is the
 | 
			
		||||
 * handle returned by xSemaphoreCreateMutex();
 | 
			
		||||
 *
 | 
			
		||||
 * @return pdTRUE if the semaphore was given.
 | 
			
		||||
 *
 | 
			
		||||
 * Example usage:
 | 
			
		||||
 <pre>
 | 
			
		||||
 SemaphoreHandle_t xMutex = NULL;
 | 
			
		||||
 | 
			
		||||
 // A task that creates a mutex.
 | 
			
		||||
 void vATask( void * pvParameters )
 | 
			
		||||
 {
 | 
			
		||||
    // Create the mutex to guard a shared resource.
 | 
			
		||||
    xMutex = xSemaphoreCreateRecursiveMutex();
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
 // A task that uses the mutex.
 | 
			
		||||
 void vAnotherTask( void * pvParameters )
 | 
			
		||||
 {
 | 
			
		||||
    // ... Do other things.
 | 
			
		||||
 | 
			
		||||
    if( xMutex != NULL )
 | 
			
		||||
    {
 | 
			
		||||
        // See if we can obtain the mutex.  If the mutex is not available
 | 
			
		||||
        // wait 10 ticks to see if it becomes free.
 | 
			
		||||
        if( xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 ) == pdTRUE )
 | 
			
		||||
        {
 | 
			
		||||
            // We were able to obtain the mutex and can now access the
 | 
			
		||||
            // shared resource.
 | 
			
		||||
 | 
			
		||||
            // ...
 | 
			
		||||
            // For some reason due to the nature of the code further calls to
 | 
			
		||||
			// xSemaphoreTakeRecursive() are made on the same mutex.  In real
 | 
			
		||||
			// code these would not be just sequential calls as this would make
 | 
			
		||||
			// no sense.  Instead the calls are likely to be buried inside
 | 
			
		||||
			// a more complex call structure.
 | 
			
		||||
            xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
 | 
			
		||||
            xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
 | 
			
		||||
 | 
			
		||||
            // The mutex has now been 'taken' three times, so will not be
 | 
			
		||||
			// available to another task until it has also been given back
 | 
			
		||||
			// three times.  Again it is unlikely that real code would have
 | 
			
		||||
			// these calls sequentially, it would be more likely that the calls
 | 
			
		||||
			// to xSemaphoreGiveRecursive() would be called as a call stack
 | 
			
		||||
			// unwound.  This is just for demonstrative purposes.
 | 
			
		||||
            xSemaphoreGiveRecursive( xMutex );
 | 
			
		||||
			xSemaphoreGiveRecursive( xMutex );
 | 
			
		||||
			xSemaphoreGiveRecursive( xMutex );
 | 
			
		||||
 | 
			
		||||
			// Now the mutex can be taken by other tasks.
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            // We could not obtain the mutex and can therefore not access
 | 
			
		||||
            // the shared resource safely.
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 }
 | 
			
		||||
 </pre>
 | 
			
		||||
 * \defgroup xSemaphoreGiveRecursive xSemaphoreGiveRecursive
 | 
			
		||||
 * \ingroup Semaphores
 | 
			
		||||
 */
 | 
			
		||||
#define xSemaphoreGiveRecursive( xMutex )	xQueueGiveMutexRecursive( ( xMutex ) )
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * xSemaphoreAltGive() is an alternative version of xSemaphoreGive().
 | 
			
		||||
 *
 | 
			
		||||
 * The source code that implements the alternative (Alt) API is much
 | 
			
		||||
 * simpler	because it executes everything from within a critical section.
 | 
			
		||||
 * This is	the approach taken by many other RTOSes, but FreeRTOS.org has the
 | 
			
		||||
 * preferred fully featured API too.  The fully featured API has more
 | 
			
		||||
 * complex	code that takes longer to execute, but makes much less use of
 | 
			
		||||
 * critical sections.  Therefore the alternative API sacrifices interrupt
 | 
			
		||||
 * responsiveness to gain execution speed, whereas the fully featured API
 | 
			
		||||
 * sacrifices execution speed to ensure better interrupt responsiveness.
 | 
			
		||||
 */
 | 
			
		||||
#define xSemaphoreAltGive( xSemaphore )		xQueueAltGenericSend( ( QueueHandle_t ) ( xSemaphore ), NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * semphr. h
 | 
			
		||||
 * <pre>
 | 
			
		||||
 xSemaphoreGiveFromISR(
 | 
			
		||||
                          SemaphoreHandle_t xSemaphore,
 | 
			
		||||
                          BaseType_t *pxHigherPriorityTaskWoken
 | 
			
		||||
                      )</pre>
 | 
			
		||||
 *
 | 
			
		||||
 * <i>Macro</i> to  release a semaphore.  The semaphore must have previously been
 | 
			
		||||
 * created with a call to vSemaphoreCreateBinary() or xSemaphoreCreateCounting().
 | 
			
		||||
 *
 | 
			
		||||
 * Mutex type semaphores (those created using a call to xSemaphoreCreateMutex())
 | 
			
		||||
 * must not be used with this macro.
 | 
			
		||||
 *
 | 
			
		||||
 * This macro can be used from an ISR.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xSemaphore A handle to the semaphore being released.  This is the
 | 
			
		||||
 * handle returned when the semaphore was created.
 | 
			
		||||
 *
 | 
			
		||||
 * @param pxHigherPriorityTaskWoken xSemaphoreGiveFromISR() will set
 | 
			
		||||
 * *pxHigherPriorityTaskWoken to pdTRUE if giving the semaphore caused a task
 | 
			
		||||
 * to unblock, and the unblocked task has a priority higher than the currently
 | 
			
		||||
 * running task.  If xSemaphoreGiveFromISR() sets this value to pdTRUE then
 | 
			
		||||
 * a context switch should be requested before the interrupt is exited.
 | 
			
		||||
 *
 | 
			
		||||
 * @return pdTRUE if the semaphore was successfully given, otherwise errQUEUE_FULL.
 | 
			
		||||
 *
 | 
			
		||||
 * Example usage:
 | 
			
		||||
 <pre>
 | 
			
		||||
 \#define LONG_TIME 0xffff
 | 
			
		||||
 \#define TICKS_TO_WAIT	10
 | 
			
		||||
 SemaphoreHandle_t xSemaphore = NULL;
 | 
			
		||||
 | 
			
		||||
 // Repetitive task.
 | 
			
		||||
 void vATask( void * pvParameters )
 | 
			
		||||
 {
 | 
			
		||||
    for( ;; )
 | 
			
		||||
    {
 | 
			
		||||
        // We want this task to run every 10 ticks of a timer.  The semaphore
 | 
			
		||||
        // was created before this task was started.
 | 
			
		||||
 | 
			
		||||
        // Block waiting for the semaphore to become available.
 | 
			
		||||
        if( xSemaphoreTake( xSemaphore, LONG_TIME ) == pdTRUE )
 | 
			
		||||
        {
 | 
			
		||||
            // It is time to execute.
 | 
			
		||||
 | 
			
		||||
            // ...
 | 
			
		||||
 | 
			
		||||
            // We have finished our task.  Return to the top of the loop where
 | 
			
		||||
            // we will block on the semaphore until it is time to execute
 | 
			
		||||
            // again.  Note when using the semaphore for synchronisation with an
 | 
			
		||||
			// ISR in this manner there is no need to 'give' the semaphore back.
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
 // Timer ISR
 | 
			
		||||
 void vTimerISR( void * pvParameters )
 | 
			
		||||
 {
 | 
			
		||||
 static uint8_t ucLocalTickCount = 0;
 | 
			
		||||
 static BaseType_t xHigherPriorityTaskWoken;
 | 
			
		||||
 | 
			
		||||
    // A timer tick has occurred.
 | 
			
		||||
 | 
			
		||||
    // ... Do other time functions.
 | 
			
		||||
 | 
			
		||||
    // Is it time for vATask () to run?
 | 
			
		||||
	xHigherPriorityTaskWoken = pdFALSE;
 | 
			
		||||
    ucLocalTickCount++;
 | 
			
		||||
    if( ucLocalTickCount >= TICKS_TO_WAIT )
 | 
			
		||||
    {
 | 
			
		||||
        // Unblock the task by releasing the semaphore.
 | 
			
		||||
        xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken );
 | 
			
		||||
 | 
			
		||||
        // Reset the count so we release the semaphore again in 10 ticks time.
 | 
			
		||||
        ucLocalTickCount = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if( xHigherPriorityTaskWoken != pdFALSE )
 | 
			
		||||
    {
 | 
			
		||||
        // We can force a context switch here.  Context switching from an
 | 
			
		||||
        // ISR uses port specific syntax.  Check the demo task for your port
 | 
			
		||||
        // to find the syntax required.
 | 
			
		||||
    }
 | 
			
		||||
 }
 | 
			
		||||
 </pre>
 | 
			
		||||
 * \defgroup xSemaphoreGiveFromISR xSemaphoreGiveFromISR
 | 
			
		||||
 * \ingroup Semaphores
 | 
			
		||||
 */
 | 
			
		||||
#define xSemaphoreGiveFromISR( xSemaphore, pxHigherPriorityTaskWoken )	xQueueGenericSendFromISR( ( QueueHandle_t ) ( xSemaphore ), NULL, ( pxHigherPriorityTaskWoken ), queueSEND_TO_BACK )
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * semphr. h
 | 
			
		||||
 * <pre>
 | 
			
		||||
 xSemaphoreTakeFromISR(
 | 
			
		||||
                          SemaphoreHandle_t xSemaphore,
 | 
			
		||||
                          BaseType_t *pxHigherPriorityTaskWoken
 | 
			
		||||
                      )</pre>
 | 
			
		||||
 *
 | 
			
		||||
 * <i>Macro</i> to  take a semaphore from an ISR.  The semaphore must have
 | 
			
		||||
 * previously been created with a call to vSemaphoreCreateBinary() or
 | 
			
		||||
 * xSemaphoreCreateCounting().
 | 
			
		||||
 *
 | 
			
		||||
 * Mutex type semaphores (those created using a call to xSemaphoreCreateMutex())
 | 
			
		||||
 * must not be used with this macro.
 | 
			
		||||
 *
 | 
			
		||||
 * This macro can be used from an ISR, however taking a semaphore from an ISR
 | 
			
		||||
 * is not a common operation.  It is likely to only be useful when taking a
 | 
			
		||||
 * counting semaphore when an interrupt is obtaining an object from a resource
 | 
			
		||||
 * pool (when the semaphore count indicates the number of resources available).
 | 
			
		||||
 *
 | 
			
		||||
 * @param xSemaphore A handle to the semaphore being taken.  This is the
 | 
			
		||||
 * handle returned when the semaphore was created.
 | 
			
		||||
 *
 | 
			
		||||
 * @param pxHigherPriorityTaskWoken xSemaphoreTakeFromISR() will set
 | 
			
		||||
 * *pxHigherPriorityTaskWoken to pdTRUE if taking the semaphore caused a task
 | 
			
		||||
 * to unblock, and the unblocked task has a priority higher than the currently
 | 
			
		||||
 * running task.  If xSemaphoreTakeFromISR() sets this value to pdTRUE then
 | 
			
		||||
 * a context switch should be requested before the interrupt is exited.
 | 
			
		||||
 *
 | 
			
		||||
 * @return pdTRUE if the semaphore was successfully taken, otherwise
 | 
			
		||||
 * pdFALSE
 | 
			
		||||
 */
 | 
			
		||||
#define xSemaphoreTakeFromISR( xSemaphore, pxHigherPriorityTaskWoken )	xQueueReceiveFromISR( ( QueueHandle_t ) ( xSemaphore ), NULL, ( pxHigherPriorityTaskWoken ) )
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * semphr. h
 | 
			
		||||
 * <pre>SemaphoreHandle_t xSemaphoreCreateMutex( void )</pre>
 | 
			
		||||
 *
 | 
			
		||||
 * <i>Macro</i> that implements a mutex semaphore by using the existing queue
 | 
			
		||||
 * mechanism.
 | 
			
		||||
 *
 | 
			
		||||
 * Mutexes created using this macro can be accessed using the xSemaphoreTake()
 | 
			
		||||
 * and xSemaphoreGive() macros.  The xSemaphoreTakeRecursive() and
 | 
			
		||||
 * xSemaphoreGiveRecursive() macros should not be used.
 | 
			
		||||
 *
 | 
			
		||||
 * This type of semaphore uses a priority inheritance mechanism so a task
 | 
			
		||||
 * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the
 | 
			
		||||
 * semaphore it is no longer required.
 | 
			
		||||
 *
 | 
			
		||||
 * Mutex type semaphores cannot be used from within interrupt service routines.
 | 
			
		||||
 *
 | 
			
		||||
 * See vSemaphoreCreateBinary() for an alternative implementation that can be
 | 
			
		||||
 * used for pure synchronisation (where one task or interrupt always 'gives' the
 | 
			
		||||
 * semaphore and another always 'takes' the semaphore) and from within interrupt
 | 
			
		||||
 * service routines.
 | 
			
		||||
 *
 | 
			
		||||
 * @return xSemaphore Handle to the created mutex semaphore.  Should be of type
 | 
			
		||||
 *		SemaphoreHandle_t.
 | 
			
		||||
 *
 | 
			
		||||
 * Example usage:
 | 
			
		||||
 <pre>
 | 
			
		||||
 SemaphoreHandle_t xSemaphore;
 | 
			
		||||
 | 
			
		||||
 void vATask( void * pvParameters )
 | 
			
		||||
 {
 | 
			
		||||
    // Semaphore cannot be used before a call to xSemaphoreCreateMutex().
 | 
			
		||||
    // This is a macro so pass the variable in directly.
 | 
			
		||||
    xSemaphore = xSemaphoreCreateMutex();
 | 
			
		||||
 | 
			
		||||
    if( xSemaphore != NULL )
 | 
			
		||||
    {
 | 
			
		||||
        // The semaphore was created successfully.
 | 
			
		||||
        // The semaphore can now be used.
 | 
			
		||||
    }
 | 
			
		||||
 }
 | 
			
		||||
 </pre>
 | 
			
		||||
 * \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex
 | 
			
		||||
 * \ingroup Semaphores
 | 
			
		||||
 */
 | 
			
		||||
#define xSemaphoreCreateMutex() xQueueCreateMutex( queueQUEUE_TYPE_MUTEX )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * semphr. h
 | 
			
		||||
 * <pre>SemaphoreHandle_t xSemaphoreCreateRecursiveMutex( void )</pre>
 | 
			
		||||
 *
 | 
			
		||||
 * <i>Macro</i> that implements a recursive mutex by using the existing queue
 | 
			
		||||
 * mechanism.
 | 
			
		||||
 *
 | 
			
		||||
 * Mutexes created using this macro can be accessed using the
 | 
			
		||||
 * xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() macros.  The
 | 
			
		||||
 * xSemaphoreTake() and xSemaphoreGive() macros should not be used.
 | 
			
		||||
 *
 | 
			
		||||
 * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex
 | 
			
		||||
 * doesn't become available again until the owner has called
 | 
			
		||||
 * xSemaphoreGiveRecursive() for each successful 'take' request.  For example,
 | 
			
		||||
 * if a task successfully 'takes' the same mutex 5 times then the mutex will
 | 
			
		||||
 * not be available to any other task until it has also  'given' the mutex back
 | 
			
		||||
 * exactly five times.
 | 
			
		||||
 *
 | 
			
		||||
 * This type of semaphore uses a priority inheritance mechanism so a task
 | 
			
		||||
 * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the
 | 
			
		||||
 * semaphore it is no longer required.
 | 
			
		||||
 *
 | 
			
		||||
 * Mutex type semaphores cannot be used from within interrupt service routines.
 | 
			
		||||
 *
 | 
			
		||||
 * See vSemaphoreCreateBinary() for an alternative implementation that can be
 | 
			
		||||
 * used for pure synchronisation (where one task or interrupt always 'gives' the
 | 
			
		||||
 * semaphore and another always 'takes' the semaphore) and from within interrupt
 | 
			
		||||
 * service routines.
 | 
			
		||||
 *
 | 
			
		||||
 * @return xSemaphore Handle to the created mutex semaphore.  Should be of type
 | 
			
		||||
 *		SemaphoreHandle_t.
 | 
			
		||||
 *
 | 
			
		||||
 * Example usage:
 | 
			
		||||
 <pre>
 | 
			
		||||
 SemaphoreHandle_t xSemaphore;
 | 
			
		||||
 | 
			
		||||
 void vATask( void * pvParameters )
 | 
			
		||||
 {
 | 
			
		||||
    // Semaphore cannot be used before a call to xSemaphoreCreateMutex().
 | 
			
		||||
    // This is a macro so pass the variable in directly.
 | 
			
		||||
    xSemaphore = xSemaphoreCreateRecursiveMutex();
 | 
			
		||||
 | 
			
		||||
    if( xSemaphore != NULL )
 | 
			
		||||
    {
 | 
			
		||||
        // The semaphore was created successfully.
 | 
			
		||||
        // The semaphore can now be used.
 | 
			
		||||
    }
 | 
			
		||||
 }
 | 
			
		||||
 </pre>
 | 
			
		||||
 * \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex
 | 
			
		||||
 * \ingroup Semaphores
 | 
			
		||||
 */
 | 
			
		||||
#define xSemaphoreCreateRecursiveMutex() xQueueCreateMutex( queueQUEUE_TYPE_RECURSIVE_MUTEX )
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * semphr. h
 | 
			
		||||
 * <pre>SemaphoreHandle_t xSemaphoreCreateCounting( UBaseType_t uxMaxCount, UBaseType_t uxInitialCount )</pre>
 | 
			
		||||
 *
 | 
			
		||||
 * <i>Macro</i> that creates a counting semaphore by using the existing
 | 
			
		||||
 * queue mechanism.
 | 
			
		||||
 *
 | 
			
		||||
 * Counting semaphores are typically used for two things:
 | 
			
		||||
 *
 | 
			
		||||
 * 1) Counting events.
 | 
			
		||||
 *
 | 
			
		||||
 *    In this usage scenario an event handler will 'give' a semaphore each time
 | 
			
		||||
 *    an event occurs (incrementing the semaphore count value), and a handler
 | 
			
		||||
 *    task will 'take' a semaphore each time it processes an event
 | 
			
		||||
 *    (decrementing the semaphore count value).  The count value is therefore
 | 
			
		||||
 *    the difference between the number of events that have occurred and the
 | 
			
		||||
 *    number that have been processed.  In this case it is desirable for the
 | 
			
		||||
 *    initial count value to be zero.
 | 
			
		||||
 *
 | 
			
		||||
 * 2) Resource management.
 | 
			
		||||
 *
 | 
			
		||||
 *    In this usage scenario the count value indicates the number of resources
 | 
			
		||||
 *    available.  To obtain control of a resource a task must first obtain a
 | 
			
		||||
 *    semaphore - decrementing the semaphore count value.  When the count value
 | 
			
		||||
 *    reaches zero there are no free resources.  When a task finishes with the
 | 
			
		||||
 *    resource it 'gives' the semaphore back - incrementing the semaphore count
 | 
			
		||||
 *    value.  In this case it is desirable for the initial count value to be
 | 
			
		||||
 *    equal to the maximum count value, indicating that all resources are free.
 | 
			
		||||
 *
 | 
			
		||||
 * @param uxMaxCount The maximum count value that can be reached.  When the
 | 
			
		||||
 *        semaphore reaches this value it can no longer be 'given'.
 | 
			
		||||
 *
 | 
			
		||||
 * @param uxInitialCount The count value assigned to the semaphore when it is
 | 
			
		||||
 *        created.
 | 
			
		||||
 *
 | 
			
		||||
 * @return Handle to the created semaphore.  Null if the semaphore could not be
 | 
			
		||||
 *         created.
 | 
			
		||||
 *
 | 
			
		||||
 * Example usage:
 | 
			
		||||
 <pre>
 | 
			
		||||
 SemaphoreHandle_t xSemaphore;
 | 
			
		||||
 | 
			
		||||
 void vATask( void * pvParameters )
 | 
			
		||||
 {
 | 
			
		||||
 SemaphoreHandle_t xSemaphore = NULL;
 | 
			
		||||
 | 
			
		||||
    // Semaphore cannot be used before a call to xSemaphoreCreateCounting().
 | 
			
		||||
    // The max value to which the semaphore can count should be 10, and the
 | 
			
		||||
    // initial value assigned to the count should be 0.
 | 
			
		||||
    xSemaphore = xSemaphoreCreateCounting( 10, 0 );
 | 
			
		||||
 | 
			
		||||
    if( xSemaphore != NULL )
 | 
			
		||||
    {
 | 
			
		||||
        // The semaphore was created successfully.
 | 
			
		||||
        // The semaphore can now be used.
 | 
			
		||||
    }
 | 
			
		||||
 }
 | 
			
		||||
 </pre>
 | 
			
		||||
 * \defgroup xSemaphoreCreateCounting xSemaphoreCreateCounting
 | 
			
		||||
 * \ingroup Semaphores
 | 
			
		||||
 */
 | 
			
		||||
#define xSemaphoreCreateCounting( uxMaxCount, uxInitialCount ) xQueueCreateCountingSemaphore( ( uxMaxCount ), ( uxInitialCount ) )
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * semphr. h
 | 
			
		||||
 * <pre>void vSemaphoreDelete( SemaphoreHandle_t xSemaphore );</pre>
 | 
			
		||||
 *
 | 
			
		||||
 * Delete a semaphore.  This function must be used with care.  For example,
 | 
			
		||||
 * do not delete a mutex type semaphore if the mutex is held by a task.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xSemaphore A handle to the semaphore to be deleted.
 | 
			
		||||
 *
 | 
			
		||||
 * \defgroup vSemaphoreDelete vSemaphoreDelete
 | 
			
		||||
 * \ingroup Semaphores
 | 
			
		||||
 */
 | 
			
		||||
#define vSemaphoreDelete( xSemaphore ) vQueueDelete( ( QueueHandle_t ) ( xSemaphore ) )
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * semphr.h
 | 
			
		||||
 * <pre>TaskHandle_t xSemaphoreGetMutexHolder( SemaphoreHandle_t xMutex );</pre>
 | 
			
		||||
 *
 | 
			
		||||
 * If xMutex is indeed a mutex type semaphore, return the current mutex holder.
 | 
			
		||||
 * If xMutex is not a mutex type semaphore, or the mutex is available (not held
 | 
			
		||||
 * by a task), return NULL.
 | 
			
		||||
 *
 | 
			
		||||
 * Note: This is a good way of determining if the calling task is the mutex
 | 
			
		||||
 * holder, but not a good way of determining the identity of the mutex holder as
 | 
			
		||||
 * the holder may change between the function exiting and the returned value
 | 
			
		||||
 * being tested.
 | 
			
		||||
 */
 | 
			
		||||
#define xSemaphoreGetMutexHolder( xSemaphore ) xQueueGetMutexHolder( ( xSemaphore ) )
 | 
			
		||||
 | 
			
		||||
#endif /* SEMAPHORE_H */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										1570
									
								
								component/os/freertos/freertos_v8.1.2/Source/include/task.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1570
									
								
								component/os/freertos/freertos_v8.1.2/Source/include/task.h
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										1121
									
								
								component/os/freertos/freertos_v8.1.2/Source/include/timers.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1121
									
								
								component/os/freertos/freertos_v8.1.2/Source/include/timers.h
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										204
									
								
								component/os/freertos/freertos_v8.1.2/Source/list.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										204
									
								
								component/os/freertos/freertos_v8.1.2/Source/list.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,204 @@
 | 
			
		|||
/*
 | 
			
		||||
    FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd.
 | 
			
		||||
    All rights reserved
 | 
			
		||||
 | 
			
		||||
    VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
 | 
			
		||||
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    FreeRTOS provides completely free yet professionally developed,    *
 | 
			
		||||
     *    robust, strictly quality controlled, supported, and cross          *
 | 
			
		||||
     *    platform software that has become a de facto standard.             *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    Help yourself get started quickly and support the FreeRTOS         *
 | 
			
		||||
     *    project by purchasing a FreeRTOS tutorial book, reference          *
 | 
			
		||||
     *    manual, or both from: http://www.FreeRTOS.org/Documentation        *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    Thank you!                                                         *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
 | 
			
		||||
    This file is part of the FreeRTOS distribution.
 | 
			
		||||
 | 
			
		||||
    FreeRTOS is free software; you can redistribute it and/or modify it under
 | 
			
		||||
    the terms of the GNU General Public License (version 2) as published by the
 | 
			
		||||
    Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
 | 
			
		||||
 | 
			
		||||
    >>!   NOTE: The modification to the GPL is included to allow you to     !<<
 | 
			
		||||
    >>!   distribute a combined work that includes FreeRTOS without being   !<<
 | 
			
		||||
    >>!   obliged to provide the source code for proprietary components     !<<
 | 
			
		||||
    >>!   outside of the FreeRTOS kernel.                                   !<<
 | 
			
		||||
 | 
			
		||||
    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
 | 
			
		||||
    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
    FOR A PARTICULAR PURPOSE.  Full license text is available from the following
 | 
			
		||||
    link: http://www.freertos.org/a00114.html
 | 
			
		||||
 | 
			
		||||
    1 tab == 4 spaces!
 | 
			
		||||
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    Having a problem?  Start by reading the FAQ "My application does   *
 | 
			
		||||
     *    not run, what could be wrong?"                                     *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    http://www.FreeRTOS.org/FAQHelp.html                               *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
 | 
			
		||||
    http://www.FreeRTOS.org - Documentation, books, training, latest versions,
 | 
			
		||||
    license and Real Time Engineers Ltd. contact details.
 | 
			
		||||
 | 
			
		||||
    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
 | 
			
		||||
    including FreeRTOS+Trace - an indispensable productivity tool, a DOS
 | 
			
		||||
    compatible FAT file system, and our tiny thread aware UDP/IP stack.
 | 
			
		||||
 | 
			
		||||
    http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
 | 
			
		||||
    Integrity Systems to sell under the OpenRTOS brand.  Low cost OpenRTOS
 | 
			
		||||
    licenses offer ticketed support, indemnification and middleware.
 | 
			
		||||
 | 
			
		||||
    http://www.SafeRTOS.com - High Integrity Systems also provide a safety
 | 
			
		||||
    engineered and independently SIL3 certified version for use in safety and
 | 
			
		||||
    mission critical applications that require provable dependability.
 | 
			
		||||
 | 
			
		||||
    1 tab == 4 spaces!
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include "FreeRTOS.h"
 | 
			
		||||
#include "list.h"
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------
 | 
			
		||||
 * PUBLIC LIST API documented in list.h
 | 
			
		||||
 *----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
void vListInitialise( List_t * const pxList )
 | 
			
		||||
{
 | 
			
		||||
	/* The list structure contains a list item which is used to mark the
 | 
			
		||||
	end of the list.  To initialise the list the list end is inserted
 | 
			
		||||
	as the only list entry. */
 | 
			
		||||
	pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd );			/*lint !e826 !e740 The mini list structure is used as the list end to save RAM.  This is checked and valid. */
 | 
			
		||||
 | 
			
		||||
	/* The list end value is the highest possible value in the list to
 | 
			
		||||
	ensure it remains at the end of the list. */
 | 
			
		||||
	pxList->xListEnd.xItemValue = portMAX_DELAY;
 | 
			
		||||
 | 
			
		||||
	/* The list end next and previous pointers point to itself so we know
 | 
			
		||||
	when the list is empty. */
 | 
			
		||||
	pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd );	/*lint !e826 !e740 The mini list structure is used as the list end to save RAM.  This is checked and valid. */
 | 
			
		||||
	pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd );/*lint !e826 !e740 The mini list structure is used as the list end to save RAM.  This is checked and valid. */
 | 
			
		||||
 | 
			
		||||
	pxList->uxNumberOfItems = ( UBaseType_t ) 0U;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
void vListInitialiseItem( ListItem_t * const pxItem )
 | 
			
		||||
{
 | 
			
		||||
	/* Make sure the list item is not recorded as being on a list. */
 | 
			
		||||
	pxItem->pvContainer = NULL;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem )
 | 
			
		||||
{
 | 
			
		||||
ListItem_t * const pxIndex = pxList->pxIndex;
 | 
			
		||||
 | 
			
		||||
	/* Insert a new list item into pxList, but rather than sort the list,
 | 
			
		||||
	makes the new list item the last item to be removed by a call to
 | 
			
		||||
	listGET_OWNER_OF_NEXT_ENTRY(). */
 | 
			
		||||
	pxNewListItem->pxNext = pxIndex;
 | 
			
		||||
	pxNewListItem->pxPrevious = pxIndex->pxPrevious;
 | 
			
		||||
	pxIndex->pxPrevious->pxNext = pxNewListItem;
 | 
			
		||||
	pxIndex->pxPrevious = pxNewListItem;
 | 
			
		||||
 | 
			
		||||
	/* Remember which list the item is in. */
 | 
			
		||||
	pxNewListItem->pvContainer = ( void * ) pxList;
 | 
			
		||||
 | 
			
		||||
	( pxList->uxNumberOfItems )++;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem )
 | 
			
		||||
{
 | 
			
		||||
ListItem_t *pxIterator;
 | 
			
		||||
const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
 | 
			
		||||
 | 
			
		||||
	/* Insert the new list item into the list, sorted in xItemValue order.
 | 
			
		||||
 | 
			
		||||
	If the list already contains a list item with the same item value then
 | 
			
		||||
	the new list item should be placed after it.  This ensures that TCB's which
 | 
			
		||||
	are stored in ready lists (all of which have the same xItemValue value)
 | 
			
		||||
	get an equal share of the CPU.  However, if the xItemValue is the same as
 | 
			
		||||
	the back marker the iteration loop below will not end.  This means we need
 | 
			
		||||
	to guard against this by checking the value first and modifying the
 | 
			
		||||
	algorithm slightly if necessary. */
 | 
			
		||||
	if( xValueOfInsertion == portMAX_DELAY )
 | 
			
		||||
	{
 | 
			
		||||
		pxIterator = pxList->xListEnd.pxPrevious;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		/* *** NOTE ***********************************************************
 | 
			
		||||
		If you find your application is crashing here then likely causes are:
 | 
			
		||||
			1) Stack overflow -
 | 
			
		||||
			   see http://www.freertos.org/Stacks-and-stack-overflow-checking.html
 | 
			
		||||
			2) Incorrect interrupt priority assignment, especially on Cortex-M3
 | 
			
		||||
			   parts where numerically high priority values denote low actual
 | 
			
		||||
			   interrupt priorities, which can seem counter intuitive.  See
 | 
			
		||||
			   configMAX_SYSCALL_INTERRUPT_PRIORITY on http://www.freertos.org/a00110.html
 | 
			
		||||
			3) Calling an API function from within a critical section or when
 | 
			
		||||
			   the scheduler is suspended, or calling an API function that does
 | 
			
		||||
			   not end in "FromISR" from an interrupt.
 | 
			
		||||
			4) Using a queue or semaphore before it has been initialised or
 | 
			
		||||
			   before the scheduler has been started (are interrupts firing
 | 
			
		||||
			   before vTaskStartScheduler() has been called?).
 | 
			
		||||
		See http://www.freertos.org/FAQHelp.html for more tips, and ensure
 | 
			
		||||
		configASSERT() is defined!  http://www.freertos.org/a00110.html#configASSERT
 | 
			
		||||
		**********************************************************************/
 | 
			
		||||
 | 
			
		||||
		for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) /*lint !e826 !e740 The mini list structure is used as the list end to save RAM.  This is checked and valid. */
 | 
			
		||||
		{
 | 
			
		||||
			/* There is nothing to do here, we are just iterating to the
 | 
			
		||||
			wanted insertion position. */
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	pxNewListItem->pxNext = pxIterator->pxNext;
 | 
			
		||||
	pxNewListItem->pxNext->pxPrevious = pxNewListItem;
 | 
			
		||||
	pxNewListItem->pxPrevious = pxIterator;
 | 
			
		||||
	pxIterator->pxNext = pxNewListItem;
 | 
			
		||||
 | 
			
		||||
	/* Remember which list the item is in.  This allows fast removal of the
 | 
			
		||||
	item later. */
 | 
			
		||||
	pxNewListItem->pvContainer = ( void * ) pxList;
 | 
			
		||||
 | 
			
		||||
	( pxList->uxNumberOfItems )++;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove )
 | 
			
		||||
{
 | 
			
		||||
/* The list item knows which list it is in.  Obtain the list from the list
 | 
			
		||||
item. */
 | 
			
		||||
List_t * const pxList = ( List_t * ) pxItemToRemove->pvContainer;
 | 
			
		||||
 | 
			
		||||
	pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;
 | 
			
		||||
	pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext;
 | 
			
		||||
 | 
			
		||||
	/* Make sure the index is left pointing to a valid item. */
 | 
			
		||||
	if( pxList->pxIndex == pxItemToRemove )
 | 
			
		||||
	{
 | 
			
		||||
		pxList->pxIndex = pxItemToRemove->pxPrevious;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	pxItemToRemove->pvContainer = NULL;
 | 
			
		||||
	( pxList->uxNumberOfItems )--;
 | 
			
		||||
 | 
			
		||||
	return pxList->uxNumberOfItems;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,746 @@
 | 
			
		|||
/*
 | 
			
		||||
    FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd.
 | 
			
		||||
    All rights reserved
 | 
			
		||||
 | 
			
		||||
    VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
 | 
			
		||||
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    FreeRTOS provides completely free yet professionally developed,    *
 | 
			
		||||
     *    robust, strictly quality controlled, supported, and cross          *
 | 
			
		||||
     *    platform software that has become a de facto standard.             *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    Help yourself get started quickly and support the FreeRTOS         *
 | 
			
		||||
     *    project by purchasing a FreeRTOS tutorial book, reference          *
 | 
			
		||||
     *    manual, or both from: http://www.FreeRTOS.org/Documentation        *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    Thank you!                                                         *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
 | 
			
		||||
    This file is part of the FreeRTOS distribution.
 | 
			
		||||
 | 
			
		||||
    FreeRTOS is free software; you can redistribute it and/or modify it under
 | 
			
		||||
    the terms of the GNU General Public License (version 2) as published by the
 | 
			
		||||
    Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
 | 
			
		||||
 | 
			
		||||
    >>!   NOTE: The modification to the GPL is included to allow you to     !<<
 | 
			
		||||
    >>!   distribute a combined work that includes FreeRTOS without being   !<<
 | 
			
		||||
    >>!   obliged to provide the source code for proprietary components     !<<
 | 
			
		||||
    >>!   outside of the FreeRTOS kernel.                                   !<<
 | 
			
		||||
 | 
			
		||||
    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
 | 
			
		||||
    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
    FOR A PARTICULAR PURPOSE.  Full license text is available from the following
 | 
			
		||||
    link: http://www.freertos.org/a00114.html
 | 
			
		||||
 | 
			
		||||
    1 tab == 4 spaces!
 | 
			
		||||
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    Having a problem?  Start by reading the FAQ "My application does   *
 | 
			
		||||
     *    not run, what could be wrong?"                                     *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    http://www.FreeRTOS.org/FAQHelp.html                               *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
 | 
			
		||||
    http://www.FreeRTOS.org - Documentation, books, training, latest versions,
 | 
			
		||||
    license and Real Time Engineers Ltd. contact details.
 | 
			
		||||
 | 
			
		||||
    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
 | 
			
		||||
    including FreeRTOS+Trace - an indispensable productivity tool, a DOS
 | 
			
		||||
    compatible FAT file system, and our tiny thread aware UDP/IP stack.
 | 
			
		||||
 | 
			
		||||
    http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
 | 
			
		||||
    Integrity Systems to sell under the OpenRTOS brand.  Low cost OpenRTOS
 | 
			
		||||
    licenses offer ticketed support, indemnification and middleware.
 | 
			
		||||
 | 
			
		||||
    http://www.SafeRTOS.com - High Integrity Systems also provide a safety
 | 
			
		||||
    engineered and independently SIL3 certified version for use in safety and
 | 
			
		||||
    mission critical applications that require provable dependability.
 | 
			
		||||
 | 
			
		||||
    1 tab == 4 spaces!
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------
 | 
			
		||||
 * Implementation of functions defined in portable.h for the ARM CM3 port.
 | 
			
		||||
 *----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/* Scheduler includes. */
 | 
			
		||||
#include "FreeRTOS.h"
 | 
			
		||||
#include "task.h"
 | 
			
		||||
 | 
			
		||||
/* For backward compatibility, ensure configKERNEL_INTERRUPT_PRIORITY is
 | 
			
		||||
defined.  The value should also ensure backward compatibility.
 | 
			
		||||
FreeRTOS.org versions prior to V4.4.0 did not include this definition. */
 | 
			
		||||
#ifndef configKERNEL_INTERRUPT_PRIORITY
 | 
			
		||||
	#define configKERNEL_INTERRUPT_PRIORITY 255
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef configSYSTICK_CLOCK_HZ
 | 
			
		||||
	#define configSYSTICK_CLOCK_HZ configCPU_CLOCK_HZ
 | 
			
		||||
	/* Ensure the SysTick is clocked at the same frequency as the core. */
 | 
			
		||||
	#define portNVIC_SYSTICK_CLK_BIT	( 1UL << 2UL )
 | 
			
		||||
#else
 | 
			
		||||
	/* The way the SysTick is clocked is not modified in case it is not the same
 | 
			
		||||
	as the core. */
 | 
			
		||||
	#define portNVIC_SYSTICK_CLK_BIT	( 0 )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Constants required to manipulate the core.  Registers first... */
 | 
			
		||||
#define portNVIC_SYSTICK_CTRL_REG			( * ( ( volatile uint32_t * ) 0xe000e010 ) )
 | 
			
		||||
#define portNVIC_SYSTICK_LOAD_REG			( * ( ( volatile uint32_t * ) 0xe000e014 ) )
 | 
			
		||||
#define portNVIC_SYSTICK_CURRENT_VALUE_REG	( * ( ( volatile uint32_t * ) 0xe000e018 ) )
 | 
			
		||||
#define portNVIC_SYSPRI2_REG				( * ( ( volatile uint32_t * ) 0xe000ed20 ) )
 | 
			
		||||
/* ...then bits in the registers. */
 | 
			
		||||
#define portNVIC_SYSTICK_INT_BIT			( 1UL << 1UL )
 | 
			
		||||
#define portNVIC_SYSTICK_ENABLE_BIT			( 1UL << 0UL )
 | 
			
		||||
#define portNVIC_SYSTICK_COUNT_FLAG_BIT		( 1UL << 16UL )
 | 
			
		||||
#define portNVIC_PENDSVCLEAR_BIT 			( 1UL << 27UL )
 | 
			
		||||
#define portNVIC_PEND_SYSTICK_CLEAR_BIT		( 1UL << 25UL )
 | 
			
		||||
 | 
			
		||||
#define portNVIC_PENDSV_PRI					( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL )
 | 
			
		||||
#define portNVIC_SYSTICK_PRI				( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL )
 | 
			
		||||
 | 
			
		||||
/* Constants required to check the validity of an interrupt priority. */
 | 
			
		||||
#define portFIRST_USER_INTERRUPT_NUMBER		( 16 )
 | 
			
		||||
#define portNVIC_IP_REGISTERS_OFFSET_16 	( 0xE000E3F0 )
 | 
			
		||||
#define portAIRCR_REG						( * ( ( volatile uint32_t * ) 0xE000ED0C ) )
 | 
			
		||||
#define portMAX_8_BIT_VALUE					( ( uint8_t ) 0xff )
 | 
			
		||||
#define portTOP_BIT_OF_BYTE					( ( uint8_t ) 0x80 )
 | 
			
		||||
#define portMAX_PRIGROUP_BITS				( ( uint8_t ) 7 )
 | 
			
		||||
#define portPRIORITY_GROUP_MASK				( 0x07UL << 8UL )
 | 
			
		||||
#define portPRIGROUP_SHIFT					( 8UL )
 | 
			
		||||
 | 
			
		||||
/* Masks off all bits but the VECTACTIVE bits in the ICSR register. */
 | 
			
		||||
#define portVECTACTIVE_MASK					( 0x1FUL )
 | 
			
		||||
 | 
			
		||||
/* Constants required to set up the initial stack. */
 | 
			
		||||
#define portINITIAL_XPSR					( 0x01000000UL )
 | 
			
		||||
 | 
			
		||||
/* The systick is a 24-bit counter. */
 | 
			
		||||
#define portMAX_24_BIT_NUMBER				( 0xffffffUL )
 | 
			
		||||
 | 
			
		||||
/* A fiddle factor to estimate the number of SysTick counts that would have
 | 
			
		||||
occurred while the SysTick counter is stopped during tickless idle
 | 
			
		||||
calculations. */
 | 
			
		||||
#define portMISSED_COUNTS_FACTOR			( 45UL )
 | 
			
		||||
 | 
			
		||||
/* Let the user override the pre-loading of the initial LR with the address of
 | 
			
		||||
prvTaskExitError() in case is messes up unwinding of the stack in the
 | 
			
		||||
debugger. */
 | 
			
		||||
#ifdef configTASK_RETURN_ADDRESS
 | 
			
		||||
	#define portTASK_RETURN_ADDRESS	configTASK_RETURN_ADDRESS
 | 
			
		||||
#else
 | 
			
		||||
	#define portTASK_RETURN_ADDRESS	prvTaskExitError
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Each task maintains its own interrupt status in the critical nesting
 | 
			
		||||
variable. */
 | 
			
		||||
static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Setup the timer to generate the tick interrupts.  The implementation in this
 | 
			
		||||
 * file is weak to allow application writers to change the timer used to
 | 
			
		||||
 * generate the tick interrupt.
 | 
			
		||||
 */
 | 
			
		||||
void vPortSetupTimerInterrupt( void );
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Exception handlers.
 | 
			
		||||
 */
 | 
			
		||||
void xPortPendSVHandler( void ) __attribute__ (( naked ));
 | 
			
		||||
void xPortSysTickHandler( void );
 | 
			
		||||
void vPortSVCHandler( void ) __attribute__ (( naked ));
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Start first task is a separate function so it can be tested in isolation.
 | 
			
		||||
 */
 | 
			
		||||
static void prvPortStartFirstTask( void ) __attribute__ (( naked ));
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Used to catch tasks that attempt to return from their implementing function.
 | 
			
		||||
 */
 | 
			
		||||
static void prvTaskExitError( void );
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * The number of SysTick increments that make up one tick period.
 | 
			
		||||
 */
 | 
			
		||||
#if configUSE_TICKLESS_IDLE == 1
 | 
			
		||||
	static uint32_t ulTimerCountsForOneTick = 0;
 | 
			
		||||
#endif /* configUSE_TICKLESS_IDLE */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * The maximum number of tick periods that can be suppressed is limited by the
 | 
			
		||||
 * 24 bit resolution of the SysTick timer.
 | 
			
		||||
 */
 | 
			
		||||
#if configUSE_TICKLESS_IDLE == 1
 | 
			
		||||
	static uint32_t xMaximumPossibleSuppressedTicks = 0;
 | 
			
		||||
#endif /* configUSE_TICKLESS_IDLE */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Compensate for the CPU cycles that pass while the SysTick is stopped (low
 | 
			
		||||
 * power functionality only.
 | 
			
		||||
 */
 | 
			
		||||
#if configUSE_TICKLESS_IDLE == 1
 | 
			
		||||
	static uint32_t ulStoppedTimerCompensation = 0;
 | 
			
		||||
#endif /* configUSE_TICKLESS_IDLE */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure
 | 
			
		||||
 * FreeRTOS API functions are not called from interrupts that have been assigned
 | 
			
		||||
 * a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY.
 | 
			
		||||
 */
 | 
			
		||||
#if ( configASSERT_DEFINED == 1 )
 | 
			
		||||
	 static uint8_t ucMaxSysCallPriority = 0;
 | 
			
		||||
	 static uint32_t ulMaxPRIGROUPValue = 0;
 | 
			
		||||
	 static const volatile uint8_t * const pcInterruptPriorityRegisters = ( const volatile uint8_t * const ) portNVIC_IP_REGISTERS_OFFSET_16;
 | 
			
		||||
#endif /* configASSERT_DEFINED */
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * See header file for description.
 | 
			
		||||
 */
 | 
			
		||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
 | 
			
		||||
{
 | 
			
		||||
	/* Simulate the stack frame as it would be created by a context switch
 | 
			
		||||
	interrupt. */
 | 
			
		||||
	pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */
 | 
			
		||||
	*pxTopOfStack = portINITIAL_XPSR;	/* xPSR */
 | 
			
		||||
	pxTopOfStack--;
 | 
			
		||||
	*pxTopOfStack = ( StackType_t ) pxCode;	/* PC */
 | 
			
		||||
	pxTopOfStack--;
 | 
			
		||||
	*pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS;	/* LR */
 | 
			
		||||
	pxTopOfStack -= 5;	/* R12, R3, R2 and R1. */
 | 
			
		||||
	*pxTopOfStack = ( StackType_t ) pvParameters;	/* R0 */
 | 
			
		||||
	pxTopOfStack -= 8;	/* R11, R10, R9, R8, R7, R6, R5 and R4. */
 | 
			
		||||
 | 
			
		||||
	return pxTopOfStack;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
static void prvTaskExitError( void )
 | 
			
		||||
{
 | 
			
		||||
	/* A function that implements a task must not exit or attempt to return to
 | 
			
		||||
	its caller as there is nothing to return to.  If a task wants to exit it
 | 
			
		||||
	should instead call vTaskDelete( NULL ).
 | 
			
		||||
 | 
			
		||||
	Artificially force an assert() to be triggered if configASSERT() is
 | 
			
		||||
	defined, then stop here so application writers can catch the error. */
 | 
			
		||||
	configASSERT( uxCriticalNesting == ~0UL );
 | 
			
		||||
	portDISABLE_INTERRUPTS();
 | 
			
		||||
	for( ;; );
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
void vPortSVCHandler( void )
 | 
			
		||||
{
 | 
			
		||||
	__asm volatile (
 | 
			
		||||
					"	ldr	r3, pxCurrentTCBConst2		\n" /* Restore the context. */
 | 
			
		||||
					"	ldr r1, [r3]					\n" /* Use pxCurrentTCBConst to get the pxCurrentTCB address. */
 | 
			
		||||
					"	ldr r0, [r1]					\n" /* The first item in pxCurrentTCB is the task top of stack. */
 | 
			
		||||
					"	ldmia r0!, {r4-r11}				\n" /* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */
 | 
			
		||||
					"	msr psp, r0						\n" /* Restore the task stack pointer. */
 | 
			
		||||
					"	isb								\n"
 | 
			
		||||
					"	mov r0, #0 						\n"
 | 
			
		||||
					"	msr	basepri, r0					\n"
 | 
			
		||||
					"	orr r14, #0xd					\n"
 | 
			
		||||
					"	bx r14							\n"
 | 
			
		||||
					"									\n"
 | 
			
		||||
					"	.align 2						\n"
 | 
			
		||||
					"pxCurrentTCBConst2: .word pxCurrentTCB				\n"
 | 
			
		||||
				);
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
static void prvPortStartFirstTask( void )
 | 
			
		||||
{
 | 
			
		||||
	__asm volatile(
 | 
			
		||||
					" ldr r0, =0xE000ED08 	\n" /* Use the NVIC offset register to locate the stack. */
 | 
			
		||||
					" ldr r0, [r0] 			\n"
 | 
			
		||||
					" ldr r0, [r0] 			\n"
 | 
			
		||||
					" msr msp, r0			\n" /* Set the msp back to the start of the stack. */
 | 
			
		||||
					" cpsie i				\n" /* Globally enable interrupts. */
 | 
			
		||||
					" cpsie f				\n"
 | 
			
		||||
					" dsb					\n"
 | 
			
		||||
					" isb					\n"
 | 
			
		||||
					" svc 0					\n" /* System call to start first task. */
 | 
			
		||||
					" nop					\n"
 | 
			
		||||
				);
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * See header file for description.
 | 
			
		||||
 */
 | 
			
		||||
BaseType_t xPortStartScheduler( void )
 | 
			
		||||
{
 | 
			
		||||
	/* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0.
 | 
			
		||||
	See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */
 | 
			
		||||
	configASSERT( configMAX_SYSCALL_INTERRUPT_PRIORITY );
 | 
			
		||||
 | 
			
		||||
	#if( configASSERT_DEFINED == 1 )
 | 
			
		||||
	{
 | 
			
		||||
		volatile uint32_t ulOriginalPriority;
 | 
			
		||||
		volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
 | 
			
		||||
		volatile uint8_t ucMaxPriorityValue;
 | 
			
		||||
 | 
			
		||||
		/* Determine the maximum priority from which ISR safe FreeRTOS API
 | 
			
		||||
		functions can be called.  ISR safe functions are those that end in
 | 
			
		||||
		"FromISR".  FreeRTOS maintains separate thread and ISR API functions to
 | 
			
		||||
		ensure interrupt entry is as fast and simple as possible.
 | 
			
		||||
 | 
			
		||||
		Save the interrupt priority value that is about to be clobbered. */
 | 
			
		||||
		ulOriginalPriority = *pucFirstUserPriorityRegister;
 | 
			
		||||
 | 
			
		||||
		/* Determine the number of priority bits available.  First write to all
 | 
			
		||||
		possible bits. */
 | 
			
		||||
		*pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
 | 
			
		||||
 | 
			
		||||
		/* Read the value back to see how many bits stuck. */
 | 
			
		||||
		ucMaxPriorityValue = *pucFirstUserPriorityRegister;
 | 
			
		||||
 | 
			
		||||
		/* Use the same mask on the maximum system call priority. */
 | 
			
		||||
		ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue;
 | 
			
		||||
 | 
			
		||||
		/* Calculate the maximum acceptable priority group value for the number
 | 
			
		||||
		of bits read back. */
 | 
			
		||||
		ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;
 | 
			
		||||
		while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
 | 
			
		||||
		{
 | 
			
		||||
			ulMaxPRIGROUPValue--;
 | 
			
		||||
			ucMaxPriorityValue <<= ( uint8_t ) 0x01;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Shift the priority group value back to its position within the AIRCR
 | 
			
		||||
		register. */
 | 
			
		||||
		ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
 | 
			
		||||
		ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
 | 
			
		||||
 | 
			
		||||
		/* Restore the clobbered interrupt priority register to its original
 | 
			
		||||
		value. */
 | 
			
		||||
		*pucFirstUserPriorityRegister = ulOriginalPriority;
 | 
			
		||||
	}
 | 
			
		||||
	#endif /* conifgASSERT_DEFINED */
 | 
			
		||||
 | 
			
		||||
	/* Make PendSV and SysTick the lowest priority interrupts. */
 | 
			
		||||
	portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI;
 | 
			
		||||
	portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI;
 | 
			
		||||
 | 
			
		||||
	/* Start the timer that generates the tick ISR.  Interrupts are disabled
 | 
			
		||||
	here already. */
 | 
			
		||||
	vPortSetupTimerInterrupt();
 | 
			
		||||
 | 
			
		||||
	/* Initialise the critical nesting count ready for the first task. */
 | 
			
		||||
	uxCriticalNesting = 0;
 | 
			
		||||
 | 
			
		||||
	/* Start the first task. */
 | 
			
		||||
	prvPortStartFirstTask();
 | 
			
		||||
 | 
			
		||||
	/* Should never get here as the tasks will now be executing!  Call the task
 | 
			
		||||
	exit error function to prevent compiler warnings about a static function
 | 
			
		||||
	not being called in the case that the application writer overrides this
 | 
			
		||||
	functionality by defining configTASK_RETURN_ADDRESS. */
 | 
			
		||||
	prvTaskExitError();
 | 
			
		||||
 | 
			
		||||
	/* Should not get here! */
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
void vPortEndScheduler( void )
 | 
			
		||||
{
 | 
			
		||||
	/* Not implemented in ports where there is nothing to return to.
 | 
			
		||||
	Artificially force an assert. */
 | 
			
		||||
	configASSERT( uxCriticalNesting == 1000UL );
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
void vPortYield( void )
 | 
			
		||||
{
 | 
			
		||||
	/* Set a PendSV to request a context switch. */
 | 
			
		||||
	portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
 | 
			
		||||
 | 
			
		||||
	/* Barriers are normally not required but do ensure the code is completely
 | 
			
		||||
	within the specified behaviour for the architecture. */
 | 
			
		||||
	__asm volatile( "dsb" );
 | 
			
		||||
	__asm volatile( "isb" );
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
void vPortEnterCritical( void )
 | 
			
		||||
{
 | 
			
		||||
	portDISABLE_INTERRUPTS();
 | 
			
		||||
	uxCriticalNesting++;
 | 
			
		||||
	__asm volatile( "dsb" );
 | 
			
		||||
	__asm volatile( "isb" );
 | 
			
		||||
	
 | 
			
		||||
	/* This is not the interrupt safe version of the enter critical function so
 | 
			
		||||
	assert() if it is being called from an interrupt context.  Only API 
 | 
			
		||||
	functions that end in "FromISR" can be used in an interrupt.  Only assert if
 | 
			
		||||
	the critical nesting count is 1 to protect against recursive calls if the
 | 
			
		||||
	assert function also uses a critical section. */
 | 
			
		||||
	if( uxCriticalNesting == 1 )
 | 
			
		||||
	{
 | 
			
		||||
		configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 );
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
void vPortExitCritical( void )
 | 
			
		||||
{
 | 
			
		||||
	configASSERT( uxCriticalNesting );
 | 
			
		||||
	uxCriticalNesting--;
 | 
			
		||||
	if( uxCriticalNesting == 0 )
 | 
			
		||||
	{
 | 
			
		||||
		portENABLE_INTERRUPTS();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
__attribute__(( naked )) uint32_t ulPortSetInterruptMask( void )
 | 
			
		||||
{
 | 
			
		||||
	__asm volatile														\
 | 
			
		||||
	(																	\
 | 
			
		||||
		"	mrs r0, basepri											\n" \
 | 
			
		||||
		"	mov r1, %0												\n"	\
 | 
			
		||||
		"	msr basepri, r1											\n" \
 | 
			
		||||
		"	bx lr													\n" \
 | 
			
		||||
		:: "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "r0", "r1"	\
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
	/* This return will not be reached but is necessary to prevent compiler
 | 
			
		||||
	warnings. */
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
__attribute__(( naked )) void vPortClearInterruptMask( uint32_t ulNewMaskValue )
 | 
			
		||||
{
 | 
			
		||||
	__asm volatile													\
 | 
			
		||||
	(																\
 | 
			
		||||
		"	msr basepri, r0										\n"	\
 | 
			
		||||
		"	bx lr												\n" \
 | 
			
		||||
		:::"r0"														\
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
	/* Just to avoid compiler warnings. */
 | 
			
		||||
	( void ) ulNewMaskValue;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
void xPortPendSVHandler( void )
 | 
			
		||||
{
 | 
			
		||||
	/* This is a naked function. */
 | 
			
		||||
 | 
			
		||||
	__asm volatile
 | 
			
		||||
	(
 | 
			
		||||
	"	mrs r0, psp							\n"
 | 
			
		||||
	"	isb									\n"
 | 
			
		||||
	"										\n"
 | 
			
		||||
	"	ldr	r3, pxCurrentTCBConst			\n" /* Get the location of the current TCB. */
 | 
			
		||||
	"	ldr	r2, [r3]						\n"
 | 
			
		||||
	"										\n"
 | 
			
		||||
	"	stmdb r0!, {r4-r11}					\n" /* Save the remaining registers. */
 | 
			
		||||
	"	str r0, [r2]						\n" /* Save the new top of stack into the first member of the TCB. */
 | 
			
		||||
	"										\n"
 | 
			
		||||
	"	stmdb sp!, {r3, r14}				\n"
 | 
			
		||||
	"	mov r0, %0							\n"
 | 
			
		||||
	"	msr basepri, r0						\n"
 | 
			
		||||
	"	bl vTaskSwitchContext				\n"
 | 
			
		||||
	"	mov r0, #0							\n"
 | 
			
		||||
	"	msr basepri, r0						\n"
 | 
			
		||||
	"	ldmia sp!, {r3, r14}				\n"
 | 
			
		||||
	"										\n"	/* Restore the context, including the critical nesting count. */
 | 
			
		||||
	"	ldr r1, [r3]						\n"
 | 
			
		||||
	"	ldr r0, [r1]						\n" /* The first item in pxCurrentTCB is the task top of stack. */
 | 
			
		||||
	"	ldmia r0!, {r4-r11}					\n" /* Pop the registers. */
 | 
			
		||||
	"	msr psp, r0							\n"
 | 
			
		||||
	"	isb									\n"
 | 
			
		||||
	"	bx r14								\n"
 | 
			
		||||
	"										\n"
 | 
			
		||||
	"	.align 2							\n"
 | 
			
		||||
	"pxCurrentTCBConst: .word pxCurrentTCB	\n"
 | 
			
		||||
	::"i"(configMAX_SYSCALL_INTERRUPT_PRIORITY)
 | 
			
		||||
	);
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
void xPortSysTickHandler( void )
 | 
			
		||||
{
 | 
			
		||||
	/* The SysTick runs at the lowest interrupt priority, so when this interrupt
 | 
			
		||||
	executes all interrupts must be unmasked.  There is therefore no need to
 | 
			
		||||
	save and then restore the interrupt mask value as its value is already
 | 
			
		||||
	known. */
 | 
			
		||||
	( void ) portSET_INTERRUPT_MASK_FROM_ISR();
 | 
			
		||||
	{
 | 
			
		||||
		/* Increment the RTOS tick. */
 | 
			
		||||
		if( xTaskIncrementTick() != pdFALSE )
 | 
			
		||||
		{
 | 
			
		||||
			/* A context switch is required.  Context switching is performed in
 | 
			
		||||
			the PendSV interrupt.  Pend the PendSV interrupt. */
 | 
			
		||||
			portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 );
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
#if configUSE_TICKLESS_IDLE == 1
 | 
			
		||||
 | 
			
		||||
	__attribute__((weak)) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime )
 | 
			
		||||
	{
 | 
			
		||||
	uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickCTRL;
 | 
			
		||||
	TickType_t xModifiableIdleTime;
 | 
			
		||||
 | 
			
		||||
		/* Make sure the SysTick reload value does not overflow the counter. */
 | 
			
		||||
		if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks )
 | 
			
		||||
		{
 | 
			
		||||
			xExpectedIdleTime = xMaximumPossibleSuppressedTicks;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Stop the SysTick momentarily.  The time the SysTick is stopped for
 | 
			
		||||
		is accounted for as best it can be, but using the tickless mode will
 | 
			
		||||
		inevitably result in some tiny drift of the time maintained by the
 | 
			
		||||
		kernel with respect to calendar time. */
 | 
			
		||||
		portNVIC_SYSTICK_CTRL_REG &= ~portNVIC_SYSTICK_ENABLE_BIT;
 | 
			
		||||
 | 
			
		||||
		/* Calculate the reload value required to wait xExpectedIdleTime
 | 
			
		||||
		tick periods.  -1 is used because this code will execute part way
 | 
			
		||||
		through one of the tick periods. */
 | 
			
		||||
		ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) );
 | 
			
		||||
		if( ulReloadValue > ulStoppedTimerCompensation )
 | 
			
		||||
		{
 | 
			
		||||
			ulReloadValue -= ulStoppedTimerCompensation;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Enter a critical section but don't use the taskENTER_CRITICAL()
 | 
			
		||||
		method as that will mask interrupts that should exit sleep mode. */
 | 
			
		||||
		__asm volatile( "cpsid i" );
 | 
			
		||||
 | 
			
		||||
		/* If a context switch is pending or a task is waiting for the scheduler
 | 
			
		||||
		to be unsuspended then abandon the low power entry. */
 | 
			
		||||
		if( eTaskConfirmSleepModeStatus() == eAbortSleep )
 | 
			
		||||
		{
 | 
			
		||||
			/* Restart from whatever is left in the count register to complete
 | 
			
		||||
			this tick period. */
 | 
			
		||||
			portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG;
 | 
			
		||||
 | 
			
		||||
			/* Restart SysTick. */
 | 
			
		||||
			portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
 | 
			
		||||
 | 
			
		||||
			/* Reset the reload register to the value required for normal tick
 | 
			
		||||
			periods. */
 | 
			
		||||
			portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
 | 
			
		||||
 | 
			
		||||
			/* Re-enable interrupts - see comments above the cpsid instruction()
 | 
			
		||||
			above. */
 | 
			
		||||
			__asm volatile( "cpsie i" );
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			/* Set the new reload value. */
 | 
			
		||||
			portNVIC_SYSTICK_LOAD_REG = ulReloadValue;
 | 
			
		||||
 | 
			
		||||
			/* Clear the SysTick count flag and set the count value back to
 | 
			
		||||
			zero. */
 | 
			
		||||
			portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
 | 
			
		||||
 | 
			
		||||
			/* Restart SysTick. */
 | 
			
		||||
			portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
 | 
			
		||||
 | 
			
		||||
			/* Sleep until something happens.  configPRE_SLEEP_PROCESSING() can
 | 
			
		||||
			set its parameter to 0 to indicate that its implementation contains
 | 
			
		||||
			its own wait for interrupt or wait for event instruction, and so wfi
 | 
			
		||||
			should not be executed again.  However, the original expected idle
 | 
			
		||||
			time variable must remain unmodified, so a copy is taken. */
 | 
			
		||||
			xModifiableIdleTime = xExpectedIdleTime;
 | 
			
		||||
			configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
 | 
			
		||||
			if( xModifiableIdleTime > 0 )
 | 
			
		||||
			{
 | 
			
		||||
				__asm volatile( "dsb" );
 | 
			
		||||
				__asm volatile( "wfi" );
 | 
			
		||||
				__asm volatile( "isb" );
 | 
			
		||||
			}
 | 
			
		||||
			configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
 | 
			
		||||
 | 
			
		||||
			/* Stop SysTick.  Again, the time the SysTick is stopped for is
 | 
			
		||||
			accounted for as best it can be, but using the tickless mode will
 | 
			
		||||
			inevitably result in some tiny drift of the time maintained by the
 | 
			
		||||
			kernel with respect to calendar time. */
 | 
			
		||||
			ulSysTickCTRL = portNVIC_SYSTICK_CTRL_REG;
 | 
			
		||||
			portNVIC_SYSTICK_CTRL_REG = ( ulSysTickCTRL & ~portNVIC_SYSTICK_ENABLE_BIT );
 | 
			
		||||
 | 
			
		||||
			/* Re-enable interrupts - see comments above the cpsid instruction()
 | 
			
		||||
			above. */
 | 
			
		||||
			__asm volatile( "cpsie i" );
 | 
			
		||||
 | 
			
		||||
			if( ( ulSysTickCTRL & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )
 | 
			
		||||
			{
 | 
			
		||||
				uint32_t ulCalculatedLoadValue;
 | 
			
		||||
 | 
			
		||||
				/* The tick interrupt has already executed, and the SysTick
 | 
			
		||||
				count reloaded with ulReloadValue.  Reset the
 | 
			
		||||
				portNVIC_SYSTICK_LOAD_REG with whatever remains of this tick
 | 
			
		||||
				period. */
 | 
			
		||||
				ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG );
 | 
			
		||||
 | 
			
		||||
				/* Don't allow a tiny value, or values that have somehow
 | 
			
		||||
				underflowed because the post sleep hook did something
 | 
			
		||||
				that took too long. */
 | 
			
		||||
				if( ( ulCalculatedLoadValue < ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) )
 | 
			
		||||
				{
 | 
			
		||||
					ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL );
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue;
 | 
			
		||||
 | 
			
		||||
				/* The tick interrupt handler will already have pended the tick
 | 
			
		||||
				processing in the kernel.  As the pending tick will be
 | 
			
		||||
				processed as soon as this function exits, the tick value
 | 
			
		||||
				maintained by the tick is stepped forward by one less than the
 | 
			
		||||
				time spent waiting. */
 | 
			
		||||
				ulCompleteTickPeriods = xExpectedIdleTime - 1UL;
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				/* Something other than the tick interrupt ended the sleep.
 | 
			
		||||
				Work out how long the sleep lasted rounded to complete tick
 | 
			
		||||
				periods (not the ulReload value which accounted for part
 | 
			
		||||
				ticks). */
 | 
			
		||||
				ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - portNVIC_SYSTICK_CURRENT_VALUE_REG;
 | 
			
		||||
 | 
			
		||||
				/* How many complete tick periods passed while the processor
 | 
			
		||||
				was waiting? */
 | 
			
		||||
				ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick;
 | 
			
		||||
 | 
			
		||||
				/* The reload value is set to whatever fraction of a single tick
 | 
			
		||||
				period remains. */
 | 
			
		||||
				portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1 ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			/* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG
 | 
			
		||||
			again, then set portNVIC_SYSTICK_LOAD_REG back to its standard
 | 
			
		||||
			value.  The critical section is used to ensure the tick interrupt
 | 
			
		||||
			can only execute once in the case that the reload register is near
 | 
			
		||||
			zero. */
 | 
			
		||||
			portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
 | 
			
		||||
			portENTER_CRITICAL();
 | 
			
		||||
			{
 | 
			
		||||
				portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
 | 
			
		||||
				vTaskStepTick( ulCompleteTickPeriods );
 | 
			
		||||
				portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
 | 
			
		||||
			}
 | 
			
		||||
			portEXIT_CRITICAL();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#endif /* #if configUSE_TICKLESS_IDLE */
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Setup the systick timer to generate the tick interrupts at the required
 | 
			
		||||
 * frequency.
 | 
			
		||||
 */
 | 
			
		||||
__attribute__(( weak )) void vPortSetupTimerInterrupt( void )
 | 
			
		||||
{
 | 
			
		||||
	/* Calculate the constants required to configure the tick interrupt. */
 | 
			
		||||
	#if configUSE_TICKLESS_IDLE == 1
 | 
			
		||||
	{
 | 
			
		||||
		ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ );
 | 
			
		||||
		xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick;
 | 
			
		||||
		ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ );
 | 
			
		||||
	}
 | 
			
		||||
	#endif /* configUSE_TICKLESS_IDLE */
 | 
			
		||||
 | 
			
		||||
	/* Configure SysTick to interrupt at the requested rate. */
 | 
			
		||||
	portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;
 | 
			
		||||
	portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT );
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
#if( configASSERT_DEFINED == 1 )
 | 
			
		||||
 | 
			
		||||
	void vPortValidateInterruptPriority( void )
 | 
			
		||||
	{
 | 
			
		||||
	uint32_t ulCurrentInterrupt;
 | 
			
		||||
	uint8_t ucCurrentPriority;
 | 
			
		||||
 | 
			
		||||
		/* Obtain the number of the currently executing interrupt. */
 | 
			
		||||
		__asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) );
 | 
			
		||||
 | 
			
		||||
		/* Is the interrupt number a user defined interrupt? */
 | 
			
		||||
		if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER )
 | 
			
		||||
		{
 | 
			
		||||
			/* Look up the interrupt's priority. */
 | 
			
		||||
			ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ];
 | 
			
		||||
 | 
			
		||||
			/* The following assertion will fail if a service routine (ISR) for
 | 
			
		||||
			an interrupt that has been assigned a priority above
 | 
			
		||||
			configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API
 | 
			
		||||
			function.  ISR safe FreeRTOS API functions must *only* be called
 | 
			
		||||
			from interrupts that have been assigned a priority at or below
 | 
			
		||||
			configMAX_SYSCALL_INTERRUPT_PRIORITY.
 | 
			
		||||
 | 
			
		||||
			Numerically low interrupt priority numbers represent logically high
 | 
			
		||||
			interrupt priorities, therefore the priority of the interrupt must
 | 
			
		||||
			be set to a value equal to or numerically *higher* than
 | 
			
		||||
			configMAX_SYSCALL_INTERRUPT_PRIORITY.
 | 
			
		||||
 | 
			
		||||
			Interrupts that	use the FreeRTOS API must not be left at their
 | 
			
		||||
			default priority of	zero as that is the highest possible priority,
 | 
			
		||||
			which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY,
 | 
			
		||||
			and	therefore also guaranteed to be invalid.
 | 
			
		||||
 | 
			
		||||
			FreeRTOS maintains separate thread and ISR API functions to ensure
 | 
			
		||||
			interrupt entry is as fast and simple as possible.
 | 
			
		||||
 | 
			
		||||
			The following links provide detailed information:
 | 
			
		||||
			http://www.freertos.org/RTOS-Cortex-M3-M4.html
 | 
			
		||||
			http://www.freertos.org/FAQHelp.html */
 | 
			
		||||
			configASSERT( ucCurrentPriority >= ucMaxSysCallPriority );
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Priority grouping:  The interrupt controller (NVIC) allows the bits
 | 
			
		||||
		that define each interrupt's priority to be split between bits that
 | 
			
		||||
		define the interrupt's pre-emption priority bits and bits that define
 | 
			
		||||
		the interrupt's sub-priority.  For simplicity all bits must be defined
 | 
			
		||||
		to be pre-emption priority bits.  The following assertion will fail if
 | 
			
		||||
		this is not the case (if some bits represent a sub-priority).
 | 
			
		||||
 | 
			
		||||
		If the application only uses CMSIS libraries for interrupt
 | 
			
		||||
		configuration then the correct setting can be achieved on all Cortex-M
 | 
			
		||||
		devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the
 | 
			
		||||
		scheduler.  Note however that some vendor specific peripheral libraries
 | 
			
		||||
		assume a non-zero priority group setting, in which cases using a value
 | 
			
		||||
		of zero will result in unpredicable behaviour. */
 | 
			
		||||
		configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#endif /* configASSERT_DEFINED */
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
void vApplicationIdleHook( void )
 | 
			
		||||
{
 | 
			
		||||
	/* Use the idle task to place the CPU into a low power mode.  Greater power
 | 
			
		||||
	saving could be achieved by not including any demo tasks that never block. */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#include "diag.h"
 | 
			
		||||
void vApplicationStackOverflowHook( xTaskHandle pxTask, signed char *pcTaskName )
 | 
			
		||||
{
 | 
			
		||||
	/* This function will be called if a task overflows its stack, if
 | 
			
		||||
	configCHECK_FOR_STACK_OVERFLOW != 0.  It might be that the function
 | 
			
		||||
	parameters have been corrupted, depending on the severity of the stack
 | 
			
		||||
	overflow.  When this is the case pxCurrentTCB can be inspected in the
 | 
			
		||||
	debugger to find the offending task. */
 | 
			
		||||
	DiagPrintf("\n\r[%s] STACK OVERFLOW - TaskName(%s)\n\r", __FUNCTION__, pcTaskName);
 | 
			
		||||
	for( ;; );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,195 @@
 | 
			
		|||
/*
 | 
			
		||||
    FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd.
 | 
			
		||||
    All rights reserved
 | 
			
		||||
 | 
			
		||||
    VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
 | 
			
		||||
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    FreeRTOS provides completely free yet professionally developed,    *
 | 
			
		||||
     *    robust, strictly quality controlled, supported, and cross          *
 | 
			
		||||
     *    platform software that has become a de facto standard.             *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    Help yourself get started quickly and support the FreeRTOS         *
 | 
			
		||||
     *    project by purchasing a FreeRTOS tutorial book, reference          *
 | 
			
		||||
     *    manual, or both from: http://www.FreeRTOS.org/Documentation        *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    Thank you!                                                         *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
 | 
			
		||||
    This file is part of the FreeRTOS distribution.
 | 
			
		||||
 | 
			
		||||
    FreeRTOS is free software; you can redistribute it and/or modify it under
 | 
			
		||||
    the terms of the GNU General Public License (version 2) as published by the
 | 
			
		||||
    Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
 | 
			
		||||
 | 
			
		||||
    >>!   NOTE: The modification to the GPL is included to allow you to     !<<
 | 
			
		||||
    >>!   distribute a combined work that includes FreeRTOS without being   !<<
 | 
			
		||||
    >>!   obliged to provide the source code for proprietary components     !<<
 | 
			
		||||
    >>!   outside of the FreeRTOS kernel.                                   !<<
 | 
			
		||||
 | 
			
		||||
    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
 | 
			
		||||
    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
    FOR A PARTICULAR PURPOSE.  Full license text is available from the following
 | 
			
		||||
    link: http://www.freertos.org/a00114.html
 | 
			
		||||
 | 
			
		||||
    1 tab == 4 spaces!
 | 
			
		||||
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    Having a problem?  Start by reading the FAQ "My application does   *
 | 
			
		||||
     *    not run, what could be wrong?"                                     *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    http://www.FreeRTOS.org/FAQHelp.html                               *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
 | 
			
		||||
    http://www.FreeRTOS.org - Documentation, books, training, latest versions,
 | 
			
		||||
    license and Real Time Engineers Ltd. contact details.
 | 
			
		||||
 | 
			
		||||
    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
 | 
			
		||||
    including FreeRTOS+Trace - an indispensable productivity tool, a DOS
 | 
			
		||||
    compatible FAT file system, and our tiny thread aware UDP/IP stack.
 | 
			
		||||
 | 
			
		||||
    http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
 | 
			
		||||
    Integrity Systems to sell under the OpenRTOS brand.  Low cost OpenRTOS
 | 
			
		||||
    licenses offer ticketed support, indemnification and middleware.
 | 
			
		||||
 | 
			
		||||
    http://www.SafeRTOS.com - High Integrity Systems also provide a safety
 | 
			
		||||
    engineered and independently SIL3 certified version for use in safety and
 | 
			
		||||
    mission critical applications that require provable dependability.
 | 
			
		||||
 | 
			
		||||
    1 tab == 4 spaces!
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef PORTMACRO_H
 | 
			
		||||
#define PORTMACRO_H
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------
 | 
			
		||||
 * Port specific definitions.
 | 
			
		||||
 *
 | 
			
		||||
 * The settings in this file configure FreeRTOS correctly for the
 | 
			
		||||
 * given hardware and compiler.
 | 
			
		||||
 *
 | 
			
		||||
 * These settings should not be altered.
 | 
			
		||||
 *-----------------------------------------------------------
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* Type definitions. */
 | 
			
		||||
#define portCHAR		char
 | 
			
		||||
#define portFLOAT		float
 | 
			
		||||
#define portDOUBLE		double
 | 
			
		||||
#define portLONG		long
 | 
			
		||||
#define portSHORT		short
 | 
			
		||||
#define portSTACK_TYPE	uint32_t
 | 
			
		||||
#define portBASE_TYPE	long
 | 
			
		||||
 | 
			
		||||
typedef portSTACK_TYPE StackType_t;
 | 
			
		||||
typedef long BaseType_t;
 | 
			
		||||
typedef unsigned long UBaseType_t;
 | 
			
		||||
 | 
			
		||||
#if( configUSE_16_BIT_TICKS == 1 )
 | 
			
		||||
	typedef uint16_t TickType_t;
 | 
			
		||||
	#define portMAX_DELAY ( TickType_t ) 0xffff
 | 
			
		||||
#else
 | 
			
		||||
	typedef uint32_t TickType_t;
 | 
			
		||||
	#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
 | 
			
		||||
#endif
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/* Architecture specifics. */
 | 
			
		||||
#define portSTACK_GROWTH			( -1 )
 | 
			
		||||
#define portTICK_PERIOD_MS			( ( TickType_t ) 1000 / configTICK_RATE_HZ )
 | 
			
		||||
#define portBYTE_ALIGNMENT			8
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Scheduler utilities. */
 | 
			
		||||
extern void vPortYield( void );
 | 
			
		||||
#define portNVIC_INT_CTRL_REG		( * ( ( volatile uint32_t * ) 0xe000ed04 ) )
 | 
			
		||||
#define portNVIC_PENDSVSET_BIT		( 1UL << 28UL )
 | 
			
		||||
#define portYIELD()					vPortYield()
 | 
			
		||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT
 | 
			
		||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/* Critical section management. */
 | 
			
		||||
extern void vPortEnterCritical( void );
 | 
			
		||||
extern void vPortExitCritical( void );
 | 
			
		||||
extern uint32_t ulPortSetInterruptMask( void );
 | 
			
		||||
extern void vPortClearInterruptMask( uint32_t ulNewMaskValue );
 | 
			
		||||
#define portSET_INTERRUPT_MASK_FROM_ISR()		ulPortSetInterruptMask()
 | 
			
		||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x)	vPortClearInterruptMask(x)
 | 
			
		||||
#define portDISABLE_INTERRUPTS()				ulPortSetInterruptMask()
 | 
			
		||||
#define portENABLE_INTERRUPTS()					vPortClearInterruptMask(0)
 | 
			
		||||
#define portENTER_CRITICAL()					vPortEnterCritical()
 | 
			
		||||
#define portEXIT_CRITICAL()						vPortExitCritical()
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/* Task function macros as described on the FreeRTOS.org WEB site.  These are
 | 
			
		||||
not necessary for to use this port.  They are defined so the common demo files
 | 
			
		||||
(which build with all the ports) will build. */
 | 
			
		||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
 | 
			
		||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/* Tickless idle/low power functionality. */
 | 
			
		||||
#ifndef portSUPPRESS_TICKS_AND_SLEEP
 | 
			
		||||
	extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
 | 
			
		||||
	#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
 | 
			
		||||
#endif
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/* Architecture specific optimisations. */
 | 
			
		||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
 | 
			
		||||
	#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
 | 
			
		||||
 | 
			
		||||
	/* Generic helper function. */
 | 
			
		||||
	__attribute__( ( always_inline ) ) static inline uint8_t ucPortCountLeadingZeros( uint32_t ulBitmap )
 | 
			
		||||
	{
 | 
			
		||||
	uint8_t ucReturn;
 | 
			
		||||
 | 
			
		||||
		__asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) );
 | 
			
		||||
		return ucReturn;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Check the configuration. */
 | 
			
		||||
	#if( configMAX_PRIORITIES > 32 )
 | 
			
		||||
		#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32.  It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
 | 
			
		||||
	#endif
 | 
			
		||||
 | 
			
		||||
	/* Store/clear the ready priorities in a bit map. */
 | 
			
		||||
	#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
 | 
			
		||||
	#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
 | 
			
		||||
 | 
			
		||||
	/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
	#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31 - ucPortCountLeadingZeros( ( uxReadyPriorities ) ) )
 | 
			
		||||
 | 
			
		||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
#ifdef configASSERT
 | 
			
		||||
	void vPortValidateInterruptPriority( void );
 | 
			
		||||
	#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() 	vPortValidateInterruptPriority()
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* portNOP() is not required by this port. */
 | 
			
		||||
#define portNOP()
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif /* PORTMACRO_H */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,646 @@
 | 
			
		|||
/*
 | 
			
		||||
    FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd.
 | 
			
		||||
    All rights reserved
 | 
			
		||||
 | 
			
		||||
    VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
 | 
			
		||||
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    FreeRTOS provides completely free yet professionally developed,    *
 | 
			
		||||
     *    robust, strictly quality controlled, supported, and cross          *
 | 
			
		||||
     *    platform software that has become a de facto standard.             *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    Help yourself get started quickly and support the FreeRTOS         *
 | 
			
		||||
     *    project by purchasing a FreeRTOS tutorial book, reference          *
 | 
			
		||||
     *    manual, or both from: http://www.FreeRTOS.org/Documentation        *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    Thank you!                                                         *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
 | 
			
		||||
    This file is part of the FreeRTOS distribution.
 | 
			
		||||
 | 
			
		||||
    FreeRTOS is free software; you can redistribute it and/or modify it under
 | 
			
		||||
    the terms of the GNU General Public License (version 2) as published by the
 | 
			
		||||
    Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
 | 
			
		||||
 | 
			
		||||
    >>!   NOTE: The modification to the GPL is included to allow you to     !<<
 | 
			
		||||
    >>!   distribute a combined work that includes FreeRTOS without being   !<<
 | 
			
		||||
    >>!   obliged to provide the source code for proprietary components     !<<
 | 
			
		||||
    >>!   outside of the FreeRTOS kernel.                                   !<<
 | 
			
		||||
 | 
			
		||||
    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
 | 
			
		||||
    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
    FOR A PARTICULAR PURPOSE.  Full license text is available from the following
 | 
			
		||||
    link: http://www.freertos.org/a00114.html
 | 
			
		||||
 | 
			
		||||
    1 tab == 4 spaces!
 | 
			
		||||
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    Having a problem?  Start by reading the FAQ "My application does   *
 | 
			
		||||
     *    not run, what could be wrong?"                                     *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    http://www.FreeRTOS.org/FAQHelp.html                               *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
 | 
			
		||||
    http://www.FreeRTOS.org - Documentation, books, training, latest versions,
 | 
			
		||||
    license and Real Time Engineers Ltd. contact details.
 | 
			
		||||
 | 
			
		||||
    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
 | 
			
		||||
    including FreeRTOS+Trace - an indispensable productivity tool, a DOS
 | 
			
		||||
    compatible FAT file system, and our tiny thread aware UDP/IP stack.
 | 
			
		||||
 | 
			
		||||
    http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
 | 
			
		||||
    Integrity Systems to sell under the OpenRTOS brand.  Low cost OpenRTOS
 | 
			
		||||
    licenses offer ticketed support, indemnification and middleware.
 | 
			
		||||
 | 
			
		||||
    http://www.SafeRTOS.com - High Integrity Systems also provide a safety
 | 
			
		||||
    engineered and independently SIL3 certified version for use in safety and
 | 
			
		||||
    mission critical applications that require provable dependability.
 | 
			
		||||
 | 
			
		||||
    1 tab == 4 spaces!
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * A sample implementation of pvPortMalloc() that allows the heap to be defined
 | 
			
		||||
 * across multiple non-contigous blocks and combines (coalescences) adjacent
 | 
			
		||||
 * memory blocks as they are freed.
 | 
			
		||||
 *
 | 
			
		||||
 * See heap_1.c, heap_2.c, heap_3.c and heap_4.c for alternative
 | 
			
		||||
 * implementations, and the memory management pages of http://www.FreeRTOS.org
 | 
			
		||||
 * for more information.
 | 
			
		||||
 *
 | 
			
		||||
 * Usage notes:
 | 
			
		||||
 *
 | 
			
		||||
 * vPortDefineHeapRegions() ***must*** be called before pvPortMalloc().
 | 
			
		||||
 * pvPortMalloc() will be called if any task objects (tasks, queues, event
 | 
			
		||||
 * groups, etc.) are created, therefore vPortDefineHeapRegions() ***must*** be
 | 
			
		||||
 * called before any other objects are defined.
 | 
			
		||||
 *
 | 
			
		||||
 * vPortDefineHeapRegions() takes a single parameter.  The parameter is an array
 | 
			
		||||
 * of HeapRegion_t structures.  HeapRegion_t is defined in portable.h as
 | 
			
		||||
 *
 | 
			
		||||
 * typedef struct HeapRegion
 | 
			
		||||
 * {
 | 
			
		||||
 *	uint8_t *pucStartAddress; << Start address of a block of memory that will be part of the heap.
 | 
			
		||||
 *	size_t xSizeInBytes;	  << Size of the block of memory.
 | 
			
		||||
 * } HeapRegion_t;
 | 
			
		||||
 *
 | 
			
		||||
 * The array is terminated using a NULL zero sized region definition, and the
 | 
			
		||||
 * memory regions defined in the array ***must*** appear in address order from
 | 
			
		||||
 * low address to high address.  So the following is a valid example of how
 | 
			
		||||
 * to use the function.
 | 
			
		||||
 *
 | 
			
		||||
 * HeapRegion_t xHeapRegions[] =
 | 
			
		||||
 * {
 | 
			
		||||
 * 	{ ( uint8_t * ) 0x80000000UL, 0x10000 }, << Defines a block of 0x10000 bytes starting at address 0x80000000
 | 
			
		||||
 * 	{ ( uint8_t * ) 0x90000000UL, 0xa0000 }, << Defines a block of 0xa0000 bytes starting at address of 0x90000000
 | 
			
		||||
 * 	{ NULL, 0 }                << Terminates the array.
 | 
			
		||||
 * };
 | 
			
		||||
 *
 | 
			
		||||
 * vPortDefineHeapRegions( xHeapRegions ); << Pass the array into vPortDefineHeapRegions().
 | 
			
		||||
 *
 | 
			
		||||
 * Note 0x80000000 is the lower address so appears in the array first.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
 | 
			
		||||
all the API functions to use the MPU wrappers.  That should only be done when
 | 
			
		||||
task.h is included from an application file. */
 | 
			
		||||
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
 | 
			
		||||
 | 
			
		||||
#include "FreeRTOS.h"
 | 
			
		||||
#include "task.h"
 | 
			
		||||
 | 
			
		||||
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
 | 
			
		||||
 | 
			
		||||
/* Block sizes must not get too small. */
 | 
			
		||||
#define heapMINIMUM_BLOCK_SIZE	( ( size_t ) ( uxHeapStructSize << 1 ) )
 | 
			
		||||
 | 
			
		||||
/* Assumes 8bit bytes! */
 | 
			
		||||
#define heapBITS_PER_BYTE		( ( size_t ) 8 )
 | 
			
		||||
 | 
			
		||||
/* Define the linked list structure.  This is used to link free blocks in order
 | 
			
		||||
of their memory address. */
 | 
			
		||||
typedef struct A_BLOCK_LINK
 | 
			
		||||
{
 | 
			
		||||
	struct A_BLOCK_LINK *pxNextFreeBlock;	/*<< The next free block in the list. */
 | 
			
		||||
	size_t xBlockSize;						/*<< The size of the free block. */
 | 
			
		||||
} BlockLink_t;
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Inserts a block of memory that is being freed into the correct position in
 | 
			
		||||
 * the list of free memory blocks.  The block being freed will be merged with
 | 
			
		||||
 * the block in front it and/or the block behind it if the memory blocks are
 | 
			
		||||
 * adjacent to each other.
 | 
			
		||||
 */
 | 
			
		||||
static void prvInsertBlockIntoFreeList( BlockLink_t *pxBlockToInsert );
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/* The size of the structure placed at the beginning of each allocated memory
 | 
			
		||||
block must by correctly byte aligned. */
 | 
			
		||||
static const uint32_t uxHeapStructSize	= ( ( sizeof ( BlockLink_t ) + ( portBYTE_ALIGNMENT - 1 ) ) & ~portBYTE_ALIGNMENT_MASK );
 | 
			
		||||
 | 
			
		||||
/* Create a couple of list links to mark the start and end of the list. */
 | 
			
		||||
static BlockLink_t xStart, *pxEnd = NULL;
 | 
			
		||||
 | 
			
		||||
/* Keeps track of the number of free bytes remaining, but says nothing about
 | 
			
		||||
fragmentation. */
 | 
			
		||||
static size_t xFreeBytesRemaining = 0;
 | 
			
		||||
static size_t xMinimumEverFreeBytesRemaining = 0;
 | 
			
		||||
 | 
			
		||||
/* Gets set to the top bit of an size_t type.  When this bit in the xBlockSize
 | 
			
		||||
member of an BlockLink_t structure is set then the block belongs to the
 | 
			
		||||
application.  When the bit is free the block is still part of the free heap
 | 
			
		||||
space. */
 | 
			
		||||
static size_t xBlockAllocatedBit = 0;
 | 
			
		||||
 | 
			
		||||
/* Realtek test code start */
 | 
			
		||||
//TODO: remove section when combine BD and BF
 | 
			
		||||
#if ((defined CONFIG_PLATFORM_8195A) || (defined CONFIG_PLATFORM_8711B))
 | 
			
		||||
#include "section_config.h"
 | 
			
		||||
SRAM_BF_DATA_SECTION
 | 
			
		||||
#endif
 | 
			
		||||
static unsigned char ucHeap[ configTOTAL_HEAP_SIZE ];
 | 
			
		||||
 | 
			
		||||
#if (defined CONFIG_PLATFORM_8195A)
 | 
			
		||||
HeapRegion_t xHeapRegions[] =
 | 
			
		||||
{
 | 
			
		||||
	{ (uint8_t*)0x10002300, 0x3D00 }, 	// Image1 recycle heap
 | 
			
		||||
	{ ucHeap, sizeof(ucHeap) },	        // Defines a block from ucHeap
 | 
			
		||||
#if 0
 | 
			
		||||
	{ (uint8_t*)0x301b5000, 300*1024 },	// SDRAM heap
 | 
			
		||||
#endif        
 | 
			
		||||
	{ NULL, 0 }                             // Terminates the array.
 | 
			
		||||
};
 | 
			
		||||
#elif (defined CONFIG_PLATFORM_8711B)
 | 
			
		||||
HeapRegion_t xHeapRegions[] =
 | 
			
		||||
{
 | 
			
		||||
	{ ucHeap, sizeof(ucHeap) }, 	// Defines a block from ucHeap
 | 
			
		||||
	{ NULL, 0 }                // Terminates the array.
 | 
			
		||||
};
 | 
			
		||||
#else
 | 
			
		||||
#error NOT SUPPORT CHIP
 | 
			
		||||
#endif
 | 
			
		||||
/* Realtek test code end */
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
#if 1
 | 
			
		||||
/*
 | 
			
		||||
	Dump xBlock list
 | 
			
		||||
*/
 | 
			
		||||
void dump_mem_block_list()
 | 
			
		||||
{
 | 
			
		||||
	BlockLink_t *pxBlock = &xStart;
 | 
			
		||||
	int count = 0;
 | 
			
		||||
 | 
			
		||||
	printf("\n===============================>Memory List:\n");
 | 
			
		||||
	while(pxBlock->pxNextFreeBlock != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		printf("[%d]=0x%p, %d\n", count++, pxBlock, pxBlock->xBlockSize);
 | 
			
		||||
		pxBlock = pxBlock->pxNextFreeBlock;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void *pvPortMalloc( size_t xWantedSize )
 | 
			
		||||
{
 | 
			
		||||
BlockLink_t *pxBlock, *pxPreviousBlock, *pxNewBlockLink;
 | 
			
		||||
void *pvReturn = NULL;
 | 
			
		||||
 | 
			
		||||
	/* Realtek test code start */
 | 
			
		||||
	if(pxEnd == NULL)
 | 
			
		||||
	{
 | 
			
		||||
		vPortDefineHeapRegions( xHeapRegions );
 | 
			
		||||
	}
 | 
			
		||||
	/* Realtek test code end */
 | 
			
		||||
 | 
			
		||||
	/* The heap must be initialised before the first call to
 | 
			
		||||
	prvPortMalloc(). */
 | 
			
		||||
	configASSERT( pxEnd );
 | 
			
		||||
 | 
			
		||||
	vTaskSuspendAll();
 | 
			
		||||
	{
 | 
			
		||||
		/* Check the requested block size is not so large that the top bit is
 | 
			
		||||
		set.  The top bit of the block size member of the BlockLink_t structure
 | 
			
		||||
		is used to determine who owns the block - the application or the
 | 
			
		||||
		kernel, so it must be free. */
 | 
			
		||||
		if( ( xWantedSize & xBlockAllocatedBit ) == 0 )
 | 
			
		||||
		{
 | 
			
		||||
			/* The wanted size is increased so it can contain a BlockLink_t
 | 
			
		||||
			structure in addition to the requested amount of bytes. */
 | 
			
		||||
			if( xWantedSize > 0 )
 | 
			
		||||
			{
 | 
			
		||||
				xWantedSize += uxHeapStructSize;
 | 
			
		||||
 | 
			
		||||
				/* Ensure that blocks are always aligned to the required number
 | 
			
		||||
				of bytes. */
 | 
			
		||||
				if( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) != 0x00 )
 | 
			
		||||
				{
 | 
			
		||||
					/* Byte alignment required. */
 | 
			
		||||
					xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) );
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
				{
 | 
			
		||||
					mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) )
 | 
			
		||||
			{
 | 
			
		||||
				/* Traverse the list from the start	(lowest address) block until
 | 
			
		||||
				one	of adequate size is found. */
 | 
			
		||||
				pxPreviousBlock = &xStart;
 | 
			
		||||
				pxBlock = xStart.pxNextFreeBlock;
 | 
			
		||||
				while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) )
 | 
			
		||||
				{
 | 
			
		||||
					pxPreviousBlock = pxBlock;
 | 
			
		||||
					pxBlock = pxBlock->pxNextFreeBlock;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				/* If the end marker was reached then a block of adequate size
 | 
			
		||||
				was	not found. */
 | 
			
		||||
				if( pxBlock != pxEnd )
 | 
			
		||||
				{
 | 
			
		||||
					/* Return the memory space pointed to - jumping over the
 | 
			
		||||
					BlockLink_t structure at its start. */
 | 
			
		||||
					pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + uxHeapStructSize );
 | 
			
		||||
 | 
			
		||||
					/* This block is being returned for use so must be taken out
 | 
			
		||||
					of the list of free blocks. */
 | 
			
		||||
					pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock;
 | 
			
		||||
 | 
			
		||||
					/* If the block is larger than required it can be split into
 | 
			
		||||
					two. */
 | 
			
		||||
					if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE )
 | 
			
		||||
					{
 | 
			
		||||
						/* This block is to be split into two.  Create a new
 | 
			
		||||
						block following the number of bytes requested. The void
 | 
			
		||||
						cast is used to prevent byte alignment warnings from the
 | 
			
		||||
						compiler. */
 | 
			
		||||
						pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize );
 | 
			
		||||
 | 
			
		||||
						/* Calculate the sizes of two blocks split from the
 | 
			
		||||
						single block. */
 | 
			
		||||
						pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize;
 | 
			
		||||
						pxBlock->xBlockSize = xWantedSize;
 | 
			
		||||
 | 
			
		||||
						/* Insert the new block into the list of free blocks. */
 | 
			
		||||
						prvInsertBlockIntoFreeList( ( pxNewBlockLink ) );
 | 
			
		||||
					}
 | 
			
		||||
					else
 | 
			
		||||
					{
 | 
			
		||||
						mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					xFreeBytesRemaining -= pxBlock->xBlockSize;
 | 
			
		||||
 | 
			
		||||
					if( xFreeBytesRemaining < xMinimumEverFreeBytesRemaining )
 | 
			
		||||
					{
 | 
			
		||||
						xMinimumEverFreeBytesRemaining = xFreeBytesRemaining;
 | 
			
		||||
					}
 | 
			
		||||
					else
 | 
			
		||||
					{
 | 
			
		||||
						mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					/* The block is being returned - it is allocated and owned
 | 
			
		||||
					by the application and has no "next" block. */
 | 
			
		||||
					pxBlock->xBlockSize |= xBlockAllocatedBit;
 | 
			
		||||
					pxBlock->pxNextFreeBlock = NULL;
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
				{
 | 
			
		||||
					mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		traceMALLOC( pvReturn, xWantedSize );
 | 
			
		||||
	}
 | 
			
		||||
	( void ) xTaskResumeAll();
 | 
			
		||||
 | 
			
		||||
	#if( configUSE_MALLOC_FAILED_HOOK == 1 )
 | 
			
		||||
	{
 | 
			
		||||
		if( pvReturn == NULL )
 | 
			
		||||
		{
 | 
			
		||||
			extern void vApplicationMallocFailedHook( void );
 | 
			
		||||
			vApplicationMallocFailedHook();
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	#endif
 | 
			
		||||
 | 
			
		||||
	return pvReturn;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
void __vPortFree( void *pv )
 | 
			
		||||
{
 | 
			
		||||
uint8_t *puc = ( uint8_t * ) pv;
 | 
			
		||||
BlockLink_t *pxLink;
 | 
			
		||||
 | 
			
		||||
	if( pv != NULL )
 | 
			
		||||
	{
 | 
			
		||||
		/* The memory being freed will have an BlockLink_t structure immediately
 | 
			
		||||
		before it. */
 | 
			
		||||
		puc -= uxHeapStructSize;
 | 
			
		||||
 | 
			
		||||
		/* This casting is to keep the compiler from issuing warnings. */
 | 
			
		||||
		pxLink = ( void * ) puc;
 | 
			
		||||
 | 
			
		||||
		/* Check the block is actually allocated. */
 | 
			
		||||
		configASSERT( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 );
 | 
			
		||||
		configASSERT( pxLink->pxNextFreeBlock == NULL );
 | 
			
		||||
 | 
			
		||||
		if( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 )
 | 
			
		||||
		{
 | 
			
		||||
			if( pxLink->pxNextFreeBlock == NULL )
 | 
			
		||||
			{
 | 
			
		||||
				/* The block is being returned to the heap - it is no longer
 | 
			
		||||
				allocated. */
 | 
			
		||||
				pxLink->xBlockSize &= ~xBlockAllocatedBit;
 | 
			
		||||
 | 
			
		||||
				vTaskSuspendAll();
 | 
			
		||||
				{
 | 
			
		||||
					/* Add this block to the list of free blocks. */
 | 
			
		||||
					xFreeBytesRemaining += pxLink->xBlockSize;
 | 
			
		||||
					traceFREE( pv, pxLink->xBlockSize );
 | 
			
		||||
					prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) );
 | 
			
		||||
				}
 | 
			
		||||
				( void ) xTaskResumeAll();
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
/* Add by Alfa 2015/02/04 -----------------------------------*/
 | 
			
		||||
static void (*ext_free)( void *p ) = NULL;
 | 
			
		||||
static uint32_t ext_upper = 0;
 | 
			
		||||
static uint32_t ext_lower = 0;
 | 
			
		||||
void vPortSetExtFree( void (*free)( void *p ), uint32_t upper, uint32_t lower )
 | 
			
		||||
{
 | 
			
		||||
	ext_free = free;
 | 
			
		||||
	ext_upper = upper;
 | 
			
		||||
	ext_lower = lower;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void vPortFree( void *pv )
 | 
			
		||||
{
 | 
			
		||||
	if( ((uint32_t)pv >= ext_lower) && ((uint32_t)pv < ext_upper) ){
 | 
			
		||||
		// use external free function
 | 
			
		||||
		if( ext_free )	ext_free( pv );
 | 
			
		||||
	}else
 | 
			
		||||
		__vPortFree( pv );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
size_t xPortGetFreeHeapSize( void )
 | 
			
		||||
{
 | 
			
		||||
	return xFreeBytesRemaining;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
size_t xPortGetMinimumEverFreeHeapSize( void )
 | 
			
		||||
{
 | 
			
		||||
	return xMinimumEverFreeBytesRemaining;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
static void prvInsertBlockIntoFreeList( BlockLink_t *pxBlockToInsert )
 | 
			
		||||
{
 | 
			
		||||
BlockLink_t *pxIterator;
 | 
			
		||||
uint8_t *puc;
 | 
			
		||||
 | 
			
		||||
	/* Iterate through the list until a block is found that has a higher address
 | 
			
		||||
	than the block being inserted. */
 | 
			
		||||
	for( pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock )
 | 
			
		||||
	{
 | 
			
		||||
		/* Nothing to do here, just iterate to the right position. */
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Do the block being inserted, and the block it is being inserted after
 | 
			
		||||
	make a contiguous block of memory? */
 | 
			
		||||
	puc = ( uint8_t * ) pxIterator;
 | 
			
		||||
	if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert )
 | 
			
		||||
	{
 | 
			
		||||
		pxIterator->xBlockSize += pxBlockToInsert->xBlockSize;
 | 
			
		||||
		pxBlockToInsert = pxIterator;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Do the block being inserted, and the block it is being inserted before
 | 
			
		||||
	make a contiguous block of memory? */
 | 
			
		||||
	puc = ( uint8_t * ) pxBlockToInsert;
 | 
			
		||||
	if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock )
 | 
			
		||||
	{
 | 
			
		||||
		if( pxIterator->pxNextFreeBlock != pxEnd )
 | 
			
		||||
		{
 | 
			
		||||
			/* Form one big block from the two blocks. */
 | 
			
		||||
			pxBlockToInsert->xBlockSize += pxIterator->pxNextFreeBlock->xBlockSize;
 | 
			
		||||
			pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock->pxNextFreeBlock;
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			pxBlockToInsert->pxNextFreeBlock = pxEnd;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* If the block being inserted plugged a gab, so was merged with the block
 | 
			
		||||
	before and the block after, then it's pxNextFreeBlock pointer will have
 | 
			
		||||
	already been set, and should not be set here as that would make it point
 | 
			
		||||
	to itself. */
 | 
			
		||||
	if( pxIterator != pxBlockToInsert )
 | 
			
		||||
	{
 | 
			
		||||
		pxIterator->pxNextFreeBlock = pxBlockToInsert;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions )
 | 
			
		||||
{
 | 
			
		||||
BlockLink_t *pxFirstFreeBlockInRegion = NULL, *pxPreviousFreeBlock;
 | 
			
		||||
uint8_t *pucAlignedHeap;
 | 
			
		||||
size_t xTotalRegionSize, xTotalHeapSize = 0;
 | 
			
		||||
BaseType_t xDefinedRegions = 0;
 | 
			
		||||
uint32_t ulAddress;
 | 
			
		||||
const HeapRegion_t *pxHeapRegion;
 | 
			
		||||
 | 
			
		||||
	/* Can only call once! */
 | 
			
		||||
	configASSERT( pxEnd == NULL );
 | 
			
		||||
 | 
			
		||||
	pxHeapRegion = &( pxHeapRegions[ xDefinedRegions ] );
 | 
			
		||||
 | 
			
		||||
	while( pxHeapRegion->xSizeInBytes > 0 )
 | 
			
		||||
	{
 | 
			
		||||
		xTotalRegionSize = pxHeapRegion->xSizeInBytes;
 | 
			
		||||
 | 
			
		||||
		/* Ensure the heap region starts on a correctly aligned boundary. */
 | 
			
		||||
		ulAddress = ( uint32_t ) pxHeapRegion->pucStartAddress;
 | 
			
		||||
		if( ( ulAddress & portBYTE_ALIGNMENT_MASK ) != 0 )
 | 
			
		||||
		{
 | 
			
		||||
			ulAddress += ( portBYTE_ALIGNMENT - 1 );
 | 
			
		||||
			ulAddress &= ~portBYTE_ALIGNMENT_MASK;
 | 
			
		||||
 | 
			
		||||
			/* Adjust the size for the bytes lost to alignment. */
 | 
			
		||||
			xTotalRegionSize -= ulAddress - ( uint32_t ) pxHeapRegion->pucStartAddress;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		pucAlignedHeap = ( uint8_t * ) ulAddress;
 | 
			
		||||
 | 
			
		||||
		/* Set xStart if it has not already been set. */
 | 
			
		||||
		if( xDefinedRegions == 0 )
 | 
			
		||||
		{
 | 
			
		||||
			/* xStart is used to hold a pointer to the first item in the list of
 | 
			
		||||
			free blocks.  The void cast is used to prevent compiler warnings. */
 | 
			
		||||
			xStart.pxNextFreeBlock = ( BlockLink_t * ) pucAlignedHeap;
 | 
			
		||||
			xStart.xBlockSize = ( size_t ) 0;
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			/* Should only get here if one region has already been added to the
 | 
			
		||||
			heap. */
 | 
			
		||||
			configASSERT( pxEnd != NULL );
 | 
			
		||||
 | 
			
		||||
			/* Check blocks are passed in with increasing start addresses. */
 | 
			
		||||
			configASSERT( ulAddress > ( uint32_t ) pxEnd );
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Remember the location of the end marker in the previous region, if
 | 
			
		||||
		any. */
 | 
			
		||||
		pxPreviousFreeBlock = pxEnd;
 | 
			
		||||
 | 
			
		||||
		/* pxEnd is used to mark the end of the list of free blocks and is
 | 
			
		||||
		inserted at the end of the region space. */
 | 
			
		||||
		ulAddress = ( ( uint32_t ) pucAlignedHeap ) + xTotalRegionSize;
 | 
			
		||||
		ulAddress -= uxHeapStructSize;
 | 
			
		||||
		ulAddress &= ~portBYTE_ALIGNMENT_MASK;
 | 
			
		||||
		pxEnd = ( BlockLink_t * ) ulAddress;
 | 
			
		||||
		pxEnd->xBlockSize = 0;
 | 
			
		||||
		pxEnd->pxNextFreeBlock = NULL;
 | 
			
		||||
 | 
			
		||||
		/* To start with there is a single free block in this region that is
 | 
			
		||||
		sized to take up the entire heap region minus the space taken by the
 | 
			
		||||
		free block structure. */
 | 
			
		||||
		pxFirstFreeBlockInRegion = ( BlockLink_t * ) pucAlignedHeap;
 | 
			
		||||
		pxFirstFreeBlockInRegion->xBlockSize = ulAddress - ( uint32_t ) pxFirstFreeBlockInRegion;
 | 
			
		||||
		pxFirstFreeBlockInRegion->pxNextFreeBlock = pxEnd;
 | 
			
		||||
 | 
			
		||||
		/* If this is not the first region that makes up the entire heap space
 | 
			
		||||
		then link the previous region to this region. */
 | 
			
		||||
		if( pxPreviousFreeBlock != NULL )
 | 
			
		||||
		{
 | 
			
		||||
			pxPreviousFreeBlock->pxNextFreeBlock = pxFirstFreeBlockInRegion;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		xTotalHeapSize += pxFirstFreeBlockInRegion->xBlockSize;
 | 
			
		||||
 | 
			
		||||
		/* Move onto the next HeapRegion_t structure. */
 | 
			
		||||
		xDefinedRegions++;
 | 
			
		||||
		pxHeapRegion = &( pxHeapRegions[ xDefinedRegions ] );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	xMinimumEverFreeBytesRemaining = xTotalHeapSize;
 | 
			
		||||
	xFreeBytesRemaining = xTotalHeapSize;
 | 
			
		||||
 | 
			
		||||
	/* Check something was actually defined before it is accessed. */
 | 
			
		||||
	configASSERT( xTotalHeapSize );
 | 
			
		||||
 | 
			
		||||
	/* Work out the position of the top bit in a size_t variable. */
 | 
			
		||||
	xBlockAllocatedBit = ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * heapBITS_PER_BYTE ) - 1 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void* pvPortReAlloc( void *pv,  size_t xWantedSize )
 | 
			
		||||
{
 | 
			
		||||
	BlockLink_t *pxLink;
 | 
			
		||||
 | 
			
		||||
	if( ((uint32_t)pv >= ext_lower) && ((uint32_t)pv < ext_upper) ){
 | 
			
		||||
		if( ext_free )  ext_free( pv );
 | 
			
		||||
		pv = NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	unsigned char *puc = ( unsigned char * ) pv;
 | 
			
		||||
 | 
			
		||||
	if( pv )
 | 
			
		||||
	{
 | 
			
		||||
		if( !xWantedSize )
 | 
			
		||||
		{
 | 
			
		||||
			vPortFree( pv );
 | 
			
		||||
			return NULL;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		void *newArea = pvPortMalloc( xWantedSize );
 | 
			
		||||
	if( newArea )
 | 
			
		||||
	{
 | 
			
		||||
			/* The memory being freed will have an xBlockLink structure immediately
 | 
			
		||||
				before it. */
 | 
			
		||||
			puc -= uxHeapStructSize;
 | 
			
		||||
 | 
			
		||||
			/* This casting is to keep the compiler from issuing warnings. */
 | 
			
		||||
			pxLink = ( void * ) puc;
 | 
			
		||||
 | 
			
		||||
			int oldSize =  (pxLink->xBlockSize & ~xBlockAllocatedBit) - uxHeapStructSize;
 | 
			
		||||
			int copySize = ( oldSize < xWantedSize ) ? oldSize : xWantedSize;
 | 
			
		||||
			memcpy( newArea, pv, copySize );
 | 
			
		||||
 | 
			
		||||
			vTaskSuspendAll();
 | 
			
		||||
			{
 | 
			
		||||
				/* Add this block to the list of free blocks. */
 | 
			
		||||
				pxLink->xBlockSize &= ~xBlockAllocatedBit;
 | 
			
		||||
				xFreeBytesRemaining += pxLink->xBlockSize;
 | 
			
		||||
				prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) );
 | 
			
		||||
			}
 | 
			
		||||
			xTaskResumeAll();
 | 
			
		||||
			return newArea;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	else if( xWantedSize )
 | 
			
		||||
		return pvPortMalloc( xWantedSize );
 | 
			
		||||
	else
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										2439
									
								
								component/os/freertos/freertos_v8.1.2/Source/queue.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										2439
									
								
								component/os/freertos/freertos_v8.1.2/Source/queue.c
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										3753
									
								
								component/os/freertos/freertos_v8.1.2/Source/tasks.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										3753
									
								
								component/os/freertos/freertos_v8.1.2/Source/tasks.c
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										936
									
								
								component/os/freertos/freertos_v8.1.2/Source/timers.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										936
									
								
								component/os/freertos/freertos_v8.1.2/Source/timers.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,936 @@
 | 
			
		|||
/*
 | 
			
		||||
    FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd.
 | 
			
		||||
    All rights reserved
 | 
			
		||||
 | 
			
		||||
    VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
 | 
			
		||||
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    FreeRTOS provides completely free yet professionally developed,    *
 | 
			
		||||
     *    robust, strictly quality controlled, supported, and cross          *
 | 
			
		||||
     *    platform software that has become a de facto standard.             *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    Help yourself get started quickly and support the FreeRTOS         *
 | 
			
		||||
     *    project by purchasing a FreeRTOS tutorial book, reference          *
 | 
			
		||||
     *    manual, or both from: http://www.FreeRTOS.org/Documentation        *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    Thank you!                                                         *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
 | 
			
		||||
    This file is part of the FreeRTOS distribution.
 | 
			
		||||
 | 
			
		||||
    FreeRTOS is free software; you can redistribute it and/or modify it under
 | 
			
		||||
    the terms of the GNU General Public License (version 2) as published by the
 | 
			
		||||
    Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
 | 
			
		||||
 | 
			
		||||
    >>!   NOTE: The modification to the GPL is included to allow you to     !<<
 | 
			
		||||
    >>!   distribute a combined work that includes FreeRTOS without being   !<<
 | 
			
		||||
    >>!   obliged to provide the source code for proprietary components     !<<
 | 
			
		||||
    >>!   outside of the FreeRTOS kernel.                                   !<<
 | 
			
		||||
 | 
			
		||||
    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
 | 
			
		||||
    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
    FOR A PARTICULAR PURPOSE.  Full license text is available from the following
 | 
			
		||||
    link: http://www.freertos.org/a00114.html
 | 
			
		||||
 | 
			
		||||
    1 tab == 4 spaces!
 | 
			
		||||
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    Having a problem?  Start by reading the FAQ "My application does   *
 | 
			
		||||
     *    not run, what could be wrong?"                                     *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
     *    http://www.FreeRTOS.org/FAQHelp.html                               *
 | 
			
		||||
     *                                                                       *
 | 
			
		||||
    ***************************************************************************
 | 
			
		||||
 | 
			
		||||
    http://www.FreeRTOS.org - Documentation, books, training, latest versions,
 | 
			
		||||
    license and Real Time Engineers Ltd. contact details.
 | 
			
		||||
 | 
			
		||||
    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
 | 
			
		||||
    including FreeRTOS+Trace - an indispensable productivity tool, a DOS
 | 
			
		||||
    compatible FAT file system, and our tiny thread aware UDP/IP stack.
 | 
			
		||||
 | 
			
		||||
    http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
 | 
			
		||||
    Integrity Systems to sell under the OpenRTOS brand.  Low cost OpenRTOS
 | 
			
		||||
    licenses offer ticketed support, indemnification and middleware.
 | 
			
		||||
 | 
			
		||||
    http://www.SafeRTOS.com - High Integrity Systems also provide a safety
 | 
			
		||||
    engineered and independently SIL3 certified version for use in safety and
 | 
			
		||||
    mission critical applications that require provable dependability.
 | 
			
		||||
 | 
			
		||||
    1 tab == 4 spaces!
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/* Standard includes. */
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
 | 
			
		||||
all the API functions to use the MPU wrappers.  That should only be done when
 | 
			
		||||
task.h is included from an application file. */
 | 
			
		||||
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
 | 
			
		||||
 | 
			
		||||
#include "FreeRTOS.h"
 | 
			
		||||
#include "task.h"
 | 
			
		||||
#include "queue.h"
 | 
			
		||||
#include "timers.h"
 | 
			
		||||
 | 
			
		||||
#if ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 0 )
 | 
			
		||||
	#error configUSE_TIMERS must be set to 1 to make the xTimerPendFunctionCall() function available.
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Lint e961 and e750 are suppressed as a MISRA exception justified because the
 | 
			
		||||
MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined for the
 | 
			
		||||
header files above, but not in this file, in order to generate the correct
 | 
			
		||||
privileged Vs unprivileged linkage and placement. */
 | 
			
		||||
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750. */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* This entire source file will be skipped if the application is not configured
 | 
			
		||||
to include software timer functionality.  This #if is closed at the very bottom
 | 
			
		||||
of this file.  If you want to include software timer functionality then ensure
 | 
			
		||||
configUSE_TIMERS is set to 1 in FreeRTOSConfig.h. */
 | 
			
		||||
#if ( configUSE_TIMERS == 1 )
 | 
			
		||||
 | 
			
		||||
/* Misc definitions. */
 | 
			
		||||
#define tmrNO_DELAY		( TickType_t ) 0U
 | 
			
		||||
 | 
			
		||||
/* The definition of the timers themselves. */
 | 
			
		||||
typedef struct tmrTimerControl
 | 
			
		||||
{
 | 
			
		||||
	const char				*pcTimerName;		/*<< Text name.  This is not used by the kernel, it is included simply to make debugging easier. */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
 | 
			
		||||
	ListItem_t				xTimerListItem;		/*<< Standard linked list item as used by all kernel features for event management. */
 | 
			
		||||
	TickType_t				xTimerPeriodInTicks;/*<< How quickly and often the timer expires. */
 | 
			
		||||
	UBaseType_t				uxAutoReload;		/*<< Set to pdTRUE if the timer should be automatically restarted once expired.  Set to pdFALSE if the timer is, in effect, a one-shot timer. */
 | 
			
		||||
	void 					*pvTimerID;			/*<< An ID to identify the timer.  This allows the timer to be identified when the same callback is used for multiple timers. */
 | 
			
		||||
	TimerCallbackFunction_t	pxCallbackFunction;	/*<< The function that will be called when the timer expires. */
 | 
			
		||||
	#if( configUSE_TRACE_FACILITY == 1 )
 | 
			
		||||
		UBaseType_t			uxTimerNumber;		/*<< An ID assigned by trace tools such as FreeRTOS+Trace */
 | 
			
		||||
	#endif
 | 
			
		||||
} xTIMER;
 | 
			
		||||
 | 
			
		||||
/* The old xTIMER name is maintained above then typedefed to the new Timer_t
 | 
			
		||||
name below to enable the use of older kernel aware debuggers. */
 | 
			
		||||
typedef xTIMER Timer_t;
 | 
			
		||||
 | 
			
		||||
/* The definition of messages that can be sent and received on the timer queue.
 | 
			
		||||
Two types of message can be queued - messages that manipulate a software timer,
 | 
			
		||||
and messages that request the execution of a non-timer related callback.  The
 | 
			
		||||
two message types are defined in two separate structures, xTimerParametersType
 | 
			
		||||
and xCallbackParametersType respectively. */
 | 
			
		||||
typedef struct tmrTimerParameters
 | 
			
		||||
{
 | 
			
		||||
	TickType_t			xMessageValue;		/*<< An optional value used by a subset of commands, for example, when changing the period of a timer. */
 | 
			
		||||
	Timer_t *			pxTimer;			/*<< The timer to which the command will be applied. */
 | 
			
		||||
} TimerParameter_t;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
typedef struct tmrCallbackParameters
 | 
			
		||||
{
 | 
			
		||||
	PendedFunction_t	pxCallbackFunction;	/* << The callback function to execute. */
 | 
			
		||||
	void *pvParameter1;						/* << The value that will be used as the callback functions first parameter. */
 | 
			
		||||
	uint32_t ulParameter2;					/* << The value that will be used as the callback functions second parameter. */
 | 
			
		||||
} CallbackParameters_t;
 | 
			
		||||
 | 
			
		||||
/* The structure that contains the two message types, along with an identifier
 | 
			
		||||
that is used to determine which message type is valid. */
 | 
			
		||||
typedef struct tmrTimerQueueMessage
 | 
			
		||||
{
 | 
			
		||||
	BaseType_t			xMessageID;			/*<< The command being sent to the timer service task. */
 | 
			
		||||
	union
 | 
			
		||||
	{
 | 
			
		||||
		TimerParameter_t xTimerParameters;
 | 
			
		||||
 | 
			
		||||
		/* Don't include xCallbackParameters if it is not going to be used as
 | 
			
		||||
		it makes the structure (and therefore the timer queue) larger. */
 | 
			
		||||
		#if ( INCLUDE_xTimerPendFunctionCall == 1 )
 | 
			
		||||
			CallbackParameters_t xCallbackParameters;
 | 
			
		||||
		#endif /* INCLUDE_xTimerPendFunctionCall */
 | 
			
		||||
	} u;
 | 
			
		||||
} DaemonTaskMessage_t;
 | 
			
		||||
 | 
			
		||||
/*lint -e956 A manual analysis and inspection has been used to determine which
 | 
			
		||||
static variables must be declared volatile. */
 | 
			
		||||
 | 
			
		||||
/* The list in which active timers are stored.  Timers are referenced in expire
 | 
			
		||||
time order, with the nearest expiry time at the front of the list.  Only the
 | 
			
		||||
timer service task is allowed to access these lists. */
 | 
			
		||||
PRIVILEGED_DATA static List_t xActiveTimerList1;
 | 
			
		||||
PRIVILEGED_DATA static List_t xActiveTimerList2;
 | 
			
		||||
PRIVILEGED_DATA static List_t *pxCurrentTimerList;
 | 
			
		||||
PRIVILEGED_DATA static List_t *pxOverflowTimerList;
 | 
			
		||||
 | 
			
		||||
/* A queue that is used to send commands to the timer service task. */
 | 
			
		||||
PRIVILEGED_DATA static QueueHandle_t xTimerQueue = NULL;
 | 
			
		||||
 | 
			
		||||
// Added by Realtek to prevent timer thread blocked
 | 
			
		||||
#ifdef INCLUDE_xTimerGetTimerDaemonTaskHandle
 | 
			
		||||
#undef INCLUDE_xTimerGetTimerDaemonTaskHandle
 | 
			
		||||
#define INCLUDE_xTimerGetTimerDaemonTaskHandle 1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if ( INCLUDE_xTimerGetTimerDaemonTaskHandle == 1 )
 | 
			
		||||
 | 
			
		||||
	PRIVILEGED_DATA static TaskHandle_t xTimerTaskHandle = NULL;
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*lint +e956 */
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Initialise the infrastructure used by the timer service task if it has not
 | 
			
		||||
 * been initialised already.
 | 
			
		||||
 */
 | 
			
		||||
static void prvCheckForValidListAndQueue( void ) PRIVILEGED_FUNCTION;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * The timer service task (daemon).  Timer functionality is controlled by this
 | 
			
		||||
 * task.  Other tasks communicate with the timer service task using the
 | 
			
		||||
 * xTimerQueue queue.
 | 
			
		||||
 */
 | 
			
		||||
static void prvTimerTask( void *pvParameters ) PRIVILEGED_FUNCTION;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Called by the timer service task to interpret and process a command it
 | 
			
		||||
 * received on the timer queue.
 | 
			
		||||
 */
 | 
			
		||||
static void	prvProcessReceivedCommands( void ) PRIVILEGED_FUNCTION;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Insert the timer into either xActiveTimerList1, or xActiveTimerList2,
 | 
			
		||||
 * depending on if the expire time causes a timer counter overflow.
 | 
			
		||||
 */
 | 
			
		||||
static BaseType_t prvInsertTimerInActiveList( Timer_t * const pxTimer, const TickType_t xNextExpiryTime, const TickType_t xTimeNow, const TickType_t xCommandTime ) PRIVILEGED_FUNCTION;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * An active timer has reached its expire time.  Reload the timer if it is an
 | 
			
		||||
 * auto reload timer, then call its callback.
 | 
			
		||||
 */
 | 
			
		||||
static void prvProcessExpiredTimer( const TickType_t xNextExpireTime, const TickType_t xTimeNow ) PRIVILEGED_FUNCTION;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * The tick count has overflowed.  Switch the timer lists after ensuring the
 | 
			
		||||
 * current timer list does not still reference some timers.
 | 
			
		||||
 */
 | 
			
		||||
static void prvSwitchTimerLists( void ) PRIVILEGED_FUNCTION;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Obtain the current tick count, setting *pxTimerListsWereSwitched to pdTRUE
 | 
			
		||||
 * if a tick count overflow occurred since prvSampleTimeNow() was last called.
 | 
			
		||||
 */
 | 
			
		||||
static TickType_t prvSampleTimeNow( BaseType_t * const pxTimerListsWereSwitched ) PRIVILEGED_FUNCTION;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * If the timer list contains any active timers then return the expire time of
 | 
			
		||||
 * the timer that will expire first and set *pxListWasEmpty to false.  If the
 | 
			
		||||
 * timer list does not contain any timers then return 0 and set *pxListWasEmpty
 | 
			
		||||
 * to pdTRUE.
 | 
			
		||||
 */
 | 
			
		||||
static TickType_t prvGetNextExpireTime( BaseType_t * const pxListWasEmpty ) PRIVILEGED_FUNCTION;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * If a timer has expired, process it.  Otherwise, block the timer service task
 | 
			
		||||
 * until either a timer does expire or a command is received.
 | 
			
		||||
 */
 | 
			
		||||
static void prvProcessTimerOrBlockTask( const TickType_t xNextExpireTime, const BaseType_t xListWasEmpty ) PRIVILEGED_FUNCTION;
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
BaseType_t xTimerCreateTimerTask( void )
 | 
			
		||||
{
 | 
			
		||||
BaseType_t xReturn = pdFAIL;
 | 
			
		||||
 | 
			
		||||
	/* This function is called when the scheduler is started if
 | 
			
		||||
	configUSE_TIMERS is set to 1.  Check that the infrastructure used by the
 | 
			
		||||
	timer service task has been created/initialised.  If timers have already
 | 
			
		||||
	been created then the initialisation will already have been performed. */
 | 
			
		||||
	prvCheckForValidListAndQueue();
 | 
			
		||||
 | 
			
		||||
	if( xTimerQueue != NULL )
 | 
			
		||||
	{
 | 
			
		||||
		#if ( INCLUDE_xTimerGetTimerDaemonTaskHandle == 1 )
 | 
			
		||||
		{
 | 
			
		||||
			/* Create the timer task, storing its handle in xTimerTaskHandle so
 | 
			
		||||
			it can be returned by the xTimerGetTimerDaemonTaskHandle() function. */
 | 
			
		||||
			xReturn = xTaskCreate( prvTimerTask, "Tmr Svc", ( uint16_t ) configTIMER_TASK_STACK_DEPTH, NULL, (( ( UBaseType_t ) configTIMER_TASK_PRIORITY + PRIORITIE_OFFSET) | portPRIVILEGE_BIT), &xTimerTaskHandle );
 | 
			
		||||
		}
 | 
			
		||||
		#else
 | 
			
		||||
		{
 | 
			
		||||
			/* Create the timer task without storing its handle. */
 | 
			
		||||
			xReturn = xTaskCreate( prvTimerTask, "Tmr Svc", ( uint16_t ) configTIMER_TASK_STACK_DEPTH, NULL, (( ( UBaseType_t ) configTIMER_TASK_PRIORITY + PRIORITIE_OFFSET) | portPRIVILEGE_BIT ), NULL);
 | 
			
		||||
		}
 | 
			
		||||
		#endif
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	configASSERT( xReturn );
 | 
			
		||||
	return xReturn;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
TimerHandle_t xTimerCreate( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
 | 
			
		||||
{
 | 
			
		||||
Timer_t *pxNewTimer;
 | 
			
		||||
 | 
			
		||||
	/* Allocate the timer structure. */
 | 
			
		||||
	if( xTimerPeriodInTicks == ( TickType_t ) 0U )
 | 
			
		||||
	{
 | 
			
		||||
		pxNewTimer = NULL;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		pxNewTimer = ( Timer_t * ) pvPortMalloc( sizeof( Timer_t ) );
 | 
			
		||||
		if( pxNewTimer != NULL )
 | 
			
		||||
		{
 | 
			
		||||
			/* Ensure the infrastructure used by the timer service task has been
 | 
			
		||||
			created/initialised. */
 | 
			
		||||
			prvCheckForValidListAndQueue();
 | 
			
		||||
 | 
			
		||||
			/* Initialise the timer structure members using the function parameters. */
 | 
			
		||||
			pxNewTimer->pcTimerName = pcTimerName;
 | 
			
		||||
			pxNewTimer->xTimerPeriodInTicks = xTimerPeriodInTicks;
 | 
			
		||||
			pxNewTimer->uxAutoReload = uxAutoReload;
 | 
			
		||||
			pxNewTimer->pvTimerID = pvTimerID;
 | 
			
		||||
			pxNewTimer->pxCallbackFunction = pxCallbackFunction;
 | 
			
		||||
			vListInitialiseItem( &( pxNewTimer->xTimerListItem ) );
 | 
			
		||||
 | 
			
		||||
			traceTIMER_CREATE( pxNewTimer );
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			traceTIMER_CREATE_FAILED();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* 0 is not a valid value for xTimerPeriodInTicks. */
 | 
			
		||||
	configASSERT( ( xTimerPeriodInTicks > 0 ) );
 | 
			
		||||
 | 
			
		||||
	return ( TimerHandle_t ) pxNewTimer;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
extern void * vTaskGetCurrentTCB( void );
 | 
			
		||||
static void	prvProcessCommands( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue );
 | 
			
		||||
 | 
			
		||||
BaseType_t xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait )
 | 
			
		||||
{
 | 
			
		||||
BaseType_t xReturn = pdFAIL;
 | 
			
		||||
DaemonTaskMessage_t xMessage;
 | 
			
		||||
 | 
			
		||||
	// Added by Realtek to prevent timer thread blocked
 | 
			
		||||
	if( ( vTaskGetCurrentTCB() == ( void * ) xTimerTaskHandle ) && ( ( xCommandID == tmrCOMMAND_STOP ) || ( xCommandID == tmrCOMMAND_CHANGE_PERIOD ) || ( xCommandID == tmrCOMMAND_DELETE ) ) )
 | 
			
		||||
	{
 | 
			
		||||
		prvProcessCommands( xTimer, xCommandID, xOptionalValue );
 | 
			
		||||
		return pdPASS;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Send a message to the timer service task to perform a particular action
 | 
			
		||||
	on a particular timer definition. */
 | 
			
		||||
	if( xTimerQueue != NULL )
 | 
			
		||||
	{
 | 
			
		||||
		/* Send a command to the timer service task to start the xTimer timer. */
 | 
			
		||||
		xMessage.xMessageID = xCommandID;
 | 
			
		||||
		xMessage.u.xTimerParameters.xMessageValue = xOptionalValue;
 | 
			
		||||
		xMessage.u.xTimerParameters.pxTimer = ( Timer_t * ) xTimer;
 | 
			
		||||
 | 
			
		||||
		if( xCommandID < tmrFIRST_FROM_ISR_COMMAND )
 | 
			
		||||
		{
 | 
			
		||||
			if( xTaskGetSchedulerState() == taskSCHEDULER_RUNNING )
 | 
			
		||||
			{
 | 
			
		||||
				xReturn = xQueueSendToBack( xTimerQueue, &xMessage, xTicksToWait );
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				xReturn = xQueueSendToBack( xTimerQueue, &xMessage, tmrNO_DELAY );
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			xReturn = xQueueSendToBackFromISR( xTimerQueue, &xMessage, pxHigherPriorityTaskWoken );
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		traceTIMER_COMMAND_SEND( xTimer, xCommandID, xOptionalValue, xReturn );
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return xReturn;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
#if ( INCLUDE_xTimerGetTimerDaemonTaskHandle == 1 )
 | 
			
		||||
 | 
			
		||||
	TaskHandle_t xTimerGetTimerDaemonTaskHandle( void )
 | 
			
		||||
	{
 | 
			
		||||
		/* If xTimerGetTimerDaemonTaskHandle() is called before the scheduler has been
 | 
			
		||||
		started, then xTimerTaskHandle will be NULL. */
 | 
			
		||||
		configASSERT( ( xTimerTaskHandle != NULL ) );
 | 
			
		||||
		return xTimerTaskHandle;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
const char * pcTimerGetTimerName( TimerHandle_t xTimer )
 | 
			
		||||
{
 | 
			
		||||
Timer_t *pxTimer = ( Timer_t * ) xTimer;
 | 
			
		||||
 | 
			
		||||
	return pxTimer->pcTimerName;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
static void prvProcessExpiredTimer( const TickType_t xNextExpireTime, const TickType_t xTimeNow )
 | 
			
		||||
{
 | 
			
		||||
BaseType_t xResult;
 | 
			
		||||
Timer_t * const pxTimer = ( Timer_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList );
 | 
			
		||||
 | 
			
		||||
	/* Remove the timer from the list of active timers.  A check has already
 | 
			
		||||
	been performed to ensure the list is not empty. */
 | 
			
		||||
	( void ) uxListRemove( &( pxTimer->xTimerListItem ) );
 | 
			
		||||
	traceTIMER_EXPIRED( pxTimer );
 | 
			
		||||
 | 
			
		||||
	/* If the timer is an auto reload timer then calculate the next
 | 
			
		||||
	expiry time and re-insert the timer in the list of active timers. */
 | 
			
		||||
	if( pxTimer->uxAutoReload == ( UBaseType_t ) pdTRUE )
 | 
			
		||||
	{
 | 
			
		||||
		/* The timer is inserted into a list using a time relative to anything
 | 
			
		||||
		other than the current time.  It will therefore be inserted into the
 | 
			
		||||
		correct list relative to the time this task thinks it is now. */
 | 
			
		||||
		if( prvInsertTimerInActiveList( pxTimer, ( xNextExpireTime + pxTimer->xTimerPeriodInTicks ), xTimeNow, xNextExpireTime ) == pdTRUE )
 | 
			
		||||
		{
 | 
			
		||||
			/* The timer expired before it was added to the active timer
 | 
			
		||||
			list.  Reload it now.  */
 | 
			
		||||
			xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START_DONT_TRACE, xNextExpireTime, NULL, tmrNO_DELAY );
 | 
			
		||||
			configASSERT( xResult );
 | 
			
		||||
			( void ) xResult;
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Call the timer callback. */
 | 
			
		||||
	pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer );
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
static void prvTimerTask( void *pvParameters )
 | 
			
		||||
{
 | 
			
		||||
TickType_t xNextExpireTime;
 | 
			
		||||
BaseType_t xListWasEmpty;
 | 
			
		||||
 | 
			
		||||
	/* Just to avoid compiler warnings. */
 | 
			
		||||
	( void ) pvParameters;
 | 
			
		||||
 | 
			
		||||
	for( ;; )
 | 
			
		||||
	{
 | 
			
		||||
		/* Query the timers list to see if it contains any timers, and if so,
 | 
			
		||||
		obtain the time at which the next timer will expire. */
 | 
			
		||||
		xNextExpireTime = prvGetNextExpireTime( &xListWasEmpty );
 | 
			
		||||
 | 
			
		||||
		/* If a timer has expired, process it.  Otherwise, block this task
 | 
			
		||||
		until either a timer does expire, or a command is received. */
 | 
			
		||||
		prvProcessTimerOrBlockTask( xNextExpireTime, xListWasEmpty );
 | 
			
		||||
 | 
			
		||||
		/* Empty the command queue. */
 | 
			
		||||
		prvProcessReceivedCommands();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
static void prvProcessTimerOrBlockTask( const TickType_t xNextExpireTime, const BaseType_t xListWasEmpty )
 | 
			
		||||
{
 | 
			
		||||
TickType_t xTimeNow;
 | 
			
		||||
BaseType_t xTimerListsWereSwitched;
 | 
			
		||||
 | 
			
		||||
	vTaskSuspendAll();
 | 
			
		||||
	{
 | 
			
		||||
		/* Obtain the time now to make an assessment as to whether the timer
 | 
			
		||||
		has expired or not.  If obtaining the time causes the lists to switch
 | 
			
		||||
		then don't process this timer as any timers that remained in the list
 | 
			
		||||
		when the lists were switched will have been processed within the
 | 
			
		||||
		prvSampleTimeNow() function. */
 | 
			
		||||
		xTimeNow = prvSampleTimeNow( &xTimerListsWereSwitched );
 | 
			
		||||
		if( xTimerListsWereSwitched == pdFALSE )
 | 
			
		||||
		{
 | 
			
		||||
			/* The tick count has not overflowed, has the timer expired? */
 | 
			
		||||
			if( ( xListWasEmpty == pdFALSE ) && ( xNextExpireTime <= xTimeNow ) )
 | 
			
		||||
			{
 | 
			
		||||
				( void ) xTaskResumeAll();
 | 
			
		||||
				prvProcessExpiredTimer( xNextExpireTime, xTimeNow );
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				/* The tick count has not overflowed, and the next expire
 | 
			
		||||
				time has not been reached yet.  This task should therefore
 | 
			
		||||
				block to wait for the next expire time or a command to be
 | 
			
		||||
				received - whichever comes first.  The following line cannot
 | 
			
		||||
				be reached unless xNextExpireTime > xTimeNow, except in the
 | 
			
		||||
				case when the current timer list is empty. */
 | 
			
		||||
				vQueueWaitForMessageRestricted( xTimerQueue, ( xNextExpireTime - xTimeNow ) );
 | 
			
		||||
 | 
			
		||||
				if( xTaskResumeAll() == pdFALSE )
 | 
			
		||||
				{
 | 
			
		||||
					/* Yield to wait for either a command to arrive, or the block time
 | 
			
		||||
					to expire.  If a command arrived between the critical section being
 | 
			
		||||
					exited and this yield then the yield will not cause the task
 | 
			
		||||
					to block. */
 | 
			
		||||
					portYIELD_WITHIN_API();
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
				{
 | 
			
		||||
					mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			( void ) xTaskResumeAll();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
static TickType_t prvGetNextExpireTime( BaseType_t * const pxListWasEmpty )
 | 
			
		||||
{
 | 
			
		||||
TickType_t xNextExpireTime;
 | 
			
		||||
 | 
			
		||||
	/* Timers are listed in expiry time order, with the head of the list
 | 
			
		||||
	referencing the task that will expire first.  Obtain the time at which
 | 
			
		||||
	the timer with the nearest expiry time will expire.  If there are no
 | 
			
		||||
	active timers then just set the next expire time to 0.  That will cause
 | 
			
		||||
	this task to unblock when the tick count overflows, at which point the
 | 
			
		||||
	timer lists will be switched and the next expiry time can be
 | 
			
		||||
	re-assessed.  */
 | 
			
		||||
	*pxListWasEmpty = listLIST_IS_EMPTY( pxCurrentTimerList );
 | 
			
		||||
	if( *pxListWasEmpty == pdFALSE )
 | 
			
		||||
	{
 | 
			
		||||
		xNextExpireTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxCurrentTimerList );
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		/* Ensure the task unblocks when the tick count rolls over. */
 | 
			
		||||
		xNextExpireTime = ( TickType_t ) 0U;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return xNextExpireTime;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
static TickType_t prvSampleTimeNow( BaseType_t * const pxTimerListsWereSwitched )
 | 
			
		||||
{
 | 
			
		||||
TickType_t xTimeNow;
 | 
			
		||||
PRIVILEGED_DATA static TickType_t xLastTime = ( TickType_t ) 0U; /*lint !e956 Variable is only accessible to one task. */
 | 
			
		||||
 | 
			
		||||
	xTimeNow = xTaskGetTickCount();
 | 
			
		||||
 | 
			
		||||
	if( xTimeNow < xLastTime )
 | 
			
		||||
	{
 | 
			
		||||
		prvSwitchTimerLists();
 | 
			
		||||
		*pxTimerListsWereSwitched = pdTRUE;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		*pxTimerListsWereSwitched = pdFALSE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	xLastTime = xTimeNow;
 | 
			
		||||
 | 
			
		||||
	return xTimeNow;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
static BaseType_t prvInsertTimerInActiveList( Timer_t * const pxTimer, const TickType_t xNextExpiryTime, const TickType_t xTimeNow, const TickType_t xCommandTime )
 | 
			
		||||
{
 | 
			
		||||
BaseType_t xProcessTimerNow = pdFALSE;
 | 
			
		||||
 | 
			
		||||
	listSET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ), xNextExpiryTime );
 | 
			
		||||
	listSET_LIST_ITEM_OWNER( &( pxTimer->xTimerListItem ), pxTimer );
 | 
			
		||||
 | 
			
		||||
	if( xNextExpiryTime <= xTimeNow )
 | 
			
		||||
	{
 | 
			
		||||
		/* Has the expiry time elapsed between the command to start/reset a
 | 
			
		||||
		timer was issued, and the time the command was processed? */
 | 
			
		||||
		if( ( xTimeNow - xCommandTime ) >= pxTimer->xTimerPeriodInTicks )
 | 
			
		||||
		{
 | 
			
		||||
			/* The time between a command being issued and the command being
 | 
			
		||||
			processed actually exceeds the timers period.  */
 | 
			
		||||
			xProcessTimerNow = pdTRUE;
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			vListInsert( pxOverflowTimerList, &( pxTimer->xTimerListItem ) );
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		if( ( xTimeNow < xCommandTime ) && ( xNextExpiryTime >= xCommandTime ) )
 | 
			
		||||
		{
 | 
			
		||||
			/* If, since the command was issued, the tick count has overflowed
 | 
			
		||||
			but the expiry time has not, then the timer must have already passed
 | 
			
		||||
			its expiry time and should be processed immediately. */
 | 
			
		||||
			xProcessTimerNow = pdTRUE;
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			vListInsert( pxCurrentTimerList, &( pxTimer->xTimerListItem ) );
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return xProcessTimerNow;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
static void	prvProcessReceivedCommands( void )
 | 
			
		||||
{
 | 
			
		||||
DaemonTaskMessage_t xMessage;
 | 
			
		||||
Timer_t *pxTimer;
 | 
			
		||||
BaseType_t xTimerListsWereSwitched, xResult;
 | 
			
		||||
TickType_t xTimeNow;
 | 
			
		||||
 | 
			
		||||
	while( xQueueReceive( xTimerQueue, &xMessage, tmrNO_DELAY ) != pdFAIL ) /*lint !e603 xMessage does not have to be initialised as it is passed out, not in, and it is not used unless xQueueReceive() returns pdTRUE. */
 | 
			
		||||
	{
 | 
			
		||||
		#if ( INCLUDE_xTimerPendFunctionCall == 1 )
 | 
			
		||||
		{
 | 
			
		||||
			/* Negative commands are pended function calls rather than timer
 | 
			
		||||
			commands. */
 | 
			
		||||
			if( xMessage.xMessageID < ( BaseType_t ) 0 )
 | 
			
		||||
			{
 | 
			
		||||
				const CallbackParameters_t * const pxCallback = &( xMessage.u.xCallbackParameters );
 | 
			
		||||
 | 
			
		||||
				/* The timer uses the xCallbackParameters member to request a
 | 
			
		||||
				callback be executed.  Check the callback is not NULL. */
 | 
			
		||||
				configASSERT( pxCallback );
 | 
			
		||||
 | 
			
		||||
				/* Call the function. */
 | 
			
		||||
				pxCallback->pxCallbackFunction( pxCallback->pvParameter1, pxCallback->ulParameter2 );
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		#endif /* INCLUDE_xTimerPendFunctionCall */
 | 
			
		||||
 | 
			
		||||
		/* Commands that are positive are timer commands rather than pended
 | 
			
		||||
		function calls. */
 | 
			
		||||
		if( xMessage.xMessageID >= ( BaseType_t ) 0 )
 | 
			
		||||
		{
 | 
			
		||||
			/* The messages uses the xTimerParameters member to work on a
 | 
			
		||||
			software timer. */
 | 
			
		||||
			pxTimer = xMessage.u.xTimerParameters.pxTimer;
 | 
			
		||||
 | 
			
		||||
			if( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) == pdFALSE )
 | 
			
		||||
			{
 | 
			
		||||
				/* The timer is in a list, remove it. */
 | 
			
		||||
				( void ) uxListRemove( &( pxTimer->xTimerListItem ) );
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			traceTIMER_COMMAND_RECEIVED( pxTimer, xMessage.xMessageID, xMessage.u.xTimerParameters.xMessageValue );
 | 
			
		||||
 | 
			
		||||
			/* In this case the xTimerListsWereSwitched parameter is not used, but
 | 
			
		||||
			it must be present in the function call.  prvSampleTimeNow() must be
 | 
			
		||||
			called after the message is received from xTimerQueue so there is no
 | 
			
		||||
			possibility of a higher priority task adding a message to the message
 | 
			
		||||
			queue with a time that is ahead of the timer daemon task (because it
 | 
			
		||||
			pre-empted the timer daemon task after the xTimeNow value was set). */
 | 
			
		||||
			xTimeNow = prvSampleTimeNow( &xTimerListsWereSwitched );
 | 
			
		||||
 | 
			
		||||
			switch( xMessage.xMessageID )
 | 
			
		||||
			{
 | 
			
		||||
				case tmrCOMMAND_START :
 | 
			
		||||
			    case tmrCOMMAND_START_FROM_ISR :
 | 
			
		||||
			    case tmrCOMMAND_RESET :
 | 
			
		||||
			    case tmrCOMMAND_RESET_FROM_ISR :
 | 
			
		||||
				case tmrCOMMAND_START_DONT_TRACE :
 | 
			
		||||
					/* Start or restart a timer. */
 | 
			
		||||
					if( prvInsertTimerInActiveList( pxTimer,  xMessage.u.xTimerParameters.xMessageValue + pxTimer->xTimerPeriodInTicks, xTimeNow, xMessage.u.xTimerParameters.xMessageValue ) == pdTRUE )
 | 
			
		||||
					{
 | 
			
		||||
						/* The timer expired before it was added to the active
 | 
			
		||||
						timer list.  Process it now. */
 | 
			
		||||
						pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer );
 | 
			
		||||
						traceTIMER_EXPIRED( pxTimer );
 | 
			
		||||
 | 
			
		||||
						if( pxTimer->uxAutoReload == ( UBaseType_t ) pdTRUE )
 | 
			
		||||
						{
 | 
			
		||||
							xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START_DONT_TRACE, xMessage.u.xTimerParameters.xMessageValue + pxTimer->xTimerPeriodInTicks, NULL, tmrNO_DELAY );
 | 
			
		||||
							configASSERT( xResult );
 | 
			
		||||
							( void ) xResult;
 | 
			
		||||
						}
 | 
			
		||||
						else
 | 
			
		||||
						{
 | 
			
		||||
							mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					else
 | 
			
		||||
					{
 | 
			
		||||
						mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
					}
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
				case tmrCOMMAND_STOP :
 | 
			
		||||
				case tmrCOMMAND_STOP_FROM_ISR :
 | 
			
		||||
					/* The timer has already been removed from the active list.
 | 
			
		||||
					There is nothing to do here. */
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
				case tmrCOMMAND_CHANGE_PERIOD :
 | 
			
		||||
				case tmrCOMMAND_CHANGE_PERIOD_FROM_ISR :
 | 
			
		||||
					pxTimer->xTimerPeriodInTicks = xMessage.u.xTimerParameters.xMessageValue;
 | 
			
		||||
					configASSERT( ( pxTimer->xTimerPeriodInTicks > 0 ) );
 | 
			
		||||
 | 
			
		||||
					/* The new period does not really have a reference, and can be
 | 
			
		||||
					longer or shorter than the old one.  The command time is
 | 
			
		||||
					therefore set to the current time, and as the period cannot be
 | 
			
		||||
					zero the next expiry time can only be in the future, meaning
 | 
			
		||||
					(unlike for the xTimerStart() case above) there is no fail case
 | 
			
		||||
					that needs to be handled here. */
 | 
			
		||||
					( void ) prvInsertTimerInActiveList( pxTimer, ( xTimeNow + pxTimer->xTimerPeriodInTicks ), xTimeNow, xTimeNow );
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
				case tmrCOMMAND_DELETE :
 | 
			
		||||
					/* The timer has already been removed from the active list,
 | 
			
		||||
					just free up the memory. */
 | 
			
		||||
					vPortFree( pxTimer );
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
				default	:
 | 
			
		||||
					/* Don't expect to get here. */
 | 
			
		||||
					break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Added by Realtek to prevent timer thread blocked
 | 
			
		||||
static void	prvProcessCommands( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue )
 | 
			
		||||
{
 | 
			
		||||
Timer_t *pxTimer = ( Timer_t * ) xTimer;
 | 
			
		||||
TickType_t xTimeNow = xTaskGetTickCount();;
 | 
			
		||||
 | 
			
		||||
	if( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) == pdFALSE )
 | 
			
		||||
	{
 | 
			
		||||
		/* The timer is in a list, remove it. */
 | 
			
		||||
		( void ) uxListRemove( &( pxTimer->xTimerListItem ) );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	switch( xCommandID )
 | 
			
		||||
	{
 | 
			
		||||
		case tmrCOMMAND_STOP :
 | 
			
		||||
			/* The timer has already been removed from the active list.
 | 
			
		||||
			There is nothing to do here. */
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case tmrCOMMAND_CHANGE_PERIOD :
 | 
			
		||||
			pxTimer->xTimerPeriodInTicks = xOptionalValue;
 | 
			
		||||
			( void ) prvInsertTimerInActiveList( pxTimer, ( xTimeNow + pxTimer->xTimerPeriodInTicks ), xTimeNow, xTimeNow );
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case tmrCOMMAND_DELETE :
 | 
			
		||||
			/* The timer has already been removed from the active list,
 | 
			
		||||
			just free up the memory. */
 | 
			
		||||
			vPortFree( pxTimer );
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		default	:
 | 
			
		||||
			/* Don't expect to get here. */
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
static void prvSwitchTimerLists( void )
 | 
			
		||||
{
 | 
			
		||||
TickType_t xNextExpireTime, xReloadTime;
 | 
			
		||||
List_t *pxTemp;
 | 
			
		||||
Timer_t *pxTimer;
 | 
			
		||||
BaseType_t xResult;
 | 
			
		||||
 | 
			
		||||
	/* The tick count has overflowed.  The timer lists must be switched.
 | 
			
		||||
	If there are any timers still referenced from the current timer list
 | 
			
		||||
	then they must have expired and should be processed before the lists
 | 
			
		||||
	are switched. */
 | 
			
		||||
	while( listLIST_IS_EMPTY( pxCurrentTimerList ) == pdFALSE )
 | 
			
		||||
	{
 | 
			
		||||
		xNextExpireTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxCurrentTimerList );
 | 
			
		||||
 | 
			
		||||
		/* Remove the timer from the list. */
 | 
			
		||||
		pxTimer = ( Timer_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList );
 | 
			
		||||
		( void ) uxListRemove( &( pxTimer->xTimerListItem ) );
 | 
			
		||||
		traceTIMER_EXPIRED( pxTimer );
 | 
			
		||||
 | 
			
		||||
		/* Execute its callback, then send a command to restart the timer if
 | 
			
		||||
		it is an auto-reload timer.  It cannot be restarted here as the lists
 | 
			
		||||
		have not yet been switched. */
 | 
			
		||||
		pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer );
 | 
			
		||||
 | 
			
		||||
		if( pxTimer->uxAutoReload == ( UBaseType_t ) pdTRUE )
 | 
			
		||||
		{
 | 
			
		||||
			/* Calculate the reload value, and if the reload value results in
 | 
			
		||||
			the timer going into the same timer list then it has already expired
 | 
			
		||||
			and the timer should be re-inserted into the current list so it is
 | 
			
		||||
			processed again within this loop.  Otherwise a command should be sent
 | 
			
		||||
			to restart the timer to ensure it is only inserted into a list after
 | 
			
		||||
			the lists have been swapped. */
 | 
			
		||||
			xReloadTime = ( xNextExpireTime + pxTimer->xTimerPeriodInTicks );
 | 
			
		||||
			if( xReloadTime > xNextExpireTime )
 | 
			
		||||
			{
 | 
			
		||||
				listSET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ), xReloadTime );
 | 
			
		||||
				listSET_LIST_ITEM_OWNER( &( pxTimer->xTimerListItem ), pxTimer );
 | 
			
		||||
				vListInsert( pxCurrentTimerList, &( pxTimer->xTimerListItem ) );
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START_DONT_TRACE, xNextExpireTime, NULL, tmrNO_DELAY );
 | 
			
		||||
				configASSERT( xResult );
 | 
			
		||||
				( void ) xResult;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	pxTemp = pxCurrentTimerList;
 | 
			
		||||
	pxCurrentTimerList = pxOverflowTimerList;
 | 
			
		||||
	pxOverflowTimerList = pxTemp;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
static void prvCheckForValidListAndQueue( void )
 | 
			
		||||
{
 | 
			
		||||
	/* Check that the list from which active timers are referenced, and the
 | 
			
		||||
	queue used to communicate with the timer service, have been
 | 
			
		||||
	initialised. */
 | 
			
		||||
	taskENTER_CRITICAL();
 | 
			
		||||
	{
 | 
			
		||||
		if( xTimerQueue == NULL )
 | 
			
		||||
		{
 | 
			
		||||
			vListInitialise( &xActiveTimerList1 );
 | 
			
		||||
			vListInitialise( &xActiveTimerList2 );
 | 
			
		||||
			pxCurrentTimerList = &xActiveTimerList1;
 | 
			
		||||
			pxOverflowTimerList = &xActiveTimerList2;
 | 
			
		||||
			xTimerQueue = xQueueCreate( ( UBaseType_t ) configTIMER_QUEUE_LENGTH, sizeof( DaemonTaskMessage_t ) );
 | 
			
		||||
			configASSERT( xTimerQueue );
 | 
			
		||||
 | 
			
		||||
			#if ( configQUEUE_REGISTRY_SIZE > 0 )
 | 
			
		||||
			{
 | 
			
		||||
				if( xTimerQueue != NULL )
 | 
			
		||||
				{
 | 
			
		||||
					vQueueAddToRegistry( xTimerQueue, "TmrQ" );
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
				{
 | 
			
		||||
					mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			#endif /* configQUEUE_REGISTRY_SIZE */
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	taskEXIT_CRITICAL();
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer )
 | 
			
		||||
{
 | 
			
		||||
BaseType_t xTimerIsInActiveList;
 | 
			
		||||
Timer_t *pxTimer = ( Timer_t * ) xTimer;
 | 
			
		||||
 | 
			
		||||
	/* Is the timer in the list of active timers? */
 | 
			
		||||
	taskENTER_CRITICAL();
 | 
			
		||||
	{
 | 
			
		||||
		/* Checking to see if it is in the NULL list in effect checks to see if
 | 
			
		||||
		it is referenced from either the current or the overflow timer lists in
 | 
			
		||||
		one go, but the logic has to be reversed, hence the '!'. */
 | 
			
		||||
		xTimerIsInActiveList = ( BaseType_t ) !( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) );
 | 
			
		||||
	}
 | 
			
		||||
	taskEXIT_CRITICAL();
 | 
			
		||||
 | 
			
		||||
	return xTimerIsInActiveList;
 | 
			
		||||
} /*lint !e818 Can't be pointer to const due to the typedef. */
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
void *pvTimerGetTimerID( const TimerHandle_t xTimer )
 | 
			
		||||
{
 | 
			
		||||
Timer_t * const pxTimer = ( Timer_t * ) xTimer;
 | 
			
		||||
 | 
			
		||||
	return pxTimer->pvTimerID;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
#if( INCLUDE_xTimerPendFunctionCall == 1 )
 | 
			
		||||
 | 
			
		||||
	BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, BaseType_t *pxHigherPriorityTaskWoken )
 | 
			
		||||
	{
 | 
			
		||||
	DaemonTaskMessage_t xMessage;
 | 
			
		||||
	BaseType_t xReturn;
 | 
			
		||||
 | 
			
		||||
		/* Complete the message with the function parameters and post it to the
 | 
			
		||||
		daemon task. */
 | 
			
		||||
		xMessage.xMessageID = tmrCOMMAND_EXECUTE_CALLBACK_FROM_ISR;
 | 
			
		||||
		xMessage.u.xCallbackParameters.pxCallbackFunction = xFunctionToPend;
 | 
			
		||||
		xMessage.u.xCallbackParameters.pvParameter1 = pvParameter1;
 | 
			
		||||
		xMessage.u.xCallbackParameters.ulParameter2 = ulParameter2;
 | 
			
		||||
 | 
			
		||||
		xReturn = xQueueSendFromISR( xTimerQueue, &xMessage, pxHigherPriorityTaskWoken );
 | 
			
		||||
		
 | 
			
		||||
		tracePEND_FUNC_CALL_FROM_ISR( xFunctionToPend, pvParameter1, ulParameter2, xReturn );
 | 
			
		||||
 | 
			
		||||
		return xReturn;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#endif /* INCLUDE_xTimerPendFunctionCall */
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
#if( INCLUDE_xTimerPendFunctionCall == 1 )
 | 
			
		||||
 | 
			
		||||
	BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait )
 | 
			
		||||
	{
 | 
			
		||||
	DaemonTaskMessage_t xMessage;
 | 
			
		||||
	BaseType_t xReturn;
 | 
			
		||||
 | 
			
		||||
		/* Complete the message with the function parameters and post it to the
 | 
			
		||||
		daemon task. */
 | 
			
		||||
		xMessage.xMessageID = tmrCOMMAND_EXECUTE_CALLBACK;
 | 
			
		||||
		xMessage.u.xCallbackParameters.pxCallbackFunction = xFunctionToPend;
 | 
			
		||||
		xMessage.u.xCallbackParameters.pvParameter1 = pvParameter1;
 | 
			
		||||
		xMessage.u.xCallbackParameters.ulParameter2 = ulParameter2;
 | 
			
		||||
 | 
			
		||||
		xReturn = xQueueSendToBack( xTimerQueue, &xMessage, xTicksToWait );
 | 
			
		||||
 | 
			
		||||
		tracePEND_FUNC_CALL( xFunctionToPend, pvParameter1, ulParameter2, xReturn );
 | 
			
		||||
		
 | 
			
		||||
		return xReturn;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#endif /* INCLUDE_xTimerPendFunctionCall */
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/* This entire source file will be skipped if the application is not configured
 | 
			
		||||
to include software timer functionality.  If you want to include software timer
 | 
			
		||||
functionality then ensure configUSE_TIMERS is set to 1 in FreeRTOSConfig.h. */
 | 
			
		||||
#endif /* configUSE_TIMERS == 1 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										64
									
								
								component/os/os_dep/device_lock.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								component/os/os_dep/device_lock.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,64 @@
 | 
			
		|||
/*
 | 
			
		||||
 *  Routines to access hardware
 | 
			
		||||
 *
 | 
			
		||||
 *  Copyright (c) 2013 Realtek Semiconductor Corp.
 | 
			
		||||
 *
 | 
			
		||||
 *  This module is a confidential and proprietary property of RealTek and
 | 
			
		||||
 *  possession or use of this module requires written permission of RealTek.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "osdep_service.h"
 | 
			
		||||
#include "device_lock.h"
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------
 | 
			
		||||
#define DEVICE_MUTEX_IS_INIT(device)	(mutex_init & (1<<device))
 | 
			
		||||
#define DEVICE_MUTEX_SET_INIT(device)	(mutex_init |= (1<<device))
 | 
			
		||||
#define DEVICE_MUTEX_CLR_INIT(device)	(mutex_init &= (~(1<<device)))
 | 
			
		||||
 | 
			
		||||
static u32 mutex_init = 0;
 | 
			
		||||
static _mutex device_mutex[RT_DEV_LOCK_MAX];
 | 
			
		||||
 | 
			
		||||
//======================================================
 | 
			
		||||
static void device_mutex_init(RT_DEV_LOCK_E device)
 | 
			
		||||
{
 | 
			
		||||
	if(!DEVICE_MUTEX_IS_INIT(device)){
 | 
			
		||||
		_lock lock;
 | 
			
		||||
		_irqL irqL;
 | 
			
		||||
		rtw_enter_critical(&lock, &irqL);
 | 
			
		||||
		if(!DEVICE_MUTEX_IS_INIT(device)){
 | 
			
		||||
			rtw_mutex_init(&device_mutex[device]);
 | 
			
		||||
			DEVICE_MUTEX_SET_INIT(device);
 | 
			
		||||
		}
 | 
			
		||||
		rtw_exit_critical(&lock, &irqL);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//======================================================
 | 
			
		||||
static void device_mutex_free(RT_DEV_LOCK_E device)
 | 
			
		||||
{
 | 
			
		||||
	if(DEVICE_MUTEX_IS_INIT(device)){
 | 
			
		||||
		_lock lock;
 | 
			
		||||
		_irqL irqL;
 | 
			
		||||
		rtw_enter_critical(&lock, &irqL);
 | 
			
		||||
		if(!DEVICE_MUTEX_IS_INIT(device)){
 | 
			
		||||
			rtw_mutex_free(&device_mutex[device]);
 | 
			
		||||
			DEVICE_MUTEX_CLR_INIT(device);
 | 
			
		||||
		}
 | 
			
		||||
		rtw_exit_critical(&lock, &irqL);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//======================================================
 | 
			
		||||
void device_mutex_lock(RT_DEV_LOCK_E device)
 | 
			
		||||
{
 | 
			
		||||
	device_mutex_init(device);
 | 
			
		||||
	while(rtw_mutex_get_timeout(&device_mutex[device], 10000)<0)
 | 
			
		||||
		printf("device lock timeout: %d\n", device);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//======================================================
 | 
			
		||||
void device_mutex_unlock(RT_DEV_LOCK_E device)
 | 
			
		||||
{
 | 
			
		||||
	device_mutex_init(device);
 | 
			
		||||
	rtw_mutex_put(&device_mutex[device]);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										23
									
								
								component/os/os_dep/include/device_lock.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								component/os/os_dep/include/device_lock.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,23 @@
 | 
			
		|||
/*
 | 
			
		||||
 *  Routines to access hardware
 | 
			
		||||
 *
 | 
			
		||||
 *  Copyright (c) 2013 Realtek Semiconductor Corp.
 | 
			
		||||
 *
 | 
			
		||||
 *  This module is a confidential and proprietary property of RealTek and
 | 
			
		||||
 *  possession or use of this module requires written permission of RealTek.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _DEVICE_LOCK_H_
 | 
			
		||||
#define _DEVICE_LOCK_H_
 | 
			
		||||
 | 
			
		||||
typedef enum _RT_DEV_LOCK_E
 | 
			
		||||
{
 | 
			
		||||
	RT_DEV_LOCK_EFUSE = 0,
 | 
			
		||||
	RT_DEV_LOCK_FLASH = 1,
 | 
			
		||||
	RT_DEV_LOCK_MAX = 2
 | 
			
		||||
}RT_DEV_LOCK_E;
 | 
			
		||||
 | 
			
		||||
void device_mutex_lock(RT_DEV_LOCK_E device);
 | 
			
		||||
void device_mutex_unlock(RT_DEV_LOCK_E device);
 | 
			
		||||
 | 
			
		||||
#endif //_DEVICE_LOCK_H_
 | 
			
		||||
							
								
								
									
										127
									
								
								component/os/os_dep/include/mailbox.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										127
									
								
								component/os/os_dep/include/mailbox.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,127 @@
 | 
			
		|||
/******************************************************************************
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
 | 
			
		||||
 *                                        
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify it
 | 
			
		||||
 * under the terms of version 2 of the GNU General Public License as
 | 
			
		||||
 * published by the Free Software Foundation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful, but WITHOUT
 | 
			
		||||
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 | 
			
		||||
 * more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License along with
 | 
			
		||||
 * this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
 | 
			
		||||
 *
 | 
			
		||||
 *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
#ifndef __MAILBOX_H_
 | 
			
		||||
#define __MAILBOX_H_
 | 
			
		||||
 | 
			
		||||
#include "hal_api.h"
 | 
			
		||||
#include "osdep_api.h"
 | 
			
		||||
#include "hal_util.h"
 | 
			
		||||
#ifdef CONFIG_FREERTOS
 | 
			
		||||
#include "queue.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define MBOX_WAIT_NO_TIMEOUT        0xffffffff  // waiting for send/receive message with no timeout
 | 
			
		||||
#define MBOX_WAIT_NONE              0           // No wait for send/receive message
 | 
			
		||||
 | 
			
		||||
typedef enum _MAILBOX_ID_ {
 | 
			
		||||
	MBOX_ID_WLAN =	    0,
 | 
			
		||||
	MBOX_ID_UART =	    1,
 | 
			
		||||
	MBOX_ID_I2C =	    2,
 | 
			
		||||
	MBOX_ID_I2S =	    3,
 | 
			
		||||
	MBOX_ID_SPI =	    4,
 | 
			
		||||
	MBOX_ID_SDIO =	    5,
 | 
			
		||||
    MBOX_ID_SDIO_MP =   6,
 | 
			
		||||
 | 
			
		||||
	MBOX_ID_MAX =	0xff	
 | 
			
		||||
} MAILBOX_ID;
 | 
			
		||||
 | 
			
		||||
#if defined(CONFIG_SDIO_DEVICE_EN) && defined(CONFIG_SDIO_DEVICE_NORMAL)
 | 
			
		||||
typedef enum _MSG_TYPE_SDIO {
 | 
			
		||||
	MSG_SDIO_RX_PKT=1,		// request to send a SDIO RX packet to the host side
 | 
			
		||||
	MSG_SDIO_C2H=2,			// request to send a C2H message
 | 
			
		||||
	MSG_SDIO_RPWM=3,		// request to set the RPWM
 | 
			
		||||
    MSG_SDIO_MP_LOOP_TXPKT=4,      // request to loopback this TX packet
 | 
			
		||||
 | 
			
		||||
	MSG_SDIO_MAX=0xff
 | 
			
		||||
} MSG_TYPE_SDIO;
 | 
			
		||||
#endif  // end  of "#ifdef CONFIG_SDIO_DEVICE_EN"
 | 
			
		||||
 | 
			
		||||
/* the data structure of a MailBox to deliver message blocks */
 | 
			
		||||
typedef struct _RTL_MAILBOX_ {
 | 
			
		||||
    void    *mbox_hdl;      // the mailbox handle which return from OS create queue API
 | 
			
		||||
	_Sema	*pWakeSema;     // the semaphore to wakeup the message receiving task
 | 
			
		||||
	_LIST	mbox_list;      // the link list to chain all created mailbox
 | 
			
		||||
	u8		mbox_id;        /* the ID of this Mailbox, this ID is 
 | 
			
		||||
                                used to locate the MBox for send/get message */
 | 
			
		||||
} RTL_MAILBOX, *PRTL_MAILBOX;
 | 
			
		||||
 | 
			
		||||
/* the data structure of a message block */
 | 
			
		||||
typedef struct _RTL_MSG_BLK {
 | 
			
		||||
    u8      MsgType;		// the message type
 | 
			
		||||
    u8      Reserved;       // reserved
 | 
			
		||||
    u16     DateLen;        // the vaild data length of the pBuf
 | 
			
		||||
    u32     Para;           // the optional parameters associated with this message type
 | 
			
		||||
    u8      *pBuf;          // point to a data buffer associated with this message type
 | 
			
		||||
} MSG_BLK, *PMSG_BLK;
 | 
			
		||||
 | 
			
		||||
/* the data structure for system level message block management */
 | 
			
		||||
typedef struct _RTL_MBOX_ROOT_ {
 | 
			
		||||
	_LIST 		mbox_list;			// the link list of all created mailbox
 | 
			
		||||
	_Mutex		Mutex;				// the Mutex to protect the mailbox create/delete procedure
 | 
			
		||||
	u8          isInitialed;        // is this Mailbox link-list initialed
 | 
			
		||||
} RTL_MBOX_ROOT, *PRTL_MBOX_ROOT;
 | 
			
		||||
 | 
			
		||||
// Export Funcction API
 | 
			
		||||
extern PRTL_MAILBOX RtlMailboxCreate(
 | 
			
		||||
    IN u8 MboxID, 
 | 
			
		||||
    IN u32 MboxSize, 
 | 
			
		||||
    IN _Sema *pWakeSema
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
extern VOID RtlMailboxDel(
 | 
			
		||||
    IN PRTL_MAILBOX MboxHdl
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
extern u8 RtlMailboxSendToBack(
 | 
			
		||||
    IN u8 MboxID, 
 | 
			
		||||
    IN MSG_BLK *pMsg, 
 | 
			
		||||
    IN u32 MSToWait, 
 | 
			
		||||
    IN u8 IsFromISR
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
extern u8 RtlMailboxSendToFront(
 | 
			
		||||
    IN u8 MboxID, 
 | 
			
		||||
    IN MSG_BLK *pMsg, 
 | 
			
		||||
    IN u32 MSToWait, 
 | 
			
		||||
    IN u8 IsFromISR
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
extern u8 RtlMailboxReceive(
 | 
			
		||||
    IN u8 MboxID, 
 | 
			
		||||
    OUT MSG_BLK *pMsg, 
 | 
			
		||||
    IN u32 MSToWait, 
 | 
			
		||||
    IN u8 IsFromISR
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
extern u8 RtlMailboxPeek(
 | 
			
		||||
    IN u8 MboxID, 
 | 
			
		||||
    OUT MSG_BLK *pMsg, 
 | 
			
		||||
    IN u32 MSToWait, 
 | 
			
		||||
    IN u8 IsFromISR
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
extern u32 RtlMailboxMsgWaiting(
 | 
			
		||||
    IN u8 MboxID, 
 | 
			
		||||
    IN u8 IsFromISR
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif	// #ifndef __MAILBOX_H_
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										343
									
								
								component/os/os_dep/include/os_support.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										343
									
								
								component/os/os_dep/include/os_support.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,343 @@
 | 
			
		|||
 /******************************************************************************
 | 
			
		||||
  *
 | 
			
		||||
  * Name: sys-support.h - System type support for Linux
 | 
			
		||||
  *       $Revision: 1.1.1.1 $
 | 
			
		||||
  *
 | 
			
		||||
  *****************************************************************************/
 | 
			
		||||
 | 
			
		||||
#ifndef __OS_SUPPORT_H__
 | 
			
		||||
#define __OS_SUPPORT_H__
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include <FreeRTOS.h>
 | 
			
		||||
#include <basic_types.h>
 | 
			
		||||
#include "os_support.h"
 | 
			
		||||
//#include "diag.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
#define __init
 | 
			
		||||
#define __exit
 | 
			
		||||
#define __devinit
 | 
			
		||||
#define __devexit
 | 
			
		||||
#endif
 | 
			
		||||
#define RTL_HZ                          100
 | 
			
		||||
 | 
			
		||||
#define SemaInit(sem, value)            vSemaphoreCreateBinary(sem)
 | 
			
		||||
#define SemaPost(sem)                   xSemaphoreGive(sem)
 | 
			
		||||
#define SemaWait(sem, block_time)       xSemaphoreTake(sem, block_time)
 | 
			
		||||
//#define printk                          DiagPrintf
 | 
			
		||||
 | 
			
		||||
#define SpinLockInit(lock)              do { } while (0)
 | 
			
		||||
#define SpinLock(x)                     do { } while (0)
 | 
			
		||||
#define SpinUnlock(x)                   do { } while (0)
 | 
			
		||||
#define SpinLockBh(x)                   do { } while (0)
 | 
			
		||||
#define SpinUnlockBh(x)                 do { } while (0)
 | 
			
		||||
#ifdef PLATFORM_FREERTOS
 | 
			
		||||
#define RestoreFlags()                  portEXIT_CRITICAL()
 | 
			
		||||
#define SaveAndCli()			        portENTER_CRITICAL()
 | 
			
		||||
#define SpinLockIrqSave(lock, flags)	SaveAndCli()
 | 
			
		||||
#define SpinUnlockIrqRestore(l, f)	    RestoreFlags()
 | 
			
		||||
#else
 | 
			
		||||
#define RestoreFlags(x)                 portENABLE_INTERRUPTS()		
 | 
			
		||||
#define SaveAndCli(x)			        portDISABLE_INTERRUPTS()
 | 
			
		||||
#define SpinLockIrqSave(lock, flags)	SaveAndCli(flags)
 | 
			
		||||
#define SpinUnlockIrqRestore(l, f)	    RestoreFlags(f)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//#define RtlKmalloc(size, flag)          pvPortMallocAligned(size, 0)
 | 
			
		||||
#define RtlKmalloc(size, flag)          pvPortMalloc(size)
 | 
			
		||||
#define RtlKfree(pv)                    vPortFreeAligned(pv)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_TIMER_MODULE
 | 
			
		||||
#define __Delay(t)                  HalDelayUs(t)
 | 
			
		||||
#else
 | 
			
		||||
static __inline__ u32 __Delay(u32 us)
 | 
			
		||||
{
 | 
			
		||||
    DBG_8195A("No Delay: please enable hardware Timer\n");
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define Mdelay(t)					__Delay(t*1000)
 | 
			
		||||
#define Udelay(t)					__Delay(t)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define ASSERT(_bool_)					do { } while (0)
 | 
			
		||||
 | 
			
		||||
//#define panic_printk				DiagPrintf
 | 
			
		||||
//#define sprintf						DiagPrintf
 | 
			
		||||
//#define diag_sprintf                DiagPrintf
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//1TODO: Need check again; the below just for compile ok ; chris
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * ATOMIC_READ - read atomic variable
 | 
			
		||||
 * @v: pointer of type atomic_t
 | 
			
		||||
 *
 | 
			
		||||
 * Atomically reads the value of @v.  Note that the guaranteed
 | 
			
		||||
 * useful range of an atomic_t is only 24 bits.
 | 
			
		||||
 */
 | 
			
		||||
//#define AtomicRead(v)  ((*v))
 | 
			
		||||
 | 
			
		||||
static __inline__ u32
 | 
			
		||||
AtomicRead(
 | 
			
		||||
    IN  atomic_t * v
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
#ifdef PLATFORM_FREERTOS
 | 
			
		||||
    u32 Temp;
 | 
			
		||||
 | 
			
		||||
    SaveAndCli();
 | 
			
		||||
    Temp = v->counter;
 | 
			
		||||
    RestoreFlags();
 | 
			
		||||
 | 
			
		||||
    return Temp;
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
   u32 Temp, Flags;
 | 
			
		||||
   
 | 
			
		||||
   SaveAndCli(Flags);
 | 
			
		||||
   Temp = v->counter;
 | 
			
		||||
   RestoreFlags(Flags);
 | 
			
		||||
   
 | 
			
		||||
   return Temp;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * ATOMIC_SET - set atomic variable
 | 
			
		||||
 * @v: pointer of type atomic_t
 | 
			
		||||
 * @i: required value
 | 
			
		||||
 *
 | 
			
		||||
 * Atomically sets the value of @v to @i.  Note that the guaranteed
 | 
			
		||||
 * useful range of an atomic_t is only 24 bits.
 | 
			
		||||
 */
 | 
			
		||||
//#define AtomicSet(v,i) ((v)->counter = (i))
 | 
			
		||||
 | 
			
		||||
static __inline__ VOID
 | 
			
		||||
AtomicSet(
 | 
			
		||||
    IN  u32 i, 
 | 
			
		||||
    IN  atomic_t * v
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
#ifdef PLATFORM_FREERTOS
 | 
			
		||||
    SaveAndCli();
 | 
			
		||||
    v->counter = i;
 | 
			
		||||
    RestoreFlags();
 | 
			
		||||
#else
 | 
			
		||||
    u32 Flags;
 | 
			
		||||
    
 | 
			
		||||
    SaveAndCli(Flags);
 | 
			
		||||
    v->counter = i;
 | 
			
		||||
    RestoreFlags(Flags);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * The MIPS I implementation is only atomic with respect to
 | 
			
		||||
 * interrupts.  R3000 based multiprocessor machines are rare anyway ...
 | 
			
		||||
 *
 | 
			
		||||
 * AtomicAdd - add integer to atomic variable
 | 
			
		||||
 * @i: integer value to add
 | 
			
		||||
 * @v: pointer of type atomic_t
 | 
			
		||||
 *
 | 
			
		||||
 * Atomically adds @i to @v.  Note that the guaranteed useful range
 | 
			
		||||
 * of an atomic_t is only 24 bits.
 | 
			
		||||
 */
 | 
			
		||||
static __inline__ VOID
 | 
			
		||||
AtomicAdd(
 | 
			
		||||
    IN  u32 i, 
 | 
			
		||||
    IN  atomic_t * v
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
#ifdef PLATFORM_FREERTOS
 | 
			
		||||
    SaveAndCli();
 | 
			
		||||
    v->counter += i;
 | 
			
		||||
    RestoreFlags();
 | 
			
		||||
#else
 | 
			
		||||
    u32 Flags;
 | 
			
		||||
    
 | 
			
		||||
    SaveAndCli(Flags);
 | 
			
		||||
    v->counter += i;
 | 
			
		||||
    RestoreFlags(Flags);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * AtomicSub - subtract the atomic variable
 | 
			
		||||
 * @i: integer value to subtract
 | 
			
		||||
 * @v: pointer of type atomic_t
 | 
			
		||||
 *
 | 
			
		||||
 * Atomically subtracts @i from @v.  Note that the guaranteed
 | 
			
		||||
 * useful range of an atomic_t is only 24 bits.
 | 
			
		||||
 */
 | 
			
		||||
static __inline__ void
 | 
			
		||||
AtomicSub(
 | 
			
		||||
    IN  u32 i, 
 | 
			
		||||
    IN  atomic_t * v
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
#ifdef PLATFORM_FREERTOS
 | 
			
		||||
    SaveAndCli();
 | 
			
		||||
    v->counter -= i;
 | 
			
		||||
    RestoreFlags();
 | 
			
		||||
#else
 | 
			
		||||
    u32 Flags;
 | 
			
		||||
 | 
			
		||||
    SaveAndCli(Flags);
 | 
			
		||||
    v->counter -= i;
 | 
			
		||||
    RestoreFlags(Flags);    
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static __inline__ u32
 | 
			
		||||
AtomicAddReturn(
 | 
			
		||||
    IN  u32 i, 
 | 
			
		||||
    IN  atomic_t * v
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
#ifdef PLATFORM_FREERTOS
 | 
			
		||||
    u32 Temp;
 | 
			
		||||
 | 
			
		||||
    SaveAndCli();
 | 
			
		||||
    Temp = v->counter;
 | 
			
		||||
    Temp += i;
 | 
			
		||||
    v->counter = Temp;
 | 
			
		||||
    RestoreFlags();
 | 
			
		||||
 | 
			
		||||
    return Temp;
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
       u32 Temp, Flags;
 | 
			
		||||
       
 | 
			
		||||
       SaveAndCli(Flags);
 | 
			
		||||
       Temp = v->counter;
 | 
			
		||||
       Temp += i;
 | 
			
		||||
       v->counter = Temp;
 | 
			
		||||
       RestoreFlags(Flags);
 | 
			
		||||
       
 | 
			
		||||
       return Temp;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static __inline__ u32
 | 
			
		||||
AtomicSubReturn(
 | 
			
		||||
    IN  u32 i, 
 | 
			
		||||
    IN  atomic_t * v
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
#ifdef PLATFORM_FREERTOS
 | 
			
		||||
    u32 Temp;       
 | 
			
		||||
 | 
			
		||||
    SaveAndCli();
 | 
			
		||||
    Temp = v->counter;
 | 
			
		||||
    Temp -= i;
 | 
			
		||||
    v->counter = Temp;
 | 
			
		||||
    RestoreFlags();
 | 
			
		||||
 | 
			
		||||
    return Temp;
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
    
 | 
			
		||||
       u32 Temp, Flags;       
 | 
			
		||||
       
 | 
			
		||||
       SaveAndCli(Flags);
 | 
			
		||||
       Temp = v->counter;
 | 
			
		||||
       Temp -= i;
 | 
			
		||||
       v->counter = Temp;
 | 
			
		||||
       RestoreFlags(Flags);
 | 
			
		||||
       
 | 
			
		||||
       return Temp;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * ATOMIC_INC - increment atomic variable
 | 
			
		||||
 * @v: pointer of type atomic_t
 | 
			
		||||
 *
 | 
			
		||||
 * Atomically increments @v by 1.  Note that the guaranteed
 | 
			
		||||
 * useful range of an atomic_t is only 24 bits.
 | 
			
		||||
 */
 | 
			
		||||
#define AtomicInc(v) AtomicAdd(1,(v))
 | 
			
		||||
 | 
			
		||||
#define AtomicIncReturn(v) AtomicAddReturn(1,(v))
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * ATOMIC_DEC - decrement and test
 | 
			
		||||
 * @v: pointer of type atomic_t
 | 
			
		||||
 *
 | 
			
		||||
 * Atomically decrements @v by 1.  Note that the guaranteed
 | 
			
		||||
 * useful range of an atomic_t is only 24 bits.
 | 
			
		||||
 */
 | 
			
		||||
#define AtomicDec(v) AtomicSub(1,(v))
 | 
			
		||||
 | 
			
		||||
#define AtomicDecReturn(v) AtomicSubReturn(1,(v))
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * ATOMIC_DEC_AND_TEST - decrement by 1 and test
 | 
			
		||||
 * @v: pointer of type atomic_t
 | 
			
		||||
 *
 | 
			
		||||
 * Atomically decrements @v by 1 and
 | 
			
		||||
 * returns true if the result is 0, or false for all other
 | 
			
		||||
 * cases.  Note that the guaranteed
 | 
			
		||||
 * useful range of an atomic_t is only 24 bits.
 | 
			
		||||
 */
 | 
			
		||||
#define AtomicDecAndTest(v) (AtomicSubReturn(1, (v)) == 0)
 | 
			
		||||
 | 
			
		||||
/* Not needed on 64bit architectures */
 | 
			
		||||
static __inline__ u32 
 | 
			
		||||
__Div64_32(
 | 
			
		||||
    IN  __uint64_t *n, 
 | 
			
		||||
    IN  u32 base
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	__uint64_t rem = *n;
 | 
			
		||||
	__uint64_t b = base;
 | 
			
		||||
	__uint64_t res, d = 1;
 | 
			
		||||
	u32 high = rem >> 32;
 | 
			
		||||
 | 
			
		||||
	/* Reduce the thing a bit first */
 | 
			
		||||
	res = 0;
 | 
			
		||||
	if (high >= base) {
 | 
			
		||||
		high /= base;
 | 
			
		||||
		res = (__uint64_t) high << 32;
 | 
			
		||||
		rem -= (__uint64_t) (high*base) << 32;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	while ((__int64_t)b > 0 && b < rem) {
 | 
			
		||||
		b = b+b;
 | 
			
		||||
		d = d+d;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	do {
 | 
			
		||||
		if (rem >= b) {
 | 
			
		||||
			rem -= b;
 | 
			
		||||
			res += d;
 | 
			
		||||
		}
 | 
			
		||||
		b >>= 1;
 | 
			
		||||
		d >>= 1;
 | 
			
		||||
	} while (d);
 | 
			
		||||
 | 
			
		||||
	*n = res;
 | 
			
		||||
	return rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define DO_DIV(n,base) ({				\
 | 
			
		||||
	unsigned int __base = (base);			\
 | 
			
		||||
	unsigned int __rem;				\
 | 
			
		||||
	(void)(((typeof((n)) *)0) == ((__uint64_t *)0));	\
 | 
			
		||||
	if (((n) >> 32) == 0) {			\
 | 
			
		||||
		__rem = (unsigned int)(n) % __base;		\
 | 
			
		||||
		(n) = (unsigned int)(n) / __base;		\
 | 
			
		||||
	} else 						\
 | 
			
		||||
		__rem = __Div64_32(&(n), __base);	\
 | 
			
		||||
	__rem;						\
 | 
			
		||||
 })
 | 
			
		||||
 | 
			
		||||
#endif /* __SYS_SUPPORT_H__ */
 | 
			
		||||
							
								
								
									
										215
									
								
								component/os/os_dep/include/os_timer.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										215
									
								
								component/os/os_dep/include/os_timer.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,215 @@
 | 
			
		|||
/******************************************************************************
 | 
			
		||||
  *
 | 
			
		||||
  * Name: sys-support.h - System type support for Linux
 | 
			
		||||
  *       $Revision: 1.1.1.1 $
 | 
			
		||||
  *
 | 
			
		||||
  *****************************************************************************/
 | 
			
		||||
 | 
			
		||||
#ifndef __OS_TIMER_H__
 | 
			
		||||
#define __OS_TIMER_H__
 | 
			
		||||
 | 
			
		||||
#include "diag.h"
 | 
			
		||||
#include "os_support.h"
 | 
			
		||||
#include "timers.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define JIFFIES	        xTaskGetTickCount()
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
	TIMER_NO_INIT = 0,
 | 
			
		||||
	TIMER_INIT = 1,
 | 
			
		||||
	TIMER_START = 2,
 | 
			
		||||
	TIMER_DISABLE = 3
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct TIMER_LIST {
 | 
			
		||||
    xTimerHandle    TimeHdl;
 | 
			
		||||
    u32             Flag;
 | 
			
		||||
	unsigned long	Data;
 | 
			
		||||
	VOID            (*Function)(void *);
 | 
			
		||||
    u32             TimerID;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static inline VOID 
 | 
			
		||||
InitTimer(
 | 
			
		||||
    IN  struct TIMER_LIST *Timer
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
#ifdef RTK_MODE_TIMER 
 | 
			
		||||
	u32 data = Timer->Data;
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef PLATFORM_FREERTOS
 | 
			
		||||
    u32 Flags;
 | 
			
		||||
#endif
 | 
			
		||||
    u32 TimerID = Timer->TimerID;
 | 
			
		||||
	VOID (*Function)(VOID *) = Timer->Function;
 | 
			
		||||
//    xTimerHandle timer_handle;
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
#ifdef PLATFORM_FREERTOS
 | 
			
		||||
	SaveAndCli();
 | 
			
		||||
#else
 | 
			
		||||
    SaveAndCli(Flags);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	if (Timer->Flag != TIMER_DISABLE) {
 | 
			
		||||
		if (Timer->Flag == TIMER_NO_INIT) {
 | 
			
		||||
            Timer->TimeHdl = xTimerCreate( (const char *)"Timer",                 // Just a test name, not used by the kernel.
 | 
			
		||||
                                            ( 100 ),                 // The timer period in ticks.
 | 
			
		||||
                                            pdFALSE,                 // The timers will auto-reload themselves when they expire.
 | 
			
		||||
                                            ( void * ) TimerID,     // Assign each timer a unique id equal to its array index.
 | 
			
		||||
                                            Function
 | 
			
		||||
                                            #ifdef RTK_MODE_TIMER                 
 | 
			
		||||
                                            ,data				// Each timer calls the same callback when it expires.                                            
 | 
			
		||||
                                            #endif
 | 
			
		||||
                                          );
 | 
			
		||||
            if (NULL == Timer->TimeHdl) {
 | 
			
		||||
                DBG_ERROR_LOG("\rInitial Timer fail !!!!!!!!!\n");
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                TimerID++;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
			Timer->Flag = TIMER_INIT;
 | 
			
		||||
		}
 | 
			
		||||
		else if (Timer->Flag == TIMER_START) {
 | 
			
		||||
            xTimerStop(Timer->TimeHdl,0);
 | 
			
		||||
			Timer->Flag = TIMER_DISABLE;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
    
 | 
			
		||||
#ifdef PLATFORM_FREERTOS
 | 
			
		||||
	RestoreFlags();	
 | 
			
		||||
#else
 | 
			
		||||
	RestoreFlags(Flags);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void 
 | 
			
		||||
ModTimer(
 | 
			
		||||
    IN  struct TIMER_LIST *Timer,
 | 
			
		||||
    IN  u32 TimeoutTicks
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
#ifndef PLATFORM_FREERTOS
 | 
			
		||||
	u32 Flags;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  	void (*Function)(void *) = Timer->Function;
 | 
			
		||||
 | 
			
		||||
#ifdef PLATFORM_FREERTOS
 | 
			
		||||
	SaveAndCli();
 | 
			
		||||
#else
 | 
			
		||||
	SaveAndCli(Flags);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	if (Timer->Flag == TIMER_NO_INIT) {
 | 
			
		||||
		if (Timer->Function) {
 | 
			
		||||
            Timer->TimeHdl = xTimerCreate((const char *)"Timer",                    // Just a text name, not used by the kernel.
 | 
			
		||||
                                            ( 100 ),                    // The timer period in ticks.
 | 
			
		||||
                                            pdFALSE,                    // The timers will auto-reload themselves when they expire.
 | 
			
		||||
                                            ( void * ) Timer->TimerID,  // Assign each timer a unique id equal to its array index.
 | 
			
		||||
                                            Function
 | 
			
		||||
                                            #ifdef RTK_MODE_TIMER                                                              
 | 
			
		||||
                                            ,Timer->Data	// Each timer calls the same callback when it expires.
 | 
			
		||||
                                            #endif
 | 
			
		||||
                                      );
 | 
			
		||||
            if (NULL == Timer->TimeHdl) {
 | 
			
		||||
                DBG_ERROR_LOG("\rInitial Timer fail !!!!!!!!!\n");
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                Timer->TimerID++;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
			Timer->Flag = TIMER_INIT;
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			//printf("###mod_timer() not initilized, timer->flag=%d timer->function=%p timeout_ticks=%llu###\n", timer->flag, timer->function, timeout_ticks);
 | 
			
		||||
#ifdef PLATFORM_FREERTOS
 | 
			
		||||
            RestoreFlags();
 | 
			
		||||
#else
 | 
			
		||||
        	RestoreFlags(Flags);
 | 
			
		||||
#endif
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	else if (Timer->Flag == TIMER_START) {
 | 
			
		||||
        xTimerStop(Timer->TimeHdl,0);
 | 
			
		||||
	 	Timer->Flag = TIMER_DISABLE;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	TimeoutTicks -= xTaskGetTickCount();
 | 
			
		||||
	if (TimeoutTicks <= 0)
 | 
			
		||||
		TimeoutTicks = 2;
 | 
			
		||||
 | 
			
		||||
	if (xTimerStart(Timer->TimeHdl, TimeoutTicks ))
 | 
			
		||||
		Timer->Flag = TIMER_START;
 | 
			
		||||
	else
 | 
			
		||||
		DBG_ERROR_LOG("\r###mod_timer() - no slots available###\n");
 | 
			
		||||
#ifdef PLATFORM_FREERTOS
 | 
			
		||||
    RestoreFlags();
 | 
			
		||||
#else
 | 
			
		||||
	RestoreFlags(Flags);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
static inline int 
 | 
			
		||||
TimerPending (
 | 
			
		||||
    IN  const struct TIMER_LIST *Timer
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
    if (Timer->TimeHdl && Timer->Flag != TIMER_NO_INIT)
 | 
			
		||||
		return 1;
 | 
			
		||||
	else
 | 
			
		||||
		return 0;
 | 
			
		||||
}
 | 
			
		||||
  
 | 
			
		||||
static inline void  
 | 
			
		||||
DelTimerSync(
 | 
			
		||||
    IN  struct TIMER_LIST *Timer
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
#ifdef PLATFORM_FREERTOS
 | 
			
		||||
	SaveAndCli();
 | 
			
		||||
#else
 | 
			
		||||
    u32 Flags;
 | 
			
		||||
    SaveAndCli(Flags);
 | 
			
		||||
#endif
 | 
			
		||||
    if (Timer->TimeHdl && Timer->Flag != TIMER_INIT) {
 | 
			
		||||
        if (Timer->Flag == TIMER_START)
 | 
			
		||||
            xTimerStop(Timer->TimeHdl, 0);
 | 
			
		||||
        
 | 
			
		||||
        xTimerDelete(Timer->TimeHdl, 0);
 | 
			
		||||
        Timer->Flag = TIMER_NO_INIT;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#ifdef PLATFORM_FREERTOS
 | 
			
		||||
    RestoreFlags();
 | 
			
		||||
#else
 | 
			
		||||
	RestoreFlags(Flags);
 | 
			
		||||
#endif	
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 /*
 | 
			
		||||
  *      These inlines deal with timer wrapping correctly. You are 
 | 
			
		||||
  *      strongly encouraged to use them
 | 
			
		||||
  *      1. Because people otherwise forget
 | 
			
		||||
  *      2. Because if the timer wrap changes in future you wont have to
 | 
			
		||||
  *         alter your driver code.
 | 
			
		||||
  *
 | 
			
		||||
  * time_after(a,b) returns true if the time a is after time b.
 | 
			
		||||
  *
 | 
			
		||||
  * Do this with "<0" and ">=0" to only test the sign of the result. A
 | 
			
		||||
  * good compiler would generate better code (and a really good compiler
 | 
			
		||||
  * wouldn't care). Gcc is currently neither.
 | 
			
		||||
  */
 | 
			
		||||
 #define TIME_AFTER(a,b)		((long)(b) - (long)(a) < 0)
 | 
			
		||||
 #define TIMER_BEFORE(a,b)		TIME_AFTER(b,a)
 | 
			
		||||
  
 | 
			
		||||
 #define TIME_AFTER_EQ(a,b)		((long)(a) - (long)(b) >= 0)
 | 
			
		||||
 #define TIMER_BEFORE_EQ(a,b)		TIME_AFTER_EQ(b,a)
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif //__OS_TIMER_H__
 | 
			
		||||
							
								
								
									
										561
									
								
								component/os/os_dep/include/osdep_api.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										561
									
								
								component/os/os_dep/include/osdep_api.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,561 @@
 | 
			
		|||
/******************************************************************************
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
 | 
			
		||||
 *                                        
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify it
 | 
			
		||||
 * under the terms of version 2 of the GNU General Public License as
 | 
			
		||||
 * published by the Free Software Foundation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful, but WITHOUT
 | 
			
		||||
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 | 
			
		||||
 * more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License along with
 | 
			
		||||
 * this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
 | 
			
		||||
 *
 | 
			
		||||
 *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
#ifndef __OSDEP_API_H_
 | 
			
		||||
#define __OSDEP_API_H_
 | 
			
		||||
 | 
			
		||||
#include "os_timer.h"
 | 
			
		||||
#include "os_support.h"
 | 
			
		||||
#include "semphr.h"
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
/* Structure used to pass parameters to each task. */
 | 
			
		||||
typedef struct SEMAPHORE_PARAMETERS
 | 
			
		||||
{
 | 
			
		||||
	xSemaphoreHandle xSemaphore;
 | 
			
		||||
//	volatile unsigned long *pulSharedVariable;
 | 
			
		||||
	portTickType xBlockTime;
 | 
			
		||||
} xSemaphoreParameters;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//#define RTW_STATUS_TIMEDOUT -110
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define MAX_SEMA_COUNT                      32	/* the maximum count of a semaphore */
 | 
			
		||||
 | 
			
		||||
typedef xSemaphoreHandle                    _Sema;
 | 
			
		||||
typedef xSemaphoreHandle	            _Mutex;
 | 
			
		||||
typedef	u32                                 _Lock;
 | 
			
		||||
typedef struct TIMER_LIST                   _Timer;
 | 
			
		||||
 | 
			
		||||
//typedef unsigned char	                _buffer;
 | 
			
		||||
 | 
			
		||||
typedef unsigned long           _IRQL;
 | 
			
		||||
//typedef	struct net_device *     _nic_hdl;
 | 
			
		||||
typedef xTaskHandle             _THREAD_HDL_;
 | 
			
		||||
typedef VOID                    THREAD_RETURN;
 | 
			
		||||
typedef VOID*                   THREAD_CONTEXT;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef mdelay
 | 
			
		||||
#define mdelay(t)					((t/portTICK_RATE_MS)>0)?(vTaskDelay(t/portTICK_RATE_MS)):(vTaskDelay(1))
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef udelay
 | 
			
		||||
#define udelay(t)					((t/(portTICK_RATE_MS*1000))>0)?vTaskDelay(t/(portTICK_RATE_MS*1000)):(vTaskDelay(1))
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* to delete/start/stop a timer it will send a message to the timer task through a message queue,
 | 
			
		||||
    so we define the max wait time for message sending */
 | 
			
		||||
#define RTL_TIMER_API_MAX_BLOCK_TIME    1000    // unit is ms
 | 
			
		||||
#define RTL_TIMER_API_MAX_BLOCK_TICKS   (RTL_TIMER_API_MAX_BLOCK_TIME/portTICK_RATE_MS)
 | 
			
		||||
 | 
			
		||||
typedef VOID
 | 
			
		||||
(*RTL_TIMER_CALL_BACK)(
 | 
			
		||||
	void    *pContext
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
typedef struct _RTL_TIMER{
 | 
			
		||||
#ifdef PLATFORM_FREERTOS
 | 
			
		||||
    xTimerHandle        TimerHandle; // the timer handle of created FreeRTOS soft-timer
 | 
			
		||||
#endif    
 | 
			
		||||
	RTL_TIMER_CALL_BACK	CallBackFunc; // Callback function of this timer
 | 
			
		||||
	u32                 msPeriod; // The period of this timer
 | 
			
		||||
	void                *Context; // Timer specific context.
 | 
			
		||||
	u8                  isPeriodical;   // is a periodical timer
 | 
			
		||||
	u8                  TimerName[35];  // the Name of timer
 | 
			
		||||
}RTL_TIMER, *PRTL_TIMER;
 | 
			
		||||
 | 
			
		||||
__inline static VOID 
 | 
			
		||||
RtlEnterCritical(VOID)
 | 
			
		||||
{
 | 
			
		||||
	portENTER_CRITICAL();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__inline static VOID 
 | 
			
		||||
RtlExitCritical(VOID)
 | 
			
		||||
{
 | 
			
		||||
	portEXIT_CRITICAL();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__inline static VOID 
 | 
			
		||||
RtlEnterCriticalBh(
 | 
			
		||||
    IN  _Lock *plock, 
 | 
			
		||||
    IN  _IRQL *pirqL
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	SpinLockBh(plock);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__inline static VOID 
 | 
			
		||||
RtlExitCriticalBh(
 | 
			
		||||
    IN  _Lock *plock, 
 | 
			
		||||
    IN  _IRQL *pirqL
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	SpinUnlockBh(plock);
 | 
			
		||||
}
 | 
			
		||||
__inline static u32 
 | 
			
		||||
RtlEnterCriticalMutex(
 | 
			
		||||
    IN  _Mutex *pmutex, 
 | 
			
		||||
    IN  _IRQL *pirqL
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	u32 ret = 0;
 | 
			
		||||
    xSemaphoreTake(*pmutex, portMAX_DELAY);
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
__inline static VOID 
 | 
			
		||||
RtlExitCriticalMutex(
 | 
			
		||||
    IN  _Mutex *pmutex,
 | 
			
		||||
    IN  _IRQL *pirqL
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
    xSemaphoreGive(*pmutex);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__inline static VOID 
 | 
			
		||||
RtlInitTimer(
 | 
			
		||||
    IN  _Timer *ptimer,
 | 
			
		||||
    IN  VOID *Data,
 | 
			
		||||
    IN  VOID (*pfunc)(VOID *),
 | 
			
		||||
    IN  VOID* cntx
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	ptimer->Function = pfunc;
 | 
			
		||||
	ptimer->Data = (unsigned long)cntx;
 | 
			
		||||
	InitTimer(ptimer);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__inline static VOID 
 | 
			
		||||
RtlSetTimer(
 | 
			
		||||
    IN  _Timer *ptimer,
 | 
			
		||||
    IN  u32 delay_time
 | 
			
		||||
)
 | 
			
		||||
{	
 | 
			
		||||
	ModTimer(ptimer , (JIFFIES+(delay_time*RTL_HZ/1000)));	
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__inline static VOID 
 | 
			
		||||
RtlCancelTimer(
 | 
			
		||||
    IN  _Timer *ptimer,
 | 
			
		||||
    IN  u8 *bcancelled
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	DelTimerSync(ptimer); 	
 | 
			
		||||
	*bcancelled=  _TRUE;//TRUE ==1; FALSE==0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__inline static u32 
 | 
			
		||||
RtlSystime2Ms(
 | 
			
		||||
    IN  u32 systime
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	return systime * 1000 / RTL_HZ;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
__inline static u32 
 | 
			
		||||
RtlMs2Systime(
 | 
			
		||||
    IN  u32 ms
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	return ms * RTL_HZ / 1000;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern u8*	RtlZmalloc(u32 sz);
 | 
			
		||||
extern u8*	RtlMalloc(u32 sz);
 | 
			
		||||
extern VOID	RtlMfree(u8 *pbuf, u32 sz);
 | 
			
		||||
 | 
			
		||||
extern VOID* RtlMalloc2d(u32 h, u32 w, u32 size);
 | 
			
		||||
extern VOID	RtlMfree2d(VOID *pbuf, u32 h, u32 w, u32 size);
 | 
			
		||||
 | 
			
		||||
extern VOID	RtlInitSema(_Sema *sema, u32 init_val);
 | 
			
		||||
extern VOID	RtlFreeSema(_Sema	*sema);
 | 
			
		||||
extern VOID	RtlUpSema(_Sema	*sema);
 | 
			
		||||
extern VOID	RtlUpSemaFromISR(_Sema	*sema);
 | 
			
		||||
extern u32	RtlDownSema(_Sema *sema);
 | 
			
		||||
extern u32 RtlDownSemaWithTimeout(_Sema *sema, u32 ms);
 | 
			
		||||
 | 
			
		||||
extern VOID	RtlMutexInit(_Mutex *pmutex);
 | 
			
		||||
extern VOID	RtlMutexFree(_Mutex *pmutex);
 | 
			
		||||
 | 
			
		||||
extern VOID	RtlSpinlockInit(_Lock *plock);
 | 
			
		||||
extern VOID	RtlSpinlockFree(_Lock *plock);
 | 
			
		||||
extern VOID	RtlSpinlock(_Lock	*plock);
 | 
			
		||||
extern VOID	RtlSpinunlock(_Lock	*plock);
 | 
			
		||||
extern VOID	RtlSpinlockEx(_Lock	*plock);
 | 
			
		||||
extern VOID	RtlSpinunlockEx(_Lock	*plock);
 | 
			
		||||
 | 
			
		||||
extern VOID	RtlSleepSchedulable(u32 ms);
 | 
			
		||||
 | 
			
		||||
extern VOID	RtlMsleepOS(u32 ms);
 | 
			
		||||
extern VOID	RtlUsleepOS(u32 us);
 | 
			
		||||
extern VOID RtlMdelayOS(u32 ms);
 | 
			
		||||
extern VOID RtlUdelayOS(u32 us);
 | 
			
		||||
 | 
			
		||||
//extern VOID	rtw_mdelay_os(u32 ms);
 | 
			
		||||
//extern VOID	rtw_udelay_os(u32 us);
 | 
			
		||||
 | 
			
		||||
//1TODO: Need Check if we need add this api
 | 
			
		||||
extern VOID RtlYieldOS(VOID);
 | 
			
		||||
 | 
			
		||||
#define RtlUpMutex(mutex)		RtlUpSema(mutex)
 | 
			
		||||
#define RtlDownMutex(mutex)		RtlDownSema(mutex)
 | 
			
		||||
 | 
			
		||||
__inline static u8 
 | 
			
		||||
RtlCancelTimerEx(
 | 
			
		||||
    IN  _Timer *ptimer
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	DelTimerSync(ptimer);
 | 
			
		||||
	return 0; 
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static __inline VOID 
 | 
			
		||||
ThreadEnter(
 | 
			
		||||
    IN  char *name
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	DBG_8195A("\rRTKTHREAD_enter %s\n", name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define ThreadExit() do{DBG_8195A("\rRTKTHREAD_exit %s\n", __FUNCTION__);}while(0)
 | 
			
		||||
 | 
			
		||||
__inline static VOID 
 | 
			
		||||
FlushSignalsThread(VOID) 
 | 
			
		||||
{
 | 
			
		||||
#ifdef PLATFORM_LINUX
 | 
			
		||||
	if (signal_pending (current)) 
 | 
			
		||||
	{
 | 
			
		||||
		flush_signals(current);
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define RTL_RND(sz, r) ((((sz)+((r)-1))/(r))*(r))
 | 
			
		||||
#define RTL_RND4(x)	(((x >> 2) + (((x & 3) == 0) ?  0: 1)) << 2)
 | 
			
		||||
 | 
			
		||||
__inline static u32 
 | 
			
		||||
RtlRnd4(
 | 
			
		||||
    IN  u32 sz
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	u32	val;
 | 
			
		||||
 | 
			
		||||
	val = ((sz >> 2) + ((sz & 3) ? 1: 0)) << 2;
 | 
			
		||||
	
 | 
			
		||||
	return val;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__inline static u32 
 | 
			
		||||
RtlRnd8(
 | 
			
		||||
    IN  u32 sz
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	u32	val;
 | 
			
		||||
 | 
			
		||||
	val = ((sz >> 3) + ((sz & 7) ? 1: 0)) << 3;
 | 
			
		||||
	
 | 
			
		||||
	return val;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__inline static u32 
 | 
			
		||||
RtlRnd128(
 | 
			
		||||
    IN  u32 sz
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	u32	val;
 | 
			
		||||
 | 
			
		||||
	val = ((sz >> 7) + ((sz & 127) ? 1: 0)) << 7;
 | 
			
		||||
	
 | 
			
		||||
	return val;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__inline 
 | 
			
		||||
static u32 RtlRnd256(
 | 
			
		||||
    IN  u32 sz
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	u32	val;
 | 
			
		||||
 | 
			
		||||
	val = ((sz >> 8) + ((sz & 255) ? 1: 0)) << 8;
 | 
			
		||||
	
 | 
			
		||||
	return val;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__inline static u32 
 | 
			
		||||
RtlRnd512(
 | 
			
		||||
    IN  u32 sz
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	u32	val;
 | 
			
		||||
 | 
			
		||||
	val = ((sz >> 9) + ((sz & 511) ? 1: 0)) << 9;
 | 
			
		||||
	
 | 
			
		||||
	return val;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__inline static u32 
 | 
			
		||||
BitShift(
 | 
			
		||||
    IN  u32 BitMask
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	u32 i;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i <= 31; i++)
 | 
			
		||||
		if (((BitMask>>i) &  0x1) == 1) break;
 | 
			
		||||
 | 
			
		||||
	return i;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//#ifdef __GNUC__
 | 
			
		||||
#ifdef PLATFORM_LINUX
 | 
			
		||||
#define STRUCT_PACKED __attribute__ ((packed))
 | 
			
		||||
#else
 | 
			
		||||
#define STRUCT_PACKED
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//Atomic integer operations
 | 
			
		||||
#define RTL_ATOMIC_T atomic_t
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static inline VOID
 | 
			
		||||
RTL_ATOMIC_SET(
 | 
			
		||||
    IN  RTL_ATOMIC_T *v, 
 | 
			
		||||
    IN  u32 i
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	AtomicSet(i,v);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline uint32_t
 | 
			
		||||
RTL_ATOMIC_READ(
 | 
			
		||||
    IN  RTL_ATOMIC_T *v
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	return AtomicRead(v);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline VOID
 | 
			
		||||
RTL_ATOMIC_ADD(
 | 
			
		||||
    IN  RTL_ATOMIC_T *v, 
 | 
			
		||||
    IN  u32 i
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	AtomicAdd(i,v);
 | 
			
		||||
}
 | 
			
		||||
static inline VOID
 | 
			
		||||
RTL_ATOMIC_SUB(
 | 
			
		||||
    IN  RTL_ATOMIC_T *v, 
 | 
			
		||||
    IN  u32 i
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	AtomicSub(i,v);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline VOID
 | 
			
		||||
RTL_ATOMIC_INC(
 | 
			
		||||
    IN  RTL_ATOMIC_T *v
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	AtomicInc(v);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline VOID
 | 
			
		||||
RTL_ATOMIC_DEC(
 | 
			
		||||
    IN  RTL_ATOMIC_T *v
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	AtomicDec(v);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline u32
 | 
			
		||||
RTL_ATOMIC_ADD_RETURN(
 | 
			
		||||
    IN  RTL_ATOMIC_T *v, 
 | 
			
		||||
    IN  u32 i
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	return AtomicAddReturn(i,v);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline u32
 | 
			
		||||
RTL_ATOMIC_SUB_RETURN(
 | 
			
		||||
    IN  RTL_ATOMIC_T *v, 
 | 
			
		||||
    IN  u32 i
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	return AtomicSubReturn(i,v);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline u32
 | 
			
		||||
RTL_ATOMIC_INC_RETURN(
 | 
			
		||||
    IN  RTL_ATOMIC_T *v
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	return AtomicIncReturn(v);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline u32
 | 
			
		||||
RTL_ATOMIC_DEC_RETURN(
 | 
			
		||||
    IN  RTL_ATOMIC_T *v
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	return AtomicDecReturn(v);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern u64 RtlModular64(u64 x, u64 y);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Macros for handling unaligned memory accesses */
 | 
			
		||||
#if 0
 | 
			
		||||
#define RTW_GET_BE16(a) ((u16) (((a)[0] << 8) | (a)[1]))
 | 
			
		||||
#define RTW_PUT_BE16(a, val)			\
 | 
			
		||||
	do {					\
 | 
			
		||||
		(a)[0] = ((u16) (val)) >> 8;	\
 | 
			
		||||
		(a)[1] = ((u16) (val)) & 0xff;	\
 | 
			
		||||
	} while (0)
 | 
			
		||||
 | 
			
		||||
#define RTW_GET_LE16(a) ((u16) (((a)[1] << 8) | (a)[0]))
 | 
			
		||||
#define RTW_PUT_LE16(a, val)			\
 | 
			
		||||
	do {					\
 | 
			
		||||
		(a)[1] = ((u16) (val)) >> 8;	\
 | 
			
		||||
		(a)[0] = ((u16) (val)) & 0xff;	\
 | 
			
		||||
	} while (0)
 | 
			
		||||
 | 
			
		||||
#define RTW_GET_BE24(a) ((((u32) (a)[0]) << 16) | (((u32) (a)[1]) << 8) | \
 | 
			
		||||
			 ((u32) (a)[2]))			 
 | 
			
		||||
#define RTW_PUT_BE24(a, val)					\
 | 
			
		||||
	do {							\
 | 
			
		||||
		(a)[0] = (u8) ((((u32) (val)) >> 16) & 0xff);	\
 | 
			
		||||
		(a)[1] = (u8) ((((u32) (val)) >> 8) & 0xff);	\
 | 
			
		||||
		(a)[2] = (u8) (((u32) (val)) & 0xff);		\
 | 
			
		||||
	} while (0)
 | 
			
		||||
 | 
			
		||||
#define RTW_GET_BE32(a) ((((u32) (a)[0]) << 24) | (((u32) (a)[1]) << 16) | \
 | 
			
		||||
			 (((u32) (a)[2]) << 8) | ((u32) (a)[3]))			 
 | 
			
		||||
#define RTW_PUT_BE32(a, val)					\
 | 
			
		||||
	do {							\
 | 
			
		||||
		(a)[0] = (u8) ((((u32) (val)) >> 24) & 0xff);	\
 | 
			
		||||
		(a)[1] = (u8) ((((u32) (val)) >> 16) & 0xff);	\
 | 
			
		||||
		(a)[2] = (u8) ((((u32) (val)) >> 8) & 0xff);	\
 | 
			
		||||
		(a)[3] = (u8) (((u32) (val)) & 0xff);		\
 | 
			
		||||
	} while (0)
 | 
			
		||||
 | 
			
		||||
#define RTW_GET_LE32(a) ((((u32) (a)[3]) << 24) | (((u32) (a)[2]) << 16) | \
 | 
			
		||||
			 (((u32) (a)[1]) << 8) | ((u32) (a)[0]))			 
 | 
			
		||||
#define RTW_PUT_LE32(a, val)					\
 | 
			
		||||
	do {							\
 | 
			
		||||
		(a)[3] = (u8) ((((u32) (val)) >> 24) & 0xff);	\
 | 
			
		||||
		(a)[2] = (u8) ((((u32) (val)) >> 16) & 0xff);	\
 | 
			
		||||
		(a)[1] = (u8) ((((u32) (val)) >> 8) & 0xff);	\
 | 
			
		||||
		(a)[0] = (u8) (((u32) (val)) & 0xff);		\
 | 
			
		||||
	} while (0)
 | 
			
		||||
 | 
			
		||||
#define RTW_GET_BE64(a) ((((u64) (a)[0]) << 56) | (((u64) (a)[1]) << 48) | \
 | 
			
		||||
			 (((u64) (a)[2]) << 40) | (((u64) (a)[3]) << 32) | \
 | 
			
		||||
			 (((u64) (a)[4]) << 24) | (((u64) (a)[5]) << 16) | \
 | 
			
		||||
			 (((u64) (a)[6]) << 8) | ((u64) (a)[7]))			 
 | 
			
		||||
#define RTW_PUT_BE64(a, val)				\
 | 
			
		||||
	do {						\
 | 
			
		||||
		(a)[0] = (u8) (((u64) (val)) >> 56);	\
 | 
			
		||||
		(a)[1] = (u8) (((u64) (val)) >> 48);	\
 | 
			
		||||
		(a)[2] = (u8) (((u64) (val)) >> 40);	\
 | 
			
		||||
		(a)[3] = (u8) (((u64) (val)) >> 32);	\
 | 
			
		||||
		(a)[4] = (u8) (((u64) (val)) >> 24);	\
 | 
			
		||||
		(a)[5] = (u8) (((u64) (val)) >> 16);	\
 | 
			
		||||
		(a)[6] = (u8) (((u64) (val)) >> 8);	\
 | 
			
		||||
		(a)[7] = (u8) (((u64) (val)) & 0xff);	\
 | 
			
		||||
	} while (0)
 | 
			
		||||
 | 
			
		||||
#define RTW_GET_LE64(a) ((((u64) (a)[7]) << 56) | (((u64) (a)[6]) << 48) | \
 | 
			
		||||
			 (((u64) (a)[5]) << 40) | (((u64) (a)[4]) << 32) | \
 | 
			
		||||
			 (((u64) (a)[3]) << 24) | (((u64) (a)[2]) << 16) | \
 | 
			
		||||
			 (((u64) (a)[1]) << 8) | ((u64) (a)[0]))
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
extern PRTL_TIMER
 | 
			
		||||
RtlTimerCreate(
 | 
			
		||||
    IN char *pTimerName,
 | 
			
		||||
    IN u32 TimerPeriodMS,
 | 
			
		||||
    IN RTL_TIMER_CALL_BACK CallbckFunc,
 | 
			
		||||
    IN void *pContext,
 | 
			
		||||
    IN u8 isPeriodical
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
extern VOID
 | 
			
		||||
RtlTimerDelete(
 | 
			
		||||
    IN PRTL_TIMER pTimerHdl
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
extern u8
 | 
			
		||||
RtlTimerStart(
 | 
			
		||||
    IN PRTL_TIMER pTimerHdl,
 | 
			
		||||
    IN u8 isFromISR
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
extern u8
 | 
			
		||||
RtlTimerStop(
 | 
			
		||||
    IN PRTL_TIMER pTimerHdl,
 | 
			
		||||
    IN u8 isFromISR
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
extern u8
 | 
			
		||||
RtlTimerReset(
 | 
			
		||||
    IN PRTL_TIMER pTimerHdl,
 | 
			
		||||
    IN u8 isFromISR
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
extern u8
 | 
			
		||||
RtlTimerChangePeriod(
 | 
			
		||||
    IN PRTL_TIMER pTimerHdl,
 | 
			
		||||
    IN u32 NewPeriodMS,
 | 
			
		||||
    IN u8 isFromISR
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
#endif	//#ifndef __OSDEP_API_H_
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										582
									
								
								component/os/os_dep/include/osdep_service.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										582
									
								
								component/os/os_dep/include/osdep_service.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,582 @@
 | 
			
		|||
/******************************************************************************
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
 | 
			
		||||
 *                                        
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify it
 | 
			
		||||
 * under the terms of version 2 of the GNU General Public License as
 | 
			
		||||
 * published by the Free Software Foundation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful, but WITHOUT
 | 
			
		||||
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 | 
			
		||||
 * more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License along with
 | 
			
		||||
 * this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
 | 
			
		||||
 *
 | 
			
		||||
 *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
#ifndef __OSDEP_SERVICE_H_
 | 
			
		||||
#define __OSDEP_SERVICE_H_
 | 
			
		||||
 | 
			
		||||
/* OS dep feature enable */
 | 
			
		||||
#include <autoconf.h>
 | 
			
		||||
 | 
			
		||||
#define CONFIG_LITTLE_ENDIAN
 | 
			
		||||
 | 
			
		||||
#if defined(CONFIG_PLATFORM_8195A) || defined(CONFIG_PLATFORM_8711B)
 | 
			
		||||
#define CONFIG_PLATFORM_AMEBA_X
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(CONFIG_PLATFORM_8195A)
 | 
			
		||||
	#define CONFIG_USE_TCM_HEAP 1					/* USE TCM HEAP */
 | 
			
		||||
	#define USE_MUTEX_FOR_SPINLOCK	1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(CONFIG_PLATFORM_AMEBA_X)
 | 
			
		||||
	#define CONFIG_MEM_MONITOR	MEM_MONITOR_SIMPLE
 | 
			
		||||
#else
 | 
			
		||||
	#define CONFIG_MEM_MONITOR	MEM_MONITOR_LEAK
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Define compilor specific symbol */
 | 
			
		||||
//
 | 
			
		||||
// inline function
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#if defined ( __ICCARM__ )
 | 
			
		||||
#define __inline__                      inline
 | 
			
		||||
#define __inline                        inline
 | 
			
		||||
#define __inline_definition			//In dialect C99, inline means that a function's definition is provided 
 | 
			
		||||
								//only for inlining, and that there is another definition 
 | 
			
		||||
								//(without inline) somewhere else in the program. 
 | 
			
		||||
								//That means that this program is incomplete, because if 
 | 
			
		||||
								//add isn't inlined (for example, when compiling without optimization), 
 | 
			
		||||
								//then main will have an unresolved reference to that other definition.
 | 
			
		||||
 | 
			
		||||
								// Do not inline function is the function body is defined .c file and this 
 | 
			
		||||
								// function will be called somewhere else, otherwise there is compile error
 | 
			
		||||
#elif defined ( __CC_ARM   )
 | 
			
		||||
#define __inline__			__inline	//__linine__ is not supported in keil compilor, use __inline instead
 | 
			
		||||
#define inline				__inline
 | 
			
		||||
#define __inline_definition			// for dialect C99
 | 
			
		||||
#elif defined   (  __GNUC__  )
 | 
			
		||||
#define __inline__                      inline
 | 
			
		||||
#define __inline                        inline
 | 
			
		||||
#define __inline_definition	inline
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#if defined(CONFIG_PLATFORM_8195A) || defined(CONFIG_PLATFORM_8711B)
 | 
			
		||||
#include "platform_autoconf.h"
 | 
			
		||||
#else
 | 
			
		||||
#ifndef SUCCESS
 | 
			
		||||
#define SUCCESS	0
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef FAIL
 | 
			
		||||
#define FAIL	(-1)
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef _SUCCESS
 | 
			
		||||
#define _SUCCESS	1
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef _FAIL
 | 
			
		||||
#define _FAIL	0
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef FALSE		
 | 
			
		||||
    #define FALSE   0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef TRUE
 | 
			
		||||
    #define TRUE    (!FALSE)
 | 
			
		||||
#endif
 | 
			
		||||
		
 | 
			
		||||
#define _TRUE        TRUE	
 | 
			
		||||
#define _FALSE	     FALSE	
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined( PLATFORM_FREERTOS)
 | 
			
		||||
#include "freertos_service.h"
 | 
			
		||||
#elif defined( PLATFORM_ECOS)
 | 
			
		||||
#include "ecos/ecos_service.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define RTW_MAX_DELAY			0xFFFFFFFF
 | 
			
		||||
#define RTW_WAIT_FOREVER		0xFFFFFFFF
 | 
			
		||||
 | 
			
		||||
/* Definitions returned by xTaskGetSchedulerState(). */
 | 
			
		||||
#define OS_SCHEDULER_NOT_STARTED	0
 | 
			
		||||
#define OS_SCHEDULER_RUNNING		1
 | 
			
		||||
#define OS_SCHEDULER_SUSPENDED		2
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct timer_list {
 | 
			
		||||
	_timerHandle 	timer_hdl;
 | 
			
		||||
	unsigned long	data;
 | 
			
		||||
	void (*function)(void *);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef thread_return (*thread_func_t)(thread_context context);
 | 
			
		||||
typedef void (*TIMER_FUN)(void *context);
 | 
			
		||||
typedef int (*event_handler_t)(char *buf, int buf_len, int flags, void *user_data);
 | 
			
		||||
 | 
			
		||||
#define CONFIG_THREAD_COMM_SEMA
 | 
			
		||||
struct task_struct {
 | 
			
		||||
	const char *task_name;
 | 
			
		||||
	_thread_hdl_ task; /* I: workqueue thread */
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_THREAD_COMM_SIGNAL
 | 
			
		||||
	const char *name;		/* I: workqueue thread name */
 | 
			
		||||
	u32 queue_num; /* total signal num */
 | 
			
		||||
	u32 cur_queue_num; /* cur signal num should < queue_num */
 | 
			
		||||
#elif defined(CONFIG_THREAD_COMM_SEMA)
 | 
			
		||||
	_sema wakeup_sema;
 | 
			
		||||
	_sema terminate_sema;
 | 
			
		||||
//	_queue work_queue;  //TODO
 | 
			
		||||
#endif
 | 
			
		||||
	u32 blocked; 
 | 
			
		||||
	u32 callback_running;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
	_xqueue event_queue;
 | 
			
		||||
	struct task_struct thread;
 | 
			
		||||
}rtw_worker_thread_t;
 | 
			
		||||
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
	event_handler_t function;
 | 
			
		||||
	char *buf;
 | 
			
		||||
	int buf_len;
 | 
			
		||||
	int flags;
 | 
			
		||||
	void *user_data;
 | 
			
		||||
} rtw_event_message_t;
 | 
			
		||||
 | 
			
		||||
struct worker_timer_entry {
 | 
			
		||||
	struct list_head 	list;
 | 
			
		||||
	_timerHandle 		timer_hdl;
 | 
			
		||||
	rtw_event_message_t	message;
 | 
			
		||||
	rtw_worker_thread_t	*worker_thread;
 | 
			
		||||
	u32 				timeout; 
 | 
			
		||||
};
 | 
			
		||||
#ifdef CONFIG_THREAD_COMM_SIGNAL
 | 
			
		||||
struct work_struct;
 | 
			
		||||
typedef void (*work_func_t)(void *context);
 | 
			
		||||
struct work_struct {
 | 
			
		||||
	_list list;
 | 
			
		||||
	u32 data;
 | 
			
		||||
	work_func_t func;
 | 
			
		||||
	void *context;
 | 
			
		||||
	struct task_struct *used_wq; 
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct delayed_work {
 | 
			
		||||
	struct work_struct work;
 | 
			
		||||
	struct timer_list timer;
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_MEM_MONITOR
 | 
			
		||||
//----- ------------------------------------------------------------------
 | 
			
		||||
// Memory Monitor
 | 
			
		||||
//----- ------------------------------------------------------------------
 | 
			
		||||
#define MEM_MONITOR_SIMPLE		0x1
 | 
			
		||||
#define MEM_MONITOR_LEAK		0x2
 | 
			
		||||
 | 
			
		||||
#define MEM_MONITOR_FLAG_WIFI_DRV	0x1
 | 
			
		||||
#define MEM_MONITOR_FLAG_WPAS		0x2
 | 
			
		||||
#if CONFIG_MEM_MONITOR & MEM_MONITOR_LEAK
 | 
			
		||||
struct mem_entry {
 | 
			
		||||
	struct list_head	list;
 | 
			
		||||
	int			size;
 | 
			
		||||
	void			*ptr;
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void init_mem_monitor(_list *pmem_table, int *used_num);
 | 
			
		||||
void deinit_mem_monitor(_list *pmem_table, int *used_num);
 | 
			
		||||
void add_mem_usage(_list *pmem_table, void *ptr, int size, int *used_num, int flag);
 | 
			
		||||
void del_mem_usage(_list *pmem_table, void *ptr, int *used_num, int flag);
 | 
			
		||||
int get_mem_usage(_list *pmem_table);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*********************************** OSDEP API *****************************************/
 | 
			
		||||
u8*	_rtw_vmalloc(u32 sz);
 | 
			
		||||
u8*	_rtw_zvmalloc(u32 sz);
 | 
			
		||||
void	_rtw_vmfree(u8 *pbuf, u32 sz);
 | 
			
		||||
u8*	_rtw_zmalloc(u32 sz);
 | 
			
		||||
u8*	_rtw_malloc(u32 sz);
 | 
			
		||||
void	_rtw_mfree(u8 *pbuf, u32 sz);
 | 
			
		||||
#ifdef CONFIG_MEM_MONITOR
 | 
			
		||||
u8*	rtw_vmalloc(u32 sz);
 | 
			
		||||
u8*	rtw_zvmalloc(u32 sz);
 | 
			
		||||
void	rtw_vmfree(u8 *pbuf, u32 sz);
 | 
			
		||||
u8*	rtw_zmalloc(u32 sz);
 | 
			
		||||
u8*	rtw_malloc(u32 sz);
 | 
			
		||||
void	rtw_mfree(u8 *pbuf, u32 sz);
 | 
			
		||||
#else
 | 
			
		||||
#define	rtw_vmalloc		_rtw_vmalloc
 | 
			
		||||
#define	rtw_zvmalloc		_rtw_zvmalloc
 | 
			
		||||
#define	rtw_vmfree  		_rtw_vmfree
 | 
			
		||||
#define	rtw_zmalloc 		_rtw_zmalloc
 | 
			
		||||
#define	rtw_malloc  		_rtw_malloc
 | 
			
		||||
#define	rtw_mfree   		_rtw_mfree
 | 
			
		||||
#endif
 | 
			
		||||
#define rtw_free(buf)		rtw_mfree((u8 *)buf, 0)
 | 
			
		||||
void*	rtw_malloc2d(int h, int w, int size);
 | 
			
		||||
void	rtw_mfree2d(void *pbuf, int h, int w, int size);
 | 
			
		||||
void	rtw_memcpy(void* dst, void* src, u32 sz);
 | 
			
		||||
int	rtw_memcmp(void *dst, void *src, u32 sz);
 | 
			
		||||
void	rtw_memset(void *pbuf, int c, u32 sz);
 | 
			
		||||
 | 
			
		||||
void	rtw_init_listhead(_list *list);
 | 
			
		||||
u32	rtw_is_list_empty(_list *phead);
 | 
			
		||||
void	rtw_list_insert_head(_list *plist, _list *phead);
 | 
			
		||||
void	rtw_list_insert_tail(_list *plist, _list *phead);
 | 
			
		||||
void	rtw_list_delete(_list *plist);
 | 
			
		||||
 | 
			
		||||
void	rtw_init_sema(_sema *sema, int init_val);
 | 
			
		||||
void	rtw_free_sema(_sema	*sema);
 | 
			
		||||
void	rtw_up_sema(_sema	*sema);
 | 
			
		||||
void	rtw_up_sema_from_isr(_sema	*sema);
 | 
			
		||||
u32	rtw_down_sema(_sema *sema);
 | 
			
		||||
u32	rtw_down_timeout_sema(_sema *sema, u32 timeout);
 | 
			
		||||
void	rtw_mutex_init(_mutex *pmutex);
 | 
			
		||||
void	rtw_mutex_free(_mutex *pmutex);
 | 
			
		||||
void	rtw_mutex_put(_mutex *pmutex);
 | 
			
		||||
void	rtw_mutex_get(_mutex *pmutex);
 | 
			
		||||
int		rtw_mutex_get_timeout(_mutex *pmutex, u32 timeout_ms);
 | 
			
		||||
void	rtw_enter_critical(_lock *plock, _irqL *pirqL);
 | 
			
		||||
void	rtw_exit_critical(_lock *plock, _irqL *pirqL);
 | 
			
		||||
void	rtw_enter_critical_from_isr(_lock *plock, _irqL *pirqL);
 | 
			
		||||
void	rtw_exit_critical_from_isr(_lock *plock, _irqL *pirqL);
 | 
			
		||||
void	rtw_enter_critical_bh(_lock *plock, _irqL *pirqL);
 | 
			
		||||
void	rtw_exit_critical_bh(_lock *plock, _irqL *pirqL);
 | 
			
		||||
int	rtw_enter_critical_mutex(_mutex *pmutex, _irqL *pirqL);
 | 
			
		||||
void	rtw_exit_critical_mutex(_mutex *pmutex, _irqL *pirqL);
 | 
			
		||||
void	rtw_spinlock_init(_lock *plock);
 | 
			
		||||
void	rtw_spinlock_free(_lock *plock);
 | 
			
		||||
void	rtw_spinlock_init(_lock *plock);
 | 
			
		||||
void	rtw_spinlock_free(_lock *plock);
 | 
			
		||||
void	rtw_spin_lock(_lock *plock);
 | 
			
		||||
void	rtw_spin_unlock(_lock *plock);
 | 
			
		||||
void	rtw_spinlock_irqsave(_lock *plock, _irqL *irqL);
 | 
			
		||||
void	rtw_spinunlock_irqsave(_lock *plock, _irqL *irqL);
 | 
			
		||||
 | 
			
		||||
int rtw_init_xqueue( _xqueue* queue, const char* name, u32 message_size, u32 number_of_messages );
 | 
			
		||||
int rtw_push_to_xqueue( _xqueue* queue, void* message, u32 timeout_ms );
 | 
			
		||||
int rtw_pop_from_xqueue( _xqueue* queue, void* message, u32 timeout_ms );
 | 
			
		||||
int rtw_deinit_xqueue( _xqueue* queue );
 | 
			
		||||
 | 
			
		||||
void	rtw_init_queue(_queue	*pqueue);
 | 
			
		||||
void	rtw_deinit_queue(_queue	*pqueue);
 | 
			
		||||
u32	rtw_is_queue_empty(_queue *pqueue);
 | 
			
		||||
u32	rtw_queue_empty(_queue	*pqueue);
 | 
			
		||||
u32	rtw_end_of_queue_search(_list *queue, _list *pelement);
 | 
			
		||||
_list* rtw_get_queue_head(_queue	*queue);
 | 
			
		||||
 | 
			
		||||
u32	rtw_get_current_time(void);
 | 
			
		||||
u32	rtw_systime_to_ms(u32 systime);
 | 
			
		||||
u32 rtw_systime_to_sec(u32 systime);
 | 
			
		||||
u32	rtw_ms_to_systime(u32 ms);
 | 
			
		||||
u32	rtw_sec_to_systime(u32 sec);
 | 
			
		||||
s32	rtw_get_passing_time_ms(u32 start);
 | 
			
		||||
s32	rtw_get_time_interval_ms(u32 start, u32 end);
 | 
			
		||||
 | 
			
		||||
void	rtw_msleep_os(int ms);
 | 
			
		||||
void	rtw_usleep_os(int us);
 | 
			
		||||
u32 	rtw_atoi(u8* s);
 | 
			
		||||
void	rtw_mdelay_os(int ms);
 | 
			
		||||
void	rtw_udelay_os(int us);
 | 
			
		||||
void	rtw_yield_os(void);
 | 
			
		||||
 | 
			
		||||
//Atomic integer operations
 | 
			
		||||
void 	ATOMIC_SET(ATOMIC_T *v, int i);
 | 
			
		||||
int		ATOMIC_READ(ATOMIC_T *v);
 | 
			
		||||
void 	ATOMIC_ADD(ATOMIC_T *v, int i);
 | 
			
		||||
void 	ATOMIC_SUB(ATOMIC_T *v, int i);
 | 
			
		||||
void 	ATOMIC_INC(ATOMIC_T *v);
 | 
			
		||||
void 	ATOMIC_DEC(ATOMIC_T *v);
 | 
			
		||||
int 	ATOMIC_ADD_RETURN(ATOMIC_T *v, int i);
 | 
			
		||||
int 	ATOMIC_SUB_RETURN(ATOMIC_T *v, int i);
 | 
			
		||||
int 	ATOMIC_INC_RETURN(ATOMIC_T *v);
 | 
			
		||||
int 	ATOMIC_DEC_RETURN(ATOMIC_T *v);
 | 
			
		||||
int ATOMIC_DEC_AND_TEST(ATOMIC_T *v);
 | 
			
		||||
 | 
			
		||||
u64	rtw_modular64(u64 x, u64 y);
 | 
			
		||||
int	rtw_get_random_bytes(void* dst, u32 size);
 | 
			
		||||
u32	rtw_getFreeHeapSize(void);
 | 
			
		||||
void	flush_signals_thread(void);
 | 
			
		||||
 | 
			
		||||
void	rtw_acquire_wakelock(void);
 | 
			
		||||
void	rtw_release_wakelock(void);
 | 
			
		||||
 | 
			
		||||
/*********************************** Thread related *****************************************/
 | 
			
		||||
int	rtw_create_task(struct task_struct *task, const char *name, u32  stack_size, u32 priority, thread_func_t func, void *thctx);
 | 
			
		||||
void rtw_delete_task(struct task_struct * task);
 | 
			
		||||
void rtw_wakeup_task(struct task_struct *task);
 | 
			
		||||
int rtw_create_worker_thread( rtw_worker_thread_t* worker_thread, u8 priority, u32 stack_size, u32 event_queue_size );
 | 
			
		||||
int rtw_delete_worker_thread( rtw_worker_thread_t* worker_thread );
 | 
			
		||||
 | 
			
		||||
#if 0 //TODO
 | 
			
		||||
void	rtw_init_delayed_work(struct delayed_work *dwork, work_func_t func, const char *name);
 | 
			
		||||
void	rtw_deinit_delayed_work(struct delayed_work *dwork);
 | 
			
		||||
int		rtw_queue_delayed_work(struct workqueue_struct *wq, struct delayed_work *dwork, u32 delay, void* context);
 | 
			
		||||
BOOLEAN rtw_cancel_delayed_work(struct delayed_work *dwork);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void	rtw_thread_enter(char *name);
 | 
			
		||||
void	rtw_thread_exit(void);
 | 
			
		||||
u8		rtw_get_scheduler_state(void);
 | 
			
		||||
 | 
			
		||||
#ifdef PLATFORM_LINUX
 | 
			
		||||
#define rtw_warn_on(condition) WARN_ON(condition)
 | 
			
		||||
#else
 | 
			
		||||
#define rtw_warn_on(condition) do {} while (0)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*********************************** Timer related *****************************************/
 | 
			
		||||
_timerHandle rtw_timerCreate( const signed char *pcTimerName, 
 | 
			
		||||
							  osdepTickType xTimerPeriodInTicks, 
 | 
			
		||||
							  u32 uxAutoReload, 
 | 
			
		||||
							  void * pvTimerID, 
 | 
			
		||||
							  TIMER_FUN pxCallbackFunction );
 | 
			
		||||
u32 rtw_timerDelete( _timerHandle xTimer, 
 | 
			
		||||
							   osdepTickType xBlockTime );
 | 
			
		||||
u32 rtw_timerIsTimerActive( _timerHandle xTimer );
 | 
			
		||||
u32 rtw_timerStop( _timerHandle xTimer, 
 | 
			
		||||
							   osdepTickType xBlockTime );
 | 
			
		||||
u32 rtw_timerChangePeriod( _timerHandle xTimer, 
 | 
			
		||||
							   osdepTickType xNewPeriod, 
 | 
			
		||||
							   osdepTickType xBlockTime );
 | 
			
		||||
 | 
			
		||||
/*********************************** OSDEP API end *****************************************/
 | 
			
		||||
#define LIST_CONTAINOR(ptr, type, member) \
 | 
			
		||||
	((type *)((char *)(ptr)-(SIZE_T)((char *)&((type *)ptr)->member - (char *)ptr)))
 | 
			
		||||
 | 
			
		||||
#define time_after(a,b)	((long)(b) - (long)(a) < 0)
 | 
			
		||||
#define time_before(a,b)	time_after(b,a)
 | 
			
		||||
#define time_after_eq(a,b)	((long)(a) - (long)(b) >= 0)
 | 
			
		||||
#define time_before_eq(a,b)	time_after_eq(b,a)
 | 
			
		||||
	
 | 
			
		||||
#define _RND(sz, r) ((((sz)+((r)-1))/(r))*(r))
 | 
			
		||||
#define RND4(x)	(((x >> 2) + (((x & 3) == 0) ?  0: 1)) << 2)
 | 
			
		||||
 | 
			
		||||
__inline static u32 _RND4(u32 sz)
 | 
			
		||||
{
 | 
			
		||||
	u32	val;
 | 
			
		||||
 | 
			
		||||
	val = ((sz >> 2) + ((sz & 3) ? 1: 0)) << 2;
 | 
			
		||||
	
 | 
			
		||||
	return val;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__inline static u32 _RND8(u32 sz)
 | 
			
		||||
{
 | 
			
		||||
	u32	val;
 | 
			
		||||
 | 
			
		||||
	val = ((sz >> 3) + ((sz & 7) ? 1: 0)) << 3;
 | 
			
		||||
	
 | 
			
		||||
	return val;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__inline static u32 _RND128(u32 sz)
 | 
			
		||||
{
 | 
			
		||||
	u32	val;
 | 
			
		||||
 | 
			
		||||
	val = ((sz >> 7) + ((sz & 127) ? 1: 0)) << 7;
 | 
			
		||||
	
 | 
			
		||||
	return val;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__inline static u32 _RND256(u32 sz)
 | 
			
		||||
{
 | 
			
		||||
	u32	val;
 | 
			
		||||
 | 
			
		||||
	val = ((sz >> 8) + ((sz & 255) ? 1: 0)) << 8;
 | 
			
		||||
	
 | 
			
		||||
	return val;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__inline static u32 _RND512(u32 sz)
 | 
			
		||||
{
 | 
			
		||||
	u32	val;
 | 
			
		||||
 | 
			
		||||
	val = ((sz >> 9) + ((sz & 511) ? 1: 0)) << 9;
 | 
			
		||||
	
 | 
			
		||||
	return val;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__inline static u32 bitshift(u32 bitmask)
 | 
			
		||||
{
 | 
			
		||||
	u32 i;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i <= 31; i++)
 | 
			
		||||
		if (((bitmask>>i) &  0x1) == 1) break;
 | 
			
		||||
 | 
			
		||||
	return i;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Macros for handling unaligned memory accesses */
 | 
			
		||||
 | 
			
		||||
#define RTW_GET_BE16(a) ((u16) (((a)[0] << 8) | (a)[1]))
 | 
			
		||||
#define RTW_PUT_BE16(a, val)			\
 | 
			
		||||
	do {					\
 | 
			
		||||
		(a)[0] = ((u16) (val)) >> 8;	\
 | 
			
		||||
		(a)[1] = ((u16) (val)) & 0xff;	\
 | 
			
		||||
	} while (0)
 | 
			
		||||
 | 
			
		||||
#define RTW_GET_LE16(a) ((u16) (((a)[1] << 8) | (a)[0]))
 | 
			
		||||
#define RTW_PUT_LE16(a, val)			\
 | 
			
		||||
	do {					\
 | 
			
		||||
		(a)[1] = ((u16) (val)) >> 8;	\
 | 
			
		||||
		(a)[0] = ((u16) (val)) & 0xff;	\
 | 
			
		||||
	} while (0)
 | 
			
		||||
 | 
			
		||||
#define RTW_GET_BE24(a) ((((u32) (a)[0]) << 16) | (((u32) (a)[1]) << 8) | \
 | 
			
		||||
			 ((u32) (a)[2]))			 
 | 
			
		||||
#define RTW_PUT_BE24(a, val)					\
 | 
			
		||||
	do {							\
 | 
			
		||||
		(a)[0] = (u8) ((((u32) (val)) >> 16) & 0xff);	\
 | 
			
		||||
		(a)[1] = (u8) ((((u32) (val)) >> 8) & 0xff);	\
 | 
			
		||||
		(a)[2] = (u8) (((u32) (val)) & 0xff);		\
 | 
			
		||||
	} while (0)
 | 
			
		||||
 | 
			
		||||
#define RTW_GET_BE32(a) ((((u32) (a)[0]) << 24) | (((u32) (a)[1]) << 16) | \
 | 
			
		||||
			 (((u32) (a)[2]) << 8) | ((u32) (a)[3]))			 
 | 
			
		||||
#define RTW_PUT_BE32(a, val)					\
 | 
			
		||||
	do {							\
 | 
			
		||||
		(a)[0] = (u8) ((((u32) (val)) >> 24) & 0xff);	\
 | 
			
		||||
		(a)[1] = (u8) ((((u32) (val)) >> 16) & 0xff);	\
 | 
			
		||||
		(a)[2] = (u8) ((((u32) (val)) >> 8) & 0xff);	\
 | 
			
		||||
		(a)[3] = (u8) (((u32) (val)) & 0xff);		\
 | 
			
		||||
	} while (0)
 | 
			
		||||
 | 
			
		||||
#define RTW_GET_LE32(a) ((((u32) (a)[3]) << 24) | (((u32) (a)[2]) << 16) | \
 | 
			
		||||
			 (((u32) (a)[1]) << 8) | ((u32) (a)[0]))			 
 | 
			
		||||
#define RTW_PUT_LE32(a, val)					\
 | 
			
		||||
	do {							\
 | 
			
		||||
		(a)[3] = (u8) ((((u32) (val)) >> 24) & 0xff);	\
 | 
			
		||||
		(a)[2] = (u8) ((((u32) (val)) >> 16) & 0xff);	\
 | 
			
		||||
		(a)[1] = (u8) ((((u32) (val)) >> 8) & 0xff);	\
 | 
			
		||||
		(a)[0] = (u8) (((u32) (val)) & 0xff);		\
 | 
			
		||||
	} while (0)
 | 
			
		||||
 | 
			
		||||
#define RTW_GET_BE64(a) ((((u64) (a)[0]) << 56) | (((u64) (a)[1]) << 48) | \
 | 
			
		||||
			 (((u64) (a)[2]) << 40) | (((u64) (a)[3]) << 32) | \
 | 
			
		||||
			 (((u64) (a)[4]) << 24) | (((u64) (a)[5]) << 16) | \
 | 
			
		||||
			 (((u64) (a)[6]) << 8) | ((u64) (a)[7]))			 
 | 
			
		||||
#define RTW_PUT_BE64(a, val)				\
 | 
			
		||||
	do {						\
 | 
			
		||||
		(a)[0] = (u8) (((u64) (val)) >> 56);	\
 | 
			
		||||
		(a)[1] = (u8) (((u64) (val)) >> 48);	\
 | 
			
		||||
		(a)[2] = (u8) (((u64) (val)) >> 40);	\
 | 
			
		||||
		(a)[3] = (u8) (((u64) (val)) >> 32);	\
 | 
			
		||||
		(a)[4] = (u8) (((u64) (val)) >> 24);	\
 | 
			
		||||
		(a)[5] = (u8) (((u64) (val)) >> 16);	\
 | 
			
		||||
		(a)[6] = (u8) (((u64) (val)) >> 8);	\
 | 
			
		||||
		(a)[7] = (u8) (((u64) (val)) & 0xff);	\
 | 
			
		||||
	} while (0)
 | 
			
		||||
 | 
			
		||||
#define RTW_GET_LE64(a) ((((u64) (a)[7]) << 56) | (((u64) (a)[6]) << 48) | \
 | 
			
		||||
			 (((u64) (a)[5]) << 40) | (((u64) (a)[4]) << 32) | \
 | 
			
		||||
			 (((u64) (a)[3]) << 24) | (((u64) (a)[2]) << 16) | \
 | 
			
		||||
			 (((u64) (a)[1]) << 8) | ((u64) (a)[0]))
 | 
			
		||||
 | 
			
		||||
struct osdep_service_ops {
 | 
			
		||||
	u8* (*rtw_vmalloc)(u32 sz);
 | 
			
		||||
	u8* (*rtw_zvmalloc)(u32 sz);
 | 
			
		||||
	void (*rtw_vmfree)(u8 *pbuf, u32 sz);
 | 
			
		||||
	u8* (*rtw_malloc)(u32 sz);
 | 
			
		||||
	u8* (*rtw_zmalloc)(u32 sz);
 | 
			
		||||
	void (*rtw_mfree)(u8 *pbuf, u32 sz);
 | 
			
		||||
	void (*rtw_memcpy)(void* dst, void* src, u32 sz);
 | 
			
		||||
	int (*rtw_memcmp)(void *dst, void *src, u32 sz);
 | 
			
		||||
	void (*rtw_memset)(void *pbuf, int c, u32 sz);
 | 
			
		||||
	void (*rtw_init_sema)(_sema *sema, int init_val);
 | 
			
		||||
	void (*rtw_free_sema)(_sema *sema);
 | 
			
		||||
	void (*rtw_up_sema)(_sema *sema);
 | 
			
		||||
	void (*rtw_up_sema_from_isr)(_sema *sema);
 | 
			
		||||
	u32 (*rtw_down_timeout_sema)(_sema *sema, u32 timeout);
 | 
			
		||||
	void (*rtw_mutex_init)(_mutex *pmutex);
 | 
			
		||||
	void (*rtw_mutex_free)(_mutex *pmutex);
 | 
			
		||||
	void (*rtw_mutex_get)(_mutex *pmutex);
 | 
			
		||||
	int (*rtw_mutex_get_timeout)(_mutex *pmutex, u32 timeout_ms);
 | 
			
		||||
	void (*rtw_mutex_put)(_mutex *pmutex);
 | 
			
		||||
	void (*rtw_enter_critical)(_lock *plock, _irqL *pirqL);
 | 
			
		||||
	void (*rtw_exit_critical)(_lock *plock, _irqL *pirqL);
 | 
			
		||||
	void (*rtw_enter_critical_from_isr)(_lock *plock, _irqL *pirqL);
 | 
			
		||||
	void (*rtw_exit_critical_from_isr)(_lock *plock, _irqL *pirqL);
 | 
			
		||||
	void (*rtw_enter_critical_bh)(_lock *plock, _irqL *pirqL);
 | 
			
		||||
	void (*rtw_exit_critical_bh)(_lock *plock, _irqL *pirqL);
 | 
			
		||||
	int (*rtw_enter_critical_mutex)(_mutex *pmutex, _irqL *pirqL);
 | 
			
		||||
	void (*rtw_exit_critical_mutex)(_mutex *pmutex, _irqL *pirqL);
 | 
			
		||||
	void (*rtw_spinlock_init)(_lock *plock);
 | 
			
		||||
	void (*rtw_spinlock_free)(_lock *plock);
 | 
			
		||||
	void (*rtw_spin_lock)(_lock *plock);
 | 
			
		||||
	void (*rtw_spin_unlock)(_lock *plock);
 | 
			
		||||
	void (*rtw_spinlock_irqsave)(_lock *plock, _irqL *irqL);
 | 
			
		||||
	void (*rtw_spinunlock_irqsave)(_lock *plock, _irqL *irqL);
 | 
			
		||||
	int (*rtw_init_xqueue)( _xqueue* queue, const char* name, u32 message_size, u32 number_of_messages );
 | 
			
		||||
	int (*rtw_push_to_xqueue)( _xqueue* queue, void* message, u32 timeout_ms );
 | 
			
		||||
	int (*rtw_pop_from_xqueue)( _xqueue* queue, void* message, u32 timeout_ms );
 | 
			
		||||
	int (*rtw_deinit_xqueue)( _xqueue* queue );
 | 
			
		||||
	u32	(*rtw_get_current_time)(void);
 | 
			
		||||
	u32 (*rtw_systime_to_ms)(u32 systime);
 | 
			
		||||
	u32 (*rtw_systime_to_sec)(u32 systime);
 | 
			
		||||
	u32 (*rtw_ms_to_systime)(u32 ms);
 | 
			
		||||
	u32	(*rtw_sec_to_systime)(u32 sec);
 | 
			
		||||
	void (*rtw_msleep_os)(int ms);
 | 
			
		||||
	void (*rtw_usleep_os)(int us);
 | 
			
		||||
	void (*rtw_mdelay_os)(int ms);
 | 
			
		||||
	void (*rtw_udelay_os)(int us);
 | 
			
		||||
	void (*rtw_yield_os)(void);
 | 
			
		||||
	void (*ATOMIC_SET)(ATOMIC_T *v, int i);
 | 
			
		||||
	int (*ATOMIC_READ)(ATOMIC_T *v);
 | 
			
		||||
	void (*ATOMIC_ADD)(ATOMIC_T *v, int i);
 | 
			
		||||
	void (*ATOMIC_SUB)(ATOMIC_T *v, int i);
 | 
			
		||||
	void (*ATOMIC_INC)(ATOMIC_T *v);
 | 
			
		||||
	void (*ATOMIC_DEC)(ATOMIC_T *v);
 | 
			
		||||
	int (*ATOMIC_ADD_RETURN)(ATOMIC_T *v, int i);
 | 
			
		||||
	int (*ATOMIC_SUB_RETURN)(ATOMIC_T *v, int i);
 | 
			
		||||
	int (*ATOMIC_INC_RETURN)(ATOMIC_T *v);
 | 
			
		||||
	int (*ATOMIC_DEC_RETURN)(ATOMIC_T *v);
 | 
			
		||||
	u64 (*rtw_modular64)(u64 x, u64 y);
 | 
			
		||||
	int (*rtw_get_random_bytes)(void* dst, u32 size);
 | 
			
		||||
	u32 (*rtw_getFreeHeapSize)(void);
 | 
			
		||||
	int (*rtw_create_task)(struct task_struct *task, const char *name, u32 stack_size, u32 priority, thread_func_t func, void *thctx);
 | 
			
		||||
	void (*rtw_delete_task)(struct task_struct *task);
 | 
			
		||||
	void (*rtw_wakeup_task)(struct task_struct *task);
 | 
			
		||||
	
 | 
			
		||||
#if 0	//TODO
 | 
			
		||||
	void (*rtw_init_delayed_work)(struct delayed_work *dwork, work_func_t func, const char *name);
 | 
			
		||||
	void (*rtw_deinit_delayed_work)(struct delayed_work *dwork);
 | 
			
		||||
	int (*rtw_queue_delayed_work)(struct workqueue_struct *wq, struct delayed_work *dwork, unsigned long delay, void* context);
 | 
			
		||||
	BOOLEAN (*rtw_cancel_delayed_work)(struct delayed_work *dwork);
 | 
			
		||||
#endif	
 | 
			
		||||
	void (*rtw_thread_enter)(char *name);
 | 
			
		||||
	void (*rtw_thread_exit)(void);
 | 
			
		||||
	_timerHandle (*rtw_timerCreate)( const signed char *pcTimerName, 
 | 
			
		||||
							  osdepTickType xTimerPeriodInTicks, 
 | 
			
		||||
							  u32 uxAutoReload, 
 | 
			
		||||
							  void * pvTimerID, 
 | 
			
		||||
							  TIMER_FUN pxCallbackFunction );
 | 
			
		||||
	u32 (*rtw_timerDelete)( _timerHandle xTimer, 
 | 
			
		||||
							   osdepTickType xBlockTime );
 | 
			
		||||
	u32 (*rtw_timerIsTimerActive)( _timerHandle xTimer );
 | 
			
		||||
	u32 (*rtw_timerStop)( _timerHandle xTimer, 
 | 
			
		||||
							   osdepTickType xBlockTime );
 | 
			
		||||
	u32 (*rtw_timerChangePeriod)( _timerHandle xTimer, 
 | 
			
		||||
							   osdepTickType xNewPeriod, 
 | 
			
		||||
							   osdepTickType xBlockTime );
 | 
			
		||||
 | 
			
		||||
	void (*rtw_acquire_wakelock)(void);
 | 
			
		||||
	void (*rtw_release_wakelock)(void);
 | 
			
		||||
 | 
			
		||||
	u8 (*rtw_get_scheduler_state)(void);
 | 
			
		||||
};
 | 
			
		||||
/*********************************** OSDEP API end *****************************************/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif	//#ifndef __OSDEP_SERVICE_H_
 | 
			
		||||
							
								
								
									
										66
									
								
								component/os/os_dep/include/tcm_heap.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								component/os/os_dep/include/tcm_heap.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,66 @@
 | 
			
		|||
#ifndef STRUCT_HEAP_H
 | 
			
		||||
#define STRUCT_HEAP_H
 | 
			
		||||
 | 
			
		||||
//#include <stdio.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <osdep_service.h>
 | 
			
		||||
 | 
			
		||||
/* NOTE: struct size must be a 2's power! */
 | 
			
		||||
typedef struct _MemChunk
 | 
			
		||||
{
 | 
			
		||||
	struct _MemChunk *next;
 | 
			
		||||
	int size;
 | 
			
		||||
} MemChunk;
 | 
			
		||||
 | 
			
		||||
typedef MemChunk heap_buf_t;
 | 
			
		||||
 | 
			
		||||
/// A heap
 | 
			
		||||
typedef struct Heap
 | 
			
		||||
{
 | 
			
		||||
	struct _MemChunk *FreeList;     ///< Head of the free list
 | 
			
		||||
} Heap;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Utility macro to allocate a heap of size \a size.
 | 
			
		||||
 *
 | 
			
		||||
 * \param name Variable name for the heap.
 | 
			
		||||
 * \param size Heap size in bytes.
 | 
			
		||||
 */
 | 
			
		||||
#define HEAP_DEFINE_BUF(name, size) \
 | 
			
		||||
	heap_buf_t name[((size) + sizeof(heap_buf_t) - 1) / sizeof(heap_buf_t)]
 | 
			
		||||
 | 
			
		||||
/// Initialize \a heap within the buffer pointed by \a memory which is of \a size bytes
 | 
			
		||||
void tcm_heap_init(void);
 | 
			
		||||
 | 
			
		||||
/// Allocate a chunk of memory of \a size bytes from the heap
 | 
			
		||||
void *tcm_heap_allocmem(int size);
 | 
			
		||||
 | 
			
		||||
/// Free a chunk of memory of \a size bytes from the heap
 | 
			
		||||
void tcm_heap_freemem(void *mem, int size);
 | 
			
		||||
 | 
			
		||||
int tcm_heap_freeSpace(void);
 | 
			
		||||
 | 
			
		||||
#define HNEW(heap, type) \
 | 
			
		||||
	(type*)tcm_heap_allocmem(heap, sizeof(type))
 | 
			
		||||
 | 
			
		||||
#define HNEWVEC(heap, type, nelem) \
 | 
			
		||||
	(type*)tcm_heap_allocmem(heap, sizeof(type) * (nelem))
 | 
			
		||||
 | 
			
		||||
#define HDELETE(heap, type, mem) \
 | 
			
		||||
	tcm_heap_freemem(heap, mem, sizeof(type))
 | 
			
		||||
 | 
			
		||||
#define HDELETEVEC(heap, type, nelem, mem) \
 | 
			
		||||
	tcm_heap_freemem(heap, mem, sizeof(type) * (nelem))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \name Compatibility interface with C standard library
 | 
			
		||||
 * \{
 | 
			
		||||
 */
 | 
			
		||||
void *tcm_heap_malloc(int size);
 | 
			
		||||
void *tcm_heap_calloc(int size);
 | 
			
		||||
void tcm_heap_free(void * mem);
 | 
			
		||||
/** \} */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif /* STRUCT_HEAP_H */
 | 
			
		||||
							
								
								
									
										574
									
								
								component/os/os_dep/mailbox.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										574
									
								
								component/os/os_dep/mailbox.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,574 @@
 | 
			
		|||
/******************************************************************************
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
 | 
			
		||||
 *                                        
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify it
 | 
			
		||||
 * under the terms of version 2 of the GNU General Public License as
 | 
			
		||||
 * published by the Free Software Foundation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful, but WITHOUT
 | 
			
		||||
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 | 
			
		||||
 * more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License along with
 | 
			
		||||
 * this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
 | 
			
		||||
 *
 | 
			
		||||
 *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define _MAILBOX_C_
 | 
			
		||||
 | 
			
		||||
#include "mailbox.h"
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 * Function Prototype Declaration
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
static PRTL_MAILBOX RtlMBoxIdToHdl(
 | 
			
		||||
    IN u8 MBoxId
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
PRTL_MAILBOX RtlMailboxCreate(
 | 
			
		||||
    IN u8 MboxID, 
 | 
			
		||||
    IN u32 MboxSize, 
 | 
			
		||||
    IN _Sema *pWakeSema
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
VOID RtlMailboxDel(
 | 
			
		||||
    IN PRTL_MAILBOX MboxHdl
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
u8 RtlMailboxSendToBack(
 | 
			
		||||
    IN u8 MboxID, 
 | 
			
		||||
    IN MSG_BLK *pMsg, 
 | 
			
		||||
    IN u32 MSToWait, 
 | 
			
		||||
    IN u8 IsFromISR
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
u8 RtlMailboxSendToFront(
 | 
			
		||||
    IN u8 MboxID, 
 | 
			
		||||
    IN MSG_BLK *pMsg, 
 | 
			
		||||
    IN u32 MSToWait, 
 | 
			
		||||
    IN u8 IsFromISR
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
u8 RtlMailboxReceive(
 | 
			
		||||
    IN u8 MboxID, 
 | 
			
		||||
    OUT MSG_BLK *pMsg, 
 | 
			
		||||
    IN u32 MSToWait, 
 | 
			
		||||
    IN u8 IsFromISR
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
u8 RtlMailboxPeek(
 | 
			
		||||
    IN u8 MboxID, 
 | 
			
		||||
    OUT MSG_BLK *pMsg, 
 | 
			
		||||
    IN u32 MSToWait, 
 | 
			
		||||
    IN u8 IsFromISR
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
u32 RtlMailboxMsgWaiting(
 | 
			
		||||
    IN u8 MboxID, 
 | 
			
		||||
    IN u8 IsFromISR
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 * Global Variable Declaration
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
static RTL_MBOX_ROOT MBox_Entry;
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 * External Function & Variable Declaration
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 * Function: RtlMBoxIdToHdl
 | 
			
		||||
 * Desc: Map a mailbox ID to the mailbox pointer.
 | 
			
		||||
 * Para:
 | 
			
		||||
 *	MBoxId: The Mailbox ID
 | 
			
		||||
 * Return: The pointer of the mailbox. If didn't found match mailbox, 
 | 
			
		||||
 *			return NULL.
 | 
			
		||||
 *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
static PRTL_MAILBOX RtlMBoxIdToHdl(
 | 
			
		||||
	IN u8 MBoxId
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	RTL_MAILBOX *pMbox=NULL;
 | 
			
		||||
	RTL_MAILBOX *pTmpMbox;
 | 
			
		||||
	_LIST *pHead;
 | 
			
		||||
	_LIST *pList;
 | 
			
		||||
 | 
			
		||||
    // if the Mailbox root entry initialed ? if not, initial it
 | 
			
		||||
    if (!MBox_Entry.isInitialed) {
 | 
			
		||||
        RtlMutexInit(&MBox_Entry.Mutex);   // Init the Mutex for the mailbox add/delete procedure protection
 | 
			
		||||
        RtlInitListhead(&MBox_Entry.mbox_list);    // Init the link list head to chain all created mailbox
 | 
			
		||||
        MBox_Entry.isInitialed = 1;
 | 
			
		||||
        MSG_MBOX_INFO("MBox Entry Initial...\n");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	pHead = &MBox_Entry.mbox_list;
 | 
			
		||||
	RtlDownMutex(&MBox_Entry.Mutex);
 | 
			
		||||
	pList = RtlListGetNext(&MBox_Entry.mbox_list);
 | 
			
		||||
	while (pList != pHead) {
 | 
			
		||||
		pTmpMbox = CONTAINER_OF(pList, RTL_MAILBOX, mbox_list);		
 | 
			
		||||
		if (MBoxId == pTmpMbox->mbox_id) {
 | 
			
		||||
			pMbox = pTmpMbox;
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		pList = RtlListGetNext(pList);
 | 
			
		||||
	}
 | 
			
		||||
	RtlUpMutex(&MBox_Entry.Mutex);
 | 
			
		||||
 | 
			
		||||
	return pMbox;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 * Function: RtlMailboxCreate
 | 
			
		||||
 * Desc: To create a mailbox with a given mailbox ID and size
 | 
			
		||||
 * Para:
 | 
			
		||||
 * 	MboxID: A number to identify this created mailbox. A message block can 
 | 
			
		||||
 *          be send to a mailbox by a given MboxID. The MboxID must be unique 
 | 
			
		||||
 *          in the whole system. If this MboxID is conflict with a created 
 | 
			
		||||
 *          mailbox, the mailbox creation will fail and return NULL.
 | 
			
		||||
 *  MboxSize: The size of this mailbox to be created. It means maximum number 
 | 
			
		||||
 *          of message blocks can be stored in this mailbox.
 | 
			
		||||
 *  pWakeSema: The semaphore to wake up the receiving task to receive the new 
 | 
			
		||||
 *          message. If the receiving task doesn't need a semaphore to wakeup 
 | 
			
		||||
 *          it, then just let this pointer is NULL.
 | 
			
		||||
 * Return: The created mailbox pointer. If it failed, return NULL.
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
PRTL_MAILBOX RtlMailboxCreate(
 | 
			
		||||
    IN u8 MboxID, 
 | 
			
		||||
    IN u32 MboxSize, 
 | 
			
		||||
    IN _Sema *pWakeSema
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	PRTL_MAILBOX pMBox=NULL;
 | 
			
		||||
 | 
			
		||||
    // if the Mailbox root entry initialed ? if not, initial it
 | 
			
		||||
    if (!MBox_Entry.isInitialed) {
 | 
			
		||||
        RtlMutexInit(&MBox_Entry.Mutex);   // Init the Mutex for the mailbox add/delete procedure protection
 | 
			
		||||
        RtlInitListhead(&MBox_Entry.mbox_list);    // Init the link list head to chain all created mailbox
 | 
			
		||||
        MBox_Entry.isInitialed = 1;
 | 
			
		||||
        MSG_MBOX_INFO("MBox Entry Initial...\n");
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
	// check if this mailbox ID is ocupied ?
 | 
			
		||||
	pMBox = RtlMBoxIdToHdl(MboxID);
 | 
			
		||||
	if (NULL != pMBox) {
 | 
			
		||||
		MSG_MBOX_ERR("RtlMailboxCreate: The Mailbox ID %d is used by someone!!\n", MboxID);
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	pMBox = (RTL_MAILBOX *)RtlZmalloc(sizeof(RTL_MAILBOX));
 | 
			
		||||
	if (NULL==pMBox) {
 | 
			
		||||
		MSG_MBOX_ERR("RtlMailboxCreate: MAlloc Failed\n");
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	RtlInitListhead(&pMBox->mbox_list);	// Init the link list to be chained into the created mailbox list
 | 
			
		||||
	pMBox->mbox_id = MboxID;
 | 
			
		||||
	pMBox->pWakeSema = pWakeSema;
 | 
			
		||||
#ifdef PLATFORM_FREERTOS
 | 
			
		||||
    pMBox->mbox_hdl = xQueueCreate(MboxSize, sizeof(MSG_BLK));
 | 
			
		||||
    if (NULL == pMBox->mbox_hdl) {
 | 
			
		||||
		MSG_MBOX_ERR("RtlMailboxCreate: xQueueCreate Failed\n");
 | 
			
		||||
        RtlMfree((void *)pMBox, sizeof(RTL_MAILBOX));        
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef PLATFORM_ECOS
 | 
			
		||||
// TODO: Create mailbox
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	// Add this mailbox to the link list of created mailbox
 | 
			
		||||
	RtlDownMutex(&MBox_Entry.Mutex);
 | 
			
		||||
	RtlListInsertTail(&pMBox->mbox_list, &MBox_Entry.mbox_list);
 | 
			
		||||
	RtlUpMutex(&MBox_Entry.Mutex);
 | 
			
		||||
 | 
			
		||||
    MSG_MBOX_INFO("A Mailbox Created: Size=%d\n", MboxSize);
 | 
			
		||||
 | 
			
		||||
	return pMBox;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 * Function: RtlMailboxDel
 | 
			
		||||
 * Desc: To delete a mailbox by a given mailbox handle.
 | 
			
		||||
 * Para:
 | 
			
		||||
 *	MboxHdl: The handle of the mailbox to be deleted.
 | 
			
		||||
 * Return: None.
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
VOID RtlMailboxDel(
 | 
			
		||||
    IN PRTL_MAILBOX MboxHdl
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	if (NULL == MboxHdl) {
 | 
			
		||||
		MSG_MBOX_ERR("RtlMailboxDel: Try to delete a NULL mailbox\n");
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Remove this mailbox from the link list of created mailbox
 | 
			
		||||
	RtlDownMutex(&MBox_Entry.Mutex);
 | 
			
		||||
	RtlListDelete(&MboxHdl->mbox_list);
 | 
			
		||||
	RtlUpMutex(&MBox_Entry.Mutex);
 | 
			
		||||
 | 
			
		||||
    // delete the Queue/Mailbox
 | 
			
		||||
#ifdef PLATFORM_FREERTOS
 | 
			
		||||
    vQueueDelete((xQueueHandle)(MboxHdl->mbox_hdl));
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef PLATFORM_ECOS
 | 
			
		||||
    // TODO: Delete mailbox
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	RtlMfree((void *)MboxHdl, sizeof(RTL_MAILBOX));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 * Function: RtlMailboxSendToBack
 | 
			
		||||
 * Desc: To put a message block to the tail of a given mailbox.
 | 
			
		||||
 * Para:
 | 
			
		||||
 *  MboxID: The identifier of the target mailbox.
 | 
			
		||||
 *  pMsg: The pointer of the message block to be put into the mailbox.
 | 
			
		||||
 *  MSToWait: If the mailbox is full, this value gives a time to wait to put 
 | 
			
		||||
 *            this message. The time unit is millisecond. 
 | 
			
		||||
 *            The special values are: 
 | 
			
		||||
 *               0: no waiting; 
 | 
			
		||||
 *               0xffffffff: wait without timeout. 
 | 
			
		||||
 *            If the waiting is timeout, the message sending is failed and 
 | 
			
		||||
 *            return _FAIL.
 | 
			
		||||
 *  IsFromISR: Is this function is called from an ISR ?
 | 
			
		||||
 * Return: _SUCCESS or _FAIL.
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
u8 RtlMailboxSendToBack(
 | 
			
		||||
    IN u8 MboxID, 
 | 
			
		||||
    IN MSG_BLK *pMsg, 
 | 
			
		||||
    IN u32 MSToWait, 
 | 
			
		||||
    IN u8 IsFromISR
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
    RTL_MAILBOX *pMbox=NULL;
 | 
			
		||||
    u32 wait_ticks;
 | 
			
		||||
#ifdef PLATFORM_FREERTOS
 | 
			
		||||
    portBASE_TYPE ret;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    pMbox = RtlMBoxIdToHdl(MboxID);
 | 
			
		||||
 | 
			
		||||
    if (NULL == pMbox) {
 | 
			
		||||
   	    MSG_MBOX_ERR("RtlMailboxSendToBack: Didn't find matched MBoxID=%d\n", MboxID);
 | 
			
		||||
        return _FAIL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#ifdef PLATFORM_FREERTOS
 | 
			
		||||
    if (MBOX_WAIT_NO_TIMEOUT == MSToWait) {
 | 
			
		||||
        wait_ticks = portMAX_DELAY;
 | 
			
		||||
    }
 | 
			
		||||
    else if (MBOX_WAIT_NONE == MSToWait) {
 | 
			
		||||
        wait_ticks = 0;
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        wait_ticks = ((MSToWait/portTICK_RATE_MS)>0)?(MSToWait/portTICK_RATE_MS):(1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (IsFromISR) {
 | 
			
		||||
        ret = xQueueSendToBackFromISR(pMbox->mbox_hdl, (void *)pMsg, NULL);//(portTickType) wait_ticks);
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        ret = xQueueSendToBack(pMbox->mbox_hdl, (void *)pMsg, (portTickType) wait_ticks);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    if(ret != pdPASS ) {
 | 
			
		||||
        // send message to the queue failed
 | 
			
		||||
   	    MSG_MBOX_ERR("RtlMailboxSendToBack: Put Msg to Queue Failed, MBoxID=%d\n", MboxID);
 | 
			
		||||
        ret = _FAIL;
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        // try to give a semaphore to wake up the receiving task
 | 
			
		||||
        if (pMbox->pWakeSema) {
 | 
			
		||||
            RtlUpSema(pMbox->pWakeSema);  
 | 
			
		||||
        }
 | 
			
		||||
        ret = _SUCCESS;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return ret;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef PLATFORM_ECOS
 | 
			
		||||
    // TODO: Put the message to a mailbox
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 * Function: RtlMailboxSendToFront
 | 
			
		||||
 * Desc: To put a message block to the head of a mailbox.
 | 
			
		||||
 * Para:
 | 
			
		||||
 *  MboxID: The identifier of the target mailbox.
 | 
			
		||||
 *  pMsg: The pointer of the message block to be put into the mailbox.
 | 
			
		||||
 *  MSToWait: If the mailbox is full, this value gives a time to wait to put 
 | 
			
		||||
 *            this message. The time unit is millisecond. 
 | 
			
		||||
 *            The special values are: 
 | 
			
		||||
 *               0: no waiting; 
 | 
			
		||||
 *               0xffffffff: wait without timeout. 
 | 
			
		||||
 *            If the waiting is timeout, the message sending is failed and 
 | 
			
		||||
 *            return _FAIL.
 | 
			
		||||
 *  IsFromISR: Is this function is called from an ISR ?
 | 
			
		||||
 * Return: _SUCCESS or _FAIL.
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
u8 RtlMailboxSendToFront(
 | 
			
		||||
    IN u8 MboxID, 
 | 
			
		||||
    IN MSG_BLK *pMsg, 
 | 
			
		||||
    IN u32 MSToWait, 
 | 
			
		||||
    IN u8 IsFromISR
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
    RTL_MAILBOX *pMbox=NULL;
 | 
			
		||||
    u32 wait_ticks;
 | 
			
		||||
#ifdef PLATFORM_FREERTOS
 | 
			
		||||
    portBASE_TYPE ret;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    pMbox = RtlMBoxIdToHdl(MboxID);
 | 
			
		||||
 | 
			
		||||
    if (NULL == pMbox) {
 | 
			
		||||
   	    MSG_MBOX_ERR("RtlMailboxSendToBack: Didn't find matched MBoxID=%d\n", MboxID);
 | 
			
		||||
        return _FAIL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#ifdef PLATFORM_FREERTOS
 | 
			
		||||
    if (MBOX_WAIT_NO_TIMEOUT == MSToWait) {
 | 
			
		||||
        wait_ticks = portMAX_DELAY;
 | 
			
		||||
    }
 | 
			
		||||
    else if (MBOX_WAIT_NONE == MSToWait) {
 | 
			
		||||
        wait_ticks = 0;
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        wait_ticks = ((MSToWait/portTICK_RATE_MS)>0)?(MSToWait/portTICK_RATE_MS):(1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (IsFromISR) {
 | 
			
		||||
        ret = xQueueSendToFrontFromISR(pMbox->mbox_hdl, (void *)pMsg, NULL);//(portTickType) wait_ticks);
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        ret = xQueueSendToFront(pMbox->mbox_hdl, (void *)pMsg, (portTickType) wait_ticks);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    if(ret != pdPASS ) {
 | 
			
		||||
        // send message to the queue failed
 | 
			
		||||
   	    MSG_MBOX_ERR("RtlMailboxSendToBack: Put Msg to Queue Failed, MBoxID=%d\n", MboxID);
 | 
			
		||||
        ret = _FAIL;
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        // try to give a semaphore to wake up the receiving task
 | 
			
		||||
        if (pMbox->pWakeSema) {
 | 
			
		||||
            RtlUpSema(pMbox->pWakeSema);  
 | 
			
		||||
        }
 | 
			
		||||
        ret = _SUCCESS;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return ret;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef PLATFORM_ECOS
 | 
			
		||||
    // TODO: eCos has no API to put message to the head of a mailbox
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 * Function: RtlMailboxSendToFront
 | 
			
		||||
 * Desc: To get a message block from a given mailbox.
 | 
			
		||||
 * Para:
 | 
			
		||||
 *  MboxID: The identifier of the target mailbox.
 | 
			
		||||
 *  pMsg: The message block to store the gotten message.
 | 
			
		||||
 *  MSToWait: If the mailbox is full, this value gives a time to wait to put 
 | 
			
		||||
 *            this message. The time unit is millisecond. 
 | 
			
		||||
 *            The special values are: 
 | 
			
		||||
 *               0: no waiting; 
 | 
			
		||||
 *               0xffffffff: wait without timeout. 
 | 
			
		||||
 *            If the waiting is timeout, the message sending is failed and 
 | 
			
		||||
 *            return _FAIL.
 | 
			
		||||
 *  IsFromISR: Is this function is called from an ISR ?
 | 
			
		||||
 * Return: _SUCCESS or _FAIL.
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
u8 RtlMailboxReceive(
 | 
			
		||||
    IN u8 MboxID, 
 | 
			
		||||
    OUT MSG_BLK *pMsg, 
 | 
			
		||||
    IN u32 MSToWait, 
 | 
			
		||||
    IN u8 IsFromISR
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	RTL_MAILBOX *pMbox=NULL;
 | 
			
		||||
    u32 wait_ticks;
 | 
			
		||||
#ifdef PLATFORM_FREERTOS
 | 
			
		||||
    portBASE_TYPE ret;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	pMbox = RtlMBoxIdToHdl(MboxID);
 | 
			
		||||
 | 
			
		||||
	if (NULL == pMbox) {
 | 
			
		||||
		MSG_MBOX_ERR("RtlMailboxReceive: Didn't find the MBox with ID=%d\n", MboxID);
 | 
			
		||||
		return _FAIL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#ifdef PLATFORM_FREERTOS
 | 
			
		||||
    if (MBOX_WAIT_NONE == MSToWait) {
 | 
			
		||||
        wait_ticks = 0;
 | 
			
		||||
    }
 | 
			
		||||
    else if (MBOX_WAIT_NO_TIMEOUT == MSToWait) {
 | 
			
		||||
        wait_ticks = portMAX_DELAY;
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        wait_ticks = ((MSToWait/portTICK_RATE_MS)>0)?(MSToWait/portTICK_RATE_MS):(1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (IsFromISR) {
 | 
			
		||||
        ret = xQueueReceiveFromISR(pMbox->mbox_hdl, (void *)pMsg, NULL);//( portTickType ) wait_ticks);
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        ret = xQueueReceive(pMbox->mbox_hdl, (void *)pMsg, ( portTickType ) wait_ticks);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    if(ret != pdTRUE ) {
 | 
			
		||||
        // receive message failed
 | 
			
		||||
        if (0 != MSToWait) {
 | 
			
		||||
            MSG_MBOX_ERR("RtlMailboxReceive: Receive Msg Failed, MBoxID=%d\n", MboxID);
 | 
			
		||||
        }
 | 
			
		||||
        ret = _FAIL;
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        ret = _SUCCESS;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return ret;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef PLATFORM_ECOS
 | 
			
		||||
    // TODO: Get a message from the mailbox
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 * Function: RtlMailboxPeek
 | 
			
		||||
 * Desc: To copy the head message from a given mailbox without move this 
 | 
			
		||||
 *       message block out from the mailbox.
 | 
			
		||||
 * Para:
 | 
			
		||||
 *  MboxID: The identifier of the target mailbox.
 | 
			
		||||
 *  pMsg: The message block to store the gotten message.
 | 
			
		||||
 *  MSToWait: If the mailbox is full, this value gives a time to wait to put 
 | 
			
		||||
 *            this message. The time unit is millisecond. 
 | 
			
		||||
 *            The special values are: 
 | 
			
		||||
 *               0: no waiting; 
 | 
			
		||||
 *               0xffffffff: wait without timeout. 
 | 
			
		||||
 *            If the waiting is timeout, the message sending is failed and 
 | 
			
		||||
 *            return _FAIL.
 | 
			
		||||
 *  IsFromISR: Is this function is called from an ISR ?
 | 
			
		||||
 * Return: _SUCCESS or _FAIL.
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
u8 RtlMailboxPeek(
 | 
			
		||||
    IN u8 MboxID, 
 | 
			
		||||
    OUT MSG_BLK *pMsg, 
 | 
			
		||||
    IN u32 MSToWait, 
 | 
			
		||||
    IN u8 IsFromISR
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	RTL_MAILBOX *pMbox=NULL;
 | 
			
		||||
    u32 wait_ticks;
 | 
			
		||||
#ifdef PLATFORM_FREERTOS
 | 
			
		||||
    portBASE_TYPE ret;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	pMbox = RtlMBoxIdToHdl(MboxID);
 | 
			
		||||
 | 
			
		||||
	if (NULL == pMbox) {
 | 
			
		||||
		MSG_MBOX_ERR("RtlMailboxPeek: Didn't find the MBox with ID=%d\n", MboxID);
 | 
			
		||||
		return _FAIL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#ifdef PLATFORM_FREERTOS
 | 
			
		||||
    if (MBOX_WAIT_NONE == MSToWait) {
 | 
			
		||||
        wait_ticks = 0;
 | 
			
		||||
    }
 | 
			
		||||
    else if (MBOX_WAIT_NO_TIMEOUT == MSToWait) {
 | 
			
		||||
        wait_ticks = portMAX_DELAY;
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        wait_ticks = ((MSToWait/portTICK_RATE_MS)>0)?(MSToWait/portTICK_RATE_MS):(1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (IsFromISR) {
 | 
			
		||||
//        ret = xQueuePeekFromISR(pMbox->mbox_hdl, (void *)pMsg, ( portTickType ) wait_ticks);
 | 
			
		||||
        // TODO: check why we have no "xQueuePeekFromISR"
 | 
			
		||||
        MSG_MBOX_ERR("RtlMailboxPeek: Current version has no 'xQueuePeekFromISR'\n");
 | 
			
		||||
        ret = pdFALSE;
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        ret = xQueuePeek(pMbox->mbox_hdl, (void *)pMsg, ( portTickType ) wait_ticks);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    if(ret != pdTRUE ) {
 | 
			
		||||
        // receive message failed
 | 
			
		||||
        MSG_MBOX_ERR("RtlMailboxReceive: Receive Msg Failed, MBoxID=%d\n", MboxID);
 | 
			
		||||
        ret = _FAIL;
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        ret = _SUCCESS;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return ret;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef PLATFORM_ECOS
 | 
			
		||||
    // TODO: Get a message from the mailbox
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 * Function: RtlMailboxMsgWaiting
 | 
			
		||||
 * Desc: To get the number of message blocks are storing in a given mailbox.
 | 
			
		||||
 * Para:
 | 
			
		||||
 *  MboxID: The identifier of the target mailbox.
 | 
			
		||||
 *  IsFromISR: Is this function is called from an ISR ?
 | 
			
		||||
 * Return: The number of message blocks are storing in this mailbox.
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
u32 RtlMailboxMsgWaiting(
 | 
			
		||||
    IN u8 MboxID, 
 | 
			
		||||
    IN u8 IsFromISR
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	RTL_MAILBOX *pMbox=NULL;
 | 
			
		||||
    u32 msg_num=0;
 | 
			
		||||
 | 
			
		||||
	pMbox = RtlMBoxIdToHdl(MboxID);
 | 
			
		||||
 | 
			
		||||
	if (NULL == pMbox) {
 | 
			
		||||
		MSG_MBOX_ERR("RtlMailboxMsgWaiting: Didn't find the MBox with ID=%d\n", MboxID);
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#ifdef PLATFORM_FREERTOS
 | 
			
		||||
    if (IsFromISR) {
 | 
			
		||||
        msg_num = uxQueueMessagesWaitingFromISR(pMbox->mbox_hdl);
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        msg_num = uxQueueMessagesWaiting(pMbox->mbox_hdl);
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef PLATFORM_ECOS
 | 
			
		||||
    // TODO: call eCos API to implement this function
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    return msg_num;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										835
									
								
								component/os/os_dep/osdep_api.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										835
									
								
								component/os/os_dep/osdep_api.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,835 @@
 | 
			
		|||
/******************************************************************************
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
 | 
			
		||||
 *                                        
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify it
 | 
			
		||||
 * under the terms of version 2 of the GNU General Public License as
 | 
			
		||||
 * published by the Free Software Foundation.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful, but WITHOUT
 | 
			
		||||
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 | 
			
		||||
 * more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License along with
 | 
			
		||||
 * this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
 | 
			
		||||
 *
 | 
			
		||||
 *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define _OSDEP_API_C_
 | 
			
		||||
 | 
			
		||||
#include <osdep_api.h>
 | 
			
		||||
 | 
			
		||||
extern _LONG_CALL_ char *_strcpy(char *dest, const char *src);
 | 
			
		||||
extern _LONG_CALL_ VOID *_memset(void *dst0, int Val,SIZE_T length);
 | 
			
		||||
 | 
			
		||||
u8* 
 | 
			
		||||
RtlMalloc(
 | 
			
		||||
    IN  u32 sz
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	u8 	*pbuf=NULL;
 | 
			
		||||
#ifndef PLATFORM_FREERTOS
 | 
			
		||||
    u32  v32=0;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef PLATFORM_FREERTOS
 | 
			
		||||
    SaveAndCli( );
 | 
			
		||||
#else
 | 
			
		||||
	SaveAndCli(v32);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	pbuf = RtlKmalloc(sz, GFP_ATOMIC);
 | 
			
		||||
 | 
			
		||||
#ifdef PLATFORM_FREERTOS
 | 
			
		||||
    RestoreFlags( );
 | 
			
		||||
#else
 | 
			
		||||
	RestoreFlags(v32);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	return pbuf;	
 | 
			
		||||
	
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
u8* 
 | 
			
		||||
RtlZmalloc(
 | 
			
		||||
    IN  u32 sz
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
#ifdef PLATFORM_FREERTOS
 | 
			
		||||
    u8  *pbuf;
 | 
			
		||||
 
 | 
			
		||||
    pbuf= RtlMalloc(sz);
 | 
			
		||||
 | 
			
		||||
    if (pbuf != NULL) {
 | 
			
		||||
        _memset(pbuf, 0, sz);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return pbuf;    
 | 
			
		||||
#else
 | 
			
		||||
	u8 	*pbuf;
 | 
			
		||||
 | 
			
		||||
    pbuf= RtlMalloc(sz);
 | 
			
		||||
 | 
			
		||||
	if (pbuf != NULL) {
 | 
			
		||||
		_memset(pbuf, 0, sz);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return pbuf;	
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
VOID
 | 
			
		||||
RtlMfree(
 | 
			
		||||
    IN  u8 *pbuf, 
 | 
			
		||||
    IN  u32 sz
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
    RtlKfree(pbuf);	
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
VOID* 
 | 
			
		||||
RtlMalloc2d(
 | 
			
		||||
    IN  u32 h, 
 | 
			
		||||
    IN  u32 w, 
 | 
			
		||||
    IN  u32 size
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	u32 j;
 | 
			
		||||
 | 
			
		||||
	VOID **a = (VOID **) RtlZmalloc( h*sizeof(VOID *) + h*w*size );
 | 
			
		||||
	if(a == NULL)
 | 
			
		||||
	{
 | 
			
		||||
		DBG_ERROR_LOG("%s: alloc memory fail!\n", __FUNCTION__);
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for( j=0; j<h; j++ )
 | 
			
		||||
		a[j] = ((char *)(a+h)) + j*w*size;
 | 
			
		||||
 | 
			
		||||
	return a;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
VOID 
 | 
			
		||||
RtlMfree2d(
 | 
			
		||||
    IN  VOID *pbuf, 
 | 
			
		||||
    IN  u32 h, 
 | 
			
		||||
    IN  u32 w, 
 | 
			
		||||
    IN  u32 size
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	RtlMfree((u8 *)pbuf, h*sizeof(VOID*) + w*h*size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
VOID 
 | 
			
		||||
RtlInitSema(
 | 
			
		||||
    IN  _Sema *sema, 
 | 
			
		||||
    IN  u32 init_val
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
#ifdef PLATFORM_FREERTOS
 | 
			
		||||
    *sema = xSemaphoreCreateCounting(MAX_SEMA_COUNT, init_val); 
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(PLATFORM_LINUX) || defined(PLATFORM_ECOS)
 | 
			
		||||
	SemaInit(sema, init_val);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
VOID 
 | 
			
		||||
RtlFreeSema(
 | 
			
		||||
    IN  _Sema *sema
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	vSemaphoreDelete(*sema);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
VOID 
 | 
			
		||||
RtlUpSema(
 | 
			
		||||
    IN  _Sema *sema
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
#ifdef PLATFORM_FREERTOS
 | 
			
		||||
   	xSemaphoreGive(*sema);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef PLATFORM_ECOS
 | 
			
		||||
	sema_post(sema);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
VOID 
 | 
			
		||||
RtlUpSemaFromISR(
 | 
			
		||||
    IN  _Sema *sema
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
#ifdef PLATFORM_FREERTOS
 | 
			
		||||
	signed portBASE_TYPE xHigherPriorityTaskWoken=pdFALSE;
 | 
			
		||||
 | 
			
		||||
   	xSemaphoreGiveFromISR(*sema, &xHigherPriorityTaskWoken);
 | 
			
		||||
//    portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
 | 
			
		||||
	if (pdFALSE != xHigherPriorityTaskWoken)
 | 
			
		||||
	{
 | 
			
		||||
		taskYIELD();
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef PLATFORM_ECOS
 | 
			
		||||
	sema_post(sema);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
u32 
 | 
			
		||||
RtlDownSema(
 | 
			
		||||
    IN   _Sema *sema
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
#ifdef PLATFORM_FREERTOS
 | 
			
		||||
    xSemaphoreTake(*sema, portMAX_DELAY);
 | 
			
		||||
    return _SUCCESS;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef PLATFORM_ECOS
 | 
			
		||||
	SemaWait(sema);
 | 
			
		||||
	return  _SUCCESS;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
u32 
 | 
			
		||||
RtlDownSemaWithTimeout(
 | 
			
		||||
    IN   _Sema *sema,
 | 
			
		||||
    IN   u32 ms
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
#ifdef PLATFORM_FREERTOS
 | 
			
		||||
    u32 timeout = ms/portTICK_RATE_MS;
 | 
			
		||||
 | 
			
		||||
    if (xSemaphoreTake(*sema, timeout) == pdTRUE) {
 | 
			
		||||
        return _SUCCESS;
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        return _FAIL;
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef PLATFORM_ECOS
 | 
			
		||||
    // TODO:
 | 
			
		||||
	SemaWait(sema);
 | 
			
		||||
	return  _SUCCESS;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
VOID	
 | 
			
		||||
RtlMutexInit(
 | 
			
		||||
    IN _Mutex *pmutex
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
#ifdef PLATFORM_FREERTOS
 | 
			
		||||
    *pmutex = xSemaphoreCreateMutex();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef PLATFORM_ECOS
 | 
			
		||||
	SemaInit(pmutex, 1);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
VOID
 | 
			
		||||
RtlMutexFree(
 | 
			
		||||
    IN _Mutex *pmutex
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	vSemaphoreDelete(*pmutex);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
VOID
 | 
			
		||||
RtlSpinlockInit(
 | 
			
		||||
    IN  _Lock *plock
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	SpinLockInit(plock);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
VOID
 | 
			
		||||
RtlSpinlockFree(
 | 
			
		||||
    IN  _Lock *plock
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
VOID
 | 
			
		||||
RtlSpinlock(
 | 
			
		||||
    IN  _Lock *plock
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
    SpinLock(plock);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
VOID
 | 
			
		||||
RtlSpinunlock(
 | 
			
		||||
    IN  _Lock *plock
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	SpinUnlock(plock);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
VOID
 | 
			
		||||
RtlSpinlockEx(
 | 
			
		||||
    IN  _Lock *plock
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
VOID
 | 
			
		||||
RtlSpinunlockEx(
 | 
			
		||||
    IN  _Lock *plock
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
VOID
 | 
			
		||||
RtlInitQueue(
 | 
			
		||||
    IN  _QUEUE  *pqueue
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	RtlInitListhead(&(pqueue->Queue));
 | 
			
		||||
 | 
			
		||||
	RtlSpinlockInit(&(pqueue->Lock));
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
u32	  
 | 
			
		||||
RtlQueueEmpty(
 | 
			
		||||
    IN  _QUEUE *pqueue
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	return (RtlIsListEmpty(&(pqueue->Queue)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
u32 
 | 
			
		||||
RtlendOfQueueSearch(
 | 
			
		||||
    IN  _LIST *head,
 | 
			
		||||
    IN  _LIST *plist)
 | 
			
		||||
{
 | 
			
		||||
	if (head == plist)
 | 
			
		||||
		return _TRUE;
 | 
			
		||||
	else
 | 
			
		||||
		return _FALSE;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
u32	
 | 
			
		||||
RtlGetCurrentTime(VOID)
 | 
			
		||||
{
 | 
			
		||||
    return JIFFIES;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
VOID 
 | 
			
		||||
RtlSleepSchedulable(
 | 
			
		||||
    IN  u32 ms
 | 
			
		||||
) 
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
#ifdef PLATFORM_LINUX
 | 
			
		||||
 | 
			
		||||
    u32 delta;
 | 
			
		||||
    
 | 
			
		||||
    delta = (ms * HZ)/1000;//(ms)
 | 
			
		||||
    if (delta == 0) {
 | 
			
		||||
        delta = 1;// 1 ms
 | 
			
		||||
    }
 | 
			
		||||
    set_current_state(TASK_INTERRUPTIBLE);
 | 
			
		||||
    if (schedule_timeout(delta) != 0) {
 | 
			
		||||
        return ;
 | 
			
		||||
    }
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
#endif	
 | 
			
		||||
#ifdef PLATFORM_FREEBSD
 | 
			
		||||
	DELAY(ms*1000);
 | 
			
		||||
	return ;
 | 
			
		||||
#endif	
 | 
			
		||||
	
 | 
			
		||||
#ifdef PLATFORM_WINDOWS
 | 
			
		||||
 | 
			
		||||
	NdisMSleep(ms*1000); //(us)*1000=(ms)
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
VOID 
 | 
			
		||||
RtlMsleepOS(
 | 
			
		||||
    IN u32 ms
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
#ifdef PLATFORM_FREERTOS
 | 
			
		||||
    u32 Dealycount = ms/portTICK_RATE_MS;
 | 
			
		||||
    if (Dealycount > 0) {
 | 
			
		||||
        vTaskDelay(Dealycount);
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        vTaskDelay(1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
VOID 
 | 
			
		||||
RtlUsleepOS(
 | 
			
		||||
    IN  u32 us
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
#ifdef PLATFORM_FREERTOS
 | 
			
		||||
    u32 Dealycount = us/portTICK_RATE_MS*1000;
 | 
			
		||||
    if (Dealycount > 0) {
 | 
			
		||||
        vTaskDelay(Dealycount);
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        vTaskDelay(1);
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
VOID 
 | 
			
		||||
RtlMdelayOS(
 | 
			
		||||
    IN   u32 ms
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
   	Mdelay((unsigned long)ms); 
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
VOID 
 | 
			
		||||
RtlUdelayOS(
 | 
			
		||||
    IN  u32 us
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
      Udelay((unsigned long)us);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
VOID 
 | 
			
		||||
RtlYieldOS(VOID)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if defined(__ICCARM__)
 | 
			
		||||
u64 
 | 
			
		||||
RtlModular64(
 | 
			
		||||
    IN  u64 n,
 | 
			
		||||
    IN  u64 base
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	unsigned int __base = (base);	
 | 
			
		||||
	unsigned int __rem;	
 | 
			
		||||
	//(void)(((typeof((n)) *)0) == ((__uint64_t *)0));
 | 
			
		||||
	if (((n) >> 32) == 0) {	
 | 
			
		||||
		__rem = (unsigned int)(n) % __base;
 | 
			
		||||
		(n) = (unsigned int)(n) / __base;
 | 
			
		||||
	} else 					
 | 
			
		||||
		__rem = __Div64_32(&(n), __base);
 | 
			
		||||
	return __rem;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
#else
 | 
			
		||||
u64 
 | 
			
		||||
RtlModular64(
 | 
			
		||||
    IN  u64 x,
 | 
			
		||||
    IN  u64 y
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	return DO_DIV(x, y);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 * Function: RtlTimerCallbckEntry
 | 
			
		||||
 * Desc: This function is a timer callback wrapper. All OS timer callback 
 | 
			
		||||
 *      will call this function and then call the real callback function inside
 | 
			
		||||
 *      this function.
 | 
			
		||||
 *
 | 
			
		||||
 * Para:
 | 
			
		||||
 * 	 pxTimer: The FreeRTOS timer handle which is expired and call this callback.
 | 
			
		||||
 *
 | 
			
		||||
 * Return: None
 | 
			
		||||
 *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
#ifdef PLATFORM_FREERTOS
 | 
			
		||||
void
 | 
			
		||||
RtlTimerCallbckEntry (
 | 
			
		||||
    IN xTimerHandle pxTimer
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
    PRTL_TIMER pTimer;
 | 
			
		||||
 | 
			
		||||
    if (NULL == pxTimer) {
 | 
			
		||||
        MSG_TIMER_ERR("RtlTimerCallbckEntry: NULL Timer Handle Err!\n");
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    pTimer = (PRTL_TIMER) pvTimerGetTimerID( pxTimer );
 | 
			
		||||
    pTimer->CallBackFunc(pTimer->Context);
 | 
			
		||||
}
 | 
			
		||||
#endif  // end of "#ifdef PLATFORM_FREERTOS"
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 * Function: RtlTimerCreate
 | 
			
		||||
 * Desc: To create a software timer.
 | 
			
		||||
 *
 | 
			
		||||
 * Para:
 | 
			
		||||
 * 	 pTimerName: A string for the timer name.
 | 
			
		||||
 * 	 TimerPeriodMS: The timer period, the unit is milli-second.
 | 
			
		||||
 *   CallbckFunc: The callback function of this timer.
 | 
			
		||||
 *   pContext: A pointer will be used as the parameter to call the timer 
 | 
			
		||||
 *              callback function.
 | 
			
		||||
 *   isPeriodical: Is this timer periodical ? (Auto reload after expired)
 | 
			
		||||
 * Return: The created timer handle, a pointer. It can be used to delete the 
 | 
			
		||||
 *          timer. If timer createion failed, return NULL.
 | 
			
		||||
 *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
PRTL_TIMER
 | 
			
		||||
RtlTimerCreate(
 | 
			
		||||
    IN char *pTimerName,
 | 
			
		||||
    IN u32 TimerPeriodMS,
 | 
			
		||||
    IN RTL_TIMER_CALL_BACK CallbckFunc,
 | 
			
		||||
    IN void *pContext,
 | 
			
		||||
    IN u8 isPeriodical
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
    PRTL_TIMER pTimer;
 | 
			
		||||
    u32 timer_ticks;
 | 
			
		||||
    int i;
 | 
			
		||||
 | 
			
		||||
    pTimer = (PRTL_TIMER)RtlZmalloc(sizeof(RTL_TIMER));
 | 
			
		||||
    if (NULL == pTimer) {
 | 
			
		||||
        MSG_TIMER_ERR("RtlTimerCreate: Alloc Mem Err!\n");
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (portTICK_RATE_MS >= TimerPeriodMS) {
 | 
			
		||||
        timer_ticks = 1;    // at least 1 system tick
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        timer_ticks = TimerPeriodMS/portTICK_RATE_MS;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#ifdef PLATFORM_FREERTOS
 | 
			
		||||
    pTimer->TimerHandle = xTimerCreate ((const char*)(pTimer->TimerName), timer_ticks, 
 | 
			
		||||
            (portBASE_TYPE)isPeriodical, (void *) pTimer, RtlTimerCallbckEntry);
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef PLATFORM_ECOS
 | 
			
		||||
// TODO: create a timer
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef PLATFORM_FREERTOS    // if any RTOS is used
 | 
			
		||||
    if (pTimer->TimerHandle) {
 | 
			
		||||
        pTimer->msPeriod = TimerPeriodMS;
 | 
			
		||||
        pTimer->CallBackFunc = CallbckFunc;
 | 
			
		||||
        pTimer->Context = pContext;
 | 
			
		||||
        pTimer->isPeriodical = isPeriodical;
 | 
			
		||||
        // copy the timer name
 | 
			
		||||
        if (NULL != pTimerName) {
 | 
			
		||||
            for(i = 0; i < sizeof(pTimer->TimerName); i++)
 | 
			
		||||
            {
 | 
			
		||||
                pTimer->TimerName[i] = pTimerName[i]; 
 | 
			
		||||
                if(pTimerName[i] == '\0')
 | 
			
		||||
                {
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            _strcpy((char*)(pTimer->TimerName), "None");
 | 
			
		||||
        }
 | 
			
		||||
        MSG_TIMER_INFO("RtlTimerCreate: SW Timer Created: Name=%s Period=%d isPeriodical=%d\n", \
 | 
			
		||||
            pTimer->TimerName, pTimer->msPeriod, pTimer->isPeriodical);
 | 
			
		||||
    }
 | 
			
		||||
    else 
 | 
			
		||||
#endif
 | 
			
		||||
    {
 | 
			
		||||
        RtlMfree((u8 *)pTimer, sizeof(RTL_TIMER));
 | 
			
		||||
        pTimer = NULL;
 | 
			
		||||
        MSG_TIMER_ERR("RtlTimerCreate: OS Create Timer Failed!\n");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    return (pTimer);    
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 * Function: RtlTimerDelete
 | 
			
		||||
 * Desc: To delete a created software timer.
 | 
			
		||||
 *
 | 
			
		||||
 * Para:
 | 
			
		||||
 * 	 pTimerHdl: The timer to be deleted
 | 
			
		||||
 *
 | 
			
		||||
 * Return: None
 | 
			
		||||
 *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
VOID
 | 
			
		||||
RtlTimerDelete(
 | 
			
		||||
    IN PRTL_TIMER pTimerHdl
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
#ifdef PLATFORM_FREERTOS
 | 
			
		||||
    portBASE_TYPE ret;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    if (NULL == pTimerHdl) {
 | 
			
		||||
        MSG_TIMER_ERR("RtlTimerDelete: NULL Timer Handle!\n");
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    MSG_TIMER_INFO("RtlTimerDelete: Name=%s\n", pTimerHdl->TimerName);
 | 
			
		||||
 | 
			
		||||
#ifdef PLATFORM_FREERTOS
 | 
			
		||||
    /* try to delete the soft timer and wait max RTL_TIMER_API_MAX_BLOCK_TICKS 
 | 
			
		||||
        to send the delete command to the timer command queue */
 | 
			
		||||
    ret = xTimerDelete(pTimerHdl->TimerHandle, RTL_TIMER_API_MAX_BLOCK_TICKS);
 | 
			
		||||
    if (pdPASS != ret) {
 | 
			
		||||
        MSG_TIMER_ERR("RtlTimerDelete: Delete OS Timer Failed!\n");
 | 
			
		||||
    }
 | 
			
		||||
#endif    
 | 
			
		||||
 | 
			
		||||
#ifdef PLATFORM_ECOS
 | 
			
		||||
    // TODO: call OS delete timer
 | 
			
		||||
#endif
 | 
			
		||||
    RtlMfree((u8 *)pTimerHdl, sizeof(RTL_TIMER));
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 * Function: RtlTimerStart
 | 
			
		||||
 * Desc: To start a created timer..
 | 
			
		||||
 *
 | 
			
		||||
 * Para:
 | 
			
		||||
 * 	 pTimerHdl: The timer to be started.
 | 
			
		||||
 *	isFromISR: The flag to indicate that is this function is called from an ISR.
 | 
			
		||||
 *
 | 
			
		||||
 * Return: _SUCCESS or _FAIL
 | 
			
		||||
 *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
u8
 | 
			
		||||
RtlTimerStart(
 | 
			
		||||
    IN PRTL_TIMER pTimerHdl,
 | 
			
		||||
    IN u8 isFromISR
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
#ifdef PLATFORM_FREERTOS
 | 
			
		||||
    u8 ret=_FAIL;
 | 
			
		||||
    portBASE_TYPE HigherPriorityTaskWoken=pdFALSE;
 | 
			
		||||
 | 
			
		||||
    if (isFromISR) {
 | 
			
		||||
        if (pdPASS == xTimerStartFromISR(pTimerHdl->TimerHandle,&HigherPriorityTaskWoken))
 | 
			
		||||
        {
 | 
			
		||||
            // start OS timer successful
 | 
			
		||||
            if (pdFALSE != HigherPriorityTaskWoken) {
 | 
			
		||||
                taskYIELD();
 | 
			
		||||
            }
 | 
			
		||||
            ret = _SUCCESS;
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            MSG_TIMER_ERR("RtlTimerStart: Start Timer(%s) from ISR failed\n", pTimerHdl->TimerName);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        if (pdPASS == xTimerStart(pTimerHdl->TimerHandle, RTL_TIMER_API_MAX_BLOCK_TICKS)) {
 | 
			
		||||
            ret = _SUCCESS;
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            MSG_TIMER_ERR("RtlTimerStart: Start Timer(%s) failed\n", pTimerHdl->TimerName);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    MSG_TIMER_INFO("RtlTimerStart: SW Timer %s Started\n", pTimerHdl->TimerName);
 | 
			
		||||
 | 
			
		||||
    return ret;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 * Function: RtlTimerStop
 | 
			
		||||
 * Desc: To stop a running timer..
 | 
			
		||||
 *
 | 
			
		||||
 * Para:
 | 
			
		||||
 * 	 pTimerHdl: The timer to be stoped.
 | 
			
		||||
 *	isFromISR: The flag to indicate that is this function is called from an ISR.
 | 
			
		||||
 *
 | 
			
		||||
 * Return: _SUCCESS or _FAIL
 | 
			
		||||
 *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
u8
 | 
			
		||||
RtlTimerStop(
 | 
			
		||||
    IN PRTL_TIMER pTimerHdl,
 | 
			
		||||
    IN u8 isFromISR
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
#ifdef PLATFORM_FREERTOS
 | 
			
		||||
    u8 ret=_FAIL;
 | 
			
		||||
    portBASE_TYPE HigherPriorityTaskWoken=pdFALSE;
 | 
			
		||||
 | 
			
		||||
    if (isFromISR) {
 | 
			
		||||
        if (pdPASS == xTimerStopFromISR(pTimerHdl->TimerHandle,&HigherPriorityTaskWoken))
 | 
			
		||||
        {
 | 
			
		||||
            // start OS timer successful
 | 
			
		||||
            if (pdFALSE != HigherPriorityTaskWoken) {
 | 
			
		||||
                taskYIELD();
 | 
			
		||||
            }
 | 
			
		||||
            ret = _SUCCESS;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        if (pdPASS == xTimerStop(pTimerHdl->TimerHandle, RTL_TIMER_API_MAX_BLOCK_TICKS)) {
 | 
			
		||||
            ret = _SUCCESS;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (_FAIL == ret) {
 | 
			
		||||
        MSG_TIMER_ERR("RtlTimerStop: Stop Timer(%s) Failed, IsFromISR=%d\n", pTimerHdl->TimerName, isFromISR);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    MSG_TIMER_INFO("RtlTimerStop: SW Timer %s Stoped\n", pTimerHdl->TimerName);
 | 
			
		||||
 | 
			
		||||
    return ret;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 * Function: RtlTimerReset
 | 
			
		||||
 * Desc: To reset a timer. A reset will get a re-start and reset
 | 
			
		||||
 *          the timer ticks counting. A running timer expired time is relative 
 | 
			
		||||
 *          to the time when Reset function be called. Please ensure the timer
 | 
			
		||||
 *          is in active state (Started). A stopped timer also will be started
 | 
			
		||||
 *          when this function is called.
 | 
			
		||||
 *
 | 
			
		||||
 * Para:
 | 
			
		||||
 * 	 pTimerHdl: The timer to be reset.
 | 
			
		||||
 *	isFromISR: The flag to indicate that is this function is called from an ISR.
 | 
			
		||||
 *
 | 
			
		||||
 * Return: _SUCCESS or _FAIL
 | 
			
		||||
 *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
u8
 | 
			
		||||
RtlTimerReset(
 | 
			
		||||
    IN PRTL_TIMER pTimerHdl,
 | 
			
		||||
    IN u8 isFromISR
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
#ifdef PLATFORM_FREERTOS
 | 
			
		||||
    u8 ret=_FAIL;
 | 
			
		||||
    portBASE_TYPE HigherPriorityTaskWoken=pdFALSE;
 | 
			
		||||
 | 
			
		||||
    if (isFromISR) {
 | 
			
		||||
        if (pdPASS == xTimerResetFromISR(pTimerHdl->TimerHandle,&HigherPriorityTaskWoken))
 | 
			
		||||
        {
 | 
			
		||||
            // start OS timer successful
 | 
			
		||||
            if (pdFALSE != HigherPriorityTaskWoken) {
 | 
			
		||||
                taskYIELD();
 | 
			
		||||
            }
 | 
			
		||||
            ret = _SUCCESS;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        if (pdPASS == xTimerReset(pTimerHdl->TimerHandle, RTL_TIMER_API_MAX_BLOCK_TICKS)) {
 | 
			
		||||
            ret = _SUCCESS;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (_FAIL == ret) {
 | 
			
		||||
        MSG_TIMER_ERR("RtlTimerReset: Reset Timer(%s) Failed, IsFromISR=%d\n", pTimerHdl->TimerName, isFromISR);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    MSG_TIMER_INFO("RtlTimerReset: SW Timer %s Reset\n", pTimerHdl->TimerName);
 | 
			
		||||
 | 
			
		||||
    return ret;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 * Function: RtlTimerChangePeriod
 | 
			
		||||
 * Desc: To change the period of a timer that was created previously.
 | 
			
		||||
 *
 | 
			
		||||
 * Para:
 | 
			
		||||
 * 	 pTimerHdl: The timer handle to be changed the priod.
 | 
			
		||||
 *   NewPeriodMS: The new timer period, in milli-second.
 | 
			
		||||
 *	 isFromISR: The flag to indicate that is this function is called from an ISR.
 | 
			
		||||
 *
 | 
			
		||||
 * Return: _SUCCESS or _FAIL
 | 
			
		||||
 *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
u8
 | 
			
		||||
RtlTimerChangePeriod(
 | 
			
		||||
    IN PRTL_TIMER pTimerHdl,
 | 
			
		||||
    IN u32 NewPeriodMS,
 | 
			
		||||
    IN u8 isFromISR
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
#ifdef PLATFORM_FREERTOS
 | 
			
		||||
    u32 timer_ticks;
 | 
			
		||||
    u8 ret=_FAIL;
 | 
			
		||||
    portBASE_TYPE HigherPriorityTaskWoken=pdFALSE;
 | 
			
		||||
 | 
			
		||||
    if (portTICK_RATE_MS >= NewPeriodMS) {
 | 
			
		||||
        timer_ticks = 1;    // at least 1 system tick
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        timer_ticks = NewPeriodMS/portTICK_RATE_MS;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (isFromISR) {
 | 
			
		||||
        if (pdPASS == xTimerChangePeriodFromISR(pTimerHdl->TimerHandle, timer_ticks, &HigherPriorityTaskWoken))
 | 
			
		||||
        {
 | 
			
		||||
            // start OS timer successful
 | 
			
		||||
            if (pdFALSE != HigherPriorityTaskWoken) {
 | 
			
		||||
                taskYIELD();
 | 
			
		||||
            }
 | 
			
		||||
            ret = _SUCCESS;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        if (pdPASS == xTimerChangePeriod(pTimerHdl->TimerHandle, timer_ticks, RTL_TIMER_API_MAX_BLOCK_TICKS)) {
 | 
			
		||||
            ret = _SUCCESS;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (_FAIL == ret) {
 | 
			
		||||
        MSG_TIMER_ERR("RtlTimerChangePeriod: Change Timer(%s) Period Failed, IsFromISR=%d\n", pTimerHdl->TimerName, isFromISR);
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        pTimerHdl->msPeriod = NewPeriodMS;
 | 
			
		||||
        MSG_TIMER_INFO("RtlTimerChangePeriod: SW Timer %s change period to %d\n", pTimerHdl->TimerName, pTimerHdl->msPeriod);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    return ret;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										1223
									
								
								component/os/os_dep/osdep_service.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1223
									
								
								component/os/os_dep/osdep_service.c
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										352
									
								
								component/os/os_dep/tcm_heap.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										352
									
								
								component/os/os_dep/tcm_heap.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,352 @@
 | 
			
		|||
//#include <autoconf.h>
 | 
			
		||||
#include "tcm_heap.h"
 | 
			
		||||
 | 
			
		||||
#include <string.h>    // memset()
 | 
			
		||||
 | 
			
		||||
#include <osdep_service.h>
 | 
			
		||||
 | 
			
		||||
//#define _DEBUG
 | 
			
		||||
 | 
			
		||||
#if CONFIG_USE_TCM_HEAP
 | 
			
		||||
#define FREE_FILL_CODE     0xDEAD
 | 
			
		||||
#define ALLOC_FILL_CODE    0xBEEF
 | 
			
		||||
 | 
			
		||||
#define ROUND_UP2(x, pad) (((x) + ((pad) - 1)) & ~((pad) - 1))
 | 
			
		||||
 | 
			
		||||
#define TCM_HEAP_SIZE	(40*1024)
 | 
			
		||||
 | 
			
		||||
static struct Heap g_tcm_heap;
 | 
			
		||||
 | 
			
		||||
#if defined (__ICCARM__)
 | 
			
		||||
#pragma location=".tcm.heap"
 | 
			
		||||
#else
 | 
			
		||||
__attribute__((section(".tcm.heap")))
 | 
			
		||||
#endif
 | 
			
		||||
HEAP_DEFINE_BUF(tcm_heap, TCM_HEAP_SIZE);
 | 
			
		||||
//unsigned char tcm_heap[TCM_HEAP_SIZE];
 | 
			
		||||
 | 
			
		||||
static int g_heap_inited=0;
 | 
			
		||||
static	_lock	tcm_lock;
 | 
			
		||||
 | 
			
		||||
extern void vPortSetExtFree( void (*free)( void *p ), uint32_t upper, uint32_t lower );
 | 
			
		||||
 | 
			
		||||
void tcm_heap_init(void)
 | 
			
		||||
{
 | 
			
		||||
	//#ifdef _DEBUG
 | 
			
		||||
	//memset(memory, FREE_FILL_CODE, size);
 | 
			
		||||
	//#endif
 | 
			
		||||
 | 
			
		||||
	//ASSERT2(((int)memory % alignof(heap_buf_t)) == 0,
 | 
			
		||||
	//"memory buffer is unaligned, please use the HEAP_DEFINE_BUF() macro to declare heap buffers!\n");
 | 
			
		||||
	
 | 
			
		||||
	/* Initialize heap with a single big chunk */
 | 
			
		||||
	g_tcm_heap.FreeList = (MemChunk *)&tcm_heap;
 | 
			
		||||
	g_tcm_heap.FreeList->next = NULL;
 | 
			
		||||
	g_tcm_heap.FreeList->size = sizeof(tcm_heap);
 | 
			
		||||
	
 | 
			
		||||
	g_heap_inited = 1;
 | 
			
		||||
	rtw_spinlock_init(&tcm_lock);
 | 
			
		||||
	
 | 
			
		||||
#if PLATFORM_FREERTOS	
 | 
			
		||||
	// let RTOS know how to free memory if using as task stack
 | 
			
		||||
	vPortSetExtFree(tcm_heap_free, 0x20000000, 0x1fff0000);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void tcm_heap_dump(void)
 | 
			
		||||
{
 | 
			
		||||
	MemChunk *chunk, *prev;
 | 
			
		||||
	struct Heap* h = &g_tcm_heap;
 | 
			
		||||
	
 | 
			
		||||
	printf("---Free List--\n\r");
 | 
			
		||||
	for (prev = (MemChunk *)&h->FreeList, chunk = h->FreeList;
 | 
			
		||||
		chunk;
 | 
			
		||||
		prev = chunk, chunk = chunk->next)
 | 
			
		||||
	{
 | 
			
		||||
		printf(" prev %x, chunk %x, size %d \n\r", prev, chunk, chunk->size);
 | 
			
		||||
	}
 | 
			
		||||
	printf("--------------\n\r");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void *tcm_heap_allocmem(int size)
 | 
			
		||||
{
 | 
			
		||||
	MemChunk *chunk, *prev;
 | 
			
		||||
	struct Heap* h = &g_tcm_heap;
 | 
			
		||||
	_irqL 	irqL;
 | 
			
		||||
 | 
			
		||||
	rtw_enter_critical(&tcm_lock, &irqL);
 | 
			
		||||
	
 | 
			
		||||
	if(!g_heap_inited)	tcm_heap_init();
 | 
			
		||||
 | 
			
		||||
	/* Round size up to the allocation granularity */
 | 
			
		||||
	size = ROUND_UP2(size, sizeof(MemChunk));
 | 
			
		||||
 | 
			
		||||
	/* Handle allocations of 0 bytes */
 | 
			
		||||
	if (!size)
 | 
			
		||||
		size = sizeof(MemChunk);
 | 
			
		||||
 | 
			
		||||
	/* Walk on the free list looking for any chunk big enough to
 | 
			
		||||
	 * fit the requested block size.
 | 
			
		||||
	 */
 | 
			
		||||
	for (prev = (MemChunk *)&h->FreeList, chunk = h->FreeList;
 | 
			
		||||
		chunk;
 | 
			
		||||
		prev = chunk, chunk = chunk->next)
 | 
			
		||||
	{
 | 
			
		||||
		if (chunk->size >= size)
 | 
			
		||||
		{
 | 
			
		||||
			if (chunk->size == size)
 | 
			
		||||
			{
 | 
			
		||||
				/* Just remove this chunk from the free list */
 | 
			
		||||
				prev->next = chunk->next;
 | 
			
		||||
				#ifdef _DEBUG
 | 
			
		||||
					memset(chunk, ALLOC_FILL_CODE, size);
 | 
			
		||||
				#endif
 | 
			
		||||
				
 | 
			
		||||
				rtw_exit_critical(&tcm_lock, &irqL);
 | 
			
		||||
				//printf("----ALLOC1-----\n\r");
 | 
			
		||||
				//tcm_heap_dump();
 | 
			
		||||
				//printf("--------------\n\r");
 | 
			
		||||
				return (void *)chunk;
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				/* Allocate from the END of an existing chunk */
 | 
			
		||||
				chunk->size -= size;
 | 
			
		||||
				#ifdef _DEBUG
 | 
			
		||||
					memset((uint8_t *)chunk + chunk->size, ALLOC_FILL_CODE, size);
 | 
			
		||||
				#endif
 | 
			
		||||
				rtw_exit_critical(&tcm_lock, &irqL);
 | 
			
		||||
				//printf("----ALLOC2-----\n\r");
 | 
			
		||||
				//tcm_heap_dump();
 | 
			
		||||
				//printf("--------------\n\r");
 | 
			
		||||
				
 | 
			
		||||
				return (void *)((uint8_t *)chunk + chunk->size);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	rtw_exit_critical(&tcm_lock, &irqL);
 | 
			
		||||
	//printf("----ALLOC3-----\n\r");
 | 
			
		||||
	//tcm_heap_dump();
 | 
			
		||||
	//printf("--------------\n\r");
 | 
			
		||||
	return NULL; /* fail */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void tcm_heap_freemem(void *mem, int size)
 | 
			
		||||
{
 | 
			
		||||
	MemChunk *prev;
 | 
			
		||||
	//ASSERT(mem);
 | 
			
		||||
	struct Heap* h = &g_tcm_heap;
 | 
			
		||||
	_irqL 	irqL;
 | 
			
		||||
 | 
			
		||||
	rtw_enter_critical(&tcm_lock, &irqL);	
 | 
			
		||||
	
 | 
			
		||||
	if(!g_heap_inited)	tcm_heap_init();
 | 
			
		||||
 | 
			
		||||
#ifdef _DEBUG
 | 
			
		||||
	memset(mem, FREE_FILL_CODE, size);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	/* Round size up to the allocation granularity */
 | 
			
		||||
	size = ROUND_UP2(size, sizeof(MemChunk));
 | 
			
		||||
 | 
			
		||||
	/* Handle allocations of 0 bytes */
 | 
			
		||||
	if (!size)
 | 
			
		||||
		size = sizeof(MemChunk);
 | 
			
		||||
 | 
			
		||||
	/* Special cases: first chunk in the free list or memory completely full */
 | 
			
		||||
	//ASSERT((uint8_t*)mem != (uint8_t*)h->FreeList);
 | 
			
		||||
	if (((uint8_t *)mem) < ((uint8_t *)h->FreeList) || !h->FreeList)
 | 
			
		||||
	{
 | 
			
		||||
		/* Insert memory block before the current free list head */
 | 
			
		||||
		prev = (MemChunk *)mem;
 | 
			
		||||
		prev->next = h->FreeList;
 | 
			
		||||
		prev->size = size;
 | 
			
		||||
		h->FreeList = prev;
 | 
			
		||||
	}
 | 
			
		||||
	else /* Normal case: not the first chunk in the free list */
 | 
			
		||||
	{
 | 
			
		||||
		/*
 | 
			
		||||
		 * Walk on the free list. Stop at the insertion point (when mem
 | 
			
		||||
		 * is between prev and prev->next)
 | 
			
		||||
		 */
 | 
			
		||||
		prev = h->FreeList;
 | 
			
		||||
		while (prev->next < (MemChunk *)mem && prev->next)
 | 
			
		||||
			prev = prev->next;
 | 
			
		||||
 | 
			
		||||
		/* Make sure mem is not *within* prev */
 | 
			
		||||
		//ASSERT((uint8_t*)mem >= (uint8_t*)prev + prev->size);
 | 
			
		||||
 | 
			
		||||
		/* Should it be merged with previous block? */
 | 
			
		||||
		if (((uint8_t *)prev) + prev->size == ((uint8_t *)mem))
 | 
			
		||||
		{
 | 
			
		||||
			/* Yes */
 | 
			
		||||
			prev->size += size;
 | 
			
		||||
		}
 | 
			
		||||
		else /* not merged with previous chunk */
 | 
			
		||||
		{
 | 
			
		||||
			MemChunk *curr = (MemChunk*)mem;
 | 
			
		||||
 | 
			
		||||
			/* insert it after the previous node
 | 
			
		||||
			 * and move the 'prev' pointer forward
 | 
			
		||||
			 * for the following operations
 | 
			
		||||
			 */
 | 
			
		||||
			curr->next = prev->next;
 | 
			
		||||
			curr->size = size;
 | 
			
		||||
			prev->next = curr;
 | 
			
		||||
 | 
			
		||||
			/* Adjust for the following test */
 | 
			
		||||
			prev = curr;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Also merge with next chunk? */
 | 
			
		||||
	if (((uint8_t *)prev) + prev->size == ((uint8_t *)prev->next))
 | 
			
		||||
	{
 | 
			
		||||
		prev->size += prev->next->size;
 | 
			
		||||
		prev->next = prev->next->next;
 | 
			
		||||
 | 
			
		||||
		/* There should be only one merge opportunity, becuase we always merge on free */
 | 
			
		||||
		//ASSERT((uint8_t*)prev + prev->size != (uint8_t*)prev->next);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	rtw_exit_critical(&tcm_lock, &irqL);	
 | 
			
		||||
	//printf("---FREE %x--\n\r", mem);
 | 
			
		||||
	//tcm_heap_dump();
 | 
			
		||||
	//printf("--------------\n\r");
 | 
			
		||||
	
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int tcm_heap_freeSpace(void)
 | 
			
		||||
{
 | 
			
		||||
	int free_mem = 0;
 | 
			
		||||
	struct Heap* h = &g_tcm_heap;
 | 
			
		||||
	_irqL 	irqL;
 | 
			
		||||
	MemChunk *chunk;
 | 
			
		||||
 | 
			
		||||
	rtw_enter_critical(&tcm_lock, &irqL);
 | 
			
		||||
	
 | 
			
		||||
	if(!g_heap_inited)	tcm_heap_init();
 | 
			
		||||
	
 | 
			
		||||
	for (chunk = h->FreeList; chunk; chunk = chunk->next)
 | 
			
		||||
		free_mem += chunk->size;
 | 
			
		||||
 | 
			
		||||
	rtw_exit_critical(&tcm_lock, &irqL);
 | 
			
		||||
	return free_mem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Standard malloc interface
 | 
			
		||||
 */
 | 
			
		||||
void *tcm_heap_malloc(int size)
 | 
			
		||||
{
 | 
			
		||||
	int *mem;
 | 
			
		||||
 | 
			
		||||
	size += sizeof(int);
 | 
			
		||||
	if ((mem = (int*)tcm_heap_allocmem(size))){
 | 
			
		||||
		*mem++ = size;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return mem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Standard calloc interface
 | 
			
		||||
 */
 | 
			
		||||
void *tcm_heap_calloc(int size)
 | 
			
		||||
{
 | 
			
		||||
	void *mem;
 | 
			
		||||
 | 
			
		||||
	if ((mem = tcm_heap_malloc(size)))
 | 
			
		||||
		memset(mem, 0, size);
 | 
			
		||||
 | 
			
		||||
	return mem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Free a block of memory, determining its size automatically.
 | 
			
		||||
 *
 | 
			
		||||
 * \param h    Heap from which the block was allocated.
 | 
			
		||||
 * \param mem  Pointer to a block of memory previously allocated with
 | 
			
		||||
 *             either heap_malloc() or heap_calloc().
 | 
			
		||||
 *
 | 
			
		||||
 * \note If \a mem is a NULL pointer, no operation is performed.
 | 
			
		||||
 *
 | 
			
		||||
 * \note Freeing the same memory block twice has undefined behavior.
 | 
			
		||||
 *
 | 
			
		||||
 * \note This function works like the ANSI C free().
 | 
			
		||||
 */
 | 
			
		||||
void tcm_heap_free(void *mem)
 | 
			
		||||
{
 | 
			
		||||
	int *_mem = (int *)mem;
 | 
			
		||||
 | 
			
		||||
	if (_mem)
 | 
			
		||||
	{
 | 
			
		||||
		--_mem;
 | 
			
		||||
		tcm_heap_freemem(_mem, *_mem);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void alloc_test(int size, int test_len)
 | 
			
		||||
{
 | 
			
		||||
	//Simple test
 | 
			
		||||
	uint8_t *a[100];
 | 
			
		||||
	int i, j;
 | 
			
		||||
	
 | 
			
		||||
	for (i = 0; i < test_len; i++)
 | 
			
		||||
	{
 | 
			
		||||
		a[i] = tcm_heap_allocmem(size);
 | 
			
		||||
		//ASSERT(a[i]);
 | 
			
		||||
		for (j = 0; j < size; j++)
 | 
			
		||||
			a[i][j] = i;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	//ASSERT(heap_freeSpace(&h) == HEAP_SIZE - test_len * ROUND_UP2(size, sizeof(MemChunk)));
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < test_len; i++)
 | 
			
		||||
	{
 | 
			
		||||
		for (j = 0; j < size; j++)
 | 
			
		||||
		{
 | 
			
		||||
			printf("a[%d][%d] = %d\n", i, j, a[i][j]);
 | 
			
		||||
			//ASSERT(a[i][j] == i);
 | 
			
		||||
		}
 | 
			
		||||
		tcm_heap_freemem(a[i], size);
 | 
			
		||||
	}
 | 
			
		||||
	//ASSERT(heap_freeSpace(&h) == HEAP_SIZE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define ALLOC_SIZE 256
 | 
			
		||||
#define ALLOC_SIZE2 1024
 | 
			
		||||
#define TEST_LEN 20
 | 
			
		||||
#define TEST_LEN2 10
 | 
			
		||||
#define HEAP_SIZE 59*1024
 | 
			
		||||
int tcm_heap_testRun(void)
 | 
			
		||||
{
 | 
			
		||||
	alloc_test(ALLOC_SIZE, TEST_LEN);
 | 
			
		||||
	alloc_test(ALLOC_SIZE2, TEST_LEN2);
 | 
			
		||||
	/* Try to allocate the whole heap */
 | 
			
		||||
	uint8_t *b = tcm_heap_allocmem(HEAP_SIZE);
 | 
			
		||||
	int i, j;
 | 
			
		||||
	//ASSERT(b);
 | 
			
		||||
	//ASSERT(heap_freeSpace(&h) == 0);
 | 
			
		||||
 | 
			
		||||
	//ASSERT(!heap_allocmem(&h, HEAP_SIZE));
 | 
			
		||||
 | 
			
		||||
	for (j = 0; j < HEAP_SIZE; j++)
 | 
			
		||||
		b[j] = j;
 | 
			
		||||
	
 | 
			
		||||
	for (j = 0; j < HEAP_SIZE; j++)
 | 
			
		||||
	{
 | 
			
		||||
		printf("b[%d] = %d\n", j, j);
 | 
			
		||||
		//ASSERT(b[j] == (j & 0xff));
 | 
			
		||||
	}
 | 
			
		||||
	tcm_heap_freemem(b, HEAP_SIZE);
 | 
			
		||||
	//ASSERT(heap_freeSpace(&h) == HEAP_SIZE);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue