+/******************************************************************************
+ Defines
+******************************************************************************/
+/* Type definitions. */
+#define portCHAR char
+#define portFLOAT float
+#define portDOUBLE double
+#define portLONG long
+#define portSHORT short
+#define portSTACK_TYPE int
+#define portBASE_TYPE long
+#define portPOINTER_SIZE_TYPE size_t
+
+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
+
+/* 32/64-bit tick type on a 32/64-bit architecture, so reads of the tick
+count do not need to be guarded with a critical section. */
+#define portTICK_TYPE_IS_ATOMIC 1
+#endif
+
+/* Hardware specifics. */
+#define portSTACK_GROWTH ( -1 )
+#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
+#define portINLINE __inline
+
+#if defined( __x86_64__) || defined( _M_X64 )
+#define portBYTE_ALIGNMENT 8
+#else
+#define portBYTE_ALIGNMENT 4
+#endif
+extern void vPortYield() ;
+#define portYIELD() vPortYield()
+#define OS_CPU_ID current_cpu_id()
+extern int current_cpu_id() ;
+#define OS_CPU_NUM CPU_CORE_NUM
+
+/* Simulated interrupts return pdFALSE if no context switch should be performed,
+or a non-zero number if a context switch should be performed. */
+#define portYIELD_FROM_ISR( x ) return x
+#define portEND_SWITCHING_ISR( x ) portYIELD_FROM_ISR( ( x ) )
+
+void vPortCloseRunningThread(void *pvTaskToDelete, volatile BaseType_t *pxPendYield);
+//void vPortDeleteThread( void *pvThreadToDelete );
+#define portCLEAN_UP_TCB( pxTCB ) //vPortDeleteThread( pxTCB )
+#define portPRE_TASK_DELETE_HOOK( pvTaskToDelete, pxPendYield ) //vPortCloseRunningThread( ( pvTaskToDelete ), ( pxPendYield ) )
+#define portDISABLE_INTERRUPTS() CPU_CRITICAL_ENTER()
+#define portENABLE_INTERRUPTS() CPU_CRITICAL_EXIT()
+
+
+/* Critical section handling. */
+void vPortEnterCritical(void);
+void vPortExitCritical(void);
+//extern void * malloc(int ) ;
+//extern void free(void *) ;
+
+//#define pvPortMalloc malloc
+//#define vPortFree free
+
+/*
+ extern volatile int cpu_lock_cnt[];
+ extern volatile int irq_lock_cnt[];
+#define __asm_csync() \
+ do { \
+ asm volatile("csync;"); \
+ asm volatile("csync;"); \
+ asm volatile("csync;"); \
+ asm volatile("csync;"); \
+ asm volatile("csync;"); \
+ } while (0)
+
+ static inline void local_irq_disable()
+ {
+ __builtin_pi32v2_cli();
+ irq_lock_cnt[current_cpu_id()]++;
+ }
+
+
+ static inline void local_irq_enable()
+ {
+ if (--irq_lock_cnt[current_cpu_id()] == 0) {
+ __builtin_pi32v2_sti();
+ }
+ }
+
+
+ #define CPU_CRITICAL_ENTER() \
+ do { \
+ local_irq_disable(); \
+ if(cpu_lock_cnt[current_cpu_id()]++ == 0) \
+ asm volatile("lockset;"); \
+ __asm_csync(); \
+ }while(0)
+
+
+ #define CPU_CRITICAL_EXIT() \
+ do { \
+ if (--cpu_lock_cnt[current_cpu_id()] == 0) \
+ asm volatile("lockclr;"); \
+ local_irq_enable();\
+ }while(0)
+
+*/
+
+
+#define portENTER_CRITICAL() CPU_CRITICAL_ENTER() // vPortEnterCritical()
+#define portEXIT_CRITICAL() CPU_CRITICAL_EXIT() // vPortExitCritical()
+
+
+#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
+#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
+#endif
+
+#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
+
+/* 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 ) \
+ do { \
+ ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) ); \
+ } while (0)
+
+
+/*-----------------------------------------------------------*/
+
+// uxTopPriority = __builtin_pi32v2_clz(uxReadyPriorities)
+#ifdef __GNUC__
+#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) \
+ uxTopPriority = 31- __builtin_clz(uxReadyPriorities)
+#else
+/* BitScanReverse returns the bit position of the most significant '1'
+in the word. */
+#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) _BitScanReverse( ( DWORD * ) &( uxTopPriority ), ( uxReadyPriorities ) )
+#endif /* __GNUC__ */
+
+#endif /* taskRECORD_READY_PRIORITY */
+
+#ifndef __GNUC__
+__pragma(warning(disable: 4211)) /* Nonstandard extension used, as extern is only nonstandard to MSVC. */
+#endif
+
+
+/* Task function macros as described on the FreeRTOS.org WEB site. */
+#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
+#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
+
+#define portINTERRUPT_YIELD ( 0UL )
+#define portINTERRUPT_TICK ( 1UL )
+
+/*
+ * Raise a simulated interrupt represented by the bit mask in ulInterruptMask.
+ * Each bit can be used to represent an individual interrupt - with the first
+ * two bits being used for the Yield and Tick interrupts respectively.
+*/
+void vPortGenerateSimulatedInterrupt(uint32_t ulInterruptNumber);
+
+/*
+ * Install an interrupt handler to be called by the simulated interrupt handler
+ * thread. The interrupt number must be above any used by the kernel itself
+ * (at the time of writing the kernel was using interrupt numbers 0, 1, and 2
+ * as defined above). The number must also be lower than 32.
+ *
+ * Interrupt handler functions must return a non-zero value if executing the
+ * handler resulted in a task switch being required.
+ */
+void vPortSetInterruptHandler(uint32_t ulInterruptNumber, uint32_t (*pvHandler)(void));
+
+/* 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
+
+#endif
+
diff --git a/include_lib/system/os/FreeRTOS/queue.h b/include_lib/system/os/FreeRTOS/queue.h
new file mode 100644
index 0000000..a90cfca
--- /dev/null
+++ b/include_lib/system/os/FreeRTOS/queue.h
@@ -0,0 +1,1799 @@
+/*
+ FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
+ All rights reserved
+
+ VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
+
+ 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 on the following
+ link: http://www.freertos.org/a00114.html
+
+ ***************************************************************************
+ * *
+ * FreeRTOS provides completely free yet professionally developed, *
+ * robust, strictly quality controlled, supported, and cross *
+ * platform software that is more than just the market leader, it *
+ * is the industry's de facto standard. *
+ * *
+ * Help yourself get started quickly while simultaneously helping *
+ * to support the FreeRTOS project by purchasing a FreeRTOS *
+ * tutorial book, reference manual, or both: *
+ * http://www.FreeRTOS.org/Documentation *
+ * *
+ ***************************************************************************
+
+ http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
+ the FAQ page "My application does not run, what could be wrong?". Have you
+ defined configASSERT()?
+
+ http://www.FreeRTOS.org/support - In return for receiving this top quality
+ embedded software for free we request you assist our global community by
+ participating in the support forum.
+
+ http://www.FreeRTOS.org/training - Investing in training allows your team to
+ be as productive as possible as early as possible. Now you can receive
+ FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
+ Ltd, and the world's leading authority on the world's leading RTOS.
+
+ 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.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
+ Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
+
+ http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
+ Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
+ licenses offer ticketed support, indemnification and commercial 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 QUEUE_H
+#define QUEUE_H
+
+#ifndef INC_FREERTOS_H
+#error "include FreeRTOS.h" must appear in source files before "include queue.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * Type by which queues are referenced. For example, a call to xQueueCreate()
+ * returns an QueueHandle_t variable that can then be used as a parameter to
+ * xQueueSend(), xQueueReceive(), etc.
+ */
+typedef void *QueueHandle_t;
+
+/**
+ * Type by which queue sets are referenced. For example, a call to
+ * xQueueCreateSet() returns an xQueueSet variable that can then be used as a
+ * parameter to xQueueSelectFromSet(), xQueueAddToSet(), etc.
+ */
+typedef void *QueueSetHandle_t;
+
+/**
+ * Queue sets can contain both queues and semaphores, so the
+ * QueueSetMemberHandle_t is defined as a type to be used where a parameter or
+ * return value can be either an QueueHandle_t or an SemaphoreHandle_t.
+ */
+typedef void *QueueSetMemberHandle_t;
+
+/* For internal use only. */
+#define queueSEND_TO_BACK ( ( BaseType_t ) 0 )
+#define queueSEND_TO_FRONT ( ( BaseType_t ) 1 )
+#define queueOVERWRITE ( ( BaseType_t ) 2 )
+
+/* For internal use only. These definitions *must* match those in queue.c. */
+#define queueQUEUE_TYPE_SET ( ( uint8_t ) 0U )
+#define queueQUEUE_TYPE_MUTEX ( ( uint8_t ) 1U )
+#define queueQUEUE_TYPE_COUNTING_SEMAPHORE ( ( uint8_t ) 2U )
+#define queueQUEUE_TYPE_BINARY_SEMAPHORE ( ( uint8_t ) 3U )
+#define queueQUEUE_TYPE_RECURSIVE_MUTEX ( ( uint8_t ) 4U )
+#define queueQUEUE_TYPE_BASE ( ( uint8_t ) 5U )
+
+/**
+ * queue. h
+ *
+ QueueHandle_t xQueueCreate(
+ UBaseType_t uxQueueLength,
+ UBaseType_t uxItemSize
+ );
+ *
+ *
+ * Creates a new queue instance, and returns a handle by which the new queue
+ * can be referenced.
+ *
+ * Internally, within the FreeRTOS implementation, queues use two blocks of
+ * memory. The first block is used to hold the queue's data structures. The
+ * second block is used to hold items placed into the queue. If a queue is
+ * created using xQueueCreate() then both blocks of memory are automatically
+ * dynamically allocated inside the xQueueCreate() function. (see
+ * http://www.freertos.org/a00111.html). If a queue is created using
+ * xQueueCreateStatic() then the application writer must provide the memory that
+ * will get used by the queue. xQueueCreateStatic() therefore allows a queue to
+ * be created without using any dynamic memory allocation.
+ *
+ * http://www.FreeRTOS.org/Embedded-RTOS-Queues.html
+ *
+ * @param uxQueueLength The maximum number of items that the queue can contain.
+ *
+ * @param uxItemSize The number of bytes each item in the queue will require.
+ * Items are queued by copy, not by reference, so this is the number of bytes
+ * that will be copied for each posted item. Each item on the queue must be
+ * the same size.
+ *
+ * @return If the queue is successfully create then a handle to the newly
+ * created queue is returned. If the queue cannot be created then 0 is
+ * returned.
+ *
+ * Example usage:
+
+ struct AMessage
+ {
+ char ucMessageID;
+ char ucData[ 20 ];
+ };
+
+ void vATask( void *pvParameters )
+ {
+ QueueHandle_t xQueue1, xQueue2;
+
+ // Create a queue capable of containing 10 uint32_t values.
+ xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) );
+ if( xQueue1 == 0 )
+ {
+ // Queue was not created and must not be used.
+ }
+
+ // Create a queue capable of containing 10 pointers to AMessage structures.
+ // These should be passed by pointer as they contain a lot of data.
+ xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+ if( xQueue2 == 0 )
+ {
+ // Queue was not created and must not be used.
+ }
+
+ // ... Rest of task code.
+ }
+
+ * \defgroup xQueueCreate xQueueCreate
+ * \ingroup QueueManagement
+ */
+#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
+#define xQueueCreate( uxQueueLength, uxItemSize ) xQueueGenericCreate( ( uxQueueLength ), ( uxItemSize ), ( queueQUEUE_TYPE_BASE ) )
+#endif
+
+/**
+ * queue. h
+ *
+ QueueHandle_t xQueueCreateStatic(
+ UBaseType_t uxQueueLength,
+ UBaseType_t uxItemSize,
+ uint8_t *pucQueueStorageBuffer,
+ StaticQueue_t *pxQueueBuffer
+ );
+ *
+ *
+ * Creates a new queue instance, and returns a handle by which the new queue
+ * can be referenced.
+ *
+ * Internally, within the FreeRTOS implementation, queues use two blocks of
+ * memory. The first block is used to hold the queue's data structures. The
+ * second block is used to hold items placed into the queue. If a queue is
+ * created using xQueueCreate() then both blocks of memory are automatically
+ * dynamically allocated inside the xQueueCreate() function. (see
+ * http://www.freertos.org/a00111.html). If a queue is created using
+ * xQueueCreateStatic() then the application writer must provide the memory that
+ * will get used by the queue. xQueueCreateStatic() therefore allows a queue to
+ * be created without using any dynamic memory allocation.
+ *
+ * http://www.FreeRTOS.org/Embedded-RTOS-Queues.html
+ *
+ * @param uxQueueLength The maximum number of items that the queue can contain.
+ *
+ * @param uxItemSize The number of bytes each item in the queue will require.
+ * Items are queued by copy, not by reference, so this is the number of bytes
+ * that will be copied for each posted item. Each item on the queue must be
+ * the same size.
+ *
+ * @param pucQueueStorageBuffer If uxItemSize is not zero then
+ * pucQueueStorageBuffer must point to a uint8_t array that is at least large
+ * enough to hold the maximum number of items that can be in the queue at any
+ * one time - which is ( uxQueueLength * uxItemsSize ) bytes. If uxItemSize is
+ * zero then pucQueueStorageBuffer can be NULL.
+ *
+ * @param pxQueueBuffer Must point to a variable of type StaticQueue_t, which
+ * will be used to hold the queue's data structure.
+ *
+ * @return If the queue is created then a handle to the created queue is
+ * returned. If pxQueueBuffer is NULL then NULL is returned.
+ *
+ * Example usage:
+
+ struct AMessage
+ {
+ char ucMessageID;
+ char ucData[ 20 ];
+ };
+
+ #define QUEUE_LENGTH 10
+ #define ITEM_SIZE sizeof( uint32_t )
+
+ // xQueueBuffer will hold the queue structure.
+ StaticQueue_t xQueueBuffer;
+
+ // ucQueueStorage will hold the items posted to the queue. Must be at least
+ // [(queue length) * ( queue item size)] bytes long.
+ uint8_t ucQueueStorage[ QUEUE_LENGTH * ITEM_SIZE ];
+
+ void vATask( void *pvParameters )
+ {
+ QueueHandle_t xQueue1;
+
+ // Create a queue capable of containing 10 uint32_t values.
+ xQueue1 = xQueueCreate( QUEUE_LENGTH, // The number of items the queue can hold.
+ ITEM_SIZE // The size of each item in the queue
+ &( ucQueueStorage[ 0 ] ), // The buffer that will hold the items in the queue.
+ &xQueueBuffer ); // The buffer that will hold the queue structure.
+
+ // The queue is guaranteed to be created successfully as no dynamic memory
+ // allocation is used. Therefore xQueue1 is now a handle to a valid queue.
+
+ // ... Rest of task code.
+ }
+
+ * \defgroup xQueueCreateStatic xQueueCreateStatic
+ * \ingroup QueueManagement
+ */
+#if( configSUPPORT_STATIC_ALLOCATION == 1 )
+#define xQueueCreateStatic( uxQueueLength, uxItemSize, pucQueueStorage, pxQueueBuffer ) xQueueGenericCreateStatic( ( uxQueueLength ), ( uxItemSize ), ( pucQueueStorage ), ( pxQueueBuffer ), ( queueQUEUE_TYPE_BASE ) )
+#endif /* configSUPPORT_STATIC_ALLOCATION */
+
+/**
+ * queue. h
+ *
+ BaseType_t xQueueSendToToFront(
+ QueueHandle_t xQueue,
+ const void *pvItemToQueue,
+ TickType_t xTicksToWait
+ );
+ *
+ *
+ * This is a macro that calls xQueueGenericSend().
+ *
+ * Post an item to the front of a queue. The item is queued by copy, not by
+ * reference. This function must not be called from an interrupt service
+ * routine. See xQueueSendFromISR () for an alternative which may be used
+ * in an ISR.
+ *
+ * @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 xTicksToWait The maximum amount of time the task should block
+ * waiting for space to become available on the queue, should it already
+ * be full. The call will return immediately if this is set to 0 and the
+ * queue is full. The time is defined in tick periods so the constant
+ * portTICK_PERIOD_MS should be used to convert to real time if this is required.
+ *
+ * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL.
+ *
+ * Example usage:
+
+ struct AMessage
+ {
+ char ucMessageID;
+ char ucData[ 20 ];
+ } xMessage;
+
+ uint32_t ulVar = 10UL;
+
+ void vATask( void *pvParameters )
+ {
+ QueueHandle_t xQueue1, xQueue2;
+ struct AMessage *pxMessage;
+
+ // Create a queue capable of containing 10 uint32_t values.
+ xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) );
+
+ // Create a queue capable of containing 10 pointers to AMessage structures.
+ // These should be passed by pointer as they contain a lot of data.
+ xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+
+ // ...
+
+ if( xQueue1 != 0 )
+ {
+ // Send an uint32_t. Wait for 10 ticks for space to become
+ // available if necessary.
+ if( xQueueSendToFront( xQueue1, ( void * ) &ulVar, ( TickType_t ) 10 ) != pdPASS )
+ {
+ // Failed to post the message, even after 10 ticks.
+ }
+ }
+
+ if( xQueue2 != 0 )
+ {
+ // Send a pointer to a struct AMessage object. Don't block if the
+ // queue is already full.
+ pxMessage = & xMessage;
+ xQueueSendToFront( xQueue2, ( void * ) &pxMessage, ( TickType_t ) 0 );
+ }
+
+ // ... Rest of task code.
+ }
+
+ * \defgroup xQueueSend xQueueSend
+ * \ingroup QueueManagement
+ */
+#define xQueueSendToFront( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_FRONT )
+
+/**
+ * queue. h
+ *
+ BaseType_t xQueueSendToBack(
+ QueueHandle_t xQueue,
+ const void *pvItemToQueue,
+ TickType_t xTicksToWait
+ );
+ *
+ *
+ * This is a macro that calls xQueueGenericSend().
+ *
+ * Post an item to the back of a queue. The item is queued by copy, not by
+ * reference. This function must not be called from an interrupt service
+ * routine. See xQueueSendFromISR () for an alternative which may be used
+ * in an ISR.
+ *
+ * @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 xTicksToWait The maximum amount of time the task should block
+ * waiting for space to become available on the queue, should it already
+ * be full. The call will return immediately if this is set to 0 and the queue
+ * is full. The time is defined in tick periods so the constant
+ * portTICK_PERIOD_MS should be used to convert to real time if this is required.
+ *
+ * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL.
+ *
+ * Example usage:
+
+ struct AMessage
+ {
+ char ucMessageID;
+ char ucData[ 20 ];
+ } xMessage;
+
+ uint32_t ulVar = 10UL;
+
+ void vATask( void *pvParameters )
+ {
+ QueueHandle_t xQueue1, xQueue2;
+ struct AMessage *pxMessage;
+
+ // Create a queue capable of containing 10 uint32_t values.
+ xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) );
+
+ // Create a queue capable of containing 10 pointers to AMessage structures.
+ // These should be passed by pointer as they contain a lot of data.
+ xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+
+ // ...
+
+ if( xQueue1 != 0 )
+ {
+ // Send an uint32_t. Wait for 10 ticks for space to become
+ // available if necessary.
+ if( xQueueSendToBack( xQueue1, ( void * ) &ulVar, ( TickType_t ) 10 ) != pdPASS )
+ {
+ // Failed to post the message, even after 10 ticks.
+ }
+ }
+
+ if( xQueue2 != 0 )
+ {
+ // Send a pointer to a struct AMessage object. Don't block if the
+ // queue is already full.
+ pxMessage = & xMessage;
+ xQueueSendToBack( xQueue2, ( void * ) &pxMessage, ( TickType_t ) 0 );
+ }
+
+ // ... Rest of task code.
+ }
+
+ * \defgroup xQueueSend xQueueSend
+ * \ingroup QueueManagement
+ */
+#define xQueueSendToBack( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK )
+
+/**
+ * queue. h
+ *
+ BaseType_t xQueueSend(
+ QueueHandle_t xQueue,
+ const void * pvItemToQueue,
+ TickType_t xTicksToWait
+ );
+ *
+ *
+ * This is a macro that calls xQueueGenericSend(). It is included for
+ * backward compatibility with versions of FreeRTOS.org that did not
+ * include the xQueueSendToFront() and xQueueSendToBack() macros. It is
+ * equivalent to xQueueSendToBack().
+ *
+ * Post an item on a queue. The item is queued by copy, not by reference.
+ * This function must not be called from an interrupt service routine.
+ * See xQueueSendFromISR () for an alternative which may be used in an ISR.
+ *
+ * @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 xTicksToWait The maximum amount of time the task should block
+ * waiting for space to become available on the queue, should it already
+ * be full. The call will return immediately if this is set to 0 and the
+ * queue is full. The time is defined in tick periods so the constant
+ * portTICK_PERIOD_MS should be used to convert to real time if this is required.
+ *
+ * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL.
+ *
+ * Example usage:
+
+ struct AMessage
+ {
+ char ucMessageID;
+ char ucData[ 20 ];
+ } xMessage;
+
+ uint32_t ulVar = 10UL;
+
+ void vATask( void *pvParameters )
+ {
+ QueueHandle_t xQueue1, xQueue2;
+ struct AMessage *pxMessage;
+
+ // Create a queue capable of containing 10 uint32_t values.
+ xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) );
+
+ // Create a queue capable of containing 10 pointers to AMessage structures.
+ // These should be passed by pointer as they contain a lot of data.
+ xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+
+ // ...
+
+ if( xQueue1 != 0 )
+ {
+ // Send an uint32_t. Wait for 10 ticks for space to become
+ // available if necessary.
+ if( xQueueSend( xQueue1, ( void * ) &ulVar, ( TickType_t ) 10 ) != pdPASS )
+ {
+ // Failed to post the message, even after 10 ticks.
+ }
+ }
+
+ if( xQueue2 != 0 )
+ {
+ // Send a pointer to a struct AMessage object. Don't block if the
+ // queue is already full.
+ pxMessage = & xMessage;
+ xQueueSend( xQueue2, ( void * ) &pxMessage, ( TickType_t ) 0 );
+ }
+
+ // ... Rest of task code.
+ }
+
+ * \defgroup xQueueSend xQueueSend
+ * \ingroup QueueManagement
+ */
+#define xQueueSend( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK )
+
+/**
+ * queue. h
+ *
+ BaseType_t xQueueOverwrite(
+ QueueHandle_t xQueue,
+ const void * pvItemToQueue
+ );
+ *
+ *
+ * Only for use with queues that have a length of one - so the queue is either
+ * empty or full.
+ *
+ * Post an item on a queue. If the queue is already full then overwrite the
+ * value held in the queue. The item is queued by copy, not by reference.
+ *
+ * This function must not be called from an interrupt service routine.
+ * See xQueueOverwriteFromISR () for an alternative which may be used in an ISR.
+ *
+ * @param xQueue The handle of the queue to which the data is being sent.
+ *
+ * @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.
+ *
+ * @return xQueueOverwrite() is a macro that calls xQueueGenericSend(), and
+ * therefore has the same return values as xQueueSendToFront(). However, pdPASS
+ * is the only value that can be returned because xQueueOverwrite() will write
+ * to the queue even when the queue is already full.
+ *
+ * Example usage:
+
+
+ void vFunction( void *pvParameters )
+ {
+ QueueHandle_t xQueue;
+ uint32_t ulVarToSend, ulValReceived;
+
+ // Create a queue to hold one uint32_t value. It is strongly
+ // recommended *not* to use xQueueOverwrite() on queues that can
+ // contain more than one value, and doing so will trigger an assertion
+ // if configASSERT() is defined.
+ xQueue = xQueueCreate( 1, sizeof( uint32_t ) );
+
+ // Write the value 10 to the queue using xQueueOverwrite().
+ ulVarToSend = 10;
+ xQueueOverwrite( xQueue, &ulVarToSend );
+
+ // Peeking the queue should now return 10, but leave the value 10 in
+ // the queue. A block time of zero is used as it is known that the
+ // queue holds a value.
+ ulValReceived = 0;
+ xQueuePeek( xQueue, &ulValReceived, 0 );
+
+ if( ulValReceived != 10 )
+ {
+ // Error unless the item was removed by a different task.
+ }
+
+ // The queue is still full. Use xQueueOverwrite() to overwrite the
+ // value held in the queue with 100.
+ ulVarToSend = 100;
+ xQueueOverwrite( xQueue, &ulVarToSend );
+
+ // This time read from the queue, leaving the queue empty once more.
+ // A block time of 0 is used again.
+ xQueueReceive( xQueue, &ulValReceived, 0 );
+
+ // The value read should be the last value written, even though the
+ // queue was already full when the value was written.
+ if( ulValReceived != 100 )
+ {
+ // Error!
+ }
+
+ // ...
+}
+
+ * \defgroup xQueueOverwrite xQueueOverwrite
+ * \ingroup QueueManagement
+ */
+#define xQueueOverwrite( xQueue, pvItemToQueue ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), 0, queueOVERWRITE )
+
+
+/**
+ * queue. h
+ *
+ BaseType_t xQueueGenericSend(
+ QueueHandle_t xQueue,
+ const void * pvItemToQueue,
+ TickType_t xTicksToWait
+ BaseType_t xCopyPosition
+ );
+ *
+ *
+ * It is preferred that the macros xQueueSend(), xQueueSendToFront() and
+ * xQueueSendToBack() are used in place of calling this function directly.
+ *
+ * Post an item on a queue. The item is queued by copy, not by reference.
+ * This function must not be called from an interrupt service routine.
+ * See xQueueSendFromISR () for an alternative which may be used in an ISR.
+ *
+ * @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 xTicksToWait The maximum amount of time the task should block
+ * waiting for space to become available on the queue, should it already
+ * be full. The call will return immediately if this is set to 0 and the
+ * queue is full. The time is defined in tick periods so the constant
+ * portTICK_PERIOD_MS should be used to convert to real time if this is required.
+ *
+ * @param xCopyPosition Can take the value queueSEND_TO_BACK to place the
+ * item at the back of the queue, or queueSEND_TO_FRONT to place the item
+ * at the front of the queue (for high priority messages).
+ *
+ * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL.
+ *
+ * Example usage:
+
+ struct AMessage
+ {
+ char ucMessageID;
+ char ucData[ 20 ];
+ } xMessage;
+
+ uint32_t ulVar = 10UL;
+
+ void vATask( void *pvParameters )
+ {
+ QueueHandle_t xQueue1, xQueue2;
+ struct AMessage *pxMessage;
+
+ // Create a queue capable of containing 10 uint32_t values.
+ xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) );
+
+ // Create a queue capable of containing 10 pointers to AMessage structures.
+ // These should be passed by pointer as they contain a lot of data.
+ xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+
+ // ...
+
+ if( xQueue1 != 0 )
+ {
+ // Send an uint32_t. Wait for 10 ticks for space to become
+ // available if necessary.
+ if( xQueueGenericSend( xQueue1, ( void * ) &ulVar, ( TickType_t ) 10, queueSEND_TO_BACK ) != pdPASS )
+ {
+ // Failed to post the message, even after 10 ticks.
+ }
+ }
+
+ if( xQueue2 != 0 )
+ {
+ // Send a pointer to a struct AMessage object. Don't block if the
+ // queue is already full.
+ pxMessage = & xMessage;
+ xQueueGenericSend( xQueue2, ( void * ) &pxMessage, ( TickType_t ) 0, queueSEND_TO_BACK );
+ }
+
+ // ... Rest of task code.
+ }
+
+ * \defgroup xQueueSend xQueueSend
+ * \ingroup QueueManagement
+ */
+BaseType_t xQueueGenericSend(QueueHandle_t xQueue, const void *const pvItemToQueue, TickType_t xTicksToWait, const BaseType_t xCopyPosition) PRIVILEGED_FUNCTION;
+
+/**
+ * queue. h
+ *
+ BaseType_t xQueuePeek(
+ QueueHandle_t xQueue,
+ void *pvBuffer,
+ TickType_t xTicksToWait
+ );
+ *
+ * This is a macro that calls the xQueueGenericReceive() function.
+ *
+ * Receive an item from a queue without removing the item from the queue.
+ * The item is received by copy so a buffer of adequate size must be
+ * provided. The number of bytes copied into the buffer was defined when
+ * the queue was created.
+ *
+ * Successfully received items remain on the queue so will be returned again
+ * by the next call, or a call to xQueueReceive().
+ *
+ * This macro must not be used in an interrupt service routine. See
+ * xQueuePeekFromISR() for an alternative that can be called from an interrupt
+ * service routine.
+ *
+ * @param xQueue The handle to the queue from which the item is to be
+ * received.
+ *
+ * @param pvBuffer Pointer to the buffer into which the received item will
+ * be copied.
+ *
+ * @param xTicksToWait The maximum amount of time the task should block
+ * waiting for an item to receive should the queue be empty at the time
+ * of the call. The time is defined in tick periods so the constant
+ * portTICK_PERIOD_MS should be used to convert to real time if this is required.
+ * xQueuePeek() will return immediately if xTicksToWait is 0 and the queue
+ * is empty.
+ *
+ * @return pdTRUE if an item was successfully received from the queue,
+ * otherwise pdFALSE.
+ *
+ * Example usage:
+
+ struct AMessage
+ {
+ char ucMessageID;
+ char ucData[ 20 ];
+ } xMessage;
+
+ QueueHandle_t xQueue;
+
+ // Task to create a queue and post a value.
+ void vATask( void *pvParameters )
+ {
+ struct AMessage *pxMessage;
+
+ // Create a queue capable of containing 10 pointers to AMessage structures.
+ // These should be passed by pointer as they contain a lot of data.
+ xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );
+ if( xQueue == 0 )
+ {
+ // Failed to create the queue.
+ }
+
+ // ...
+
+ // Send a pointer to a struct AMessage object. Don't block if the
+ // queue is already full.
+ pxMessage = & xMessage;
+ xQueueSend( xQueue, ( void * ) &pxMessage, ( TickType_t ) 0 );
+
+ // ... Rest of task code.
+ }
+
+ // Task to peek the data from the queue.
+ void vADifferentTask( void *pvParameters )
+ {
+ struct AMessage *pxRxedMessage;
+
+ if( xQueue != 0 )
+ {
+ // Peek a message on the created queue. Block for 10 ticks if a
+ // message is not immediately available.
+ if( xQueuePeek( xQueue, &( pxRxedMessage ), ( TickType_t ) 10 ) )
+ {
+ // pcRxedMessage now points to the struct AMessage variable posted
+ // by vATask, but the item still remains on the queue.
+ }
+ }
+
+ // ... Rest of task code.
+ }
+
+ * \defgroup xQueueReceive xQueueReceive
+ * \ingroup QueueManagement
+ */
+#define xQueuePeek( xQueue, pvBuffer, xTicksToWait ) xQueueGenericReceive( ( xQueue ), ( pvBuffer ), ( xTicksToWait ), pdTRUE )
+
+/**
+ * queue. h
+ *
+ BaseType_t xQueuePeekFromISR(
+ QueueHandle_t xQueue,
+ void *pvBuffer,
+ );
+ *
+ * A version of xQueuePeek() that can be called from an interrupt service
+ * routine (ISR).
+ *
+ * Receive an item from a queue without removing the item from the queue.
+ * The item is received by copy so a buffer of adequate size must be
+ * provided. The number of bytes copied into the buffer was defined when
+ * the queue was created.
+ *
+ * Successfully received items remain on the queue so will be returned again
+ * by the next call, or a call to xQueueReceive().
+ *
+ * @param xQueue The handle to the queue from which the item is to be
+ * received.
+ *
+ * @param pvBuffer Pointer to the buffer into which the received item will
+ * be copied.
+ *
+ * @return pdTRUE if an item was successfully received from the queue,
+ * otherwise pdFALSE.
+ *
+ * \defgroup xQueuePeekFromISR xQueuePeekFromISR
+ * \ingroup QueueManagement
+ */
+BaseType_t xQueuePeekFromISR(QueueHandle_t xQueue, void *const pvBuffer) PRIVILEGED_FUNCTION;
+
+/**
+ * queue. h
+ *
+ BaseType_t xQueueReceive(
+ QueueHandle_t xQueue,
+ void *pvBuffer,
+ TickType_t xTicksToWait
+ );
+ *
+ * This is a macro that calls the xQueueGenericReceive() function.
+ *
+ * Receive an item from a queue. The item is received by copy so a buffer of
+ * adequate size must be provided. The number of bytes copied into the buffer
+ * was defined when the queue was created.
+ *
+ * Successfully received items are removed from the queue.
+ *
+ * This function must not be used in an interrupt service routine. See
+ * xQueueReceiveFromISR for an alternative that can.
+ *
+ * @param xQueue The handle to the queue from which the item is to be
+ * received.
+ *
+ * @param pvBuffer Pointer to the buffer into which the received item will
+ * be copied.
+ *
+ * @param xTicksToWait The maximum amount of time the task should block
+ * waiting for an item to receive should the queue be empty at the time
+ * of the call. xQueueReceive() will return immediately if xTicksToWait
+ * is zero and the queue is empty. The time is defined in tick periods so the
+ * constant portTICK_PERIOD_MS should be used to convert to real time if this is
+ * required.
+ *
+ * @return pdTRUE if an item was successfully received from the queue,
+ * otherwise pdFALSE.
+ *
+ * Example usage:
+
+ struct AMessage
+ {
+ char ucMessageID;
+ char ucData[ 20 ];
+ } xMessage;
+
+ QueueHandle_t xQueue;
+
+ // Task to create a queue and post a value.
+ void vATask( void *pvParameters )
+ {
+ struct AMessage *pxMessage;
+
+ // Create a queue capable of containing 10 pointers to AMessage structures.
+ // These should be passed by pointer as they contain a lot of data.
+ xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );
+ if( xQueue == 0 )
+ {
+ // Failed to create the queue.
+ }
+
+ // ...
+
+ // Send a pointer to a struct AMessage object. Don't block if the
+ // queue is already full.
+ pxMessage = & xMessage;
+ xQueueSend( xQueue, ( void * ) &pxMessage, ( TickType_t ) 0 );
+
+ // ... Rest of task code.
+ }
+
+ // Task to receive from the queue.
+ void vADifferentTask( void *pvParameters )
+ {
+ struct AMessage *pxRxedMessage;
+
+ if( xQueue != 0 )
+ {
+ // Receive a message on the created queue. Block for 10 ticks if a
+ // message is not immediately available.
+ if( xQueueReceive( xQueue, &( pxRxedMessage ), ( TickType_t ) 10 ) )
+ {
+ // pcRxedMessage now points to the struct AMessage variable posted
+ // by vATask.
+ }
+ }
+
+ // ... Rest of task code.
+ }
+
+ * \defgroup xQueueReceive xQueueReceive
+ * \ingroup QueueManagement
+ */
+#define xQueueReceive( xQueue, pvBuffer, xTicksToWait ) xQueueGenericReceive( ( xQueue ), ( pvBuffer ), ( xTicksToWait ), pdFALSE )
+
+
+/**
+ * queue. h
+ *
+ BaseType_t xQueueGenericReceive(
+ QueueHandle_t xQueue,
+ void *pvBuffer,
+ TickType_t xTicksToWait
+ BaseType_t xJustPeek
+ );
+ *
+ * It is preferred that the macro xQueueReceive() be used rather than calling
+ * this function directly.
+ *
+ * Receive an item from a queue. The item is received by copy so a buffer of
+ * adequate size must be provided. The number of bytes copied into the buffer
+ * was defined when the queue was created.
+ *
+ * This function must not be used in an interrupt service routine. See
+ * xQueueReceiveFromISR for an alternative that can.
+ *
+ * @param xQueue The handle to the queue from which the item is to be
+ * received.
+ *
+ * @param pvBuffer Pointer to the buffer into which the received item will
+ * be copied.
+ *
+ * @param xTicksToWait The maximum amount of time the task should block
+ * waiting for an item to receive should the queue be empty at the time
+ * of the call. The time is defined in tick periods so the constant
+ * portTICK_PERIOD_MS should be used to convert to real time if this is required.
+ * xQueueGenericReceive() will return immediately if the queue is empty and
+ * xTicksToWait is 0.
+ *
+ * @param xJustPeek When set to true, the item received from the queue is not
+ * actually removed from the queue - meaning a subsequent call to
+ * xQueueReceive() will return the same item. When set to false, the item
+ * being received from the queue is also removed from the queue.
+ *
+ * @return pdTRUE if an item was successfully received from the queue,
+ * otherwise pdFALSE.
+ *
+ * Example usage:
+
+ struct AMessage
+ {
+ char ucMessageID;
+ char ucData[ 20 ];
+ } xMessage;
+
+ QueueHandle_t xQueue;
+
+ // Task to create a queue and post a value.
+ void vATask( void *pvParameters )
+ {
+ struct AMessage *pxMessage;
+
+ // Create a queue capable of containing 10 pointers to AMessage structures.
+ // These should be passed by pointer as they contain a lot of data.
+ xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );
+ if( xQueue == 0 )
+ {
+ // Failed to create the queue.
+ }
+
+ // ...
+
+ // Send a pointer to a struct AMessage object. Don't block if the
+ // queue is already full.
+ pxMessage = & xMessage;
+ xQueueSend( xQueue, ( void * ) &pxMessage, ( TickType_t ) 0 );
+
+ // ... Rest of task code.
+ }
+
+ // Task to receive from the queue.
+ void vADifferentTask( void *pvParameters )
+ {
+ struct AMessage *pxRxedMessage;
+
+ if( xQueue != 0 )
+ {
+ // Receive a message on the created queue. Block for 10 ticks if a
+ // message is not immediately available.
+ if( xQueueGenericReceive( xQueue, &( pxRxedMessage ), ( TickType_t ) 10 ) )
+ {
+ // pcRxedMessage now points to the struct AMessage variable posted
+ // by vATask.
+ }
+ }
+
+ // ... Rest of task code.
+ }
+
+ * \defgroup xQueueReceive xQueueReceive
+ * \ingroup QueueManagement
+ */
+BaseType_t xQueueGenericReceive(QueueHandle_t xQueue, void *const pvBuffer, TickType_t xTicksToWait, const BaseType_t xJustPeek) PRIVILEGED_FUNCTION;
+
+/**
+ * queue. h
+ * UBaseType_t uxQueueMessagesWaiting( const QueueHandle_t xQueue );
+ *
+ * Return the number of messages stored in a queue.
+ *
+ * @param xQueue A handle to the queue being queried.
+ *
+ * @return The number of messages available in the queue.
+ *
+ * \defgroup uxQueueMessagesWaiting uxQueueMessagesWaiting
+ * \ingroup QueueManagement
+ */
+UBaseType_t uxQueueMessagesWaiting(const QueueHandle_t xQueue) PRIVILEGED_FUNCTION;
+
+/**
+ * queue. h
+ * UBaseType_t uxQueueSpacesAvailable( const QueueHandle_t xQueue );
+ *
+ * Return the number of free spaces available in a queue. This is equal to the
+ * number of items that can be sent to the queue before the queue becomes full
+ * if no items are removed.
+ *
+ * @param xQueue A handle to the queue being queried.
+ *
+ * @return The number of spaces available in the queue.
+ *
+ * \defgroup uxQueueMessagesWaiting uxQueueMessagesWaiting
+ * \ingroup QueueManagement
+ */
+UBaseType_t uxQueueSpacesAvailable(const QueueHandle_t xQueue) PRIVILEGED_FUNCTION;
+
+/**
+ * queue. h
+ * void vQueueDelete( QueueHandle_t xQueue );
+ *
+ * Delete a queue - freeing all the memory allocated for storing of items
+ * placed on the queue.
+ *
+ * @param xQueue A handle to the queue to be deleted.
+ *
+ * \defgroup vQueueDelete vQueueDelete
+ * \ingroup QueueManagement
+ */
+void vQueueDelete(QueueHandle_t xQueue) PRIVILEGED_FUNCTION;
+
+/**
+ * queue. h
+ *
+ BaseType_t xQueueSendToFrontFromISR(
+ QueueHandle_t xQueue,
+ const void *pvItemToQueue,
+ BaseType_t *pxHigherPriorityTaskWoken
+ );
+
+ *
+ * This is a macro that calls xQueueGenericSendFromISR().
+ *
+ * Post an item to the front of a queue. It is safe to use this macro from
+ * within an interrupt service routine.
+ *
+ * Items are queued by copy not reference so it is preferable to only
+ * queue small items, especially when called from an ISR. In most cases
+ * it would be preferable to store a pointer to the item being queued.
+ *
+ * @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 pxHigherPriorityTaskWoken xQueueSendToFrontFromISR() will set
+ * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task
+ * to unblock, and the unblocked task has a priority higher than the currently
+ * running task. If xQueueSendToFromFromISR() sets this value to pdTRUE then
+ * a context switch should be requested before the interrupt is exited.
+ *
+ * @return pdTRUE if the data was successfully sent to the queue, otherwise
+ * errQUEUE_FULL.
+ *
+ * Example usage for buffered IO (where the ISR can obtain more than one value
+ * per call):
+
+ void vBufferISR( void )
+ {
+ char cIn;
+ BaseType_t xHigherPrioritTaskWoken;
+
+ // We have not woken a task at the start of the ISR.
+ xHigherPriorityTaskWoken = pdFALSE;
+
+ // Loop until the buffer is empty.
+ do
+ {
+ // Obtain a byte from the buffer.
+ cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
+
+ // Post the byte.
+ xQueueSendToFrontFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );
+
+ } while( portINPUT_BYTE( BUFFER_COUNT ) );
+
+ // Now the buffer is empty we can switch context if necessary.
+ if( xHigherPriorityTaskWoken )
+ {
+ taskYIELD ();
+ }
+ }
+
+ *
+ * \defgroup xQueueSendFromISR xQueueSendFromISR
+ * \ingroup QueueManagement
+ */
+#define xQueueSendToFrontFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_FRONT )
+
+
+/**
+ * queue. h
+ *
+ BaseType_t xQueueSendToBackFromISR(
+ QueueHandle_t xQueue,
+ const void *pvItemToQueue,
+ BaseType_t *pxHigherPriorityTaskWoken
+ );
+
+ *
+ * This is a macro that calls xQueueGenericSendFromISR().
+ *
+ * Post an item to the back of a queue. It is safe to use this macro from
+ * within an interrupt service routine.
+ *
+ * Items are queued by copy not reference so it is preferable to only
+ * queue small items, especially when called from an ISR. In most cases
+ * it would be preferable to store a pointer to the item being queued.
+ *
+ * @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 pxHigherPriorityTaskWoken xQueueSendToBackFromISR() will set
+ * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task
+ * to unblock, and the unblocked task has a priority higher than the currently
+ * running task. If xQueueSendToBackFromISR() sets this value to pdTRUE then
+ * a context switch should be requested before the interrupt is exited.
+ *
+ * @return pdTRUE if the data was successfully sent to the queue, otherwise
+ * errQUEUE_FULL.
+ *
+ * Example usage for buffered IO (where the ISR can obtain more than one value
+ * per call):
+
+ void vBufferISR( void )
+ {
+ char cIn;
+ BaseType_t xHigherPriorityTaskWoken;
+
+ // We have not woken a task at the start of the ISR.
+ xHigherPriorityTaskWoken = pdFALSE;
+
+ // Loop until the buffer is empty.
+ do
+ {
+ // Obtain a byte from the buffer.
+ cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
+
+ // Post the byte.
+ xQueueSendToBackFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );
+
+ } while( portINPUT_BYTE( BUFFER_COUNT ) );
+
+ // Now the buffer is empty we can switch context if necessary.
+ if( xHigherPriorityTaskWoken )
+ {
+ taskYIELD ();
+ }
+ }
+
+ *
+ * \defgroup xQueueSendFromISR xQueueSendFromISR
+ * \ingroup QueueManagement
+ */
+#define xQueueSendToBackFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_BACK )
+
+/**
+ * queue. h
+ *
+ BaseType_t xQueueOverwriteFromISR(
+ QueueHandle_t xQueue,
+ const void * pvItemToQueue,
+ BaseType_t *pxHigherPriorityTaskWoken
+ );
+ *
+ *
+ * A version of xQueueOverwrite() that can be used in an interrupt service
+ * routine (ISR).
+ *
+ * Only for use with queues that can hold a single item - so the queue is either
+ * empty or full.
+ *
+ * Post an item on a queue. If the queue is already full then overwrite the
+ * value held in the queue. The item is queued by copy, not by reference.
+ *
+ * @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 pxHigherPriorityTaskWoken xQueueOverwriteFromISR() will set
+ * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task
+ * to unblock, and the unblocked task has a priority higher than the currently
+ * running task. If xQueueOverwriteFromISR() sets this value to pdTRUE then
+ * a context switch should be requested before the interrupt is exited.
+ *
+ * @return xQueueOverwriteFromISR() is a macro that calls
+ * xQueueGenericSendFromISR(), and therefore has the same return values as
+ * xQueueSendToFrontFromISR(). However, pdPASS is the only value that can be
+ * returned because xQueueOverwriteFromISR() will write to the queue even when
+ * the queue is already full.
+ *
+ * Example usage:
+
+
+ QueueHandle_t xQueue;
+
+ void vFunction( void *pvParameters )
+ {
+ // Create a queue to hold one uint32_t value. It is strongly
+ // recommended *not* to use xQueueOverwriteFromISR() on queues that can
+ // contain more than one value, and doing so will trigger an assertion
+ // if configASSERT() is defined.
+ xQueue = xQueueCreate( 1, sizeof( uint32_t ) );
+}
+
+void vAnInterruptHandler( void )
+{
+// xHigherPriorityTaskWoken must be set to pdFALSE before it is used.
+BaseType_t xHigherPriorityTaskWoken = pdFALSE;
+uint32_t ulVarToSend, ulValReceived;
+
+ // Write the value 10 to the queue using xQueueOverwriteFromISR().
+ ulVarToSend = 10;
+ xQueueOverwriteFromISR( xQueue, &ulVarToSend, &xHigherPriorityTaskWoken );
+
+ // The queue is full, but calling xQueueOverwriteFromISR() again will still
+ // pass because the value held in the queue will be overwritten with the
+ // new value.
+ ulVarToSend = 100;
+ xQueueOverwriteFromISR( xQueue, &ulVarToSend, &xHigherPriorityTaskWoken );
+
+ // Reading from the queue will now return 100.
+
+ // ...
+
+ if( xHigherPrioritytaskWoken == pdTRUE )
+ {
+ // Writing to the queue caused a task to unblock and the unblocked task
+ // has a priority higher than or equal to the priority of the currently
+ // executing task (the task this interrupt interrupted). Perform a context
+ // switch so this interrupt returns directly to the unblocked task.
+ portYIELD_FROM_ISR(); // or portEND_SWITCHING_ISR() depending on the port.
+ }
+}
+
+ * \defgroup xQueueOverwriteFromISR xQueueOverwriteFromISR
+ * \ingroup QueueManagement
+ */
+#define xQueueOverwriteFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueOVERWRITE )
+
+/**
+ * queue. h
+ *
+ BaseType_t xQueueSendFromISR(
+ QueueHandle_t xQueue,
+ const void *pvItemToQueue,
+ BaseType_t *pxHigherPriorityTaskWoken
+ );
+
+ *
+ * This is a macro that calls xQueueGenericSendFromISR(). It is included
+ * for backward compatibility with versions of FreeRTOS.org that did not
+ * include the xQueueSendToBackFromISR() and xQueueSendToFrontFromISR()
+ * macros.
+ *
+ * Post an item to the back of a queue. It is safe to use this function from
+ * within an interrupt service routine.
+ *
+ * Items are queued by copy not reference so it is preferable to only
+ * queue small items, especially when called from an ISR. In most cases
+ * it would be preferable to store a pointer to the item being queued.
+ *
+ * @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 pxHigherPriorityTaskWoken xQueueSendFromISR() will set
+ * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task
+ * to unblock, and the unblocked task has a priority higher than the currently
+ * running task. If xQueueSendFromISR() sets this value to pdTRUE then
+ * a context switch should be requested before the interrupt is exited.
+ *
+ * @return pdTRUE if the data was successfully sent to the queue, otherwise
+ * errQUEUE_FULL.
+ *
+ * Example usage for buffered IO (where the ISR can obtain more than one value
+ * per call):
+
+ void vBufferISR( void )
+ {
+ char cIn;
+ BaseType_t xHigherPriorityTaskWoken;
+
+ // We have not woken a task at the start of the ISR.
+ xHigherPriorityTaskWoken = pdFALSE;
+
+ // Loop until the buffer is empty.
+ do
+ {
+ // Obtain a byte from the buffer.
+ cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
+
+ // Post the byte.
+ xQueueSendFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );
+
+ } while( portINPUT_BYTE( BUFFER_COUNT ) );
+
+ // Now the buffer is empty we can switch context if necessary.
+ if( xHigherPriorityTaskWoken )
+ {
+ // Actual macro used here is port specific.
+ portYIELD_FROM_ISR ();
+ }
+ }
+
+ *
+ * \defgroup xQueueSendFromISR xQueueSendFromISR
+ * \ingroup QueueManagement
+ */
+#define xQueueSendFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_BACK )
+
+/**
+ * queue. h
+ *
+ BaseType_t xQueueGenericSendFromISR(
+ QueueHandle_t xQueue,
+ const void *pvItemToQueue,
+ BaseType_t *pxHigherPriorityTaskWoken,
+ BaseType_t xCopyPosition
+ );
+
+ *
+ * It is preferred that the macros xQueueSendFromISR(),
+ * xQueueSendToFrontFromISR() and xQueueSendToBackFromISR() be used in place
+ * of calling this function directly. xQueueGiveFromISR() is an
+ * equivalent for use by semaphores that don't actually copy any data.
+ *
+ * Post an item on a queue. It is safe to use this function from within an
+ * interrupt service routine.
+ *
+ * Items are queued by copy not reference so it is preferable to only
+ * queue small items, especially when called from an ISR. In most cases
+ * it would be preferable to store a pointer to the item being queued.
+ *
+ * @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 pxHigherPriorityTaskWoken xQueueGenericSendFromISR() will set
+ * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task
+ * to unblock, and the unblocked task has a priority higher than the currently
+ * running task. If xQueueGenericSendFromISR() sets this value to pdTRUE then
+ * a context switch should be requested before the interrupt is exited.
+ *
+ * @param xCopyPosition Can take the value queueSEND_TO_BACK to place the
+ * item at the back of the queue, or queueSEND_TO_FRONT to place the item
+ * at the front of the queue (for high priority messages).
+ *
+ * @return pdTRUE if the data was successfully sent to the queue, otherwise
+ * errQUEUE_FULL.
+ *
+ * Example usage for buffered IO (where the ISR can obtain more than one value
+ * per call):
+
+ void vBufferISR( void )
+ {
+ char cIn;
+ BaseType_t xHigherPriorityTaskWokenByPost;
+
+ // We have not woken a task at the start of the ISR.
+ xHigherPriorityTaskWokenByPost = pdFALSE;
+
+ // Loop until the buffer is empty.
+ do
+ {
+ // Obtain a byte from the buffer.
+ cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
+
+ // Post each byte.
+ xQueueGenericSendFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWokenByPost, queueSEND_TO_BACK );
+
+ } while( portINPUT_BYTE( BUFFER_COUNT ) );
+
+ // Now the buffer is empty we can switch context if necessary. Note that the
+ // name of the yield function required is port specific.
+ if( xHigherPriorityTaskWokenByPost )
+ {
+ taskYIELD_YIELD_FROM_ISR();
+ }
+ }
+
+ *
+ * \defgroup xQueueSendFromISR xQueueSendFromISR
+ * \ingroup QueueManagement
+ */
+BaseType_t xQueueGenericSendFromISR(QueueHandle_t xQueue, const void *const pvItemToQueue, BaseType_t *const pxHigherPriorityTaskWoken, const BaseType_t xCopyPosition) PRIVILEGED_FUNCTION;
+BaseType_t xQueueGiveFromISR(QueueHandle_t xQueue, BaseType_t *const pxHigherPriorityTaskWoken) PRIVILEGED_FUNCTION;
+
+/**
+ * queue. h
+ *
+ BaseType_t xQueueReceiveFromISR(
+ QueueHandle_t xQueue,
+ void *pvBuffer,
+ BaseType_t *pxTaskWoken
+ );
+ *
+ *
+ * Receive an item from a queue. It is safe to use this function from within an
+ * interrupt service routine.
+ *
+ * @param xQueue The handle to the queue from which the item is to be
+ * received.
+ *
+ * @param pvBuffer Pointer to the buffer into which the received item will
+ * be copied.
+ *
+ * @param pxTaskWoken A task may be blocked waiting for space to become
+ * available on the queue. If xQueueReceiveFromISR causes such a task to
+ * unblock *pxTaskWoken will get set to pdTRUE, otherwise *pxTaskWoken will
+ * remain unchanged.
+ *
+ * @return pdTRUE if an item was successfully received from the queue,
+ * otherwise pdFALSE.
+ *
+ * Example usage:
+
+
+ QueueHandle_t xQueue;
+
+ // Function to create a queue and post some values.
+ void vAFunction( void *pvParameters )
+ {
+ char cValueToPost;
+ const TickType_t xTicksToWait = ( TickType_t )0xff;
+
+ // Create a queue capable of containing 10 characters.
+ xQueue = xQueueCreate( 10, sizeof( char ) );
+ if( xQueue == 0 )
+ {
+ // Failed to create the queue.
+ }
+
+ // ...
+
+ // Post some characters that will be used within an ISR. If the queue
+ // is full then this task will block for xTicksToWait ticks.
+ cValueToPost = 'a';
+ xQueueSend( xQueue, ( void * ) &cValueToPost, xTicksToWait );
+ cValueToPost = 'b';
+ xQueueSend( xQueue, ( void * ) &cValueToPost, xTicksToWait );
+
+ // ... keep posting characters ... this task may block when the queue
+ // becomes full.
+
+ cValueToPost = 'c';
+ xQueueSend( xQueue, ( void * ) &cValueToPost, xTicksToWait );
+ }
+
+ // ISR that outputs all the characters received on the queue.
+ void vISR_Routine( void )
+ {
+ BaseType_t xTaskWokenByReceive = pdFALSE;
+ char cRxedChar;
+
+ while( xQueueReceiveFromISR( xQueue, ( void * ) &cRxedChar, &xTaskWokenByReceive) )
+ {
+ // A character was received. Output the character now.
+ vOutputCharacter( cRxedChar );
+
+ // If removing the character from the queue woke the task that was
+ // posting onto the queue cTaskWokenByReceive will have been set to
+ // pdTRUE. No matter how many times this loop iterates only one
+ // task will be woken.
+ }
+
+ if( cTaskWokenByPost != ( char ) pdFALSE;
+ {
+ taskYIELD ();
+ }
+ }
+
+ * \defgroup xQueueReceiveFromISR xQueueReceiveFromISR
+ * \ingroup QueueManagement
+ */
+BaseType_t xQueueReceiveFromISR(QueueHandle_t xQueue, void *const pvBuffer, BaseType_t *const pxHigherPriorityTaskWoken) PRIVILEGED_FUNCTION;
+
+/*
+ * Utilities to query queues that are safe to use from an ISR. These utilities
+ * should be used only from witin an ISR, or within a critical section.
+ */
+BaseType_t xQueueIsQueueEmptyFromISR(const QueueHandle_t xQueue) PRIVILEGED_FUNCTION;
+BaseType_t xQueueIsQueueFullFromISR(const QueueHandle_t xQueue) PRIVILEGED_FUNCTION;
+UBaseType_t uxQueueMessagesWaitingFromISR(const QueueHandle_t xQueue) PRIVILEGED_FUNCTION;
+
+/*
+ * The functions defined above are for passing data to and from tasks. The
+ * functions below are the equivalents for passing data to and from
+ * co-routines.
+ *
+ * These functions are called from the co-routine macro implementation and
+ * should not be called directly from application code. Instead use the macro
+ * wrappers defined within croutine.h.
+ */
+BaseType_t xQueueCRSendFromISR(QueueHandle_t xQueue, const void *pvItemToQueue, BaseType_t xCoRoutinePreviouslyWoken);
+BaseType_t xQueueCRReceiveFromISR(QueueHandle_t xQueue, void *pvBuffer, BaseType_t *pxTaskWoken);
+BaseType_t xQueueCRSend(QueueHandle_t xQueue, const void *pvItemToQueue, TickType_t xTicksToWait);
+BaseType_t xQueueCRReceive(QueueHandle_t xQueue, void *pvBuffer, TickType_t xTicksToWait);
+
+/*
+ * For internal use only. Use xSemaphoreCreateMutex(),
+ * xSemaphoreCreateCounting() or xSemaphoreGetMutexHolder() instead of calling
+ * these functions directly.
+ */
+QueueHandle_t xQueueCreateMutex(const uint8_t ucQueueType) PRIVILEGED_FUNCTION;
+QueueHandle_t xQueueCreateMutexStatic(const uint8_t ucQueueType, StaticQueue_t *pxStaticQueue) PRIVILEGED_FUNCTION;
+QueueHandle_t xQueueCreateCountingSemaphore(const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount) PRIVILEGED_FUNCTION;
+QueueHandle_t xQueueCreateCountingSemaphoreStatic(const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount, StaticQueue_t *pxStaticQueue) PRIVILEGED_FUNCTION;
+void *xQueueGetMutexHolder(QueueHandle_t xSemaphore) PRIVILEGED_FUNCTION;
+
+/*
+ * For internal use only. Use xSemaphoreTakeMutexRecursive() or
+ * xSemaphoreGiveMutexRecursive() instead of calling these functions directly.
+ */
+BaseType_t xQueueTakeMutexRecursive(QueueHandle_t xMutex, TickType_t xTicksToWait) PRIVILEGED_FUNCTION;
+BaseType_t xQueueGiveMutexRecursive(QueueHandle_t pxMutex) PRIVILEGED_FUNCTION;
+
+/*
+ * Reset a queue back to its original empty state. The return value is now
+ * obsolete and is always set to pdPASS.
+ */
+#define xQueueReset( xQueue ) xQueueGenericReset( xQueue, pdFALSE )
+
+/*
+ * The registry is provided as a means for kernel aware debuggers to
+ * locate queues, semaphores and mutexes. Call vQueueAddToRegistry() add
+ * a queue, semaphore or mutex handle to the registry if you want the handle
+ * to be available to a kernel aware debugger. If you are not using a kernel
+ * aware debugger then this function can be ignored.
+ *
+ * configQUEUE_REGISTRY_SIZE defines the maximum number of handles the
+ * registry can hold. configQUEUE_REGISTRY_SIZE must be greater than 0
+ * within FreeRTOSConfig.h for the registry to be available. Its value
+ * does not effect the number of queues, semaphores and mutexes that can be
+ * created - just the number that the registry can hold.
+ *
+ * @param xQueue The handle of the queue being added to the registry. This
+ * is the handle returned by a call to xQueueCreate(). Semaphore and mutex
+ * handles can also be passed in here.
+ *
+ * @param pcName The name to be associated with the handle. This is the
+ * name that the kernel aware debugger will display. The queue registry only
+ * stores a pointer to the string - so the string must be persistent (global or
+ * preferably in ROM/Flash), not on the stack.
+ */
+#if( configQUEUE_REGISTRY_SIZE > 0 )
+void vQueueAddToRegistry(QueueHandle_t xQueue, const char *pcName) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
+#endif
+
+/*
+ * The registry is provided as a means for kernel aware debuggers to
+ * locate queues, semaphores and mutexes. Call vQueueAddToRegistry() add
+ * a queue, semaphore or mutex handle to the registry if you want the handle
+ * to be available to a kernel aware debugger, and vQueueUnregisterQueue() to
+ * remove the queue, semaphore or mutex from the register. If you are not using
+ * a kernel aware debugger then this function can be ignored.
+ *
+ * @param xQueue The handle of the queue being removed from the registry.
+ */
+#if( configQUEUE_REGISTRY_SIZE > 0 )
+void vQueueUnregisterQueue(QueueHandle_t xQueue) PRIVILEGED_FUNCTION;
+#endif
+
+/*
+ * The queue registry is provided as a means for kernel aware debuggers to
+ * locate queues, semaphores and mutexes. Call pcQueueGetName() to look
+ * up and return the name of a queue in the queue registry from the queue's
+ * handle.
+ *
+ * @param xQueue The handle of the queue the name of which will be returned.
+ * @return If the queue is in the registry then a pointer to the name of the
+ * queue is returned. If the queue is not in the registry then NULL is
+ * returned.
+ */
+#if( configQUEUE_REGISTRY_SIZE > 0 )
+const char *pcQueueGetName(QueueHandle_t xQueue) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
+#endif
+
+/*
+ * Generic version of the function used to creaet a queue using dynamic memory
+ * allocation. This is called by other functions and macros that create other
+ * RTOS objects that use the queue structure as their base.
+ */
+#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
+QueueHandle_t xQueueGenericCreate(const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, const uint8_t ucQueueType) PRIVILEGED_FUNCTION;
+#endif
+
+/*
+ * Generic version of the function used to creaet a queue using dynamic memory
+ * allocation. This is called by other functions and macros that create other
+ * RTOS objects that use the queue structure as their base.
+ */
+#if( configSUPPORT_STATIC_ALLOCATION == 1 )
+QueueHandle_t xQueueGenericCreateStatic(const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, uint8_t *pucQueueStorage, StaticQueue_t *pxStaticQueue, const uint8_t ucQueueType) PRIVILEGED_FUNCTION;
+#endif
+
+/*
+ * Queue sets provide a mechanism to allow a task to block (pend) on a read
+ * operation from multiple queues or semaphores simultaneously.
+ *
+ * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this
+ * function.
+ *
+ * A queue set must be explicitly created using a call to xQueueCreateSet()
+ * before it can be used. Once created, standard FreeRTOS queues and semaphores
+ * can be added to the set using calls to xQueueAddToSet().
+ * xQueueSelectFromSet() is then used to determine which, if any, of the queues
+ * or semaphores contained in the set is in a state where a queue read or
+ * semaphore take operation would be successful.
+ *
+ * Note 1: See the documentation on http://wwwFreeRTOS.org/RTOS-queue-sets.html
+ * for reasons why queue sets are very rarely needed in practice as there are
+ * simpler methods of blocking on multiple objects.
+ *
+ * Note 2: Blocking on a queue set that contains a mutex will not cause the
+ * mutex holder to inherit the priority of the blocked task.
+ *
+ * Note 3: An additional 4 bytes of RAM is required for each space in a every
+ * queue added to a queue set. Therefore counting semaphores that have a high
+ * maximum count value should not be added to a queue set.
+ *
+ * Note 4: A receive (in the case of a queue) or take (in the case of a
+ * semaphore) operation must not be performed on a member of a queue set unless
+ * a call to xQueueSelectFromSet() has first returned a handle to that set member.
+ *
+ * @param uxEventQueueLength Queue sets store events that occur on
+ * the queues and semaphores contained in the set. uxEventQueueLength specifies
+ * the maximum number of events that can be queued at once. To be absolutely
+ * certain that events are not lost uxEventQueueLength should be set to the
+ * total sum of the length of the queues added to the set, where binary
+ * semaphores and mutexes have a length of 1, and counting semaphores have a
+ * length set by their maximum count value. Examples:
+ * + If a queue set is to hold a queue of length 5, another queue of length 12,
+ * and a binary semaphore, then uxEventQueueLength should be set to
+ * (5 + 12 + 1), or 18.
+ * + If a queue set is to hold three binary semaphores then uxEventQueueLength
+ * should be set to (1 + 1 + 1 ), or 3.
+ * + If a queue set is to hold a counting semaphore that has a maximum count of
+ * 5, and a counting semaphore that has a maximum count of 3, then
+ * uxEventQueueLength should be set to (5 + 3), or 8.
+ *
+ * @return If the queue set is created successfully then a handle to the created
+ * queue set is returned. Otherwise NULL is returned.
+ */
+QueueSetHandle_t xQueueCreateSet(const UBaseType_t uxEventQueueLength) PRIVILEGED_FUNCTION;
+
+/*
+ * Adds a queue or semaphore to a queue set that was previously created by a
+ * call to xQueueCreateSet().
+ *
+ * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this
+ * function.
+ *
+ * Note 1: A receive (in the case of a queue) or take (in the case of a
+ * semaphore) operation must not be performed on a member of a queue set unless
+ * a call to xQueueSelectFromSet() has first returned a handle to that set member.
+ *
+ * @param xQueueOrSemaphore The handle of the queue or semaphore being added to
+ * the queue set (cast to an QueueSetMemberHandle_t type).
+ *
+ * @param xQueueSet The handle of the queue set to which the queue or semaphore
+ * is being added.
+ *
+ * @return If the queue or semaphore was successfully added to the queue set
+ * then pdPASS is returned. If the queue could not be successfully added to the
+ * queue set because it is already a member of a different queue set then pdFAIL
+ * is returned.
+ */
+BaseType_t xQueueAddToSet(QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet) PRIVILEGED_FUNCTION;
+
+/*
+ * Removes a queue or semaphore from a queue set. A queue or semaphore can only
+ * be removed from a set if the queue or semaphore is empty.
+ *
+ * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this
+ * function.
+ *
+ * @param xQueueOrSemaphore The handle of the queue or semaphore being removed
+ * from the queue set (cast to an QueueSetMemberHandle_t type).
+ *
+ * @param xQueueSet The handle of the queue set in which the queue or semaphore
+ * is included.
+ *
+ * @return If the queue or semaphore was successfully removed from the queue set
+ * then pdPASS is returned. If the queue was not in the queue set, or the
+ * queue (or semaphore) was not empty, then pdFAIL is returned.
+ */
+BaseType_t xQueueRemoveFromSet(QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet) PRIVILEGED_FUNCTION;
+
+/*
+ * xQueueSelectFromSet() selects from the members of a queue set a queue or
+ * semaphore that either contains data (in the case of a queue) or is available
+ * to take (in the case of a semaphore). xQueueSelectFromSet() effectively
+ * allows a task to block (pend) on a read operation on all the queues and
+ * semaphores in a queue set simultaneously.
+ *
+ * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this
+ * function.
+ *
+ * Note 1: See the documentation on http://wwwFreeRTOS.org/RTOS-queue-sets.html
+ * for reasons why queue sets are very rarely needed in practice as there are
+ * simpler methods of blocking on multiple objects.
+ *
+ * Note 2: Blocking on a queue set that contains a mutex will not cause the
+ * mutex holder to inherit the priority of the blocked task.
+ *
+ * Note 3: A receive (in the case of a queue) or take (in the case of a
+ * semaphore) operation must not be performed on a member of a queue set unless
+ * a call to xQueueSelectFromSet() has first returned a handle to that set member.
+ *
+ * @param xQueueSet The queue set on which the task will (potentially) block.
+ *
+ * @param xTicksToWait The maximum time, in ticks, that the calling task will
+ * remain in the Blocked state (with other tasks executing) to wait for a member
+ * of the queue set to be ready for a successful queue read or semaphore take
+ * operation.
+ *
+ * @return xQueueSelectFromSet() will return the handle of a queue (cast to
+ * a QueueSetMemberHandle_t type) contained in the queue set that contains data,
+ * or the handle of a semaphore (cast to a QueueSetMemberHandle_t type) contained
+ * in the queue set that is available, or NULL if no such queue or semaphore
+ * exists before before the specified block time expires.
+ */
+QueueSetMemberHandle_t xQueueSelectFromSet(QueueSetHandle_t xQueueSet, const TickType_t xTicksToWait) PRIVILEGED_FUNCTION;
+
+/*
+ * A version of xQueueSelectFromSet() that can be used from an ISR.
+ */
+QueueSetMemberHandle_t xQueueSelectFromSetFromISR(QueueSetHandle_t xQueueSet) PRIVILEGED_FUNCTION;
+
+/* Not public API functions. */
+void vQueueWaitForMessageRestricted(QueueHandle_t xQueue, TickType_t xTicksToWait, const BaseType_t xWaitIndefinitely) PRIVILEGED_FUNCTION;
+BaseType_t xQueueGenericReset(QueueHandle_t xQueue, BaseType_t xNewQueue) PRIVILEGED_FUNCTION;
+void vQueueSetQueueNumber(QueueHandle_t xQueue, UBaseType_t uxQueueNumber) PRIVILEGED_FUNCTION;
+UBaseType_t uxQueueGetQueueNumber(QueueHandle_t xQueue) PRIVILEGED_FUNCTION;
+uint8_t ucQueueGetQueueType(QueueHandle_t xQueue) PRIVILEGED_FUNCTION;
+
+UBaseType_t uxQueueMessagesSet(const QueueHandle_t xQueue, int cnt);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* QUEUE_H */
+
diff --git a/include_lib/system/os/FreeRTOS/semphr.h b/include_lib/system/os/FreeRTOS/semphr.h
new file mode 100644
index 0000000..4ae16cf
--- /dev/null
+++ b/include_lib/system/os/FreeRTOS/semphr.h
@@ -0,0 +1,1175 @@
+/*
+ FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
+ All rights reserved
+
+ VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
+
+ 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 on the following
+ link: http://www.freertos.org/a00114.html
+
+ ***************************************************************************
+ * *
+ * FreeRTOS provides completely free yet professionally developed, *
+ * robust, strictly quality controlled, supported, and cross *
+ * platform software that is more than just the market leader, it *
+ * is the industry's de facto standard. *
+ * *
+ * Help yourself get started quickly while simultaneously helping *
+ * to support the FreeRTOS project by purchasing a FreeRTOS *
+ * tutorial book, reference manual, or both: *
+ * http://www.FreeRTOS.org/Documentation *
+ * *
+ ***************************************************************************
+
+ http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
+ the FAQ page "My application does not run, what could be wrong?". Have you
+ defined configASSERT()?
+
+ http://www.FreeRTOS.org/support - In return for receiving this top quality
+ embedded software for free we request you assist our global community by
+ participating in the support forum.
+
+ http://www.FreeRTOS.org/training - Investing in training allows your team to
+ be as productive as possible as early as possible. Now you can receive
+ FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
+ Ltd, and the world's leading authority on the world's leading RTOS.
+
+ 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.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
+ Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
+
+ http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
+ Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
+ licenses offer ticketed support, indemnification and commercial 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
+ * vSemaphoreCreateBinary( SemaphoreHandle_t xSemaphore )
+ *
+ * In many usage scenarios it is faster and more memory efficient to use a
+ * direct to task notification in place of a binary semaphore!
+ * http://www.freertos.org/RTOS-task-notifications.html
+ *
+ * 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'.
+ *
+ * Macro 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:
+
+ 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.
+ }
+ }
+
+ * \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary
+ * \ingroup Semaphores
+ */
+#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
+#define vSemaphoreCreateBinary( xSemaphore ) \
+ { \
+ ( xSemaphore ) = xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE ); \
+ if( ( xSemaphore ) != NULL ) \
+ { \
+ ( void ) xSemaphoreGive( ( xSemaphore ) ); \
+ } \
+ }
+#endif
+
+/**
+ * semphr. h
+ * SemaphoreHandle_t xSemaphoreCreateBinary( void )
+ *
+ * Creates a new binary semaphore instance, and returns a handle by which the
+ * new semaphore can be referenced.
+ *
+ * In many usage scenarios it is faster and more memory efficient to use a
+ * direct to task notification in place of a binary semaphore!
+ * http://www.freertos.org/RTOS-task-notifications.html
+ *
+ * Internally, within the FreeRTOS implementation, binary semaphores use a block
+ * of memory, in which the semaphore structure is stored. If a binary semaphore
+ * is created using xSemaphoreCreateBinary() then the required memory is
+ * automatically dynamically allocated inside the xSemaphoreCreateBinary()
+ * function. (see http://www.freertos.org/a00111.html). If a binary semaphore
+ * is created using xSemaphoreCreateBinaryStatic() then the application writer
+ * must provide the memory. xSemaphoreCreateBinaryStatic() therefore allows a
+ * binary semaphore to be created without using any dynamic memory allocation.
+ *
+ * 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'.
+ *
+ * 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, or NULL if the memory required to
+ * hold the semaphore's data structures could not be allocated.
+ *
+ * Example usage:
+
+ SemaphoreHandle_t xSemaphore = NULL;
+
+ void vATask( void * pvParameters )
+ {
+ // Semaphore cannot be used before a call to xSemaphoreCreateBinary().
+ // 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.
+ }
+ }
+
+ * \defgroup xSemaphoreCreateBinary xSemaphoreCreateBinary
+ * \ingroup Semaphores
+ */
+#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
+#define xSemaphoreCreateBinary() xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE )
+#endif
+
+/**
+ * semphr. h
+ * SemaphoreHandle_t xSemaphoreCreateBinaryStatic( StaticSemaphore_t *pxSemaphoreBuffer )
+ *
+ * Creates a new binary semaphore instance, and returns a handle by which the
+ * new semaphore can be referenced.
+ *
+ * NOTE: In many usage scenarios it is faster and more memory efficient to use a
+ * direct to task notification in place of a binary semaphore!
+ * http://www.freertos.org/RTOS-task-notifications.html
+ *
+ * Internally, within the FreeRTOS implementation, binary semaphores use a block
+ * of memory, in which the semaphore structure is stored. If a binary semaphore
+ * is created using xSemaphoreCreateBinary() then the required memory is
+ * automatically dynamically allocated inside the xSemaphoreCreateBinary()
+ * function. (see http://www.freertos.org/a00111.html). If a binary semaphore
+ * is created using xSemaphoreCreateBinaryStatic() then the application writer
+ * must provide the memory. xSemaphoreCreateBinaryStatic() therefore allows a
+ * binary semaphore to be created without using any dynamic memory allocation.
+ *
+ * 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 pxSemaphoreBuffer Must point to a variable of type StaticSemaphore_t,
+ * which will then be used to hold the semaphore's data structure, removing the
+ * need for the memory to be allocated dynamically.
+ *
+ * @return If the semaphore is created then a handle to the created semaphore is
+ * returned. If pxSemaphoreBuffer is NULL then NULL is returned.
+ *
+ * Example usage:
+
+ SemaphoreHandle_t xSemaphore = NULL;
+ StaticSemaphore_t xSemaphoreBuffer;
+
+ void vATask( void * pvParameters )
+ {
+ // Semaphore cannot be used before a call to xSemaphoreCreateBinary().
+ // The semaphore's data structures will be placed in the xSemaphoreBuffer
+ // variable, the address of which is passed into the function. The
+ // function's parameter is not NULL, so the function will not attempt any
+ // dynamic memory allocation, and therefore the function will not return
+ // return NULL.
+ xSemaphore = xSemaphoreCreateBinary( &xSemaphoreBuffer );
+
+ // Rest of task code goes here.
+ }
+
+ * \defgroup xSemaphoreCreateBinaryStatic xSemaphoreCreateBinaryStatic
+ * \ingroup Semaphores
+ */
+#if( configSUPPORT_STATIC_ALLOCATION == 1 )
+#define xSemaphoreCreateBinaryStatic( pxStaticSemaphore ) xQueueGenericCreateStatic( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, NULL, pxStaticSemaphore, queueQUEUE_TYPE_BINARY_SEMAPHORE )
+#endif /* configSUPPORT_STATIC_ALLOCATION */
+
+/**
+ * semphr. h
+ * xSemaphoreTake(
+ * SemaphoreHandle_t xSemaphore,
+ * TickType_t xBlockTime
+ * )
+ *
+ * Macro to obtain a semaphore. The semaphore must have previously been
+ * created with a call to xSemaphoreCreateBinary(), 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:
+
+ SemaphoreHandle_t xSemaphore = NULL;
+
+ // A task that creates a semaphore.
+ void vATask( void * pvParameters )
+ {
+ // Create the semaphore to guard a shared resource.
+ xSemaphore = xSemaphoreCreateBinary();
+ }
+
+ // 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.
+ }
+ }
+ }
+
+ * \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
+ * )
+ *
+ * Macro 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:
+
+ 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.
+ }
+ }
+ }
+
+ * \defgroup xSemaphoreTakeRecursive xSemaphoreTakeRecursive
+ * \ingroup Semaphores
+ */
+#if( configUSE_RECURSIVE_MUTEXES == 1 )
+#define xSemaphoreTakeRecursive( xMutex, xBlockTime ) xQueueTakeMutexRecursive( ( xMutex ), ( xBlockTime ) )
+#endif
+
+/**
+ * semphr. h
+ * xSemaphoreGive( SemaphoreHandle_t xSemaphore )
+ *
+ * Macro to release a semaphore. The semaphore must have previously been
+ * created with a call to xSemaphoreCreateBinary(), 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:
+
+ SemaphoreHandle_t xSemaphore = NULL;
+
+ void vATask( void * pvParameters )
+ {
+ // Create the semaphore to guard a shared resource.
+ xSemaphore = vSemaphoreCreateBinary();
+
+ 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.
+ }
+ }
+ }
+ }
+
+ * \defgroup xSemaphoreGive xSemaphoreGive
+ * \ingroup Semaphores
+ */
+#define xSemaphoreGive( xSemaphore ) xQueueGenericSend( ( QueueHandle_t ) ( xSemaphore ), NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )
+
+/**
+ * semphr. h
+ * xSemaphoreGiveRecursive( SemaphoreHandle_t xMutex )
+ *
+ * Macro 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:
+
+ 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.
+ }
+ }
+ }
+
+ * \defgroup xSemaphoreGiveRecursive xSemaphoreGiveRecursive
+ * \ingroup Semaphores
+ */
+#if( configUSE_RECURSIVE_MUTEXES == 1 )
+#define xSemaphoreGiveRecursive( xMutex ) xQueueGiveMutexRecursive( ( xMutex ) )
+#endif
+
+/**
+ * semphr. h
+ *
+ xSemaphoreGiveFromISR(
+ SemaphoreHandle_t xSemaphore,
+ BaseType_t *pxHigherPriorityTaskWoken
+ )
+ *
+ * Macro to release a semaphore. The semaphore must have previously been
+ * created with a call to xSemaphoreCreateBinary() 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:
+
+ \#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.
+ }
+ }
+
+ * \defgroup xSemaphoreGiveFromISR xSemaphoreGiveFromISR
+ * \ingroup Semaphores
+ */
+#define xSemaphoreGiveFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueGiveFromISR( ( QueueHandle_t ) ( xSemaphore ), ( pxHigherPriorityTaskWoken ) )
+
+/**
+ * semphr. h
+ *
+ xSemaphoreTakeFromISR(
+ SemaphoreHandle_t xSemaphore,
+ BaseType_t *pxHigherPriorityTaskWoken
+ )
+ *
+ * Macro to take a semaphore from an ISR. The semaphore must have
+ * previously been created with a call to xSemaphoreCreateBinary() 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
+ * SemaphoreHandle_t xSemaphoreCreateMutex( void )
+ *
+ * Creates a new mutex type semaphore instance, and returns a handle by which
+ * the new mutex can be referenced.
+ *
+ * Internally, within the FreeRTOS implementation, mutex semaphores use a block
+ * of memory, in which the mutex structure is stored. If a mutex is created
+ * using xSemaphoreCreateMutex() then the required memory is automatically
+ * dynamically allocated inside the xSemaphoreCreateMutex() function. (see
+ * http://www.freertos.org/a00111.html). If a mutex is created using
+ * xSemaphoreCreateMutexStatic() then the application writer must provided the
+ * memory. xSemaphoreCreateMutexStatic() therefore allows a mutex to be created
+ * without using any dynamic memory allocation.
+ *
+ * Mutexes created using this function can be accessed using the xSemaphoreTake()
+ * and xSemaphoreGive() macros. The xSemaphoreTakeRecursive() and
+ * xSemaphoreGiveRecursive() macros must 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 xSemaphoreCreateBinary() 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 If the mutex was successfully created then a handle to the created
+ * semaphore is returned. If there was not enough heap to allocate the mutex
+ * data structures then NULL is returned.
+ *
+ * Example usage:
+
+ 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.
+ }
+ }
+
+ * \defgroup xSemaphoreCreateMutex xSemaphoreCreateMutex
+ * \ingroup Semaphores
+ */
+#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
+#define xSemaphoreCreateMutex() xQueueCreateMutex( queueQUEUE_TYPE_MUTEX )
+#endif
+
+/**
+ * semphr. h
+ * SemaphoreHandle_t xSemaphoreCreateMutexStatic( StaticSemaphore_t *pxMutexBuffer )
+ *
+ * Creates a new mutex type semaphore instance, and returns a handle by which
+ * the new mutex can be referenced.
+ *
+ * Internally, within the FreeRTOS implementation, mutex semaphores use a block
+ * of memory, in which the mutex structure is stored. If a mutex is created
+ * using xSemaphoreCreateMutex() then the required memory is automatically
+ * dynamically allocated inside the xSemaphoreCreateMutex() function. (see
+ * http://www.freertos.org/a00111.html). If a mutex is created using
+ * xSemaphoreCreateMutexStatic() then the application writer must provided the
+ * memory. xSemaphoreCreateMutexStatic() therefore allows a mutex to be created
+ * without using any dynamic memory allocation.
+ *
+ * Mutexes created using this function can be accessed using the xSemaphoreTake()
+ * and xSemaphoreGive() macros. The xSemaphoreTakeRecursive() and
+ * xSemaphoreGiveRecursive() macros must 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 xSemaphoreCreateBinary() 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.
+ *
+ * @param pxMutexBuffer Must point to a variable of type StaticSemaphore_t,
+ * which will be used to hold the mutex's data structure, removing the need for
+ * the memory to be allocated dynamically.
+ *
+ * @return If the mutex was successfully created then a handle to the created
+ * mutex is returned. If pxMutexBuffer was NULL then NULL is returned.
+ *
+ * Example usage:
+
+ SemaphoreHandle_t xSemaphore;
+ StaticSemaphore_t xMutexBuffer;
+
+ void vATask( void * pvParameters )
+ {
+ // A mutex cannot be used before it has been created. xMutexBuffer is
+ // into xSemaphoreCreateMutexStatic() so no dynamic memory allocation is
+ // attempted.
+ xSemaphore = xSemaphoreCreateMutexStatic( &xMutexBuffer );
+
+ // As no dynamic memory allocation was performed, xSemaphore cannot be NULL,
+ // so there is no need to check it.
+ }
+
+ * \defgroup xSemaphoreCreateMutexStatic xSemaphoreCreateMutexStatic
+ * \ingroup Semaphores
+ */
+#if( configSUPPORT_STATIC_ALLOCATION == 1 )
+#define xSemaphoreCreateMutexStatic( pxMutexBuffer ) xQueueCreateMutexStatic( queueQUEUE_TYPE_MUTEX, ( pxMutexBuffer ) )
+#endif /* configSUPPORT_STATIC_ALLOCATION */
+
+
+/**
+ * semphr. h
+ * SemaphoreHandle_t xSemaphoreCreateRecursiveMutex( void )
+ *
+ * Creates a new recursive mutex type semaphore instance, and returns a handle
+ * by which the new recursive mutex can be referenced.
+ *
+ * Internally, within the FreeRTOS implementation, recursive mutexs use a block
+ * of memory, in which the mutex structure is stored. If a recursive mutex is
+ * created using xSemaphoreCreateRecursiveMutex() then the required memory is
+ * automatically dynamically allocated inside the
+ * xSemaphoreCreateRecursiveMutex() function. (see
+ * http://www.freertos.org/a00111.html). If a recursive mutex is created using
+ * xSemaphoreCreateRecursiveMutexStatic() then the application writer must
+ * provide the memory that will get used by the mutex.
+ * xSemaphoreCreateRecursiveMutexStatic() therefore allows a recursive mutex to
+ * be created without using any dynamic memory allocation.
+ *
+ * Mutexes created using this macro can be accessed using the
+ * xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() macros. The
+ * xSemaphoreTake() and xSemaphoreGive() macros must 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 xSemaphoreCreateBinary() 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:
+
+ 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.
+ }
+ }
+
+ * \defgroup xSemaphoreCreateRecursiveMutex xSemaphoreCreateRecursiveMutex
+ * \ingroup Semaphores
+ */
+#if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configUSE_RECURSIVE_MUTEXES == 1 ) )
+#define xSemaphoreCreateRecursiveMutex() xQueueCreateMutex( queueQUEUE_TYPE_RECURSIVE_MUTEX )
+#endif
+
+/**
+ * semphr. h
+ * SemaphoreHandle_t xSemaphoreCreateRecursiveMutexStatic( StaticSemaphore_t *pxMutexBuffer )
+ *
+ * Creates a new recursive mutex type semaphore instance, and returns a handle
+ * by which the new recursive mutex can be referenced.
+ *
+ * Internally, within the FreeRTOS implementation, recursive mutexs use a block
+ * of memory, in which the mutex structure is stored. If a recursive mutex is
+ * created using xSemaphoreCreateRecursiveMutex() then the required memory is
+ * automatically dynamically allocated inside the
+ * xSemaphoreCreateRecursiveMutex() function. (see
+ * http://www.freertos.org/a00111.html). If a recursive mutex is created using
+ * xSemaphoreCreateRecursiveMutexStatic() then the application writer must
+ * provide the memory that will get used by the mutex.
+ * xSemaphoreCreateRecursiveMutexStatic() therefore allows a recursive mutex to
+ * be created without using any dynamic memory allocation.
+ *
+ * Mutexes created using this macro can be accessed using the
+ * xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() macros. The
+ * xSemaphoreTake() and xSemaphoreGive() macros must 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 xSemaphoreCreateBinary() 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.
+ *
+ * @param pxMutexBuffer Must point to a variable of type StaticSemaphore_t,
+ * which will then be used to hold the recursive mutex's data structure,
+ * removing the need for the memory to be allocated dynamically.
+ *
+ * @return If the recursive mutex was successfully created then a handle to the
+ * created recursive mutex is returned. If pxMutexBuffer was NULL then NULL is
+ * returned.
+ *
+ * Example usage:
+
+ SemaphoreHandle_t xSemaphore;
+ StaticSemaphore_t xMutexBuffer;
+
+ void vATask( void * pvParameters )
+ {
+ // A recursive semaphore cannot be used before it is created. Here a
+ // recursive mutex is created using xSemaphoreCreateRecursiveMutexStatic().
+ // The address of xMutexBuffer is passed into the function, and will hold
+ // the mutexes data structures - so no dynamic memory allocation will be
+ // attempted.
+ xSemaphore = xSemaphoreCreateRecursiveMutexStatic( &xMutexBuffer );
+
+ // As no dynamic memory allocation was performed, xSemaphore cannot be NULL,
+ // so there is no need to check it.
+ }
+
+ * \defgroup xSemaphoreCreateRecursiveMutexStatic xSemaphoreCreateRecursiveMutexStatic
+ * \ingroup Semaphores
+ */
+#if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configUSE_RECURSIVE_MUTEXES == 1 ) )
+#define xSemaphoreCreateRecursiveMutexStatic( pxStaticSemaphore ) xQueueCreateMutexStatic( queueQUEUE_TYPE_RECURSIVE_MUTEX, pxStaticSemaphore )
+#endif /* configSUPPORT_STATIC_ALLOCATION */
+
+/**
+ * semphr. h
+ * SemaphoreHandle_t xSemaphoreCreateCounting( UBaseType_t uxMaxCount, UBaseType_t uxInitialCount )
+ *
+ * Creates a new counting semaphore instance, and returns a handle by which the
+ * new counting semaphore can be referenced.
+ *
+ * In many usage scenarios it is faster and more memory efficient to use a
+ * direct to task notification in place of a counting semaphore!
+ * http://www.freertos.org/RTOS-task-notifications.html
+ *
+ * Internally, within the FreeRTOS implementation, counting semaphores use a
+ * block of memory, in which the counting semaphore structure is stored. If a
+ * counting semaphore is created using xSemaphoreCreateCounting() then the
+ * required memory is automatically dynamically allocated inside the
+ * xSemaphoreCreateCounting() function. (see
+ * http://www.freertos.org/a00111.html). If a counting semaphore is created
+ * using xSemaphoreCreateCountingStatic() then the application writer can
+ * instead optionally provide the memory that will get used by the counting
+ * semaphore. xSemaphoreCreateCountingStatic() therefore allows a counting
+ * semaphore to be created without using any dynamic memory allocation.
+ *
+ * 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:
+
+ 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.
+ }
+ }
+
+ * \defgroup xSemaphoreCreateCounting xSemaphoreCreateCounting
+ * \ingroup Semaphores
+ */
+#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
+#define xSemaphoreCreateCounting( uxMaxCount, uxInitialCount ) xQueueCreateCountingSemaphore( ( uxMaxCount ), ( uxInitialCount ) )
+#endif
+
+/**
+ * semphr. h
+ * SemaphoreHandle_t xSemaphoreCreateCountingStatic( UBaseType_t uxMaxCount, UBaseType_t uxInitialCount, StaticSemaphore_t *pxSemaphoreBuffer )
+ *
+ * Creates a new counting semaphore instance, and returns a handle by which the
+ * new counting semaphore can be referenced.
+ *
+ * In many usage scenarios it is faster and more memory efficient to use a
+ * direct to task notification in place of a counting semaphore!
+ * http://www.freertos.org/RTOS-task-notifications.html
+ *
+ * Internally, within the FreeRTOS implementation, counting semaphores use a
+ * block of memory, in which the counting semaphore structure is stored. If a
+ * counting semaphore is created using xSemaphoreCreateCounting() then the
+ * required memory is automatically dynamically allocated inside the
+ * xSemaphoreCreateCounting() function. (see
+ * http://www.freertos.org/a00111.html). If a counting semaphore is created
+ * using xSemaphoreCreateCountingStatic() then the application writer must
+ * provide the memory. xSemaphoreCreateCountingStatic() therefore allows a
+ * counting semaphore to be created without using any dynamic memory allocation.
+ *
+ * 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.
+ *
+ * @param pxSemaphoreBuffer Must point to a variable of type StaticSemaphore_t,
+ * which will then be used to hold the semaphore's data structure, removing the
+ * need for the memory to be allocated dynamically.
+ *
+ * @return If the counting semaphore was successfully created then a handle to
+ * the created counting semaphore is returned. If pxSemaphoreBuffer was NULL
+ * then NULL is returned.
+ *
+ * Example usage:
+
+ SemaphoreHandle_t xSemaphore;
+ StaticSemaphore_t xSemaphoreBuffer;
+
+ void vATask( void * pvParameters )
+ {
+ SemaphoreHandle_t xSemaphore = NULL;
+
+ // Counting semaphore cannot be used before they have been created. Create
+ // a counting semaphore using xSemaphoreCreateCountingStatic(). The max
+ // value to which the semaphore can count is 10, and the initial value
+ // assigned to the count will be 0. The address of xSemaphoreBuffer is
+ // passed in and will be used to hold the semaphore structure, so no dynamic
+ // memory allocation will be used.
+ xSemaphore = xSemaphoreCreateCounting( 10, 0, &xSemaphoreBuffer );
+
+ // No memory allocation was attempted so xSemaphore cannot be NULL, so there
+ // is no need to check its value.
+ }
+
+ * \defgroup xSemaphoreCreateCountingStatic xSemaphoreCreateCountingStatic
+ * \ingroup Semaphores
+ */
+#if( configSUPPORT_STATIC_ALLOCATION == 1 )
+#define xSemaphoreCreateCountingStatic( uxMaxCount, uxInitialCount, pxSemaphoreBuffer ) xQueueCreateCountingSemaphoreStatic( ( uxMaxCount ), ( uxInitialCount ), ( pxSemaphoreBuffer ) )
+#endif /* configSUPPORT_STATIC_ALLOCATION */
+
+/**
+ * semphr. h
+ * void vSemaphoreDelete( SemaphoreHandle_t xSemaphore );
+ *
+ * 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
+ * TaskHandle_t xSemaphoreGetMutexHolder( SemaphoreHandle_t xMutex );
+ *
+ * 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 ) )
+
+/**
+ * semphr.h
+ * UBaseType_t uxSemaphoreGetCount( SemaphoreHandle_t xSemaphore );
+ *
+ * If the semaphore is a counting semaphore then uxSemaphoreGetCount() returns
+ * its current count value. If the semaphore is a binary semaphore then
+ * uxSemaphoreGetCount() returns 1 if the semaphore is available, and 0 if the
+ * semaphore is not available.
+ *
+ */
+#define uxSemaphoreGetCount( xSemaphore ) uxQueueMessagesWaiting( ( QueueHandle_t ) ( xSemaphore ) )
+
+#define uxSemaphoreSetCount( xSemaphore, cnt) \
+ uxQueueMessagesSet((QueueHandle_t)xSemaphore, cnt)
+
+
+#endif /* SEMAPHORE_H */
+
+
diff --git a/include_lib/system/os/FreeRTOS/task.h b/include_lib/system/os/FreeRTOS/task.h
new file mode 100644
index 0000000..044fefa
--- /dev/null
+++ b/include_lib/system/os/FreeRTOS/task.h
@@ -0,0 +1,2268 @@
+/*
+ FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
+ All rights reserved
+
+ VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
+
+ 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 on the following
+ link: http://www.freertos.org/a00114.html
+
+ ***************************************************************************
+ * *
+ * FreeRTOS provides completely free yet professionally developed, *
+ * robust, strictly quality controlled, supported, and cross *
+ * platform software that is more than just the market leader, it *
+ * is the industry's de facto standard. *
+ * *
+ * Help yourself get started quickly while simultaneously helping *
+ * to support the FreeRTOS project by purchasing a FreeRTOS *
+ * tutorial book, reference manual, or both: *
+ * http://www.FreeRTOS.org/Documentation *
+ * *
+ ***************************************************************************
+
+ http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
+ the FAQ page "My application does not run, what could be wrong?". Have you
+ defined configASSERT()?
+
+ http://www.FreeRTOS.org/support - In return for receiving this top quality
+ embedded software for free we request you assist our global community by
+ participating in the support forum.
+
+ http://www.FreeRTOS.org/training - Investing in training allows your team to
+ be as productive as possible as early as possible. Now you can receive
+ FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
+ Ltd, and the world's leading authority on the world's leading RTOS.
+
+ 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.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
+ Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
+
+ http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
+ Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
+ licenses offer ticketed support, indemnification and commercial 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_TASK_H
+#define INC_TASK_H
+
+#ifndef INC_FREERTOS_H
+#error "include FreeRTOS.h must appear in source files before include task.h"
+#endif
+
+#include "list.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*-----------------------------------------------------------
+ * MACROS AND DEFINITIONS
+ *----------------------------------------------------------*/
+
+#define tskKERNEL_VERSION_NUMBER "V9.0.0"
+#define tskKERNEL_VERSION_MAJOR 9
+#define tskKERNEL_VERSION_MINOR 0
+#define tskKERNEL_VERSION_BUILD 0
+
+/**
+ * task. h
+ *
+ * Type by which tasks are referenced. For example, a call to xTaskCreate
+ * returns (via a pointer parameter) an TaskHandle_t variable that can then
+ * be used as a parameter to vTaskDelete to delete the task.
+ *
+ * \defgroup TaskHandle_t TaskHandle_t
+ * \ingroup Tasks
+ */
+typedef void *TaskHandle_t;
+
+/*
+ * Defines the prototype to which the application task hook function must
+ * conform.
+ */
+typedef BaseType_t (*TaskHookFunction_t)(void *);
+
+/* Task states returned by eTaskGetState. */
+typedef enum {
+ eRunning = 0, /* A task is querying the state of itself, so must be running. */
+ eReady, /* The task being queried is in a read or pending ready list. */
+ eBlocked, /* The task being queried is in the Blocked state. */
+ eSuspended, /* The task being queried is in the Suspended state, or is in the Blocked state with an infinite time out. */
+ eDeleted, /* The task being queried has been deleted, but its TCB has not yet been freed. */
+ eInvalid /* Used as an 'invalid state' value. */
+} eTaskState;
+
+/* Actions that can be performed when vTaskNotify() is called. */
+typedef enum {
+ eNoAction = 0, /* Notify the task without updating its notify value. */
+ eSetBits, /* Set bits in the task's notification value. */
+ eIncrement, /* Increment the task's notification value. */
+ eSetValueWithOverwrite, /* Set the task's notification value to a specific value even if the previous value has not yet been read by the task. */
+ eSetValueWithoutOverwrite /* Set the task's notification value if the previous value has been read by the task. */
+} eNotifyAction;
+
+/*
+ * Used internally only.
+ */
+typedef struct xTIME_OUT {
+ BaseType_t xOverflowCount;
+ TickType_t xTimeOnEntering;
+} TimeOut_t;
+
+/*
+ * Defines the memory ranges allocated to the task when an MPU is used.
+ */
+typedef struct xMEMORY_REGION {
+ void *pvBaseAddress;
+ uint32_t ulLengthInBytes;
+ uint32_t ulParameters;
+} MemoryRegion_t;
+
+/*
+ * Parameters required to create an MPU protected task.
+ */
+typedef struct xTASK_PARAMETERS {
+ TaskFunction_t pvTaskCode;
+ const char *const pcName; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
+ uint16_t usStackDepth;
+ void *pvParameters;
+ UBaseType_t uxPriority;
+ StackType_t *puxStackBuffer;
+ MemoryRegion_t xRegions[ portNUM_CONFIGURABLE_REGIONS ];
+} TaskParameters_t;
+
+/* Used with the uxTaskGetSystemState() function to return the state of each task
+in the system. */
+typedef struct xTASK_STATUS {
+ TaskHandle_t xHandle; /* The handle of the task to which the rest of the information in the structure relates. */
+ const char *pcTaskName; /* A pointer to the task's name. This value will be invalid if the task was deleted since the structure was populated! */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
+ UBaseType_t xTaskNumber; /* A number unique to the task. */
+ eTaskState eCurrentState; /* The state in which the task existed when the structure was populated. */
+ UBaseType_t uxCurrentPriority; /* The priority at which the task was running (may be inherited) when the structure was populated. */
+ UBaseType_t uxBasePriority; /* The priority to which the task will return if the task's current priority has been inherited to avoid unbounded priority inversion when obtaining a mutex. Only valid if configUSE_MUTEXES is defined as 1 in FreeRTOSConfig.h. */
+ uint32_t ulRunTimeCounter; /* The total run time allocated to the task so far, as defined by the run time stats clock. See http://www.freertos.org/rtos-run-time-stats.html. Only valid when configGENERATE_RUN_TIME_STATS is defined as 1 in FreeRTOSConfig.h. */
+ StackType_t *pxStackBase; /* Points to the lowest address of the task's stack area. */
+ uint16_t usStackHighWaterMark; /* The minimum amount of stack space that has remained for the task since the task was created. The closer this value is to zero the closer the task has come to overflowing its stack. */
+} TaskStatus_t;
+
+/* Possible return values for eTaskConfirmSleepModeStatus(). */
+typedef enum {
+ eAbortSleep = 0, /* A task has been made ready or a context switch pended since portSUPPORESS_TICKS_AND_SLEEP() was called - abort entering a sleep mode. */
+ eStandardSleep, /* Enter a sleep mode that will not last any longer than the expected idle time. */
+ eNoTasksWaitingTimeout /* No tasks are waiting for a timeout so it is safe to enter a sleep mode that can only be exited by an external interrupt. */
+} eSleepModeStatus;
+
+/**
+ * Defines the priority used by the idle task. This must not be modified.
+ *
+ * \ingroup TaskUtils
+ */
+#define tskIDLE_PRIORITY ( ( UBaseType_t ) 0U )
+
+/**
+ * task. h
+ *
+ * Macro for forcing a context switch.
+ *
+ * \defgroup taskYIELD taskYIELD
+ * \ingroup SchedulerControl
+ */
+#define taskYIELD() portYIELD()
+
+/**
+ * task. h
+ *
+ * Macro to mark the start of a critical code region. Preemptive context
+ * switches cannot occur when in a critical region.
+ *
+ * NOTE: This may alter the stack (depending on the portable implementation)
+ * so must be used with care!
+ *
+ * \defgroup taskENTER_CRITICAL taskENTER_CRITICAL
+ * \ingroup SchedulerControl
+ */
+#define taskENTER_CRITICAL() portENTER_CRITICAL()
+#define taskENTER_CRITICAL_FROM_ISR() portSET_INTERRUPT_MASK_FROM_ISR()
+
+/**
+ * task. h
+ *
+ * Macro to mark the end of a critical code region. Preemptive context
+ * switches cannot occur when in a critical region.
+ *
+ * NOTE: This may alter the stack (depending on the portable implementation)
+ * so must be used with care!
+ *
+ * \defgroup taskEXIT_CRITICAL taskEXIT_CRITICAL
+ * \ingroup SchedulerControl
+ */
+#define taskEXIT_CRITICAL() portEXIT_CRITICAL()
+#define taskEXIT_CRITICAL_FROM_ISR( x ) portCLEAR_INTERRUPT_MASK_FROM_ISR( x )
+/**
+ * task. h
+ *
+ * Macro to disable all maskable interrupts.
+ *
+ * \defgroup taskDISABLE_INTERRUPTS taskDISABLE_INTERRUPTS
+ * \ingroup SchedulerControl
+ */
+#define taskDISABLE_INTERRUPTS() portDISABLE_INTERRUPTS()
+
+/**
+ * task. h
+ *
+ * Macro to enable microcontroller interrupts.
+ *
+ * \defgroup taskENABLE_INTERRUPTS taskENABLE_INTERRUPTS
+ * \ingroup SchedulerControl
+ */
+#define taskENABLE_INTERRUPTS() portENABLE_INTERRUPTS()
+
+/* Definitions returned by xTaskGetSchedulerState(). taskSCHEDULER_SUSPENDED is
+0 to generate more optimal code when configASSERT() is defined as the constant
+is used in assert() statements. */
+#define taskSCHEDULER_SUSPENDED ( ( BaseType_t ) 0 )
+#define taskSCHEDULER_NOT_STARTED ( ( BaseType_t ) 1 )
+#define taskSCHEDULER_RUNNING ( ( BaseType_t ) 2 )
+
+
+/*-----------------------------------------------------------
+ * TASK CREATION API
+ *----------------------------------------------------------*/
+
+/**
+ * task. h
+ *
+ BaseType_t xTaskCreate(
+ TaskFunction_t pvTaskCode,
+ const char * const pcName,
+ uint16_t usStackDepth,
+ void *pvParameters,
+ UBaseType_t uxPriority,
+ TaskHandle_t *pvCreatedTask
+ );
+ *
+ * Create a new task and add it to the list of tasks that are ready to run.
+ *
+ * Internally, within the FreeRTOS implementation, tasks use two blocks of
+ * memory. The first block is used to hold the task's data structures. The
+ * second block is used by the task as its stack. If a task is created using
+ * xTaskCreate() then both blocks of memory are automatically dynamically
+ * allocated inside the xTaskCreate() function. (see
+ * http://www.freertos.org/a00111.html). If a task is created using
+ * xTaskCreateStatic() then the application writer must provide the required
+ * memory. xTaskCreateStatic() therefore allows a task to be created without
+ * using any dynamic memory allocation.
+ *
+ * See xTaskCreateStatic() for a version that does not use any dynamic memory
+ * allocation.
+ *
+ * xTaskCreate() can only be used to create a task that has unrestricted
+ * access to the entire microcontroller memory map. Systems that include MPU
+ * support can alternatively create an MPU constrained task using
+ * xTaskCreateRestricted().
+ *
+ * @param pvTaskCode Pointer to the task entry function. Tasks
+ * must be implemented to never return (i.e. continuous loop).
+ *
+ * @param pcName A descriptive name for the task. This is mainly used to
+ * facilitate debugging. Max length defined by configMAX_TASK_NAME_LEN - default
+ * is 16.
+ *
+ * @param usStackDepth The size of the task stack specified as the number of
+ * variables the stack can hold - not the number of bytes. For example, if
+ * the stack is 16 bits wide and usStackDepth is defined as 100, 200 bytes
+ * will be allocated for stack storage.
+ *
+ * @param pvParameters Pointer that will be used as the parameter for the task
+ * being created.
+ *
+ * @param uxPriority The priority at which the task should run. Systems that
+ * include MPU support can optionally create tasks in a privileged (system)
+ * mode by setting bit portPRIVILEGE_BIT of the priority parameter. For
+ * example, to create a privileged task at priority 2 the uxPriority parameter
+ * should be set to ( 2 | portPRIVILEGE_BIT ).
+ *
+ * @param pvCreatedTask Used to pass back a handle by which the created task
+ * can be referenced.
+ *
+ * @return pdPASS if the task was successfully created and added to a ready
+ * list, otherwise an error code defined in the file projdefs.h
+ *
+ * Example usage:
+
+ // Task to be created.
+ void vTaskCode( void * pvParameters )
+ {
+ for( ;; )
+ {
+ // Task code goes here.
+ }
+ }
+
+ // Function that creates a task.
+ void vOtherFunction( void )
+ {
+ static uint8_t ucParameterToPass;
+ TaskHandle_t xHandle = NULL;
+
+ // Create the task, storing the handle. Note that the passed parameter ucParameterToPass
+ // must exist for the lifetime of the task, so in this case is declared static. If it was just an
+ // an automatic stack variable it might no longer exist, or at least have been corrupted, by the time
+ // the new task attempts to access it.
+ xTaskCreate( vTaskCode, "NAME", STACK_SIZE, &ucParameterToPass, tskIDLE_PRIORITY, &xHandle );
+ configASSERT( xHandle );
+
+ // Use the handle to delete the task.
+ if( xHandle != NULL )
+ {
+ vTaskDelete( xHandle );
+ }
+ }
+
+ * \defgroup xTaskCreate xTaskCreate
+ * \ingroup Tasks
+ */
+#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
+BaseType_t xTaskCreate(TaskFunction_t pxTaskCode,
+ const char *const pcName,
+ const uint16_t usStackDepth,
+ void *const pvParameters,
+ UBaseType_t uxPriority,
+ TaskHandle_t *const pxCreatedTask) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
+#endif
+
+/**
+ * task. h
+ *
+ TaskHandle_t xTaskCreateStatic( TaskFunction_t pvTaskCode,
+ const char * const pcName,
+ uint32_t ulStackDepth,
+ void *pvParameters,
+ UBaseType_t uxPriority,
+ StackType_t *pxStackBuffer,
+ StaticTask_t *pxTaskBuffer );
+ *
+ * Create a new task and add it to the list of tasks that are ready to run.
+ *
+ * Internally, within the FreeRTOS implementation, tasks use two blocks of
+ * memory. The first block is used to hold the task's data structures. The
+ * second block is used by the task as its stack. If a task is created using
+ * xTaskCreate() then both blocks of memory are automatically dynamically
+ * allocated inside the xTaskCreate() function. (see
+ * http://www.freertos.org/a00111.html). If a task is created using
+ * xTaskCreateStatic() then the application writer must provide the required
+ * memory. xTaskCreateStatic() therefore allows a task to be created without
+ * using any dynamic memory allocation.
+ *
+ * @param pvTaskCode Pointer to the task entry function. Tasks
+ * must be implemented to never return (i.e. continuous loop).
+ *
+ * @param pcName A descriptive name for the task. This is mainly used to
+ * facilitate debugging. The maximum length of the string is defined by
+ * configMAX_TASK_NAME_LEN in FreeRTOSConfig.h.
+ *
+ * @param ulStackDepth The size of the task stack specified as the number of
+ * variables the stack can hold - not the number of bytes. For example, if
+ * the stack is 32-bits wide and ulStackDepth is defined as 100 then 400 bytes
+ * will be allocated for stack storage.
+ *
+ * @param pvParameters Pointer that will be used as the parameter for the task
+ * being created.
+ *
+ * @param uxPriority The priority at which the task will run.
+ *
+ * @param pxStackBuffer Must point to a StackType_t array that has at least
+ * ulStackDepth indexes - the array will then be used as the task's stack,
+ * removing the need for the stack to be allocated dynamically.
+ *
+ * @param pxTaskBuffer Must point to a variable of type StaticTask_t, which will
+ * then be used to hold the task's data structures, removing the need for the
+ * memory to be allocated dynamically.
+ *
+ * @return If neither pxStackBuffer or pxTaskBuffer are NULL, then the task will
+ * be created and pdPASS is returned. If either pxStackBuffer or pxTaskBuffer
+ * are NULL then the task will not be created and
+ * errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY is returned.
+ *
+ * Example usage:
+
+
+ // Dimensions the buffer that the task being created will use as its stack.
+ // NOTE: This is the number of words the stack will hold, not the number of
+ // bytes. For example, if each stack item is 32-bits, and this is set to 100,
+ // then 400 bytes (100 * 32-bits) will be allocated.
+ #define STACK_SIZE 200
+
+ // Structure that will hold the TCB of the task being created.
+ StaticTask_t xTaskBuffer;
+
+ // Buffer that the task being created will use as its stack. Note this is
+ // an array of StackType_t variables. The size of StackType_t is dependent on
+ // the RTOS port.
+ StackType_t xStack[ STACK_SIZE ];
+
+ // Function that implements the task being created.
+ void vTaskCode( void * pvParameters )
+ {
+ // The parameter value is expected to be 1 as 1 is passed in the
+ // pvParameters value in the call to xTaskCreateStatic().
+ configASSERT( ( uint32_t ) pvParameters == 1UL );
+
+ for( ;; )
+ {
+ // Task code goes here.
+ }
+ }
+
+ // Function that creates a task.
+ void vOtherFunction( void )
+ {
+ TaskHandle_t xHandle = NULL;
+
+ // Create the task without using any dynamic memory allocation.
+ xHandle = xTaskCreateStatic(
+ vTaskCode, // Function that implements the task.
+ "NAME", // Text name for the task.
+ STACK_SIZE, // Stack size in words, not bytes.
+ ( void * ) 1, // Parameter passed into the task.
+ tskIDLE_PRIORITY,// Priority at which the task is created.
+ xStack, // Array to use as the task's stack.
+ &xTaskBuffer ); // Variable to hold the task's data structure.
+
+ // puxStackBuffer and pxTaskBuffer were not NULL, so the task will have
+ // been created, and xHandle will be the task's handle. Use the handle
+ // to suspend the task.
+ vTaskSuspend( xHandle );
+ }
+
+ * \defgroup xTaskCreateStatic xTaskCreateStatic
+ * \ingroup Tasks
+ */
+#if( configSUPPORT_STATIC_ALLOCATION == 1 )
+TaskHandle_t xTaskCreateStatic(TaskFunction_t pxTaskCode,
+ const char *const pcName,
+ const uint32_t ulStackDepth,
+ void *const pvParameters,
+ UBaseType_t uxPriority,
+ StackType_t *const puxStackBuffer,
+ StaticTask_t *const pxTaskBuffer) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
+#endif /* configSUPPORT_STATIC_ALLOCATION */
+
+/**
+ * task. h
+ *
+ BaseType_t xTaskCreateRestricted( TaskParameters_t *pxTaskDefinition, TaskHandle_t *pxCreatedTask );
+ *
+ * xTaskCreateRestricted() should only be used in systems that include an MPU
+ * implementation.
+ *
+ * Create a new task and add it to the list of tasks that are ready to run.
+ * The function parameters define the memory regions and associated access
+ * permissions allocated to the task.
+ *
+ * @param pxTaskDefinition Pointer to a structure that contains a member
+ * for each of the normal xTaskCreate() parameters (see the xTaskCreate() API
+ * documentation) plus an optional stack buffer and the memory region
+ * definitions.
+ *
+ * @param pxCreatedTask Used to pass back a handle by which the created task
+ * can be referenced.
+ *
+ * @return pdPASS if the task was successfully created and added to a ready
+ * list, otherwise an error code defined in the file projdefs.h
+ *
+ * Example usage:
+
+// Create an TaskParameters_t structure that defines the task to be created.
+static const TaskParameters_t xCheckTaskParameters =
+{
+ vATask, // pvTaskCode - the function that implements the task.
+ "ATask", // pcName - just a text name for the task to assist debugging.
+ 100, // usStackDepth - the stack size DEFINED IN WORDS.
+ NULL, // pvParameters - passed into the task function as the function parameters.
+ ( 1UL | portPRIVILEGE_BIT ),// uxPriority - task priority, set the portPRIVILEGE_BIT if the task should run in a privileged state.
+ cStackBuffer,// puxStackBuffer - the buffer to be used as the task stack.
+
+ // xRegions - Allocate up to three separate memory regions for access by
+ // the task, with appropriate access permissions. Different processors have
+ // different memory alignment requirements - refer to the FreeRTOS documentation
+ // for full information.
+ {
+ // Base address Length Parameters
+ { cReadWriteArray, 32, portMPU_REGION_READ_WRITE },
+ { cReadOnlyArray, 32, portMPU_REGION_READ_ONLY },
+ { cPrivilegedOnlyAccessArray, 128, portMPU_REGION_PRIVILEGED_READ_WRITE }
+ }
+};
+
+int main( void )
+{
+TaskHandle_t xHandle;
+
+ // Create a task from the const structure defined above. The task handle
+ // is requested (the second parameter is not NULL) but in this case just for
+ // demonstration purposes as its not actually used.
+ xTaskCreateRestricted( &xRegTest1Parameters, &xHandle );
+
+ // Start the scheduler.
+ vTaskStartScheduler();
+
+ // Will only get here if there was insufficient memory to create the idle
+ // and/or timer task.
+ for( ;; );
+}
+
+ * \defgroup xTaskCreateRestricted xTaskCreateRestricted
+ * \ingroup Tasks
+ */
+#if( portUSING_MPU_WRAPPERS == 1 )
+BaseType_t xTaskCreateRestricted(const TaskParameters_t *const pxTaskDefinition, TaskHandle_t *pxCreatedTask) PRIVILEGED_FUNCTION;
+#endif
+
+/**
+ * task. h
+ *
+ void vTaskAllocateMPURegions( TaskHandle_t xTask, const MemoryRegion_t * const pxRegions );
+ *
+ * Memory regions are assigned to a restricted task when the task is created by
+ * a call to xTaskCreateRestricted(). These regions can be redefined using
+ * vTaskAllocateMPURegions().
+ *
+ * @param xTask The handle of the task being updated.
+ *
+ * @param xRegions A pointer to an MemoryRegion_t structure that contains the
+ * new memory region definitions.
+ *
+ * Example usage:
+
+// Define an array of MemoryRegion_t structures that configures an MPU region
+// allowing read/write access for 1024 bytes starting at the beginning of the
+// ucOneKByte array. The other two of the maximum 3 definable regions are
+// unused so set to zero.
+static const MemoryRegion_t xAltRegions[ portNUM_CONFIGURABLE_REGIONS ] =
+{
+ // Base address Length Parameters
+ { ucOneKByte, 1024, portMPU_REGION_READ_WRITE },
+ { 0, 0, 0 },
+ { 0, 0, 0 }
+};
+
+void vATask( void *pvParameters )
+{
+ // This task was created such that it has access to certain regions of
+ // memory as defined by the MPU configuration. At some point it is
+ // desired that these MPU regions are replaced with that defined in the
+ // xAltRegions const struct above. Use a call to vTaskAllocateMPURegions()
+ // for this purpose. NULL is used as the task handle to indicate that this
+ // function should modify the MPU regions of the calling task.
+ vTaskAllocateMPURegions( NULL, xAltRegions );
+
+ // Now the task can continue its function, but from this point on can only
+ // access its stack and the ucOneKByte array (unless any other statically
+ // defined or shared regions have been declared elsewhere).
+}
+
+ * \defgroup xTaskCreateRestricted xTaskCreateRestricted
+ * \ingroup Tasks
+ */
+void vTaskAllocateMPURegions(TaskHandle_t xTask, const MemoryRegion_t *const pxRegions) PRIVILEGED_FUNCTION;
+
+/**
+ * task. h
+ * void vTaskDelete( TaskHandle_t xTask );
+ *
+ * INCLUDE_vTaskDelete must be defined as 1 for this function to be available.
+ * See the configuration section for more information.
+ *
+ * Remove a task from the RTOS real time kernel's management. The task being
+ * deleted will be removed from all ready, blocked, suspended and event lists.
+ *
+ * NOTE: The idle task is responsible for freeing the kernel allocated
+ * memory from tasks that have been deleted. It is therefore important that
+ * the idle task is not starved of microcontroller processing time if your
+ * application makes any calls to vTaskDelete (). Memory allocated by the
+ * task code is not automatically freed, and should be freed before the task
+ * is deleted.
+ *
+ * See the demo application file death.c for sample code that utilises
+ * vTaskDelete ().
+ *
+ * @param xTask The handle of the task to be deleted. Passing NULL will
+ * cause the calling task to be deleted.
+ *
+ * Example usage:
+
+ void vOtherFunction( void )
+ {
+ TaskHandle_t xHandle;
+
+ // Create the task, storing the handle.
+ xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+ // Use the handle to delete the task.
+ vTaskDelete( xHandle );
+ }
+
+ * \defgroup vTaskDelete vTaskDelete
+ * \ingroup Tasks
+ */
+void vTaskDelete(TaskHandle_t xTaskToDelete) PRIVILEGED_FUNCTION;
+
+/*-----------------------------------------------------------
+ * TASK CONTROL API
+ *----------------------------------------------------------*/
+
+/**
+ * task. h
+ * void vTaskDelay( const TickType_t xTicksToDelay );
+ *
+ * Delay a task for a given number of ticks. The actual time that the
+ * task remains blocked depends on the tick rate. The constant
+ * portTICK_PERIOD_MS can be used to calculate real time from the tick
+ * rate - with the resolution of one tick period.
+ *
+ * INCLUDE_vTaskDelay must be defined as 1 for this function to be available.
+ * See the configuration section for more information.
+ *
+ *
+ * vTaskDelay() specifies a time at which the task wishes to unblock relative to
+ * the time at which vTaskDelay() is called. For example, specifying a block
+ * period of 100 ticks will cause the task to unblock 100 ticks after
+ * vTaskDelay() is called. vTaskDelay() does not therefore provide a good method
+ * of controlling the frequency of a periodic task as the path taken through the
+ * code, as well as other task and interrupt activity, will effect the frequency
+ * at which vTaskDelay() gets called and therefore the time at which the task
+ * next executes. See vTaskDelayUntil() for an alternative API function designed
+ * to facilitate fixed frequency execution. It does this by specifying an
+ * absolute time (rather than a relative time) at which the calling task should
+ * unblock.
+ *
+ * @param xTicksToDelay The amount of time, in tick periods, that
+ * the calling task should block.
+ *
+ * Example usage:
+
+ void vTaskFunction( void * pvParameters )
+ {
+ // Block for 500ms.
+ const TickType_t xDelay = 500 / portTICK_PERIOD_MS;
+
+ for( ;; )
+ {
+ // Simply toggle the LED every 500ms, blocking between each toggle.
+ vToggleLED();
+ vTaskDelay( xDelay );
+ }
+ }
+
+ * \defgroup vTaskDelay vTaskDelay
+ * \ingroup TaskCtrl
+ */
+void vTaskDelay(const TickType_t xTicksToDelay) PRIVILEGED_FUNCTION;
+
+/**
+ * task. h
+ * void vTaskDelayUntil( TickType_t *pxPreviousWakeTime, const TickType_t xTimeIncrement );
+ *
+ * INCLUDE_vTaskDelayUntil must be defined as 1 for this function to be available.
+ * See the configuration section for more information.
+ *
+ * Delay a task until a specified time. This function can be used by periodic
+ * tasks to ensure a constant execution frequency.
+ *
+ * This function differs from vTaskDelay () in one important aspect: vTaskDelay () will
+ * cause a task to block for the specified number of ticks from the time vTaskDelay () is
+ * called. It is therefore difficult to use vTaskDelay () by itself to generate a fixed
+ * execution frequency as the time between a task starting to execute and that task
+ * calling vTaskDelay () may not be fixed [the task may take a different path though the
+ * code between calls, or may get interrupted or preempted a different number of times
+ * each time it executes].
+ *
+ * Whereas vTaskDelay () specifies a wake time relative to the time at which the function
+ * is called, vTaskDelayUntil () specifies the absolute (exact) time at which it wishes to
+ * unblock.
+ *
+ * The constant portTICK_PERIOD_MS can be used to calculate real time from the tick
+ * rate - with the resolution of one tick period.
+ *
+ * @param pxPreviousWakeTime Pointer to a variable that holds the time at which the
+ * task was last unblocked. The variable must be initialised with the current time
+ * prior to its first use (see the example below). Following this the variable is
+ * automatically updated within vTaskDelayUntil ().
+ *
+ * @param xTimeIncrement The cycle time period. The task will be unblocked at
+ * time *pxPreviousWakeTime + xTimeIncrement. Calling vTaskDelayUntil with the
+ * same xTimeIncrement parameter value will cause the task to execute with
+ * a fixed interface period.
+ *
+ * Example usage:
+
+ // Perform an action every 10 ticks.
+ void vTaskFunction( void * pvParameters )
+ {
+ TickType_t xLastWakeTime;
+ const TickType_t xFrequency = 10;
+
+ // Initialise the xLastWakeTime variable with the current time.
+ xLastWakeTime = xTaskGetTickCount ();
+ for( ;; )
+ {
+ // Wait for the next cycle.
+ vTaskDelayUntil( &xLastWakeTime, xFrequency );
+
+ // Perform action here.
+ }
+ }
+
+ * \defgroup vTaskDelayUntil vTaskDelayUntil
+ * \ingroup TaskCtrl
+ */
+void vTaskDelayUntil(TickType_t *const pxPreviousWakeTime, const TickType_t xTimeIncrement) PRIVILEGED_FUNCTION;
+
+/**
+ * task. h
+ * BaseType_t xTaskAbortDelay( TaskHandle_t xTask );
+ *
+ * INCLUDE_xTaskAbortDelay must be defined as 1 in FreeRTOSConfig.h for this
+ * function to be available.
+ *
+ * A task will enter the Blocked state when it is waiting for an event. The
+ * event it is waiting for can be a temporal event (waiting for a time), such
+ * as when vTaskDelay() is called, or an event on an object, such as when
+ * xQueueReceive() or ulTaskNotifyTake() is called. If the handle of a task
+ * that is in the Blocked state is used in a call to xTaskAbortDelay() then the
+ * task will leave the Blocked state, and return from whichever function call
+ * placed the task into the Blocked state.
+ *
+ * @param xTask The handle of the task to remove from the Blocked state.
+ *
+ * @return If the task referenced by xTask was not in the Blocked state then
+ * pdFAIL is returned. Otherwise pdPASS is returned.
+ *
+ * \defgroup xTaskAbortDelay xTaskAbortDelay
+ * \ingroup TaskCtrl
+ */
+BaseType_t xTaskAbortDelay(TaskHandle_t xTask) PRIVILEGED_FUNCTION;
+
+/**
+ * task. h
+ * UBaseType_t uxTaskPriorityGet( TaskHandle_t xTask );
+ *
+ * INCLUDE_uxTaskPriorityGet must be defined as 1 for this function to be available.
+ * See the configuration section for more information.
+ *
+ * Obtain the priority of any task.
+ *
+ * @param xTask Handle of the task to be queried. Passing a NULL
+ * handle results in the priority of the calling task being returned.
+ *
+ * @return The priority of xTask.
+ *
+ * Example usage:
+
+ void vAFunction( void )
+ {
+ TaskHandle_t xHandle;
+
+ // Create a task, storing the handle.
+ xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+ // ...
+
+ // Use the handle to obtain the priority of the created task.
+ // It was created with tskIDLE_PRIORITY, but may have changed
+ // it itself.
+ if( uxTaskPriorityGet( xHandle ) != tskIDLE_PRIORITY )
+ {
+ // The task has changed it's priority.
+ }
+
+ // ...
+
+ // Is our priority higher than the created task?
+ if( uxTaskPriorityGet( xHandle ) < uxTaskPriorityGet( NULL ) )
+ {
+ // Our priority (obtained using NULL handle) is higher.
+ }
+ }
+
+ * \defgroup uxTaskPriorityGet uxTaskPriorityGet
+ * \ingroup TaskCtrl
+ */
+UBaseType_t uxTaskPriorityGet(TaskHandle_t xTask) PRIVILEGED_FUNCTION;
+
+/**
+ * task. h
+ * UBaseType_t uxTaskPriorityGetFromISR( TaskHandle_t xTask );
+ *
+ * A version of uxTaskPriorityGet() that can be used from an ISR.
+ */
+UBaseType_t uxTaskPriorityGetFromISR(TaskHandle_t xTask) PRIVILEGED_FUNCTION;
+
+/**
+ * task. h
+ * eTaskState eTaskGetState( TaskHandle_t xTask );
+ *
+ * INCLUDE_eTaskGetState must be defined as 1 for this function to be available.
+ * See the configuration section for more information.
+ *
+ * Obtain the state of any task. States are encoded by the eTaskState
+ * enumerated type.
+ *
+ * @param xTask Handle of the task to be queried.
+ *
+ * @return The state of xTask at the time the function was called. Note the
+ * state of the task might change between the function being called, and the
+ * functions return value being tested by the calling task.
+ */
+eTaskState eTaskGetState(TaskHandle_t xTask) PRIVILEGED_FUNCTION;
+
+/**
+ * task. h
+ * void vTaskGetInfo( TaskHandle_t xTask, TaskStatus_t *pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState );
+ *
+ * configUSE_TRACE_FACILITY must be defined as 1 for this function to be
+ * available. See the configuration section for more information.
+ *
+ * Populates a TaskStatus_t structure with information about a task.
+ *
+ * @param xTask Handle of the task being queried. If xTask is NULL then
+ * information will be returned about the calling task.
+ *
+ * @param pxTaskStatus A pointer to the TaskStatus_t structure that will be
+ * filled with information about the task referenced by the handle passed using
+ * the xTask parameter.
+ *
+ * @xGetFreeStackSpace The TaskStatus_t structure contains a member to report
+ * the stack high water mark of the task being queried. Calculating the stack
+ * high water mark takes a relatively long time, and can make the system
+ * temporarily unresponsive - so the xGetFreeStackSpace parameter is provided to
+ * allow the high water mark checking to be skipped. The high watermark value
+ * will only be written to the TaskStatus_t structure if xGetFreeStackSpace is
+ * not set to pdFALSE;
+ *
+ * @param eState The TaskStatus_t structure contains a member to report the
+ * state of the task being queried. Obtaining the task state is not as fast as
+ * a simple assignment - so the eState parameter is provided to allow the state
+ * information to be omitted from the TaskStatus_t structure. To obtain state
+ * information then set eState to eInvalid - otherwise the value passed in
+ * eState will be reported as the task state in the TaskStatus_t structure.
+ *
+ * Example usage:
+
+ void vAFunction( void )
+ {
+ TaskHandle_t xHandle;
+ TaskStatus_t xTaskDetails;
+
+ // Obtain the handle of a task from its name.
+ xHandle = xTaskGetHandle( "Task_Name" );
+
+ // Check the handle is not NULL.
+ configASSERT( xHandle );
+
+ // Use the handle to obtain further information about the task.
+ vTaskGetInfo( xHandle,
+ &xTaskDetails,
+ pdTRUE, // Include the high water mark in xTaskDetails.
+ eInvalid ); // Include the task state in xTaskDetails.
+ }
+
+ * \defgroup vTaskGetInfo vTaskGetInfo
+ * \ingroup TaskCtrl
+ */
+void vTaskGetInfo(TaskHandle_t xTask, TaskStatus_t *pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState) PRIVILEGED_FUNCTION;
+
+/**
+ * task. h
+ * void vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority );
+ *
+ * INCLUDE_vTaskPrioritySet must be defined as 1 for this function to be available.
+ * See the configuration section for more information.
+ *
+ * Set the priority of any task.
+ *
+ * A context switch will occur before the function returns if the priority
+ * being set is higher than the currently executing task.
+ *
+ * @param xTask Handle to the task for which the priority is being set.
+ * Passing a NULL handle results in the priority of the calling task being set.
+ *
+ * @param uxNewPriority The priority to which the task will be set.
+ *
+ * Example usage:
+
+ void vAFunction( void )
+ {
+ TaskHandle_t xHandle;
+
+ // Create a task, storing the handle.
+ xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+ // ...
+
+ // Use the handle to raise the priority of the created task.
+ vTaskPrioritySet( xHandle, tskIDLE_PRIORITY + 1 );
+
+ // ...
+
+ // Use a NULL handle to raise our priority to the same value.
+ vTaskPrioritySet( NULL, tskIDLE_PRIORITY + 1 );
+ }
+
+ * \defgroup vTaskPrioritySet vTaskPrioritySet
+ * \ingroup TaskCtrl
+ */
+void vTaskPrioritySet(TaskHandle_t xTask, UBaseType_t uxNewPriority) PRIVILEGED_FUNCTION;
+
+/**
+ * task. h
+ * void vTaskSuspend( TaskHandle_t xTaskToSuspend );
+ *
+ * INCLUDE_vTaskSuspend must be defined as 1 for this function to be available.
+ * See the configuration section for more information.
+ *
+ * Suspend any task. When suspended a task will never get any microcontroller
+ * processing time, no matter what its priority.
+ *
+ * Calls to vTaskSuspend are not accumulative -
+ * i.e. calling vTaskSuspend () twice on the same task still only requires one
+ * call to vTaskResume () to ready the suspended task.
+ *
+ * @param xTaskToSuspend Handle to the task being suspended. Passing a NULL
+ * handle will cause the calling task to be suspended.
+ *
+ * Example usage:
+
+ void vAFunction( void )
+ {
+ TaskHandle_t xHandle;
+
+ // Create a task, storing the handle.
+ xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+ // ...
+
+ // Use the handle to suspend the created task.
+ vTaskSuspend( xHandle );
+
+ // ...
+
+ // The created task will not run during this period, unless
+ // another task calls vTaskResume( xHandle ).
+
+ //...
+
+
+ // Suspend ourselves.
+ vTaskSuspend( NULL );
+
+ // We cannot get here unless another task calls vTaskResume
+ // with our handle as the parameter.
+ }
+
+ * \defgroup vTaskSuspend vTaskSuspend
+ * \ingroup TaskCtrl
+ */
+void vTaskSuspend(TaskHandle_t xTaskToSuspend) PRIVILEGED_FUNCTION;
+
+/**
+ * task. h
+ * void vTaskResume( TaskHandle_t xTaskToResume );
+ *
+ * INCLUDE_vTaskSuspend must be defined as 1 for this function to be available.
+ * See the configuration section for more information.
+ *
+ * Resumes a suspended task.
+ *
+ * A task that has been suspended by one or more calls to vTaskSuspend ()
+ * will be made available for running again by a single call to
+ * vTaskResume ().
+ *
+ * @param xTaskToResume Handle to the task being readied.
+ *
+ * Example usage:
+
+ void vAFunction( void )
+ {
+ TaskHandle_t xHandle;
+
+ // Create a task, storing the handle.
+ xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+ // ...
+
+ // Use the handle to suspend the created task.
+ vTaskSuspend( xHandle );
+
+ // ...
+
+ // The created task will not run during this period, unless
+ // another task calls vTaskResume( xHandle ).
+
+ //...
+
+
+ // Resume the suspended task ourselves.
+ vTaskResume( xHandle );
+
+ // The created task will once again get microcontroller processing
+ // time in accordance with its priority within the system.
+ }
+
+ * \defgroup vTaskResume vTaskResume
+ * \ingroup TaskCtrl
+ */
+void vTaskResume(TaskHandle_t xTaskToResume) PRIVILEGED_FUNCTION;
+
+/**
+ * task. h
+ * void xTaskResumeFromISR( TaskHandle_t xTaskToResume );
+ *
+ * INCLUDE_xTaskResumeFromISR must be defined as 1 for this function to be
+ * available. See the configuration section for more information.
+ *
+ * An implementation of vTaskResume() that can be called from within an ISR.
+ *
+ * A task that has been suspended by one or more calls to vTaskSuspend ()
+ * will be made available for running again by a single call to
+ * xTaskResumeFromISR ().
+ *
+ * xTaskResumeFromISR() should not be used to synchronise a task with an
+ * interrupt if there is a chance that the interrupt could arrive prior to the
+ * task being suspended - as this can lead to interrupts being missed. Use of a
+ * semaphore as a synchronisation mechanism would avoid this eventuality.
+ *
+ * @param xTaskToResume Handle to the task being readied.
+ *
+ * @return pdTRUE if resuming the task should result in a context switch,
+ * otherwise pdFALSE. This is used by the ISR to determine if a context switch
+ * may be required following the ISR.
+ *
+ * \defgroup vTaskResumeFromISR vTaskResumeFromISR
+ * \ingroup TaskCtrl
+ */
+BaseType_t xTaskResumeFromISR(TaskHandle_t xTaskToResume) PRIVILEGED_FUNCTION;
+
+/*-----------------------------------------------------------
+ * SCHEDULER CONTROL
+ *----------------------------------------------------------*/
+
+/**
+ * task. h
+ * void vTaskStartScheduler( void );
+ *
+ * Starts the real time kernel tick processing. After calling the kernel
+ * has control over which tasks are executed and when.
+ *
+ * See the demo application file main.c for an example of creating
+ * tasks and starting the kernel.
+ *
+ * Example usage:
+
+ void vAFunction( void )
+ {
+ // Create at least one task before starting the kernel.
+ xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
+
+ // Start the real time kernel with preemption.
+ vTaskStartScheduler ();
+
+ // Will not get here unless a task calls vTaskEndScheduler ()
+ }
+
+ *
+ * \defgroup vTaskStartScheduler vTaskStartScheduler
+ * \ingroup SchedulerControl
+ */
+void vTaskStartScheduler(void) PRIVILEGED_FUNCTION;
+
+/**
+ * task. h
+ * void vTaskEndScheduler( void );
+ *
+ * NOTE: At the time of writing only the x86 real mode port, which runs on a PC
+ * in place of DOS, implements this function.
+ *
+ * Stops the real time kernel tick. All created tasks will be automatically
+ * deleted and multitasking (either preemptive or cooperative) will
+ * stop. Execution then resumes from the point where vTaskStartScheduler ()
+ * was called, as if vTaskStartScheduler () had just returned.
+ *
+ * See the demo application file main. c in the demo/PC directory for an
+ * example that uses vTaskEndScheduler ().
+ *
+ * vTaskEndScheduler () requires an exit function to be defined within the
+ * portable layer (see vPortEndScheduler () in port. c for the PC port). This
+ * performs hardware specific operations such as stopping the kernel tick.
+ *
+ * vTaskEndScheduler () will cause all of the resources allocated by the
+ * kernel to be freed - but will not free resources allocated by application
+ * tasks.
+ *
+ * Example usage:
+
+ void vTaskCode( void * pvParameters )
+ {
+ for( ;; )
+ {
+ // Task code goes here.
+
+ // At some point we want to end the real time kernel processing
+ // so call ...
+ vTaskEndScheduler ();
+ }
+ }
+
+ void vAFunction( void )
+ {
+ // Create at least one task before starting the kernel.
+ xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
+
+ // Start the real time kernel with preemption.
+ vTaskStartScheduler ();
+
+ // Will only get here when the vTaskCode () task has called
+ // vTaskEndScheduler (). When we get here we are back to single task
+ // execution.
+ }
+
+ *
+ * \defgroup vTaskEndScheduler vTaskEndScheduler
+ * \ingroup SchedulerControl
+ */
+void vTaskEndScheduler(void) PRIVILEGED_FUNCTION;
+
+/**
+ * task. h
+ * void vTaskSuspendAll( void );
+ *
+ * Suspends the scheduler without disabling interrupts. Context switches will
+ * not occur while the scheduler is suspended.
+ *
+ * After calling vTaskSuspendAll () the calling task will continue to execute
+ * without risk of being swapped out until a call to xTaskResumeAll () has been
+ * made.
+ *
+ * API functions that have the potential to cause a context switch (for example,
+ * vTaskDelayUntil(), xQueueSend(), etc.) must not be called while the scheduler
+ * is suspended.
+ *
+ * Example usage:
+
+ void vTask1( void * pvParameters )
+ {
+ for( ;; )
+ {
+ // Task code goes here.
+
+ // ...
+
+ // At some point the task wants to perform a long operation during
+ // which it does not want to get swapped out. It cannot use
+ // taskENTER_CRITICAL ()/taskEXIT_CRITICAL () as the length of the
+ // operation may cause interrupts to be missed - including the
+ // ticks.
+
+ // Prevent the real time kernel swapping out the task.
+ vTaskSuspendAll ();
+
+ // Perform the operation here. There is no need to use critical
+ // sections as we have all the microcontroller processing time.
+ // During this time interrupts will still operate and the kernel
+ // tick count will be maintained.
+
+ // ...
+
+ // The operation is complete. Restart the kernel.
+ xTaskResumeAll ();
+ }
+ }
+
+ * \defgroup vTaskSuspendAll vTaskSuspendAll
+ * \ingroup SchedulerControl
+ */
+void vTaskSuspendAll(void) PRIVILEGED_FUNCTION;
+
+/**
+ * task. h
+ * BaseType_t xTaskResumeAll( void );
+ *
+ * Resumes scheduler activity after it was suspended by a call to
+ * vTaskSuspendAll().
+ *
+ * xTaskResumeAll() only resumes the scheduler. It does not unsuspend tasks
+ * that were previously suspended by a call to vTaskSuspend().
+ *
+ * @return If resuming the scheduler caused a context switch then pdTRUE is
+ * returned, otherwise pdFALSE is returned.
+ *
+ * Example usage:
+
+ void vTask1( void * pvParameters )
+ {
+ for( ;; )
+ {
+ // Task code goes here.
+
+ // ...
+
+ // At some point the task wants to perform a long operation during
+ // which it does not want to get swapped out. It cannot use
+ // taskENTER_CRITICAL ()/taskEXIT_CRITICAL () as the length of the
+ // operation may cause interrupts to be missed - including the
+ // ticks.
+
+ // Prevent the real time kernel swapping out the task.
+ vTaskSuspendAll ();
+
+ // Perform the operation here. There is no need to use critical
+ // sections as we have all the microcontroller processing time.
+ // During this time interrupts will still operate and the real
+ // time kernel tick count will be maintained.
+
+ // ...
+
+ // The operation is complete. Restart the kernel. We want to force
+ // a context switch - but there is no point if resuming the scheduler
+ // caused a context switch already.
+ if( !xTaskResumeAll () )
+ {
+ taskYIELD ();
+ }
+ }
+ }
+
+ * \defgroup xTaskResumeAll xTaskResumeAll
+ * \ingroup SchedulerControl
+ */
+BaseType_t xTaskResumeAll(void) PRIVILEGED_FUNCTION;
+
+/*-----------------------------------------------------------
+ * TASK UTILITIES
+ *----------------------------------------------------------*/
+
+/**
+ * task. h
+ * TickType_t xTaskGetTickCount( void );
+ *
+ * @return The count of ticks since vTaskStartScheduler was called.
+ *
+ * \defgroup xTaskGetTickCount xTaskGetTickCount
+ * \ingroup TaskUtils
+ */
+TickType_t xTaskGetTickCount(void) PRIVILEGED_FUNCTION;
+
+/**
+ * task. h
+ * TickType_t xTaskGetTickCountFromISR( void );
+ *
+ * @return The count of ticks since vTaskStartScheduler was called.
+ *
+ * This is a version of xTaskGetTickCount() that is safe to be called from an
+ * ISR - provided that TickType_t is the natural word size of the
+ * microcontroller being used or interrupt nesting is either not supported or
+ * not being used.
+ *
+ * \defgroup xTaskGetTickCountFromISR xTaskGetTickCountFromISR
+ * \ingroup TaskUtils
+ */
+TickType_t xTaskGetTickCountFromISR(void) PRIVILEGED_FUNCTION;
+
+/**
+ * task. h
+ * uint16_t uxTaskGetNumberOfTasks( void );
+ *
+ * @return The number of tasks that the real time kernel is currently managing.
+ * This includes all ready, blocked and suspended tasks. A task that
+ * has been deleted but not yet freed by the idle task will also be
+ * included in the count.
+ *
+ * \defgroup uxTaskGetNumberOfTasks uxTaskGetNumberOfTasks
+ * \ingroup TaskUtils
+ */
+UBaseType_t uxTaskGetNumberOfTasks(void) PRIVILEGED_FUNCTION;
+
+/**
+ * task. h
+ * char *pcTaskGetName( TaskHandle_t xTaskToQuery );
+ *
+ * @return The text (human readable) name of the task referenced by the handle
+ * xTaskToQuery. A task can query its own name by either passing in its own
+ * handle, or by setting xTaskToQuery to NULL.
+ *
+ * \defgroup pcTaskGetName pcTaskGetName
+ * \ingroup TaskUtils
+ */
+char *pcTaskGetName(TaskHandle_t xTaskToQuery) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
+
+/**
+ * task. h
+ * TaskHandle_t xTaskGetHandle( const char *pcNameToQuery );
+ *
+ * NOTE: This function takes a relatively long time to complete and should be
+ * used sparingly.
+ *
+ * @return The handle of the task that has the human readable name pcNameToQuery.
+ * NULL is returned if no matching name is found. INCLUDE_xTaskGetHandle
+ * must be set to 1 in FreeRTOSConfig.h for pcTaskGetHandle() to be available.
+ *
+ * \defgroup pcTaskGetHandle pcTaskGetHandle
+ * \ingroup TaskUtils
+ */
+TaskHandle_t xTaskGetHandle(const char *pcNameToQuery) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
+
+/**
+ * task.h
+ * UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask );
+ *
+ * INCLUDE_uxTaskGetStackHighWaterMark must be set to 1 in FreeRTOSConfig.h for
+ * this function to be available.
+ *
+ * Returns the high water mark of the stack associated with xTask. That is,
+ * the minimum free stack space there has been (in words, so on a 32 bit machine
+ * a value of 1 means 4 bytes) since the task started. The smaller the returned
+ * number the closer the task has come to overflowing its stack.
+ *
+ * @param xTask Handle of the task associated with the stack to be checked.
+ * Set xTask to NULL to check the stack of the calling task.
+ *
+ * @return The smallest amount of free stack space there has been (in words, so
+ * actual spaces on the stack rather than bytes) since the task referenced by
+ * xTask was created.
+ */
+UBaseType_t uxTaskGetStackHighWaterMark(TaskHandle_t xTask) PRIVILEGED_FUNCTION;
+
+/* When using trace macros it is sometimes necessary to include task.h before
+FreeRTOS.h. When this is done TaskHookFunction_t will not yet have been defined,
+so the following two prototypes will cause a compilation error. This can be
+fixed by simply guarding against the inclusion of these two prototypes unless
+they are explicitly required by the configUSE_APPLICATION_TASK_TAG configuration
+constant. */
+#ifdef configUSE_APPLICATION_TASK_TAG
+#if configUSE_APPLICATION_TASK_TAG == 1
+/**
+ * task.h
+ * void vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHookFunction );
+ *
+ * Sets pxHookFunction to be the task hook function used by the task xTask.
+ * Passing xTask as NULL has the effect of setting the calling tasks hook
+ * function.
+ */
+void vTaskSetApplicationTaskTag(TaskHandle_t xTask, TaskHookFunction_t pxHookFunction) PRIVILEGED_FUNCTION;
+
+/**
+ * task.h
+ * void xTaskGetApplicationTaskTag( TaskHandle_t xTask );
+ *
+ * Returns the pxHookFunction value assigned to the task xTask.
+ */
+TaskHookFunction_t xTaskGetApplicationTaskTag(TaskHandle_t xTask) PRIVILEGED_FUNCTION;
+#endif /* configUSE_APPLICATION_TASK_TAG ==1 */
+#endif /* ifdef configUSE_APPLICATION_TASK_TAG */
+
+#if( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 )
+
+/* Each task contains an array of pointers that is dimensioned by the
+configNUM_THREAD_LOCAL_STORAGE_POINTERS setting in FreeRTOSConfig.h. The
+kernel does not use the pointers itself, so the application writer can use
+the pointers for any purpose they wish. The following two functions are
+used to set and query a pointer respectively. */
+void vTaskSetThreadLocalStoragePointer(TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue) PRIVILEGED_FUNCTION;
+void *pvTaskGetThreadLocalStoragePointer(TaskHandle_t xTaskToQuery, BaseType_t xIndex) PRIVILEGED_FUNCTION;
+
+#endif
+
+/**
+ * task.h
+ * BaseType_t xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter );
+ *
+ * Calls the hook function associated with xTask. Passing xTask as NULL has
+ * the effect of calling the Running tasks (the calling task) hook function.
+ *
+ * pvParameter is passed to the hook function for the task to interpret as it
+ * wants. The return value is the value returned by the task hook function
+ * registered by the user.
+ */
+BaseType_t xTaskCallApplicationTaskHook(TaskHandle_t xTask, void *pvParameter) PRIVILEGED_FUNCTION;
+
+/**
+ * xTaskGetIdleTaskHandle() is only available if
+ * INCLUDE_xTaskGetIdleTaskHandle is set to 1 in FreeRTOSConfig.h.
+ *
+ * Simply returns the handle of the idle task. It is not valid to call
+ * xTaskGetIdleTaskHandle() before the scheduler has been started.
+ */
+TaskHandle_t xTaskGetIdleTaskHandle(void) PRIVILEGED_FUNCTION;
+
+/**
+ * configUSE_TRACE_FACILITY must be defined as 1 in FreeRTOSConfig.h for
+ * uxTaskGetSystemState() to be available.
+ *
+ * uxTaskGetSystemState() populates an TaskStatus_t structure for each task in
+ * the system. TaskStatus_t structures contain, among other things, members
+ * for the task handle, task name, task priority, task state, and total amount
+ * of run time consumed by the task. See the TaskStatus_t structure
+ * definition in this file for the full member list.
+ *
+ * NOTE: This function is intended for debugging use only as its use results in
+ * the scheduler remaining suspended for an extended period.
+ *
+ * @param pxTaskStatusArray A pointer to an array of TaskStatus_t structures.
+ * The array must contain at least one TaskStatus_t structure for each task
+ * that is under the control of the RTOS. The number of tasks under the control
+ * of the RTOS can be determined using the uxTaskGetNumberOfTasks() API function.
+ *
+ * @param uxArraySize The size of the array pointed to by the pxTaskStatusArray
+ * parameter. The size is specified as the number of indexes in the array, or
+ * the number of TaskStatus_t structures contained in the array, not by the
+ * number of bytes in the array.
+ *
+ * @param pulTotalRunTime If configGENERATE_RUN_TIME_STATS is set to 1 in
+ * FreeRTOSConfig.h then *pulTotalRunTime is set by uxTaskGetSystemState() to the
+ * total run time (as defined by the run time stats clock, see
+ * http://www.freertos.org/rtos-run-time-stats.html) since the target booted.
+ * pulTotalRunTime can be set to NULL to omit the total run time information.
+ *
+ * @return The number of TaskStatus_t structures that were populated by
+ * uxTaskGetSystemState(). This should equal the number returned by the
+ * uxTaskGetNumberOfTasks() API function, but will be zero if the value passed
+ * in the uxArraySize parameter was too small.
+ *
+ * Example usage:
+
+ // This example demonstrates how a human readable table of run time stats
+ // information is generated from raw data provided by uxTaskGetSystemState().
+ // The human readable table is written to pcWriteBuffer
+ void vTaskGetRunTimeStats( char *pcWriteBuffer )
+ {
+ TaskStatus_t *pxTaskStatusArray;
+ volatile UBaseType_t uxArraySize, x;
+ uint32_t ulTotalRunTime, ulStatsAsPercentage;
+
+ // Make sure the write buffer does not contain a string.
+ *pcWriteBuffer = 0x00;
+
+ // Take a snapshot of the number of tasks in case it changes while this
+ // function is executing.
+ uxArraySize = uxTaskGetNumberOfTasks();
+
+ // Allocate a TaskStatus_t structure for each task. An array could be
+ // allocated statically at compile time.
+ pxTaskStatusArray = pvPortMalloc( uxArraySize * sizeof( TaskStatus_t ) );
+
+ if( pxTaskStatusArray != NULL )
+ {
+ // Generate raw status information about each task.
+ uxArraySize = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize, &ulTotalRunTime );
+
+ // For percentage calculations.
+ ulTotalRunTime /= 100UL;
+
+ // Avoid divide by zero errors.
+ if( ulTotalRunTime > 0 )
+ {
+ // For each populated position in the pxTaskStatusArray array,
+ // format the raw data as human readable ASCII data
+ for( x = 0; x < uxArraySize; x++ )
+ {
+ // What percentage of the total run time has the task used?
+ // This will always be rounded down to the nearest integer.
+ // ulTotalRunTimeDiv100 has already been divided by 100.
+ ulStatsAsPercentage = pxTaskStatusArray[ x ].ulRunTimeCounter / ulTotalRunTime;
+
+ if( ulStatsAsPercentage > 0UL )
+ {
+ sprintf( pcWriteBuffer, "%s\t\t%lu\t\t%lu%%\r\n", pxTaskStatusArray[ x ].pcTaskName, pxTaskStatusArray[ x ].ulRunTimeCounter, ulStatsAsPercentage );
+ }
+ else
+ {
+ // If the percentage is zero here then the task has
+ // consumed less than 1% of the total run time.
+ sprintf( pcWriteBuffer, "%s\t\t%lu\t\t<1%%\r\n", pxTaskStatusArray[ x ].pcTaskName, pxTaskStatusArray[ x ].ulRunTimeCounter );
+ }
+
+ pcWriteBuffer += strlen( ( char * ) pcWriteBuffer );
+ }
+ }
+
+ // The array is no longer needed, free the memory it consumes.
+ vPortFree( pxTaskStatusArray );
+ }
+ }
+
+ */
+UBaseType_t uxTaskGetSystemState(TaskStatus_t *const pxTaskStatusArray, const UBaseType_t uxArraySize, uint32_t *const pulTotalRunTime) PRIVILEGED_FUNCTION;
+
+/**
+ * task. h
+ * void vTaskList( char *pcWriteBuffer );
+ *
+ * configUSE_TRACE_FACILITY and configUSE_STATS_FORMATTING_FUNCTIONS must
+ * both be defined as 1 for this function to be available. See the
+ * configuration section of the FreeRTOS.org website for more information.
+ *
+ * NOTE 1: This function will disable interrupts for its duration. It is
+ * not intended for normal application runtime use but as a debug aid.
+ *
+ * Lists all the current tasks, along with their current state and stack
+ * usage high water mark.
+ *
+ * Tasks are reported as blocked ('B'), ready ('R'), deleted ('D') or
+ * suspended ('S').
+ *
+ * PLEASE NOTE:
+ *
+ * This function is provided for convenience only, and is used by many of the
+ * demo applications. Do not consider it to be part of the scheduler.
+ *
+ * vTaskList() calls uxTaskGetSystemState(), then formats part of the
+ * uxTaskGetSystemState() output into a human readable table that displays task
+ * names, states and stack usage.
+ *
+ * vTaskList() has a dependency on the sprintf() C library function that might
+ * bloat the code size, use a lot of stack, and provide different results on
+ * different platforms. An alternative, tiny, third party, and limited
+ * functionality implementation of sprintf() is provided in many of the
+ * FreeRTOS/Demo sub-directories in a file called printf-stdarg.c (note
+ * printf-stdarg.c does not provide a full snprintf() implementation!).
+ *
+ * It is recommended that production systems call uxTaskGetSystemState()
+ * directly to get access to raw stats data, rather than indirectly through a
+ * call to vTaskList().
+ *
+ * @param pcWriteBuffer A buffer into which the above mentioned details
+ * will be written, in ASCII form. This buffer is assumed to be large
+ * enough to contain the generated report. Approximately 40 bytes per
+ * task should be sufficient.
+ *
+ * \defgroup vTaskList vTaskList
+ * \ingroup TaskUtils
+ */
+void vTaskList(char *pcWriteBuffer) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
+
+/**
+ * task. h
+ * void vTaskGetRunTimeStats( char *pcWriteBuffer );
+ *
+ * configGENERATE_RUN_TIME_STATS and configUSE_STATS_FORMATTING_FUNCTIONS
+ * must both be defined as 1 for this function to be available. The application
+ * must also then provide definitions for
+ * portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and portGET_RUN_TIME_COUNTER_VALUE()
+ * to configure a peripheral timer/counter and return the timers current count
+ * value respectively. The counter should be at least 10 times the frequency of
+ * the tick count.
+ *
+ * NOTE 1: This function will disable interrupts for its duration. It is
+ * not intended for normal application runtime use but as a debug aid.
+ *
+ * Setting configGENERATE_RUN_TIME_STATS to 1 will result in a total
+ * accumulated execution time being stored for each task. The resolution
+ * of the accumulated time value depends on the frequency of the timer
+ * configured by the portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() macro.
+ * Calling vTaskGetRunTimeStats() writes the total execution time of each
+ * task into a buffer, both as an absolute count value and as a percentage
+ * of the total system execution time.
+ *
+ * NOTE 2:
+ *
+ * This function is provided for convenience only, and is used by many of the
+ * demo applications. Do not consider it to be part of the scheduler.
+ *
+ * vTaskGetRunTimeStats() calls uxTaskGetSystemState(), then formats part of the
+ * uxTaskGetSystemState() output into a human readable table that displays the
+ * amount of time each task has spent in the Running state in both absolute and
+ * percentage terms.
+ *
+ * vTaskGetRunTimeStats() has a dependency on the sprintf() C library function
+ * that might bloat the code size, use a lot of stack, and provide different
+ * results on different platforms. An alternative, tiny, third party, and
+ * limited functionality implementation of sprintf() is provided in many of the
+ * FreeRTOS/Demo sub-directories in a file called printf-stdarg.c (note
+ * printf-stdarg.c does not provide a full snprintf() implementation!).
+ *
+ * It is recommended that production systems call uxTaskGetSystemState() directly
+ * to get access to raw stats data, rather than indirectly through a call to
+ * vTaskGetRunTimeStats().
+ *
+ * @param pcWriteBuffer A buffer into which the execution times will be
+ * written, in ASCII form. This buffer is assumed to be large enough to
+ * contain the generated report. Approximately 40 bytes per task should
+ * be sufficient.
+ *
+ * \defgroup vTaskGetRunTimeStats vTaskGetRunTimeStats
+ * \ingroup TaskUtils
+ */
+void vTaskGetRunTimeStats(char *pcWriteBuffer) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
+
+/**
+ * task. h
+ * BaseType_t xTaskNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction );
+ *
+ * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this
+ * function to be available.
+ *
+ * When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private
+ * "notification value", which is a 32-bit unsigned integer (uint32_t).
+ *
+ * Events can be sent to a task using an intermediary object. Examples of such
+ * objects are queues, semaphores, mutexes and event groups. Task notifications
+ * are a method of sending an event directly to a task without the need for such
+ * an intermediary object.
+ *
+ * A notification sent to a task can optionally perform an action, such as
+ * update, overwrite or increment the task's notification value. In that way
+ * task notifications can be used to send data to a task, or be used as light
+ * weight and fast binary or counting semaphores.
+ *
+ * A notification sent to a task will remain pending until it is cleared by the
+ * task calling xTaskNotifyWait() or ulTaskNotifyTake(). If the task was
+ * already in the Blocked state to wait for a notification when the notification
+ * arrives then the task will automatically be removed from the Blocked state
+ * (unblocked) and the notification cleared.
+ *
+ * A task can use xTaskNotifyWait() to [optionally] block to wait for a
+ * notification to be pending, or ulTaskNotifyTake() to [optionally] block
+ * to wait for its notification value to have a non-zero value. The task does
+ * not consume any CPU time while it is in the Blocked state.
+ *
+ * See http://www.FreeRTOS.org/RTOS-task-notifications.html for details.
+ *
+ * @param xTaskToNotify The handle of the task being notified. The handle to a
+ * task can be returned from the xTaskCreate() API function used to create the
+ * task, and the handle of the currently running task can be obtained by calling
+ * xTaskGetCurrentTaskHandle().
+ *
+ * @param ulValue Data that can be sent with the notification. How the data is
+ * used depends on the value of the eAction parameter.
+ *
+ * @param eAction Specifies how the notification updates the task's notification
+ * value, if at all. Valid values for eAction are as follows:
+ *
+ * eSetBits -
+ * The task's notification value is bitwise ORed with ulValue. xTaskNofify()
+ * always returns pdPASS in this case.
+ *
+ * eIncrement -
+ * The task's notification value is incremented. ulValue is not used and
+ * xTaskNotify() always returns pdPASS in this case.
+ *
+ * eSetValueWithOverwrite -
+ * The task's notification value is set to the value of ulValue, even if the
+ * task being notified had not yet processed the previous notification (the
+ * task already had a notification pending). xTaskNotify() always returns
+ * pdPASS in this case.
+ *
+ * eSetValueWithoutOverwrite -
+ * If the task being notified did not already have a notification pending then
+ * the task's notification value is set to ulValue and xTaskNotify() will
+ * return pdPASS. If the task being notified already had a notification
+ * pending then no action is performed and pdFAIL is returned.
+ *
+ * eNoAction -
+ * The task receives a notification without its notification value being
+ * updated. ulValue is not used and xTaskNotify() always returns pdPASS in
+ * this case.
+ *
+ * pulPreviousNotificationValue -
+ * Can be used to pass out the subject task's notification value before any
+ * bits are modified by the notify function.
+ *
+ * @return Dependent on the value of eAction. See the description of the
+ * eAction parameter.
+ *
+ * \defgroup xTaskNotify xTaskNotify
+ * \ingroup TaskNotifications
+ */
+BaseType_t xTaskGenericNotify(TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue) PRIVILEGED_FUNCTION;
+#define xTaskNotify( xTaskToNotify, ulValue, eAction ) xTaskGenericNotify( ( xTaskToNotify ), ( ulValue ), ( eAction ), NULL )
+#define xTaskNotifyAndQuery( xTaskToNotify, ulValue, eAction, pulPreviousNotifyValue ) xTaskGenericNotify( ( xTaskToNotify ), ( ulValue ), ( eAction ), ( pulPreviousNotifyValue ) )
+
+/**
+ * task. h
+ * BaseType_t xTaskNotifyFromISR( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, BaseType_t *pxHigherPriorityTaskWoken );
+ *
+ * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this
+ * function to be available.
+ *
+ * When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private
+ * "notification value", which is a 32-bit unsigned integer (uint32_t).
+ *
+ * A version of xTaskNotify() that can be used from an interrupt service routine
+ * (ISR).
+ *
+ * Events can be sent to a task using an intermediary object. Examples of such
+ * objects are queues, semaphores, mutexes and event groups. Task notifications
+ * are a method of sending an event directly to a task without the need for such
+ * an intermediary object.
+ *
+ * A notification sent to a task can optionally perform an action, such as
+ * update, overwrite or increment the task's notification value. In that way
+ * task notifications can be used to send data to a task, or be used as light
+ * weight and fast binary or counting semaphores.
+ *
+ * A notification sent to a task will remain pending until it is cleared by the
+ * task calling xTaskNotifyWait() or ulTaskNotifyTake(). If the task was
+ * already in the Blocked state to wait for a notification when the notification
+ * arrives then the task will automatically be removed from the Blocked state
+ * (unblocked) and the notification cleared.
+ *
+ * A task can use xTaskNotifyWait() to [optionally] block to wait for a
+ * notification to be pending, or ulTaskNotifyTake() to [optionally] block
+ * to wait for its notification value to have a non-zero value. The task does
+ * not consume any CPU time while it is in the Blocked state.
+ *
+ * See http://www.FreeRTOS.org/RTOS-task-notifications.html for details.
+ *
+ * @param xTaskToNotify The handle of the task being notified. The handle to a
+ * task can be returned from the xTaskCreate() API function used to create the
+ * task, and the handle of the currently running task can be obtained by calling
+ * xTaskGetCurrentTaskHandle().
+ *
+ * @param ulValue Data that can be sent with the notification. How the data is
+ * used depends on the value of the eAction parameter.
+ *
+ * @param eAction Specifies how the notification updates the task's notification
+ * value, if at all. Valid values for eAction are as follows:
+ *
+ * eSetBits -
+ * The task's notification value is bitwise ORed with ulValue. xTaskNofify()
+ * always returns pdPASS in this case.
+ *
+ * eIncrement -
+ * The task's notification value is incremented. ulValue is not used and
+ * xTaskNotify() always returns pdPASS in this case.
+ *
+ * eSetValueWithOverwrite -
+ * The task's notification value is set to the value of ulValue, even if the
+ * task being notified had not yet processed the previous notification (the
+ * task already had a notification pending). xTaskNotify() always returns
+ * pdPASS in this case.
+ *
+ * eSetValueWithoutOverwrite -
+ * If the task being notified did not already have a notification pending then
+ * the task's notification value is set to ulValue and xTaskNotify() will
+ * return pdPASS. If the task being notified already had a notification
+ * pending then no action is performed and pdFAIL is returned.
+ *
+ * eNoAction -
+ * The task receives a notification without its notification value being
+ * updated. ulValue is not used and xTaskNotify() always returns pdPASS in
+ * this case.
+ *
+ * @param pxHigherPriorityTaskWoken xTaskNotifyFromISR() will set
+ * *pxHigherPriorityTaskWoken to pdTRUE if sending the notification caused the
+ * task to which the notification was sent to leave the Blocked state, and the
+ * unblocked task has a priority higher than the currently running task. If
+ * xTaskNotifyFromISR() sets this value to pdTRUE then a context switch should
+ * be requested before the interrupt is exited. How a context switch is
+ * requested from an ISR is dependent on the port - see the documentation page
+ * for the port in use.
+ *
+ * @return Dependent on the value of eAction. See the description of the
+ * eAction parameter.
+ *
+ * \defgroup xTaskNotify xTaskNotify
+ * \ingroup TaskNotifications
+ */
+BaseType_t xTaskGenericNotifyFromISR(TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue, BaseType_t *pxHigherPriorityTaskWoken) PRIVILEGED_FUNCTION;
+#define xTaskNotifyFromISR( xTaskToNotify, ulValue, eAction, pxHigherPriorityTaskWoken ) xTaskGenericNotifyFromISR( ( xTaskToNotify ), ( ulValue ), ( eAction ), NULL, ( pxHigherPriorityTaskWoken ) )
+#define xTaskNotifyAndQueryFromISR( xTaskToNotify, ulValue, eAction, pulPreviousNotificationValue, pxHigherPriorityTaskWoken ) xTaskGenericNotifyFromISR( ( xTaskToNotify ), ( ulValue ), ( eAction ), ( pulPreviousNotificationValue ), ( pxHigherPriorityTaskWoken ) )
+
+/**
+ * task. h
+ * BaseType_t xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait );
+ *
+ * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this
+ * function to be available.
+ *
+ * When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private
+ * "notification value", which is a 32-bit unsigned integer (uint32_t).
+ *
+ * Events can be sent to a task using an intermediary object. Examples of such
+ * objects are queues, semaphores, mutexes and event groups. Task notifications
+ * are a method of sending an event directly to a task without the need for such
+ * an intermediary object.
+ *
+ * A notification sent to a task can optionally perform an action, such as
+ * update, overwrite or increment the task's notification value. In that way
+ * task notifications can be used to send data to a task, or be used as light
+ * weight and fast binary or counting semaphores.
+ *
+ * A notification sent to a task will remain pending until it is cleared by the
+ * task calling xTaskNotifyWait() or ulTaskNotifyTake(). If the task was
+ * already in the Blocked state to wait for a notification when the notification
+ * arrives then the task will automatically be removed from the Blocked state
+ * (unblocked) and the notification cleared.
+ *
+ * A task can use xTaskNotifyWait() to [optionally] block to wait for a
+ * notification to be pending, or ulTaskNotifyTake() to [optionally] block
+ * to wait for its notification value to have a non-zero value. The task does
+ * not consume any CPU time while it is in the Blocked state.
+ *
+ * See http://www.FreeRTOS.org/RTOS-task-notifications.html for details.
+ *
+ * @param ulBitsToClearOnEntry Bits that are set in ulBitsToClearOnEntry value
+ * will be cleared in the calling task's notification value before the task
+ * checks to see if any notifications are pending, and optionally blocks if no
+ * notifications are pending. Setting ulBitsToClearOnEntry to ULONG_MAX (if
+ * limits.h is included) or 0xffffffffUL (if limits.h is not included) will have
+ * the effect of resetting the task's notification value to 0. Setting
+ * ulBitsToClearOnEntry to 0 will leave the task's notification value unchanged.
+ *
+ * @param ulBitsToClearOnExit If a notification is pending or received before
+ * the calling task exits the xTaskNotifyWait() function then the task's
+ * notification value (see the xTaskNotify() API function) is passed out using
+ * the pulNotificationValue parameter. Then any bits that are set in
+ * ulBitsToClearOnExit will be cleared in the task's notification value (note
+ * *pulNotificationValue is set before any bits are cleared). Setting
+ * ulBitsToClearOnExit to ULONG_MAX (if limits.h is included) or 0xffffffffUL
+ * (if limits.h is not included) will have the effect of resetting the task's
+ * notification value to 0 before the function exits. Setting
+ * ulBitsToClearOnExit to 0 will leave the task's notification value unchanged
+ * when the function exits (in which case the value passed out in
+ * pulNotificationValue will match the task's notification value).
+ *
+ * @param pulNotificationValue Used to pass the task's notification value out
+ * of the function. Note the value passed out will not be effected by the
+ * clearing of any bits caused by ulBitsToClearOnExit being non-zero.
+ *
+ * @param xTicksToWait The maximum amount of time that the task should wait in
+ * the Blocked state for a notification to be received, should a notification
+ * not already be pending when xTaskNotifyWait() was called. The task
+ * will not consume any processing time while it is in the Blocked state. This
+ * is specified in kernel ticks, the macro pdMS_TO_TICSK( value_in_ms ) can be
+ * used to convert a time specified in milliseconds to a time specified in
+ * ticks.
+ *
+ * @return If a notification was received (including notifications that were
+ * already pending when xTaskNotifyWait was called) then pdPASS is
+ * returned. Otherwise pdFAIL is returned.
+ *
+ * \defgroup xTaskNotifyWait xTaskNotifyWait
+ * \ingroup TaskNotifications
+ */
+BaseType_t xTaskNotifyWait(uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait) PRIVILEGED_FUNCTION;
+
+/**
+ * task. h
+ * BaseType_t xTaskNotifyGive( TaskHandle_t xTaskToNotify );
+ *
+ * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this macro
+ * to be available.
+ *
+ * When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private
+ * "notification value", which is a 32-bit unsigned integer (uint32_t).
+ *
+ * Events can be sent to a task using an intermediary object. Examples of such
+ * objects are queues, semaphores, mutexes and event groups. Task notifications
+ * are a method of sending an event directly to a task without the need for such
+ * an intermediary object.
+ *
+ * A notification sent to a task can optionally perform an action, such as
+ * update, overwrite or increment the task's notification value. In that way
+ * task notifications can be used to send data to a task, or be used as light
+ * weight and fast binary or counting semaphores.
+ *
+ * xTaskNotifyGive() is a helper macro intended for use when task notifications
+ * are used as light weight and faster binary or counting semaphore equivalents.
+ * Actual FreeRTOS semaphores are given using the xSemaphoreGive() API function,
+ * the equivalent action that instead uses a task notification is
+ * xTaskNotifyGive().
+ *
+ * When task notifications are being used as a binary or counting semaphore
+ * equivalent then the task being notified should wait for the notification
+ * using the ulTaskNotificationTake() API function rather than the
+ * xTaskNotifyWait() API function.
+ *
+ * See http://www.FreeRTOS.org/RTOS-task-notifications.html for more details.
+ *
+ * @param xTaskToNotify The handle of the task being notified. The handle to a
+ * task can be returned from the xTaskCreate() API function used to create the
+ * task, and the handle of the currently running task can be obtained by calling
+ * xTaskGetCurrentTaskHandle().
+ *
+ * @return xTaskNotifyGive() is a macro that calls xTaskNotify() with the
+ * eAction parameter set to eIncrement - so pdPASS is always returned.
+ *
+ * \defgroup xTaskNotifyGive xTaskNotifyGive
+ * \ingroup TaskNotifications
+ */
+#define xTaskNotifyGive( xTaskToNotify ) xTaskGenericNotify( ( xTaskToNotify ), ( 0 ), eIncrement, NULL )
+
+/**
+ * task. h
+ * void vTaskNotifyGiveFromISR( TaskHandle_t xTaskHandle, BaseType_t *pxHigherPriorityTaskWoken );
+ *
+ * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this macro
+ * to be available.
+ *
+ * When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private
+ * "notification value", which is a 32-bit unsigned integer (uint32_t).
+ *
+ * A version of xTaskNotifyGive() that can be called from an interrupt service
+ * routine (ISR).
+ *
+ * Events can be sent to a task using an intermediary object. Examples of such
+ * objects are queues, semaphores, mutexes and event groups. Task notifications
+ * are a method of sending an event directly to a task without the need for such
+ * an intermediary object.
+ *
+ * A notification sent to a task can optionally perform an action, such as
+ * update, overwrite or increment the task's notification value. In that way
+ * task notifications can be used to send data to a task, or be used as light
+ * weight and fast binary or counting semaphores.
+ *
+ * vTaskNotifyGiveFromISR() is intended for use when task notifications are
+ * used as light weight and faster binary or counting semaphore equivalents.
+ * Actual FreeRTOS semaphores are given from an ISR using the
+ * xSemaphoreGiveFromISR() API function, the equivalent action that instead uses
+ * a task notification is vTaskNotifyGiveFromISR().
+ *
+ * When task notifications are being used as a binary or counting semaphore
+ * equivalent then the task being notified should wait for the notification
+ * using the ulTaskNotificationTake() API function rather than the
+ * xTaskNotifyWait() API function.
+ *
+ * See http://www.FreeRTOS.org/RTOS-task-notifications.html for more details.
+ *
+ * @param xTaskToNotify The handle of the task being notified. The handle to a
+ * task can be returned from the xTaskCreate() API function used to create the
+ * task, and the handle of the currently running task can be obtained by calling
+ * xTaskGetCurrentTaskHandle().
+ *
+ * @param pxHigherPriorityTaskWoken vTaskNotifyGiveFromISR() will set
+ * *pxHigherPriorityTaskWoken to pdTRUE if sending the notification caused the
+ * task to which the notification was sent to leave the Blocked state, and the
+ * unblocked task has a priority higher than the currently running task. If
+ * vTaskNotifyGiveFromISR() sets this value to pdTRUE then a context switch
+ * should be requested before the interrupt is exited. How a context switch is
+ * requested from an ISR is dependent on the port - see the documentation page
+ * for the port in use.
+ *
+ * \defgroup xTaskNotifyWait xTaskNotifyWait
+ * \ingroup TaskNotifications
+ */
+void vTaskNotifyGiveFromISR(TaskHandle_t xTaskToNotify, BaseType_t *pxHigherPriorityTaskWoken) PRIVILEGED_FUNCTION;
+
+/**
+ * task. h
+ * uint32_t ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait );
+ *
+ * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this
+ * function to be available.
+ *
+ * When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private
+ * "notification value", which is a 32-bit unsigned integer (uint32_t).
+ *
+ * Events can be sent to a task using an intermediary object. Examples of such
+ * objects are queues, semaphores, mutexes and event groups. Task notifications
+ * are a method of sending an event directly to a task without the need for such
+ * an intermediary object.
+ *
+ * A notification sent to a task can optionally perform an action, such as
+ * update, overwrite or increment the task's notification value. In that way
+ * task notifications can be used to send data to a task, or be used as light
+ * weight and fast binary or counting semaphores.
+ *
+ * ulTaskNotifyTake() is intended for use when a task notification is used as a
+ * faster and lighter weight binary or counting semaphore alternative. Actual
+ * FreeRTOS semaphores are taken using the xSemaphoreTake() API function, the
+ * equivalent action that instead uses a task notification is
+ * ulTaskNotifyTake().
+ *
+ * When a task is using its notification value as a binary or counting semaphore
+ * other tasks should send notifications to it using the xTaskNotifyGive()
+ * macro, or xTaskNotify() function with the eAction parameter set to
+ * eIncrement.
+ *
+ * ulTaskNotifyTake() can either clear the task's notification value to
+ * zero on exit, in which case the notification value acts like a binary
+ * semaphore, or decrement the task's notification value on exit, in which case
+ * the notification value acts like a counting semaphore.
+ *
+ * A task can use ulTaskNotifyTake() to [optionally] block to wait for a
+ * the task's notification value to be non-zero. The task does not consume any
+ * CPU time while it is in the Blocked state.
+ *
+ * Where as xTaskNotifyWait() will return when a notification is pending,
+ * ulTaskNotifyTake() will return when the task's notification value is
+ * not zero.
+ *
+ * See http://www.FreeRTOS.org/RTOS-task-notifications.html for details.
+ *
+ * @param xClearCountOnExit if xClearCountOnExit is pdFALSE then the task's
+ * notification value is decremented when the function exits. In this way the
+ * notification value acts like a counting semaphore. If xClearCountOnExit is
+ * not pdFALSE then the task's notification value is cleared to zero when the
+ * function exits. In this way the notification value acts like a binary
+ * semaphore.
+ *
+ * @param xTicksToWait The maximum amount of time that the task should wait in
+ * the Blocked state for the task's notification value to be greater than zero,
+ * should the count not already be greater than zero when
+ * ulTaskNotifyTake() was called. The task will not consume any processing
+ * time while it is in the Blocked state. This is specified in kernel ticks,
+ * the macro pdMS_TO_TICSK( value_in_ms ) can be used to convert a time
+ * specified in milliseconds to a time specified in ticks.
+ *
+ * @return The task's notification count before it is either cleared to zero or
+ * decremented (see the xClearCountOnExit parameter).
+ *
+ * \defgroup ulTaskNotifyTake ulTaskNotifyTake
+ * \ingroup TaskNotifications
+ */
+uint32_t ulTaskNotifyTake(BaseType_t xClearCountOnExit, TickType_t xTicksToWait) PRIVILEGED_FUNCTION;
+
+/**
+ * task. h
+ * BaseType_t xTaskNotifyStateClear( TaskHandle_t xTask );
+ *
+ * If the notification state of the task referenced by the handle xTask is
+ * eNotified, then set the task's notification state to eNotWaitingNotification.
+ * The task's notification value is not altered. Set xTask to NULL to clear the
+ * notification state of the calling task.
+ *
+ * @return pdTRUE if the task's notification state was set to
+ * eNotWaitingNotification, otherwise pdFALSE.
+ * \defgroup xTaskNotifyStateClear xTaskNotifyStateClear
+ * \ingroup TaskNotifications
+ */
+BaseType_t xTaskNotifyStateClear(TaskHandle_t xTask);
+
+/*-----------------------------------------------------------
+ * SCHEDULER INTERNALS AVAILABLE FOR PORTING PURPOSES
+ *----------------------------------------------------------*/
+
+/*
+ * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS ONLY
+ * INTENDED FOR USE WHEN IMPLEMENTING A PORT OF THE SCHEDULER AND IS
+ * AN INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER.
+ *
+ * Called from the real time kernel tick (either preemptive or cooperative),
+ * this increments the tick count and checks if any tasks that are blocked
+ * for a finite period required removing from a blocked list and placing on
+ * a ready list. If a non-zero value is returned then a context switch is
+ * required because either:
+ * + A task was removed from a blocked list because its timeout had expired,
+ * or
+ * + Time slicing is in use and there is a task of equal priority to the
+ * currently running task.
+ */
+BaseType_t xTaskIncrementTick(void) PRIVILEGED_FUNCTION;
+
+/*
+ * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN
+ * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER.
+ *
+ * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED.
+ *
+ * Removes the calling task from the ready list and places it both
+ * on the list of tasks waiting for a particular event, and the
+ * list of delayed tasks. The task will be removed from both lists
+ * and replaced on the ready list should either the event occur (and
+ * there be no higher priority tasks waiting on the same event) or
+ * the delay period expires.
+ *
+ * The 'unordered' version replaces the event list item value with the
+ * xItemValue value, and inserts the list item at the end of the list.
+ *
+ * The 'ordered' version uses the existing event list item value (which is the
+ * owning tasks priority) to insert the list item into the event list is task
+ * priority order.
+ *
+ * @param pxEventList The list containing tasks that are blocked waiting
+ * for the event to occur.
+ *
+ * @param xItemValue The item value to use for the event list item when the
+ * event list is not ordered by task priority.
+ *
+ * @param xTicksToWait The maximum amount of time that the task should wait
+ * for the event to occur. This is specified in kernel ticks,the constant
+ * portTICK_PERIOD_MS can be used to convert kernel ticks into a real time
+ * period.
+ */
+void vTaskPlaceOnEventList(List_t *const pxEventList, const TickType_t xTicksToWait) PRIVILEGED_FUNCTION;
+void vTaskPlaceOnUnorderedEventList(List_t *pxEventList, const TickType_t xItemValue, const TickType_t xTicksToWait) PRIVILEGED_FUNCTION;
+
+/*
+ * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN
+ * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER.
+ *
+ * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED.
+ *
+ * This function performs nearly the same function as vTaskPlaceOnEventList().
+ * The difference being that this function does not permit tasks to block
+ * indefinitely, whereas vTaskPlaceOnEventList() does.
+ *
+ */
+void vTaskPlaceOnEventListRestricted(List_t *const pxEventList, TickType_t xTicksToWait, const BaseType_t xWaitIndefinitely) PRIVILEGED_FUNCTION;
+
+/*
+ * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN
+ * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER.
+ *
+ * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED.
+ *
+ * Removes a task from both the specified event list and the list of blocked
+ * tasks, and places it on a ready queue.
+ *
+ * xTaskRemoveFromEventList()/xTaskRemoveFromUnorderedEventList() will be called
+ * if either an event occurs to unblock a task, or the block timeout period
+ * expires.
+ *
+ * xTaskRemoveFromEventList() is used when the event list is in task priority
+ * order. It removes the list item from the head of the event list as that will
+ * have the highest priority owning task of all the tasks on the event list.
+ * xTaskRemoveFromUnorderedEventList() is used when the event list is not
+ * ordered and the event list items hold something other than the owning tasks
+ * priority. In this case the event list item value is updated to the value
+ * passed in the xItemValue parameter.
+ *
+ * @return pdTRUE if the task being removed has a higher priority than the task
+ * making the call, otherwise pdFALSE.
+ */
+BaseType_t xTaskRemoveFromEventList(const List_t *const pxEventList) PRIVILEGED_FUNCTION;
+BaseType_t xTaskRemoveFromUnorderedEventList(ListItem_t *pxEventListItem, const TickType_t xItemValue) PRIVILEGED_FUNCTION;
+
+/*
+ * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS ONLY
+ * INTENDED FOR USE WHEN IMPLEMENTING A PORT OF THE SCHEDULER AND IS
+ * AN INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER.
+ *
+ * Sets the pointer to the current TCB to the TCB of the highest priority task
+ * that is ready to run.
+ */
+int xTaskSwitchContext(void) PRIVILEGED_FUNCTION;
+
+/*
+ * THESE FUNCTIONS MUST NOT BE USED FROM APPLICATION CODE. THEY ARE USED BY
+ * THE EVENT BITS MODULE.
+ */
+TickType_t uxTaskResetEventItemValue(void) PRIVILEGED_FUNCTION;
+
+/*
+ * Return the handle of the calling task.
+ */
+TaskHandle_t xTaskGetCurrentTaskHandle(void) PRIVILEGED_FUNCTION;
+
+/*
+ * Capture the current time status for future reference.
+ */
+void vTaskSetTimeOutState(TimeOut_t *const pxTimeOut) PRIVILEGED_FUNCTION;
+
+/*
+ * Compare the time status now with that previously captured to see if the
+ * timeout has expired.
+ */
+BaseType_t xTaskCheckForTimeOut(TimeOut_t *const pxTimeOut, TickType_t *const pxTicksToWait) PRIVILEGED_FUNCTION;
+
+/*
+ * Shortcut used by the queue implementation to prevent unnecessary call to
+ * taskYIELD();
+ */
+void vTaskMissedYield(void) PRIVILEGED_FUNCTION;
+
+/*
+ * Returns the scheduler state as taskSCHEDULER_RUNNING,
+ * taskSCHEDULER_NOT_STARTED or taskSCHEDULER_SUSPENDED.
+ */
+BaseType_t xTaskGetSchedulerState(void) PRIVILEGED_FUNCTION;
+
+/*
+ * Raises the priority of the mutex holder to that of the calling task should
+ * the mutex holder have a priority less than the calling task.
+ */
+void vTaskPriorityInherit(TaskHandle_t const pxMutexHolder) PRIVILEGED_FUNCTION;
+
+/*
+ * Set the priority of a task back to its proper priority in the case that it
+ * inherited a higher priority while it was holding a semaphore.
+ */
+BaseType_t xTaskPriorityDisinherit(TaskHandle_t const pxMutexHolder) PRIVILEGED_FUNCTION;
+
+/*
+ * Get the uxTCBNumber assigned to the task referenced by the xTask parameter.
+ */
+UBaseType_t uxTaskGetTaskNumber(TaskHandle_t xTask) PRIVILEGED_FUNCTION;
+
+/*
+ * Set the uxTaskNumber of the task referenced by the xTask parameter to
+ * uxHandle.
+ */
+void vTaskSetTaskNumber(TaskHandle_t xTask, const UBaseType_t uxHandle) PRIVILEGED_FUNCTION;
+
+/*
+ * Only available when configUSE_TICKLESS_IDLE is set to 1.
+ * If tickless mode is being used, or a low power mode is implemented, then
+ * the tick interrupt will not execute during idle periods. When this is the
+ * case, the tick count value maintained by the scheduler needs to be kept up
+ * to date with the actual execution time by being skipped forward by a time
+ * equal to the idle period.
+ */
+void vTaskStepTick(const TickType_t xTicksToJump) PRIVILEGED_FUNCTION;
+
+TickType_t xGetExpectedIdleTime(void) PRIVILEGED_FUNCTION;
+/*
+ * Only avilable when configUSE_TICKLESS_IDLE is set to 1.
+ * Provided for use within portSUPPRESS_TICKS_AND_SLEEP() to allow the port
+ * specific sleep function to determine if it is ok to proceed with the sleep,
+ * and if it is ok to proceed, if it is ok to sleep indefinitely.
+ *
+ * This function is necessary because portSUPPRESS_TICKS_AND_SLEEP() is only
+ * called with the scheduler suspended, not from within a critical section. It
+ * is therefore possible for an interrupt to request a context switch between
+ * portSUPPRESS_TICKS_AND_SLEEP() and the low power mode actually being
+ * entered. eTaskConfirmSleepModeStatus() should be called from a short
+ * critical section between the timer being stopped and the sleep mode being
+ * entered to ensure it is ok to proceed into the sleep mode.
+ */
+eSleepModeStatus eTaskConfirmSleepModeStatus(void) PRIVILEGED_FUNCTION;
+
+/*
+ * For internal use only. Increment the mutex held count when a mutex is
+ * taken and return the handle of the task that has taken the mutex.
+ */
+void *pvTaskIncrementMutexHeldCount(void) PRIVILEGED_FUNCTION;
+
+void vPortStartFirstTask(void) ;
+
+// TickType_t prvGetExpectedIdleTime(void) PRIVILEGED_FUNCTION;
+TickType_t xGetExpectedIdleTime(void);
+
+void *uxTaskStack(void *tcb);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* INC_TASK_H */
+
+
+
diff --git a/include_lib/system/os/os_api.h b/include_lib/system/os/os_api.h
new file mode 100644
index 0000000..f4142a7
--- /dev/null
+++ b/include_lib/system/os/os_api.h
@@ -0,0 +1,442 @@
+#ifndef OS_API_H
+#define OS_API_H
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+
+
+#include "generic/typedef.h"
+//#include "generic/list.h"
+#include "os/os_cpu.h"
+#include "os/os_error.h"
+#include "os/os_type.h"
+
+
+typedef void *TaskHandle_t;
+
+#define Q_MSG 0x100000
+#define Q_EVENT 0x200000
+#define Q_CALLBACK 0x300000
+#define Q_USER 0x400000
+
+#define OS_DEL_NO_PEND 0u
+#define OS_DEL_ALWAYS 1u
+
+#define OS_TASK_DEL_REQ 0x01u
+#define OS_TASK_DEL_RES 0x02u
+#define OS_TASK_DEL_OK 0x03u
+
+
+#define OS_TASK_SELF (char *)0x1
+#define OS_TASK_FATHER (char *)0x2
+
+
+/* --------------------------------------------------------------------------*/
+/**
+ * @brief reserved
+ */
+/* ----------------------------------------------------------------------------*/
+void os_init(void);
+
+/* --------------------------------------------------------------------------*/
+/**
+ * @brief reserved
+ */
+/* ----------------------------------------------------------------------------*/
+void os_start(void);
+
+/* --------------------------------------------------------------------------*/
+/**
+ * @brief reserved
+ */
+/* ----------------------------------------------------------------------------*/
+void os_init_tick(int);
+
+/* --------------------------------------------------------------------------*/
+/**
+ * @brief 创建任务
+ *
+ * @param task 任务回调函数
+ * @param p_arg 传递给任务回调函数的参数
+ * @param prio 任务的优先级
+ * @param stksize 任务的堆栈大小, 单位(u32)
+ * @param qsize 任务的queue大小,单位(byte)
+ * @param name 任务名 (名字长度不能超过configMAX_TASK_NAME_LEN字节)
+ *
+ * @return 错误码
+ */
+/* ----------------------------------------------------------------------------*/
+int os_task_create(void (*task)(void *p_arg),
+ void *p_arg,
+ u8 prio,
+ u32 stksize,
+ int qsize,
+ const char *name);
+
+int os_task_create_affinity_core(void (*task)(void *p_arg),
+ void *p_arg,
+ u8 prio,
+ u32 stksize,
+ int qsize,
+ const char *name,
+ u8 core);
+
+/* --------------------------------------------------------------------------*/
+/**
+ * @brief 获取当前任务名
+ *
+ * @return 当前任务名
+ */
+/* ----------------------------------------------------------------------------*/
+const char *os_current_task();
+
+/* --------------------------------------------------------------------------*/
+/**
+ * @brief 删除任务
+ *
+ * @param name 任务名
+ *
+ * @return 错误码
+ */
+/* ----------------------------------------------------------------------------*/
+int os_task_del_req(const char *name);
+
+/* --------------------------------------------------------------------------*/
+/**
+ * @brief 响应任务删除请求,标记资源已经释放,可以删除当前任
+ *
+ * @param name 任务名,任务自己可以用OS_TASK_SELF
+ *
+ * @return 错误码
+ */
+/* ----------------------------------------------------------------------------*/
+int os_task_del_res(const char *name);
+
+/* --------------------------------------------------------------------------*/
+/**
+ * @brief 删除任务
+ *
+ * @param name 任务名
+ *
+ * @return 错误码
+ */
+/* ----------------------------------------------------------------------------*/
+int os_task_del(const char *name);
+
+
+/* --------------------------------------------------------------------------*/
+/**
+ * @brief 延时。中断函数或者关闭系统总中断的情况下不能调用此函数
+ *
+ * @param time_tick 延时时间
+ */
+/* ----------------------------------------------------------------------------*/
+void os_time_dly(int time_tick);
+
+
+/* --------------------------------------------------------------------------*/
+/**
+ * @brief 发送Q_USER类型taskq
+ *
+ * @param name 任务名
+ * @param argc 后面传入的参数的个数。发送的最大参数个数限制为8个int类型
+ *
+ * @return 错误码
+ */
+/* ----------------------------------------------------------------------------*/
+int os_taskq_post(const char *name, int argc, ...);
+
+/* --------------------------------------------------------------------------*/
+/**
+ * @brief 非阻塞方式查询taskq
+ *
+ * @param argc 最大可获取的queue长度,单位(int)
+ * @param argv 存放queue的buf
+ *
+ * @return 错误码
+ */
+/* ----------------------------------------------------------------------------*/
+int os_taskq_accept(int argc, int *argv);
+
+/* --------------------------------------------------------------------------*/
+/**
+ * @brief 阻塞方式获取taskq
+ *
+ * @param fmt 保留,传NULL
+ * @param argv 存放queue的buf
+ * @param argc 最大可获取的queue长度,单位(int)
+ *
+ * @return 错误码
+ */
+/* ----------------------------------------------------------------------------*/
+int os_taskq_pend(const char *fmt, int *argv, int argc);
+// int os_task_pend(const char *fmt, int *argv, int argc);
+// int __os_taskq_pend(int *argv, int argc, int tick);
+
+
+
+/* --------------------------------------------------------------------------*/
+/**
+ * @brief 发送指定类型的taskq
+ *
+ * @param name 任务名
+ * @param type queue类型
+ * @param argc 后面传入的参数的个数
+ * @param argv
+ *
+ * @return 错误码
+ */
+/* ----------------------------------------------------------------------------*/
+int os_taskq_post_type(const char *name, int type, int argc, int *argv);
+
+
+/* --------------------------------------------------------------------------*/
+/**
+ * @brief 发送Q_MSG类型的taskq
+ *
+ * @param name 任务名
+ * @param argc 后面参数的个数
+ *
+ * @reutrn 错误码
+ */
+/* ----------------------------------------------------------------------------*/
+int os_taskq_post_msg(const char *name, int argc, ...);
+
+
+/* --------------------------------------------------------------------------*/
+/**
+ * @brief 发送Q_EVENT类型的taskq
+ *
+ * @param name 任务名
+ * @param argc 后面参数的个数
+ *
+ * @reutrn 错误码
+ */
+/* ----------------------------------------------------------------------------*/
+int os_taskq_post_event(const char *name, int argc, ...);
+
+
+/* --------------------------------------------------------------------------*/
+/**
+ * @brief 删除指定类型的taskq
+ *
+ * @param name 任务名
+ * @param type taskq的类型
+ *
+ * @reutrn 错误码
+ */
+/* ----------------------------------------------------------------------------*/
+int os_taskq_del_type(const char *name, int type);
+
+/* --------------------------------------------------------------------------*/
+/**
+ * @brief 清除所有taskq
+ *
+ * @reutrn 错误码
+ */
+/* ----------------------------------------------------------------------------*/
+int os_taskq_flush(void);
+
+/* --------------------------------------------------------------------------*/
+/**
+ * @brief 创建信号量
+ *
+ * @param sem 信号量
+ * @param int 初始计数值
+ *
+ * @reutrn 错误码
+ */
+/* ----------------------------------------------------------------------------*/
+int os_sem_create(OS_SEM *, int);
+
+/* --------------------------------------------------------------------------*/
+/**
+ * @brief 非阻塞方式查询信号量
+ *
+ * @param sem 信号量
+ *
+ * @reutrn 错误码
+ */
+/* ----------------------------------------------------------------------------*/
+int os_sem_accept(OS_SEM *);
+
+/* --------------------------------------------------------------------------*/
+/**
+ * @brief 阻塞方式获取信号量
+ *
+ * @param sem 信号量
+ * @param timeout 等待时长,0表示一直等待
+ *
+ * @reutrn 错误码
+ */
+/* ----------------------------------------------------------------------------*/
+int os_sem_pend(OS_SEM *, int timeout);
+
+/* --------------------------------------------------------------------------*/
+/**
+ * @brief 发送信号量
+ *
+ * @param sem 信号量
+ *
+ * @reutrn 错误码
+ */
+/* ----------------------------------------------------------------------------*/
+int os_sem_post(OS_SEM *);
+
+/* --------------------------------------------------------------------------*/
+/**
+ * @brief 信号量删除
+ *
+ * @param sem 信号量
+ * @param block 保留
+ *
+ * @reutrn 错误码
+ */
+/* ----------------------------------------------------------------------------*/
+int os_sem_del(OS_SEM *, int block);
+
+/* --------------------------------------------------------------------------*/
+/**
+ * @brief 信号量设置
+ *
+ * @param sem 信号量
+ * @param cnt 计数值
+ *
+ * @reutrn 错误码
+ */
+/* ----------------------------------------------------------------------------*/
+int os_sem_set(OS_SEM *, u16 cnt);
+
+/* --------------------------------------------------------------------------*/
+/**
+ * @brief 信号量类型是否queueQUEUE_TYPE_COUNTING_SEMAPHORE
+ *
+ * @param true:信号量匹配, fail:信号量不匹配
+ *
+ * @reutrn 错误码
+ */
+/* ----------------------------------------------------------------------------*/
+int os_sem_valid(OS_SEM *);
+
+/* --------------------------------------------------------------------------*/
+/**
+ * @brief 判断信号量是否可用
+ *
+ * @param sem 信号量
+ *
+ * @reutrn 可用数量
+ */
+/* ----------------------------------------------------------------------------*/
+int os_sem_query(OS_SEM *);
+
+/* --------------------------------------------------------------------------*/
+/**
+ * @brief 创建互斥量
+ *
+ * @param mutex 互斥量
+ *
+ * @reutrn 错误码
+ */
+/* ----------------------------------------------------------------------------*/
+int os_mutex_create(OS_MUTEX *);
+
+/* --------------------------------------------------------------------------*/
+/**
+ * @brief 非阻塞方式查询互斥量
+ *
+ * @param mutex:互斥量
+ *
+ * @reutrn 错误码
+ */
+/* ----------------------------------------------------------------------------*/
+int os_mutex_accept(OS_MUTEX *);
+
+/* --------------------------------------------------------------------------*/
+/**
+ * @brief 阻塞方式查询互斥量
+ *
+ * @param mutex 互斥量
+ * @param timeout 等待时间,0表示一直等待
+ *
+ * @reutrn 错误码
+ */
+/* ----------------------------------------------------------------------------*/
+int os_mutex_pend(OS_MUTEX *, int timeout);
+
+/* --------------------------------------------------------------------------*/
+/**
+ * @brief 发送斥量
+ *
+ * @param mutex 互斥量
+ *
+ * @reutrn 错误码
+ */
+/* ----------------------------------------------------------------------------*/
+int os_mutex_post(OS_MUTEX *);
+
+/* --------------------------------------------------------------------------*/
+/**
+ * @brief 删除斥量
+ *
+ * @param mutex 互斥量
+ * @param block 保留
+ *
+ * @reutrn 错误码
+ */
+/* ----------------------------------------------------------------------------*/
+int os_mutex_del(OS_MUTEX *, int block);
+
+/* --------------------------------------------------------------------------*/
+/**
+ * @brief 互斥量类型是否queueQUEUE_TYPE_MUTEX
+ *
+ * @param true:互斥量匹配, fail:互斥量不匹配
+ *
+ * @reutrn 错误码
+ */
+/* ----------------------------------------------------------------------------*/
+int os_mutex_valid(OS_MUTEX *);
+
+/*struct os_msg *os_message_create(int size);
+
+int os_message_receive(struct os_msg **msg, int block_time);
+
+int os_message_send(const char *task_name, struct os_msg *msg, int msgflg);
+
+int os_message_delete(struct os_msg *msg);*/
+
+
+
+int os_q_create(OS_QUEUE *pevent, /*void **start, */QS size);
+
+int os_q_del(OS_QUEUE *pevent, u8 opt);
+
+int os_q_flush(OS_QUEUE *pevent);
+
+int os_q_pend(OS_QUEUE *pevent, int timeout, void *msg);
+
+int os_q_post(OS_QUEUE *pevent, void *msg);
+
+int os_q_query(OS_QUEUE *pevent);
+
+int os_q_valid(OS_QUEUE *pevent);
+
+int task_queue_post_event(const char *name, void *data, int len);
+
+void *os_task_get_handle(const char *name);
+
+void os_suspend_other_core(void);
+
+void os_resume_other_core(void);
+
+void os_system_info_output(void);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/include_lib/system/os/os_cfg.h b/include_lib/system/os/os_cfg.h
new file mode 100644
index 0000000..a1eea4f
--- /dev/null
+++ b/include_lib/system/os/os_cfg.h
@@ -0,0 +1,135 @@
+/***********************************Jieli tech************************************************
+File : os_cfg.h
+By : Juntham
+date : 2014-07-03 09:09
+ ********************************************************************************************/
+
+#ifndef OS_CFG_H
+#define OS_CFG_H
+#include "os/os_cpu.h"
+
+#define OS_TIME_SLICE_EN 1
+
+#define OS_PRIORITY_INVERSION 1 /*是否处理优先级翻转*/
+
+/* ---------------------- MISCELLANEOUS ----------------------- */
+#define OS_ARG_CHK_EN 0 /* Enable (1) or Disable (0) argument checking */
+#define OS_CPU_HOOKS_EN 1 /* hooks are found in the processor port files */
+
+#if OS_TIME_SLICE_EN > 0
+#define OS_LOWEST_PRIO (0) /* Defines the lowest priority that can be assigned ... */
+#else
+#define OS_LOWEST_PRIO (0+OS_CPU_CORE-1)/* Defines the lowest priority that can be assigned */
+#endif
+
+#define OS_IDLE_PRIO (OS_LOWEST_PRIO) /* IDLE task priority */
+
+#define OS_MAX_TASKS 31 /* Max. number of tasks in your application, MUST be >= 2 */
+
+#define OS_SCHED_LOCK_EN 1 /* Include code for OSSchedLock() and OSSchedUnlock() */
+
+#define OS_TICKS_PER_SEC 100 /* Set the number of ticks in one second */
+
+#define OS_PARENT_TCB 1 /* 是否记录父任务的TCB */
+
+#define OS_CHILD_TCB 0 /* 是否记录子任务的TCB */
+
+/* ----------------------TASK MESSAGE QUEUES ---------------------- */
+#define OS_TASKQ_EN 1 /* Enable (1) or Disable (0) code generation for QUEUES */
+#define OS_TASKQ_ACCEPT_EN 1 /* Include code for OSTaskQAccept() */
+#define OS_TASKQ_PEND_EN 1 /* Include code for OSTaskQAccept() */
+#define OS_TASKQ_FLUSH_EN 1 /* Include code for OSTaskQFlush() */
+#define OS_TASKQ_POST_EN 1 /* Include code for OSTaskQPost() */
+#define OS_TASKQ_POST_FRONT_EN 1 /* Include code for OSTaskQPostFront() */
+#define OS_TASKQ_QUERY_EN 1 /* Include code for OSTaskQQuery() */
+
+/* ---------------- MUTUAL EXCLUSION SEMAPHORES --------------- */
+#define OS_MUTEX_EN 1 /* Enable (1) or Disable (0) code generation for MUTEX */
+#define OS_MUTEX_ACCEPT_EN 1 /* Include code for OSMutexAccept() */
+#define OS_MUTEX_DEL_EN 1 /* Include code for OSMutexDel() */
+#define OS_MUTEX_QUERY_EN 0 /* Include code for OSMutexQuery() */
+
+/* ------------------------ SEMAPHORES ------------------------ */
+#define OS_SEM_EN 1 /* Enable (1) or Disable (0) code generation for SEMAPHORES */
+#define OS_SEM_ACCEPT_EN 1 /* Include code for OSSemAccept() */
+#define OS_SEM_DEL_EN 1 /* Include code for OSSemDel() */
+#define OS_SEM_QUERY_EN 1 /* Include code for OSSemQuery() */
+#define OS_SEM_SET_EN 1 /* Include code for OSSemSet() */
+
+/* ---------------------- MESSAGE QUEUES ---------------------- */
+#define OS_Q_EN 1 /* Enable (1) or Disable (0) code generation for QUEUES */
+#define OS_Q_ACCEPT_EN 1 /* Include code for OSQAccept() */
+#define OS_Q_DEL_EN 1 /* Include code for OSQDel() */
+#define OS_Q_FLUSH_EN 1 /* Include code for OSQFlush() */
+#define OS_Q_POST_EN 1 /* Include code for OSQPost() */
+#define OS_Q_POST_FRONT_EN 1 /* Include code for OSQPostFront() */
+#define OS_Q_POST_OPT_EN 1 /* Include code for OSQPostOpt() */
+#define OS_Q_QUERY_EN 1 /* Include code for OSQQuery() */
+
+/* ----------------------- EVENT FLAGS ------------------------ */
+#define OS_FLAG_EN 0 /* Enable (1) or Disable (0) code generation for EVENT FLAGS */
+#define OS_MAX_FLAGS 1 /* Max. number of Event Flag Groups in your application */
+#define OS_FLAG_WAIT_CLR_EN 1 /* Include code for Wait on Clear EVENT FLAGS */
+#define OS_FLAG_ACCEPT_EN 1 /* Include code for OSFlagAccept() */
+#define OS_FLAG_DEL_EN 1 /* Include code for OSFlagDel() */
+#define OS_FLAG_NAME_SIZE 0//32 /* Determine the size of the name of an event flag group */
+#define OS_FLAG_QUERY_EN 1 /* Include code for OSFlagQuery() */
+#define OS_FLAGS_NBITS 32 /* Size in #bits of OS_FLAGS data type (8, 16 or 32) */
+
+/* --------------------- TASK MANAGEMENT ---------------------- */
+#define OS_TASK_CHANGE_PRIO_EN 1 /* Include code for OSTaskChangePrio() */
+#define OS_TASK_CREATE_EN 1 /* Include code for OSTaskCreate() */
+#define OS_TASK_DEL_EN 1 /* Include code for OSTaskDel() */
+#define OS_TASK_QUERY_EN 0 /* Include code for OSTaskQuery() */
+#define OS_TASK_SUSPEND_EN 1 /* Include code for OSTaskSuspend() and OSTaskResume() */
+#define OS_TASK_SW_HOOK_EN 0 /* Include code for OSTaskSwHook() */
+#define OS_TASK_STK_CHK 0
+
+/* --------------------- TIME MANAGEMENT ---------------------- */
+#define OS_TIME_DLY_HMSM_EN 0 /* Include code for OSTimeDlyHMSM() */
+#define OS_TIME_DLY_RESUME_EN 1 /* Include code for OSTimeDlyResume() */
+#define OS_TIME_GET_SET_EN 1 /* Include code for OSTimeGet() and OSTimeSet() */
+#define OS_TIME_TICK_HOOK_EN 0 /* Include code for OSTimeTickHook() */
+
+#define OS_EVENT_EN ((OS_Q_EN > 0) || (OS_SEM_EN > 0) || (OS_MUTEX_EN > 0))
+
+
+//for make
+#define portMAX_DELAY 0
+
+#ifndef tskIDLE_PRIORITY
+#define tskIDLE_PRIORITY 0
+#endif /* #ifndef tskIDLE_PRIORITY */
+
+#ifndef configMAX_PRIORITIES
+#define configMAX_PRIORITIES 8
+#endif /* #ifndef configMAX_PRIORITIES */
+
+#ifndef configSUPPORT_DYNAMIC_ALLOCATION
+/* Defaults to 1 for backward compatibility. */
+#define configSUPPORT_DYNAMIC_ALLOCATION 1
+#endif
+
+#ifndef OS_CPU_NUM
+#define OS_CPU_NUM CPU_CORE_NUM
+#endif /* #ifndef OS_CPU_NUM */
+
+
+#ifndef OS_MBOX_EN
+#define OS_MBOX_EN 0
+#endif
+
+#ifndef OS_MEM_EN
+#define OS_MEM_EN 0
+#endif
+
+
+#ifndef configAPPLICATION_ALLOCATED_HEAP
+#define configAPPLICATION_ALLOCATED_HEAP 0
+#endif
+
+#ifndef configUSE_MALLOC_FAILED_HOOK
+#define configUSE_MALLOC_FAILED_HOOK 0
+#endif
+
+#endif
diff --git a/include_lib/system/os/os_cpu.h b/include_lib/system/os/os_cpu.h
new file mode 100644
index 0000000..fb9e943
--- /dev/null
+++ b/include_lib/system/os/os_cpu.h
@@ -0,0 +1,117 @@
+/***********************************Jieli tech************************************************
+ File : os_cpu.h
+ By : Juntham
+ date : 2014-07-03 09:06
+********************************************************************************************/
+#ifndef _OS_CPU_H
+#define _OS_CPU_H
+
+#include "asm/cpu.h"
+#include "jiffies.h"
+
+
+#ifndef __ASSEMBLY__
+typedef unsigned short QS;
+typedef unsigned int OS_STK; /* Each stack entry is 32-bit wide*/
+typedef unsigned int OS_CPU_SR; /* Unsigned 32 bit quantity */
+typedef unsigned int OS_CPU_DATA; /* Unsigned 32 bit quantity */
+#endif
+
+#define OS_CPU_EXT extern
+#define OS_CPU_CORE CPU_CORE_NUM
+
+#define OS_CPU_ID current_cpu_id()
+#define OS_STK_GROWTH 1 /* Stack grows from HIGH to LOW memory*/
+
+#define OS_CPU_MMU 0
+
+#define OS_CPU_VIRTUAL_MEM 1 //临时定义:区别于OS_CPU_MMU
+
+#ifndef OS_CORE_AFFINITY_ENABLE
+#define OS_CORE_AFFINITY_ENABLE 0
+#endif
+
+#define OS_TASK_CLR(a) CPU_TASK_CLR(a)
+#define OS_TASK_SW(a) CPU_TASK_SW(a) /* 任务级任务切换函数*/
+#define OS_INT_NESTING CPU_INT_NESTING
+
+#define CPU_SR_ALLOC()
+
+#define OS_SR_ALLOC()
+
+#define OS_ENTER_CRITICAL() \
+ CPU_CRITICAL_ENTER(); \
+
+#define OS_EXIT_CRITICAL() \
+ CPU_CRITICAL_EXIT()
+
+
+
+
+#ifndef __ASSEMBLY__
+
+/*#include "system/spinlock.h"
+
+extern spinlock_t os_lock;
+
+#define OS_ENTER_CRITICAL() \
+ spin_lock(&os_lock)
+
+#define OS_EXIT_CRITICAL() \
+ spin_unlock(&os_lock)*/
+
+
+void OSCtxSw(void);
+
+extern void EnableOtherCpu(void) ;
+
+#define os_ctx_sw OSCtxSw
+
+void OSInitTick(u32 hz);
+
+void InstallOSISR(void);
+
+void os_task_dead(const char *task_name);
+
+//=======================================================//
+// 系统进临界区多核同步类型 //
+//=======================================================//
+enum CPU_SUSPEND_TYPE {
+ CPU_SUSPEND_TYPE_NONE = 0,
+ CPU_SUSPEND_TYPE_SFC = 0x55, //操作Flash
+ CPU_SUSPEND_TYPE_PDOWN, //系统进低功耗Pdown
+ CPU_SUSPEND_TYPE_POFF, //系统进低功耗Pdown
+ CPU_SUSPEND_TYPE_SOFF,
+};
+
+/* ---------------------------------------------------------------------------- */
+/**
+ * @brief 系统进入临界区用于多核同步
+ */
+/* ---------------------------------------------------------------------------- */
+void cpu_suspend_other_core(enum CPU_SUSPEND_TYPE type);
+
+/* ---------------------------------------------------------------------------- */
+/**
+ * @brief 系统退出临界区用于多核同步
+ */
+/* ---------------------------------------------------------------------------- */
+void cpu_resume_other_core(enum CPU_SUSPEND_TYPE type);
+
+#endif
+
+/*
+*********************************************************************************************************
+* DATA TYPES
+* (Compiler Specific)
+*********************************************************************************************************
+*/
+
+
+#define OS_CRITICAL_METHOD 3
+#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
+//#define CPU_SR_ALLOC() OS_CPU_SR cpu_sr
+#endif
+
+
+#endif /*_OS_CPU_H */
diff --git a/include_lib/system/os/os_error.h b/include_lib/system/os/os_error.h
new file mode 100644
index 0000000..f8e06b0
--- /dev/null
+++ b/include_lib/system/os/os_error.h
@@ -0,0 +1,79 @@
+#ifndef __OS_ERROR_H__
+#define __OS_ERROR_H__
+
+#define OS_ERR_NONE 0
+
+
+enum {
+ OS_NO_ERR = 0,
+ OS_TRUE,
+ OS_ERR_EVENT_TYPE,
+ OS_ERR_PEND_ISR,
+ OS_ERR_POST_NULL_PTR,
+ OS_ERR_PEVENT_NULL,
+ OS_ERR_POST_ISR,
+ OS_ERR_QUERY_ISR,
+ OS_ERR_INVALID_OPT,
+ OS_ERR_TASK_WAITING,
+ OS_ERR_PDATA_NULL,
+ OS_TIMEOUT,
+ OS_TIMER,
+ OS_TASKQ,
+ OS_TASK_NOT_EXIST,
+ OS_ERR_EVENT_NAME_TOO_LONG,
+ OS_ERR_FLAG_NAME_TOO_LONG,
+ OS_ERR_TASK_NAME_TOO_LONG,
+ OS_ERR_PNAME_NULL,
+ OS_ERR_TASK_CREATE_ISR,
+ OS_MBOX_FULL,
+ OS_Q_FULL,
+ OS_Q_EMPTY,
+ OS_Q_ERR,
+ OS_ERR_NO_QBUF,
+ OS_PRIO_EXIST,
+ OS_PRIO_ERR,
+ OS_PRIO_INVALID,
+ OS_SEM_OVF,
+ OS_TASK_DEL_ERR,
+ OS_TASK_DEL_IDLE,
+ OS_TASK_DEL_ISR,
+ OS_NO_MORE_TCB,
+ OS_TIME_NOT_DLY,
+ OS_TIME_INVALID_MINUTES,
+ OS_TIME_INVALID_SECONDS,
+ OS_TIME_INVALID_MILLI,
+ OS_TIME_ZERO_DLY,
+ OS_TASK_SUSPEND_PRIO,
+ OS_TASK_SUSPEND_IDLE,
+ OS_TASK_RESUME_PRIO,
+ OS_TASK_NOT_SUSPENDED,
+ OS_MEM_INVALID_PART,
+ OS_MEM_INVALID_BLKS,
+ OS_MEM_INVALID_SIZE,
+ OS_MEM_NO_FREE_BLKS,
+ OS_MEM_FULL,
+ OS_MEM_INVALID_PBLK,
+ OS_MEM_INVALID_PMEM,
+ OS_MEM_INVALID_PDATA,
+ OS_MEM_INVALID_ADDR,
+ OS_MEM_NAME_TOO_LONG,
+ OS_ERR_MEM_NO_MEM,
+ OS_ERR_NOT_MUTEX_OWNER,
+ OS_TASK_OPT_ERR,
+ OS_ERR_DEL_ISR,
+ OS_ERR_CREATE_ISR,
+ OS_FLAG_INVALID_PGRP,
+ OS_FLAG_ERR_WAIT_TYPE,
+ OS_FLAG_ERR_NOT_RDY,
+ OS_FLAG_INVALID_OPT,
+ OS_FLAG_GRP_DEPLETED,
+ OS_ERR_PIP_LOWER,
+ OS_ERR_MSG_POOL_EMPTY,
+ OS_ERR_MSG_POOL_NULL_PTR,
+ OS_ERR_MSG_POOL_FULL,
+
+};
+
+
+#endif
+
diff --git a/include_lib/system/os/os_type.h b/include_lib/system/os/os_type.h
new file mode 100644
index 0000000..4c69f71
--- /dev/null
+++ b/include_lib/system/os/os_type.h
@@ -0,0 +1,35 @@
+#ifndef __OS_TYPE_H
+#define __OS_TYPE_H
+
+
+#define OS_TICKS_PER_SEC 100
+
+#if defined CONFIG_UCOS_ENABLE
+
+typedef struct {
+ unsigned char OSEventType;
+ int aa;
+ void *bb;
+ unsigned char value;
+ unsigned char prio;
+ unsigned short cc;
+} OS_SEM, OS_MUTEX, OS_QUEUE;
+
+#include
+
+#elif defined CONFIG_FREE_RTOS_ENABLE
+
+#include "FreeRTOS/FreeRTOS.h"
+#include "FreeRTOS/semphr.h"
+#include "FreeRTOS/task.h"
+
+typedef StaticSemaphore_t OS_SEM, OS_MUTEX;
+typedef StaticQueue_t OS_QUEUE;
+
+
+#else
+#error "no_os_defined"
+#endif
+
+
+#endif
diff --git a/include_lib/system/os/ucos_ii.h b/include_lib/system/os/ucos_ii.h
new file mode 100644
index 0000000..6480b9e
--- /dev/null
+++ b/include_lib/system/os/ucos_ii.h
@@ -0,0 +1,806 @@
+/***********************************Jieli tech************************************************
+ File : ucos_ii.h
+ By : Juntham
+ date : 2014-07-03 09:09
+********************************************************************************************/
+
+#ifndef OS_uCOS_II_H
+#define OS_uCOS_II_H
+
+
+#include "generic/typedef.h"
+#include "os/os_cpu.h"
+#include "os/os_cfg.h"
+#include "os/os_api.h"
+
+/*
+ *********************************************************************************************************
+ * INCLUDE HEADER FILES
+ *********************************************************************************************************
+ */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+// #define uCOS_ENTER_CRITICAL() CPU_CRITICAL_ENTER()
+// #define uCOS_EXIT_CRITICAL() CPU_CRITICAL_EXIT()
+
+void uCOS_ENTER_CRITICAL(void);
+void uCOS_EXIT_CRITICAL(void);
+
+
+#define OS_VERSION 100u /* Version */
+
+#define OS_STAT_RDY 0x00u /* Ready to run */
+#define OS_STAT_SEM 0x01u /* Pending on semaphore */
+#define OS_STAT_Q 0x02u /* Pending on queue */
+#define OS_STAT_SUSPEND 0x04u /* Task is suspended */
+#define OS_STAT_MUTEX 0x08u /* Pending on mutual exclusion semaphore */
+#define OS_STAT_TASK_Q 0x10u /* Pending on task Q */
+#define OS_STAT_DELAY 0x20u /* Task on delay */
+#define OS_STAT_FLAG 0x40u /* Pending on event flag group */
+
+#define OS_STAT_PEND_ANY (OS_STAT_SEM | OS_STAT_Q | OS_STAT_MUTEX | OS_STAT_TASK_Q)
+
+/*
+ *********************************************************************************************************
+ * OS_EVENT types
+ *********************************************************************************************************
+*/
+#define OS_EVENT_TYPE_UNUSED 0u
+#define OS_EVENT_TYPE_Q 1u
+#define OS_EVENT_TYPE_SEM 2u
+#define OS_EVENT_TYPE_MUTEX 3u
+#define OS_EVENT_TYPE_FLAG 5u
+
+/*
+*********************************************************************************************************
+* OS???PostOpt() OPTIONS
+*
+* These #defines are used to establish the options for OSMboxPostOpt() and OSQPostOpt().
+*********************************************************************************************************
+*/
+#define OS_POST_OPT_NONE 0x00u /* NO option selected */
+#define OS_POST_OPT_BROADCAST 0x01u /* Broadcast message to ALL tasks waiting */
+#define OS_POST_OPT_FRONT 0x02u /* Post to highest priority task waiting */
+
+/*
+ *********************************************************************************************************
+ * MISCELLANEOUS
+ *********************************************************************************************************
+ */
+
+#ifdef OS_GLOBALS
+#define OS_EXT
+#else
+#define OS_EXT extern
+#endif
+/*
+*********************************************************************************************************
+* EVENT CONTROL BLOCK
+*********************************************************************************************************
+*/
+#if OS_EVENT_EN
+struct event_cnt {
+ u16 cnt;
+};
+struct event_mutex {
+ u8 value;
+ u8 prio;
+ u16 OwnerNestingCtr;
+};
+
+struct os_tcb;
+
+typedef struct os_event {
+ u8 OSEventType; /* Type of event control block (see OS_EVENT_TYPE_xxxx) */
+#if OS_TIME_SLICE_EN > 0
+ struct os_tcb *OSTCBList; /* TCB List */
+#else
+ OS_CPU_DATA OSTCBList;
+#endif
+ void *OSEventPtr; /* Pointer to message or queue structure */
+ union {
+ struct event_cnt OSEvent;
+ struct event_mutex OSMutex;
+ };
+} OS_EVENT;
+
+
+
+/*
+*********************************************************************************************************
+* EVENT FLAGS CONTROL BLOCK
+*********************************************************************************************************
+*/
+
+
+#if (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0)
+/*
+*********************************************************************************************************
+* EVENT FLAGS
+*********************************************************************************************************
+*/
+#define OS_FLAG_WAIT_CLR_ALL 0u /* Wait for ALL the bits specified to be CLR (i.e. 0) */
+#define OS_FLAG_WAIT_CLR_AND 0u
+
+#define OS_FLAG_WAIT_CLR_ANY 1u /* Wait for ANY of the bits specified to be CLR (i.e. 0) */
+#define OS_FLAG_WAIT_CLR_OR 1u
+
+#define OS_FLAG_WAIT_SET_ALL 2u /* Wait for ALL the bits specified to be SET (i.e. 1) */
+#define OS_FLAG_WAIT_SET_AND 2u
+
+#define OS_FLAG_WAIT_SET_ANY 3u /* Wait for ANY of the bits specified to be SET (i.e. 1) */
+#define OS_FLAG_WAIT_SET_OR 3u
+
+
+#define OS_FLAG_CONSUME 0x80u /* Consume the flags if condition(s) satisfied */
+
+
+#define OS_FLAG_CLR 0u
+#define OS_FLAG_SET 1u
+
+#if OS_FLAGS_NBITS == 8 /* Determine the size of OS_FLAGS (8, 16 or 32 bits) */
+typedef INT8U OS_FLAGS;
+#endif
+
+#if OS_FLAGS_NBITS == 16
+typedef INT16U OS_FLAGS;
+#endif
+
+#if OS_FLAGS_NBITS == 32
+typedef u32 OS_FLAGS;
+#endif
+
+
+
+typedef struct os_flag_grp { /* Event Flag Group */
+ u8 OSFlagType; /* Should be set to OS_EVENT_TYPE_FLAG */
+ void *OSFlagWaitList; /* Pointer to first NODE of task waiting on event flag */
+ OS_FLAGS OSFlagFlags; /* 8, 16 or 32 bit flags */
+#if OS_FLAG_NAME_SIZE > 1
+ u8 OSFlagName[OS_FLAG_NAME_SIZE];
+#endif
+} OS_FLAG_GRP;
+
+
+
+typedef struct os_flag_node { /* Event Flag Wait List Node */
+ void *OSFlagNodeNext; /* Pointer to next NODE in wait list */
+ void *OSFlagNodePrev; /* Pointer to previous NODE in wait list */
+ void *OSFlagNodeTCB; /* Pointer to TCB of waiting task */
+ void *OSFlagNodeFlagGrp; /* Pointer to Event Flag Group */
+ OS_FLAGS OSFlagNodeFlags; /* Event flag to wait on */
+ u8 OSFlagNodeWaitType; /* Type of wait: */
+ /* OS_FLAG_WAIT_AND */
+ /* OS_FLAG_WAIT_ALL */
+ /* OS_FLAG_WAIT_OR */
+ /* OS_FLAG_WAIT_ANY */
+} OS_FLAG_NODE;
+
+OS_EXT OS_FLAG_GRP OSFlagTbl[OS_MAX_FLAGS]; /* Table containing event flag groups */
+OS_EXT OS_FLAG_GRP *OSFlagFreeList; /* Pointer to free list of event flag groups */
+
+OS_FLAG_GRP *OSFlagCreate(OS_FLAGS flags, u8 *err);
+OS_FLAG_GRP *OSFlagDel(OS_FLAG_GRP *pgrp, u8 opt, u8 *err);
+OS_FLAGS OSFlagPend(OS_FLAG_GRP *pgrp, OS_FLAGS flags, u8 wait_type, u16 timeout, u8 *err);
+OS_FLAGS OSFlagPost(OS_FLAG_GRP *pgrp, OS_FLAGS flags, u8 opt, u8 *err);
+#endif
+
+/*$PAGE*/
+
+/*
+ *********************************************************************************************************
+ * MESSAGE QUEUE DATA
+ *********************************************************************************************************
+ */
+
+#if (OS_Q_EN > 0) || (OS_TASKQ_EN > 0)
+typedef struct os_q { /* QUEUE CONTROL BLOCK */
+ QS OSQIn;
+ QS OSQOut;
+ QS OSQSize; /* Size of queue (maximum number of entries) */
+ QS OSQEntries; /* Current number of entries in the queue */
+ void **OSQStart; /* Pointer to start of queue data */
+} OS_Q;
+#endif
+
+/*$PAGE*/
+
+/*
+ *********************************************************************************************************
+ * TASK CONTROL BLOCK
+ *********************************************************************************************************
+*/
+typedef struct os_tcb {
+ OS_STK *OSTCBStkPtr; /* Pointer to current top of stack */
+
+#if OS_CPU_MMU > 0
+ u8 *frame;
+#endif
+
+#if OS_TIME_SLICE_EN > 0
+ u8 slice_quanta; /* 时间片初始值 */
+ u8 slice_cnt; /* 时间片模式下的计数值 */
+ u16 OSTCBDly; /* Nbr ticks to delay task or, timeout waiting for event */
+#endif
+
+#if OS_TASKQ_EN > 0
+ OS_Q task_q;
+#endif
+
+#if OS_PARENT_TCB > 0
+ struct os_tcb *OSTCBParent;
+#endif
+
+#if OS_CHILD_TCB > 0
+ struct os_tcb *OSTCBChildNext;
+#endif
+
+#if OS_TIME_SLICE_EN > 0
+ struct os_tcb *OSTCBEventNext; /* Pointer to next TCB in the event waiting TCB list */
+ struct os_tcb *OSTCBEventPrev; /* Pointer to previous TCB in the event waiting TCB list */
+ struct os_tcb *OSTCBSliceNext; /* Pointer to next TCB in the time slice TCB list */
+ struct os_tcb *OSTCBSlicePrev; /* Pointer to previous TCB in the time slice TCB list */
+#endif
+
+#if OS_EVENT_EN
+ OS_EVENT *OSTCBEventPtr; /* Pointer to event control block */
+#endif
+
+#if (OS_Q_EN > 0) || (OS_TASKQ_EN > 0)
+ void *OSTCBMsg; /* Message received from OSMboxPost() or OSQPost() */
+#endif
+
+#if OS_FLAG_EN > 0
+ OS_FLAG_NODE *OSTCBFlagNode; /* Pointer to event flag node */
+ OS_FLAGS OSTCBFlagsRdy;
+#endif
+
+#if OS_TIME_SLICE_EN == 0
+ u16 OSTCBDly; /* Nbr ticks to delay task or, timeout waiting for event */
+#endif
+ u8 OSTCBPrio; /* Task priority (0 == highest) */
+ u8 OSTCBStat; /* Task status */
+ u8 OSTCBPendTO; /* Flag indicating PEND timed out (TRUE == timed out) */
+
+
+#if OS_TASK_DEL_EN > 0
+ u8 OSTCBDelReq; /* Indicates whether a task needs to delete itself */
+#endif
+
+ u8 OSCoreAffinity; /* core */
+
+ u8 fork_thread;
+ OS_STK *OSTCBStkTos;
+ int *pid;
+ OS_STK stk_size;
+ OS_STK *p_stk_base;
+ char *name;
+ u32 timeout;
+ u32 RunTimeCounterStart;
+ u32 RunTimeCounterTotal;
+} OS_TCB;
+
+
+typedef struct os_tcb_list {
+ OS_TCB *ptcb;
+#if OS_TIME_SLICE_EN > 0
+ OS_TCB *idle_ptcb;
+#endif
+} OS_TCB_LIST;
+
+/*
+ *********************************************************************************************************
+ * MUTUAL EXCLUSION SEMAPHORE MANAGEMENT
+ *********************************************************************************************************
+ */
+
+#if OS_MUTEX_EN > 0
+
+#if OS_MUTEX_ACCEPT_EN > 0
+u8 OSMutexAccept(OS_EVENT *pevent);
+#endif
+
+u8 OSMutexCreate(OS_EVENT *pevent);
+
+#if OS_MUTEX_DEL_EN > 0
+u8 OSMutexDel(OS_EVENT *pevent, u8 opt);
+#endif
+
+u8 OSMutexPend(OS_EVENT *pevent, u16 timeout);
+u8 OSMutexPost(OS_EVENT *pevent);
+
+#if OS_MUTEX_QUERY_EN > 0
+u8 OSMutexQuery(OS_EVENT *pevent, OS_MUTEX_DATA *p_mutex_data);
+#endif
+
+#endif
+/*
+ *********************************************************************************************************
+ * MESSAGE QUEUE MANAGEMENT
+ *********************************************************************************************************
+ */
+
+#if (OS_Q_EN > 0)
+
+#if OS_Q_ACCEPT_EN > 0
+u8 OSQAccept(OS_EVENT *pevent, void *msg);
+#endif
+
+u8 OSQCreate(OS_EVENT *pevent, /*void **start, */QS size);
+
+#if OS_Q_DEL_EN > 0
+u8 OSQDel(OS_EVENT *pevent, u8 opt);
+#endif
+
+#if OS_Q_FLUSH_EN > 0
+u8 OSQFlush(OS_EVENT *pevent);
+#endif
+
+u8 OSQPend(OS_EVENT *pevent, u16 timeout, void *msg);
+
+#if OS_Q_POST_EN > 0
+u8 OSQPost(OS_EVENT *pevent, void *msg);
+#endif
+
+#if OS_Q_POST_FRONT_EN > 0
+u8 OSQPostFront(OS_EVENT *pevent, void *msg);
+#endif
+
+#if OS_Q_POST_OPT_EN > 0
+u8 OSQPostOpt(OS_EVENT *pevent, void *msg, u8 opt);
+#endif
+
+#if OS_Q_QUERY_EN > 0
+u16 OSQQuery(OS_EVENT *pevent);
+#endif
+
+#endif
+
+/*$PAGE*/
+/*
+*********************************************************************************************************
+* SEMAPHORE MANAGEMENT
+*********************************************************************************************************
+*/
+#if OS_SEM_EN > 0
+
+#if OS_SEM_ACCEPT_EN > 0
+u16 OSSemAccept(OS_EVENT *pevent);
+#endif
+
+u8 OSSemCreate(OS_EVENT *pevent, u16 cnt);
+
+#if OS_SEM_DEL_EN > 0
+u8 OSSemDel(OS_EVENT *pevent, u8 opt);
+#endif
+
+u8 OSSemPend(OS_EVENT *pevent, u16 timeout);
+u8 OSSemPost(OS_EVENT *pevent);
+
+#if OS_SEM_QUERY_EN > 0
+u16 OSSemQuery(OS_EVENT *pevent);
+#endif
+
+#if OS_SEM_SET_EN > 0
+u8 OSSemSet(OS_EVENT *pevent, u16 cnt);
+#endif
+
+#endif
+
+/*$PAGE*/
+/*
+ *********************************************************************************************************
+ * TASK MANAGEMENT
+ *********************************************************************************************************
+ */
+#if OS_TASK_CHANGE_PRIO_EN > 0
+u8 OSTaskChangePrio(char *name, u8 newprio);
+#endif
+
+#if OS_TASK_CREATE_EN > 0
+u8 OSTaskCreate(void (*task)(void *p_arg), OS_TCB *task_tcb, void *p_arg
+#if OS_CPU_MMU == 0
+ , OS_STK *ptos
+#endif
+ , u8 prio
+#if OS_TASKQ_EN > 0
+ , void **start, QS qsize
+#endif
+#if OS_TIME_SLICE_EN > 0
+ , u8 time_quanta
+#endif
+ , s8 *name
+ );
+#endif
+
+u8 OSTaskQAccept(int argc, int *argv);
+
+u8 OSTaskQPend(u16 timeout, int argc, int *argv);
+
+u8 OSTaskQPost(const char *name, int argc, ...);
+
+u8 OSTaskQFlush(const char *name);
+
+u8 OSTaskQPostFront(const char *name, int argc, ...);
+
+u8 OSTaskQQuery(const char *name, u8 *task_q_entries);
+
+#if OS_TASK_DEL_EN > 0
+u8 OSTaskDel(const char *name);
+u8 OSTaskDelReq(const char *name);
+void OSTaskDelRes(const char *name);
+#endif
+
+
+#if OS_TASK_SUSPEND_EN > 0
+u8 OSTaskResume(const char *name);
+u8 OSTaskSuspend(const char *name);
+#endif
+
+#if OS_TASK_QUERY_EN > 0
+u8 OSTaskQuery(const char *name, OS_TCB *p_task_data);
+#endif
+
+
+/*$PAGE*/
+/*
+ *********************************************************************************************************
+ * TIME MANAGEMENT
+ *********************************************************************************************************
+ */
+
+void OSTimeDly(u16 ticks);
+
+
+#if OS_TIME_GET_SET_EN > 0
+u32 OSTimeGet(void);
+void OSTimeSet(u32 ticks);
+
+#endif
+
+void OSTimeTick(void);
+
+/*
+ *********************************************************************************************************
+ * MISCELLANEOUS
+ *********************************************************************************************************
+ */
+
+void OSInit(void);
+
+void OSStart();
+
+u16 OSVersion(void);
+#endif
+/*
+ *********************************************************************************************************
+ * GLOBAL VARIABLES
+ *********************************************************************************************************
+*/
+
+OS_EXT volatile u8 OSRunning; /* Flag indicating that kernel is running */
+OS_EXT volatile OS_CPU_DATA OSRdyTbl;
+OS_EXT volatile u32 OSIdleCtr; /* Idle counter */
+OS_EXT OS_TCB *OSTCBCur[OS_CPU_CORE]; /* Pointer to currently running TCB */
+OS_EXT OS_TCB *OSTCBHighRdy[OS_CPU_CORE]; /* Pointer to highest priority TCB R-to-R */
+OS_EXT OS_TCB_LIST OSTCBPrioTbl[OS_MAX_TASKS + 1]; /* Table of pointers to created TCBs */
+
+
+#if (OS_INT_NESTING == 1)
+OS_EXT u8 OSIntNesting;
+#elif (OS_INT_NESTING == 2)
+extern int is_cpu_int_nesting();
+#define OSIntNesting is_cpu_int_nesting()
+#endif
+
+#if OS_TIME_GET_SET_EN > 0
+OS_EXT volatile u32 OSTime; /* Current value of system time (in ticks) */
+#endif
+
+
+/*
+ *********************************************************************************************************
+ * MISCELLANEOUS
+ *********************************************************************************************************
+ */
+
+/* void OSInit(void); */
+
+void OSIntEnter(void);
+void OSIntExit(void);
+
+#if OS_SCHED_LOCK_EN > 0
+void OSSchedLock(void);
+void OSSchedUnlock(void);
+#endif
+
+u32 OS_HighPrio(OS_CPU_DATA table);
+
+void OS_SchedRoundRobin(OS_TCB *ptcb);
+
+void OS_InsertRdyListHead(OS_TCB *ptcb);
+
+void OS_InsertRdyListTail(OS_TCB *ptcb);
+
+void OS_InsertIdleList(OS_TCB *ptcb);
+
+void OS_RemoveRdyList(OS_TCB *ptcb);
+
+void OS_RemoveIdleList(OS_TCB *ptcb);
+
+void OS_InsertListHead(OS_TCB *ptcb);
+
+void OS_RemoveList(OS_TCB *ptcb);
+
+/* void OSStart(); */
+
+void OSStatInit(void);
+
+/* u16 OSVersion(void); */
+
+/*$PAGE*/
+
+/*
+ *********************************************************************************************************
+ * INTERNAL FUNCTION PROTOTYPES
+ * (Your application MUST NOT call these functions)
+ *********************************************************************************************************
+ */
+
+#if OS_TASK_DEL_EN > 0
+void OS_Dummy(void);
+#endif
+
+#if OS_EVENT_EN
+void OS_ExchangePrio(OS_TCB *ptcba, OS_TCB *ptcbb);
+
+#if OS_TIME_SLICE_EN > 0
+OS_TCB *OS_EventHighestTask(OS_TCB *ptcb, u8 prio);
+void OS_EventTaskRdy(OS_EVENT *pevent, OS_TCB *ptcb, void *msg, u8 msk);
+#else
+OS_TCB *OS_EventTaskRdy(OS_EVENT *pevent, void *msg, u8 msk);
+#endif
+
+void OS_EventTaskWait(OS_EVENT *pevent, OS_TCB *OSTCB);
+void OS_EventTO(OS_EVENT *pevent, OS_TCB *OSTCB);
+void OS_EventWaitListInit(OS_EVENT *pevent);
+#endif
+
+void OS_MemClr(u8 *pdest, u16 size);
+void OS_MemCopy(u8 *pdest, u8 *psrc, u16 size);
+
+#if OS_Q_EN > 0
+void OS_QInit(void);
+#endif
+
+int OS_Sched(void);
+
+void OS_TaskIdle(void *p_arg);
+
+void OSIdleOtherCore(void);
+
+void OSResumOtherCore(void);
+
+void OS_CoreAffinitySet(const char *name, u8 Core);
+
+/*$PAGE*/
+
+/*
+ *********************************************************************************************************
+ * FUNCTION PROTOTYPES
+ * (Target Specific Functions)
+ *********************************************************************************************************
+ */
+
+#if OS_VERSION >= 204
+void OSInitHookBegin(void);
+void OSInitHookEnd(void);
+#endif
+
+#ifndef OS_ISR_PROTO_EXT
+void OSIntCtxSw(void);
+void OSStartHighRdy(void);
+#endif
+
+void OSTaskCreateHook(OS_TCB *ptcb);
+void OSTaskDelHook(OS_TCB *ptcb);
+
+#if OS_VERSION >= 251
+void OSTaskIdleHook(void);
+#endif
+
+void OSTaskStatHook(void);
+OS_STK *OSTaskStkInit(void(*p_task)(void *pd), void *p_arg, OS_STK *p_stk_base, u16 opt);
+
+#if OS_TASK_SW_HOOK_EN > 0
+void OSTaskSwHook(void);
+#endif
+
+#if OS_VERSION >= 204
+void OSTCBInitHook(OS_TCB *ptcb);
+#endif
+
+#if OS_TIME_TICK_HOOK_EN > 0
+void OSTimeTickHook(void);
+#endif
+extern void OS_TASK_DEL_HOOK(OS_TCB *ptcb) ;
+/*$PAGE*/
+/*
+ *********************************************************************************************************
+ * LOOK FOR MISSING #define CONSTANTS
+ *
+ * This section is used to generate ERROR messages at compile time if certain #define constants are
+ * MISSING in OS_CFG.H. This allows you to quickly determine the source of the error.
+ *
+ * You SHOULD NOT change this section UNLESS you would like to add more comments as to the source of the
+ * compile time error.
+ *********************************************************************************************************
+ */
+
+
+/*
+ *********************************************************************************************************
+ * MUTUAL EXCLUSION SEMAPHORES
+ *********************************************************************************************************
+ */
+
+#ifndef OS_MUTEX_EN
+#error "OS_CFG.H, Missing OS_MUTEX_EN: Enable (1) or Disable (0) code generation for MUTEX"
+#else
+#ifndef OS_MUTEX_ACCEPT_EN
+#error "OS_CFG.H, Missing OS_MUTEX_ACCEPT_EN: Include code for OSMutexAccept()"
+#endif
+
+#ifndef OS_MUTEX_DEL_EN
+#error "OS_CFG.H, Missing OS_MUTEX_DEL_EN: Include code for OSMutexDel()"
+#endif
+
+#ifndef OS_MUTEX_QUERY_EN
+#error "OS_CFG.H, Missing OS_MUTEX_QUERY_EN: Include code for OSMutexQuery()"
+#endif
+#endif
+
+/*
+ *********************************************************************************************************
+ * SEMAPHORES
+ *********************************************************************************************************
+ */
+
+#ifndef OS_SEM_EN
+#error "OS_CFG.H, Missing OS_SEM_EN: Enable (1) or Disable (0) code generation for SEMAPHORES"
+#else
+#ifndef OS_SEM_ACCEPT_EN
+#error "OS_CFG.H, Missing OS_SEM_ACCEPT_EN: Include code for OSSemAccept()"
+#endif
+
+#ifndef OS_SEM_DEL_EN
+#error "OS_CFG.H, Missing OS_SEM_DEL_EN: Include code for OSSemDel()"
+#endif
+
+#ifndef OS_SEM_QUERY_EN
+#error "OS_CFG.H, Missing OS_SEM_QUERY_EN: Include code for OSSemQuery()"
+#endif
+
+#ifndef OS_SEM_SET_EN
+#error "OS_CFG.H, Missing OS_SEM_SET_EN: Include code for OSSemSet()"
+#endif
+#endif
+
+/*
+ *********************************************************************************************************
+ * TASK MANAGEMENT
+ *********************************************************************************************************
+ */
+
+#ifndef OS_MAX_TASKS
+#error "OS_CFG.H, Missing OS_MAX_TASKS: Max. number of tasks in your application"
+#else
+#if OS_MAX_TASKS < 2
+#error "OS_CFG.H, OS_MAX_TASKS must be >= 2"
+#endif
+
+/* #if OS_MAX_TASKS > (OS_LOWEST_PRIO - OS_N_SYS_TASKS + 1) */
+/* #error "OS_CFG.H, OS_MAX_TASKS must be <= OS_LOWEST_PRIO - OS_N_SYS_TASKS + 1" */
+/* #endif */
+
+#endif
+
+#if OS_VERSION < 280
+#if OS_LOWEST_PRIO > 63
+#error "OS_CFG.H, OS_LOWEST_PRIO must be <= 63 in V2.7x or lower"
+#endif
+#endif
+
+#if OS_VERSION >= 280
+#if OS_LOWEST_PRIO > 254
+#error "OS_CFG.H, OS_LOWEST_PRIO must be <= 254 in V2.8x and higher"
+#endif
+#endif
+
+#ifndef OS_TASK_CHANGE_PRIO_EN
+#error "OS_CFG.H, Missing OS_TASK_CHANGE_PRIO_EN: Include code for OSTaskChangePrio()"
+#endif
+
+#ifndef OS_TASK_CREATE_EN
+#error "OS_CFG.H, Missing OS_TASK_CREATE_EN: Include code for OSTaskCreate()"
+#endif
+
+#ifndef OS_TASK_DEL_EN
+#error "OS_CFG.H, Missing OS_TASK_DEL_EN: Include code for OSTaskDel()"
+#endif
+
+#ifndef OS_TASK_SUSPEND_EN
+#error "OS_CFG.H, Missing OS_TASK_SUSPEND_EN: Include code for OSTaskSuspend() and OSTaskResume()"
+#endif
+
+#ifndef OS_TASK_QUERY_EN
+#error "OS_CFG.H, Missing OS_TASK_QUERY_EN: Include code for OSTaskQuery()"
+#endif
+
+/*
+ *********************************************************************************************************
+ * TIME MANAGEMENT
+ *********************************************************************************************************
+ */
+
+#ifndef OS_TICKS_PER_SEC
+#error "OS_CFG.H, Missing OS_TICKS_PER_SEC: Sets the number of ticks in one second"
+#endif
+
+#ifndef OS_TIME_DLY_HMSM_EN
+#error "OS_CFG.H, Missing OS_TIME_DLY_HMSM_EN: Include code for OSTimeDlyHMSM()"
+#endif
+
+#ifndef OS_TIME_DLY_RESUME_EN
+#error "OS_CFG.H, Missing OS_TIME_DLY_RESUME_EN: Include code for OSTimeDlyResume()"
+#endif
+
+#ifndef OS_TIME_GET_SET_EN
+#error "OS_CFG.H, Missing OS_TIME_GET_SET_EN: Include code for OSTimeGet() and OSTimeSet()"
+#endif
+
+/*
+ *********************************************************************************************************
+ * MISCELLANEOUS
+ *********************************************************************************************************
+ */
+
+#ifndef OS_ARG_CHK_EN
+#error "OS_CFG.H, Missing OS_ARG_CHK_EN: Enable (1) or Disable (0) argument checking"
+#endif
+
+
+#ifndef OS_CPU_HOOKS_EN
+#error "OS_CFG.H, Missing OS_CPU_HOOKS_EN: uC/OS-II hooks are found in the processor port files when 1"
+#endif
+
+
+#ifndef OS_LOWEST_PRIO
+#error "OS_CFG.H, Missing OS_LOWEST_PRIO: Defines the lowest priority that can be assigned"
+#endif
+
+
+#ifndef OS_SCHED_LOCK_EN
+#error "OS_CFG.H, Missing OS_SCHED_LOCK_EN: Include code for OSSchedLock() and OSSchedUnlock()"
+#endif
+
+
+
+#ifndef OS_TASK_SW_HOOK_EN
+#error "OS_CFG.H, Missing OS_TASK_SW_HOOK_EN: Allows you to include the code for OSTaskSwHook() or not"
+#endif
+
+
+#ifndef OS_TIME_TICK_HOOK_EN
+#error "OS_CFG.H, Missing OS_TIME_TICK_HOOK_EN: Allows you to include the code for OSTimeTickHook() or not"
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/include_lib/system/port/br28/system_lib.ld b/include_lib/system/port/br28/system_lib.ld
new file mode 100644
index 0000000..82aaa35
--- /dev/null
+++ b/include_lib/system/port/br28/system_lib.ld
@@ -0,0 +1,294 @@
+SECTIONS
+{
+ .data : ALIGN(4)
+ {
+ . = ALIGN(4);
+ system_data_start = .;
+
+ _video_subdev_begin = .;
+ PROVIDE(video_subdev_begin = .);
+ KEEP(*(.video_subdev.0))
+ KEEP(*(.video_subdev.1))
+ KEEP(*(.video_subdev.2))
+ KEEP(*(.video_subdev.3))
+ KEEP(*(.video_subdev.4))
+ KEEP(*(.video_subdev.5))
+ _video_subdev_end = .;
+ PROVIDE(video_subdev_end = .);
+
+ _audio_subdev_begin = .;
+ PROVIDE(audio_subdev_begin = .);
+ KEEP(*(.audio_subdev.0))
+ KEEP(*(.audio_subdev.1))
+ KEEP(*(.audio_subdev.2))
+ KEEP(*(.audio_subdev.3))
+ _audio_subdev_end = .;
+ PROVIDE(audio_subdev_end = .);
+
+ _iic_device_begin = .;
+ PROVIDE(iic_device_begin = .);
+ KEEP(*(.iic))
+ _iic_device_end = .;
+ PROVIDE(iic_device_end = .);
+
+ _avin_spi_device_begin = .;
+ PROVIDE(avin_spi_device_begin = .);
+ KEEP(*(.sw_spi))
+ _avin_spi_device_end = .;
+ PROVIDE(avin_spi_device_end = .);
+
+ _video_dev_begin = .;
+ PROVIDE(video_dev_begin = .);
+ KEEP(*(.video_device))
+ _video_dev_end = .;
+ PROVIDE(video_dev_end = .);
+
+ _key_driver_ops_begin = .;
+ PROVIDE(key_driver_ops_begin = .);
+ KEEP(*(.key_driver_ops))
+ _key_driver_ops_end = .;
+ PROVIDE(key_driver_ops_end = .);
+
+ _touch_driver_begin = .;
+ PROVIDE(touch_driver_begin = .);
+ KEEP(*(.touch_driver))
+ _touch_driver_end = .;
+ PROVIDE(touch_driver_end = .);
+
+ _static_hi_timer_begin = .;
+ PROVIDE(static_hi_timer_begin = .);
+ KEEP(*(.hi_timer))
+ _static_hi_timer_end = .;
+ PROVIDE(static_hi_timer_end = .);
+
+ _sys_cpu_timer_begin = .;
+ PROVIDE(sys_cpu_timer_begin = .);
+ KEEP(*(.sys_cpu_timer))
+ _sys_cpu_timer_end = .;
+ PROVIDE(sys_cpu_timer_end = .);
+
+ _sys_config_begin = .;
+ PROVIDE(sys_config_begin = .);
+ KEEP(*(.sys_cfg))
+ _sys_config_end = .;
+ PROVIDE(sys_config_end = .);
+
+ _sys_fat_begin = .;
+ PROVIDE(sys_fat_begin = .);
+ KEEP(*(.fs_fat))
+ _sys_fat_end = .;
+ PROVIDE(sys_fat_end = .);
+
+ _app_begin = .;
+ PROVIDE(app_begin = .);
+ KEEP(*(.app))
+ _app_end = .;
+ PROVIDE(app_end = .);
+
+ *(.crypto_ecdh_data)
+ *(.crypto_data)
+
+ *(.mem_data)
+ *(.os_port_data)
+
+ *(.os_str)
+ *(.os_data)
+
+ *(.uECC_data)
+ *(.ECDH_sample_data)
+
+ __movable_slot_start = .;
+ *(movable.slot.*);
+ __movable_slot_end = .;
+
+ system_data_end = .;
+
+ } > ram0
+
+ .bss (NOLOAD) :ALIGN(4)
+ {
+ system_bss_start = .;
+ . = ALIGN(4);
+ *(.os_bss)
+ *(.mem_heap)
+ *(.memp_memory_x)
+ *(.mem_bss)
+ *(.os_port_bss)
+
+ *(.uECC_bss)
+ *(.ECDH_sample_bss)
+
+ system_bss_end = .;
+
+ } > ram0
+
+ .text : ALIGN(4)
+ {
+ . = ALIGN(4);
+ system_text_start = .;
+
+ _device_node_begin = .;
+ PROVIDE(device_node_begin = .);
+ KEEP(*(.device))
+ _device_node_end = .;
+ PROVIDE(device_node_end = .);
+
+ config_target_begin = .;
+ PROVIDE(config_target_begin = .);
+ KEEP(*(.config_target))
+ config_target_end = .;
+ PROVIDE(config_target_end = .);
+
+ system_code_begin = .;
+ KEEP(*(.system.*.text))
+ system_code_end = .;
+ . = ALIGN(4);
+ system_code_size = system_code_end - system_code_begin;
+
+ vfs_ops_begin = .;
+ KEEP(*(.vfs_operations))
+ vfs_ops_end = .;
+
+ _lib_version_begin = .;
+ PROVIDE(lib_version_begin = .);
+ KEEP(*(.lib_version))
+ _lib_version_end = .;
+ PROVIDE(lib_version_end = .);
+
+ _initcall_begin = .;
+ PROVIDE(initcall_begin = .);
+ KEEP(*(.initcall))
+ _initcall_end = .;
+ PROVIDE(initcall_end = .);
+
+ _early_initcall_begin = .;
+ PROVIDE(early_initcall_begin = .);
+ KEEP(*(.early.initcall))
+ _early_initcall_end = .;
+ PROVIDE(early_initcall_end = .);
+
+ _late_initcall_begin = .;
+ PROVIDE(late_initcall_begin = .);
+ KEEP(*(.late.initcall))
+ _late_initcall_end = .;
+ PROVIDE(late_initcall_end = .);
+
+ _platform_initcall_begin = .;
+ PROVIDE(platform_initcall_begin = .);
+ KEEP(*(.platform.initcall))
+ _platform_initcall_end = .;
+ PROVIDE(platform_initcall_end = .);
+
+ _module_initcall_begin = .;
+ PROVIDE(module_initcall_begin = .);
+ KEEP(*(.module.initcall))
+ _module_initcall_end = .;
+ PROVIDE(module_initcall_end = .);
+
+ _sys_event_handler_begin = .;
+ PROVIDE(sys_event_handler_begin = .);
+ KEEP(*(.sys_event.4.handler))
+ KEEP(*(.sys_event.3.handler))
+ KEEP(*(.sys_event.2.handler))
+ KEEP(*(.sys_event.1.handler))
+ KEEP(*(.sys_event.0.handler))
+ _sys_event_handler_end = .;
+ PROVIDE(sys_event_handler_end = .);
+
+ _syscfg_arg_begin = .;
+ PROVIDE(syscfg_arg_begin = .);
+ KEEP(*(.syscfg.arg))
+ _syscfg_arg_end = .;
+ PROVIDE(syscfg_arg_end = .);
+
+ _syscfg_handler_begin = .;
+ PROVIDE(syscfg_handler_begin = .);
+ KEEP(*(.syscfg.handler))
+ _syscfg_handler_end = .;
+ PROVIDE(syscfg_handler_end = .);
+
+ _syscfg_ops_begin = .;
+ PROVIDE(syscfg_ops_begin = .);
+ KEEP(*(.syscfg.2.ops))
+ KEEP(*(.syscfg.1.ops))
+ KEEP(*(.syscfg.0.ops))
+ _syscfg_ops_end = .;
+ PROVIDE(syscfg_ops_end = .);
+
+ _server_info_begin = .;
+ PROVIDE(server_info_begin = .);
+ KEEP(*(.server_info))
+ _server_info_end = .;
+ PROVIDE(server_info_end = .);
+
+ _bus_device_begin = .;
+ PROVIDE(bus_device_begin = .);
+ KEEP(*(.bus_device))
+ _bus_device_end = .;
+ PROVIDE(bus_device_end = .);
+
+ _sys_power_hal_ops_begin = .;
+ PROVIDE(sys_power_hal_ops_begin = .);
+ KEEP(*(.sys_power_hal_ops))
+ _sys_power_hal_ops_end = .;
+ PROVIDE(sys_power_hal_ops_end = .);
+
+
+
+ crypto_begin = .;
+ *(.crypto_ecdh_code)
+ *(.crypto_ecdh_const)
+
+ *(.crypto_bigint_code)
+ *(.crypto_bigint_const)
+
+ *(.crypto_code)
+ *(.crypto_const)
+
+ *(.ECDH_sample_code)
+ *(.ECDH_sample_const)
+
+ *(.uECC_code)
+ *(.uECC_const)
+
+ *(.hmac_code)
+ *(.hmac_const)
+
+ *(.hash_sample_code)
+ *(.hash_sample_const)
+
+ *(.aes_cmac_sample_code)
+ *(.aes_cmac_sample_const)
+ crypto_end = .;
+ crypto_size = . - crypto_begin;
+
+ *(.mem_code)
+ *(.mem_const)
+
+ *(.os_port_code)
+ *(.os_port_const)
+
+ *(.os_const)
+
+ *(.math_fast_funtion_code)
+
+ __movable_function_start = .;
+ *(movable.text.*);
+ *(movable.stub.*);
+ *(movable.region.*);
+ /* *(.movable.code*) */
+ __movable_function_end = .;
+ __movable_function_size = __movable_function_end - __movable_function_start;
+
+ system_text_end = .;
+
+
+ system_code_total_size = system_text_end - system_text_start;
+ } > code0
+
+ .data_code ALIGN(32):
+ {
+ *(.os_code)
+ } > ram0
+}
+
diff --git a/include_lib/system/power_manage.h b/include_lib/system/power_manage.h
new file mode 100644
index 0000000..f937eec
--- /dev/null
+++ b/include_lib/system/power_manage.h
@@ -0,0 +1,103 @@
+#ifndef __POWER_MANAGE_H_
+#define __POWER_MANAGE_H_
+
+#include "generic/typedef.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum {
+ DEVICE_EVENT_POWER_SHUTDOWN = 0x10,
+ DEVICE_EVENT_POWER_STARTUP,
+ DEVICE_EVENT_POWER_PERCENT,
+ DEVICE_EVENT_POWER_CHARGER_IN,
+ DEVICE_EVENT_POWER_CHARGER_OUT
+};
+
+#define PWR_SCAN_TIMES 3
+
+#define PWR_DELAY_INFINITE 0xffffffff
+
+#define PWR_WKUP_PORT "wkup_port"
+#define PWR_WKUP_ALARM "wkup_alarm"
+#define PWR_WKUP_PWR_ON "wkup_pwr_on"
+#define PWR_WKUP_ABNORMAL "wkup_abnormal"
+#define PWR_WKUP_SHORT_KEY "wkup_short_key"
+
+struct sys_power_hal_ops {
+ void (*init)(void);
+ void (*poweroff)(void *arg);
+ int (*wakeup_check)(char *reason, int max_len);
+ int (*port_wakeup_config)(const char *port, int enable);
+ int (*alarm_wakeup_config)(u32 sec, int enable);
+ int (*get_battery_voltage)(void);
+ int (*get_battery_percent)(void);
+ int (*charger_online)(void);
+};
+
+extern const struct sys_power_hal_ops sys_power_hal_ops_begin[];
+extern const struct sys_power_hal_ops sys_power_hal_ops_end[];
+
+#define REGISTER_SYS_POWER_HAL_OPS(ops) \
+ static const struct sys_power_hal_ops ops sec(.sys_power_hal_ops)
+
+
+void sys_power_early_init();
+/*
+ * @brief 断电关机,不释放资源
+ */
+void sys_power_poweroff(void *arg);
+/*
+ * @brief 软关机,触发DEVICE_EVENT_POWER_SHUTDOWN事件,app捕获事件释放资源再调用sys_power_poweroff()
+ */
+void sys_power_shutdown();
+
+int sys_power_set_port_wakeup(const char *port, int enable);
+
+int sys_power_set_alarm_wakeup(u32 sec, int enable);
+
+const char *sys_power_get_wakeup_reason();
+
+void sys_power_clr_wakeup_reason(const char *str);
+
+int sys_power_get_battery_voltage();
+
+int sys_power_get_battery_persent();
+
+int sys_power_is_charging();
+
+int sys_power_charger_online(void);
+/*
+ * @brief 倒计时自动关机
+ * @parm dly_secs 延时关机时间,赋值0为永不关机
+ * @return none
+ */
+void sys_power_auto_shutdown_start(u32 dly_secs);
+void sys_power_auto_shutdown_pause();
+void sys_power_auto_shutdown_resume();
+void sys_power_auto_shutdown_clear();
+void sys_power_auto_shutdown_stop();
+
+
+int sys_power_low_voltage(u32 voltage);
+
+/*
+ * @brief 低电延时关机
+ * @parm p_low_percent 低电电量百分比
+ * @parm dly_secs 延时关机时间,赋值0为立即关机,赋值PWR_DELAY_INFINITE为永不关机
+ * @return none
+ */
+void sys_power_low_voltage_shutdown(u32 voltage, u32 dly_secs);
+/*
+ * @brief 插拔延时关机
+ * @parm dly_secs 延时关机时间,赋值0为立即关机,赋值PWR_DELAY_INFINITE为永不关机
+ * @return none
+ */
+void sys_power_charger_off_shutdown(u32 dly_secs);
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/include_lib/system/server/server_core.h b/include_lib/system/server/server_core.h
new file mode 100644
index 0000000..dada5f4
--- /dev/null
+++ b/include_lib/system/server/server_core.h
@@ -0,0 +1,85 @@
+#ifndef SERVER_H
+#define SERVER_H
+
+#include "generic/typedef.h"
+#include "system/task.h"
+#include "spinlock.h"
+#include "list.h"
+
+
+#define REQ_COMPLETE_CALLBACK 0x01000000
+#define REQ_WAIT_COMPLETE 0x02000000
+#define REQ_HI_PRIORITY 0x04000000
+
+
+#define REQ_TYPE_MASK 0x00ffffff
+
+
+struct server_req {
+ int type;
+ int err;
+ void *server_priv;
+ struct list_head entry;
+ struct server *server;
+ void *user;
+ const char *owner;
+ OS_SEM sem;
+ union {
+ int state;
+ void (*func)(void *, void *, int);
+ } complete;
+ u32 arg[0];
+};
+
+
+struct server_info {
+ const char *name;
+ u16 reqlen;
+ u8 reqnum;
+ void *(*open)(void *, void *);
+ void (*close)(void *);
+};
+
+#define REQ_BUF_LEN 512
+
+struct server {
+ bool avaliable;
+ void *server;
+ OS_SEM sem;
+ OS_MUTEX mutex;
+ spinlock_t lock;
+ struct list_head *req_buf;
+ struct list_head free;
+ struct list_head pending;
+ const struct server_info *info;
+ const char *owner;
+ void *handler_priv;
+ void (*event_handler)(void *, int argc, int *argv);
+};
+
+
+
+#define SERVER_REGISTER(info) \
+ const struct server_info info sec(.server_info)
+
+
+#define server_load(server) \
+ load_module(server)
+
+struct server *server_open(const char *name, void *arg);
+
+void server_register_event_handler(struct server *server, void *priv,
+ void (*handler)(void *, int argc, int *argv));
+
+void server_close(struct server *server);
+
+int server_request(struct server *server, int req_type, void *arg);
+
+int server_request_async(struct server *server, int req_type, void *arg, ...);
+
+int server_req_complete(struct server_req *req);
+
+int server_event_handler(void *_server, int argc, int *argv);
+
+#endif
+
diff --git a/include_lib/system/spi/nor_fs.h b/include_lib/system/spi/nor_fs.h
new file mode 100644
index 0000000..c245574
--- /dev/null
+++ b/include_lib/system/spi/nor_fs.h
@@ -0,0 +1,101 @@
+/***********************************Jieli tech************************************************
+ File : nor_fs.h
+ By : Huxi
+ Email: xi_hu@zh-jieli.com
+ date : 2016-11-30 14:30
+********************************************************************************************/
+#ifndef _NOR_FS_H_
+#define _NOR_FS_H_
+
+// #include "sdk_cfg.h"
+#include "typedef.h"
+// #include "system/includes.h"
+
+// #define SPI_REC_EN 1
+
+#define NORFS_DATA_LEN 16
+
+#define REC_FILE_END 0xFE
+
+
+//文件索引
+typedef struct __RECF_INDEX_INFO {
+ u16 index; //文件索引号
+ u16 sector; //文件所在扇区
+} RECF_INDEX_INFO ;
+
+#define FLASH_PAGE_SIZE 256
+//文件系统句柄
+typedef struct __RECFILESYSTEM {
+ RECF_INDEX_INFO index;
+ u8 buf[FLASH_PAGE_SIZE];
+ u16 total_file;
+ u16 first_sector;
+ u16 last_sector;
+ // u8 *buf;
+ u8 sector_size;
+ void (*eraser)(u32 address);
+ s32(*read)(u8 *buf, u32 addr, u32 len);
+ s32(*write)(u8 *buf, u32 addr, u32 len);
+} RECFILESYSTEM, *PRECFILESYSTEM ;
+
+
+
+//文件句柄
+typedef struct __REC_FILE {
+ RECF_INDEX_INFO index;
+ RECFILESYSTEM *pfs;
+ u32 addr;
+ char priv_data[NORFS_DATA_LEN];
+ u32 len;
+ u32 w_len;
+ u32 rw_p;
+ u16 sr;
+} REC_FILE;
+
+enum {
+ NOR_FS_SEEK_SET = 0,
+ NOR_FS_SEEK_CUR = 0x01
+};
+// enum {
+// NOR_FS_SEEK_SET = 0x01,
+// NOR_FS_SEEK_CUR = 0x02
+// };
+
+
+typedef struct __nor_fs_hdl {
+ u16 index;
+ RECFILESYSTEM *recfs;
+ REC_FILE *recfile;
+} NOR_FS_HDL;
+
+
+u8 recf_seek(REC_FILE *pfile, u8 type, int offsize);
+u16 recf_read(REC_FILE *pfile, u8 *buff, u16 btr);
+u16 recf_write(REC_FILE *pfile, u8 *buff, u16 btw);
+u32 create_recfile(RECFILESYSTEM *pfs, REC_FILE *pfile);
+u32 close_recfile(REC_FILE *pfile);
+u32 open_recfile(u32 index, RECFILESYSTEM *pfs, REC_FILE *pfile);
+void recf_save_sr(REC_FILE *pfile, u16 sr);
+
+int music_flash_file_set_index(u8 file_sel, u32 index);
+u32 recfs_scan(RECFILESYSTEM *pfs);
+void init_nor_fs(RECFILESYSTEM *pfs, u16 sector_start, u16 sector_end, u8 sector_size);
+
+u32 nor_fs_init(void);
+int nor_fs_set_rec_capacity(int capacity); //需要先设置容量。
+int nor_fs_ops_init(void);
+int recfs_scan_ex();
+u32 nor_get_capacity(void);
+u32 flashinsize_rec_get_capacity(void);
+int sdfile_rec_scan_ex();
+void rec_clear_norfs_fileindex(void);
+void clear_norfs_fileindex(void);
+u32 _sdfile_rec_init(void);
+int set_rec_capacity(int capacity); //需要先设置容量。
+int sdfile_rec_ops_init(void);
+u32 nor_get_index(void);
+u32 flashinsize_rec_get_index(void);
+int nor_set_offset_addr(int offset);
+
+#endif
diff --git a/include_lib/system/spinlock.h b/include_lib/system/spinlock.h
new file mode 100644
index 0000000..fa676f3
--- /dev/null
+++ b/include_lib/system/spinlock.h
@@ -0,0 +1,145 @@
+#ifndef SYS_SPINLOCK_H
+#define SYS_SPINLOCK_H
+
+#include "typedef.h"
+#include "cpu.h"
+#include "irq.h"
+
+
+struct __spinlock {
+ volatile u32 rwlock;
+};
+
+typedef struct __spinlock spinlock_t;
+
+#if CPU_CORE_NUM > 1
+
+#define preempt_disable() \
+ __local_irq_disable()
+
+#define preempt_enable() \
+ __local_irq_enable()
+
+#else
+
+#define preempt_disable() \
+ local_irq_disable()
+
+#define preempt_enable() \
+ local_irq_enable()
+
+
+
+
+#endif
+
+
+#if CPU_CORE_NUM > 1
+
+#define spin_acquire(lock) \
+ do { \
+ arch_spin_lock(lock); \
+ }while(0)
+
+#define spin_release(lock) \
+ do { \
+ arch_spin_unlock(lock); \
+ }while(0)
+
+#else
+
+#define spin_acquire(lock) \
+ do { \
+ }while(0)
+
+
+#define spin_release(lock) \
+ do { \
+ }while(0)
+
+#endif
+
+
+#define DEFINE_SPINLOCK(x) \
+ spinlock_t x = { .rwlock = 0 }
+
+
+static inline void spin_lock_init(spinlock_t *lock)
+{
+ lock->rwlock = 0;
+}
+extern u32 spin_lock_cnt[];
+
+#if 1
+static inline void spin_lock(spinlock_t *lock)
+{
+ preempt_disable();
+ /*ASSERT(spin_lock_cnt[current_cpu_id()] == 0);
+ spin_lock_cnt[current_cpu_id()] = 1;*/
+ spin_acquire(lock);
+}
+
+
+static inline void spin_unlock(spinlock_t *lock)
+{
+ /*spin_lock_cnt[current_cpu_id()] = 0;*/
+ spin_release(lock);
+ preempt_enable();
+}
+
+#else
+
+
+#define spin_lock(lock) \
+ do { \
+ preempt_disable(); \
+ if (!(T2_CON & (1<<0))) { \
+ T2_CNT = 0; \
+ T2_PRD = 120000000 / 10; \
+ T2_CON = 1; \
+ } \
+ spin_lock_cnt[current_cpu_id()] = T2_CNT; \
+ spin_acquire(lock); \
+ } while (0)
+
+
+#define spin_unlock(lock) \
+ do { \
+ u32 t = T2_CNT;\
+ if(t < spin_lock_cnt[current_cpu_id()]) \
+ t += T2_PRD - spin_lock_cnt[current_cpu_id()]; \
+ else \
+ t -= spin_lock_cnt[current_cpu_id()]; \
+ spin_release(lock); \
+ preempt_enable(); \
+ if (t > 100000) { /*120000 == 1ms*/ \
+ printf("???????spinlock: %d, %s\n", t, __func__); \
+ } \
+ } while(0)
+
+#endif
+
+/*#define spin_lock_irqsave(lock, flags) \
+ do { \
+ local_irq_save(flags); \
+ spin_acquire((lock)); \
+ }while(0)
+
+#define spin_unlock_irqrestore(lock, flags) \
+ do { \
+ spin_release((lock)); \
+ local_irq_restore(flags); \
+ }while(0) */
+
+
+
+
+
+
+
+
+
+
+
+#endif
+
diff --git a/include_lib/system/sys_time.h b/include_lib/system/sys_time.h
new file mode 100644
index 0000000..02db2b5
--- /dev/null
+++ b/include_lib/system/sys_time.h
@@ -0,0 +1,50 @@
+#ifndef SYS_TIME_H
+#define SYS_TIME_H
+
+#include "typedef.h"
+
+
+struct sys_time {
+ u16 year;
+ u8 month;
+ u8 day;
+ u8 hour;
+ u8 min;
+ u8 sec;
+};
+
+#if 0
+struct tm {
+ int tm_sec; /* Seconds. [0-60] (1 leap second) */
+ int tm_min; /* Minutes. [0-59] */
+ int tm_hour; /* Hours. [0-23] */
+ int tm_mday; /* Day. [1-31] */
+ int tm_mon; /* Month. [0-11] */
+ int tm_year; /* Year - 1900. */
+ int tm_wday; /* Day of week. [0-6] */
+ int tm_yday; /* Days in year.[0-365] */
+ int tm_isdst; /* DST. [-1/0/1]*/
+
+# ifdef __USE_MISC
+ long int tm_gmtoff; /* Seconds east of UTC. */
+ const char *tm_zone; /* Timezone abbreviation. */
+# else
+ long int __tm_gmtoff; /* Seconds east of UTC. */
+ const char *__tm_zone; /* Timezone abbreviation. */
+# endif
+};
+
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+#endif
diff --git a/include_lib/system/syscfg_id.h b/include_lib/system/syscfg_id.h
new file mode 100644
index 0000000..5fba4f4
--- /dev/null
+++ b/include_lib/system/syscfg_id.h
@@ -0,0 +1,333 @@
+
+#ifndef __JL_CFG_DEC_H__
+#define __JL_CFG_DEC_H__
+
+#include "typedef.h"
+
+struct btif_item {
+ u16 id;
+ u16 data_len;
+};
+
+
+struct syscfg_operataions {
+ int (*init)(void);
+ int (*check_id)(u16 item_id);
+ int (*read)(u16 item_id, u8 *buf, u16 len);
+ int (*write)(u16 item_id, u8 *buf, u16 len);
+ int (*dma_write)(u16 item_id, u8 *buf, u16 len);
+ int (*read_string)(u16 item_id, u8 *buf, u16 len, u8 ver);
+ u8 *(*ptr_read)(u16 item_id, u16 *len);
+};
+
+#define REGISTER_SYSCFG_OPS(cfg, pri) \
+ const struct syscfg_operataions cfg SEC_USED(.syscfg.pri.ops)
+
+//=================================================================================//
+// 系统配置项(VM, BTIF, cfg_bin)读写接口 //
+//接口说明: //
+// 1.输入参数 //
+// 1)item_id: 配置项ID号, 由本文件统一分配; //
+// 2)buf: 用于存储read/write数据内容; //
+// 3)len: buf的长度(byte), buf长度必须大于等于read/write数据长度; //
+// 2.返回参数: //
+// 1)执行正确: 返回值等于实际上所读到的数据长度(大于0); //
+// 2)执行错误: 返回值小于等于0, 小于0表示相关错误码; //
+// 3.读写接口使用注意事项: //
+// 1)不能在中断里调用写(write)接口; //
+// 2)调用本读写接口时应该习惯性判断返回值来检查read/write动作是否执行正确; //
+//=================================================================================//
+
+/* --------------------------------------------------------------------------*/
+/**
+ * @brief 读取对应配置项的内容
+ *
+ * @param [in] item_id 配置项ID号
+ * @param [out] buf 用于存储read数据内容
+ * @param [in] len buf的长度(byte), buf长度必须大于等于read数据长度
+ *
+ * @return 1)执行正确: 返回值等于实际上所读到的数据长度(大于0);
+ * 2)执行错误: 返回值小于等于0, 小于0表示相关错误码;
+ */
+/* --------------------------------------------------------------------------*/
+int syscfg_read(u16 item_id, void *buf, u16 len);
+
+/* --------------------------------------------------------------------------*/
+/**
+ * @brief 读取cfg_tool.bin对应配置项的内容
+ *
+ * @param [in] item_id 配置项ID号
+ * @param [out] buf 用于存储read数据内容
+ * @param [in] len buf的长度(byte), buf长度必须大于等于read数据长度
+ *
+ * @return 1)执行正确: 返回值等于实际上所读到的数据长度(大于0);
+ * 2)执行错误: 返回值小于等于0, 小于0表示相关错误码;
+ */
+/* --------------------------------------------------------------------------*/
+int syscfg_read_btmac_blemac_from_bin(u16 item_id, void *buf, u16 len);
+
+/* --------------------------------------------------------------------------*/
+/**
+ * @brief 写入对应配置项的内容
+ *
+ * @param [in] item_id 配置项ID号
+ * @param [in] buf 用于存储write数据内容
+ * @param [in] len buf的长度(byte), buf长度必须大于等于write数据长度
+ *
+ * @return 1)执行正确: 返回值等于实际上所读到的数据长度(大于0);
+ * 2)执行错误: 返回值小于等于0, 小于0表示相关错误码;
+ */
+/* --------------------------------------------------------------------------*/
+int syscfg_write(u16 item_id, void *buf, u16 len);
+
+/* --------------------------------------------------------------------------*/
+/**
+ * @brief 以dma的方式写入对应配置项的内容, 请注意buf地址需要按照4byte对齐
+ *
+ * @param [in] item_id 配置项ID号
+ * @param [in] buf 用于存储write数据内容
+ * @param [in] len buf的长度(byte), buf长度必须大于等于write数据长度
+ *
+ * @return 1)执行正确: 返回值等于实际上所读到的数据长度(大于0);
+ * 2)执行错误: 返回值小于等于0, 小于0表示相关错误码;
+ */
+/* --------------------------------------------------------------------------*/
+int syscfg_dma_write(u16 item_id, void *buf, u16 len);
+
+/* --------------------------------------------------------------------------*/
+/**
+ * @brief 读取同一个配置项存在多份数据中的某一份数据, ver读取表示第几份数据, ver从 0 开始;
+ * @brief 典型应用: 读取配置项CFG_BT_NAME中多个蓝牙名中的某一个蓝牙名;
+ *
+ * @param [in] item_id 配置项ID号
+ * @param [in] buf 用于存储read数据内容
+ * @param [in] len buf的长度(byte), buf长度必须大于等于read数据长度
+ * @param [in] ver 读取表示第几份数据
+ *
+ * @return 1)执行正确: 返回值等于实际上所读到的数据长度(大于0);
+ * 2)执行错误: 返回值小于等于0, 小于0表示相关错误码;
+ */
+/* --------------------------------------------------------------------------*/
+int syscfg_read_string(u16 item_id, void *buf, u16 len, u8 ver);
+
+/* --------------------------------------------------------------------------*/
+/**
+ * @brief 获取配置项的地址
+ * @brief 注: 只支持cfg_tools.bin文件中的配置项读取
+ * @param [in] item_id 配置项ID号
+ * @param [out] len 配置项长度
+ *
+ * @return 配置项地址指针(可以用cpu直接访问);
+ */
+/* --------------------------------------------------------------------------*/
+u8 *syscfg_ptr_read(u16 item_id, u16 *len);
+
+
+//==================================================================================================//
+// 配置项ID分配说明 //
+// 1.配置项ID号根据存储区域进行分配; //
+// 2.存储区域有3个: 1)VM区域; 2)sys_cfg.bin; 3)BTIF区域 //
+// 3.配置项ID号分配如下: //
+// 0)[0]: 配置项ID号0为配置项工具保留ID号; //
+// 1)[ 1 ~ 49]: 共49项, 预留给用户自定义, 只存于VM区域; //
+// 2)[ 50 ~ 99]: 共50项, sdk相关配置项, 只存于VM区域; //
+// 3)[100 ~ 127]: 共28项, sdk相关配置项, 可以存于VM区域, sys_cfg.bin(作为默认值) 和 BTIF区域; //
+// 4)[512 ~ 700]: 共188项, sdk相关配置项, 只存于sys_cfg.bin; //
+//==================================================================================================//
+
+//=================================================================================//
+// 用户自定义配置项[1 ~ 49] //
+//=================================================================================//
+#define CFG_USER_DEFINE_BEGIN 1
+
+
+#define CFG_USER_PAIR_INFO 2
+#define CFG_USER_TIM_FLAG 3
+
+
+
+
+#define VM_ALARM_0 3+1
+#define VM_ALARM_1 4+1
+#define VM_ALARM_2 5+1
+#define VM_ALARM_3 6+1
+#define VM_ALARM_4 7+1
+#define VM_ALARM_EX0 8+1
+#define VM_ALARM_EX1 9+1
+#define VM_ALARM_EX2 10+1
+#define VM_ALARM_EX3 11+1
+#define VM_ALARM_EX4 12+1
+#define VM_ALARM_NAME_0 13+1
+#define VM_ALARM_NAME_1 14+1
+#define VM_ALARM_NAME_2 15+1
+#define VM_ALARM_NAME_3 16+1
+#define VM_ALARM_NAME_4 17+1
+#define VM_ALARM_RING_NAME_0 18+1
+#define VM_ALARM_RING_NAME_1 19+1
+#define VM_ALARM_RING_NAME_2 20+1
+#define VM_ALARM_RING_NAME_3 21+1
+#define VM_ALARM_RING_NAME_4 22+1
+#define VM_ALARM_MASK 23+1
+#define CFG_USER_DEVICE_STA 24+1
+#define CFG_USER_PLAN_INFO1 25+1
+
+#define CFG_USER_BATTERY_LEVEL 26+1
+
+
+#define CFG_USER_DEFINE_END 49
+
+//=================================================================================//
+// 只存VM配置项[50 ~ 99] //
+//=================================================================================//
+#define CFG_STORE_VM_ONLY_BEGIN 50
+#define AT_CHAR_DEV_NAME 51
+#define CFG_STORE_VM_ONLY_END 99
+
+//=================================================================================//
+// 可以存于VM, sys_cfg.bin(默认值)和BTIF区域的配置项[100 ~ 127] //
+// (VM支持扩展到511) //
+//=================================================================================//
+#define CFG_STORE_VM_BIN_BTIF_BEGIN 100
+#define CFG_STORE_VM_BIN_BTIF_END (VM_ITEM_MAX_NUM - 1) //在app_cfg文件中配置128/256
+
+//==================================================================================================//
+//ID号分配方案:
+// 1) 与APP CASE 相关的ID (0 ~ 50);
+// 3) lib库保留ID(蓝牙, trim 值) (范围: 61 ~ 127); //67项
+// 4) 与app_case 扩展ID号,需要更大的ram资源(128 ~ 511);
+//==================================================================================================//
+
+//=================================================================================//
+// SDK库保留配置项[61 ~ 127] //
+//=================================================================================//
+#define CFG_REMOTE_DB_INFO 61
+#define CFG_REMOTE_DB_00 62
+#define CFG_REMOTE_DB_01 63
+#define CFG_REMOTE_DB_02 64
+#define CFG_REMOTE_DB_03 65
+#define CFG_REMOTE_DB_04 66
+#define CFG_REMOTE_DB_05 67
+#define CFG_REMOTE_DB_06 68
+#define CFG_REMOTE_DB_07 69
+#define CFG_REMOTE_DB_08 70
+#define CFG_REMOTE_DB_09 71
+#define CFG_REMOTE_DB_10 72
+#define CFG_REMOTE_DB_11 73
+#define CFG_REMOTE_DB_12 74
+#define CFG_REMOTE_DB_13 75
+#define CFG_REMOTE_DB_14 76
+#define CFG_REMOTE_DB_15 77
+#define CFG_REMOTE_DB_16 78
+#define CFG_REMOTE_DB_17 79
+#define CFG_REMOTE_DB_18 80
+#define CFG_REMOTE_DB_19 81
+// #define CFG_NULL 82
+#define CFG_BLE_MODE_INFO 83
+#define CFG_TWS_PAIR_AA 84
+#define CFG_TWS_CONNECT_AA 85
+#define CFG_MUSIC_VOL 86
+#define CFG_DAC_DTB 88
+#define CFG_MC_BIAS 89
+#define CFG_POR_FLAG 90
+#define CFG_MIC_LDO_VSEL 91
+#define CFG_DAC_TRIM_INFO 92
+#define CFG_BT_TRIM_INFO 93
+#define CFG_ANC_INFO 94
+#define CFG_TWS_LOCAL_ADDR 95
+#define CFG_TWS_REMOTE_ADDR 96
+#define CFG_TWS_COMMON_ADDR 97
+#define CFG_TWS_CHANNEL 98
+#define VM_PMU_VOLTAGE 99
+// #define CFG_NULL 100
+
+//=========== btif & cfg_tool.bin & vm ============//
+#define CFG_BT_NAME 101
+#define CFG_BT_MAC_ADDR 102
+#define CFG_BLE_NAME 103
+#define CFG_BLE_MAC_ADDR 104
+#define VM_OLD_RTC_TIME 105
+#define VM_OLD_REAL_TIME 106
+#define VM_BLE_LOCAL_INFO 109
+#define CFG_BT_FRE_OFFSET 110
+#define VM_GFPS_KEY_LIST 111
+#define VM_GFPS_NAME 112
+// #define CFG_NULL 113
+#define VM_TME_AUTH_COOKIE 114
+// #define CFG_NULL 115
+
+#define VM_RTC_TRIM 116
+
+#define VM_BLE_REMOTE_DB_INFO 117
+#define VM_BLE_REMOTE_DB_00 118
+#define VM_BLE_REMOTE_DB_01 119
+#define VM_BLE_REMOTE_DB_02 120
+#define VM_BLE_REMOTE_DB_03 121
+#define VM_BLE_REMOTE_DB_04 122
+#define VM_BLE_REMOTE_DB_05 123
+#define VM_BLE_REMOTE_DB_06 124
+#define VM_BLE_REMOTE_DB_07 125
+#define VM_BLE_REMOTE_DB_08 126
+#define VM_BLE_REMOTE_DB_09 127
+
+#define CFG_ONLINE_EQ_DRC_DATA_ID 254//在线调试保存参数的id
+#define CFG_ONLINE_SAVE_ID 255//在线保存文件大小的id
+
+
+//=================================================================================//
+// 只存于sys_cfg.bin的配置项[512 ~ 700] //
+//=================================================================================//
+#define CFG_STORE_BIN_ONLY_BEGIN 512
+//硬件类配置项[513 ~ 600]
+#define CFG_UART_ID 513
+#define CFG_HWI2C_ID 514
+#define CFG_SWI2C_ID 515
+#define CFG_HWSPI_ID 516
+#define CFG_SWSPI_ID 517
+#define CFG_SD_ID 518
+#define CFG_USB_ID 519
+#define CFG_LCD_ID 520
+#define CFG_TOUCH_ID 521
+#define CFG_IOKEY_ID 522
+#define CFG_ADKEY_ID 523
+#define CFG_AUDIO_ID 524
+#define CFG_VIDEO_ID 525
+#define CFG_WIFI_ID 526
+#define CFG_NIC_ID 527
+#define CFG_LED_ID 528
+#define CFG_POWER_MANG_ID 529
+#define CFG_IRFLT_ID 530
+#define CFG_PLCNT_ID 531
+#define CFG_PWMLED_ID 532
+#define CFG_RDEC_ID 533
+#define CFG_CHARGE_STORE_ID 534
+#define CFG_CHARGE_ID 535
+#define CFG_LOWPOWER_V_ID 536
+#define CFG_MIC_TYPE_ID 537
+#define CFG_COMBINE_SYS_VOL_ID 538
+#define CFG_COMBINE_CALL_VOL_ID 539
+#define CFG_LP_TOUCH_KEY_ID 540
+
+//蓝牙类配置项[601 ~ 650]
+#define CFG_BT_RF_POWER_ID 601
+#define CFG_TWS_PAIR_CODE_ID 602
+#define CFG_AUTO_OFF_TIME_ID 603
+#define CFG_AEC_ID 604
+#define CFG_UI_TONE_STATUS_ID 605
+#define CFG_KEY_MSG_ID 606
+#define CFG_LRC_ID 607
+#define CFG_DMS_ID 609
+#define CFG_ANC_ID 610
+#define CFG_SMS_DNS_ID 612 //单mic神经网络降噪
+#define CFG_DMS_DNS_ID 613 //双mic神经网络降噪
+#define CFG_DMS_FLEXIBLE_ID 614 //灵活可变双mic降噪
+#define CFG_BLE_RF_POWER_ID 615
+#define CFG_DMS_DNS_FLEXIBLE_ID 616 //灵活可变双mic神经网络降噪
+#define CFG_TMS_DNS_ID 617 //3mic神经网络降噪参数
+
+//其它类配置项[651 ~ 700]
+#define CFG_STORE_BIN_ONLY_END 700
+
+
+
+#endif
+
diff --git a/include_lib/system/task.h b/include_lib/system/task.h
new file mode 100644
index 0000000..9830fb7
--- /dev/null
+++ b/include_lib/system/task.h
@@ -0,0 +1,42 @@
+#ifndef TASK_PRIORITY_H
+#define TASK_PRIORITY_H
+
+
+#include "os/os_api.h"
+
+
+struct task_info {
+ const char *name;
+ u8 prio;
+ u8 core;
+ u16 stack_size;
+ u16 qsize;
+};
+
+
+
+typedef OS_SEM sem_t;
+typedef OS_MUTEX mutex_t;
+
+
+int task_create(void (*task)(void *p), void *p, const char *name);
+
+
+int task_exit(const char *name);
+
+int task_delete(const char *name);
+
+int task_kill(const char *name);
+
+
+
+
+
+
+
+
+
+
+#endif
+
+
diff --git a/include_lib/system/timer.h b/include_lib/system/timer.h
new file mode 100644
index 0000000..7a1f184
--- /dev/null
+++ b/include_lib/system/timer.h
@@ -0,0 +1,308 @@
+#ifndef SYS_TIMER_H
+#define SYS_TIMER_H
+
+
+#include "typedef.h"
+#include "generic/list.h"
+
+
+struct static_sys_timer {
+ void (*func)(void *priv);
+ void *priv;
+ u32 msec;
+ u32 jiffies;
+};
+
+struct sys_usec_timer {
+ void (*func)(void *priv);
+ void *priv;
+ const char *owner;
+ struct sys_cpu_timer *timer;
+};
+
+
+#define SYS_HI_TIMER_ADD(_func, _priv, _msec) \
+ static struct static_sys_timer hi_timer sec(.hi_timer) = { \
+ .func = _func, \
+ .priv = _priv, \
+ .msec = _msec, \
+ }
+
+extern struct static_sys_timer static_hi_timer_begin[];
+extern struct static_sys_timer static_hi_timer_end[];
+
+#define list_for_each_static_hi_timer(p) \
+ for (p=static_hi_timer_begin; p>24)|((x>>8)&0xff00)|(x<<24)|((x&0xff00)<<8))
+#define font_ntoh(x) (unsigned short int )((x>>8&0x00ff)|x<<8&0xff00)
+
+extern const struct font_info font_info_table[];
+
+
+typedef struct {
+ u8 codepage;
+ u32 ansi_offset;
+ u32 table_offset;
+} LANG_TABLE;
+
+
+#define CP874 (1)
+#define CP937 (2)
+#define CP1250 (3)
+#define CP1251 (4)
+#define CP1252 (5)
+#define CP1253 (6)
+#define CP1254 (7)
+#define CP1255 (8)
+#define CP1256 (9)
+#define CP1257 (10)
+#define CP1258 (11)
+#define CPKSC (12)
+#define CPSIJS (13)
+
+
+extern const LANG_TABLE *lange_info_table;
+
+
+int font_set_offset_table(const LANG_TABLE *table);
+
+
+
+#endif
diff --git a/include_lib/system/ui/font/font_sdfs.h b/include_lib/system/ui/font/font_sdfs.h
new file mode 100644
index 0000000..654c70d
--- /dev/null
+++ b/include_lib/system/ui/font/font_sdfs.h
@@ -0,0 +1,23 @@
+#ifndef __UI_SDFS_H__
+#define __UI_SDFS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "generic/typedef.h"
+#include "fs/fs.h"
+
+#define SD_SEEK_SET 0x00
+#define SD_SEEK_CUR 0x01
+
+FILE *font_sd_fopen(const char *filename, void *arg);
+int font_sd_fread(FILE *fp, void *buf, u32 len);
+int font_sd_fseek(FILE *fp, u8 seek_mode, u32 offset);
+int font_sd_fclose(FILE *fp);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include_lib/system/ui/font/font_textout.h b/include_lib/system/ui/font/font_textout.h
new file mode 100644
index 0000000..ff08732
--- /dev/null
+++ b/include_lib/system/ui/font/font_textout.h
@@ -0,0 +1,103 @@
+#ifndef __FONT_OUT_H__
+#define __FONT_OUT_H__
+
+#include "generic/typedef.h"
+#include "font/font_all.h"
+
+/**
+ * @brief 打开字库
+ *
+ * @param info:字库信息
+ * @param language:语言
+ *
+ * @returns TRUE:打开成功 FALSE:打开失败
+ */
+struct font_info *font_open(struct font_info *info, u8 language);
+/**
+ * @brief 获取字符宽度
+ *
+ * @param info
+ * @param str
+ * @param strlen
+ *
+ * @returns
+ */
+u16 font_text_width(struct font_info *info, u8 *str, u16 strlen);
+u16 font_textw_width(struct font_info *info, u8 *str, u16 strlen);
+u16 font_textu_width(struct font_info *info, u8 *str, u16 strlen);
+
+/**
+ * @brief 字库内码显示接口
+ *
+ * @param info
+ * @param str
+ * @param strlen
+ *
+ * @returns
+ */
+u16 font_textout(struct font_info *info, u8 *str, u16 strlen, u16 x, u16 y);
+/**
+ * @brief 字库unicode显示接口
+ *
+ * @param info
+ * @param str
+ * @param strlen
+ * @param x
+ * @param y
+ *
+ * @returns
+ */
+u16 font_textout_unicode(struct font_info *info, u8 *str, u16 strlen, u16 x, u16 y);
+/**
+ * @brief 字库utf8显示接口
+ *
+ * @param info
+ * @param str
+ * @param strlen
+ * @param x
+ * @param y
+ *
+ * @returns
+ */
+u16 font_textout_utf8(struct font_info *info, u8 *str, u16 strlen, u16 x, u16 y);
+/**
+ * @brief utf8转内码
+ *
+ * @param info
+ * @param utf8
+ * @param utf8len
+ * @param ansi
+ *
+ * @returns
+ */
+u16 font_utf8toansi(struct font_info *info, u8 *utf8, u16 utf8len, u8 *ansi);
+/**
+ * @brief utf16转内码
+ *
+ * @param info
+ * @param utf
+ * @param len
+ * @param ansi
+ *
+ * @returns
+ */
+u16 font_utf16toansi(struct font_info *info, u8 *utf, u16 len, u8 *ansi);
+/**
+ * @brief utf8转utf16
+ *
+ * @param info
+ * @param utf8
+ * @param utf8len
+ * @param utf16
+ *
+ * @returns
+ */
+u16 font_utf8toutf16(struct font_info *info, u8 *utf8, u16 utf8len, u16 *utf16);
+/**
+ * @brief 字库关闭
+ *
+ * @param info
+ */
+void font_close(struct font_info *info);
+
+#endif
diff --git a/include_lib/system/ui/font/language_list.h b/include_lib/system/ui/font/language_list.h
new file mode 100644
index 0000000..0c0bd60
--- /dev/null
+++ b/include_lib/system/ui/font/language_list.h
@@ -0,0 +1,29 @@
+#ifndef __LANGUAGE_LIST_H__
+#define __LANGUAGE_LIST_H__
+
+#define Chinese_Simplified 1 //简体中文
+#define Chinese_Traditional 2 //繁体中文
+#define Japanese 3 //日语
+#define Korean 4 //韩语
+#define English 5 //英语
+#define French 6 //法语
+#define German 7 //德语
+#define Italian 8 //意大利语
+#define Dutch 9 //荷兰语
+#define Portuguese 10 //葡萄牙语
+#define Spanish 11 //西班牙语
+#define Swedish 12 //瑞典语
+#define Czech 13 //捷克语
+#define Danish 14 //丹麦语
+#define Polish 15 //波兰语
+#define Russian 16 //俄语
+#define Turkey 17 //土耳其语
+#define Hebrew 18 //希伯来语
+#define Thai 19 //泰语
+#define Hungarian 20 //匈牙利语
+#define Romanian 21 //罗马尼亚语
+#define Arabic 22 //阿拉伯语
+#define Vietnam 23 //越南语
+#define Tibetan 24 //藏文
+
+#endif
diff --git a/include_lib/system/ui/res/resfile.h b/include_lib/system/ui/res/resfile.h
new file mode 100644
index 0000000..66065ef
--- /dev/null
+++ b/include_lib/system/ui/res/resfile.h
@@ -0,0 +1,101 @@
+#ifndef RESFILE_H
+#define RESFILE_H
+
+#include "typedef.h"
+#include "fs/fs.h"
+
+// resfile共用文件句柄
+#if (defined(CONFIG_CPU_BR23) && defined(CONFIG_APP_WATCH))
+#define RESFILE_COMMON_HDL_EN 0
+#else
+#define RESFILE_COMMON_HDL_EN 0
+#endif
+
+#define FILE_TYPE_JPEG 5
+#define AT_UI_RAM AT(.ui_ram)
+
+
+//图像数据格式
+enum {
+ PIXEL_FMT_ARGB8888,
+ PIXEL_FMT_RGB888,
+ PIXEL_FMT_RGB565,
+ PIXEL_FMT_L8,
+ PIXEL_FMT_AL88,
+ PIXEL_FMT_AL44,
+ PIXEL_FMT_A8,
+ PIXEL_FMT_L1,
+ PIXEL_FMT_ARGB8565,
+ PIXEL_FMT_OSD16,
+ PIXEL_FMT_SOLID,
+ PIXEL_FMT_JPEG,
+ PIXEL_FMT_UNKNOW,
+};
+
+// #define EXTERN_PATH "storage/nor_ui/C/res/"
+// #define EXTERN_PATH "storage/virfat_flash/C/uires/"
+struct image_file {
+ u8 format;
+ u8 compress;
+ u16 data_crc;
+ u16 width;
+ u16 height;
+ u32 offset;
+ u32 len;
+};
+
+typedef struct resfile {
+ FILE *file;
+#if RESFILE_COMMON_HDL_EN
+ struct list_head entry;
+ u32 offset;
+ u32 size;
+#endif
+} RESFILE;
+
+int open_resfile(const char *name);
+void close_resfile();
+
+int res_file_version_compare(int res_ver);
+
+int open_str_file(const char *name);
+void close_str_file();
+int str_file_version_compare(int str_ver);
+
+int open_style_file(const char *name);
+
+int font_ascii_init(const char *name);
+int open_image_by_id(RESFILE *specfile, struct image_file *f, int id, int page);
+int read_image_data(struct image_file *f, u8 *data, int len);
+int br23_read_image_data(RESFILE *specfile, struct image_file *f, u8 *data, int len, int offset);
+int br25_read_image_data(RESFILE *specfile, struct image_file *f, u8 *data, int len, int offset);
+u32 image_decode(const void *pSour, void *pDest, u32 SourLen, u32 DestLen, u8 compress);
+int open_string_pic(struct image_file *file, int id);
+int read_str_data(struct image_file *f, u8 *data, int len);
+int br23_read_str_data(struct image_file *f, u8 *data, int len, int offset);
+int br25_read_str_data(struct image_file *f, u8 *data, int len, int offset);
+int load_pallet_table(int id, u32 *data);
+int ui_language_set(int language);
+int ui_language_get();
+
+RESFILE *res_fopen(const char *path, const char *mode);
+int res_fread(RESFILE *_file, void *buf, u32 len);
+int res_fseek(RESFILE *_file, int offset, int fromwhere);
+int res_flen(RESFILE *file);
+int res_fclose(RESFILE *file);
+int _norflash_read_watch(u8 *buf, u32 addr, u32 len, u8 wait);//加速读
+
+struct ui_load_info {
+ u8 pj_id;
+ const char *path;
+ RESFILE *file;
+ RESFILE *res;
+ RESFILE *str;
+};
+
+void *ui_load_res_by_pj_id(int pj_id);
+void *ui_load_str_by_pj_id(int pj_id);
+int ui_set_sty_path_by_pj_id(int pj_id, const u8 *path);
+void *ui_load_sty_by_pj_id(int pj_id);
+
+#endif
diff --git a/include_lib/system/ui/ui/control.h b/include_lib/system/ui/ui/control.h
new file mode 100644
index 0000000..8223202
--- /dev/null
+++ b/include_lib/system/ui/ui/control.h
@@ -0,0 +1,371 @@
+#ifndef UI_CONTROL_H
+#define UI_CONTROL_H
+
+#include "ui/ui_core.h"
+
+union ui_control_info;
+struct layout_info;
+
+#define CTRL_TYPE_WINDOW 2
+#define CTRL_TYPE_LAYOUT 3
+#define CTRL_TYPE_LAYER 4
+#define CTRL_TYPE_GRID 5
+#define CTRL_TYPE_LIST 6
+#define CTRL_TYPE_BUTTON 7
+#define CTRL_TYPE_PIC 8
+#define CTRL_TYPE_BATTERY 9
+#define CTRL_TYPE_TIME 10
+#define CTRL_TYPE_CAMERA_VIEW 11
+#define CTRL_TYPE_TEXT 12
+#define CTRL_TYPE_ANIMATION 13
+#define CTRL_TYPE_PLAYER 14
+#define CTRL_TYPE_NUMBER 15
+
+#define CTRL_TYPE_PROGRESS 20
+#define CTRL_PROGRESS_CHILD_BEGIN (CTRL_TYPE_PROGRESS + 1)
+#define CTRL_PROGRESS_CHILD_HIGHLIGHT (CTRL_PROGRESS_CHILD_BEGIN) //21
+#define CTRL_PROGRESS_CHILD_END (CTRL_PROGRESS_CHILD_BEGIN + 1)
+
+#define CTRL_TYPE_MULTIPROGRESS 22
+#define CTRL_MULTIPROGRESS_CHILD_BEGIN (CTRL_TYPE_MULTIPROGRESS + 1)
+#define CTRL_MULTIPROGRESS_CHILD_HIGHLIGHT (CTRL_MULTIPROGRESS_CHILD_BEGIN)//23
+#define CTRL_MULTIPROGRESS_CHILD_END (CTRL_MULTIPROGRESS_CHILD_BEGIN + 1)
+
+#define CTRL_TYPE_WATCH 24
+#define CTRL_WATCH_CHILD_BEGIN (CTRL_TYPE_WATCH + 1)
+#define CTRL_WATCH_CHILD_HOUR (CTRL_WATCH_CHILD_BEGIN)//25
+#define CTRL_WATCH_CHILD_MIN (CTRL_WATCH_CHILD_BEGIN+1)//26
+#define CTRL_WATCH_CHILD_SEC (CTRL_WATCH_CHILD_BEGIN+2)//27
+#define CTRL_WATCH_CHILD_END (CTRL_WATCH_CHILD_BEGIN+3)
+
+
+#define CTRL_TYPE_SLIDER 28
+
+#define SLIDER_CHILD_BEGIN (CTRL_TYPE_SLIDER+1)
+#define SLIDER_CHILD_UNSELECT_PIC (SLIDER_CHILD_BEGIN)//29
+#define SLIDER_CHILD_SELECTED_PIC (SLIDER_CHILD_BEGIN+1)//30
+#define SLIDER_CHILD_SLIDER_PIC (SLIDER_CHILD_BEGIN+2)//31
+#define SLIDER_CHILD_PERSENT_TEXT (SLIDER_CHILD_BEGIN+3)//32
+#define SLIDER_CHILD_END (SLIDER_CHILD_BEGIN+4)
+
+
+#define CTRL_TYPE_VSLIDER 33
+
+#define VSLIDER_CHILD_BEGIN (CTRL_TYPE_VSLIDER+1)
+#define VSLIDER_CHILD_UNSELECT_PIC (VSLIDER_CHILD_BEGIN)//34
+#define VSLIDER_CHILD_SELECTED_PIC (VSLIDER_CHILD_BEGIN+1)//35
+#define VSLIDER_CHILD_SLIDER_PIC (VSLIDER_CHILD_BEGIN+2)//36
+#define VSLIDER_CHILD_PERSENT_TEXT (VSLIDER_CHILD_BEGIN+3)//37
+#define VSLIDER_CHILD_END (VSLIDER_CHILD_BEGIN+4)
+
+
+struct ui_ctrl_info_head {
+ u8 type;
+ u8 ctrl_num;
+ u8 css_num;
+ u8 len;
+ u8 page;
+ u8 rev[3];
+ int id;
+ struct element_css1 *css;
+};
+
+struct ui_image_list {
+ u16 num;
+ u16 image[0];
+};
+
+struct ui_text_list {
+ u16 num;
+ char str[0];
+};
+
+
+struct ui_image_list_t {
+ u16 num;
+ u16 image[64];
+};
+
+#define UI_TEXT_LIST_MAX_NUM 3
+struct ui_text_list_t {
+ u16 num;
+ u16 str[50];
+};
+
+struct ui_button_info {
+ struct ui_ctrl_info_head head;
+ struct element_event_action *action;
+};
+
+
+
+struct ui_camera_info {
+ struct ui_ctrl_info_head head;
+ char device[8];
+ struct element_event_action *action;
+};
+
+struct ui_player_info {
+ struct ui_ctrl_info_head head;
+ char device[8];
+ struct element_event_action *action;
+};
+
+struct ui_time_info {
+ struct ui_ctrl_info_head head;
+ char source[8];
+ u8 auto_cnt;
+ u8 rev[3];
+ char format[16];
+ int color;
+ int hi_color;
+ u16 number[10];
+ u16 delimiter[10];
+ struct element_event_action *action;
+};
+
+struct ui_number_info {
+ struct ui_ctrl_info_head head;
+ char source[8];
+ char format[16];
+ int color;
+ int hi_color;
+ u16 number[10];
+ u16 delimiter[10];
+ u16 space[2];
+ struct element_event_action *action;
+};
+
+
+struct ui_pic_info {
+ struct ui_ctrl_info_head head;
+ u8 highlight;
+ u16 cent_x;
+ u16 cent_y;
+ struct ui_image_list *normal_img;
+ struct ui_image_list *highlight_img;
+ struct element_event_action *action;
+};
+
+
+struct ui_battery_info {
+ struct ui_ctrl_info_head head;
+ struct ui_image_list *normal_image;
+ struct ui_image_list *charge_image;
+ struct element_event_action *action;
+};
+
+
+struct ui_text_info {
+ struct ui_ctrl_info_head head;
+ char source[8];
+ char code[8];
+ int color;
+ int highlight_color;
+ struct ui_text_list *str;
+ struct element_event_action *action;
+};
+
+
+struct ui_grid_info {
+ struct ui_ctrl_info_head head;
+ u8 page_mode;
+ char highlight_index;
+ struct element_event_action *action;
+ struct layout_info *info;
+};
+
+struct ui_animation_info {
+ struct ui_ctrl_info_head head;
+ u16 loop_num;
+ u32 interval;
+ struct ui_image_list *img;
+ struct element_event_action *action;
+};
+
+struct ui_slider_info {
+ struct ui_ctrl_info_head head;
+ u8 step;
+ struct ui_ctrl_info_head *ctrl;
+ // struct element_event_action *action;
+};
+
+struct ui_vslider_info {
+ struct ui_ctrl_info_head head;
+ u8 step;
+ struct ui_ctrl_info_head *ctrl;
+ // struct element_event_action *action;
+};
+
+struct ui_watch_info {
+ struct ui_ctrl_info_head head;
+ char source[8];
+ struct element_event_action *action;
+ struct ui_ctrl_info_head *ctrl;
+};
+
+struct ui_progress_info {
+ struct ui_ctrl_info_head head;
+ char source[8];
+ struct element_event_action *action;
+ struct ui_ctrl_info_head *ctrl;
+};
+
+struct ui_multiprogress_info {
+ struct ui_ctrl_info_head head;
+ char source[8];
+ struct element_event_action *action;
+ struct ui_ctrl_info_head *ctrl;
+};
+
+struct ui_browser_info {
+ struct ui_ctrl_info_head head;
+ u8 row;
+ u8 column;
+ u8 interval;
+ u8 scroll;
+ u8 auto_highlight;
+ struct element_event_action *action;
+ struct ui_ctrl_info_head *ctrl;
+};
+
+struct ui_fattrs_info {
+ struct ui_ctrl_info_head head;
+ struct element_event_action *action;
+ struct ui_ctrl_info_head *ctrl;
+};
+
+struct layout_info {
+ struct ui_ctrl_info_head head;
+ struct element_event_action *action;
+ union ui_control_info *ctrl;
+};
+
+
+struct layer_info {
+ struct ui_ctrl_info_head head;
+ u8 format;
+ struct element_event_action *action;
+ struct layout_info *layout;
+};
+
+
+union ui_control_info {
+ struct ui_ctrl_info_head head;//16 bytes
+ struct ui_button_info button;//20 bytes
+ struct ui_camera_info camera;//28 bytes
+ struct ui_time_info time;//84 bytes
+ struct ui_number_info number;
+ struct ui_pic_info pic;//36 bytes
+ struct ui_battery_info battery;//28 bytes
+ struct ui_text_info text;//40 bytes
+ struct ui_grid_info grid;//28 bytes
+ struct layer_info layer;
+ struct layout_info layout;
+ struct ui_watch_info watch;
+ struct ui_progress_info progress;
+ struct ui_multiprogress_info multiprogress;
+ struct ui_slider_info slider;
+ struct ui_vslider_info vslider;
+};//84 bytes
+
+// union ui_control_info {
+// struct ui_ctrl_info_head head;
+// struct ui_button_info button;
+// struct ui_camera_info camera;
+// struct ui_time_info time;
+// struct ui_number_info number;
+// struct ui_pic_info pic;
+// struct ui_battery_info battery;
+// struct ui_text_info text;
+// struct ui_grid_info grid;
+// };
+
+
+struct window_info {
+ u8 type;
+ u8 ctrl_num;
+ u8 css_num;
+ u8 len;
+ u8 rev[4];
+ struct rect rect;
+ struct layer_info *layer;
+// struct element_event_action *action;
+};
+
+struct control_ops {
+ int type;
+ void *(*new)(const void *, struct element *);
+ /*int (*delete)(void *);*/
+};
+
+extern const struct control_ops control_ops_begin[];
+extern const struct control_ops control_ops_end[];
+
+
+#define REGISTER_CONTROL_OPS(_type) \
+ static const struct control_ops control_ops_##_type sec(.control_ops) __attribute__((used)) = { \
+ .type = _type,
+
+
+
+#define get_control_ops_by_type(_type) \
+ ({ \
+ const struct control_ops *ops, *ret=NULL; \
+ for (ops = control_ops_begin; ops < control_ops_end; ops++) { \
+ if (ops->type == _type) { \
+ ret = ops; \
+ break; \
+ } \
+ }\
+ ret; \
+ })
+
+
+#if 0
+struct control_event_header {
+ int id;
+ int len;
+};
+
+extern struct control_event_header control_event_handler_begin[];
+extern struct control_event_header control_event_handler_end[];
+
+
+#define REGISTER_CONTROL_EVENT_HANDLER(control, _id) \
+ static const struct control##_event_handler __##control##_event_handler_##_id \
+ sec(.control_event_handler) = { \
+ .header = { \
+ .id = _id, \
+ .len = sizeof(struct control##_event_handler), \
+ }, \
+
+
+
+
+static inline void *control_event_handler_for_id(int id)
+{
+ struct control_event_header *p;
+
+ for (p = control_event_handler_begin; p < control_event_handler_end;) {
+ if (p->id == id) {
+ return p;
+ }
+ p = (u8 *)p + p->len;
+ }
+
+ return NULL;
+}
+#endif
+
+
+
+
+
+
+
+
+#endif
+
+
+
diff --git a/include_lib/system/ui/ui/layer.h b/include_lib/system/ui/ui/layer.h
new file mode 100644
index 0000000..4154292
--- /dev/null
+++ b/include_lib/system/ui/ui/layer.h
@@ -0,0 +1,53 @@
+#ifndef LAYER_H
+#define LAYER_H
+
+
+#include "ui/layout.h"
+#include "ui/control.h"
+
+
+struct layer {
+ struct element elm; //must be first
+ u8 hide;
+ u8 inited;
+ u8 highlight;
+ u8 ctrl_num;
+ u8 css_num;
+ u32 css[2];
+ struct draw_context dc;
+ struct layout *layout;
+ const struct layer_info *info;
+ const struct element_event_handler *handler;
+};
+
+
+#define layer_for_id(id) \
+ (struct layer *)ui_core_get_element_by_id(id);
+
+
+struct layer *layer_new(struct layer_info *info, int num, struct element *parent);
+
+
+void layer_delete_probe(struct layer *layer, int num);
+
+void layer_delete(struct layer *layer, int num);
+
+int layer_show(int id);
+
+int layer_hide(int id);
+
+int layer_toggle(int id);
+
+
+
+
+
+
+
+
+
+#endif
+
+
+
+
diff --git a/include_lib/system/ui/ui/layout.h b/include_lib/system/ui/ui/layout.h
new file mode 100644
index 0000000..ae1bd16
--- /dev/null
+++ b/include_lib/system/ui/ui/layout.h
@@ -0,0 +1,54 @@
+#ifndef LAYOUT_H
+#define LAYOUT_H
+
+
+#include "ui/ui_core.h"
+#include "ui/control.h"
+
+
+
+
+
+struct layout {
+ struct element elm; //must be first
+ u8 hide: 1;
+ u8 inited: 1;
+ u8 release: 6;
+ // u8 css_num:5;
+ // u32 css[2];
+ struct layout *layout;
+ const struct layout_info *info;
+ const struct element_event_handler *handler;
+};
+
+
+
+#define layout_for_id(id) \
+ (struct layout *)ui_core_get_element_by_id(id);
+
+
+struct layout *layout_new(struct layout_info *, int, struct element *);
+
+void layout_delete_probe(struct layout *layout, int num);
+
+void layout_delete(struct layout *layout, int num);
+
+int layout_show(int id);
+
+int layout_hide(int id);
+
+int layout_toggle(int id);
+
+void layout_on_focus(struct layout *layout);
+void layout_lose_focus(struct layout *layout);
+
+
+/*int layout_current_highlight(int id);*/
+
+/*int layout_onkey(struct layout *layout, struct element_key_event *e);*/
+
+
+
+#endif
+
+
diff --git a/include_lib/system/ui/ui/p.h b/include_lib/system/ui/ui/p.h
new file mode 100644
index 0000000..2993b33
--- /dev/null
+++ b/include_lib/system/ui/ui/p.h
@@ -0,0 +1,40 @@
+#ifndef UI_P_H
+#define UI_P_H
+
+#include "ui/ui_core.h"
+
+struct ui_str {
+ const char *format;
+ char *str;
+};
+
+struct element_text {
+ struct element elm; //must be first
+ char *str;
+ const char *format;
+ void *priv;
+ int color;
+ const struct element_event_handler *handler;
+};
+
+
+
+void text_element_set_text(struct element_text *text, char *str,
+ const char *format, int color);
+
+
+void text_element_init(struct element_text *text, int id, u8 page, u8 prj,
+ const struct element_css1 *css,
+ const struct element_event_action *action);
+
+
+void text_element_set_event_handler(struct element_text *text, void *priv,
+ const struct element_event_handler *handler);
+
+
+
+
+
+
+#endif
+
diff --git a/include_lib/system/ui/ui/ui.h b/include_lib/system/ui/ui/ui.h
new file mode 100644
index 0000000..b143e80
--- /dev/null
+++ b/include_lib/system/ui/ui/ui.h
@@ -0,0 +1,112 @@
+#ifndef UI_CORE_H
+#define UI_CORE_H
+
+#include "window.h"
+#include "ui_button.h"
+#include "ui_grid.h"
+#include "ui_time.h"
+#include "ui_camera.h"
+#include "ui_pic.h"
+#include "ui_text.h"
+#include "ui_battery.h"
+#include "ui_browser.h"
+#include "ui_slider.h"
+#include "ui_slider_vert.h"
+#include "ui_number.h"
+#include "ui_watch.h"
+#include "ui_progress.h"
+#include "ui_progress_multi.h"
+#include "ui_rotate.h"
+#include
+
+struct uimsg_handl {
+ const char *msg;
+ int (*handler)(const char *type, u32 args);
+};
+
+int ui_framework_init(void *);
+
+int ui_set_style_file(struct ui_style *style);
+
+int ui_style_file_version_compare(int version);
+
+int ui_redraw(int id);
+
+int ui_show(int id);
+
+int ui_hide(int id);
+
+int ui_set_call(int (*func)(int), int param);
+
+int ui_event_onkey(struct element_key_event *e);
+
+int ui_event_ontouch(struct element_touch_event *e);
+
+struct element *ui_get_highlight_child_by_id(int id);
+int ui_invert_element_by_id(int id);
+
+int ui_no_highlight_element(struct element *elm);
+int ui_no_highlight_element_by_id(int id);
+int ui_highlight_element(struct element *elm);
+int ui_highlight_element_by_id(int id);
+
+int ui_get_current_window_id();
+
+int ui_register_msg_handler(int id, const struct uimsg_handl *handl);
+
+int ui_message_handler(int id, const char *msg, va_list);
+
+const char *str_substr_iter(const char *str, char delim, int *iter);
+
+int ui_get_child_by_id(int id, int (*event_handler_cb)(void *, int, int));
+
+int ui_set_default_handler(int (*ontouch)(void *, struct element_touch_event *),
+ int (*onkey)(void *, struct element_key_event *),
+ int (*onchange)(void *, enum element_change_event, void *));
+
+/*
+ * 锁定元素elm之外的区域,所有的触摸消息都发给elm
+ */
+void ui_ontouch_lock(void *elm);
+void ui_ontouch_unlock(void *elm);
+
+/*
+ * 锁定控件的夫图层,先不推向imb显示
+ */
+int ui_lock_layer(int id);
+int ui_unlock_layer(int id);
+
+int ui_get_disp_status_by_id(int id);
+
+int create_control_by_id(char *tabfile, int page_id, int id, int parent_id);
+int delete_control_by_id(int id);
+
+
+void ui_remove_backcolor(struct element *elm);
+void ui_remove_backimage(struct element *elm);
+void ui_remove_border(struct element *elm);
+
+int ui_fill_rect(struct draw_context *dc, int left, int top, int width, int height, u32 acolor);
+int ui_draw_image(struct draw_context *dc, int page, int id, int x, int y);
+int ui_draw_ascii(struct draw_context *dc, char *str, int strlen, int x, int y, int color);
+int ui_draw_text(struct draw_context *dc, int encode, int endian, char *str, int strlen, int x, int y, int color);
+int ui_draw_strpic(struct draw_context *dc, int id, int x, int y, int color);
+void ui_draw_line(void *_dc, int x0, int y0, int x1, int y1, int color);
+void ui_draw_line_by_angle(void *_dc, int x, int y, int length, int angle, int color);
+void ui_draw_rect(void *_dc, int x, int y, int width, int height, int color);
+void ui_draw_circle(struct draw_context *dc, int center_x, int center_y,
+ int radius_big, int radius_small, int angle_begin,
+ int angle_end, int color, int percent);
+int ui_draw_set_pixel(struct draw_context *dc, int x, int y, int pixel);
+u32 ui_draw_get_pixel(struct draw_context *dc, int x, int y);
+u16 ui_draw_get_mixed_pixel(u16 backcolor, u16 forecolor, u8 alpha);
+
+void *load_control_info_by_id(char *tabfile, u32 page_id, u32 id);
+void *ui_control_new(void *_pos, void *parent);
+
+
+#define ui_id2type(id) (((id)>>16) & 0x3f)
+
+
+#endif
+
diff --git a/include_lib/system/ui/ui/ui.ld b/include_lib/system/ui/ui/ui.ld
new file mode 100644
index 0000000..16fdea5
--- /dev/null
+++ b/include_lib/system/ui/ui/ui.ld
@@ -0,0 +1,37 @@
+ lcd_interface_begin = .;
+ KEEP(*(.lcd_if_info))
+ lcd_interface_end = .;
+
+ ui_style_begin = .;
+ KEEP(*(.ui_style))
+ ui_style_end = .;
+
+
+ elm_event_handler_begin_JL = .;
+ KEEP(*(.elm_event_handler_JL))
+ elm_event_handler_end_JL = .;
+
+ elm_event_handler_begin_UPGRADE = .;
+ KEEP(*(.elm_event_handler_UPGRADE))
+ elm_event_handler_end_UPGRADE = .;
+
+
+
+ elm_event_handler_begin_DIAL = .;
+ KEEP(*(.elm_event_handler_DIAL))
+ elm_event_handler_end_DIAL = .;
+
+
+ control_event_handler_begin = .;
+ KEEP(*(.control_event_handler))
+ control_event_handler_end = .;
+
+ control_ops_begin = .;
+ KEEP(*(.control_ops))
+ control_ops_end = .;
+
+ battery_notify_begin = .;
+ *(.battery_notify)
+ battery_notify_end = .;
+
+
diff --git a/include_lib/system/ui/ui/ui_battery.h b/include_lib/system/ui/ui/ui_battery.h
new file mode 100644
index 0000000..f19a3b5
--- /dev/null
+++ b/include_lib/system/ui/ui/ui_battery.h
@@ -0,0 +1,29 @@
+#ifndef UI_BATTERY_H
+#define UI_BATTERY_H
+
+
+#include "ui/control.h"
+#include "list.h"
+
+
+
+
+
+
+struct ui_battery {
+ struct element elm;
+ int src;
+ u8 index;
+ u16 charge_image;
+ u16 normal_image;
+ struct list_head entry;
+ const struct ui_battery_info *info;
+ const struct element_event_handler *handler;
+};
+
+void ui_battery_enable();
+void ui_battery_level_change(int persent, int incharge);//改变所有电池控件
+int ui_battery_set_level_by_id(int id, int persent, int incharge);//修改指定id
+int ui_battery_set_level(struct ui_battery *battery, int persent, int incharge);//初始化使用
+
+#endif
diff --git a/include_lib/system/ui/ui/ui_browser.h b/include_lib/system/ui/ui/ui_browser.h
new file mode 100644
index 0000000..494b029
--- /dev/null
+++ b/include_lib/system/ui/ui/ui_browser.h
@@ -0,0 +1,92 @@
+#ifndef UI_BROWSER_H
+#define UI_BROWSER_H
+
+
+
+#include "ui/ui_core.h"
+#include "ui/control.h"
+
+
+
+
+struct ui_browser {
+ struct element elm;
+ struct ui_file_browser *hdl;
+ char order; // 1 表示 正序, 非1 表示反序
+ u8 inited;
+ u8 hide_byself;
+ u8 item_num;
+ u8 highlight;
+ u8 show_mode;
+ u16 cur_number;
+ u16 file_number;
+ struct ui_grid *grid;
+ const char *path;
+ const char *ftype;
+ const struct ui_browser_info *info;
+ const struct element_event_handler *handler;
+};
+
+
+#define ui_file_browser_cur_item(bro) ui_grid_cur_item(((struct ui_browser *)bro)->grid)
+
+
+int ui_file_browser_page_num(struct ui_browser *bro);
+
+int ui_file_browser_cur_page(struct ui_browser *bro, int *file_num);
+
+int ui_file_browser_set_page(struct ui_browser *bro, int page);
+
+int ui_file_browser_set_page_by_id(int id, int page);
+
+int ui_file_browser_next_page(struct ui_browser *bro);
+
+int ui_file_browser_next_page_by_id(int id);
+
+int ui_file_browser_prev_page(struct ui_browser *bro);
+
+int ui_file_browser_prev_page_by_id(int id);
+
+int ui_file_browser_set_dir(struct ui_browser *bro, const char *path, const char *ftype);
+
+int ui_file_browser_set_dir_by_id(int id, const char *path, const char *ftype);
+
+int ui_file_browser_get_file_attrs(struct ui_browser *bro, int item,
+ struct ui_file_attrs *attrs);
+
+int ui_file_browser_set_file_attrs(struct ui_browser *bro, int item,
+ struct ui_file_attrs *attrs);
+
+void *ui_file_browser_open_file(struct ui_browser *bro, int item);
+
+
+int ui_file_browser_del_file(struct ui_browser *bro, int item);
+
+int ui_file_browser_highlight_item(struct ui_browser *bro, int item, bool yes);
+
+void *ui_file_browser_get_child_by_id(struct ui_browser *bro, int item, int id);
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#endif
diff --git a/include_lib/system/ui/ui/ui_button.h b/include_lib/system/ui/ui/ui_button.h
new file mode 100644
index 0000000..762d2e7
--- /dev/null
+++ b/include_lib/system/ui/ui/ui_button.h
@@ -0,0 +1,20 @@
+#ifndef UI_BUTTON_H
+#define UI_BUTTON_H
+
+
+#include "ui/control.h"
+#include "ui/ui_core.h"
+
+struct button {
+ struct element elm;
+ u8 image_index;
+ u8 css_num;
+ u32 css[2];
+ const struct ui_button_info *info;
+ const struct element_event_handler *handler;
+};
+
+void ui_button_enable();
+
+#endif
+
diff --git a/include_lib/system/ui/ui/ui_camera.h b/include_lib/system/ui/ui/ui_camera.h
new file mode 100644
index 0000000..f29f044
--- /dev/null
+++ b/include_lib/system/ui/ui/ui_camera.h
@@ -0,0 +1,34 @@
+#ifndef UI_CAMERA_H
+#define UI_CAMERA_H
+
+#include "ui/control.h"
+#include "ui/ui_core.h"
+
+
+
+
+
+
+struct ui_camera {
+ struct element elm; //must be first
+ int fd;
+ const struct ui_camera_info *info;
+ const struct element_event_handler *handler;
+};
+
+
+
+#define ui_camera_for_id(id) \
+ (struct ui_camera*)ui_core_get_element_by_id(id)
+
+
+
+void register_ui_camera_handler(const struct element_event_handler *handler);
+
+int ui_camera_set_rect(int id, struct rect *r);
+
+
+
+
+#endif
+
diff --git a/include_lib/system/ui/ui/ui_core.h b/include_lib/system/ui/ui/ui_core.h
new file mode 100644
index 0000000..431ea37
--- /dev/null
+++ b/include_lib/system/ui/ui/ui_core.h
@@ -0,0 +1,566 @@
+#ifndef UI_ELEMENT_CORE_H
+#define UI_ELEMENT_CORE_H
+
+#include "typedef.h"
+#include "rect.h"
+#include "system/event.h"
+// #include "fs/fs.h"
+#include "res/resfile.h"
+
+
+#define UI_CTRL_BUTTON 0
+
+struct element;
+
+
+#ifdef offsetof
+#undef offsetof
+#endif
+#ifdef container_of
+#undef container_of
+#endif
+
+#define offsetof(type, memb) \
+((unsigned long)(&((type *)0)->memb))
+
+#define container_of(ptr, type, memb) \
+((type *)((char *)ptr - offsetof(type, memb)))
+
+enum ui_direction {
+ UI_DIR_UP,
+ UI_DIR_DOWN,
+ UI_DIR_LEFT,
+ UI_DIR_RIGHT,
+};
+
+enum ui_align {
+ UI_ALIGN_LEFT = 0,
+ UI_ALIGN_CENTER,
+ UI_ALIGN_RIGHT,
+};
+
+
+enum {
+ POSITION_ABSOLUTE = 0,
+ POSITION_RELATIVE = 1,
+};
+
+enum {
+ ELM_EVENT_TOUCH_DOWN,
+ ELM_EVENT_TOUCH_MOVE,
+ ELM_EVENT_TOUCH_R_MOVE,
+ ELM_EVENT_TOUCH_L_MOVE,
+ ELM_EVENT_TOUCH_D_MOVE,
+ ELM_EVENT_TOUCH_U_MOVE,
+ ELM_EVENT_TOUCH_HOLD,
+ ELM_EVENT_TOUCH_UP,
+};
+
+
+enum {
+ ELM_EVENT_KEY_CLICK,
+ ELM_EVENT_KEY_LONG,
+ ELM_EVENT_KEY_HOLD,
+};
+
+enum {
+ ELM_STA_INITED,
+ //ELM_STA_SHOW_PROBE,
+ //ELM_STA_SHOW_POST,
+ ELM_STA_HIDE,
+ ELM_STA_SHOW,
+ ELM_STA_PAUSE,
+};
+
+enum {
+ ELM_FLAG_NORMAL,
+ ELM_FLAG_HEAD,
+};
+
+enum {
+ DC_DATA_FORMAT_OSD8 = 0,
+ DC_DATA_FORMAT_YUV420 = 1,
+ DC_DATA_FORMAT_OSD16 = 2,
+ DC_DATA_FORMAT_OSD8A = 3,
+ DC_DATA_FORMAT_MONO = 4,
+};
+
+
+struct element_touch_event {
+ int event;
+ int xoffset;
+ int yoffset;
+ u8 hold_up;
+ u8 onfocus;
+ u8 move_dir;
+ struct position pos;
+ struct position mov;
+ void *private_data;
+};
+
+struct element_key_event {
+ u8 event;
+ u8 value;
+ void *private_data;
+};
+
+#define ELM_KEY_EVENT(e) (0x0000 | (e->event) | (e->value << 8))
+#define ELM_TOUCH_EVENT(e) (0x1000 | (e->event))
+#define ELM_CHANGE_EVENT(e) (0x2000 | (e->event))
+
+enum element_change_event {
+ ON_CHANGE_INIT_PROBE,
+ ON_CHANGE_INIT,
+ ON_CHANGE_TRY_OPEN_DC,
+ ON_CHANGE_FIRST_SHOW,
+ ON_CHANGE_SHOW_PROBE,
+ ON_CHANGE_SHOW,
+ ON_CHANGE_SHOW_POST,
+ ON_CHANGE_HIDE,
+ ON_CHANGE_HIGHLIGHT,
+ ON_CHANGE_RELEASE_PROBE,
+ ON_CHANGE_RELEASE,
+ ON_CHANGE_ANIMATION_END,
+ ON_CHANGE_SHOW_COMPLETED,
+ ON_CHANGE_UPDATE_ITEM,
+};
+
+
+struct element_event_handler {
+ int id;
+ int (*ontouch)(void *, struct element_touch_event *);
+ int (*onkey)(void *, struct element_key_event *);
+ int (*onchange)(void *, enum element_change_event, void *);
+};
+
+struct jaction {
+ u32 show;
+ u32 hide;
+};
+
+enum {
+ ELM_ACTION_HIDE = 0,
+ ELM_ACTION_SHOW,
+ ELM_ACTION_TOGGLE,
+ ELM_ACTION_HIGHLIGHT,
+};
+
+struct event_action {
+ u16 event;
+ u16 action;
+ int id;
+ u8 argc;
+ char argv[];
+};
+
+struct element_event_action {
+ u16 num;
+ struct event_action action[0];
+};
+
+struct image_preview {
+ RESFILE *file;
+ int id;
+ int page;
+};
+
+
+struct image {
+ int x;
+ int y;
+ int id;
+ int page;
+ int en;
+};
+
+struct draw_context {
+ u8 ref;
+ u8 alpha;
+ u8 align;
+ u8 data_format;
+ u8 prj;
+ u8 page;
+ u8 buf_num;
+ u32 background_color;
+ void *handl;
+ struct element *elm;
+ struct rect rect;
+ struct rect draw;
+ void *dc;
+
+ struct image_preview preview;
+
+ struct rect need_draw;
+ struct rect disp;
+ u16 width;
+ u16 height;
+ u8 *fbuf;
+ u32 fbuf_len;
+ u8 *buf;
+ u8 *buf0;
+ u8 *buf1;
+ u32 len;
+ u16 lines;
+ u8 col_align;
+ u8 row_align;
+
+ struct image draw_img;
+
+ u8 *mask;
+};
+
+struct css_border {
+ u16 left: 4;
+ u16 top: 4;
+ u16 right: 4;
+ u16 bottom: 4;
+ u16 color: 16;
+};
+
+struct css_border1 {
+ u8 left;
+ u8 top;
+ u8 right;
+ u8 bottom;
+ int color: 24;
+};
+
+struct element_css {
+ u8 align: 2;
+ u8 invisible: 1;
+ u8 z_order: 5;
+ int left/* : 16 */;
+ int top/* : 16 */;
+ int width/* : 16 */;
+ int height/* : 16 */;
+ u32 background_color: 24;
+ u32 alpha: 8;
+ int background_image: 24;
+ int image_quadrant: 8;
+ struct css_border border;
+};
+
+struct element_css1 {
+ u8 align;
+ u8 invisible;
+ u8 z_order;
+ int left;
+ int top;
+ int width;
+ int height;
+ u32 background_color: 24;
+ u32 alpha: 8;
+ int background_image: 24;
+ int image_quadrant: 8;
+ struct css_border1 border;
+};
+
+struct element_ops {
+ int (*show)(struct element *);
+ int (*redraw)(struct element *, struct rect *);
+};
+
+struct element {
+ u32 highlight: 1;
+ u32 state: 2;
+ u32 ref: 5;
+ u32 prj: 3;
+ u32 page: 21;
+ // u32 alive;
+ int id;
+ struct element *parent;
+ struct list_head sibling;
+ struct list_head child;
+ struct element *focus;
+ struct element_css css;
+ struct draw_context *dc;
+ // const struct element_ops *ops;
+ const struct element_event_handler *handler;
+ // const struct element_event_action *action;
+};
+
+struct ui_style {
+ const char *file;
+ u32 version;
+};
+
+enum {
+ UI_FTYPE_VIDEO = 0,
+ UI_FTYPE_IMAGE,
+ UI_FTYPE_AUDIO,
+ UI_FTYPE_DIR,
+ UI_FTYPE_UNKNOW = 0xff,
+};
+
+struct ui_file_attrs {
+ char *format;
+ char fname[128];
+ struct vfs_attr attr;
+ u8 ftype;
+ u16 file_num;
+ u32 film_len;
+};
+
+struct ui_image_attrs {
+ u16 width;
+ u16 height;
+};
+
+struct ui_text_attrs {
+ const char *str;
+ const char *format;
+ int color;
+ u16 strlen;
+ u16 offset;
+ u8 encode: 2;
+ u8 endian: 1;
+ u8 flags: 5;
+ // u16 offset;
+ u16 displen;
+};
+
+struct ui_file_browser {
+ int file_number;
+ u8 dev_num;
+ void *private_data;
+};
+
+#define ELEMENT_ALIVE 0x53547a7b
+
+#define element_born(elm) \
+ elm->alive = ELEMENT_ALIVE
+
+#define element_alive(elm) \
+ (elm->alive == ELEMENT_ALIVE)
+
+
+#define list_for_each_child_element(p, elm) \
+ list_for_each_entry(p, &(elm)->child, sibling)
+
+#define list_for_each_child_element_reverse(p, n, elm) \
+ list_for_each_entry_reverse_safe(p, n, &(elm)->child, sibling)
+
+#define list_for_each_child_element_safe(p, n, elm) \
+ list_for_each_entry_safe(p, n, &(elm)->child, sibling)
+
+struct ui_platform_api {
+ void *(*malloc)(int);
+ void (*free)(void *);
+
+ int (*load_style)(struct ui_style *);
+
+ void *(*load_window)(int id);
+ void (*unload_window)(void *);
+
+ int (*open_draw_context)(struct draw_context *);
+ int (*get_draw_context)(struct draw_context *);
+ int (*put_draw_context)(struct draw_context *);
+ int (*set_draw_context)(struct draw_context *);
+ int (*close_draw_context)(struct draw_context *);
+
+ int (*fill_rect)(struct draw_context *, u32 color);
+ int (*draw_rect)(struct draw_context *, struct css_border *border);
+ int (*draw_image)(struct draw_context *, u32 src, u8 quadrant, u8 *mask);
+ int (*draw_point)(struct draw_context *, u16 x, u16 y, u32 color);
+ u32(*read_point)(struct draw_context *dc, u16 x, u16 y);
+ int (*invert_rect)(struct draw_context *, u32 color);
+
+ void *(*load_widget_info)(void *_head, u8 page);
+ void *(*load_css)(u8 page, void *_css);
+ void *(*load_image_list)(u8 page, void *_list);
+ void *(*load_text_list)(u8 page, void *__list);
+
+ //int (*highlight)(struct draw_context *);
+ int (*show_text)(struct draw_context *, struct ui_text_attrs *);
+ int (*read_image_info)(struct draw_context *, u32, u8, struct ui_image_attrs *);
+
+ int (*open_device)(struct draw_context *, const char *device);
+ int (*close_device)(int);
+
+ void *(*set_timer)(void *, void (*callback)(void *), u32 msec);
+ int (*del_timer)(void *);
+
+ struct ui_file_browser *(*file_browser_open)(struct rect *r,
+ const char *path, const char *ftype, int show_mode);
+
+ int (*get_file_attrs)(struct ui_file_browser *, struct ui_file_attrs *attrs);
+
+ int (*set_file_attrs)(struct ui_file_browser *, struct ui_file_attrs *attrs);
+
+ int (*clear_file_preview)(struct ui_file_browser *, struct rect *r);
+
+ int (*show_file_preview)(struct ui_file_browser *, struct rect *r, struct ui_file_attrs *attrs);
+
+ int (*flush_file_preview)(struct ui_file_browser *);
+
+ void *(*open_file)(struct ui_file_browser *, struct ui_file_attrs *attrs);
+ int (*delete_file)(struct ui_file_browser *, struct ui_file_attrs *attrs);
+
+ int (*move_file_preview)(struct ui_file_browser *_bro, struct rect *dst, struct rect *src);
+
+ void (*file_browser_close)(struct ui_file_browser *);
+
+};
+
+extern /* const */ struct ui_platform_api *platform_api;
+
+extern /* const */ struct element_event_handler dumy_handler;
+
+struct janimation {
+ u8 persent[5];
+ u8 direction;
+ u8 play_state;
+ u8 iteration_count;
+ u16 delay;
+ u16 duration;
+ struct element_css css[0];
+};
+
+
+extern struct element_event_handler *elm_event_handler_begin;
+extern struct element_event_handler *elm_event_handler_end;
+
+
+#define ___REGISTER_UI_EVENT_HANDLER(style, _id) \
+ static const struct element_event_handler element_event_handler_##_id \
+ sec(.elm_event_handler_##style) __attribute__((used)) = { \
+ .id = _id,
+
+#define __REGISTER_UI_EVENT_HANDLER(style, _id) \
+ ___REGISTER_UI_EVENT_HANDLER(style, _id)
+
+#define REGISTER_UI_EVENT_HANDLER(id) \
+ __REGISTER_UI_EVENT_HANDLER(STYLE_NAME, id)
+
+
+
+struct ui_style_info {
+ const char *name;
+ struct element_event_handler *begin;
+ struct element_event_handler *end;
+};
+
+extern struct ui_style_info ui_style_begin[];
+extern struct ui_style_info ui_style_end[];
+
+#define __REGISTER_UI_STYLE(style_name) \
+ extern struct element_event_handler elm_event_handler_begin_##style_name[]; \
+ extern struct element_event_handler elm_event_handler_end_##style_name[]; \
+ static const struct ui_style_info ui_style_##style_name sec(.ui_style) __attribute__((used)) = { \
+ .name = #style_name, \
+ .begin = elm_event_handler_begin_##style_name, \
+ .end = elm_event_handler_end_##style_name, \
+ };
+
+#define REGISTER_UI_STYLE(style_name) \
+ __REGISTER_UI_STYLE(style_name)
+
+
+static inline struct element_event_handler *element_event_handler_for_id(u32 id)
+{
+ struct element_event_handler *p;
+
+ for (p = elm_event_handler_begin; p < elm_event_handler_end; p++) {
+ if (p->id == id) {
+ return p;
+ }
+ }
+
+ return NULL;
+}
+
+
+
+
+#define ui_core_get_element_css(elm) \
+ &((struct element *)(elm))->css
+
+#define ui_core_element_invisable(elm, i) \
+ ((struct element *)(elm))->css.invisible = i
+
+
+int ui_core_init(const struct ui_platform_api *api, struct rect *rect);
+
+int ui_core_set_style(const char *style);
+
+void ui_core_set_rotate(int _rotate);
+
+int ui_core_get_rotate();
+
+
+void *ui_core_malloc(int size);
+
+void ui_core_free(void *buf);
+
+void ui_core_element_init(struct element *,
+ u32 id,
+ u8 page,
+ u8 prj,
+ /* const */ struct element_css1 *,
+ const struct element_event_handler *,
+ const struct element_event_action *);
+
+void ui_core_get_element_abs_rect(struct element *elm, struct rect *rect);
+
+void ui_core_append_child(void *_child);
+
+struct element *ui_core_get_first_child();
+
+void ui_core_remove_element(void *_child);
+
+
+int ui_core_open_draw_context(struct draw_context *dc, struct element *elm);
+
+int ui_core_close_draw_context(struct draw_context *dc);
+
+int ui_core_show(void *_elm, int init);
+
+int ui_core_hide(void *_elm);
+
+struct element *get_element_by_id(struct element *elm, u32 id);
+
+struct element *ui_core_get_element_by_id(u32 id);
+int ui_core_get_disp_status_by_id(u32 id);
+
+struct element *ui_core_get_up_element(struct element *elm);
+struct element *ui_core_get_down_element(struct element *elm);
+struct element *ui_core_get_left_element(struct element *elm);
+struct element *ui_core_get_right_element(struct element *elm);
+
+int ui_core_element_ontouch(struct element *, struct element_touch_event *e);
+
+int ui_core_ontouch(struct element_touch_event *e);
+
+int ui_core_element_onkey(struct element *elm, struct element_key_event *e);
+
+int ui_core_onkey(struct element_key_event *e);
+
+void ui_core_element_append_child(struct element *parent, struct element *child);
+
+struct element_css *ui_core_set_element_css(void *_elm, const struct element_css1 *css);
+
+int ui_core_invert_rect(struct draw_context *dc);
+
+void ui_core_release_child_probe(struct element *elm);
+
+void ui_core_release_child(struct element *elm);
+
+
+int ui_core_redraw(void *_elm);
+
+int ui_core_highlight_element(struct element *elm, int yes);
+
+void ui_core_element_on_focus(struct element *elm, int yes);
+
+
+void ui_core_ontouch_lose_focus(struct element *elm);
+
+void ui_core_ontouch_lock(struct element *elm);
+
+void ui_core_ontouch_unlock(struct element *elm);
+
+int ui_core_get_draw_context(struct draw_context *dc, struct element *elm, struct rect *draw);
+#endif
+
+
+
diff --git a/include_lib/system/ui/ui/ui_grid.h b/include_lib/system/ui/ui/ui_grid.h
new file mode 100644
index 0000000..aab744f
--- /dev/null
+++ b/include_lib/system/ui/ui/ui_grid.h
@@ -0,0 +1,149 @@
+#ifndef UI_GRID_H
+#define UI_GRID_H
+
+
+#include "ui/ui_core.h"
+#include "ui/control.h"
+
+enum {
+ GRID_SCROLL_MODE,
+ GRID_PAGE_MODE,
+};
+
+enum {
+ SCROLL_DIRECTION_NONE,
+ SCROLL_DIRECTION_LR,
+ SCROLL_DIRECTION_UD,
+};
+
+struct ui_grid_item_info {
+ u8 row;
+ u8 col;
+ u8 page_mode;
+ u8 highlight_index;
+ u16 interval;
+ struct layout_info *info;
+};
+
+struct scroll_area {
+ int left;
+ int top;
+ int right;
+ int bottom;
+};
+
+
+struct ui_grid_dynamic {
+ int dhi_index;
+ int dcol_num;
+ int drow_num;
+
+ int min_row_index;
+ int max_row_index;
+ int min_col_index;
+ int max_col_index;
+ int min_show_row_index;
+ int max_show_row_index;
+ int min_show_col_index;
+ int max_show_col_index;
+
+ int grid_xval;
+ int grid_yval;
+ u8 grid_col_num;
+ u8 grid_row_num;
+ u8 grid_show_row;
+ u8 grid_show_col;
+ int base_index_once;
+};
+
+struct ui_grid {
+ struct element elm;
+ // char hi_num;
+ char hi_index;
+ char touch_index;
+ char onfocus;
+ u8 page_mode;
+ u8 slide_direction;
+ u8 col_num;
+ u8 row_num;
+ u8 show_row;
+ u8 show_col;
+ u8 avail_item_num;
+ u8 pix_scroll;
+ u8 ctrl_num;
+ // u8 rotate;
+ int x_interval;
+ int y_interval;
+ int max_show_left;
+ int max_show_top;
+ int min_show_left;
+ int min_show_top;
+ int max_left;
+ int max_top;
+ int min_left;
+ int min_top;
+ // int scroll_step;
+ // u8 ctrl_num;
+ struct scroll_area *area;
+ struct layout *item;
+ struct layout_info *item_info;
+ // struct element elm2;
+ struct ui_grid_dynamic *dynamic;
+ struct position pos;
+ struct draw_context dc;
+ const struct ui_grid_info *info;
+ const struct element_event_handler *handler;
+};
+
+extern const struct element_event_handler grid_elm_handler;
+
+static inline int ui_grid_cur_item(struct ui_grid *grid)
+{
+ if (grid->touch_index >= 0) {
+ return grid->touch_index;
+ }
+ return grid->hi_index;
+}
+
+#define ui_grid_set_item(grid, index) (grid)->hi_index = index
+
+void ui_grid_enable();
+void ui_grid_on_focus(struct ui_grid *grid);
+void ui_grid_lose_focus(struct ui_grid *grid);
+void ui_grid_state_reset(struct ui_grid *grid, int highlight_item);
+int ui_grid_highlight_item(struct ui_grid *grid, int item, bool yes);
+int ui_grid_highlight_item_by_id(int id, int item, bool yes);
+struct ui_grid *__ui_grid_new(struct element_css1 *css, int id, struct ui_grid_item_info *info, struct element *parent);
+int ui_grid_slide(struct ui_grid *grid, int direction, int steps);
+int ui_grid_set_item_num(struct ui_grid *grid, int item_num);
+int ui_grid_set_slide_direction(struct ui_grid *grid, int dir);
+int ui_grid_slide_with_callback(struct ui_grid *grid, int direction, int steps, void(*callback)(void *ctrl));
+
+int ui_grid_dynamic_slide(struct ui_grid *grid, int direction, int steps);//动态列表滚动
+int ui_grid_dynamic_create(struct ui_grid *grid, int direction, int list_total, int (*event_handler_cb)(void *, int, int, int)); //动态列表创建
+int ui_grid_dynamic_release(struct ui_grid *grid);//动态列表释放
+
+int ui_grid_dynamic_cur_item(struct ui_grid *grid);//动态列表获取选项
+int ui_grid_dynamic_set_item_by_id(int id, int count);//修改动态列表数
+int ui_grid_dynamic_reset(struct ui_grid *grid, int index); //重置动态列表
+void ui_grid_set_scroll_area(struct ui_grid *grid, struct scroll_area *area);
+
+int ui_grid_init_dynamic(struct ui_grid *grid, int *row, int *col);
+int ui_grid_add_dynamic(struct ui_grid *grid, int *row, int *col, int redraw);
+int ui_grid_del_dynamic(struct ui_grid *grid, int *row, int *col, int redraw);
+int ui_grid_set_hi_index(struct ui_grid *grid, int hi_index);
+int ui_grid_set_pix_scroll(struct ui_grid *grid, int enable);
+int ui_grid_get_hindex(struct ui_grid *grid);
+int ui_grid_set_hindex_dynamic(struct ui_grid *grid, int dhindex, int init, int hi_index);
+int ui_grid_get_hindex_dynamic(struct ui_grid *grid);
+int ui_grid_set_base_dynamic(struct ui_grid *grid, u32 base_index_once);
+// int ui_grid_update_by_id_dynamic(int id, int redraw);
+int ui_grid_update_by_id_dynamic(int id, int item_sel, int redraw);
+int ui_grid_add_dynamic_by_id(int id, int *row, int *col, int redraw);
+int ui_grid_del_dynamic_by_id(int id, int *row, int *col, int redraw);
+int ui_grid_cur_item_dynamic(struct ui_grid *grid);
+
+#endif
+
+
+
diff --git a/include_lib/system/ui/ui/ui_number.h b/include_lib/system/ui/ui/ui_number.h
new file mode 100644
index 0000000..7cc1a2a
--- /dev/null
+++ b/include_lib/system/ui/ui/ui_number.h
@@ -0,0 +1,44 @@
+#ifndef UI_NUMBER_H
+#define UI_NUMBER_H
+
+
+#include "ui/control.h"
+#include "ui/ui_core.h"
+#include "ui/p.h"
+
+enum {
+ TYPE_NUM,
+ TYPE_STRING,
+};
+
+struct unumber {
+ u8 numbs;
+ u8 type;
+ u32 number[2];
+ u8 *num_str;
+};
+
+struct ui_number {
+ struct element_text text;
+ char source[8];
+ u16 number[2];
+ u16 buf[20];
+
+ int color;
+ int hi_color;
+ u8 css_num;
+ u8 nums: 6;
+ u8 type: 2;
+ u32 css[2];
+ u8 *num_str;
+ const struct ui_number_info *info;
+ const struct element_event_handler *handler;
+};
+
+void ui_number_enable();
+void *new_ui_number(const void *_info, struct element *parent);
+int ui_number_update(struct ui_number *number, struct unumber *n);
+int ui_number_update_by_id(int id, struct unumber *n);
+
+#endif
+
diff --git a/include_lib/system/ui/ui/ui_pic.h b/include_lib/system/ui/ui/ui_pic.h
new file mode 100644
index 0000000..38a6463
--- /dev/null
+++ b/include_lib/system/ui/ui/ui_pic.h
@@ -0,0 +1,30 @@
+#ifndef UI_PIC_H
+#define UI_PIC_H
+
+#include "ui/ui_core.h"
+
+
+
+
+struct ui_pic {
+ struct element elm;
+ u8 index;
+ // u8 css_num:2;
+ // u32 css[2];
+ // u16 highlight_img;
+ // u16 normal_img;
+ // u16 highlight_img_num:8;
+ // u16 normal_img_num:8;
+ const struct ui_pic_info *info;
+ const struct element_event_handler *handler;
+};
+
+void ui_pic_enable();
+void *new_ui_pic(const void *_info, struct element *parent);
+int ui_pic_show_image_by_id(int id, int index);
+int ui_pic_set_image_index(struct ui_pic *pic, int index);
+int ui_pic_get_normal_image_number_by_id(int id);
+int ui_pic_get_highlgiht_image_number_by_id(int id);
+int ui_pic_set_hide_by_id(int id, int hide);
+
+#endif
diff --git a/include_lib/system/ui/ui/ui_progress.h b/include_lib/system/ui/ui/ui_progress.h
new file mode 100644
index 0000000..1e89f56
--- /dev/null
+++ b/include_lib/system/ui/ui/ui_progress.h
@@ -0,0 +1,48 @@
+#ifndef UI_PROGRESS_H
+#define UI_PROGRESS_H
+
+
+#include "ui/control.h"
+#include "ui/ui_core.h"
+
+
+#define PROGRESS_CHILD_NUM (CTRL_PROGRESS_CHILD_END - CTRL_PROGRESS_CHILD_BEGIN)
+
+
+struct progress_highlight_info {
+ struct ui_ctrl_info_head head;
+ u16 center_x;
+ u16 center_y;
+ u16 radius_big;
+ u16 radius_small;
+ u16 angle_begin;
+ u16 angle_end;
+ struct ui_image_list *img;
+};
+
+struct ui_progress {
+ struct element elm;
+ struct element child_elm[PROGRESS_CHILD_NUM];
+ char source[8];
+ u16 center_x;
+ u16 center_y;
+ u16 radius;
+ u16 angle_begin;
+ u16 angle_end;
+ u8 ctrl_num;
+ char percent;
+ u8 *mask;
+ u16 mask_len;
+ void *timer;
+ const struct layout_info *info;
+ const struct progress_highlight_info *pic_info[PROGRESS_CHILD_NUM];
+ const struct element_event_handler *handler;
+};
+
+void ui_progress_enable();
+int ui_progress_set_persent_by_id(int id, int persent);
+int ui_progress_set_persent(struct ui_progress *progress, int percent);
+
+#endif
+
+
diff --git a/include_lib/system/ui/ui/ui_progress_multi.h b/include_lib/system/ui/ui/ui_progress_multi.h
new file mode 100644
index 0000000..bca15d9
--- /dev/null
+++ b/include_lib/system/ui/ui/ui_progress_multi.h
@@ -0,0 +1,59 @@
+#ifndef UI_PROGRESS_MULTI_H
+#define UI_PROGRESS_MULTI_H
+
+
+#include "ui/control.h"
+#include "ui/ui_core.h"
+
+
+#define MULTIPROGRESS_CHILD_NUM (CTRL_MULTIPROGRESS_CHILD_END - CTRL_MULTIPROGRESS_CHILD_BEGIN)
+
+struct multiprogress_highlight_info {
+ struct ui_ctrl_info_head head;
+ u16 number;
+ u16 center_x;
+ u16 center_y;
+ u16 radius0_big;
+ u16 radius0_small;
+ u16 radius1_big;
+ u16 radius1_small;
+ u16 radius2_big;
+ u16 radius2_small;
+ u16 angle_begin;
+ u16 angle_end;
+ struct ui_image_list *img;
+};
+
+struct ui_multiprogress {
+ struct element elm;
+ struct element child_elm[MULTIPROGRESS_CHILD_NUM];
+ char source[8];
+ u16 center_x;
+ u16 center_y;
+ u16 radius;
+ u16 angle_begin;
+ u16 angle_end;
+ u8 ctrl_num;
+ char percent[3];
+ u8 circle_num;
+ u8 index;
+ u8 *mask;
+ u16 mask_len;
+ void *timer;
+ const struct layout_info *info;
+ const struct multiprogress_highlight_info *pic_info[MULTIPROGRESS_CHILD_NUM];
+ const struct element_event_handler *handler;
+};
+
+void ui_multiprogress_enable();
+int ui_multiprogress_set_persent_by_id(int id, int persent);
+int ui_multiprogress_set_second_persent_by_id(int id, int percent);
+int ui_multiprogress_set_third_persent_by_id(int id, int percent);
+
+int ui_multiprogress_set_persent(struct ui_multiprogress *multiprogress, int percent);
+int ui_multiprogress_set_second_persent(struct ui_multiprogress *multiprogress, int percent);
+int ui_multiprogress_set_third_persent(struct ui_multiprogress *multiprogress, int percent);
+
+#endif
+
+
diff --git a/include_lib/system/ui/ui/ui_rotate.h b/include_lib/system/ui/ui/ui_rotate.h
new file mode 100644
index 0000000..981f471
--- /dev/null
+++ b/include_lib/system/ui/ui/ui_rotate.h
@@ -0,0 +1,11 @@
+#ifndef __UI_ROTATE_H__
+#define __UI_ROTATE_H__
+
+#include "rect.h"
+
+void rotate_0(unsigned char *src, unsigned char *src1, int sw, int sh, int cx, int cy, unsigned char *dst, int dw, int dh, int dx, int dy, struct rect *rect, int angle);
+void rotate_1(unsigned char *tmp, unsigned char *src, int sw, int sh, int cx, int cy, unsigned char *dst, int dw, int dh, int dx, int dy, struct rect *rect, int angle);
+void rotate_map(int sw, int sh, int scx, int scy, int *dw, int *dh, int dcx, int dcy, int angle);
+
+#endif
+
diff --git a/include_lib/system/ui/ui/ui_slider.h b/include_lib/system/ui/ui/ui_slider.h
new file mode 100644
index 0000000..6dfede0
--- /dev/null
+++ b/include_lib/system/ui/ui/ui_slider.h
@@ -0,0 +1,43 @@
+#ifndef UI_SLIDER_H
+#define UI_SLIDER_H
+
+#include "ui/ui_core.h"
+#include "ui/control.h"
+
+
+#define SLIDER_CHILD_NUM (SLIDER_CHILD_END - SLIDER_CHILD_BEGIN)
+
+
+struct slider_text_info {
+ u8 move;
+ int min_value;
+ int max_value;
+ int text_color;
+};
+
+
+struct ui_slider {
+ struct element elm;
+ struct element child_elm[SLIDER_CHILD_NUM];
+ u8 step;
+ char persent;
+ s16 left;
+ s16 width;
+ s16 min_value;
+ s16 max_value;
+ u16 text_color;
+ const struct ui_slider_info *info;
+ const struct slider_text_info *text_info;
+ const struct element_event_handler *handler;
+};
+
+void ui_slider_enable();
+int ui_slider_set_persent_by_id(int id, int persent);
+int ui_slider_set_persent(struct ui_slider *slider, int persent);
+
+int slider_touch_slider_move(struct ui_slider *slider, struct element_touch_event *e);//触摸滑动功能
+
+int slider_get_percent(struct ui_slider *slider);
+
+#endif
+
diff --git a/include_lib/system/ui/ui/ui_slider_vert.h b/include_lib/system/ui/ui/ui_slider_vert.h
new file mode 100644
index 0000000..7fb7fc0
--- /dev/null
+++ b/include_lib/system/ui/ui/ui_slider_vert.h
@@ -0,0 +1,41 @@
+#ifndef UI_SLIDER_VERT_H
+#define UI_SLIDER_VERT_H
+
+#include "ui/ui_core.h"
+#include "ui/control.h"
+
+#define VSLIDER_CHILD_NUM (VSLIDER_CHILD_END - VSLIDER_CHILD_BEGIN)
+
+struct vslider_text_info {
+ u8 move;
+ int min_value;
+ int max_value;
+ int text_color;
+};
+
+
+struct ui_vslider {
+ struct element elm;
+ struct element child_elm[VSLIDER_CHILD_NUM];
+ u8 step;
+ char persent;
+ s16 top;
+ s16 height;
+ u16 min_value;
+ u16 max_value;
+ u16 text_color;
+ const struct ui_slider_info *info;
+ const struct vslider_text_info *text_info;
+ const struct element_event_handler *handler;
+};
+
+
+void ui_vslider_enable();
+int ui_vslider_set_persent_by_id(int id, int persent);
+int ui_vslider_set_persent(struct ui_vslider *vslider, int persent);
+
+int vslider_touch_slider_move(struct ui_vslider *vslider, struct element_touch_event *e);//触摸滑动功能
+
+int vslider_get_percent(struct ui_vslider *vslider);
+#endif
+
diff --git a/include_lib/system/ui/ui/ui_text.h b/include_lib/system/ui/ui/ui_text.h
new file mode 100644
index 0000000..8761121
--- /dev/null
+++ b/include_lib/system/ui/ui/ui_text.h
@@ -0,0 +1,56 @@
+#ifndef UI_TEXT_H
+#define UI_TEXT_H
+
+#include "ui/ui_core.h"
+#include "ui/control.h"
+#include "font/font_all.h"
+
+
+struct ui_text {
+ struct element elm;
+ struct ui_text_attrs attrs;
+ char source[8];
+ u16 timer;
+ u16 _str[UI_TEXT_LIST_MAX_NUM];
+ char _format[7];
+ u8 str_num;
+ u8 index;
+ // u8 str_num:4;
+ // u8 css_num:4;
+ // u32 css[2];
+ // u16 attr_color;
+ // u16 attr_highlight_color;
+ // struct ui_text_attrs attrs;
+ const struct ui_text_info *info;
+ const struct element_event_handler *handler;
+};
+
+
+
+void ui_text_enable();
+void *new_ui_text(const void *_info, struct element *parent);
+/*api of format 'ascii'*/
+int ui_text_set_str(struct ui_text *text, const char *format, const char *str, int strlen, u32 flags);
+int ui_text_set_str_by_id(int id, const char *format, const char *str);
+/*api of format 'strpic'*/
+int ui_text_set_index(struct ui_text *text, int index);
+int ui_text_show_index_by_id(int id, int index);
+/*api of format 'text'*/
+void ui_text_set_text_attrs(struct ui_text *text, const char *str, int strlen, u8 encode, u8 endian, u32 flags);
+int ui_text_set_text_by_id(int id, const char *str, int strlen, u32 flags);
+int ui_text_set_textw_by_id(int id, const char *str, int strlen, int endian, u32 flags);
+int ui_text_set_textu_by_id(int id, const char *str, int strlen, u32 flags);
+
+void text_release(struct ui_text *text);
+/*
+ * 注意:
+ * 1.store_buf必须是全局或者静态,不能是局部,大小为index_num+1
+ * 2.index_buf表示当前文本控件字符串id的序号,从0开始
+ * 3.index_num表示有多少个字符串id拼起来
+ * */
+int ui_text_set_combine_index(struct ui_text *text, u16 *store_buf, u8 *index_buf, int index_num);
+
+
+int ui_text_set_hide_by_id(int id, int hide);
+
+#endif
diff --git a/include_lib/system/ui/ui/ui_time.h b/include_lib/system/ui/ui/ui_time.h
new file mode 100644
index 0000000..e9f5bc2
--- /dev/null
+++ b/include_lib/system/ui/ui/ui_time.h
@@ -0,0 +1,44 @@
+#ifndef UI_TIME_H
+#define UI_TIME_H
+
+
+#include "ui/control.h"
+#include "ui/ui_core.h"
+#include "ui/p.h"
+
+struct utime {
+ u16 year;
+ u8 month;
+ u8 day;
+ u8 hour;
+ u8 min;
+ u8 sec;
+};
+
+struct ui_time {
+ struct element_text text;
+ char source[8];
+ u16 year: 12;
+ u16 month: 4;
+ u8 day;
+ u8 hour;
+ u8 min;
+ u8 sec;
+ u8 css_num;
+ u8 auto_cnt;
+ u32 css[2];
+ int color;
+ int hi_color;
+ u16 buf[20];
+ void *timer;
+ const struct ui_time_info *info;
+ const struct element_event_handler *handler;
+};
+
+void ui_time_enable();
+void *new_ui_time(const void *_info, struct element *parent);
+
+int ui_time_update(struct ui_time *time, struct utime *t);
+int ui_time_update_by_id(int id, struct utime *time);
+
+#endif
diff --git a/include_lib/system/ui/ui/ui_watch.h b/include_lib/system/ui/ui/ui_watch.h
new file mode 100644
index 0000000..dc8bc2d
--- /dev/null
+++ b/include_lib/system/ui/ui/ui_watch.h
@@ -0,0 +1,52 @@
+#ifndef UI_WATCH_H
+#define UI_WATCH_H
+
+
+#include "ui/control.h"
+#include "ui/ui_core.h"
+
+
+#define WATCH_CHILD_NUM (CTRL_WATCH_CHILD_END - CTRL_WATCH_CHILD_BEGIN)
+
+
+struct watch_pic_info {
+ struct ui_ctrl_info_head head;
+ u16 cent_x;
+ u16 cent_y;
+ struct ui_image_list *img;
+};
+
+struct watch_css_info {
+ int left: 16;
+ int top: 16;
+ int width: 16;
+ int height: 16;
+};
+
+struct ui_watch {
+ struct element elm;
+ struct element child_elm[WATCH_CHILD_NUM];
+ struct watch_css_info child_css[WATCH_CHILD_NUM];
+ char source[8];
+ u8 hour;
+ u8 min;
+ u8 sec;
+ u8 last_hour;
+ u8 last_min;
+ u8 last_sec;
+ u8 updata;
+ u8 ctrl_num;
+ void *timer;
+ const struct layout_info *info;
+ const struct watch_pic_info *pic_info[WATCH_CHILD_NUM];
+ const struct element_event_handler *handler;
+};
+
+
+void ui_watch_enable();
+int ui_watch_set_time_by_id(int id, int hour, int min, int sec);
+int ui_watch_set_time(struct ui_watch *watch, int hour, int min, int sec);
+
+#endif
+
+
diff --git a/include_lib/system/ui/ui/window.h b/include_lib/system/ui/ui/window.h
new file mode 100644
index 0000000..00a417a
--- /dev/null
+++ b/include_lib/system/ui/ui/window.h
@@ -0,0 +1,48 @@
+#ifndef UI_WINDOW_H
+#define UI_WINDOW_H
+
+
+#include "ui/layer.h"
+#include "ui/ui_core.h"
+#include "ui/control.h"
+#include "list.h"
+
+
+
+
+
+struct window {
+ struct element elm; //must be first
+ u8 busy;
+ u8 hide;
+ u8 ctrl_num;
+ struct list_head entry;
+ struct layer *layer;
+ const struct window_info *info;
+ const struct element_event_handler *handler;
+ void *private_data;
+};
+
+
+extern const struct window_info *window_table;
+
+
+
+#define REGISTER_WINDOW_EVENT_HANDLER(id) \
+ REGISTER_UI_EVENT_HANDLER(id)
+
+
+int window_show(int);
+
+int window_hide(int id);
+
+int window_toggle(int id);
+
+int window_ontouch(struct element_touch_event *e);
+
+int window_onkey(struct element_key_event *e);
+
+
+#endif
+
+
diff --git a/include_lib/system/ui/ui_simple/ui_res.h b/include_lib/system/ui/ui_simple/ui_res.h
new file mode 100644
index 0000000..b412b0f
--- /dev/null
+++ b/include_lib/system/ui/ui_simple/ui_res.h
@@ -0,0 +1,128 @@
+/*******************************************************************************************
+ File Name: ap_res.h
+
+ Version: 1.00
+
+ Discription:
+
+ Author:yulin deng
+
+ Email :flowingfeeze@163.com
+
+ Date:星期三, 六月 22 2011
+
+ Copyright:(c) 2011 @ , All Rights Reserved.
+*******************************************************************************************/
+#ifndef __ap_res_h
+#define __ap_res_h
+#include "typedef.h"
+
+/******************************************************************
+ ************************资源头的数据结构***************************
+ 资源结构:
+ 资源头 res_head
+ ------------------------------------------
+ 资源目录项 res_head_Item1(picture Item head)
+ res_head_Item2(string Item head)
+ res_head_Item3(multi-string Item head)
+ ------------------------------------------
+ 资源索引表 res_entry1(picture 1)
+ ................
+ res_entryN(picture N)
+ res_entry1(lang 1)
+ ................
+ res_entryN(lang N)
+ --------------------------------------------
+ 资源数据 picture data 1
+ ................
+ picture data N
+ Lang ID 1 entry
+ ................
+ Lang ID N entry
+ Lang 1 string data
+ ................
+ Lang N string data
+ ******************************************************************/
+#define RESHEADITEM 16 //各个entry长度,统一为16uint8s
+#define GROUPDEFINE 6
+#define ROW_COUNT_DEF 6
+#define TYPE_DIR 0
+#define TYPE_FILE 1
+
+
+#ifndef uint8
+#define uint8 u8
+#endif
+#ifndef uint16
+#define uint16 u16
+#endif
+#ifndef uint32
+#define uint32 u32
+#endif
+#ifndef int32
+#define int32 int
+#endif
+
+
+
+
+typedef struct {
+ uint8 magic[4]; //'R', 'U', '2', 0x19
+ uint16 counts; //资源的个数
+} res_head_t; //6 uint8s
+
+
+/*资源类型索引表的数据结构*/
+typedef struct {
+ uint32 dwOffset; //资源内容索引表的偏移
+ uint16 wCount; //资源类型总数
+ uint8 bItemType; //'P'--PIC Table,'S'--String Table,'X' -- XML File
+ uint8 type;
+} res_entry_t;
+
+/*资源内容信息索引的数据结构*/
+typedef struct {
+ uint16 wWidth; //若是图片,则代表图片宽,若是字符串,则代表ID总数
+ uint16 wHeight; //若是图片,则代表图片长,若是字符串,则代表该语言的ID.
+ uint32 bType; //资源类型,0x01--language string ,0x02--PIC
+ uint32 dwOffset; //图片数据区在文件内偏移,4 uint8s
+ uint32 dwLength; //资源长度, 最大 4G,4 uint8s
+} res_infor_t; //13 uint8s
+
+
+/*多国语言资源ID索引表的数据结构*/
+typedef struct {
+ uint32 dwOffset; // 字符ID号对应字符串编码在文件内的偏移
+ uint16 dwLength; // 字符串长度.即unicode编码字符串的字节数
+} res_langid_entry_t; // 6 uint8s
+
+typedef struct {
+ uint8 filetype; //文件类型 0-- 目录 1 文件
+ char name[12];
+ int32 DirEntry;
+} file_record_m;
+
+// extern res_entry_t res_entry;
+u8 ResOpen(const char *filename);
+void *ResGetFp();
+uint16 ResShowPic(uint16 pic_id, uint8 x, uint8 y);
+uint16 ResShowMultiString(uint8 x, uint8 y, uint16 StringID);
+void ResClose();
+u8 InitRes();
+
+
+
+
+#define LCDPAGE 8
+#define LCDCOLUMN 128
+#define SCR_WIDTH LCDCOLUMN
+#define SCR_HEIGHT (LCDPAGE*8)
+
+#define MENUICONWIDTH 12 //菜单项目左边图标的宽度(象素)
+#define MENUITEMHEIGHT 16 //菜单项目的高度(象素)
+#define SCROLLBARWIDTH 6 //垂直滚动条的宽度(象素)
+
+extern u8 LCDBuff[LCDPAGE][LCDCOLUMN];
+
+
+#endif
diff --git a/include_lib/system/user_cfg.h b/include_lib/system/user_cfg.h
new file mode 100644
index 0000000..429a29a
--- /dev/null
+++ b/include_lib/system/user_cfg.h
@@ -0,0 +1,122 @@
+#ifndef __USER_CFG_H__
+#define __USER_CFG_H__
+
+#include "typedef.h"
+#include "app_config.h"
+
+#define LOCAL_NAME_LEN 32 /*BD_NAME_LEN_MAX*/
+
+//bt bin结构
+typedef struct __BT_CONFIG {
+ u8 edr_name[LOCAL_NAME_LEN]; //经典蓝牙名
+ u8 mac_addr[6]; //蓝牙MAC地址
+ u8 rf_power; //发射功率
+ u8 dac_analog_gain; //通话DAC模拟增益
+ u8 mic_analog_gain; //通话MIC增益
+ u16 tws_device_indicate; /*设置对箱搜索标识,inquiry时候用,搜索到相应的标识才允许连接*/
+ u8 tws_local_addr[6];
+ u8 ble_name[LOCAL_NAME_LEN]; //ble蓝牙名
+ u8 ble_mac_addr[6]; //ble蓝牙MAC地址
+ u8 ble_rf_power; //ble发射功率
+} _GNU_PACKED_ BT_CONFIG;
+
+//audio bin结构
+typedef struct __AUDIO_CONFIG {
+ u8 sw;
+ u8 max_sys_vol; //最大系统音量
+ u8 default_vol; //开机默认音量
+ u8 tone_vol; //提示音音量
+} _GNU_PACKED_ AUDIO_CONFIG;
+
+//status bin结构体
+typedef struct __STATUS {
+ u8 charge_start; //开始充电
+ u8 charge_full; //充电完成
+ u8 power_on; //开机
+ u8 power_off; //关机
+ u8 lowpower; //低电
+ u8 max_vol; //最大音量
+ u8 phone_in; //来电
+ u8 phone_out; //去电
+ u8 phone_activ; //通话中
+ u8 bt_init_ok; //蓝牙初始化完成
+ u8 bt_connect_ok; //蓝牙连接成功
+ u8 bt_disconnect; //蓝牙断开
+ u8 tws_connect_ok; //TWS连接成功
+ u8 tws_disconnect; //TWS蓝牙断开
+} _GNU_PACKED_ STATUS;
+
+typedef struct __STATUS_CONFIG {
+ u8 sw;
+ STATUS led; //led status
+ STATUS tone; //tone status
+} _GNU_PACKED_ STATUS_CONFIG;
+
+//charge bin结构
+typedef struct __CHARGE_CONFIG {
+ u8 sw; //开关
+ u8 poweron_en; //支持开机充电
+ u8 full_v; //充满电压
+ u8 full_c; //充满电流
+ u8 charge_c; //充电电流
+} _GNU_PACKED_ CHARGE_CONFIG;
+
+//key
+typedef struct __KEY_OP {
+ u8 short_msg; //短按消息
+ u8 long_msg; //长按消息
+ u8 hold_msg; //hold 消息
+ u8 up_msg; //抬键消息
+ u8 double_msg; //双击消息
+ u8 triple_msg; //三击消息
+} _GNU_PACKED_ KEY_OP;
+
+//mic type
+typedef struct __MIC_TYPE_CONFIG {
+ u8 type; //0:不省电容模式 1:省电容模式
+ //1:16K 2:7.5K 3:5.1K 4:6.8K 5:4.7K 6:3.5K 7:2.9K 8:3K 9:2.5K 10:2.1K 11:1.9K 12:2K 13:1.8K 14:1.6K 15:1.5K 16:1K 31:0.6K
+ u8 pull_up;
+ //00:2.3v 01:2.5v 10:2.7v 11:3.0v
+ u8 ldo_lev;
+} _GNU_PACKED_ MIC_TYPE_CONFIG;
+
+
+
+//自动关机时间配置
+typedef struct __AUTO_OFF_TIME_CONFIG {
+ u8 auto_off_time;
+} _GNU_PACKED_ AUTO_OFF_TIME_CONFIG;
+
+//低电压提示配置
+typedef struct __AUTO_LOWPOWER_V_CONFIG {
+ u16 warning_tone_v;
+ u16 poweroff_tone_v;
+} _GNU_PACKED_ AUTO_LOWPOWER_V_CONFIG;
+
+//LRC配置
+typedef struct __LRC_CONFIG {
+ u16 lrc_ws_inc;
+ u16 lrc_ws_init;
+ u16 btosc_ws_inc;
+ u16 btosc_ws_init;
+ u8 lrc_change_mode;
+} _GNU_PACKED_ LRC_CONFIG;
+
+void cfg_file_parse(u8 idx);
+const u8 *bt_get_mac_addr();
+void bt_get_tws_local_addr(u8 *addr);
+
+STATUS *get_led_config(void);
+STATUS *get_tone_config(void);
+void get_random_number(u8 *ptr, u8 len);
+extern void bt_get_vm_mac_addr(u8 *addr);
+extern u8 get_max_sys_vol(void);
+extern const char *bt_get_local_name();
+extern u16 bt_get_tws_device_indicate(u8 *tws_device_indicate);
+const char *bt_get_local_name();
+extern void bt_update_mac_addr(u8 *addr);
+extern void bt_set_local_name(char *name, u8 len);
+extern void bt_reset_and_get_mac_addr(u8 *addr);
+extern void bt_set_pair_code_en(u8 en);
+
+#endif
diff --git a/include_lib/system/wait.h b/include_lib/system/wait.h
new file mode 100644
index 0000000..63e0911
--- /dev/null
+++ b/include_lib/system/wait.h
@@ -0,0 +1,16 @@
+#ifndef WAIT_COMPLETION_H
+#define WAIT_COMPLETION_H
+
+
+
+
+
+int wait_completion_schedule();
+
+u16 wait_completion(int (*condition)(void), int (*callback)(void *), void *priv);
+
+int wait_completion_del(u16 id);
+
+
+
+#endif
diff --git a/include_lib/update/dual_bank_updata_api.h b/include_lib/update/dual_bank_updata_api.h
new file mode 100644
index 0000000..acd7bfc
--- /dev/null
+++ b/include_lib/update/dual_bank_updata_api.h
@@ -0,0 +1,71 @@
+#ifndef _DUAL_BANK_API_H_
+#define _DUAL_BANK_API_H_
+
+/* @brief:Api for getting the buffer size for temporary storage
+ */
+u32 get_dual_bank_passive_update_max_buf(void);
+
+/* @brief:Initializes the update task,and setting the crc value and file size of new fw;
+ * @param fw_crc:crc value of new fw file
+ * @param fw_size:total size of new fw file
+ * @param priv:reserved
+ * @param max_ptk_len: Supported maxium length of every programming,it decides the max size of programming every time
+ */
+u32 dual_bank_passive_update_init(u32 fw_crc, u32 fw_size, u16 max_pkt_len, void *priv);
+
+/* @brief:exit the update task
+ * @param priv:reserved
+ */
+u32 dual_bank_passive_update_exit(void *priv);
+
+/* @brief:Judge whether enough space for new fw file
+ * @note: it should be called after dual_bank_passive_update_init(...);
+ * @param fw_size:fw size of new fw file
+ */
+u32 dual_bank_update_allow_check(u32 fw_size);
+
+
+/* @brief:copy the data to temporary buffer and notify task to write non-volatile storage
+ * @param data:the pointer to download data
+ * @param len:the length to download data
+ * @param write_complete_cb:callback for programming done,return 0 if no err occurred
+*/
+u32 dual_bank_update_write(void *data, u16 len, int (*write_complete_cb)(void *priv));
+
+/* @brief: caculate all the data had flashed,and compare with the cre value intializeed when update init;
+ * @crc_init_hdl:if it equals NULL,use internal implementation(CRC16-CCITT Standard);otherwise,use user's customization;
+ * @crc_calc_hdl:if it equals NULL,use internal implementation(CRC16-CCITT Standard);otherwise,use user's customization;
+ * @verify_result_hdl:when the verification completed,this callback for result notification;
+ * if crc_res equals 1,crc verification passed,if 0,the verification failed.
+*/
+u32 dual_bank_update_verify(void (*crc_init_hdl)(void), u32(*crc_calc_hdl)(u32 init_crc, u8 *data, u32 len), int (*verify_result_hdl)(int crc_res));
+
+
+/* @brief:After the new fw verification succeed,call this api to program the new boot info for new fw
+ * @param burn_boot_info_result_hdl:this callback for error notification
+ * if err equals 0,the operate to burn boot info succeed,other value means to fail.
+ */
+u32 dual_bank_update_burn_boot_info(int (*burn_boot_info_result_hdl)(int err));
+
+enum {
+
+ CLEAR_APP_RUNNING_BANK = 0,
+ CLEAR_APP_UPDATE_BANK,
+};
+
+/* @brief:this api for erasing the boot info of specific bank,it should be called much carefully
+ * @param type:it decides which bank's boot info would be erased;
+ * clean the boot info of running bank and call system_reset,system will run the other bank if available;
+ */
+int flash_update_clr_boot_info(u8 type);
+
+/* @brief:this api for user read flash data to calculate crc
+ * @param offset: the offset relative to update area
+ read_buf: user data buffer
+ read_len: read length
+ @returns: Actual read length
+ */
+u32 dual_bank_update_read_data(u32 offset, u8 *read_buf, u32 read_len);
+
+#endif
+
diff --git a/include_lib/update/uart_update.h b/include_lib/update/uart_update.h
new file mode 100644
index 0000000..b247e4e
--- /dev/null
+++ b/include_lib/update/uart_update.h
@@ -0,0 +1,43 @@
+#ifndef _UART_DEV_
+#define _UART_DEV_
+
+#include "typedef.h"
+
+#define MSG_UART_UPDATE_READY 0x1
+#define MSG_UART_UPDATE_START 0x2
+#define MSG_UART_UPDATE_START_RSP 0X3
+#define MSG_UART_UPDATE_READ_RSP 0x4
+
+#define PROTOCAL_SIZE 528
+#define SYNC_SIZE 6
+#define SYNC_MARK0 0xAA
+#define SYNC_MARK1 0x55
+
+typedef union {
+ u8 raw_data[PROTOCAL_SIZE + SYNC_SIZE];
+ struct {
+ u8 mark0;
+ u8 mark1;
+ u16 length;
+ u8 data[PROTOCAL_SIZE + 2]; //最后CRC16
+ } data;
+} protocal_frame_t;
+
+struct file_info {
+ u8 cmd;
+ u32 addr;
+ u32 len;
+} __attribute__((packed));
+
+typedef struct __update_io {
+ u16 rx;
+ u16 tx;
+ u8 input_channel; //input channel选择,根据方案选择未被使用的channel
+ u8 output_channel; //同input channel
+} uart_update_cfg;
+
+void uart_update_init(uart_update_cfg *cfg);
+void sava_uart_update_param(void);
+
+#endif
+
diff --git a/include_lib/update/update.h b/include_lib/update/update.h
new file mode 100644
index 0000000..1cd3cae
--- /dev/null
+++ b/include_lib/update/update.h
@@ -0,0 +1,161 @@
+#ifndef _UPDATE_H_
+#define _UPDATE_H_
+
+#include "typedef.h"
+
+extern u32 UPDATA_BEG;
+
+#define UPDATA_FLAG_ADDR ((void *)((u32)&UPDATA_BEG + 0x08))
+#define BOOT_STATUS_ADDR ((void *)((u32)&UPDATA_BEG)) //预留8个bytes
+
+#define UPDATA_MAGIC (0x5A00) //防止CRC == 0 的情况
+
+typedef enum {
+ UPDATA_NON = UPDATA_MAGIC,
+ UPDATA_READY,
+ UPDATA_SUCC,
+ UPDATA_PARM_ERR,
+ UPDATA_DEV_ERR,
+ UPDATA_KEY_ERR,
+} UPDATA_RESULT;
+
+typedef enum {
+ USB_UPDATA = UPDATA_MAGIC, //0x5A00
+ SD0_UPDATA, //0x5A01
+ SD1_UPDATA,
+ PC_UPDATA,
+ UART_UPDATA,
+ BT_UPDATA,
+ BLE_APP_UPDATA,
+ SPP_APP_UPDATA,
+ DUAL_BANK_UPDATA,
+ BLE_TEST_UPDATA,
+ NORFLASH_UPDATA,
+ //NOTE:以上的定义不要调整,新升级方式在此添加,注意加在USER_NORFLASH_UFW_UPDATA之前;
+ USER_NORFLASH_UFW_UPDATA,
+
+ NON_DEV = 0xFFFF,
+} UPDATA_TYPE;
+
+// sd
+enum {
+ SD_CONTROLLER_0 = 1,
+ SD_CONTROLLER_1,
+};
+enum {
+ SD0_IO_A = 1,
+ SD0_IO_B,
+ SD1_IO_A,
+ SD1_IO_B,
+ SD0_IO_C,
+ SD0_IO_D,
+ SD0_IO_E,
+ SD0_IO_F,
+};
+typedef struct _UPDATA_SD {
+ u8 control_type;
+ u8 control_io;
+ u8 online_check_way;
+ u8 max_data_baud;
+ u16 wDevTimeOutMax;
+ u8 per_online_status;
+ u8 hc_mode;
+ u8(*io_det_func)(void);
+ u8 power;
+ u8 control_io_clk;
+ u8 control_io_cmd;
+ u8 control_io_dat;
+} UPDATA_SD;
+
+// uart
+typedef struct _UPDATA_UART {
+ u32 control_io_tx; // ram0
+
+ .bss (NOLOAD) :ALIGN(4)
+ {
+ update_bss_start = .;
+
+ *(.update_bss)
+ update_bss_end = .;
+ } > ram0
+
+ .text : ALIGN(4)
+ {
+ update_code_start = .;
+
+ *(.bt_updata_ram_code)
+ *(.update_const)
+ *(.update_code)
+
+ update_code_end = .;
+ } > code0
+
+
+ UPDATE_CODE_TOTAL_SIZE = update_code_end - update_code_start;
+}
+
+
diff --git a/include_lib/update/update_loader_download.h b/include_lib/update/update_loader_download.h
new file mode 100644
index 0000000..f14f9e6
--- /dev/null
+++ b/include_lib/update/update_loader_download.h
@@ -0,0 +1,197 @@
+#ifndef _UPDATE_LOADER_DOWNLOAD_H_
+#define _UPDATE_LOADER_DOWNLOAD_H_
+
+#include "typedef.h"
+
+extern const int config_update_mode;
+extern const int support_dual_bank_update_en;
+#define UPDATE_MODULE_IS_SUPPORT(x) (config_update_mode & x)
+#define UPDATE_SUPPORT_DEV_IS_NULL() (config_update_mode == UPDATE_DEV_NULL)
+#define UPDATE_DUAL_BANK_IS_SUPPORT() (1 == support_dual_bank_update_en)
+
+struct __tws_ota_para {
+ u32 fm_size;
+ u32 fm_crc;
+ u16 max_pkt_len;
+};
+
+typedef struct _ret_code {
+ int stu;
+ u8 err_code;
+} update_ret_code_t;
+
+typedef struct _update_op_api_tws {
+ //for tws ota start
+ int (*tws_ota_start)(void *priv);
+ int (*tws_ota_data_send)(u8 *buf, u16 len);
+ int (*tws_ota_err)(u8);
+ u16(*enter_verfiy_hdl)(void *priv);
+ u16(*exit_verify_hdl)(u8 *, u8 *);
+ u16(*update_boot_info_hdl)(void *priv);
+ int (*tws_ota_result_hdl)(u8);
+ int (*tws_ota_data_send_pend)(void);
+ //for user chip update
+ int (*tws_ota_user_chip_update_send)(u8 cmd, u8 *buf, u16 len);
+} update_op_tws_api_t; //给tws同步升级用的接口
+
+update_op_tws_api_t *get_tws_update_api(void);
+void tws_sync_update_crc_handler_register(void (*crc_init_hdl)(void), u32(*crc_calc_hdl)(u32 init_crc, u8 *data, u32 len));
+void update_start_exit_sniff(void);
+void set_ota_status(u8 status);
+
+typedef struct _update_op_api_t {
+ void (*ch_init)(void (*resume_hdl)(void *priv), int (*sleep_hdl)(void *priv));
+ u16(*f_open)(void);
+ u16(*f_read)(void *fp, u8 *buff, u16 len);
+ int (*f_seek)(void *fp, u8 type, u32 offset);
+ u16(*f_stop)(u8 err);
+ int (*notify_update_content_size)(void *priv, u32 size);
+ void (*ch_exit)(void *priv);
+} update_op_api_t;
+
+extern const update_op_api_t lmp_ch_update_op;
+extern const update_op_api_t strg_ch_update_op;
+extern const update_op_api_t rcsp_update_op;
+
+#define UPDATE_SEAGNMENT_EN 1
+
+enum {
+ UPDATE_LOADER_OK = 1,
+ UPDATE_LOADER_ERR,
+};
+
+enum {
+ PKT_FLAG_MIDDLE = 0,
+ PKT_FLAG_FIRST,
+ PKT_FLAG_LAST,
+};
+
+//update result code bitmap
+#define UPDATE_RESULT_FLAG_BITMAP BIT(7)
+
+//update result code;
+enum {
+ UPDATE_RESULT_ERR_NONE = 0,
+ UPDATE_RESULT_FILE_SIZE_ERR = 0x1, //文件大小错误
+ UPDATE_RESULT_LOADER_SIZE_ERR = 0x2, //loader大小错误
+ UPDATE_RESULT_LOADER_VERIFY_ERR, //update loader校验失败
+ UPDATE_RESULT_REMOTE_FILE_HEAD_ERR, //读升级文件头错误
+
+ UPDATE_RESULT_LOCAL_FILE_HEAD_ERR = 0x5, //读flash文件头错误
+ UPDATE_RESULT_NOT_FIND_TARGET_FILE_ERR, //找不到目标文件(ota.bin找不到对应loader)
+ UPDATE_RESULT_FILE_OPERATION_ERR, //文件操作失败
+ UPDATE_RESULT_FLASH_DATA_VERIFY_ERR, //flash数据校验失败
+
+ UPDATE_RESULT_UBOOT_NOT_MATCH = 0x09, //UBOOT不匹配
+ UPDATE_RESULT_PRODUCT_INFO_NOT_MATCH = 0x0a, //芯片型号不匹配
+ UPDATE_RESULT_EX_DSP_UPDATE_ERR, //外部IC升级出错;
+ UPDATE_RESULT_CFG_UPDATE_ERR, //配置升级出错
+
+ UPDATE_RESULT_FLASH_ERASE_ERR = 0x0d, //flash 擦失败(可能是写保护)
+ UPDATE_RESULT_REMOTE_FILE_NOT_MATCH, //升级文件不匹配
+ UPDATE_RESULT_ANC_CFG_UPDATE_ERR, //ANC配置升级出错
+ UPDATE_RESULT_ANC_COEF_UPDATE_ERR = 0x10, //ANC配置升级出错
+ UPDATE_RESULT_OTA_TWS_NO_RSP, //对耳同步升级传输数据没有回复
+ UPDATE_RESULT_RESOURCE_LIMIT, //资源不足
+ UPDATE_RESULT_OTA_TWS_START_ERR, //对耳启动升级失败
+ UPDATE_RESULT_OTA_TWS_CRC_ERROR, //对耳校验失败
+ UPDATE_RESULT_OTA_APP_EXIT = 0x15, //升级过程APP强制退出
+ UPDATE_RESULT_TWS_NO_CONNECT, //对耳未连接
+ UPDATE_RESULT_READ_REMOTE_FILE_ERR, //读取不到远端数据
+ UPDATE_RESULT_UFW_FLASH_HEAD_CRC_ERR, //校验远端文件里的FLASH_HEAD失败
+ UPDATE_RESULT_UFW_CODE_HEAD_CRC_ERR, //校验远端文件里的APP_CODE_HEAD失败
+ UPDATE_RESULT_UFW_ALGIN_OF_OFFSET_MATCH_ERR, //升级文件中找不到和本地对齐和偏移方式一致的文件
+ UPDATE_RESULT_UFW_CANNOT_FIND_VM_AREA, //升级文件中找不到vm区域信息
+ UPDATE_RESULT_LOADER_HEAD_CRC_ERR, //校验LOADER_HEAD失败,检查ota.bin前面数据是否为00
+ UPDATE_RESULT_LOADER_WRITE_ERR, //写loader失败
+ UPDATE_RESULT_DUALBANK_GET_UFW_APP_HEAD_ERR, //双备份获取远端APP_head失败
+ UPDATE_RESULT_DUALBANK_GET_LOCAL_APP_HEAD_ERR, //双备份获取本地APP_head失败
+ UPDATE_RESULT_DUALBANK_APP_HEAD_NOT_MATCH, //双备份本地和远端APP分解线不匹配
+};
+
+#include "system/task.h"
+typedef struct _update_type_info_t {
+ int type;
+ u8 task_en;
+ void (*cb)(void *priv, int type, u8 cmd);
+ void *cb_priv;
+ update_op_api_t *p_op_api;
+ void (*common_state_cbk)(int type, u32 status, u32 code);
+ OS_SEM update_sem;
+} update_type_info_t;
+
+typedef struct _update_mode_info_t {
+ s32 type;
+ void (*state_cbk)(int type, u32 status, void *priv);
+ const update_op_api_t *p_op_api;
+ u8 task_en;
+} update_mode_info_t;
+
+typedef struct _succ_report_t {
+ u32 loader_saddr;
+ u32 priv_param;
+ u32(*update_param_write_hdl)(u32 priv, u8 *buf, u16 len);
+} succ_report_t;
+
+#define UPDATE_DEV_NULL 0
+#define UPDATE_BT_LMP_EN BIT(0)
+#define UPDATE_STORAGE_DEV_EN BIT(1)
+#define UPDATE_UART_EN BIT(2)
+#define UPDATE_APP_EN BIT(3) //包括APP升级还有其他升级方式,如串口升级(非测试盒方式)
+#define UPDATE_BLE_TEST_EN BIT(4)
+
+typedef struct _user_chip_update_t {
+ u8 *file_name;
+ int (*update_init)(void *priv, update_op_api_t *file_ops);
+ int (*update_get_len)(void);
+ int (*update_loop)(void *priv);
+} user_chip_update_t;
+
+typedef struct _user_chip_info_t {
+ union {
+ struct {
+ u32 file_addr;
+ };
+ struct {
+ u32 addr;
+ };
+ };
+ u32 len;
+ u16 crc;
+ u32 dev_addr;
+} user_chip_update_info_t;
+
+typedef struct _update_size_t {
+ u8 type;
+} update_type_t;
+
+enum UPDATE_SIZE_TYPE {
+ UPDATE_LEN_TYPE_CONTENT = 0,
+ UPDATE_LEN_TYPE_LOADER,
+ UPDATE_LEN_TYPE_EX_IC,
+};
+
+void register_user_chip_update_handle(const user_chip_update_t *user_update_ins);
+void rcsp_update_loader_download_init(int update_type, void (*result_cbk)(void *priv, u8 type, u8 cmd));
+
+int app_active_update_task_init(update_mode_info_t *info);
+int update_file_verify(u32 ufw_addr, u16(*ufw_read)(void *buf, u32 addr, u32 len));
+
+//==========================================================//
+// 获取升级进度信息 //
+//注意: 只有双备份升级可以获取该信息 //
+//==========================================================//
+typedef struct _update_percent_info {
+ u32 total_len; //固件总升级大小
+ u32 finish_len; //当前完成升级大小
+ u32 percent; //当前进度百分比
+} update_percent_info;
+
+//注册升级进度更新回调函数:
+void register_update_percent_info_callback_handle(void (*handle)(update_percent_info *info));
+
+//查询当前升级进度信息:
+void update_percent_info_query(update_percent_info *info);
+
+#endif /*_UPDATE_LOADER_DOWNLOAD_H_*/
+
diff --git a/tools/make_prompt.bat b/tools/make_prompt.bat
new file mode 100644
index 0000000..e42893f
--- /dev/null
+++ b/tools/make_prompt.bat
@@ -0,0 +1,5 @@
+SET SCRIPT_PATH=%~dp0%
+set PATH=%SCRIPT_PATH%\utils;%PATH%
+
+cd ..
+cmd
diff --git a/tools/package_release.py b/tools/package_release.py
new file mode 100644
index 0000000..b586101
--- /dev/null
+++ b/tools/package_release.py
@@ -0,0 +1,637 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+###############################################################################
+# @file package_release.py
+# @brief 根据当前开发工程自动生成客户交付 Release 工程
+# @author cyWu <1917507415@qq.com>
+# @date 2026.08.04
+# @version V1.0.0
+# @history
+# - V1.0.0, 2026.08.04, cyWu, 首次发布
+# - V1.0.1, 2026.08.04, cyWu, 产物统一输出到 release/ 目录
+# - V1.0.2, 2026.08.05, cyWu, 交付包命名改为 JBao_JL7016_SOC_SDK_Vx.x.x
+#
+# 使用方式(在项目根或任意目录):
+# python tools/package_release.py
+#
+# 约束:
+# - 仅使用 Python 标准库
+# - 所有删除 / 过滤 / 复制只作用于 Release 副本
+# - 绝不修改开发工程业务源码、Makefile、build_lib.bat、CodeBlocks 工程
+###############################################################################
+
+from __future__ import annotations
+
+import fnmatch
+import os
+import re
+import shutil
+import sys
+import zipfile
+from datetime import datetime
+from pathlib import Path
+from typing import Dict, Iterable, List, Set
+
+
+# =============================================================================
+# 可配置区域(集中管理,扩展模块只改这里)
+# =============================================================================
+
+# 版本文件(相对项目根)
+VERSION_FILE = "version.txt"
+
+# Release 输出根目录(相对项目根,产物全部放这里)
+RELEASE_OUTPUT_DIR = "release"
+
+# Release 命名规则
+RELEASE_DIR_PREFIX = "JBao_JL7016_SOC_SDK_V"
+RELEASE_ZIP_SUFFIX = ".zip"
+README_NAME = "JBao_JL7016_SOC_SDK_README.md"
+
+# 工程展示名称(写入 README)
+PROJECT_DISPLAY_NAME = "AC701N Earphone SDK"
+CHIP_DISPLAY_NAME = "AC7016C(BR28)"
+
+# 复制时跳过的目录名(任意层级)
+SKIP_DIR_NAMES: Set[str] = {
+ ".git",
+ ".vscode",
+ ".idea",
+ "objs",
+ "obj",
+ "__pycache__",
+ RELEASE_OUTPUT_DIR, # 不把已有交付产物拷进新包
+}
+
+# 复制时跳过的根目录文件(仅项目根下,不进客户包)
+SKIP_ROOT_FILES: Set[str] = {
+ ".gitignore",
+ "version.txt",
+}
+
+# 复制时跳过的文件通配(任意层级,按文件名匹配)
+SKIP_FILE_PATTERNS: List[str] = [
+ "*.o",
+ "*.d",
+ "*.dep",
+ "*.obj",
+ "*.bak",
+ "*.log",
+ "*.tmp",
+ "*.temp",
+ "*.swp",
+ "*.swo",
+ "*.orig",
+ "*.rej",
+ "*.pyc",
+ "*.layout",
+ "*.depend",
+ "Thumbs.db",
+ ".DS_Store",
+]
+
+# 复制时跳过的路径前缀(相对项目根,防自复制嵌套)
+SKIP_PATH_PREFIXES: List[str] = [
+ RELEASE_OUTPUT_DIR,
+ "Release_Project_V", # 兼容旧版曾放在项目根的产物
+ "JBao_JL7016_SOC_SDK_V", # 兼容曾放在项目根的新命名产物
+]
+
+# ---------------------------------------------------------------------------
+# 需要封装交付的模块配置
+# ---------------------------------------------------------------------------
+# public_headers : 保留的公开头文件(仅文件名,相对模块根或子目录中同名匹配)
+# remove_patterns : 删除的源码通配(递归)
+# remove_internal_headers : True 时删除非 public_headers 的所有 .h/.hpp
+# prune_empty_dirs : 清理后删除空目录
+# remove_extra : 额外删除的相对路径(相对模块根)
+# keep_extra : 额外强制保留的相对路径(文件或目录,相对模块根)
+# ---------------------------------------------------------------------------
+MODULE_CONFIG: Dict[str, dict] = {
+ "apps/usr_le_code": {
+ "public_headers": [
+ "usr_le_api.h",
+ "usr_le_product.h",
+ ],
+ "remove_patterns": [
+ "*.c",
+ "*.cpp",
+ "*.cc",
+ ],
+ "remove_internal_headers": True,
+ "prune_empty_dirs": True,
+ "remove_extra": [
+ "build_lib.bat",
+ ],
+ "keep_extra": [
+ "lib/",
+ ],
+ },
+}
+
+
+# =============================================================================
+# 路径管理
+# =============================================================================
+
+def get_project_root() -> Path:
+ """
+ @brief 由脚本位置推导项目根目录(tools/ 的上一级)
+ @return 项目根 Path
+ """
+ return Path(__file__).resolve().parent.parent
+
+
+def read_version(project_root: Path) -> str:
+ """
+ @brief 读取 version.txt
+ @param project_root 项目根
+ @return 版本号字符串,例如 "1.0.0"
+ """
+ version_path = project_root / VERSION_FILE
+ if not version_path.is_file():
+ raise FileNotFoundError(f"version file not found: {version_path}")
+
+ version = version_path.read_text(encoding="utf-8").strip()
+ if not version:
+ raise ValueError(f"version file is empty: {version_path}")
+
+ # 简单校验:不允许路径分隔符,避免生成非法目录名
+ if any(ch in version for ch in ("/", "\\", "..")):
+ raise ValueError(f"invalid version string: {version!r}")
+
+ return version
+
+
+def get_release_paths(project_root: Path, version: str) -> dict:
+ """
+ @brief 统一生成 Release 相关路径(均位于 release/ 下)
+ @param project_root 项目根
+ @param version 版本号
+ @return 含 output_dir / dir / zip / readme 的字典
+ """
+ dir_name = f"{RELEASE_DIR_PREFIX}{version}"
+ output_dir = project_root / RELEASE_OUTPUT_DIR
+ release_dir = output_dir / dir_name
+ release_zip = output_dir / f"{dir_name}{RELEASE_ZIP_SUFFIX}"
+ readme_path = release_dir / README_NAME
+ return {
+ "dir_name": dir_name,
+ "output_dir": output_dir,
+ "release_dir": release_dir,
+ "release_zip": release_zip,
+ "readme_path": readme_path,
+ }
+
+
+# =============================================================================
+# 复制过滤
+# =============================================================================
+
+def _match_any(name: str, patterns: Iterable[str]) -> bool:
+ """
+ @brief 判断文件名是否匹配任一通配符
+ """
+ return any(fnmatch.fnmatch(name, pat) for pat in patterns)
+
+
+def should_skip_path(rel_path: Path) -> bool:
+ """
+ @brief 判断相对项目根的路径在复制时是否应跳过
+ @param rel_path 相对路径
+ @return True=跳过
+ """
+ parts = rel_path.parts
+ if not parts:
+ return False
+
+ # 跳过项目根下指定文件(如 .gitignore / version.txt)
+ if len(parts) == 1 and parts[0] in SKIP_ROOT_FILES:
+ return True
+
+ # 跳过指定目录名(任意层级)
+ for part in parts:
+ if part in SKIP_DIR_NAMES:
+ return True
+
+ # 跳过 Release 产物路径(防嵌套)
+ rel_posix = rel_path.as_posix()
+ for prefix in SKIP_PATH_PREFIXES:
+ if rel_posix == prefix.rstrip("/") or rel_posix.startswith(prefix):
+ return True
+
+ # 跳过匹配的文件名
+ if _match_any(rel_path.name, SKIP_FILE_PATTERNS):
+ return True
+
+ # 跳过已有 zip 包(根目录下)
+ if len(parts) == 1 and rel_path.name.endswith(RELEASE_ZIP_SUFFIX):
+ if rel_path.name.startswith(RELEASE_DIR_PREFIX):
+ return True
+
+ return False
+
+
+def copy_project(project_root: Path, release_dir: Path) -> int:
+ """
+ @brief 过滤复制整工程到 Release 目录
+ @param project_root 开发工程根
+ @param release_dir 目标 Release 目录
+ @return 复制的文件数量
+ """
+ copied = 0
+
+ for root, dirs, files in os.walk(project_root):
+ root_path = Path(root)
+ rel_root = root_path.relative_to(project_root)
+
+ # 就地过滤子目录,避免继续向下遍历
+ keep_dirs: List[str] = []
+ for d in dirs:
+ candidate = rel_root / d if str(rel_root) != "." else Path(d)
+ if should_skip_path(candidate):
+ continue
+ keep_dirs.append(d)
+ dirs[:] = keep_dirs
+
+ # 目标目录
+ dst_root = release_dir if str(rel_root) == "." else release_dir / rel_root
+ dst_root.mkdir(parents=True, exist_ok=True)
+
+ for name in files:
+ rel_file = rel_root / name if str(rel_root) != "." else Path(name)
+ if should_skip_path(rel_file):
+ continue
+
+ src = root_path / name
+ dst = dst_root / name
+ shutil.copy2(src, dst)
+ copied += 1
+
+ return copied
+
+
+# =============================================================================
+# 模块清理(仅作用于 Release 副本)
+# =============================================================================
+
+def _is_under_keep_extra(rel_posix: str, keep_extra: List[str]) -> bool:
+ """
+ @brief 判断模块内相对路径是否属于 keep_extra 保护范围
+ """
+ for keep in keep_extra:
+ keep_norm = keep.replace("\\", "/").rstrip("/")
+ if not keep_norm:
+ continue
+ # 目录保护:keep 以 / 结尾或配置为目录前缀
+ if rel_posix == keep_norm or rel_posix.startswith(keep_norm + "/"):
+ return True
+ # 兼容配置写成 "lib/" 的情况已在上方处理
+ if keep.endswith("/") and (rel_posix == keep_norm or rel_posix.startswith(keep_norm + "/")):
+ return True
+ return False
+
+
+def _prune_empty_dirs(module_dir: Path) -> int:
+ """
+ @brief 自底向上删除空目录
+ @return 删除的空目录数量
+ """
+ removed = 0
+ # 深度优先:按路径长度降序
+ all_dirs = sorted(
+ (p for p in module_dir.rglob("*") if p.is_dir()),
+ key=lambda p: len(p.parts),
+ reverse=True,
+ )
+ for d in all_dirs:
+ try:
+ if not any(d.iterdir()):
+ d.rmdir()
+ removed += 1
+ except OSError:
+ pass
+ return removed
+
+
+def clean_module(release_dir: Path, module_rel: str, cfg: dict) -> dict:
+ """
+ @brief 按配置清理单个封装模块(仅 Release 内)
+ @param release_dir Release 根目录
+ @param module_rel 模块相对路径,如 apps/usr_le_code
+ @param cfg MODULE_CONFIG 中的单项配置
+ @return 统计信息字典
+ """
+ module_dir = release_dir / module_rel
+ stats = {
+ "module": module_rel,
+ "removed_sources": 0,
+ "removed_headers": 0,
+ "removed_extra": 0,
+ "pruned_dirs": 0,
+ "missing": False,
+ }
+
+ if not module_dir.is_dir():
+ stats["missing"] = True
+ print(f"[WARN] module not found in Release: {module_rel}")
+ return stats
+
+ public_headers: Set[str] = set(cfg.get("public_headers", []))
+ remove_patterns: List[str] = list(cfg.get("remove_patterns", []))
+ remove_internal_headers: bool = bool(cfg.get("remove_internal_headers", True))
+ prune_empty_dirs: bool = bool(cfg.get("prune_empty_dirs", True))
+ remove_extra: List[str] = list(cfg.get("remove_extra", []))
+ keep_extra: List[str] = list(cfg.get("keep_extra", []))
+
+ # 1) 删除匹配 remove_patterns 的源文件
+ for path in list(module_dir.rglob("*")):
+ if not path.is_file():
+ continue
+ rel = path.relative_to(module_dir).as_posix()
+ if _is_under_keep_extra(rel, keep_extra):
+ continue
+ if _match_any(path.name, remove_patterns):
+ path.unlink()
+ stats["removed_sources"] += 1
+
+ # 2) 删除非公开头文件
+ if remove_internal_headers:
+ header_patterns = ["*.h", "*.hpp"]
+ for path in list(module_dir.rglob("*")):
+ if not path.is_file():
+ continue
+ if not _match_any(path.name, header_patterns):
+ continue
+ rel = path.relative_to(module_dir).as_posix()
+ if _is_under_keep_extra(rel, keep_extra):
+ continue
+ # 公开头文件按“文件名”匹配,便于配置只写文件名
+ if path.name in public_headers:
+ continue
+ path.unlink()
+ stats["removed_headers"] += 1
+
+ # 3) 删除额外指定文件/目录
+ for extra in remove_extra:
+ target = module_dir / extra
+ if not target.exists():
+ continue
+ if target.is_dir():
+ shutil.rmtree(target)
+ else:
+ target.unlink()
+ stats["removed_extra"] += 1
+
+ # 4) 清理空目录
+ if prune_empty_dirs:
+ stats["pruned_dirs"] = _prune_empty_dirs(module_dir)
+
+ return stats
+
+
+def clean_all_modules(release_dir: Path) -> List[dict]:
+ """
+ @brief 遍历 MODULE_CONFIG 清理所有模块
+ """
+ results = []
+ for module_rel, cfg in MODULE_CONFIG.items():
+ print(f"[INFO] cleaning module: {module_rel}")
+ results.append(clean_module(release_dir, module_rel, cfg))
+ return results
+
+
+def sanitize_release_makefile(release_dir: Path) -> None:
+ """
+ @brief 调整 Release 副本中的 Makefile:仅链接预编译 libusr_le_code.a
+ 开发工程 Makefile 不动;客户包不得再尝试用已删除源码重建库
+ @param release_dir Release 根目录
+ """
+ makefile = release_dir / "Makefile"
+ if not makefile.is_file():
+ print("[WARN] Makefile not found in Release, skip sanitize")
+ return
+
+ text = makefile.read_text(encoding="utf-8")
+
+ # 1) 去掉源码列表与 OBJS,仅保留预编译库路径
+ text2, n1 = re.subn(
+ r"# usr_le_code 静态库[^\n]*\n"
+ r"USR_LE_LIB := apps/usr_le_code/lib/libusr_le_code\.a\n"
+ r"USR_LE_SRC_FILES := \\\n"
+ r"(?:[ \t]+apps/usr_le_code/[^\n]+\n)+"
+ r"\n"
+ r"USR_LE_OBJS :=[^\n]+\n",
+ "# usr_le_code 预编译静态库(Release 不附带协议源码,禁止本地重建)\n"
+ "USR_LE_LIB := apps/usr_le_code/lib/libusr_le_code.a\n"
+ "\n",
+ text,
+ count=1,
+ )
+ if n1 == 0:
+ raise RuntimeError("sanitize Makefile failed: USR_LE_SRC_FILES block not found")
+
+ # 2) .PHONY 去掉 lib_usr_le
+ text2, n2 = re.subn(
+ r"\.PHONY:\s*all clean pre_build lib_usr_le\b",
+ ".PHONY: all clean pre_build",
+ text2,
+ count=1,
+ )
+ if n2 == 0:
+ # 兼容顺序变化,尽量剥离 lib_usr_le
+ text2 = re.sub(r"\s+lib_usr_le\b", "", text2, count=1)
+
+ # 3) 删除 lib_usr_le 目标与 $(USR_LE_LIB): $(USR_LE_OBJS) 重建规则
+ # 保留 all / OUT_ELF 对 $(USR_LE_LIB) 的依赖:库文件已存在即可链接
+ text2, n3 = re.subn(
+ r"\n# 单独编译 usr_le_code 静态库:[^\n]*\n"
+ r"lib_usr_le:[^\n]*\n"
+ r"\n"
+ r"\$\(USR_LE_LIB\): \$\(USR_LE_OBJS\)\n"
+ r"(?:[ \t]+[^\n]+\n)+",
+ "\n",
+ text2,
+ count=1,
+ )
+ if n3 == 0:
+ raise RuntimeError("sanitize Makefile failed: lib_usr_le rebuild rule not found")
+
+ makefile.write_text(text2, encoding="utf-8")
+ print("[INFO] sanitized Release Makefile (prebuilt libusr_le_code.a only)")
+
+
+# =============================================================================
+# README / ZIP
+# =============================================================================
+
+def write_readme(readme_path: Path, version: str, module_stats: List[dict]) -> None:
+ """
+ @brief 生成 JBao_JL7016_SOC_SDK_README.md
+ @param readme_path README 路径
+ @param version 版本号
+ @param module_stats 模块清理统计(用于目录说明)
+ """
+ now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
+
+ lines: List[str] = [
+ f"# {PROJECT_DISPLAY_NAME}",
+ "",
+ "## 基本信息",
+ "",
+ f"- 工程名称:{PROJECT_DISPLAY_NAME}",
+ f"- 版本号:V{version}",
+ f"- 生成时间:{now}",
+ f"- 适用芯片:{CHIP_DISPLAY_NAME}",
+ "",
+ "## 目录说明",
+ "",
+ "```",
+ f"{RELEASE_DIR_PREFIX}{version}/",
+ "├── apps/",
+ "│ ├── common/ # SDK 公共模块",
+ "│ ├── earphone/ # 耳机应用",
+ "│ ├── usr_jb_proto/ # 应用协议层",
+ "│ ├── usr_periph/ # 板级外设(RTC 等,源码开放)",
+ "│ └── usr_le_code/ # BLE 协议库(库文件 + 公开头文件)",
+ "├── cpu/ # 芯片相关代码与工具",
+ "├── include_lib/ # SDK 头文件",
+ "├── tools/ # 工程工具",
+ "├── Makefile",
+ "├── AC701N.cbp",
+ f"└── {README_NAME}",
+ "```",
+ "",
+ "### 封装模块公开接口",
+ "",
+ ]
+
+ for module_rel, cfg in MODULE_CONFIG.items():
+ public_headers = cfg.get("public_headers", [])
+ lines.append(f"**{module_rel}**")
+ lines.append("")
+ lines.append(f"- 静态库:`{module_rel}/lib/`")
+ lines.append("- 公开头文件:")
+ for h in public_headers:
+ lines.append(f" - `{module_rel}/{h}`")
+ lines.append("")
+
+ lines.append("---")
+ lines.append("")
+ lines.append("*本文件由 tools/package_release.py 自动生成。*")
+ lines.append("")
+
+ readme_path.write_text("\n".join(lines), encoding="utf-8")
+
+
+def make_zip(release_dir: Path, release_zip: Path) -> None:
+ """
+ @brief 将 Release 目录压缩为 zip(与目录同级)
+ @param release_dir Release 目录
+ @param release_zip 目标 zip 路径
+ """
+ if release_zip.exists():
+ release_zip.unlink()
+
+ with zipfile.ZipFile(release_zip, "w", compression=zipfile.ZIP_DEFLATED) as zf:
+ for path in release_dir.rglob("*"):
+ if path.is_file():
+ arcname = path.relative_to(release_dir.parent)
+ zf.write(path, arcname.as_posix())
+
+
+# =============================================================================
+# 主流程
+# =============================================================================
+
+def remove_old_release(release_dir: Path, release_zip: Path) -> None:
+ """
+ @brief 删除已有同名 Release 目录与 zip
+ """
+ if release_dir.exists():
+ print(f"[INFO] remove old release dir: {release_dir.name}")
+ shutil.rmtree(release_dir)
+
+ if release_zip.exists():
+ print(f"[INFO] remove old release zip: {release_zip.name}")
+ release_zip.unlink()
+
+
+def main() -> int:
+ """
+ @brief Release 打包主入口
+ @return 进程退出码,0=成功
+ """
+ try:
+ project_root = get_project_root()
+ version = read_version(project_root)
+ paths = get_release_paths(project_root, version)
+
+ release_dir: Path = paths["release_dir"]
+ release_zip: Path = paths["release_zip"]
+ readme_path: Path = paths["readme_path"]
+ dir_name: str = paths["dir_name"]
+
+ print("=" * 60)
+ print(" AC701N Release Package Tool")
+ print("=" * 60)
+ output_dir: Path = paths["output_dir"]
+
+ print(f"[INFO] project root : {project_root}")
+ print(f"[INFO] version : {version}")
+ print(f"[INFO] output dir : {RELEASE_OUTPUT_DIR}/")
+ print(f"[INFO] release dir : {RELEASE_OUTPUT_DIR}/{dir_name}")
+ print()
+
+ # 确保 release/ 输出目录存在
+ output_dir.mkdir(parents=True, exist_ok=True)
+
+ # ① 删除旧产物
+ remove_old_release(release_dir, release_zip)
+
+ # ② 过滤复制
+ print("[INFO] copying project ...")
+ copied = copy_project(project_root, release_dir)
+ print(f"[INFO] copied files : {copied}")
+
+ # ③ 模块清理(仅 Release 副本)
+ print("[INFO] cleaning encapsulated modules ...")
+ module_stats = clean_all_modules(release_dir)
+ for st in module_stats:
+ if st["missing"]:
+ continue
+ print(
+ f" - {st['module']}: "
+ f"src={st['removed_sources']}, "
+ f"hdr={st['removed_headers']}, "
+ f"extra={st['removed_extra']}, "
+ f"empty_dirs={st['pruned_dirs']}"
+ )
+
+ # ④ Release Makefile:禁止用已删除源码重建库(开发工程 Makefile 不动)
+ print("[INFO] sanitizing Release Makefile ...")
+ sanitize_release_makefile(release_dir)
+
+ # ⑤ README
+ print("[INFO] writing README ...")
+ write_readme(readme_path, version, module_stats)
+
+ # ⑥ ZIP
+ print("[INFO] creating zip ...")
+ make_zip(release_dir, release_zip)
+
+ print()
+ print("=" * 60)
+ print("[OK] Release package generated successfully")
+ print(f" dir : {release_dir}")
+ print(f" zip : {release_zip}")
+ print("=" * 60)
+ return 0
+
+ except Exception as exc:
+ print(f"[FAIL] {exc}", file=sys.stderr)
+ return 1
+
+
+if __name__ == "__main__":
+ sys.exit(main())
diff --git a/tools/utils/[.exe b/tools/utils/[.exe
new file mode 100644
index 0000000..c71fba5
Binary files /dev/null and b/tools/utils/[.exe differ
diff --git a/tools/utils/do_merge_libs.bat b/tools/utils/do_merge_libs.bat
new file mode 100644
index 0000000..091500e
--- /dev/null
+++ b/tools/utils/do_merge_libs.bat
@@ -0,0 +1,18 @@
+@echo off
+setlocal enabledelayedexpansion
+set INDIR=%1%
+set MERGE=%2%
+set AROUT=%3%
+
+echo %INDIR%
+echo %MERGE%
+echo %AROUT%
+
+set FILES=
+
+for /f "tokens=*" %%i in ('dir /b %INDIR%\*.a') DO SET FILES=!FILES! %INDIR%\%%i
+
+echo %FILES%
+
+%MERGE% --no-rewrite --output %AROUT% %FILES%
+
diff --git a/tools/utils/find.exe b/tools/utils/find.exe
new file mode 100644
index 0000000..85192fb
Binary files /dev/null and b/tools/utils/find.exe differ
diff --git a/tools/utils/fixbat.exe b/tools/utils/fixbat.exe
new file mode 100644
index 0000000..e6280d2
Binary files /dev/null and b/tools/utils/fixbat.exe differ
diff --git a/tools/utils/libiconv2.dll b/tools/utils/libiconv2.dll
new file mode 100644
index 0000000..747073f
Binary files /dev/null and b/tools/utils/libiconv2.dll differ
diff --git a/tools/utils/libintl3.dll b/tools/utils/libintl3.dll
new file mode 100644
index 0000000..ec11e6b
Binary files /dev/null and b/tools/utils/libintl3.dll differ
diff --git a/tools/utils/ls.exe b/tools/utils/ls.exe
new file mode 100644
index 0000000..96ff2e5
Binary files /dev/null and b/tools/utils/ls.exe differ
diff --git a/tools/utils/make.exe b/tools/utils/make.exe
new file mode 100644
index 0000000..17bfc2e
Binary files /dev/null and b/tools/utils/make.exe differ
diff --git a/tools/utils/merge-archives.exe b/tools/utils/merge-archives.exe
new file mode 100644
index 0000000..07e1a2b
Binary files /dev/null and b/tools/utils/merge-archives.exe differ
diff --git a/tools/utils/mkdir_win.exe b/tools/utils/mkdir_win.exe
new file mode 100644
index 0000000..f96d181
Binary files /dev/null and b/tools/utils/mkdir_win.exe differ
diff --git a/tools/utils/override-seg.exe b/tools/utils/override-seg.exe
new file mode 100644
index 0000000..3e759e2
Binary files /dev/null and b/tools/utils/override-seg.exe differ
diff --git a/tools/utils/rm.exe b/tools/utils/rm.exe
new file mode 100644
index 0000000..8e79306
Binary files /dev/null and b/tools/utils/rm.exe differ
diff --git a/tools/utils/true.exe b/tools/utils/true.exe
new file mode 100644
index 0000000..cb41f82
Binary files /dev/null and b/tools/utils/true.exe differ
diff --git a/tools/utils/uname.exe b/tools/utils/uname.exe
new file mode 100644
index 0000000..3e2f4cf
Binary files /dev/null and b/tools/utils/uname.exe differ