Backup before error handling refactoring

This commit is contained in:
jkwoo
2026-07-13 17:10:02 +09:00
commit 04fc19b485
1132 changed files with 347840 additions and 0 deletions

357
UCOSIII/UCOS_BSP/bsp.c Normal file
View File

@@ -0,0 +1,357 @@
/*
*********************************************************************************************************
*
* Module name: BSP module
* File name: BSP.c
* Version: V1.0
* Description: hardware driver collection
*
* Modify records:
* Version date author description
* v1.0 2015-08-17 JK.Woo ST firmware V1.0.2 version.
*
* Copyright (c), 2013-2014
*********************************************************************************************************
*/
#define BSP_MODULE
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "iwdg.h"
#include <bsp.h>
void NVIC_Configuration(void);
/*
*********************************************************************************************************
* REGISTERS
*********************************************************************************************************
*/
#define BSP_REG_DEM_CR (*(CPU_REG32 *)0xE000EDFC) //DEMCR register
#define BSP_REG_DWT_CR (*(CPU_REG32 *)0xE0001000) //DWT control register
#define BSP_REG_DWT_CYCCNT (*(CPU_REG32 *)0xE0001004) //DWT clock count register
#define BSP_REG_DBGMCU_CR (*(CPU_REG32 *)0xE0042004)
/*
*********************************************************************************************************
* REGISTER BITS
*********************************************************************************************************
*/
#define BSP_DBGMCU_CR_TRACE_IOEN_MASK 0x10
#define BSP_DBGMCU_CR_TRACE_MODE_ASYNC 0x00
#define BSP_DBGMCU_CR_TRACE_MODE_SYNC_01 0x40
#define BSP_DBGMCU_CR_TRACE_MODE_SYNC_02 0x80
#define BSP_DBGMCU_CR_TRACE_MODE_SYNC_04 0xC0
#define BSP_DBGMCU_CR_TRACE_MODE_MASK 0xC0
//DEMCR register 24th place, if you want to use the DWT ETM ITM and 24th position of the TPIU registers DEMCR 1
#define BSP_BIT_DEM_CR_TRCENA DEF_BIT_24
//DWTCR Register No. 0, when 1 CYCCNT counter, use CYCCNT before the first class
#define BSP_BIT_DWT_CR_CYCCNTENA DEF_BIT_00
/*
*********************************************************************************************************
* Function name: bsp_Init
* Function description: initialize hardware devices
* Parameters: none
* Return value: none
*********************************************************************************************************
*/
void bsp_Init(void)
{
NVIC_Configuration(); /* Interrupt priority grouping configuration */
//#ifdef CONSOLE_DEBUG
uart1_init(115200); // Serial port init
IWDG_ReloadCounter();
//#endif // #ifdef CONSOLE_DEBUG
IWDG_Init();
DIO_Init(); // LED init
#ifdef TRACE_EN /* See project / compiler preprocessor options. */
BSP_CPU_REG_DBGMCU_CR |= BSP_DBGMCU_CR_TRACE_IOEN_MASK; /* Enable tracing (see Note #2). */
BSP_CPU_REG_DBGMCU_CR &= ~BSP_DBGMCU_CR_TRACE_MODE_MASK; /* Clr trace mode sel bits. */
BSP_CPU_REG_DBGMCU_CR |= BSP_DBGMCU_CR_TRACE_MODE_SYNC_04; /* Cfg trace mode to synch 4-bit. */
#endif
}
/*
*********************************************************************************************************
* Function name: NVIC_Configuration
* Function description: the interrupt priority configuration, here assigned to priority groups first, and then
* specific modules which implement the priority configuration
* Parameters: none
* Return value: none
*********************************************************************************************************
*/
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
#ifdef VECT_TAB_RAM
/* Set the Vector Table base location at 0x20000000 */
NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
#else /* VECT_TAB_FLASH */
/* Set the Vector Table base location at 0x08020000 */
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x3000);
#endif
/* Set the NVIC priority preemptive priorities grouped into Group2:0-3, 0-3-response priority */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
/* Enable the CAN1 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//#ifdef CONSOLE_DEBUG
/* Enable the USART1 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//#endif // #ifdef CONSOLE_DEBUG
}
/*
*********************************************************************************************************
* BSP_CPU_ClkFreq()
* Description : Read CPU registers to determine the CPU clock frequency of the chip.
* Argument(s) : none.
* Return(s) : The CPU clock frequency, in Hz.
* Caller(s) : Application.
* Note(s) : none.
*********************************************************************************************************
*/
CPU_INT32U BSP_CPU_ClkFreq (void)
{
RCC_ClocksTypeDef rcc_clocks;
RCC_GetClocksFreq(&rcc_clocks); //Gets the clock frequency
return ((CPU_INT32U)rcc_clocks.HCLK_Frequency); //Returns the HCLK clock frequency
}
/*$PAGE*/
/*
*********************************************************************************************************
* CPU_TS_TmrInit()
* Description : Initialize & start CPU timestamp timer.
* Argument(s) : none.
* Return(s) : none.
* Caller(s) : CPU_TS_Init().
* This function is an INTERNAL CPU module function & MUST be implemented by application/
* BSP function(s) [see Note #1] but MUST NOT be called by application function(s).
* Note(s) : (1) CPU_TS_TmrInit() is an application/BSP function that MUST be defined by the developer
* if either of the following CPU features is enabled :
* (a) CPU timestamps
* (b) CPU interrupts disabled time measurements
* See 'cpu_cfg.h CPU TIMESTAMP CONFIGURATION Note #1'
* & 'cpu_cfg.h CPU INTERRUPTS DISABLED TIME MEASUREMENT CONFIGURATION Note #1a'.
* (2) (a) Timer count values MUST be returned via word-size-configurable 'CPU_TS_TMR'
* data type.
* (1) If timer has more bits, truncate timer values' higher-order bits greater
* than the configured 'CPU_TS_TMR' timestamp timer data type word size.
* (2) Since the timer MUST NOT have less bits than the configured 'CPU_TS_TMR'
* timestamp timer data type word size; 'CPU_CFG_TS_TMR_SIZE' MUST be
* configured so that ALL bits in 'CPU_TS_TMR' data type are significant.
* In other words, if timer size is not a binary-multiple of 8-bit octets
* (e.g. 20-bits or even 24-bits), then the next lower, binary-multiple
* octet word size SHOULD be configured (e.g. to 16-bits). However, the
* minimum supported word size for CPU timestamp timers is 8-bits.
* See also 'cpu_cfg.h CPU TIMESTAMP CONFIGURATION Note #2'
* & 'cpu_core.h CPU TIMESTAMP DATA TYPES Note #1'.
* (b) Timer SHOULD be an 'up' counter whose values increase with each time count.
* (c) When applicable, timer period SHOULD be less than the typical measured time
* but MUST be less than the maximum measured time; otherwise, timer resolution
* inadequate to measure desired times.
* See also 'CPU_TS_TmrRd() Note #2'.
*********************************************************************************************************
*/
#if (CPU_CFG_TS_TMR_EN == DEF_ENABLED)
void CPU_TS_TmrInit (void)
{
CPU_INT32U fclk_freq;
fclk_freq = BSP_CPU_ClkFreq();
BSP_REG_DEM_CR |= (CPU_INT32U)BSP_BIT_DEM_CR_TRCENA; //Using DWT /* Enable Cortex-M4's DWT CYCCNT reg. */
BSP_REG_DWT_CYCCNT = (CPU_INT32U)0u; //Initializes the CYCCNT register
BSP_REG_DWT_CR |= (CPU_INT32U)BSP_BIT_DWT_CR_CYCCNTENA;//Open CYCCNT
CPU_TS_TmrFreqSet((CPU_TS_TMR_FREQ)fclk_freq);
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* CPU_TS_TmrRd()
* Description : Get current CPU timestamp timer count value.
* Argument(s) : none.
* Return(s) : Timestamp timer count (see Notes #2a & #2b).
* Caller(s) : CPU_TS_Init(),
* CPU_TS_Get32(),
* CPU_TS_Get64(),
* CPU_IntDisMeasStart(),
* CPU_IntDisMeasStop().
* This function is an INTERNAL CPU module function & MUST be implemented by application/
* BSP function(s) [see Note #1] but SHOULD NOT be called by application function(s).
* Note(s) : (1) CPU_TS_TmrRd() is an application/BSP function that MUST be defined by the developer
* if either of the following CPU features is enabled :
* (a) CPU timestamps
* (b) CPU interrupts disabled time measurements
* See 'cpu_cfg.h CPU TIMESTAMP CONFIGURATION Note #1'
* & 'cpu_cfg.h CPU INTERRUPTS DISABLED TIME MEASUREMENT CONFIGURATION Note #1a'.
* (2) (a) Timer count values MUST be returned via word-size-configurable 'CPU_TS_TMR'
* data type.
* (1) If timer has more bits, truncate timer values' higher-order bits greater
* than the configured 'CPU_TS_TMR' timestamp timer data type word size.
* (2) Since the timer MUST NOT have less bits than the configured 'CPU_TS_TMR'
* timestamp timer data type word size; 'CPU_CFG_TS_TMR_SIZE' MUST be
* configured so that ALL bits in 'CPU_TS_TMR' data type are significant.
* In other words, if timer size is not a binary-multiple of 8-bit octets
* (e.g. 20-bits or even 24-bits), then the next lower, binary-multiple
* octet word size SHOULD be configured (e.g. to 16-bits). However, the
* minimum supported word size for CPU timestamp timers is 8-bits.
* See also 'cpu_cfg.h CPU TIMESTAMP CONFIGURATION Note #2'
* & 'cpu_core.h CPU TIMESTAMP DATA TYPES Note #1'.
* (b) Timer SHOULD be an 'up' counter whose values increase with each time count.
* (1) If timer is a 'down' counter whose values decrease with each time count,
* then the returned timer value MUST be ones-complemented.
* (c) (1) When applicable, the amount of time measured by CPU timestamps is
* calculated by either of the following equations :
* (A) Time measured = Number timer counts * Timer period
* where
*
* Number timer counts Number of timer counts measured
* Timer period Timer's period in some units of
* (fractional) seconds
* Time measured Amount of time measured, in same
* units of (fractional) seconds
* as the Timer period
*
* Number timer counts
* (B) Time measured = ---------------------
* Timer frequency
*
* where
*
* Number timer counts Number of timer counts measured
* Timer frequency Timer's frequency in some units
* of counts per second
* Time measured Amount of time measured, in seconds
*
* (2) Timer period SHOULD be less than the typical measured time but MUST be less
* than the maximum measured time; otherwise, timer resolution inadequate to
* measure desired times.
*********************************************************************************************************
*/
#if (CPU_CFG_TS_TMR_EN == DEF_ENABLED)
CPU_TS_TMR CPU_TS_TmrRd (void)
{
CPU_TS_TMR ts_tmr_cnts;
ts_tmr_cnts = (CPU_TS_TMR)BSP_REG_DWT_CYCCNT;
return (ts_tmr_cnts);
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* CPU_TSxx_to_uSec()
* Description : Convert a 32-/64-bit CPU timestamp from timer counts to microseconds.
* Argument(s) : ts_cnts CPU timestamp (in timestamp timer counts [see Note #2aA]).
* Return(s) : Converted CPU timestamp (in microseconds [see Note #2aD]).
* Caller(s) : Application.
* This function is an (optional) CPU module application programming interface (API)
* function which MAY be implemented by application/BSP function(s) [see Note #1] &
* MAY be called by application function(s).
* Note(s) : (1) CPU_TS32_to_uSec()/CPU_TS64_to_uSec() are application/BSP functions that MAY be
* optionally defined by the developer when either of the following CPU features is
* enabled :
* (a) CPU timestamps
* (b) CPU interrupts disabled time measurements
* See 'cpu_cfg.h CPU TIMESTAMP CONFIGURATION Note #1'
* & 'cpu_cfg.h CPU INTERRUPTS DISABLED TIME MEASUREMENT CONFIGURATION Note #1a'.
* (2) (a) The amount of time measured by CPU timestamps is calculated by either of
* the following equations :
*
* 10^6 microseconds
* (1) Time measured = Number timer counts * ------------------- * Timer period
* 1 second
*
* Number timer counts 10^6 microseconds
* (2) Time measured = --------------------- * -------------------
* Timer frequency 1 second
*
* where
*
* (A) Number timer counts Number of timer counts measured
* (B) Timer frequency Timer's frequency in some units
* of counts per second
* (C) Timer period Timer's period in some units of
* (fractional) seconds
* (D) Time measured Amount of time measured,
* in microseconds
*
* (b) Timer period SHOULD be less than the typical measured time but MUST be less
* than the maximum measured time; otherwise, timer resolution inadequate to
* measure desired times.
*
* (c) Specific implementations may convert any number of CPU_TS32 or CPU_TS64 bits
* -- up to 32 or 64, respectively -- into microseconds.
*********************************************************************************************************
*/
#if (CPU_CFG_TS_32_EN == DEF_ENABLED)
CPU_INT64U CPU_TS32_to_uSec (CPU_TS32 ts_cnts)
{
CPU_INT64U ts_us;
CPU_INT64U fclk_freq;
fclk_freq = BSP_CPU_ClkFreq();
ts_us = ts_cnts / (fclk_freq / DEF_TIME_NBR_uS_PER_SEC);
return (ts_us);
}
#endif
#if (CPU_CFG_TS_64_EN == DEF_ENABLED)
CPU_INT64U CPU_TS64_to_uSec (CPU_TS64 ts_cnts)
{
CPU_INT64U ts_us;
CPU_INT64U fclk_freq;
fclk_freq = BSP_CPU_ClkFreq();
ts_us = ts_cnts / (fclk_freq / DEF_TIME_NBR_uS_PER_SEC);
return (ts_us);
}
#endif

25
UCOSIII/UCOS_BSP/bsp.h Normal file
View File

@@ -0,0 +1,25 @@
#ifndef BSP_PRESENT
#define BSP_PRESENT
#ifdef BSP_MODULE
#define BSP_EXT
#else
#define BSP_EXT extern
#endif
#include <stdio.h>
#include <stdarg.h>
#include <cpu.h>
#include <cpu_core.h>
#include <lib_def.h>
#include <lib_ascii.h>
#include <stm32f10x_conf.h>
void bsp_Init(void);
#endif

View File

@@ -0,0 +1,723 @@
/*
*********************************************************************************************************
* uC/CPU
* CPU CONFIGURATION & PORT LAYER
*
* (c) Copyright 2004-2011; Micrium, Inc.; Weston, FL
*
* All rights reserved. Protected by international copyright laws.
*
* uC/CPU is provided in source form to registered licensees ONLY. It is
* illegal to distribute this source code to any third party unless you receive
* written permission by an authorized Micrium representative. Knowledge of
* the source code may NOT be used to develop a similar product.
*
* Please help us continue to provide the Embedded community with the finest
* software available. Your honesty is greatly appreciated.
*
* You can contact us at www.micrium.com.
*********************************************************************************************************
*/
/*
*********************************************************************************************************
*
* CPU PORT FILE
*
* ARM-Cortex-M3
* GNU C Compiler
*
* Filename : cpu.h
* Version : V1.29.01.00
* Programmer(s) : JJL
* FT
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* MODULE
*
* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of
* the CPU module present pre-processor macro definition.
*********************************************************************************************************
*/
#ifndef CPU_MODULE_PRESENT /* See Note #1. */
#define CPU_MODULE_PRESENT
/*
*********************************************************************************************************
* CPU INCLUDE FILES
*
* Note(s) : (1) The following CPU files are located in the following directories :
*
* (a) \<Your Product Application>\cpu_cfg.h
*
* (b) (1) \<CPU-Compiler Directory>\cpu_def.h
* (2) \<CPU-Compiler Directory>\<cpu>\<compiler>\cpu*.*
*
* where
* <Your Product Application> directory path for Your Product's Application
* <CPU-Compiler Directory> directory path for common CPU-compiler software
* <cpu> directory name for specific CPU
* <compiler> directory name for specific compiler
*
* (2) Compiler MUST be configured to include as additional include path directories :
*
* (a) '\<Your Product Application>\' directory See Note #1a
*
* (b) (1) '\<CPU-Compiler Directory>\' directory See Note #1b1
* (2) '\<CPU-Compiler Directory>\<cpu>\<compiler>\' directory See Note #1b2
*
* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from
* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions.
*
* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric
* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to
* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED).
*********************************************************************************************************
*/
#include <cpu_def.h>
#include <cpu_cfg.h> /* See Note #3. */
/*$PAGE*/
/*
*********************************************************************************************************
* CONFIGURE STANDARD DATA TYPES
*
* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications.
*
* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer
* data type of a pointer to a function which returns void & has no arguments.
*
* (2) Example function pointer usage :
*
* CPU_FNCT_VOID FnctName;
*
* FnctName();
*
* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer
* data type of a pointer to a function which returns void & has a single void
* pointer argument.
*
* (2) Example function pointer usage :
*
* CPU_FNCT_PTR FnctName;
* void *p_obj
*
* FnctName(p_obj);
*********************************************************************************************************
*/
typedef void CPU_VOID;
typedef char CPU_CHAR; /* 8-bit character */
typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */
typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */
typedef signed char CPU_INT08S; /* 8-bit signed integer */
typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */
typedef signed short CPU_INT16S; /* 16-bit signed integer */
typedef unsigned int CPU_INT32U; /* 32-bit unsigned integer */
typedef signed int CPU_INT32S; /* 32-bit signed integer */
typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */
typedef signed long long CPU_INT64S; /* 64-bit signed integer */
typedef float CPU_FP32; /* 32-bit floating point */
typedef double CPU_FP64; /* 64-bit floating point */
typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */
typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */
typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */
typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */
typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */
typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */
/*$PAGE*/
/*
*********************************************************************************************************
* CPU WORD CONFIGURATION
*
* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or
* compiler's word sizes :
*
* CPU_WORD_SIZE_08 8-bit word size
* CPU_WORD_SIZE_16 16-bit word size
* CPU_WORD_SIZE_32 32-bit word size
* CPU_WORD_SIZE_64 64-bit word size
*
* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order :
*
* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant
* octet @ lowest memory address)
* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant
* octet @ lowest memory address)
*********************************************************************************************************
*/
/* Define CPU word sizes (see Note #1) : */
#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */
#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */
#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */
#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */
/*
*********************************************************************************************************
* CONFIGURE CPU ADDRESS & DATA TYPES
*********************************************************************************************************
*/
/* CPU address type based on address bus size. */
#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32)
typedef CPU_INT32U CPU_ADDR;
#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16)
typedef CPU_INT16U CPU_ADDR;
#else
typedef CPU_INT08U CPU_ADDR;
#endif
/* CPU data type based on data bus size. */
#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32)
typedef CPU_INT32U CPU_DATA;
#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16)
typedef CPU_INT16U CPU_DATA;
#else
typedef CPU_INT08U CPU_DATA;
#endif
typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */
typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */
/*
*********************************************************************************************************
* CPU STACK CONFIGURATION
*
* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order :
*
* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack
* memory address after data is pushed onto the stack
* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack
* memory address after data is pushed onto the stack
*********************************************************************************************************
*/
#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */
typedef CPU_INT32U CPU_STK; /* Defines CPU stack word size (in octets). */
typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size (in number of CPU_STKs). */
/*$PAGE*/
/*
*********************************************************************************************************
* CRITICAL SECTION CONFIGURATION
*
* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method :
*
* Enter/Exit critical sections by ...
*
* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts
* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack
* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable
*
* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support
* multiple levels of interrupts. However, with some CPUs/compilers, this is the only
* available method.
*
* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple
* levels of interrupts. However, this method assumes that the compiler provides C-level
* &/or assembly-level functionality for the following :
*
* ENTER CRITICAL SECTION :
* (1) Push/save interrupt status onto a local stack
* (2) Disable interrupts
*
* EXIT CRITICAL SECTION :
* (3) Pop/restore interrupt status from a local stack
*
* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple
* levels of interrupts. However, this method assumes that the compiler provides C-level
* &/or assembly-level functionality for the following :
*
* ENTER CRITICAL SECTION :
* (1) Save interrupt status into a local variable
* (2) Disable interrupts
*
* EXIT CRITICAL SECTION :
* (3) Restore interrupt status from a local variable
*
* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT
* allow inline assembly in C source files, critical section macro's MUST call an assembly
* subroutine defined in a 'cpu_a.asm' file located in the following software directory :
*
* \<CPU-Compiler Directory>\<cpu>\<compiler>\
*
* where
* <CPU-Compiler Directory> directory path for common CPU-compiler software
* <cpu> directory name for specific CPU
* <compiler> directory name for specific compiler
*
* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need
* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured).
*
* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if
* used, MUST be declared following ALL other local variables.
*
* Example :
*
* void Fnct (void)
* {
* CPU_INT08U val_08;
* CPU_INT16U val_16;
* CPU_INT32U val_32;
* CPU_SR_ALLOC(); MUST be declared after ALL other local variables
* :
* :
* }
*
* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to
* completely store the CPU's/compiler's status word.
*********************************************************************************************************
*/
/*$PAGE*/
/* Configure CPU critical method (see Note #1) : */
#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL
typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */
/* Allocates CPU status register word (see Note #3a). */
#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)
#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0
#else
#define CPU_SR_ALLOC()
#endif
#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/
#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */
#ifdef CPU_CFG_INT_DIS_MEAS_EN
/* Disable interrupts, ... */
/* & start interrupts disabled time measurement.*/
#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \
CPU_IntDisMeasStart(); } while (0)
/* Stop & measure interrupts disabled time, */
/* ... & re-enable interrupts. */
#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \
CPU_INT_EN(); } while (0)
#else
#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */
#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* CPU COUNT ZEROS CONFIGURATION
*
* Note(s) : (1) (a) Configure CPU_CFG_LEAD_ZEROS_ASM_PRESENT to define count leading zeros bits
* function(s) in :
*
* (1) 'cpu_a.asm', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/
* 'cpu_cfg.h' to enable assembly-optimized function(s)
*
* (2) 'cpu_core.c', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/
* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise
*
* (b) Configure CPU_CFG_TRAIL_ZEROS_ASM_PRESENT to define count trailing zeros bits
* function(s) in :
*
* (1) 'cpu_a.asm', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/
* 'cpu_cfg.h' to enable assembly-optimized function(s)
*
* (2) 'cpu_core.c', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/
* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise
*********************************************************************************************************
*/
/* Configure CPU count leading zeros bits ... */
#define CPU_CFG_LEAD_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1a). */
/* Configure CPU count trailing zeros bits ... */
#define CPU_CFG_TRAIL_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1b). */
/*$PAGE*/
/*
*********************************************************************************************************
* FUNCTION PROTOTYPES
*********************************************************************************************************
*/
void CPU_IntDis (void);
void CPU_IntEn (void);
void CPU_IntSrcDis (CPU_INT08U pos);
void CPU_IntSrcEn (CPU_INT08U pos);
void CPU_IntSrcPendClr(CPU_INT08U pos);
CPU_INT16S CPU_IntSrcPrioGet(CPU_INT08U pos);
void CPU_IntSrcPrioSet(CPU_INT08U pos,
CPU_INT08U prio);
CPU_SR CPU_SR_Save (void);
void CPU_SR_Restore (CPU_SR cpu_sr);
void CPU_WaitForInt (void);
void CPU_WaitForExcept(void);
CPU_DATA CPU_RevBits (CPU_DATA val);
void CPU_BitBandClr (CPU_ADDR addr,
CPU_INT08U bit_nbr);
void CPU_BitBandSet (CPU_ADDR addr,
CPU_INT08U bit_nbr);
/*$PAGE*/
/*
*********************************************************************************************************
* INTERRUPT SOURCES
*********************************************************************************************************
*/
#define CPU_INT_STK_PTR 0u
#define CPU_INT_RESET 1u
#define CPU_INT_NMI 2u
#define CPU_INT_HFAULT 3u
#define CPU_INT_MEM 4u
#define CPU_INT_BUSFAULT 5u
#define CPU_INT_USAGEFAULT 6u
#define CPU_INT_RSVD_07 7u
#define CPU_INT_RSVD_08 8u
#define CPU_INT_RSVD_09 9u
#define CPU_INT_RSVD_10 10u
#define CPU_INT_SVCALL 11u
#define CPU_INT_DBGMON 12u
#define CPU_INT_RSVD_13 13u
#define CPU_INT_PENDSV 14u
#define CPU_INT_SYSTICK 15u
#define CPU_INT_EXT0 16u
/*
*********************************************************************************************************
* CPU REGISTERS
*********************************************************************************************************
*/
#define CPU_REG_NVIC_NVIC (*((CPU_REG32 *)(0xE000E004))) /* Int Ctrl'er Type Reg. */
#define CPU_REG_NVIC_ST_CTRL (*((CPU_REG32 *)(0xE000E010))) /* SysTick Ctrl & Status Reg. */
#define CPU_REG_NVIC_ST_RELOAD (*((CPU_REG32 *)(0xE000E014))) /* SysTick Reload Value Reg. */
#define CPU_REG_NVIC_ST_CURRENT (*((CPU_REG32 *)(0xE000E018))) /* SysTick Current Value Reg. */
#define CPU_REG_NVIC_ST_CAL (*((CPU_REG32 *)(0xE000E01C))) /* SysTick Calibration Value Reg. */
#define CPU_REG_NVIC_SETEN(n) (*((CPU_REG32 *)(0xE000E100 + (n) * 4u))) /* IRQ Set En Reg. */
#define CPU_REG_NVIC_CLREN(n) (*((CPU_REG32 *)(0xE000E180 + (n) * 4u))) /* IRQ Clr En Reg. */
#define CPU_REG_NVIC_SETPEND(n) (*((CPU_REG32 *)(0xE000E200 + (n) * 4u))) /* IRQ Set Pending Reg. */
#define CPU_REG_NVIC_CLRPEND(n) (*((CPU_REG32 *)(0xE000E280 + (n) * 4u))) /* IRQ Clr Pending Reg. */
#define CPU_REG_NVIC_ACTIVE(n) (*((CPU_REG32 *)(0xE000E300 + (n) * 4u))) /* IRQ Active Reg. */
#define CPU_REG_NVIC_PRIO(n) (*((CPU_REG32 *)(0xE000E400 + (n) * 4u))) /* IRQ Prio Reg. */
#define CPU_REG_NVIC_CPUID (*((CPU_REG32 *)(0xE000ED00))) /* CPUID Base Reg. */
#define CPU_REG_NVIC_ICSR (*((CPU_REG32 *)(0xE000ED04))) /* Int Ctrl State Reg. */
#define CPU_REG_NVIC_VTOR (*((CPU_REG32 *)(0xE000ED08))) /* Vect Tbl Offset Reg. */
#define CPU_REG_NVIC_AIRCR (*((CPU_REG32 *)(0xE000ED0C))) /* App Int/Reset Ctrl Reg. */
#define CPU_REG_NVIC_SCR (*((CPU_REG32 *)(0xE000ED10))) /* System Ctrl Reg. */
#define CPU_REG_NVIC_CCR (*((CPU_REG32 *)(0xE000ED14))) /* Cfg Ctrl Reg. */
#define CPU_REG_NVIC_SHPRI1 (*((CPU_REG32 *)(0xE000ED18))) /* System Handlers 4 to 7 Prio. */
#define CPU_REG_NVIC_SHPRI2 (*((CPU_REG32 *)(0xE000ED1C))) /* System Handlers 8 to 11 Prio. */
#define CPU_REG_NVIC_SHPRI3 (*((CPU_REG32 *)(0xE000ED20))) /* System Handlers 12 to 15 Prio. */
#define CPU_REG_NVIC_SHCSR (*((CPU_REG32 *)(0xE000ED24))) /* System Handler Ctrl & State Reg. */
#define CPU_REG_NVIC_CFSR (*((CPU_REG32 *)(0xE000ED28))) /* Configurable Fault Status Reg. */
#define CPU_REG_NVIC_HFSR (*((CPU_REG32 *)(0xE000ED2C))) /* Hard Fault Status Reg. */
#define CPU_REG_NVIC_DFSR (*((CPU_REG32 *)(0xE000ED30))) /* Debug Fault Status Reg. */
#define CPU_REG_NVIC_MMFAR (*((CPU_REG32 *)(0xE000ED34))) /* Mem Manage Addr Reg. */
#define CPU_REG_NVIC_BFAR (*((CPU_REG32 *)(0xE000ED38))) /* Bus Fault Addr Reg. */
#define CPU_REG_NVIC_AFSR (*((CPU_REG32 *)(0xE000ED3C))) /* Aux Fault Status Reg. */
#define CPU_REG_NVIC_PFR0 (*((CPU_REG32 *)(0xE000ED40))) /* Processor Feature Reg 0. */
#define CPU_REG_NVIC_PFR1 (*((CPU_REG32 *)(0xE000ED44))) /* Processor Feature Reg 1. */
#define CPU_REG_NVIC_DFR0 (*((CPU_REG32 *)(0xE000ED48))) /* Debug Feature Reg 0. */
#define CPU_REG_NVIC_AFR0 (*((CPU_REG32 *)(0xE000ED4C))) /* Aux Feature Reg 0. */
#define CPU_REG_NVIC_MMFR0 (*((CPU_REG32 *)(0xE000ED50))) /* Memory Model Feature Reg 0. */
#define CPU_REG_NVIC_MMFR1 (*((CPU_REG32 *)(0xE000ED54))) /* Memory Model Feature Reg 1. */
#define CPU_REG_NVIC_MMFR2 (*((CPU_REG32 *)(0xE000ED58))) /* Memory Model Feature Reg 2. */
#define CPU_REG_NVIC_MMFR3 (*((CPU_REG32 *)(0xE000ED5C))) /* Memory Model Feature Reg 3. */
#define CPU_REG_NVIC_ISAFR0 (*((CPU_REG32 *)(0xE000ED60))) /* ISA Feature Reg 0. */
#define CPU_REG_NVIC_ISAFR1 (*((CPU_REG32 *)(0xE000ED64))) /* ISA Feature Reg 1. */
#define CPU_REG_NVIC_ISAFR2 (*((CPU_REG32 *)(0xE000ED68))) /* ISA Feature Reg 2. */
#define CPU_REG_NVIC_ISAFR3 (*((CPU_REG32 *)(0xE000ED6C))) /* ISA Feature Reg 3. */
#define CPU_REG_NVIC_ISAFR4 (*((CPU_REG32 *)(0xE000ED70))) /* ISA Feature Reg 4. */
#define CPU_REG_NVIC_SW_TRIG (*((CPU_REG32 *)(0xE000EF00))) /* Software Trigger Int Reg. */
#define CPU_REG_MPU_TYPE (*((CPU_REG32 *)(0xE000ED90))) /* MPU Type Reg. */
#define CPU_REG_MPU_CTRL (*((CPU_REG32 *)(0xE000ED94))) /* MPU Ctrl Reg. */
#define CPU_REG_MPU_REG_NBR (*((CPU_REG32 *)(0xE000ED98))) /* MPU Region Nbr Reg. */
#define CPU_REG_MPU_REG_BASE (*((CPU_REG32 *)(0xE000ED9C))) /* MPU Region Base Addr Reg. */
#define CPU_REG_MPU_REG_ATTR (*((CPU_REG32 *)(0xE000EDA0))) /* MPU Region Attrib & Size Reg. */
#define CPU_REG_DBG_CTRL (*((CPU_REG32 *)(0xE000EDF0))) /* Debug Halting Ctrl & Status Reg. */
#define CPU_REG_DBG_SELECT (*((CPU_REG32 *)(0xE000EDF4))) /* Debug Core Reg Selector Reg. */
#define CPU_REG_DBG_DATA (*((CPU_REG32 *)(0xE000EDF8))) /* Debug Core Reg Data Reg. */
#define CPU_REG_DBG_INT (*((CPU_REG32 *)(0xE000EDFC))) /* Debug Except & Monitor Ctrl Reg. */
/*$PAGE*/
/*
*********************************************************************************************************
* CPU REGISTER BITS
*********************************************************************************************************
*/
/* ---------- SYSTICK CTRL & STATUS REG BITS ---------- */
#define CPU_REG_NVIC_ST_CTRL_COUNTFLAG 0x00010000
#define CPU_REG_NVIC_ST_CTRL_CLKSOURCE 0x00000004
#define CPU_REG_NVIC_ST_CTRL_TICKINT 0x00000002
#define CPU_REG_NVIC_ST_CTRL_ENABLE 0x00000001
/* -------- SYSTICK CALIBRATION VALUE REG BITS -------- */
#define CPU_REG_NVIC_ST_CAL_NOREF 0x80000000
#define CPU_REG_NVIC_ST_CAL_SKEW 0x40000000
/* -------------- INT CTRL STATE REG BITS ------------- */
#define CPU_REG_NVIC_ICSR_NMIPENDSET 0x80000000
#define CPU_REG_NVIC_ICSR_PENDSVSET 0x10000000
#define CPU_REG_NVIC_ICSR_PENDSVCLR 0x08000000
#define CPU_REG_NVIC_ICSR_PENDSTSET 0x04000000
#define CPU_REG_NVIC_ICSR_PENDSTCLR 0x02000000
#define CPU_REG_NVIC_ICSR_ISRPREEMPT 0x00800000
#define CPU_REG_NVIC_ICSR_ISRPENDING 0x00400000
#define CPU_REG_NVIC_ICSR_RETTOBASE 0x00000800
/* ------------- VECT TBL OFFSET REG BITS ------------- */
#define CPU_REG_NVIC_VTOR_TBLBASE 0x20000000
/* ------------ APP INT/RESET CTRL REG BITS ----------- */
#define CPU_REG_NVIC_AIRCR_ENDIANNESS 0x00008000
#define CPU_REG_NVIC_AIRCR_SYSRESETREQ 0x00000004
#define CPU_REG_NVIC_AIRCR_VECTCLRACTIVE 0x00000002
#define CPU_REG_NVIC_AIRCR_VECTRESET 0x00000001
/* --------------- SYSTEM CTRL REG BITS --------------- */
#define CPU_REG_NVIC_SCR_SEVONPEND 0x00000010
#define CPU_REG_NVIC_SCR_SLEEPDEEP 0x00000004
#define CPU_REG_NVIC_SCR_SLEEPONEXIT 0x00000002
/* ----------------- CFG CTRL REG BITS ---------------- */
#define CPU_REG_NVIC_CCR_STKALIGN 0x00000200
#define CPU_REG_NVIC_CCR_BFHFNMIGN 0x00000100
#define CPU_REG_NVIC_CCR_DIV_0_TRP 0x00000010
#define CPU_REG_NVIC_CCR_UNALIGN_TRP 0x00000008
#define CPU_REG_NVIC_CCR_USERSETMPEND 0x00000002
#define CPU_REG_NVIC_CCR_NONBASETHRDENA 0x00000001
/* ------- SYSTEM HANDLER CTRL & STATE REG BITS ------- */
#define CPU_REG_NVIC_SHCSR_USGFAULTENA 0x00040000
#define CPU_REG_NVIC_SHCSR_BUSFAULTENA 0x00020000
#define CPU_REG_NVIC_SHCSR_MEMFAULTENA 0x00010000
#define CPU_REG_NVIC_SHCSR_SVCALLPENDED 0x00008000
#define CPU_REG_NVIC_SHCSR_BUSFAULTPENDED 0x00004000
#define CPU_REG_NVIC_SHCSR_MEMFAULTPENDED 0x00002000
#define CPU_REG_NVIC_SHCSR_USGFAULTPENDED 0x00001000
#define CPU_REG_NVIC_SHCSR_SYSTICKACT 0x00000800
#define CPU_REG_NVIC_SHCSR_PENDSVACT 0x00000400
#define CPU_REG_NVIC_SHCSR_MONITORACT 0x00000100
#define CPU_REG_NVIC_SHCSR_SVCALLACT 0x00000080
#define CPU_REG_NVIC_SHCSR_USGFAULTACT 0x00000008
#define CPU_REG_NVIC_SHCSR_BUSFAULTACT 0x00000002
#define CPU_REG_NVIC_SHCSR_MEMFAULTACT 0x00000001
/*$PAGE*/
/* -------- CONFIGURABLE FAULT STATUS REG BITS -------- */
#define CPU_REG_NVIC_CFSR_DIVBYZERO 0x02000000
#define CPU_REG_NVIC_CFSR_UNALIGNED 0x01000000
#define CPU_REG_NVIC_CFSR_NOCP 0x00080000
#define CPU_REG_NVIC_CFSR_INVPC 0x00040000
#define CPU_REG_NVIC_CFSR_INVSTATE 0x00020000
#define CPU_REG_NVIC_CFSR_UNDEFINSTR 0x00010000
#define CPU_REG_NVIC_CFSR_BFARVALID 0x00008000
#define CPU_REG_NVIC_CFSR_STKERR 0x00001000
#define CPU_REG_NVIC_CFSR_UNSTKERR 0x00000800
#define CPU_REG_NVIC_CFSR_IMPRECISERR 0x00000400
#define CPU_REG_NVIC_CFSR_PRECISERR 0x00000200
#define CPU_REG_NVIC_CFSR_IBUSERR 0x00000100
#define CPU_REG_NVIC_CFSR_MMARVALID 0x00000080
#define CPU_REG_NVIC_CFSR_MSTKERR 0x00000010
#define CPU_REG_NVIC_CFSR_MUNSTKERR 0x00000008
#define CPU_REG_NVIC_CFSR_DACCVIOL 0x00000002
#define CPU_REG_NVIC_CFSR_IACCVIOL 0x00000001
/* ------------ HARD FAULT STATUS REG BITS ------------ */
#define CPU_REG_NVIC_HFSR_DEBUGEVT 0x80000000
#define CPU_REG_NVIC_HFSR_FORCED 0x40000000
#define CPU_REG_NVIC_HFSR_VECTTBL 0x00000002
/* ------------ DEBUG FAULT STATUS REG BITS ----------- */
#define CPU_REG_NVIC_DFSR_EXTERNAL 0x00000010
#define CPU_REG_NVIC_DFSR_VCATCH 0x00000008
#define CPU_REG_NVIC_DFSR_DWTTRAP 0x00000004
#define CPU_REG_NVIC_DFSR_BKPT 0x00000002
#define CPU_REG_NVIC_DFSR_HALTED 0x00000001
/*
*********************************************************************************************************
* CPU REGISTER MASK
*********************************************************************************************************
*/
#define CPU_MSK_NVIC_ICSR_VECT_ACTIVE 0x000001FF
/*$PAGE*/
/*
*********************************************************************************************************
* CONFIGURATION ERRORS
*********************************************************************************************************
*/
#ifndef CPU_CFG_ADDR_SIZE
#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' "
#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]"
#error " [ || CPU_WORD_SIZE_16 16-bit alignment]"
#error " [ || CPU_WORD_SIZE_32 32-bit alignment]"
#error " [ || CPU_WORD_SIZE_64 64-bit alignment]"
#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \
(CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \
(CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \
(CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64))
#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' "
#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]"
#error " [ || CPU_WORD_SIZE_16 16-bit alignment]"
#error " [ || CPU_WORD_SIZE_32 32-bit alignment]"
#error " [ || CPU_WORD_SIZE_64 64-bit alignment]"
#endif
#ifndef CPU_CFG_DATA_SIZE
#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' "
#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]"
#error " [ || CPU_WORD_SIZE_16 16-bit alignment]"
#error " [ || CPU_WORD_SIZE_32 32-bit alignment]"
#error " [ || CPU_WORD_SIZE_64 64-bit alignment]"
#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \
(CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \
(CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \
(CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64))
#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' "
#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]"
#error " [ || CPU_WORD_SIZE_16 16-bit alignment]"
#error " [ || CPU_WORD_SIZE_32 32-bit alignment]"
#error " [ || CPU_WORD_SIZE_64 64-bit alignment]"
#endif
#ifndef CPU_CFG_DATA_SIZE_MAX
#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' "
#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]"
#error " [ || CPU_WORD_SIZE_16 16-bit alignment]"
#error " [ || CPU_WORD_SIZE_32 32-bit alignment]"
#error " [ || CPU_WORD_SIZE_64 64-bit alignment]"
#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \
(CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \
(CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \
(CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64))
#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' "
#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]"
#error " [ || CPU_WORD_SIZE_16 16-bit alignment]"
#error " [ || CPU_WORD_SIZE_32 32-bit alignment]"
#error " [ || CPU_WORD_SIZE_64 64-bit alignment]"
#endif
#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE)
#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' "
#error " [MUST be >= CPU_CFG_DATA_SIZE]"
#endif
/*$PAGE*/
#ifndef CPU_CFG_ENDIAN_TYPE
#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' "
#error " [MUST be CPU_ENDIAN_TYPE_BIG ]"
#error " [ || CPU_ENDIAN_TYPE_LITTLE]"
#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \
(CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE))
#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' "
#error " [MUST be CPU_ENDIAN_TYPE_BIG ]"
#error " [ || CPU_ENDIAN_TYPE_LITTLE]"
#endif
#ifndef CPU_CFG_STK_GROWTH
#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' "
#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]"
#error " [ || CPU_STK_GROWTH_HI_TO_LO]"
#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \
(CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO))
#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' "
#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]"
#error " [ || CPU_STK_GROWTH_HI_TO_LO]"
#endif
#ifndef CPU_CFG_CRITICAL_METHOD
#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' "
#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]"
#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]"
#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]"
#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \
(CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \
(CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL))
#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' "
#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]"
#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]"
#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]"
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* MODULE END
*
* Note(s) : (1) See 'cpu.h MODULE'.
*********************************************************************************************************
*/
#endif /* End of CPU module include. */

View File

@@ -0,0 +1,296 @@
@********************************************************************************************************
@ uC/CPU
@ CPU CONFIGURATION & PORT LAYER
@
@ (c) Copyright 2004-2011; Micrium, Inc.; Weston, FL
@
@ All rights reserved. Protected by international copyright laws.
@
@ uC/CPU is provided in source form to registered licensees ONLY. It is
@ illegal to distribute this source code to any third party unless you receive
@ written permission by an authorized Micrium representative. Knowledge of
@ the source code may NOT be used to develop a similar product.
@
@ Please help us continue to provide the Embedded community with the finest
@ software available. Your honesty is greatly appreciated.
@
@ You can contact us at www.micrium.com.
@********************************************************************************************************
@********************************************************************************************************
@
@ CPU PORT FILE
@
@ ARM-Cortex-M3
@ GNU C Compiler
@
@ Filename : cpu_a.s
@ Version : V1.29.01.00
@ Programmer(s) : JJL
@********************************************************************************************************
@********************************************************************************************************
@ PUBLIC FUNCTIONS
@********************************************************************************************************
.global CPU_IntDis
.global CPU_IntEn
.global CPU_SR_Save
.global CPU_SR_Restore
.global CPU_WaitForInt
.global CPU_WaitForExcept
.global CPU_CntLeadZeros
.global CPU_CntTrailZeros
.global CPU_RevBits
@********************************************************************************************************
@ CODE GENERATION DIRECTIVES
@********************************************************************************************************
.text
.align 2
.thumb
.syntax unified
@$PAGE
@********************************************************************************************************
@ DISABLE and ENABLE INTERRUPTS
@
@ Description : Disable/Enable interrupts.
@
@ Prototypes : void CPU_IntDis(void);
@ void CPU_IntEn (void);
@********************************************************************************************************
.thumb_func
CPU_IntDis:
CPSID I
BX LR
.thumb_func
CPU_IntEn:
CPSIE I
BX LR
@********************************************************************************************************
@ CRITICAL SECTION FUNCTIONS
@
@ Description : Disable/Enable interrupts by preserving the state of interrupts. Generally speaking, the
@ state of the interrupt disable flag is stored in the local variable 'cpu_sr' & interrupts
@ are then disabled ('cpu_sr' is allocated in all functions that need to disable interrupts).
@ The previous interrupt state is restored by copying 'cpu_sr' into the CPU's status register.
@
@ Prototypes : CPU_SR CPU_SR_Save (void);
@ void CPU_SR_Restore(CPU_SR cpu_sr);
@
@ Note(s) : (1) These functions are used in general like this :
@
@ void Task (void *p_arg)
@ {
@ CPU_SR_ALLOC(); /* Allocate storage for CPU status register */
@ :
@ :
@ CPU_CRITICAL_ENTER(); /* cpu_sr = CPU_SR_Save(); */
@ :
@ :
@ CPU_CRITICAL_EXIT(); /* CPU_SR_Restore(cpu_sr); */
@ :
@ }
@********************************************************************************************************
.thumb_func
CPU_SR_Save:
MRS R0, PRIMASK @ Set prio int mask to mask all (except faults)
CPSID I
BX LR
.thumb_func
CPU_SR_Restore: @ See Note #2.
MSR PRIMASK, R0
BX LR
@$PAGE
@********************************************************************************************************
@ WAIT FOR INTERRUPT
@
@ Description : Enters sleep state, which will be exited when an interrupt is received.
@
@ Prototypes : void CPU_WaitForInt (void)
@
@ Argument(s) : none.
@********************************************************************************************************
.thumb_func
CPU_WaitForInt:
WFI @ Wait for interrupt
BX LR
@********************************************************************************************************
@ WAIT FOR EXCEPTION
@
@ Description : Enters sleep state, which will be exited when an exception is received.
@
@ Prototypes : void CPU_WaitForExcept (void)
@
@ Argument(s) : none.
@********************************************************************************************************
.thumb_func
CPU_WaitForExcept:
WFE @ Wait for exception
BX LR
@$PAGE
@********************************************************************************************************
@ CPU_CntLeadZeros()
@ COUNT LEADING ZEROS
@
@ Description : Counts the number of contiguous, most-significant, leading zero bits before the
@ first binary one bit in a data value.
@
@ Prototype : CPU_DATA CPU_CntLeadZeros(CPU_DATA val);
@
@ Argument(s) : val Data value to count leading zero bits.
@
@ Return(s) : Number of contiguous, most-significant, leading zero bits in 'val'.
@
@ Caller(s) : Application.
@
@ This function is an INTERNAL CPU module function but MAY be called by application
@ function(s).
@
@ Note(s) : (1) (a) Supports 32-bit data value size as configured by 'CPU_DATA' (see 'cpu.h
@ CPU WORD CONFIGURATION Note #1').
@
@ (b) For 32-bit values :
@
@ b31 b30 b29 ... b04 b03 b02 b01 b00 # Leading Zeros
@ --- --- --- --- --- --- --- --- ---------------
@ 1 x x x x x x x 0
@ 0 1 x x x x x x 1
@ 0 0 1 x x x x x 2
@ : : : : : : : : :
@ : : : : : : : : :
@ 0 0 0 1 x x x x 27
@ 0 0 0 0 1 x x x 28
@ 0 0 0 0 0 1 x x 29
@ 0 0 0 0 0 0 1 x 30
@ 0 0 0 0 0 0 0 1 31
@ 0 0 0 0 0 0 0 0 32
@
@
@ (2) MUST be defined in 'cpu_a.asm' (or 'cpu_c.c') if CPU_CFG_LEAD_ZEROS_ASM_PRESENT is
@ #define'd in 'cpu_cfg.h' or 'cpu.h'.
@********************************************************************************************************
.thumb_func
CPU_CntLeadZeros:
CLZ R0, R0 @ Count leading zeros
BX LR
@$PAGE
@********************************************************************************************************
@ CPU_CntTrailZeros()
@ COUNT TRAILING ZEROS
@
@ Description : Counts the number of contiguous, least-significant, trailing zero bits before the
@ first binary one bit in a data value.
@
@ Prototype : CPU_DATA CPU_CntTrailZeros(CPU_DATA val);
@
@ Argument(s) : val Data value to count trailing zero bits.
@
@ Return(s) : Number of contiguous, least-significant, trailing zero bits in 'val'.
@
@ Caller(s) : Application.
@
@ This function is an INTERNAL CPU module function but MAY be called by application
@ function(s).
@
@ Note(s) : (1) (a) Supports 32-bit data value size as configured by 'CPU_DATA' (see 'cpu.h
@ CPU WORD CONFIGURATION Note #1').
@
@ (b) For 32-bit values :
@
@ b31 b30 b29 b28 b27 ... b02 b01 b00 # Trailing Zeros
@ --- --- --- --- --- --- --- --- ----------------
@ x x x x x x x 1 0
@ x x x x x x 1 0 1
@ x x x x x 1 0 0 2
@ : : : : : : : : :
@ : : : : : : : : :
@ x x x x 1 0 0 0 27
@ x x x 1 0 0 0 0 28
@ x x 1 0 0 0 0 0 29
@ x 1 0 0 0 0 0 0 30
@ 1 0 0 0 0 0 0 0 31
@ 0 0 0 0 0 0 0 0 32
@
@
@ (2) MUST be defined in 'cpu_a.asm' (or 'cpu_c.c') if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT is
@ #define'd in 'cpu_cfg.h' or 'cpu.h'.
@********************************************************************************************************
.thumb_func
CPU_CntTrailZeros:
RBIT R0, R0 @ Reverse bits
CLZ R0, R0 @ Count leading zeros
BX LR
@$PAGE
@********************************************************************************************************
@ CPU_RevBits()
@ REVERSE BITS
@
@ Description : Reverses the bits in a data value.
@
@ Prototypes : CPU_DATA CPU_RevBits(CPU_DATA val);
@
@ Argument(s) : val Data value to reverse bits.
@
@ Return(s) : Value with all bits in 'val' reversed (see Note #1).
@
@ Caller(s) : Application.
@
@ This function is an INTERNAL CPU module function but MAY be called by application function(s).
@
@ Note(s) : (1) The final, reversed data value for 'val' is such that :
@
@ 'val's final bit 0 = 'val's original bit N
@ 'val's final bit 1 = 'val's original bit (N - 1)
@ 'val's final bit 2 = 'val's original bit (N - 2)
@
@ ... ...
@
@ 'val's final bit (N - 2) = 'val's original bit 2
@ 'val's final bit (N - 1) = 'val's original bit 1
@ 'val's final bit N = 'val's original bit 0
@********************************************************************************************************
.thumb_func
CPU_RevBits:
RBIT R0, R0 @ Reverse bits
BX LR
@$PAGE
@********************************************************************************************************
@ CPU ASSEMBLY PORT FILE END
@********************************************************************************************************
.end

View File

@@ -0,0 +1,755 @@
/*
*********************************************************************************************************
* uC/CPU
* CPU CONFIGURATION & PORT LAYER
*
* (c) Copyright 2004-2011; Micrium, Inc.; Weston, FL
*
* All rights reserved. Protected by international copyright laws.
*
* uC/CPU is provided in source form to registered licensees ONLY. It is
* illegal to distribute this source code to any third party unless you receive
* written permission by an authorized Micrium representative. Knowledge of
* the source code may NOT be used to develop a similar product.
*
* Please help us continue to provide the Embedded community with the finest
* software available. Your honesty is greatly appreciated.
*
* You can contact us at www.micrium.com.
*********************************************************************************************************
*/
/*
*********************************************************************************************************
*
* CPU PORT FILE
*
* ARM-Cortex-M3
* GNU C Compiler
*
* Filename : cpu_c.c
* Version : V1.29.01.00
* Programmer(s) : JJL
* BAN
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* INCLUDE FILES
*********************************************************************************************************
*/
#define MICRIUM_SOURCE
#include <cpu.h>
#include <cpu_core.h>
#include <lib_def.h>
/*$PAGE*/
/*
*********************************************************************************************************
* LOCAL DEFINES
*********************************************************************************************************
*/
#define CPU_INT_SRC_POS_MAX ((((CPU_REG_NVIC_NVIC + 1) & 0x1F) * 32) + 16)
#define CPU_BIT_BAND_SRAM_REG_LO 0x20000000
#define CPU_BIT_BAND_SRAM_REG_HI 0x200FFFFF
#define CPU_BIT_BAND_SRAM_BASE 0x22000000
#define CPU_BIT_BAND_PERIPH_REG_LO 0x40000000
#define CPU_BIT_BAND_PERIPH_REG_HI 0x400FFFFF
#define CPU_BIT_BAND_PERIPH_BASE 0x42000000
/*
*********************************************************************************************************
* LOCAL CONSTANTS
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* LOCAL DATA TYPES
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* LOCAL TABLES
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* LOCAL GLOBAL VARIABLES
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* LOCAL FUNCTION PROTOTYPES
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* LOCAL CONFIGURATION ERRORS
*********************************************************************************************************
*/
/*$PAGE*/
/*
*********************************************************************************************************
* CPU_BitBandClr()
*
* Description : Clear bit in bit-band region.
*
* Argument(s) : addr Byte address in memory space.
*
* bit_nbr Bit number in byte.
*
* Return(s) : none.
*
* Caller(s) : Application.
*
* Note(s) : none.
*********************************************************************************************************
*/
void CPU_BitBandClr (CPU_ADDR addr,
CPU_INT08U bit_nbr)
{
CPU_ADDR bit_word_off;
CPU_ADDR bit_word_addr;
if ((addr >= CPU_BIT_BAND_SRAM_REG_LO) &&
(addr <= CPU_BIT_BAND_SRAM_REG_HI)) {
bit_word_off = ((addr - CPU_BIT_BAND_SRAM_REG_LO ) * 32) + (bit_nbr * 4);
bit_word_addr = CPU_BIT_BAND_SRAM_BASE + bit_word_off;
*(volatile CPU_INT32U *)(bit_word_addr) = 0;
} else if ((addr >= CPU_BIT_BAND_PERIPH_REG_LO) &&
(addr <= CPU_BIT_BAND_PERIPH_REG_HI)) {
bit_word_off = ((addr - CPU_BIT_BAND_PERIPH_REG_LO) * 32) + (bit_nbr * 4);
bit_word_addr = CPU_BIT_BAND_PERIPH_BASE + bit_word_off;
*(volatile CPU_INT32U *)(bit_word_addr) = 0;
}
}
/*$PAGE*/
/*
*********************************************************************************************************
* CPU_BitBandSet()
*
* Description : Set bit in bit-band region.
*
* Argument(s) : addr Byte address in memory space.
*
* bit_nbr Bit number in byte.
*
* Return(s) : none.
*
* Caller(s) : Application.
*
* Note(s) : none.
*********************************************************************************************************
*/
void CPU_BitBandSet (CPU_ADDR addr,
CPU_INT08U bit_nbr)
{
CPU_ADDR bit_word_off;
CPU_ADDR bit_word_addr;
if ((addr >= CPU_BIT_BAND_SRAM_REG_LO) &&
(addr <= CPU_BIT_BAND_SRAM_REG_HI)) {
bit_word_off = ((addr - CPU_BIT_BAND_SRAM_REG_LO ) * 32) + (bit_nbr * 4);
bit_word_addr = CPU_BIT_BAND_SRAM_BASE + bit_word_off;
*(volatile CPU_INT32U *)(bit_word_addr) = 1;
} else if ((addr >= CPU_BIT_BAND_PERIPH_REG_LO) &&
(addr <= CPU_BIT_BAND_PERIPH_REG_HI)) {
bit_word_off = ((addr - CPU_BIT_BAND_PERIPH_REG_LO) * 32) + (bit_nbr * 4);
bit_word_addr = CPU_BIT_BAND_PERIPH_BASE + bit_word_off;
*(volatile CPU_INT32U *)(bit_word_addr) = 1;
}
}
/*$PAGE*/
/*
*********************************************************************************************************
* CPU_IntSrcDis()
*
* Description : Disable an interrupt source.
*
* Argument(s) : pos Position of interrupt vector in interrupt table :
*
* 0 Invalid (see Note #1a).
* 1 Invalid (see Note #1b).
* 2 Non-maskable interrupt.
* 3 Hard Fault.
* 4 Memory Management.
* 5 Bus Fault.
* 6 Usage Fault.
* 7-10 Reserved.
* 11 SVCall
* 12 Debug monitor.
* 13 Reserved
* 14 PendSV.
* 15 SysTick.
* 16+ External Interrupt.
*
* Return(s) : none.
*
* Caller(s) : Application.
*
* Note(s) : (1) Several table positions do not contain interrupt sources :
*
* (a) Position 0 contains the stack pointer.
* (b) Positions 7-10, 13 are reserved.
*
* (2) Several interrupts cannot be disabled/enabled :
*
* (a) Reset.
* (b) NMI.
* (c) Hard fault.
* (d) SVCall.
* (e) Debug monitor.
* (f) PendSV.
*
* (3) The maximum Cortex-M3 table position is 256. A particular Cortex-M3 may have fewer
* than 240 external exceptions and, consequently, fewer than 256 table positions.
* This function assumes that the specified table position is valid if the interrupt
* controller type register's INTLINESNUM field is large enough so that the position
* COULD be valid.
*********************************************************************************************************
*/
/*$PAGE*/
void CPU_IntSrcDis (CPU_INT08U pos)
{
CPU_INT08U group;
CPU_INT08U pos_max;
CPU_INT08U nbr;
CPU_SR_ALLOC();
switch (pos) {
case CPU_INT_STK_PTR: /* ---------------- INVALID OR RESERVED --------------- */
case CPU_INT_RSVD_07:
case CPU_INT_RSVD_08:
case CPU_INT_RSVD_09:
case CPU_INT_RSVD_10:
case CPU_INT_RSVD_13:
break;
/* ----------------- SYSTEM EXCEPTIONS ---------------- */
case CPU_INT_RESET: /* Reset (see Note #2). */
case CPU_INT_NMI: /* Non-maskable interrupt (see Note #2). */
case CPU_INT_HFAULT: /* Hard fault (see Note #2). */
case CPU_INT_SVCALL: /* SVCall (see Note #2). */
case CPU_INT_DBGMON: /* Debug monitor (see Note #2). */
case CPU_INT_PENDSV: /* PendSV (see Note #2). */
break;
case CPU_INT_MEM: /* Memory management. */
CPU_CRITICAL_ENTER();
CPU_REG_NVIC_SHCSR &= ~CPU_REG_NVIC_SHCSR_MEMFAULTENA;
CPU_CRITICAL_EXIT();
break;
case CPU_INT_BUSFAULT: /* Bus fault. */
CPU_CRITICAL_ENTER();
CPU_REG_NVIC_SHCSR &= ~CPU_REG_NVIC_SHCSR_BUSFAULTENA;
CPU_CRITICAL_EXIT();
break;
case CPU_INT_USAGEFAULT: /* Usage fault. */
CPU_CRITICAL_ENTER();
CPU_REG_NVIC_SHCSR &= ~CPU_REG_NVIC_SHCSR_USGFAULTENA;
CPU_CRITICAL_EXIT();
break;
case CPU_INT_SYSTICK: /* SysTick. */
CPU_CRITICAL_ENTER();
CPU_REG_NVIC_ST_CTRL &= ~CPU_REG_NVIC_ST_CTRL_ENABLE;
CPU_CRITICAL_EXIT();
break;
/* ---------------- EXTERNAL INTERRUPT ---------------- */
default:
pos_max = CPU_INT_SRC_POS_MAX;
if (pos < pos_max) { /* See Note #3. */
group = (pos - 16) / 32;
nbr = (pos - 16) % 32;
CPU_CRITICAL_ENTER();
CPU_REG_NVIC_CLREN(group) = DEF_BIT(nbr);
CPU_CRITICAL_EXIT();
}
break;
}
}
/*$PAGE*/
/*
*********************************************************************************************************
* CPU_IntSrcEn()
*
* Description : Enable an interrupt source.
*
* Argument(s) : pos Position of interrupt vector in interrupt table (see 'CPU_IntSrcDis()').
*
* Return(s) : none.
*
* Caller(s) : Application.
*
* Note(s) : (1) See 'CPU_IntSrcDis() Note #1'.
*
* (2) See 'CPU_IntSrcDis() Note #2'.
*
* (3) See 'CPU_IntSrcDis() Note #3'.
*********************************************************************************************************
*/
void CPU_IntSrcEn (CPU_INT08U pos)
{
CPU_INT08U group;
CPU_INT08U nbr;
CPU_INT08U pos_max;
CPU_SR_ALLOC();
switch (pos) {
case CPU_INT_STK_PTR: /* ---------------- INVALID OR RESERVED --------------- */
case CPU_INT_RSVD_07:
case CPU_INT_RSVD_08:
case CPU_INT_RSVD_09:
case CPU_INT_RSVD_10:
case CPU_INT_RSVD_13:
break;
/* ----------------- SYSTEM EXCEPTIONS ---------------- */
case CPU_INT_RESET: /* Reset (see Note #2). */
case CPU_INT_NMI: /* Non-maskable interrupt (see Note #2). */
case CPU_INT_HFAULT: /* Hard fault (see Note #2). */
case CPU_INT_SVCALL: /* SVCall (see Note #2). */
case CPU_INT_DBGMON: /* Debug monitor (see Note #2). */
case CPU_INT_PENDSV: /* PendSV (see Note #2). */
break;
case CPU_INT_MEM: /* Memory management. */
CPU_CRITICAL_ENTER();
CPU_REG_NVIC_SHCSR |= CPU_REG_NVIC_SHCSR_MEMFAULTENA;
CPU_CRITICAL_EXIT();
break;
case CPU_INT_BUSFAULT: /* Bus fault. */
CPU_CRITICAL_ENTER();
CPU_REG_NVIC_SHCSR |= CPU_REG_NVIC_SHCSR_BUSFAULTENA;
CPU_CRITICAL_EXIT();
break;
case CPU_INT_USAGEFAULT: /* Usage fault. */
CPU_CRITICAL_ENTER();
CPU_REG_NVIC_SHCSR |= CPU_REG_NVIC_SHCSR_USGFAULTENA;
CPU_CRITICAL_EXIT();
break;
case CPU_INT_SYSTICK: /* SysTick. */
CPU_CRITICAL_ENTER();
CPU_REG_NVIC_ST_CTRL |= CPU_REG_NVIC_ST_CTRL_ENABLE;
CPU_CRITICAL_EXIT();
break;
/* ---------------- EXTERNAL INTERRUPT ---------------- */
default:
pos_max = CPU_INT_SRC_POS_MAX;
if (pos < pos_max) { /* See Note #3. */
group = (pos - 16) / 32;
nbr = (pos - 16) % 32;
CPU_CRITICAL_ENTER();
CPU_REG_NVIC_SETEN(group) = DEF_BIT(nbr);
CPU_CRITICAL_EXIT();
}
break;
}
}
/*$PAGE*/
/*
*********************************************************************************************************
* CPU_IntSrcPendClr()
*
* Description : Clear a pending interrupt.
*
* Argument(s) : pos Position of interrupt vector in interrupt table (see 'CPU_IntSrcDis()').
*
* Return(s) : none.
*
* Caller(s) : Application.
*
* Note(s) : (1) See 'CPU_IntSrcDis() Note #1'.
*
* (2) The pending status of several interrupts cannot be clear/set :
*
* (a) Reset.
* (b) NMI.
* (c) Hard fault.
* (d) Memory Managment.
* (e) Bus Fault.
* (f) Usage Fault.
* (g) SVCall.
* (h) Debug monitor.
* (i) PendSV.
* (j) Systick
*
* (3) See 'CPU_IntSrcDis() Note #3'.
*********************************************************************************************************
*/
void CPU_IntSrcPendClr (CPU_INT08U pos)
{
CPU_INT08U group;
CPU_INT08U nbr;
CPU_INT08U pos_max;
CPU_SR_ALLOC();
switch (pos) {
case CPU_INT_STK_PTR: /* ---------------- INVALID OR RESERVED --------------- */
case CPU_INT_RSVD_07:
case CPU_INT_RSVD_08:
case CPU_INT_RSVD_09:
case CPU_INT_RSVD_10:
case CPU_INT_RSVD_13:
break;
/* ----------------- SYSTEM EXCEPTIONS ---------------- */
case CPU_INT_RESET: /* Reset (see Note #2). */
case CPU_INT_NMI: /* Non-maskable interrupt (see Note #2). */
case CPU_INT_HFAULT: /* Hard fault (see Note #2). */
case CPU_INT_MEM: /* Memory management (see Note #2). */
case CPU_INT_SVCALL: /* SVCall (see Note #2). */
case CPU_INT_DBGMON: /* Debug monitor (see Note #2). */
case CPU_INT_PENDSV: /* PendSV (see Note #2). */
case CPU_INT_BUSFAULT: /* Bus fault. */
case CPU_INT_USAGEFAULT: /* Usage fault. */
case CPU_INT_SYSTICK: /* SysTick. */
break;
/* ---------------- EXTERNAL INTERRUPT ---------------- */
default:
pos_max = CPU_INT_SRC_POS_MAX;
if (pos < pos_max) { /* See Note #3. */
group = (pos - 16) / 32;
nbr = (pos - 16) % 32;
CPU_CRITICAL_ENTER();
CPU_REG_NVIC_CLRPEND(group) = DEF_BIT(nbr);
CPU_CRITICAL_EXIT();
}
break;
}
}
/*$PAGE*/
/*
*********************************************************************************************************
* CPU_IntSrcPrioSet()
*
* Description : Set priority of an interrupt source.
*
* Argument(s) : pos Position of interrupt vector in interrupt table (see 'CPU_IntSrcDis()').
*
* prio Priority. Use a lower priority number for a higher priority.
*
* Return(s) : none.
*
* Caller(s) : Application.
*
* Note(s) : (1) See 'CPU_IntSrcDis() Note #1'.
*
* (2) Several interrupts priorities CANNOT be set :
*
* (a) Reset (always -3).
* (b) NMI (always -2).
* (c) Hard fault (always -1).
*
* (3) See 'CPU_IntSrcDis() Note #3'.
*********************************************************************************************************
*/
void CPU_IntSrcPrioSet (CPU_INT08U pos,
CPU_INT08U prio)
{
CPU_INT08U group;
CPU_INT08U nbr;
CPU_INT08U pos_max;
CPU_INT32U prio_32;
CPU_INT32U temp;
CPU_SR_ALLOC();
prio_32 = CPU_RevBits((CPU_INT08U)prio);
prio = (CPU_INT08U)(prio_32 >> (3 * DEF_OCTET_NBR_BITS));
switch (pos) {
case CPU_INT_STK_PTR: /* ---------------- INVALID OR RESERVED --------------- */
case CPU_INT_RSVD_07:
case CPU_INT_RSVD_08:
case CPU_INT_RSVD_09:
case CPU_INT_RSVD_10:
case CPU_INT_RSVD_13:
break;
/* ----------------- SYSTEM EXCEPTIONS ---------------- */
case CPU_INT_RESET: /* Reset (see Note #2). */
case CPU_INT_NMI: /* Non-maskable interrupt (see Note #2). */
case CPU_INT_HFAULT: /* Hard fault (see Note #2). */
break;
case CPU_INT_MEM: /* Memory management. */
CPU_CRITICAL_ENTER();
temp = CPU_REG_NVIC_SHPRI1;
temp &= ~(DEF_OCTET_MASK << (0 * DEF_OCTET_NBR_BITS));
temp |= (prio << (0 * DEF_OCTET_NBR_BITS));
CPU_REG_NVIC_SHPRI1 = temp;
CPU_CRITICAL_EXIT();
break;
case CPU_INT_BUSFAULT: /* Bus fault. */
CPU_CRITICAL_ENTER();
temp = CPU_REG_NVIC_SHPRI1;
temp &= ~(DEF_OCTET_MASK << (1 * DEF_OCTET_NBR_BITS));
temp |= (prio << (1 * DEF_OCTET_NBR_BITS));
CPU_REG_NVIC_SHPRI1 = temp;
CPU_CRITICAL_EXIT();
break;
case CPU_INT_USAGEFAULT: /* Usage fault. */
CPU_CRITICAL_ENTER();
temp = CPU_REG_NVIC_SHPRI1;
temp &= ~(DEF_OCTET_MASK << (2 * DEF_OCTET_NBR_BITS));
temp |= (prio << (2 * DEF_OCTET_NBR_BITS));
CPU_REG_NVIC_SHPRI1 = temp;
CPU_CRITICAL_EXIT();
break;
case CPU_INT_SVCALL: /* SVCall. */
CPU_CRITICAL_ENTER();
temp = CPU_REG_NVIC_SHPRI2;
temp &= ~((CPU_INT32U)DEF_OCTET_MASK << (3 * DEF_OCTET_NBR_BITS));
temp |= (prio << (3 * DEF_OCTET_NBR_BITS));
CPU_REG_NVIC_SHPRI2 = temp;
CPU_CRITICAL_EXIT();
break;
case CPU_INT_DBGMON: /* Debug monitor. */
CPU_CRITICAL_ENTER();
temp = CPU_REG_NVIC_SHPRI3;
temp &= ~(DEF_OCTET_MASK << (0 * DEF_OCTET_NBR_BITS));
temp |= (prio << (0 * DEF_OCTET_NBR_BITS));
CPU_REG_NVIC_SHPRI3 = temp;
CPU_CRITICAL_EXIT();
break;
case CPU_INT_PENDSV: /* PendSV. */
CPU_CRITICAL_ENTER();
temp = CPU_REG_NVIC_SHPRI3;
temp &= ~(DEF_OCTET_MASK << (2 * DEF_OCTET_NBR_BITS));
temp |= (prio << (2 * DEF_OCTET_NBR_BITS));
CPU_REG_NVIC_SHPRI3 = temp;
CPU_CRITICAL_EXIT();
break;
case CPU_INT_SYSTICK: /* SysTick. */
CPU_CRITICAL_ENTER();
temp = CPU_REG_NVIC_SHPRI3;
temp &= ~((CPU_INT32U)DEF_OCTET_MASK << (3 * DEF_OCTET_NBR_BITS));
temp |= (prio << (3 * DEF_OCTET_NBR_BITS));
CPU_REG_NVIC_SHPRI3 = temp;
CPU_CRITICAL_EXIT();
break;
/* ---------------- EXTERNAL INTERRUPT ---------------- */
default:
pos_max = CPU_INT_SRC_POS_MAX;
if (pos < pos_max) { /* See Note #3. */
group = (pos - 16) / 4;
nbr = (pos - 16) % 4;
CPU_CRITICAL_ENTER();
temp = CPU_REG_NVIC_PRIO(group);
temp &= ~(DEF_OCTET_MASK << (nbr * DEF_OCTET_NBR_BITS));
temp |= (prio << (nbr * DEF_OCTET_NBR_BITS));
CPU_REG_NVIC_PRIO(group) = temp;
CPU_CRITICAL_EXIT();
}
break;
}
}
/*$PAGE*/
/*
*********************************************************************************************************
* CPU_IntSrcPrioGet()
*
* Description : Get priority of an interrupt source.
*
* Argument(s) : pos Position of interrupt vector in interrupt table (see 'CPU_IntSrcDis()').
*
* Return(s) : Priority of interrupt source. If the interrupt source specified is invalid, then
* DEF_INT_16S_MIN_VAL is returned.
*
* Caller(s) : Application.
*
* Note(s) : (1) See 'CPU_IntSrcDis() Note #1'.
*
* (2) See 'CPU_IntSrcPrioSet() Note #2'.
*
* (3) See 'CPU_IntSrcDis() Note #3'.
*********************************************************************************************************
*/
CPU_INT16S CPU_IntSrcPrioGet (CPU_INT08U pos)
{
CPU_INT08U group;
CPU_INT08U nbr;
CPU_INT08U pos_max;
CPU_INT16S prio;
CPU_INT32U prio_32;
CPU_INT32U temp;
CPU_SR_ALLOC();
switch (pos) {
case CPU_INT_STK_PTR: /* ---------------- INVALID OR RESERVED --------------- */
case CPU_INT_RSVD_07:
case CPU_INT_RSVD_08:
case CPU_INT_RSVD_09:
case CPU_INT_RSVD_10:
case CPU_INT_RSVD_13:
prio = DEF_INT_16S_MIN_VAL;
break;
/* ----------------- SYSTEM EXCEPTIONS ---------------- */
case CPU_INT_RESET: /* Reset (see Note #2). */
prio = -3;
break;
case CPU_INT_NMI: /* Non-maskable interrupt (see Note #2). */
prio = -2;
break;
case CPU_INT_HFAULT: /* Hard fault (see Note #2). */
prio = -1;
break;
case CPU_INT_MEM: /* Memory management. */
CPU_CRITICAL_ENTER();
temp = CPU_REG_NVIC_SHPRI1;
prio = (temp >> (0 * DEF_OCTET_NBR_BITS)) & DEF_OCTET_MASK;
CPU_CRITICAL_EXIT();
break;
case CPU_INT_BUSFAULT: /* Bus fault. */
CPU_CRITICAL_ENTER();
temp = CPU_REG_NVIC_SHPRI1;
prio = (temp >> (1 * DEF_OCTET_NBR_BITS)) & DEF_OCTET_MASK;
CPU_CRITICAL_EXIT();
break;
case CPU_INT_USAGEFAULT: /* Usage fault. */
CPU_CRITICAL_ENTER();
temp = CPU_REG_NVIC_SHPRI1;
prio = (temp >> (2 * DEF_OCTET_NBR_BITS)) & DEF_OCTET_MASK;
break;
case CPU_INT_SVCALL: /* SVCall. */
CPU_CRITICAL_ENTER();
temp = CPU_REG_NVIC_SHPRI2;
prio = (temp >> (3 * DEF_OCTET_NBR_BITS)) & DEF_OCTET_MASK;
CPU_CRITICAL_EXIT();
break;
case CPU_INT_DBGMON: /* Debug monitor. */
CPU_CRITICAL_ENTER();
temp = CPU_REG_NVIC_SHPRI3;
prio = (temp >> (0 * DEF_OCTET_NBR_BITS)) & DEF_OCTET_MASK;
CPU_CRITICAL_EXIT();
break;
case CPU_INT_PENDSV: /* PendSV. */
CPU_CRITICAL_ENTER();
temp = CPU_REG_NVIC_SHPRI3;
prio = (temp >> (2 * DEF_OCTET_NBR_BITS)) & DEF_OCTET_MASK;
CPU_CRITICAL_EXIT();
break;
case CPU_INT_SYSTICK: /* SysTick. */
CPU_CRITICAL_ENTER();
temp = CPU_REG_NVIC_SHPRI3;
prio = (temp >> (3 * DEF_OCTET_NBR_BITS)) & DEF_OCTET_MASK;
CPU_CRITICAL_EXIT();
break;
/* ---------------- EXTERNAL INTERRUPT ---------------- */
default:
pos_max = CPU_INT_SRC_POS_MAX;
if (pos < pos_max) { /* See Note #3. */
group = (pos - 16) / 4;
nbr = (pos - 16) % 4;
CPU_CRITICAL_ENTER();
temp = CPU_REG_NVIC_PRIO(group);
CPU_CRITICAL_EXIT();
prio = (temp >> (nbr * DEF_OCTET_NBR_BITS)) & DEF_OCTET_MASK;
} else {
prio = DEF_INT_16S_MIN_VAL;
}
break;
}
if (prio >= 0) {
prio_32 = CPU_RevBits((CPU_INT32U)prio);
prio = (CPU_INT16S)(prio_32 >> (3 * DEF_OCTET_NBR_BITS));
}
return (prio);
}

View File

@@ -0,0 +1,723 @@
/*
*********************************************************************************************************
* uC/CPU
* CPU CONFIGURATION & PORT LAYER
*
* (c) Copyright 2004-2011; Micrium, Inc.; Weston, FL
*
* All rights reserved. Protected by international copyright laws.
*
* uC/CPU is provided in source form to registered licensees ONLY. It is
* illegal to distribute this source code to any third party unless you receive
* written permission by an authorized Micrium representative. Knowledge of
* the source code may NOT be used to develop a similar product.
*
* Please help us continue to provide the Embedded community with the finest
* software available. Your honesty is greatly appreciated.
*
* You can contact us at www.micrium.com.
*********************************************************************************************************
*/
/*
*********************************************************************************************************
*
* CPU PORT FILE
*
* ARM-Cortex-M3
* IAR C Compiler
*
* Filename : cpu.h
* Version : V1.29.01.00
* Programmer(s) : JJL
* BAN
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* MODULE
*
* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of
* the CPU module present pre-processor macro definition.
*********************************************************************************************************
*/
#ifndef CPU_MODULE_PRESENT /* See Note #1. */
#define CPU_MODULE_PRESENT
/*
*********************************************************************************************************
* CPU INCLUDE FILES
*
* Note(s) : (1) The following CPU files are located in the following directories :
*
* (a) \<Your Product Application>\cpu_cfg.h
*
* (b) (1) \<CPU-Compiler Directory>\cpu_def.h
* (2) \<CPU-Compiler Directory>\<cpu>\<compiler>\cpu*.*
*
* where
* <Your Product Application> directory path for Your Product's Application
* <CPU-Compiler Directory> directory path for common CPU-compiler software
* <cpu> directory name for specific CPU
* <compiler> directory name for specific compiler
*
* (2) Compiler MUST be configured to include as additional include path directories :
*
* (a) '\<Your Product Application>\' directory See Note #1a
*
* (b) (1) '\<CPU-Compiler Directory>\' directory See Note #1b1
* (2) '\<CPU-Compiler Directory>\<cpu>\<compiler>\' directory See Note #1b2
*
* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from
* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions.
*
* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric
* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to
* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED).
*********************************************************************************************************
*/
#include <cpu_def.h>
#include <cpu_cfg.h> /* See Note #3. */
/*$PAGE*/
/*
*********************************************************************************************************
* CONFIGURE STANDARD DATA TYPES
*
* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications.
*
* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer
* data type of a pointer to a function which returns void & has no arguments.
*
* (2) Example function pointer usage :
*
* CPU_FNCT_VOID FnctName;
*
* FnctName();
*
* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer
* data type of a pointer to a function which returns void & has a single void
* pointer argument.
*
* (2) Example function pointer usage :
*
* CPU_FNCT_PTR FnctName;
* void *p_obj
*
* FnctName(p_obj);
*********************************************************************************************************
*/
typedef void CPU_VOID;
typedef char CPU_CHAR; /* 8-bit character */
typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */
typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */
typedef signed char CPU_INT08S; /* 8-bit signed integer */
typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */
typedef signed short CPU_INT16S; /* 16-bit signed integer */
typedef unsigned int CPU_INT32U; /* 32-bit unsigned integer */
typedef signed int CPU_INT32S; /* 32-bit signed integer */
typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */
typedef signed long long CPU_INT64S; /* 64-bit signed integer */
typedef float CPU_FP32; /* 32-bit floating point */
typedef double CPU_FP64; /* 64-bit floating point */
typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */
typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */
typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */
typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */
typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */
typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */
/*$PAGE*/
/*
*********************************************************************************************************
* CPU WORD CONFIGURATION
*
* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or
* compiler's word sizes :
*
* CPU_WORD_SIZE_08 8-bit word size
* CPU_WORD_SIZE_16 16-bit word size
* CPU_WORD_SIZE_32 32-bit word size
* CPU_WORD_SIZE_64 64-bit word size
*
* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order :
*
* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant
* octet @ lowest memory address)
* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant
* octet @ lowest memory address)
*********************************************************************************************************
*/
/* Define CPU word sizes (see Note #1) : */
#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */
#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */
#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */
#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */
/*
*********************************************************************************************************
* CONFIGURE CPU ADDRESS & DATA TYPES
*********************************************************************************************************
*/
/* CPU address type based on address bus size. */
#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32)
typedef CPU_INT32U CPU_ADDR;
#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16)
typedef CPU_INT16U CPU_ADDR;
#else
typedef CPU_INT08U CPU_ADDR;
#endif
/* CPU data type based on data bus size. */
#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32)
typedef CPU_INT32U CPU_DATA;
#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16)
typedef CPU_INT16U CPU_DATA;
#else
typedef CPU_INT08U CPU_DATA;
#endif
typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */
typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */
/*
*********************************************************************************************************
* CPU STACK CONFIGURATION
*
* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order :
*
* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack
* memory address after data is pushed onto the stack
* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack
* memory address after data is pushed onto the stack
*********************************************************************************************************
*/
#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */
typedef CPU_INT32U CPU_STK; /* Defines CPU stack word size (in octets). */
typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size (in number of CPU_STKs). */
/*$PAGE*/
/*
*********************************************************************************************************
* CRITICAL SECTION CONFIGURATION
*
* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method :
*
* Enter/Exit critical sections by ...
*
* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts
* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack
* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable
*
* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support
* multiple levels of interrupts. However, with some CPUs/compilers, this is the only
* available method.
*
* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple
* levels of interrupts. However, this method assumes that the compiler provides C-level
* &/or assembly-level functionality for the following :
*
* ENTER CRITICAL SECTION :
* (1) Push/save interrupt status onto a local stack
* (2) Disable interrupts
*
* EXIT CRITICAL SECTION :
* (3) Pop/restore interrupt status from a local stack
*
* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple
* levels of interrupts. However, this method assumes that the compiler provides C-level
* &/or assembly-level functionality for the following :
*
* ENTER CRITICAL SECTION :
* (1) Save interrupt status into a local variable
* (2) Disable interrupts
*
* EXIT CRITICAL SECTION :
* (3) Restore interrupt status from a local variable
*
* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT
* allow inline assembly in C source files, critical section macro's MUST call an assembly
* subroutine defined in a 'cpu_a.asm' file located in the following software directory :
*
* \<CPU-Compiler Directory>\<cpu>\<compiler>\
*
* where
* <CPU-Compiler Directory> directory path for common CPU-compiler software
* <cpu> directory name for specific CPU
* <compiler> directory name for specific compiler
*
* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need
* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured).
*
* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if
* used, MUST be declared following ALL other local variables.
*
* Example :
*
* void Fnct (void)
* {
* CPU_INT08U val_08;
* CPU_INT16U val_16;
* CPU_INT32U val_32;
* CPU_SR_ALLOC(); MUST be declared after ALL other local variables
* :
* :
* }
*
* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to
* completely store the CPU's/compiler's status word.
*********************************************************************************************************
*/
/*$PAGE*/
/* Configure CPU critical method (see Note #1) : */
#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL
typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */
/* Allocates CPU status register word (see Note #3a). */
#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)
#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0
#else
#define CPU_SR_ALLOC()
#endif
#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/
#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */
#ifdef CPU_CFG_INT_DIS_MEAS_EN
/* Disable interrupts, ... */
/* & start interrupts disabled time measurement.*/
#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \
CPU_IntDisMeasStart(); } while (0)
/* Stop & measure interrupts disabled time, */
/* ... & re-enable interrupts. */
#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \
CPU_INT_EN(); } while (0)
#else
#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */
#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* CPU COUNT ZEROS CONFIGURATION
*
* Note(s) : (1) (a) Configure CPU_CFG_LEAD_ZEROS_ASM_PRESENT to define count leading zeros bits
* function(s) in :
*
* (1) 'cpu_a.asm', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/
* 'cpu_cfg.h' to enable assembly-optimized function(s)
*
* (2) 'cpu_core.c', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/
* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise
*
* (b) Configure CPU_CFG_TRAIL_ZEROS_ASM_PRESENT to define count trailing zeros bits
* function(s) in :
*
* (1) 'cpu_a.asm', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/
* 'cpu_cfg.h' to enable assembly-optimized function(s)
*
* (2) 'cpu_core.c', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/
* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise
*********************************************************************************************************
*/
/* Configure CPU count leading zeros bits ... */
#define CPU_CFG_LEAD_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1a). */
/* Configure CPU count trailing zeros bits ... */
#define CPU_CFG_TRAIL_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1b). */
/*$PAGE*/
/*
*********************************************************************************************************
* FUNCTION PROTOTYPES
*********************************************************************************************************
*/
void CPU_IntDis (void);
void CPU_IntEn (void);
void CPU_IntSrcDis (CPU_INT08U pos);
void CPU_IntSrcEn (CPU_INT08U pos);
void CPU_IntSrcPendClr(CPU_INT08U pos);
CPU_INT16S CPU_IntSrcPrioGet(CPU_INT08U pos);
void CPU_IntSrcPrioSet(CPU_INT08U pos,
CPU_INT08U prio);
CPU_SR CPU_SR_Save (void);
void CPU_SR_Restore (CPU_SR cpu_sr);
void CPU_WaitForInt (void);
void CPU_WaitForExcept(void);
CPU_DATA CPU_RevBits (CPU_DATA val);
void CPU_BitBandClr (CPU_ADDR addr,
CPU_INT08U bit_nbr);
void CPU_BitBandSet (CPU_ADDR addr,
CPU_INT08U bit_nbr);
/*$PAGE*/
/*
*********************************************************************************************************
* INTERRUPT SOURCES
*********************************************************************************************************
*/
#define CPU_INT_STK_PTR 0u
#define CPU_INT_RESET 1u
#define CPU_INT_NMI 2u
#define CPU_INT_HFAULT 3u
#define CPU_INT_MEM 4u
#define CPU_INT_BUSFAULT 5u
#define CPU_INT_USAGEFAULT 6u
#define CPU_INT_RSVD_07 7u
#define CPU_INT_RSVD_08 8u
#define CPU_INT_RSVD_09 9u
#define CPU_INT_RSVD_10 10u
#define CPU_INT_SVCALL 11u
#define CPU_INT_DBGMON 12u
#define CPU_INT_RSVD_13 13u
#define CPU_INT_PENDSV 14u
#define CPU_INT_SYSTICK 15u
#define CPU_INT_EXT0 16u
/*
*********************************************************************************************************
* CPU REGISTERS
*********************************************************************************************************
*/
#define CPU_REG_NVIC_NVIC (*((CPU_REG32 *)(0xE000E004))) /* Int Ctrl'er Type Reg. */
#define CPU_REG_NVIC_ST_CTRL (*((CPU_REG32 *)(0xE000E010))) /* SysTick Ctrl & Status Reg. */
#define CPU_REG_NVIC_ST_RELOAD (*((CPU_REG32 *)(0xE000E014))) /* SysTick Reload Value Reg. */
#define CPU_REG_NVIC_ST_CURRENT (*((CPU_REG32 *)(0xE000E018))) /* SysTick Current Value Reg. */
#define CPU_REG_NVIC_ST_CAL (*((CPU_REG32 *)(0xE000E01C))) /* SysTick Calibration Value Reg. */
#define CPU_REG_NVIC_SETEN(n) (*((CPU_REG32 *)(0xE000E100 + (n) * 4u))) /* IRQ Set En Reg. */
#define CPU_REG_NVIC_CLREN(n) (*((CPU_REG32 *)(0xE000E180 + (n) * 4u))) /* IRQ Clr En Reg. */
#define CPU_REG_NVIC_SETPEND(n) (*((CPU_REG32 *)(0xE000E200 + (n) * 4u))) /* IRQ Set Pending Reg. */
#define CPU_REG_NVIC_CLRPEND(n) (*((CPU_REG32 *)(0xE000E280 + (n) * 4u))) /* IRQ Clr Pending Reg. */
#define CPU_REG_NVIC_ACTIVE(n) (*((CPU_REG32 *)(0xE000E300 + (n) * 4u))) /* IRQ Active Reg. */
#define CPU_REG_NVIC_PRIO(n) (*((CPU_REG32 *)(0xE000E400 + (n) * 4u))) /* IRQ Prio Reg. */
#define CPU_REG_NVIC_CPUID (*((CPU_REG32 *)(0xE000ED00))) /* CPUID Base Reg. */
#define CPU_REG_NVIC_ICSR (*((CPU_REG32 *)(0xE000ED04))) /* Int Ctrl State Reg. */
#define CPU_REG_NVIC_VTOR (*((CPU_REG32 *)(0xE000ED08))) /* Vect Tbl Offset Reg. */
#define CPU_REG_NVIC_AIRCR (*((CPU_REG32 *)(0xE000ED0C))) /* App Int/Reset Ctrl Reg. */
#define CPU_REG_NVIC_SCR (*((CPU_REG32 *)(0xE000ED10))) /* System Ctrl Reg. */
#define CPU_REG_NVIC_CCR (*((CPU_REG32 *)(0xE000ED14))) /* Cfg Ctrl Reg. */
#define CPU_REG_NVIC_SHPRI1 (*((CPU_REG32 *)(0xE000ED18))) /* System Handlers 4 to 7 Prio. */
#define CPU_REG_NVIC_SHPRI2 (*((CPU_REG32 *)(0xE000ED1C))) /* System Handlers 8 to 11 Prio. */
#define CPU_REG_NVIC_SHPRI3 (*((CPU_REG32 *)(0xE000ED20))) /* System Handlers 12 to 15 Prio. */
#define CPU_REG_NVIC_SHCSR (*((CPU_REG32 *)(0xE000ED24))) /* System Handler Ctrl & State Reg. */
#define CPU_REG_NVIC_CFSR (*((CPU_REG32 *)(0xE000ED28))) /* Configurable Fault Status Reg. */
#define CPU_REG_NVIC_HFSR (*((CPU_REG32 *)(0xE000ED2C))) /* Hard Fault Status Reg. */
#define CPU_REG_NVIC_DFSR (*((CPU_REG32 *)(0xE000ED30))) /* Debug Fault Status Reg. */
#define CPU_REG_NVIC_MMFAR (*((CPU_REG32 *)(0xE000ED34))) /* Mem Manage Addr Reg. */
#define CPU_REG_NVIC_BFAR (*((CPU_REG32 *)(0xE000ED38))) /* Bus Fault Addr Reg. */
#define CPU_REG_NVIC_AFSR (*((CPU_REG32 *)(0xE000ED3C))) /* Aux Fault Status Reg. */
#define CPU_REG_NVIC_PFR0 (*((CPU_REG32 *)(0xE000ED40))) /* Processor Feature Reg 0. */
#define CPU_REG_NVIC_PFR1 (*((CPU_REG32 *)(0xE000ED44))) /* Processor Feature Reg 1. */
#define CPU_REG_NVIC_DFR0 (*((CPU_REG32 *)(0xE000ED48))) /* Debug Feature Reg 0. */
#define CPU_REG_NVIC_AFR0 (*((CPU_REG32 *)(0xE000ED4C))) /* Aux Feature Reg 0. */
#define CPU_REG_NVIC_MMFR0 (*((CPU_REG32 *)(0xE000ED50))) /* Memory Model Feature Reg 0. */
#define CPU_REG_NVIC_MMFR1 (*((CPU_REG32 *)(0xE000ED54))) /* Memory Model Feature Reg 1. */
#define CPU_REG_NVIC_MMFR2 (*((CPU_REG32 *)(0xE000ED58))) /* Memory Model Feature Reg 2. */
#define CPU_REG_NVIC_MMFR3 (*((CPU_REG32 *)(0xE000ED5C))) /* Memory Model Feature Reg 3. */
#define CPU_REG_NVIC_ISAFR0 (*((CPU_REG32 *)(0xE000ED60))) /* ISA Feature Reg 0. */
#define CPU_REG_NVIC_ISAFR1 (*((CPU_REG32 *)(0xE000ED64))) /* ISA Feature Reg 1. */
#define CPU_REG_NVIC_ISAFR2 (*((CPU_REG32 *)(0xE000ED68))) /* ISA Feature Reg 2. */
#define CPU_REG_NVIC_ISAFR3 (*((CPU_REG32 *)(0xE000ED6C))) /* ISA Feature Reg 3. */
#define CPU_REG_NVIC_ISAFR4 (*((CPU_REG32 *)(0xE000ED70))) /* ISA Feature Reg 4. */
#define CPU_REG_NVIC_SW_TRIG (*((CPU_REG32 *)(0xE000EF00))) /* Software Trigger Int Reg. */
#define CPU_REG_MPU_TYPE (*((CPU_REG32 *)(0xE000ED90))) /* MPU Type Reg. */
#define CPU_REG_MPU_CTRL (*((CPU_REG32 *)(0xE000ED94))) /* MPU Ctrl Reg. */
#define CPU_REG_MPU_REG_NBR (*((CPU_REG32 *)(0xE000ED98))) /* MPU Region Nbr Reg. */
#define CPU_REG_MPU_REG_BASE (*((CPU_REG32 *)(0xE000ED9C))) /* MPU Region Base Addr Reg. */
#define CPU_REG_MPU_REG_ATTR (*((CPU_REG32 *)(0xE000EDA0))) /* MPU Region Attrib & Size Reg. */
#define CPU_REG_DBG_CTRL (*((CPU_REG32 *)(0xE000EDF0))) /* Debug Halting Ctrl & Status Reg. */
#define CPU_REG_DBG_SELECT (*((CPU_REG32 *)(0xE000EDF4))) /* Debug Core Reg Selector Reg. */
#define CPU_REG_DBG_DATA (*((CPU_REG32 *)(0xE000EDF8))) /* Debug Core Reg Data Reg. */
#define CPU_REG_DBG_INT (*((CPU_REG32 *)(0xE000EDFC))) /* Debug Except & Monitor Ctrl Reg. */
/*$PAGE*/
/*
*********************************************************************************************************
* CPU REGISTER BITS
*********************************************************************************************************
*/
/* ---------- SYSTICK CTRL & STATUS REG BITS ---------- */
#define CPU_REG_NVIC_ST_CTRL_COUNTFLAG 0x00010000
#define CPU_REG_NVIC_ST_CTRL_CLKSOURCE 0x00000004
#define CPU_REG_NVIC_ST_CTRL_TICKINT 0x00000002
#define CPU_REG_NVIC_ST_CTRL_ENABLE 0x00000001
/* -------- SYSTICK CALIBRATION VALUE REG BITS -------- */
#define CPU_REG_NVIC_ST_CAL_NOREF 0x80000000
#define CPU_REG_NVIC_ST_CAL_SKEW 0x40000000
/* -------------- INT CTRL STATE REG BITS ------------- */
#define CPU_REG_NVIC_ICSR_NMIPENDSET 0x80000000
#define CPU_REG_NVIC_ICSR_PENDSVSET 0x10000000
#define CPU_REG_NVIC_ICSR_PENDSVCLR 0x08000000
#define CPU_REG_NVIC_ICSR_PENDSTSET 0x04000000
#define CPU_REG_NVIC_ICSR_PENDSTCLR 0x02000000
#define CPU_REG_NVIC_ICSR_ISRPREEMPT 0x00800000
#define CPU_REG_NVIC_ICSR_ISRPENDING 0x00400000
#define CPU_REG_NVIC_ICSR_RETTOBASE 0x00000800
/* ------------- VECT TBL OFFSET REG BITS ------------- */
#define CPU_REG_NVIC_VTOR_TBLBASE 0x20000000
/* ------------ APP INT/RESET CTRL REG BITS ----------- */
#define CPU_REG_NVIC_AIRCR_ENDIANNESS 0x00008000
#define CPU_REG_NVIC_AIRCR_SYSRESETREQ 0x00000004
#define CPU_REG_NVIC_AIRCR_VECTCLRACTIVE 0x00000002
#define CPU_REG_NVIC_AIRCR_VECTRESET 0x00000001
/* --------------- SYSTEM CTRL REG BITS --------------- */
#define CPU_REG_NVIC_SCR_SEVONPEND 0x00000010
#define CPU_REG_NVIC_SCR_SLEEPDEEP 0x00000004
#define CPU_REG_NVIC_SCR_SLEEPONEXIT 0x00000002
/* ----------------- CFG CTRL REG BITS ---------------- */
#define CPU_REG_NVIC_CCR_STKALIGN 0x00000200
#define CPU_REG_NVIC_CCR_BFHFNMIGN 0x00000100
#define CPU_REG_NVIC_CCR_DIV_0_TRP 0x00000010
#define CPU_REG_NVIC_CCR_UNALIGN_TRP 0x00000008
#define CPU_REG_NVIC_CCR_USERSETMPEND 0x00000002
#define CPU_REG_NVIC_CCR_NONBASETHRDENA 0x00000001
/* ------- SYSTEM HANDLER CTRL & STATE REG BITS ------- */
#define CPU_REG_NVIC_SHCSR_USGFAULTENA 0x00040000
#define CPU_REG_NVIC_SHCSR_BUSFAULTENA 0x00020000
#define CPU_REG_NVIC_SHCSR_MEMFAULTENA 0x00010000
#define CPU_REG_NVIC_SHCSR_SVCALLPENDED 0x00008000
#define CPU_REG_NVIC_SHCSR_BUSFAULTPENDED 0x00004000
#define CPU_REG_NVIC_SHCSR_MEMFAULTPENDED 0x00002000
#define CPU_REG_NVIC_SHCSR_USGFAULTPENDED 0x00001000
#define CPU_REG_NVIC_SHCSR_SYSTICKACT 0x00000800
#define CPU_REG_NVIC_SHCSR_PENDSVACT 0x00000400
#define CPU_REG_NVIC_SHCSR_MONITORACT 0x00000100
#define CPU_REG_NVIC_SHCSR_SVCALLACT 0x00000080
#define CPU_REG_NVIC_SHCSR_USGFAULTACT 0x00000008
#define CPU_REG_NVIC_SHCSR_BUSFAULTACT 0x00000002
#define CPU_REG_NVIC_SHCSR_MEMFAULTACT 0x00000001
/*$PAGE*/
/* -------- CONFIGURABLE FAULT STATUS REG BITS -------- */
#define CPU_REG_NVIC_CFSR_DIVBYZERO 0x02000000
#define CPU_REG_NVIC_CFSR_UNALIGNED 0x01000000
#define CPU_REG_NVIC_CFSR_NOCP 0x00080000
#define CPU_REG_NVIC_CFSR_INVPC 0x00040000
#define CPU_REG_NVIC_CFSR_INVSTATE 0x00020000
#define CPU_REG_NVIC_CFSR_UNDEFINSTR 0x00010000
#define CPU_REG_NVIC_CFSR_BFARVALID 0x00008000
#define CPU_REG_NVIC_CFSR_STKERR 0x00001000
#define CPU_REG_NVIC_CFSR_UNSTKERR 0x00000800
#define CPU_REG_NVIC_CFSR_IMPRECISERR 0x00000400
#define CPU_REG_NVIC_CFSR_PRECISERR 0x00000200
#define CPU_REG_NVIC_CFSR_IBUSERR 0x00000100
#define CPU_REG_NVIC_CFSR_MMARVALID 0x00000080
#define CPU_REG_NVIC_CFSR_MSTKERR 0x00000010
#define CPU_REG_NVIC_CFSR_MUNSTKERR 0x00000008
#define CPU_REG_NVIC_CFSR_DACCVIOL 0x00000002
#define CPU_REG_NVIC_CFSR_IACCVIOL 0x00000001
/* ------------ HARD FAULT STATUS REG BITS ------------ */
#define CPU_REG_NVIC_HFSR_DEBUGEVT 0x80000000
#define CPU_REG_NVIC_HFSR_FORCED 0x40000000
#define CPU_REG_NVIC_HFSR_VECTTBL 0x00000002
/* ------------ DEBUG FAULT STATUS REG BITS ----------- */
#define CPU_REG_NVIC_DFSR_EXTERNAL 0x00000010
#define CPU_REG_NVIC_DFSR_VCATCH 0x00000008
#define CPU_REG_NVIC_DFSR_DWTTRAP 0x00000004
#define CPU_REG_NVIC_DFSR_BKPT 0x00000002
#define CPU_REG_NVIC_DFSR_HALTED 0x00000001
/*
*********************************************************************************************************
* CPU REGISTER MASK
*********************************************************************************************************
*/
#define CPU_MSK_NVIC_ICSR_VECT_ACTIVE 0x000001FF
/*$PAGE*/
/*
*********************************************************************************************************
* CONFIGURATION ERRORS
*********************************************************************************************************
*/
#ifndef CPU_CFG_ADDR_SIZE
#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' "
#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]"
#error " [ || CPU_WORD_SIZE_16 16-bit alignment]"
#error " [ || CPU_WORD_SIZE_32 32-bit alignment]"
#error " [ || CPU_WORD_SIZE_64 64-bit alignment]"
#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \
(CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \
(CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \
(CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64))
#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' "
#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]"
#error " [ || CPU_WORD_SIZE_16 16-bit alignment]"
#error " [ || CPU_WORD_SIZE_32 32-bit alignment]"
#error " [ || CPU_WORD_SIZE_64 64-bit alignment]"
#endif
#ifndef CPU_CFG_DATA_SIZE
#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' "
#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]"
#error " [ || CPU_WORD_SIZE_16 16-bit alignment]"
#error " [ || CPU_WORD_SIZE_32 32-bit alignment]"
#error " [ || CPU_WORD_SIZE_64 64-bit alignment]"
#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \
(CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \
(CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \
(CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64))
#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' "
#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]"
#error " [ || CPU_WORD_SIZE_16 16-bit alignment]"
#error " [ || CPU_WORD_SIZE_32 32-bit alignment]"
#error " [ || CPU_WORD_SIZE_64 64-bit alignment]"
#endif
#ifndef CPU_CFG_DATA_SIZE_MAX
#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' "
#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]"
#error " [ || CPU_WORD_SIZE_16 16-bit alignment]"
#error " [ || CPU_WORD_SIZE_32 32-bit alignment]"
#error " [ || CPU_WORD_SIZE_64 64-bit alignment]"
#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \
(CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \
(CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \
(CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64))
#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' "
#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]"
#error " [ || CPU_WORD_SIZE_16 16-bit alignment]"
#error " [ || CPU_WORD_SIZE_32 32-bit alignment]"
#error " [ || CPU_WORD_SIZE_64 64-bit alignment]"
#endif
#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE)
#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' "
#error " [MUST be >= CPU_CFG_DATA_SIZE]"
#endif
/*$PAGE*/
#ifndef CPU_CFG_ENDIAN_TYPE
#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' "
#error " [MUST be CPU_ENDIAN_TYPE_BIG ]"
#error " [ || CPU_ENDIAN_TYPE_LITTLE]"
#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \
(CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE))
#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' "
#error " [MUST be CPU_ENDIAN_TYPE_BIG ]"
#error " [ || CPU_ENDIAN_TYPE_LITTLE]"
#endif
#ifndef CPU_CFG_STK_GROWTH
#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' "
#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]"
#error " [ || CPU_STK_GROWTH_HI_TO_LO]"
#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \
(CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO))
#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' "
#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]"
#error " [ || CPU_STK_GROWTH_HI_TO_LO]"
#endif
#ifndef CPU_CFG_CRITICAL_METHOD
#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' "
#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]"
#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]"
#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]"
#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \
(CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \
(CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL))
#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' "
#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]"
#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]"
#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]"
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* MODULE END
*
* Note(s) : (1) See 'cpu.h MODULE'.
*********************************************************************************************************
*/
#endif /* End of CPU module include. */

View File

@@ -0,0 +1,286 @@
;********************************************************************************************************
; uC/CPU
; CPU CONFIGURATION & PORT LAYER
;
; (c) Copyright 2004-2011; Micrium, Inc.; Weston, FL
;
; All rights reserved. Protected by international copyright laws.
;
; uC/CPU is provided in source form to registered licensees ONLY. It is
; illegal to distribute this source code to any third party unless you receive
; written permission by an authorized Micrium representative. Knowledge of
; the source code may NOT be used to develop a similar product.
;
; Please help us continue to provide the Embedded community with the finest
; software available. Your honesty is greatly appreciated.
;
; You can contact us at www.micrium.com.
;********************************************************************************************************
;********************************************************************************************************
;
; CPU PORT FILE
;
; ARM-Cortex-M3
; IAR C Compiler
;
; Filename : cpu_a.asm
; Version : V1.29.01.00
; Programmer(s) : JJL
;********************************************************************************************************
;********************************************************************************************************
; PUBLIC FUNCTIONS
;********************************************************************************************************
PUBLIC CPU_IntDis
PUBLIC CPU_IntEn
PUBLIC CPU_SR_Save
PUBLIC CPU_SR_Restore
PUBLIC CPU_WaitForInt
PUBLIC CPU_WaitForExcept
PUBLIC CPU_CntLeadZeros
PUBLIC CPU_CntTrailZeros
PUBLIC CPU_RevBits
;********************************************************************************************************
; CODE GENERATION DIRECTIVES
;********************************************************************************************************
RSEG CODE:CODE:NOROOT(2)
THUMB
;$PAGE
;********************************************************************************************************
; DISABLE and ENABLE INTERRUPTS
;
; Description : Disable/Enable interrupts.
;
; Prototypes : void CPU_IntDis(void);
; void CPU_IntEn (void);
;********************************************************************************************************
CPU_IntDis
CPSID I
BX LR
CPU_IntEn
CPSIE I
BX LR
;********************************************************************************************************
; CRITICAL SECTION FUNCTIONS
;
; Description : Disable/Enable interrupts by preserving the state of interrupts. Generally speaking, the
; state of the interrupt disable flag is stored in the local variable 'cpu_sr' & interrupts
; are then disabled ('cpu_sr' is allocated in all functions that need to disable interrupts).
; The previous interrupt state is restored by copying 'cpu_sr' into the CPU's status register.
;
; Prototypes : CPU_SR CPU_SR_Save (void);
; void CPU_SR_Restore(CPU_SR cpu_sr);
;
; Note(s) : (1) These functions are used in general like this :
;
; void Task (void *p_arg)
; {
; CPU_SR_ALLOC(); /* Allocate storage for CPU status register */
; :
; :
; CPU_CRITICAL_ENTER(); /* cpu_sr = CPU_SR_Save(); */
; :
; :
; CPU_CRITICAL_EXIT(); /* CPU_SR_Restore(cpu_sr); */
; :
; }
;********************************************************************************************************
CPU_SR_Save
MRS R0, PRIMASK ; Set prio int mask to mask all (except faults)
CPSID I
BX LR
CPU_SR_Restore ; See Note #2.
MSR PRIMASK, R0
BX LR
;$PAGE
;********************************************************************************************************
; WAIT FOR INTERRUPT
;
; Description : Enters sleep state, which will be exited when an interrupt is received.
;
; Prototypes : void CPU_WaitForInt (void)
;
; Argument(s) : none.
;********************************************************************************************************
CPU_WaitForInt
WFI ; Wait for interrupt
BX LR
;********************************************************************************************************
; WAIT FOR EXCEPTION
;
; Description : Enters sleep state, which will be exited when an exception is received.
;
; Prototypes : void CPU_WaitForExcept (void)
;
; Argument(s) : none.
;********************************************************************************************************
CPU_WaitForExcept
WFE ; Wait for exception
BX LR
;$PAGE
;********************************************************************************************************
; CPU_CntLeadZeros()
; COUNT LEADING ZEROS
;
; Description : Counts the number of contiguous, most-significant, leading zero bits before the
; first binary one bit in a data value.
;
; Prototype : CPU_DATA CPU_CntLeadZeros(CPU_DATA val);
;
; Argument(s) : val Data value to count leading zero bits.
;
; Return(s) : Number of contiguous, most-significant, leading zero bits in 'val'.
;
; Caller(s) : Application.
;
; This function is an INTERNAL CPU module function but MAY be called by application
; function(s).
;
; Note(s) : (1) (a) Supports 32-bit data value size as configured by 'CPU_DATA' (see 'cpu.h
; CPU WORD CONFIGURATION Note #1').
;
; (b) For 32-bit values :
;
; b31 b30 b29 ... b04 b03 b02 b01 b00 # Leading Zeros
; --- --- --- --- --- --- --- --- ---------------
; 1 x x x x x x x 0
; 0 1 x x x x x x 1
; 0 0 1 x x x x x 2
; : : : : : : : : :
; : : : : : : : : :
; 0 0 0 1 x x x x 27
; 0 0 0 0 1 x x x 28
; 0 0 0 0 0 1 x x 29
; 0 0 0 0 0 0 1 x 30
; 0 0 0 0 0 0 0 1 31
; 0 0 0 0 0 0 0 0 32
;
;
; (2) MUST be defined in 'cpu_a.asm' (or 'cpu_c.c') if CPU_CFG_LEAD_ZEROS_ASM_PRESENT is
; #define'd in 'cpu_cfg.h' or 'cpu.h'.
;********************************************************************************************************
CPU_CntLeadZeros
CLZ R0, R0 ; Count leading zeros
BX LR
;$PAGE
;********************************************************************************************************
; CPU_CntTrailZeros()
; COUNT TRAILING ZEROS
;
; Description : Counts the number of contiguous, least-significant, trailing zero bits before the
; first binary one bit in a data value.
;
; Prototype : CPU_DATA CPU_CntTrailZeros(CPU_DATA val);
;
; Argument(s) : val Data value to count trailing zero bits.
;
; Return(s) : Number of contiguous, least-significant, trailing zero bits in 'val'.
;
; Caller(s) : Application.
;
; This function is an INTERNAL CPU module function but MAY be called by application
; function(s).
;
; Note(s) : (1) (a) Supports 32-bit data value size as configured by 'CPU_DATA' (see 'cpu.h
; CPU WORD CONFIGURATION Note #1').
;
; (b) For 32-bit values :
;
; b31 b30 b29 b28 b27 ... b02 b01 b00 # Trailing Zeros
; --- --- --- --- --- --- --- --- ----------------
; x x x x x x x 1 0
; x x x x x x 1 0 1
; x x x x x 1 0 0 2
; : : : : : : : : :
; : : : : : : : : :
; x x x x 1 0 0 0 27
; x x x 1 0 0 0 0 28
; x x 1 0 0 0 0 0 29
; x 1 0 0 0 0 0 0 30
; 1 0 0 0 0 0 0 0 31
; 0 0 0 0 0 0 0 0 32
;
;
; (2) MUST be defined in 'cpu_a.asm' (or 'cpu_c.c') if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT is
; #define'd in 'cpu_cfg.h' or 'cpu.h'.
;********************************************************************************************************
CPU_CntTrailZeros
RBIT R0, R0 ; Reverse bits
CLZ R0, R0 ; Count trailing zeros
BX LR
;$PAGE
;********************************************************************************************************
; CPU_RevBits()
; REVERSE BITS
;
; Description : Reverses the bits in a data value.
;
; Prototypes : CPU_DATA CPU_RevBits(CPU_DATA val);
;
; Argument(s) : val Data value to reverse bits.
;
; Return(s) : Value with all bits in 'val' reversed (see Note #1).
;
; Caller(s) : Application.
;
; This function is an INTERNAL CPU module function but MAY be called by application function(s).
;
; Note(s) : (1) The final, reversed data value for 'val' is such that :
;
; 'val's final bit 0 = 'val's original bit N
; 'val's final bit 1 = 'val's original bit (N - 1)
; 'val's final bit 2 = 'val's original bit (N - 2)
;
; ... ...
;
; 'val's final bit (N - 2) = 'val's original bit 2
; 'val's final bit (N - 1) = 'val's original bit 1
; 'val's final bit N = 'val's original bit 0
;********************************************************************************************************
CPU_RevBits
RBIT R0, R0 ; Reverse bits
BX LR
;$PAGE
;********************************************************************************************************
; CPU ASSEMBLY PORT FILE END
;********************************************************************************************************
END

View File

@@ -0,0 +1,755 @@
/*
*********************************************************************************************************
* uC/CPU
* CPU CONFIGURATION & PORT LAYER
*
* (c) Copyright 2004-2011; Micrium, Inc.; Weston, FL
*
* All rights reserved. Protected by international copyright laws.
*
* uC/CPU is provided in source form to registered licensees ONLY. It is
* illegal to distribute this source code to any third party unless you receive
* written permission by an authorized Micrium representative. Knowledge of
* the source code may NOT be used to develop a similar product.
*
* Please help us continue to provide the Embedded community with the finest
* software available. Your honesty is greatly appreciated.
*
* You can contact us at www.micrium.com.
*********************************************************************************************************
*/
/*
*********************************************************************************************************
*
* CPU PORT FILE
*
* ARM-Cortex-M3
* IAR C Compiler
*
* Filename : cpu_c.c
* Version : V1.29.01.00
* Programmer(s) : JJL
* BAN
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* INCLUDE FILES
*********************************************************************************************************
*/
#define MICRIUM_SOURCE
#include <cpu.h>
#include <cpu_core.h>
#include <lib_def.h>
/*$PAGE*/
/*
*********************************************************************************************************
* LOCAL DEFINES
*********************************************************************************************************
*/
#define CPU_INT_SRC_POS_MAX ((((CPU_REG_NVIC_NVIC + 1) & 0x1F) * 32) + 16)
#define CPU_BIT_BAND_SRAM_REG_LO 0x20000000
#define CPU_BIT_BAND_SRAM_REG_HI 0x200FFFFF
#define CPU_BIT_BAND_SRAM_BASE 0x22000000
#define CPU_BIT_BAND_PERIPH_REG_LO 0x40000000
#define CPU_BIT_BAND_PERIPH_REG_HI 0x400FFFFF
#define CPU_BIT_BAND_PERIPH_BASE 0x42000000
/*
*********************************************************************************************************
* LOCAL CONSTANTS
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* LOCAL DATA TYPES
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* LOCAL TABLES
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* LOCAL GLOBAL VARIABLES
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* LOCAL FUNCTION PROTOTYPES
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* LOCAL CONFIGURATION ERRORS
*********************************************************************************************************
*/
/*$PAGE*/
/*
*********************************************************************************************************
* CPU_BitBandClr()
*
* Description : Clear bit in bit-band region.
*
* Argument(s) : addr Byte address in memory space.
*
* bit_nbr Bit number in byte.
*
* Return(s) : none.
*
* Caller(s) : Application.
*
* Note(s) : none.
*********************************************************************************************************
*/
void CPU_BitBandClr (CPU_ADDR addr,
CPU_INT08U bit_nbr)
{
CPU_ADDR bit_word_off;
CPU_ADDR bit_word_addr;
if ((addr >= CPU_BIT_BAND_SRAM_REG_LO) &&
(addr <= CPU_BIT_BAND_SRAM_REG_HI)) {
bit_word_off = ((addr - CPU_BIT_BAND_SRAM_REG_LO ) * 32) + (bit_nbr * 4);
bit_word_addr = CPU_BIT_BAND_SRAM_BASE + bit_word_off;
*(volatile CPU_INT32U *)(bit_word_addr) = 0;
} else if ((addr >= CPU_BIT_BAND_PERIPH_REG_LO) &&
(addr <= CPU_BIT_BAND_PERIPH_REG_HI)) {
bit_word_off = ((addr - CPU_BIT_BAND_PERIPH_REG_LO) * 32) + (bit_nbr * 4);
bit_word_addr = CPU_BIT_BAND_PERIPH_BASE + bit_word_off;
*(volatile CPU_INT32U *)(bit_word_addr) = 0;
}
}
/*$PAGE*/
/*
*********************************************************************************************************
* CPU_BitBandSet()
*
* Description : Set bit in bit-band region.
*
* Argument(s) : addr Byte address in memory space.
*
* bit_nbr Bit number in byte.
*
* Return(s) : none.
*
* Caller(s) : Application.
*
* Note(s) : none.
*********************************************************************************************************
*/
void CPU_BitBandSet (CPU_ADDR addr,
CPU_INT08U bit_nbr)
{
CPU_ADDR bit_word_off;
CPU_ADDR bit_word_addr;
if ((addr >= CPU_BIT_BAND_SRAM_REG_LO) &&
(addr <= CPU_BIT_BAND_SRAM_REG_HI)) {
bit_word_off = ((addr - CPU_BIT_BAND_SRAM_REG_LO ) * 32) + (bit_nbr * 4);
bit_word_addr = CPU_BIT_BAND_SRAM_BASE + bit_word_off;
*(volatile CPU_INT32U *)(bit_word_addr) = 1;
} else if ((addr >= CPU_BIT_BAND_PERIPH_REG_LO) &&
(addr <= CPU_BIT_BAND_PERIPH_REG_HI)) {
bit_word_off = ((addr - CPU_BIT_BAND_PERIPH_REG_LO) * 32) + (bit_nbr * 4);
bit_word_addr = CPU_BIT_BAND_PERIPH_BASE + bit_word_off;
*(volatile CPU_INT32U *)(bit_word_addr) = 1;
}
}
/*$PAGE*/
/*
*********************************************************************************************************
* CPU_IntSrcDis()
*
* Description : Disable an interrupt source.
*
* Argument(s) : pos Position of interrupt vector in interrupt table :
*
* 0 Invalid (see Note #1a).
* 1 Invalid (see Note #1b).
* 2 Non-maskable interrupt.
* 3 Hard Fault.
* 4 Memory Management.
* 5 Bus Fault.
* 6 Usage Fault.
* 7-10 Reserved.
* 11 SVCall
* 12 Debug monitor.
* 13 Reserved
* 14 PendSV.
* 15 SysTick.
* 16+ External Interrupt.
*
* Return(s) : none.
*
* Caller(s) : Application.
*
* Note(s) : (1) Several table positions do not contain interrupt sources :
*
* (a) Position 0 contains the stack pointer.
* (b) Positions 7-10, 13 are reserved.
*
* (2) Several interrupts cannot be disabled/enabled :
*
* (a) Reset.
* (b) NMI.
* (c) Hard fault.
* (d) SVCall.
* (e) Debug monitor.
* (f) PendSV.
*
* (3) The maximum Cortex-M3 table position is 256. A particular Cortex-M3 may have fewer
* than 240 external exceptions and, consequently, fewer than 256 table positions.
* This function assumes that the specified table position is valid if the interrupt
* controller type register's INTLINESNUM field is large enough so that the position
* COULD be valid.
*********************************************************************************************************
*/
/*$PAGE*/
void CPU_IntSrcDis (CPU_INT08U pos)
{
CPU_INT08U group;
CPU_INT08U pos_max;
CPU_INT08U nbr;
CPU_SR_ALLOC();
switch (pos) {
case CPU_INT_STK_PTR: /* ---------------- INVALID OR RESERVED --------------- */
case CPU_INT_RSVD_07:
case CPU_INT_RSVD_08:
case CPU_INT_RSVD_09:
case CPU_INT_RSVD_10:
case CPU_INT_RSVD_13:
break;
/* ----------------- SYSTEM EXCEPTIONS ---------------- */
case CPU_INT_RESET: /* Reset (see Note #2). */
case CPU_INT_NMI: /* Non-maskable interrupt (see Note #2). */
case CPU_INT_HFAULT: /* Hard fault (see Note #2). */
case CPU_INT_SVCALL: /* SVCall (see Note #2). */
case CPU_INT_DBGMON: /* Debug monitor (see Note #2). */
case CPU_INT_PENDSV: /* PendSV (see Note #2). */
break;
case CPU_INT_MEM: /* Memory management. */
CPU_CRITICAL_ENTER();
CPU_REG_NVIC_SHCSR &= ~CPU_REG_NVIC_SHCSR_MEMFAULTENA;
CPU_CRITICAL_EXIT();
break;
case CPU_INT_BUSFAULT: /* Bus fault. */
CPU_CRITICAL_ENTER();
CPU_REG_NVIC_SHCSR &= ~CPU_REG_NVIC_SHCSR_BUSFAULTENA;
CPU_CRITICAL_EXIT();
break;
case CPU_INT_USAGEFAULT: /* Usage fault. */
CPU_CRITICAL_ENTER();
CPU_REG_NVIC_SHCSR &= ~CPU_REG_NVIC_SHCSR_USGFAULTENA;
CPU_CRITICAL_EXIT();
break;
case CPU_INT_SYSTICK: /* SysTick. */
CPU_CRITICAL_ENTER();
CPU_REG_NVIC_ST_CTRL &= ~CPU_REG_NVIC_ST_CTRL_ENABLE;
CPU_CRITICAL_EXIT();
break;
/* ---------------- EXTERNAL INTERRUPT ---------------- */
default:
pos_max = CPU_INT_SRC_POS_MAX;
if (pos < pos_max) { /* See Note #3. */
group = (pos - 16) / 32;
nbr = (pos - 16) % 32;
CPU_CRITICAL_ENTER();
CPU_REG_NVIC_CLREN(group) = DEF_BIT(nbr);
CPU_CRITICAL_EXIT();
}
break;
}
}
/*$PAGE*/
/*
*********************************************************************************************************
* CPU_IntSrcEn()
*
* Description : Enable an interrupt source.
*
* Argument(s) : pos Position of interrupt vector in interrupt table (see 'CPU_IntSrcDis()').
*
* Return(s) : none.
*
* Caller(s) : Application.
*
* Note(s) : (1) See 'CPU_IntSrcDis() Note #1'.
*
* (2) See 'CPU_IntSrcDis() Note #2'.
*
* (3) See 'CPU_IntSrcDis() Note #3'.
*********************************************************************************************************
*/
void CPU_IntSrcEn (CPU_INT08U pos)
{
CPU_INT08U group;
CPU_INT08U nbr;
CPU_INT08U pos_max;
CPU_SR_ALLOC();
switch (pos) {
case CPU_INT_STK_PTR: /* ---------------- INVALID OR RESERVED --------------- */
case CPU_INT_RSVD_07:
case CPU_INT_RSVD_08:
case CPU_INT_RSVD_09:
case CPU_INT_RSVD_10:
case CPU_INT_RSVD_13:
break;
/* ----------------- SYSTEM EXCEPTIONS ---------------- */
case CPU_INT_RESET: /* Reset (see Note #2). */
case CPU_INT_NMI: /* Non-maskable interrupt (see Note #2). */
case CPU_INT_HFAULT: /* Hard fault (see Note #2). */
case CPU_INT_SVCALL: /* SVCall (see Note #2). */
case CPU_INT_DBGMON: /* Debug monitor (see Note #2). */
case CPU_INT_PENDSV: /* PendSV (see Note #2). */
break;
case CPU_INT_MEM: /* Memory management. */
CPU_CRITICAL_ENTER();
CPU_REG_NVIC_SHCSR |= CPU_REG_NVIC_SHCSR_MEMFAULTENA;
CPU_CRITICAL_EXIT();
break;
case CPU_INT_BUSFAULT: /* Bus fault. */
CPU_CRITICAL_ENTER();
CPU_REG_NVIC_SHCSR |= CPU_REG_NVIC_SHCSR_BUSFAULTENA;
CPU_CRITICAL_EXIT();
break;
case CPU_INT_USAGEFAULT: /* Usage fault. */
CPU_CRITICAL_ENTER();
CPU_REG_NVIC_SHCSR |= CPU_REG_NVIC_SHCSR_USGFAULTENA;
CPU_CRITICAL_EXIT();
break;
case CPU_INT_SYSTICK: /* SysTick. */
CPU_CRITICAL_ENTER();
CPU_REG_NVIC_ST_CTRL |= CPU_REG_NVIC_ST_CTRL_ENABLE;
CPU_CRITICAL_EXIT();
break;
/* ---------------- EXTERNAL INTERRUPT ---------------- */
default:
pos_max = CPU_INT_SRC_POS_MAX;
if (pos < pos_max) { /* See Note #3. */
group = (pos - 16) / 32;
nbr = (pos - 16) % 32;
CPU_CRITICAL_ENTER();
CPU_REG_NVIC_SETEN(group) = DEF_BIT(nbr);
CPU_CRITICAL_EXIT();
}
break;
}
}
/*$PAGE*/
/*
*********************************************************************************************************
* CPU_IntSrcPendClr()
*
* Description : Clear a pending interrupt.
*
* Argument(s) : pos Position of interrupt vector in interrupt table (see 'CPU_IntSrcDis()').
*
* Return(s) : none.
*
* Caller(s) : Application.
*
* Note(s) : (1) See 'CPU_IntSrcDis() Note #1'.
*
* (2) The pending status of several interrupts cannot be clear/set :
*
* (a) Reset.
* (b) NMI.
* (c) Hard fault.
* (d) Memory Managment.
* (e) Bus Fault.
* (f) Usage Fault.
* (g) SVCall.
* (h) Debug monitor.
* (i) PendSV.
* (j) Systick
*
* (3) See 'CPU_IntSrcDis() Note #3'.
*********************************************************************************************************
*/
void CPU_IntSrcPendClr (CPU_INT08U pos)
{
CPU_INT08U group;
CPU_INT08U nbr;
CPU_INT08U pos_max;
CPU_SR_ALLOC();
switch (pos) {
case CPU_INT_STK_PTR: /* ---------------- INVALID OR RESERVED --------------- */
case CPU_INT_RSVD_07:
case CPU_INT_RSVD_08:
case CPU_INT_RSVD_09:
case CPU_INT_RSVD_10:
case CPU_INT_RSVD_13:
break;
/* ----------------- SYSTEM EXCEPTIONS ---------------- */
case CPU_INT_RESET: /* Reset (see Note #2). */
case CPU_INT_NMI: /* Non-maskable interrupt (see Note #2). */
case CPU_INT_HFAULT: /* Hard fault (see Note #2). */
case CPU_INT_MEM: /* Memory management (see Note #2). */
case CPU_INT_SVCALL: /* SVCall (see Note #2). */
case CPU_INT_DBGMON: /* Debug monitor (see Note #2). */
case CPU_INT_PENDSV: /* PendSV (see Note #2). */
case CPU_INT_BUSFAULT: /* Bus fault. */
case CPU_INT_USAGEFAULT: /* Usage fault. */
case CPU_INT_SYSTICK: /* SysTick. */
break;
/* ---------------- EXTERNAL INTERRUPT ---------------- */
default:
pos_max = CPU_INT_SRC_POS_MAX;
if (pos < pos_max) { /* See Note #3. */
group = (pos - 16) / 32;
nbr = (pos - 16) % 32;
CPU_CRITICAL_ENTER();
CPU_REG_NVIC_CLRPEND(group) = DEF_BIT(nbr);
CPU_CRITICAL_EXIT();
}
break;
}
}
/*$PAGE*/
/*
*********************************************************************************************************
* CPU_IntSrcPrioSet()
*
* Description : Set priority of an interrupt source.
*
* Argument(s) : pos Position of interrupt vector in interrupt table (see 'CPU_IntSrcDis()').
*
* prio Priority. Use a lower priority number for a higher priority.
*
* Return(s) : none.
*
* Caller(s) : Application.
*
* Note(s) : (1) See 'CPU_IntSrcDis() Note #1'.
*
* (2) Several interrupts priorities CANNOT be set :
*
* (a) Reset (always -3).
* (b) NMI (always -2).
* (c) Hard fault (always -1).
*
* (3) See 'CPU_IntSrcDis() Note #3'.
*********************************************************************************************************
*/
void CPU_IntSrcPrioSet (CPU_INT08U pos,
CPU_INT08U prio)
{
CPU_INT08U group;
CPU_INT08U nbr;
CPU_INT08U pos_max;
CPU_INT32U prio_32;
CPU_INT32U temp;
CPU_SR_ALLOC();
prio_32 = CPU_RevBits((CPU_INT08U)prio);
prio = (CPU_INT08U)(prio_32 >> (3 * DEF_OCTET_NBR_BITS));
switch (pos) {
case CPU_INT_STK_PTR: /* ---------------- INVALID OR RESERVED --------------- */
case CPU_INT_RSVD_07:
case CPU_INT_RSVD_08:
case CPU_INT_RSVD_09:
case CPU_INT_RSVD_10:
case CPU_INT_RSVD_13:
break;
/* ----------------- SYSTEM EXCEPTIONS ---------------- */
case CPU_INT_RESET: /* Reset (see Note #2). */
case CPU_INT_NMI: /* Non-maskable interrupt (see Note #2). */
case CPU_INT_HFAULT: /* Hard fault (see Note #2). */
break;
case CPU_INT_MEM: /* Memory management. */
CPU_CRITICAL_ENTER();
temp = CPU_REG_NVIC_SHPRI1;
temp &= ~(DEF_OCTET_MASK << (0 * DEF_OCTET_NBR_BITS));
temp |= (prio << (0 * DEF_OCTET_NBR_BITS));
CPU_REG_NVIC_SHPRI1 = temp;
CPU_CRITICAL_EXIT();
break;
case CPU_INT_BUSFAULT: /* Bus fault. */
CPU_CRITICAL_ENTER();
temp = CPU_REG_NVIC_SHPRI1;
temp &= ~(DEF_OCTET_MASK << (1 * DEF_OCTET_NBR_BITS));
temp |= (prio << (1 * DEF_OCTET_NBR_BITS));
CPU_REG_NVIC_SHPRI1 = temp;
CPU_CRITICAL_EXIT();
break;
case CPU_INT_USAGEFAULT: /* Usage fault. */
CPU_CRITICAL_ENTER();
temp = CPU_REG_NVIC_SHPRI1;
temp &= ~(DEF_OCTET_MASK << (2 * DEF_OCTET_NBR_BITS));
temp |= (prio << (2 * DEF_OCTET_NBR_BITS));
CPU_REG_NVIC_SHPRI1 = temp;
CPU_CRITICAL_EXIT();
break;
case CPU_INT_SVCALL: /* SVCall. */
CPU_CRITICAL_ENTER();
temp = CPU_REG_NVIC_SHPRI2;
temp &= ~((CPU_INT32U)DEF_OCTET_MASK << (3 * DEF_OCTET_NBR_BITS));
temp |= (prio << (3 * DEF_OCTET_NBR_BITS));
CPU_REG_NVIC_SHPRI2 = temp;
CPU_CRITICAL_EXIT();
break;
case CPU_INT_DBGMON: /* Debug monitor. */
CPU_CRITICAL_ENTER();
temp = CPU_REG_NVIC_SHPRI3;
temp &= ~(DEF_OCTET_MASK << (0 * DEF_OCTET_NBR_BITS));
temp |= (prio << (0 * DEF_OCTET_NBR_BITS));
CPU_REG_NVIC_SHPRI3 = temp;
CPU_CRITICAL_EXIT();
break;
case CPU_INT_PENDSV: /* PendSV. */
CPU_CRITICAL_ENTER();
temp = CPU_REG_NVIC_SHPRI3;
temp &= ~(DEF_OCTET_MASK << (2 * DEF_OCTET_NBR_BITS));
temp |= (prio << (2 * DEF_OCTET_NBR_BITS));
CPU_REG_NVIC_SHPRI3 = temp;
CPU_CRITICAL_EXIT();
break;
case CPU_INT_SYSTICK: /* SysTick. */
CPU_CRITICAL_ENTER();
temp = CPU_REG_NVIC_SHPRI3;
temp &= ~((CPU_INT32U)DEF_OCTET_MASK << (3 * DEF_OCTET_NBR_BITS));
temp |= (prio << (3 * DEF_OCTET_NBR_BITS));
CPU_REG_NVIC_SHPRI3 = temp;
CPU_CRITICAL_EXIT();
break;
/* ---------------- EXTERNAL INTERRUPT ---------------- */
default:
pos_max = CPU_INT_SRC_POS_MAX;
if (pos < pos_max) { /* See Note #3. */
group = (pos - 16) / 4;
nbr = (pos - 16) % 4;
CPU_CRITICAL_ENTER();
temp = CPU_REG_NVIC_PRIO(group);
temp &= ~(DEF_OCTET_MASK << (nbr * DEF_OCTET_NBR_BITS));
temp |= (prio << (nbr * DEF_OCTET_NBR_BITS));
CPU_REG_NVIC_PRIO(group) = temp;
CPU_CRITICAL_EXIT();
}
break;
}
}
/*$PAGE*/
/*
*********************************************************************************************************
* CPU_IntSrcPrioGet()
*
* Description : Get priority of an interrupt source.
*
* Argument(s) : pos Position of interrupt vector in interrupt table (see 'CPU_IntSrcDis()').
*
* Return(s) : Priority of interrupt source. If the interrupt source specified is invalid, then
* DEF_INT_16S_MIN_VAL is returned.
*
* Caller(s) : Application.
*
* Note(s) : (1) See 'CPU_IntSrcDis() Note #1'.
*
* (2) See 'CPU_IntSrcPrioSet() Note #2'.
*
* (3) See 'CPU_IntSrcDis() Note #3'.
*********************************************************************************************************
*/
CPU_INT16S CPU_IntSrcPrioGet (CPU_INT08U pos)
{
CPU_INT08U group;
CPU_INT08U nbr;
CPU_INT08U pos_max;
CPU_INT16S prio;
CPU_INT32U prio_32;
CPU_INT32U temp;
CPU_SR_ALLOC();
switch (pos) {
case CPU_INT_STK_PTR: /* ---------------- INVALID OR RESERVED --------------- */
case CPU_INT_RSVD_07:
case CPU_INT_RSVD_08:
case CPU_INT_RSVD_09:
case CPU_INT_RSVD_10:
case CPU_INT_RSVD_13:
prio = DEF_INT_16S_MIN_VAL;
break;
/* ----------------- SYSTEM EXCEPTIONS ---------------- */
case CPU_INT_RESET: /* Reset (see Note #2). */
prio = -3;
break;
case CPU_INT_NMI: /* Non-maskable interrupt (see Note #2). */
prio = -2;
break;
case CPU_INT_HFAULT: /* Hard fault (see Note #2). */
prio = -1;
break;
case CPU_INT_MEM: /* Memory management. */
CPU_CRITICAL_ENTER();
temp = CPU_REG_NVIC_SHPRI1;
prio = (temp >> (0 * DEF_OCTET_NBR_BITS)) & DEF_OCTET_MASK;
CPU_CRITICAL_EXIT();
break;
case CPU_INT_BUSFAULT: /* Bus fault. */
CPU_CRITICAL_ENTER();
temp = CPU_REG_NVIC_SHPRI1;
prio = (temp >> (1 * DEF_OCTET_NBR_BITS)) & DEF_OCTET_MASK;
CPU_CRITICAL_EXIT();
break;
case CPU_INT_USAGEFAULT: /* Usage fault. */
CPU_CRITICAL_ENTER();
temp = CPU_REG_NVIC_SHPRI1;
prio = (temp >> (2 * DEF_OCTET_NBR_BITS)) & DEF_OCTET_MASK;
break;
case CPU_INT_SVCALL: /* SVCall. */
CPU_CRITICAL_ENTER();
temp = CPU_REG_NVIC_SHPRI2;
prio = (temp >> (3 * DEF_OCTET_NBR_BITS)) & DEF_OCTET_MASK;
CPU_CRITICAL_EXIT();
break;
case CPU_INT_DBGMON: /* Debug monitor. */
CPU_CRITICAL_ENTER();
temp = CPU_REG_NVIC_SHPRI3;
prio = (temp >> (0 * DEF_OCTET_NBR_BITS)) & DEF_OCTET_MASK;
CPU_CRITICAL_EXIT();
break;
case CPU_INT_PENDSV: /* PendSV. */
CPU_CRITICAL_ENTER();
temp = CPU_REG_NVIC_SHPRI3;
prio = (temp >> (2 * DEF_OCTET_NBR_BITS)) & DEF_OCTET_MASK;
CPU_CRITICAL_EXIT();
break;
case CPU_INT_SYSTICK: /* SysTick. */
CPU_CRITICAL_ENTER();
temp = CPU_REG_NVIC_SHPRI3;
prio = (temp >> (3 * DEF_OCTET_NBR_BITS)) & DEF_OCTET_MASK;
CPU_CRITICAL_EXIT();
break;
/* ---------------- EXTERNAL INTERRUPT ---------------- */
default:
pos_max = CPU_INT_SRC_POS_MAX;
if (pos < pos_max) { /* See Note #3. */
group = (pos - 16) / 4;
nbr = (pos - 16) % 4;
CPU_CRITICAL_ENTER();
temp = CPU_REG_NVIC_PRIO(group);
CPU_CRITICAL_EXIT();
prio = (temp >> (nbr * DEF_OCTET_NBR_BITS)) & DEF_OCTET_MASK;
} else {
prio = DEF_INT_16S_MIN_VAL;
}
break;
}
if (prio >= 0) {
prio_32 = CPU_RevBits((CPU_INT32U)prio);
prio = (CPU_INT16S)(prio_32 >> (3 * DEF_OCTET_NBR_BITS));
}
return (prio);
}

View File

@@ -0,0 +1,726 @@
/*
*********************************************************************************************************
* uC/CPU
* CPU CONFIGURATION & PORT LAYER
*
* (c) Copyright 2004-2011; Micrium, Inc.; Weston, FL
*
* All rights reserved. Protected by international copyright laws.
*
* uC/CPU is provided in source form to registered licensees ONLY. It is
* illegal to distribute this source code to any third party unless you receive
* written permission by an authorized Micrium representative. Knowledge of
* the source code may NOT be used to develop a similar product.
*
* Please help us continue to provide the Embedded community with the finest
* software available. Your honesty is greatly appreciated.
*
* You can contact us at www.micrium.com.
*********************************************************************************************************
*/
/*
*********************************************************************************************************
*
* CPU PORT FILE
*
* ARM-Cortex-M3
* RealView Development Suite
* RealView Microcontroller Development Kit (MDK)
* ARM Developer Suite (ADS)
* Keil uVision
*
* Filename : cpu.h
* Version : V1.29.01.00
* Programmer(s) : JJL
* BAN
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* MODULE
*
* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of
* the CPU module present pre-processor macro definition.
*********************************************************************************************************
*/
#ifndef CPU_MODULE_PRESENT /* See Note #1. */
#define CPU_MODULE_PRESENT
/*
*********************************************************************************************************
* CPU INCLUDE FILES
*
* Note(s) : (1) The following CPU files are located in the following directories :
*
* (a) \<Your Product Application>\cpu_cfg.h
*
* (b) (1) \<CPU-Compiler Directory>\cpu_def.h
* (2) \<CPU-Compiler Directory>\<cpu>\<compiler>\cpu*.*
*
* where
* <Your Product Application> directory path for Your Product's Application
* <CPU-Compiler Directory> directory path for common CPU-compiler software
* <cpu> directory name for specific CPU
* <compiler> directory name for specific compiler
*
* (2) Compiler MUST be configured to include as additional include path directories :
*
* (a) '\<Your Product Application>\' directory See Note #1a
*
* (b) (1) '\<CPU-Compiler Directory>\' directory See Note #1b1
* (2) '\<CPU-Compiler Directory>\<cpu>\<compiler>\' directory See Note #1b2
*
* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from
* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions.
*
* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric
* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to
* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED).
*********************************************************************************************************
*/
#include <cpu_def.h>
#include <cpu_cfg.h> /* See Note #3. */
/*$PAGE*/
/*
*********************************************************************************************************
* CONFIGURE STANDARD DATA TYPES
*
* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications.
*
* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer
* data type of a pointer to a function which returns void & has no arguments.
*
* (2) Example function pointer usage :
*
* CPU_FNCT_VOID FnctName;
*
* FnctName();
*
* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer
* data type of a pointer to a function which returns void & has a single void
* pointer argument.
*
* (2) Example function pointer usage :
*
* CPU_FNCT_PTR FnctName;
* void *p_obj
*
* FnctName(p_obj);
*********************************************************************************************************
*/
typedef void CPU_VOID;
typedef char CPU_CHAR; /* 8-bit character */
typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */
typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */
typedef signed char CPU_INT08S; /* 8-bit signed integer */
typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */
typedef signed short CPU_INT16S; /* 16-bit signed integer */
typedef unsigned int CPU_INT32U; /* 32-bit unsigned integer */
typedef signed int CPU_INT32S; /* 32-bit signed integer */
typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */
typedef signed long long CPU_INT64S; /* 64-bit signed integer */
typedef float CPU_FP32; /* 32-bit floating point */
typedef double CPU_FP64; /* 64-bit floating point */
typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */
typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */
typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */
typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */
typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */
typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */
/*$PAGE*/
/*
*********************************************************************************************************
* CPU WORD CONFIGURATION
*
* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or
* compiler's word sizes :
*
* CPU_WORD_SIZE_08 8-bit word size
* CPU_WORD_SIZE_16 16-bit word size
* CPU_WORD_SIZE_32 32-bit word size
* CPU_WORD_SIZE_64 64-bit word size
*
* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order :
*
* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant
* octet @ lowest memory address)
* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant
* octet @ lowest memory address)
*********************************************************************************************************
*/
/* Define CPU word sizes (see Note #1) : */
#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */
#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */
#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */
#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */
/*
*********************************************************************************************************
* CONFIGURE CPU ADDRESS & DATA TYPES
*********************************************************************************************************
*/
/* CPU address type based on address bus size. */
#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32)
typedef CPU_INT32U CPU_ADDR;
#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16)
typedef CPU_INT16U CPU_ADDR;
#else
typedef CPU_INT08U CPU_ADDR;
#endif
/* CPU data type based on data bus size. */
#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32)
typedef CPU_INT32U CPU_DATA;
#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16)
typedef CPU_INT16U CPU_DATA;
#else
typedef CPU_INT08U CPU_DATA;
#endif
typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */
typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */
/*
*********************************************************************************************************
* CPU STACK CONFIGURATION
*
* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order :
*
* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack
* memory address after data is pushed onto the stack
* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack
* memory address after data is pushed onto the stack
*********************************************************************************************************
*/
#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */
typedef CPU_INT32U CPU_STK; /* Defines CPU stack word size (in octets). */
typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size (in number of CPU_STKs). */
/*$PAGE*/
/*
*********************************************************************************************************
* CRITICAL SECTION CONFIGURATION
*
* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method :
*
* Enter/Exit critical sections by ...
*
* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts
* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack
* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable
*
* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support
* multiple levels of interrupts. However, with some CPUs/compilers, this is the only
* available method.
*
* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple
* levels of interrupts. However, this method assumes that the compiler provides C-level
* &/or assembly-level functionality for the following :
*
* ENTER CRITICAL SECTION :
* (1) Push/save interrupt status onto a local stack
* (2) Disable interrupts
*
* EXIT CRITICAL SECTION :
* (3) Pop/restore interrupt status from a local stack
*
* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple
* levels of interrupts. However, this method assumes that the compiler provides C-level
* &/or assembly-level functionality for the following :
*
* ENTER CRITICAL SECTION :
* (1) Save interrupt status into a local variable
* (2) Disable interrupts
*
* EXIT CRITICAL SECTION :
* (3) Restore interrupt status from a local variable
*
* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT
* allow inline assembly in C source files, critical section macro's MUST call an assembly
* subroutine defined in a 'cpu_a.asm' file located in the following software directory :
*
* \<CPU-Compiler Directory>\<cpu>\<compiler>\
*
* where
* <CPU-Compiler Directory> directory path for common CPU-compiler software
* <cpu> directory name for specific CPU
* <compiler> directory name for specific compiler
*
* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need
* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured).
*
* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if
* used, MUST be declared following ALL other local variables.
*
* Example :
*
* void Fnct (void)
* {
* CPU_INT08U val_08;
* CPU_INT16U val_16;
* CPU_INT32U val_32;
* CPU_SR_ALLOC(); MUST be declared after ALL other local variables
* :
* :
* }
*
* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to
* completely store the CPU's/compiler's status word.
*********************************************************************************************************
*/
/*$PAGE*/
/* Configure CPU critical method (see Note #1) : */
#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL
typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */
/* Allocates CPU status register word (see Note #3a). */
#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)
#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0
#else
#define CPU_SR_ALLOC()
#endif
#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/
#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */
#ifdef CPU_CFG_INT_DIS_MEAS_EN
/* Disable interrupts, ... */
/* & start interrupts disabled time measurement.*/
#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \
CPU_IntDisMeasStart(); } while (0)
/* Stop & measure interrupts disabled time, */
/* ... & re-enable interrupts. */
#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \
CPU_INT_EN(); } while (0)
#else
#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */
#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* CPU COUNT ZEROS CONFIGURATION
*
* Note(s) : (1) (a) Configure CPU_CFG_LEAD_ZEROS_ASM_PRESENT to define count leading zeros bits
* function(s) in :
*
* (1) 'cpu_a.asm', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/
* 'cpu_cfg.h' to enable assembly-optimized function(s)
*
* (2) 'cpu_core.c', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/
* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise
*
* (b) Configure CPU_CFG_TRAIL_ZEROS_ASM_PRESENT to define count trailing zeros bits
* function(s) in :
*
* (1) 'cpu_a.asm', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/
* 'cpu_cfg.h' to enable assembly-optimized function(s)
*
* (2) 'cpu_core.c', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/
* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise
*********************************************************************************************************
*/
/* Configure CPU count leading zeros bits ... */
#define CPU_CFG_LEAD_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1a). */
/* Configure CPU count trailing zeros bits ... */
#define CPU_CFG_TRAIL_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1b). */
/*$PAGE*/
/*
*********************************************************************************************************
* FUNCTION PROTOTYPES
*********************************************************************************************************
*/
void CPU_IntDis (void);
void CPU_IntEn (void);
void CPU_IntSrcDis (CPU_INT08U pos);
void CPU_IntSrcEn (CPU_INT08U pos);
void CPU_IntSrcPendClr(CPU_INT08U pos);
CPU_INT16S CPU_IntSrcPrioGet(CPU_INT08U pos);
void CPU_IntSrcPrioSet(CPU_INT08U pos,
CPU_INT08U prio);
CPU_SR CPU_SR_Save (void);
void CPU_SR_Restore (CPU_SR cpu_sr);
void CPU_WaitForInt (void);
void CPU_WaitForExcept(void);
CPU_DATA CPU_RevBits (CPU_DATA val);
void CPU_BitBandClr (CPU_ADDR addr,
CPU_INT08U bit_nbr);
void CPU_BitBandSet (CPU_ADDR addr,
CPU_INT08U bit_nbr);
/*$PAGE*/
/*
*********************************************************************************************************
* INTERRUPT SOURCES
*********************************************************************************************************
*/
#define CPU_INT_STK_PTR 0u
#define CPU_INT_RESET 1u
#define CPU_INT_NMI 2u
#define CPU_INT_HFAULT 3u
#define CPU_INT_MEM 4u
#define CPU_INT_BUSFAULT 5u
#define CPU_INT_USAGEFAULT 6u
#define CPU_INT_RSVD_07 7u
#define CPU_INT_RSVD_08 8u
#define CPU_INT_RSVD_09 9u
#define CPU_INT_RSVD_10 10u
#define CPU_INT_SVCALL 11u
#define CPU_INT_DBGMON 12u
#define CPU_INT_RSVD_13 13u
#define CPU_INT_PENDSV 14u
#define CPU_INT_SYSTICK 15u
#define CPU_INT_EXT0 16u
/*
*********************************************************************************************************
* CPU REGISTERS
*********************************************************************************************************
*/
#define CPU_REG_NVIC_NVIC (*((CPU_REG32 *)(0xE000E004))) /* Int Ctrl'er Type Reg. */
#define CPU_REG_NVIC_ST_CTRL (*((CPU_REG32 *)(0xE000E010))) /* SysTick Ctrl & Status Reg. */
#define CPU_REG_NVIC_ST_RELOAD (*((CPU_REG32 *)(0xE000E014))) /* SysTick Reload Value Reg. */
#define CPU_REG_NVIC_ST_CURRENT (*((CPU_REG32 *)(0xE000E018))) /* SysTick Current Value Reg. */
#define CPU_REG_NVIC_ST_CAL (*((CPU_REG32 *)(0xE000E01C))) /* SysTick Calibration Value Reg. */
#define CPU_REG_NVIC_SETEN(n) (*((CPU_REG32 *)(0xE000E100 + (n) * 4u))) /* IRQ Set En Reg. */
#define CPU_REG_NVIC_CLREN(n) (*((CPU_REG32 *)(0xE000E180 + (n) * 4u))) /* IRQ Clr En Reg. */
#define CPU_REG_NVIC_SETPEND(n) (*((CPU_REG32 *)(0xE000E200 + (n) * 4u))) /* IRQ Set Pending Reg. */
#define CPU_REG_NVIC_CLRPEND(n) (*((CPU_REG32 *)(0xE000E280 + (n) * 4u))) /* IRQ Clr Pending Reg. */
#define CPU_REG_NVIC_ACTIVE(n) (*((CPU_REG32 *)(0xE000E300 + (n) * 4u))) /* IRQ Active Reg. */
#define CPU_REG_NVIC_PRIO(n) (*((CPU_REG32 *)(0xE000E400 + (n) * 4u))) /* IRQ Prio Reg. */
#define CPU_REG_NVIC_CPUID (*((CPU_REG32 *)(0xE000ED00))) /* CPUID Base Reg. */
#define CPU_REG_NVIC_ICSR (*((CPU_REG32 *)(0xE000ED04))) /* Int Ctrl State Reg. */
#define CPU_REG_NVIC_VTOR (*((CPU_REG32 *)(0xE000ED08))) /* Vect Tbl Offset Reg. */
#define CPU_REG_NVIC_AIRCR (*((CPU_REG32 *)(0xE000ED0C))) /* App Int/Reset Ctrl Reg. */
#define CPU_REG_NVIC_SCR (*((CPU_REG32 *)(0xE000ED10))) /* System Ctrl Reg. */
#define CPU_REG_NVIC_CCR (*((CPU_REG32 *)(0xE000ED14))) /* Cfg Ctrl Reg. */
#define CPU_REG_NVIC_SHPRI1 (*((CPU_REG32 *)(0xE000ED18))) /* System Handlers 4 to 7 Prio. */
#define CPU_REG_NVIC_SHPRI2 (*((CPU_REG32 *)(0xE000ED1C))) /* System Handlers 8 to 11 Prio. */
#define CPU_REG_NVIC_SHPRI3 (*((CPU_REG32 *)(0xE000ED20))) /* System Handlers 12 to 15 Prio. */
#define CPU_REG_NVIC_SHCSR (*((CPU_REG32 *)(0xE000ED24))) /* System Handler Ctrl & State Reg. */
#define CPU_REG_NVIC_CFSR (*((CPU_REG32 *)(0xE000ED28))) /* Configurable Fault Status Reg. */
#define CPU_REG_NVIC_HFSR (*((CPU_REG32 *)(0xE000ED2C))) /* Hard Fault Status Reg. */
#define CPU_REG_NVIC_DFSR (*((CPU_REG32 *)(0xE000ED30))) /* Debug Fault Status Reg. */
#define CPU_REG_NVIC_MMFAR (*((CPU_REG32 *)(0xE000ED34))) /* Mem Manage Addr Reg. */
#define CPU_REG_NVIC_BFAR (*((CPU_REG32 *)(0xE000ED38))) /* Bus Fault Addr Reg. */
#define CPU_REG_NVIC_AFSR (*((CPU_REG32 *)(0xE000ED3C))) /* Aux Fault Status Reg. */
#define CPU_REG_NVIC_PFR0 (*((CPU_REG32 *)(0xE000ED40))) /* Processor Feature Reg 0. */
#define CPU_REG_NVIC_PFR1 (*((CPU_REG32 *)(0xE000ED44))) /* Processor Feature Reg 1. */
#define CPU_REG_NVIC_DFR0 (*((CPU_REG32 *)(0xE000ED48))) /* Debug Feature Reg 0. */
#define CPU_REG_NVIC_AFR0 (*((CPU_REG32 *)(0xE000ED4C))) /* Aux Feature Reg 0. */
#define CPU_REG_NVIC_MMFR0 (*((CPU_REG32 *)(0xE000ED50))) /* Memory Model Feature Reg 0. */
#define CPU_REG_NVIC_MMFR1 (*((CPU_REG32 *)(0xE000ED54))) /* Memory Model Feature Reg 1. */
#define CPU_REG_NVIC_MMFR2 (*((CPU_REG32 *)(0xE000ED58))) /* Memory Model Feature Reg 2. */
#define CPU_REG_NVIC_MMFR3 (*((CPU_REG32 *)(0xE000ED5C))) /* Memory Model Feature Reg 3. */
#define CPU_REG_NVIC_ISAFR0 (*((CPU_REG32 *)(0xE000ED60))) /* ISA Feature Reg 0. */
#define CPU_REG_NVIC_ISAFR1 (*((CPU_REG32 *)(0xE000ED64))) /* ISA Feature Reg 1. */
#define CPU_REG_NVIC_ISAFR2 (*((CPU_REG32 *)(0xE000ED68))) /* ISA Feature Reg 2. */
#define CPU_REG_NVIC_ISAFR3 (*((CPU_REG32 *)(0xE000ED6C))) /* ISA Feature Reg 3. */
#define CPU_REG_NVIC_ISAFR4 (*((CPU_REG32 *)(0xE000ED70))) /* ISA Feature Reg 4. */
#define CPU_REG_NVIC_SW_TRIG (*((CPU_REG32 *)(0xE000EF00))) /* Software Trigger Int Reg. */
#define CPU_REG_MPU_TYPE (*((CPU_REG32 *)(0xE000ED90))) /* MPU Type Reg. */
#define CPU_REG_MPU_CTRL (*((CPU_REG32 *)(0xE000ED94))) /* MPU Ctrl Reg. */
#define CPU_REG_MPU_REG_NBR (*((CPU_REG32 *)(0xE000ED98))) /* MPU Region Nbr Reg. */
#define CPU_REG_MPU_REG_BASE (*((CPU_REG32 *)(0xE000ED9C))) /* MPU Region Base Addr Reg. */
#define CPU_REG_MPU_REG_ATTR (*((CPU_REG32 *)(0xE000EDA0))) /* MPU Region Attrib & Size Reg. */
#define CPU_REG_DBG_CTRL (*((CPU_REG32 *)(0xE000EDF0))) /* Debug Halting Ctrl & Status Reg. */
#define CPU_REG_DBG_SELECT (*((CPU_REG32 *)(0xE000EDF4))) /* Debug Core Reg Selector Reg. */
#define CPU_REG_DBG_DATA (*((CPU_REG32 *)(0xE000EDF8))) /* Debug Core Reg Data Reg. */
#define CPU_REG_DBG_INT (*((CPU_REG32 *)(0xE000EDFC))) /* Debug Except & Monitor Ctrl Reg. */
/*$PAGE*/
/*
*********************************************************************************************************
* CPU REGISTER BITS
*********************************************************************************************************
*/
/* ---------- SYSTICK CTRL & STATUS REG BITS ---------- */
#define CPU_REG_NVIC_ST_CTRL_COUNTFLAG 0x00010000
#define CPU_REG_NVIC_ST_CTRL_CLKSOURCE 0x00000004
#define CPU_REG_NVIC_ST_CTRL_TICKINT 0x00000002
#define CPU_REG_NVIC_ST_CTRL_ENABLE 0x00000001
/* -------- SYSTICK CALIBRATION VALUE REG BITS -------- */
#define CPU_REG_NVIC_ST_CAL_NOREF 0x80000000
#define CPU_REG_NVIC_ST_CAL_SKEW 0x40000000
/* -------------- INT CTRL STATE REG BITS ------------- */
#define CPU_REG_NVIC_ICSR_NMIPENDSET 0x80000000
#define CPU_REG_NVIC_ICSR_PENDSVSET 0x10000000
#define CPU_REG_NVIC_ICSR_PENDSVCLR 0x08000000
#define CPU_REG_NVIC_ICSR_PENDSTSET 0x04000000
#define CPU_REG_NVIC_ICSR_PENDSTCLR 0x02000000
#define CPU_REG_NVIC_ICSR_ISRPREEMPT 0x00800000
#define CPU_REG_NVIC_ICSR_ISRPENDING 0x00400000
#define CPU_REG_NVIC_ICSR_RETTOBASE 0x00000800
/* ------------- VECT TBL OFFSET REG BITS ------------- */
#define CPU_REG_NVIC_VTOR_TBLBASE 0x20000000
/* ------------ APP INT/RESET CTRL REG BITS ----------- */
#define CPU_REG_NVIC_AIRCR_ENDIANNESS 0x00008000
#define CPU_REG_NVIC_AIRCR_SYSRESETREQ 0x00000004
#define CPU_REG_NVIC_AIRCR_VECTCLRACTIVE 0x00000002
#define CPU_REG_NVIC_AIRCR_VECTRESET 0x00000001
/* --------------- SYSTEM CTRL REG BITS --------------- */
#define CPU_REG_NVIC_SCR_SEVONPEND 0x00000010
#define CPU_REG_NVIC_SCR_SLEEPDEEP 0x00000004
#define CPU_REG_NVIC_SCR_SLEEPONEXIT 0x00000002
/* ----------------- CFG CTRL REG BITS ---------------- */
#define CPU_REG_NVIC_CCR_STKALIGN 0x00000200
#define CPU_REG_NVIC_CCR_BFHFNMIGN 0x00000100
#define CPU_REG_NVIC_CCR_DIV_0_TRP 0x00000010
#define CPU_REG_NVIC_CCR_UNALIGN_TRP 0x00000008
#define CPU_REG_NVIC_CCR_USERSETMPEND 0x00000002
#define CPU_REG_NVIC_CCR_NONBASETHRDENA 0x00000001
/* ------- SYSTEM HANDLER CTRL & STATE REG BITS ------- */
#define CPU_REG_NVIC_SHCSR_USGFAULTENA 0x00040000
#define CPU_REG_NVIC_SHCSR_BUSFAULTENA 0x00020000
#define CPU_REG_NVIC_SHCSR_MEMFAULTENA 0x00010000
#define CPU_REG_NVIC_SHCSR_SVCALLPENDED 0x00008000
#define CPU_REG_NVIC_SHCSR_BUSFAULTPENDED 0x00004000
#define CPU_REG_NVIC_SHCSR_MEMFAULTPENDED 0x00002000
#define CPU_REG_NVIC_SHCSR_USGFAULTPENDED 0x00001000
#define CPU_REG_NVIC_SHCSR_SYSTICKACT 0x00000800
#define CPU_REG_NVIC_SHCSR_PENDSVACT 0x00000400
#define CPU_REG_NVIC_SHCSR_MONITORACT 0x00000100
#define CPU_REG_NVIC_SHCSR_SVCALLACT 0x00000080
#define CPU_REG_NVIC_SHCSR_USGFAULTACT 0x00000008
#define CPU_REG_NVIC_SHCSR_BUSFAULTACT 0x00000002
#define CPU_REG_NVIC_SHCSR_MEMFAULTACT 0x00000001
/*$PAGE*/
/* -------- CONFIGURABLE FAULT STATUS REG BITS -------- */
#define CPU_REG_NVIC_CFSR_DIVBYZERO 0x02000000
#define CPU_REG_NVIC_CFSR_UNALIGNED 0x01000000
#define CPU_REG_NVIC_CFSR_NOCP 0x00080000
#define CPU_REG_NVIC_CFSR_INVPC 0x00040000
#define CPU_REG_NVIC_CFSR_INVSTATE 0x00020000
#define CPU_REG_NVIC_CFSR_UNDEFINSTR 0x00010000
#define CPU_REG_NVIC_CFSR_BFARVALID 0x00008000
#define CPU_REG_NVIC_CFSR_STKERR 0x00001000
#define CPU_REG_NVIC_CFSR_UNSTKERR 0x00000800
#define CPU_REG_NVIC_CFSR_IMPRECISERR 0x00000400
#define CPU_REG_NVIC_CFSR_PRECISERR 0x00000200
#define CPU_REG_NVIC_CFSR_IBUSERR 0x00000100
#define CPU_REG_NVIC_CFSR_MMARVALID 0x00000080
#define CPU_REG_NVIC_CFSR_MSTKERR 0x00000010
#define CPU_REG_NVIC_CFSR_MUNSTKERR 0x00000008
#define CPU_REG_NVIC_CFSR_DACCVIOL 0x00000002
#define CPU_REG_NVIC_CFSR_IACCVIOL 0x00000001
/* ------------ HARD FAULT STATUS REG BITS ------------ */
#define CPU_REG_NVIC_HFSR_DEBUGEVT 0x80000000
#define CPU_REG_NVIC_HFSR_FORCED 0x40000000
#define CPU_REG_NVIC_HFSR_VECTTBL 0x00000002
/* ------------ DEBUG FAULT STATUS REG BITS ----------- */
#define CPU_REG_NVIC_DFSR_EXTERNAL 0x00000010
#define CPU_REG_NVIC_DFSR_VCATCH 0x00000008
#define CPU_REG_NVIC_DFSR_DWTTRAP 0x00000004
#define CPU_REG_NVIC_DFSR_BKPT 0x00000002
#define CPU_REG_NVIC_DFSR_HALTED 0x00000001
/*
*********************************************************************************************************
* CPU REGISTER MASK
*********************************************************************************************************
*/
#define CPU_MSK_NVIC_ICSR_VECT_ACTIVE 0x000001FF
/*$PAGE*/
/*
*********************************************************************************************************
* CONFIGURATION ERRORS
*********************************************************************************************************
*/
#ifndef CPU_CFG_ADDR_SIZE
#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' "
#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]"
#error " [ || CPU_WORD_SIZE_16 16-bit alignment]"
#error " [ || CPU_WORD_SIZE_32 32-bit alignment]"
#error " [ || CPU_WORD_SIZE_64 64-bit alignment]"
#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \
(CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \
(CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32) && \
(CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_64))
#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' "
#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]"
#error " [ || CPU_WORD_SIZE_16 16-bit alignment]"
#error " [ || CPU_WORD_SIZE_32 32-bit alignment]"
#error " [ || CPU_WORD_SIZE_64 64-bit alignment]"
#endif
#ifndef CPU_CFG_DATA_SIZE
#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' "
#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]"
#error " [ || CPU_WORD_SIZE_16 16-bit alignment]"
#error " [ || CPU_WORD_SIZE_32 32-bit alignment]"
#error " [ || CPU_WORD_SIZE_64 64-bit alignment]"
#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \
(CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \
(CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32) && \
(CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_64))
#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' "
#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]"
#error " [ || CPU_WORD_SIZE_16 16-bit alignment]"
#error " [ || CPU_WORD_SIZE_32 32-bit alignment]"
#error " [ || CPU_WORD_SIZE_64 64-bit alignment]"
#endif
#ifndef CPU_CFG_DATA_SIZE_MAX
#error "CPU_CFG_DATA_SIZE_MAX not #define'd in 'cpu.h' "
#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]"
#error " [ || CPU_WORD_SIZE_16 16-bit alignment]"
#error " [ || CPU_WORD_SIZE_32 32-bit alignment]"
#error " [ || CPU_WORD_SIZE_64 64-bit alignment]"
#elif ((CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_08) && \
(CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_16) && \
(CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_32) && \
(CPU_CFG_DATA_SIZE_MAX != CPU_WORD_SIZE_64))
#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' "
#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]"
#error " [ || CPU_WORD_SIZE_16 16-bit alignment]"
#error " [ || CPU_WORD_SIZE_32 32-bit alignment]"
#error " [ || CPU_WORD_SIZE_64 64-bit alignment]"
#endif
#if (CPU_CFG_DATA_SIZE_MAX < CPU_CFG_DATA_SIZE)
#error "CPU_CFG_DATA_SIZE_MAX illegally #define'd in 'cpu.h' "
#error " [MUST be >= CPU_CFG_DATA_SIZE]"
#endif
/*$PAGE*/
#ifndef CPU_CFG_ENDIAN_TYPE
#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' "
#error " [MUST be CPU_ENDIAN_TYPE_BIG ]"
#error " [ || CPU_ENDIAN_TYPE_LITTLE]"
#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \
(CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE))
#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' "
#error " [MUST be CPU_ENDIAN_TYPE_BIG ]"
#error " [ || CPU_ENDIAN_TYPE_LITTLE]"
#endif
#ifndef CPU_CFG_STK_GROWTH
#error "CPU_CFG_STK_GROWTH not #define'd in 'cpu.h' "
#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]"
#error " [ || CPU_STK_GROWTH_HI_TO_LO]"
#elif ((CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_LO_TO_HI) && \
(CPU_CFG_STK_GROWTH != CPU_STK_GROWTH_HI_TO_LO))
#error "CPU_CFG_STK_GROWTH illegally #define'd in 'cpu.h' "
#error " [MUST be CPU_STK_GROWTH_LO_TO_HI]"
#error " [ || CPU_STK_GROWTH_HI_TO_LO]"
#endif
#ifndef CPU_CFG_CRITICAL_METHOD
#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' "
#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]"
#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]"
#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]"
#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \
(CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \
(CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL))
#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' "
#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]"
#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]"
#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]"
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* MODULE END
*
* Note(s) : (1) See 'cpu.h MODULE'.
*********************************************************************************************************
*/
#endif /* End of CPU module include. */

View File

@@ -0,0 +1,291 @@
;********************************************************************************************************
; uC/CPU
; CPU CONFIGURATION & PORT LAYER
;
; (c) Copyright 2004-2011; Micrium, Inc.; Weston, FL
;
; All rights reserved. Protected by international copyright laws.
;
; uC/CPU is provided in source form to registered licensees ONLY. It is
; illegal to distribute this source code to any third party unless you receive
; written permission by an authorized Micrium representative. Knowledge of
; the source code may NOT be used to develop a similar product.
;
; Please help us continue to provide the Embedded community with the finest
; software available. Your honesty is greatly appreciated.
;
; You can contact us at www.micrium.com.
;********************************************************************************************************
;********************************************************************************************************
;
; CPU PORT FILE
;
; ARM-Cortex-M3
; RealView Development Suite
; RealView Microcontroller Development Kit (MDK)
; ARM Developer Suite (ADS)
; Keil uVision
;
; Filename : cpu_a.asm
; Version : V1.29.01.00
; Programmer(s) : BAN
;********************************************************************************************************
;********************************************************************************************************
; PUBLIC FUNCTIONS
;********************************************************************************************************
EXPORT CPU_IntDis
EXPORT CPU_IntEn
EXPORT CPU_SR_Save
EXPORT CPU_SR_Restore
EXPORT CPU_WaitForInt
EXPORT CPU_WaitForExcept
EXPORT CPU_CntLeadZeros
EXPORT CPU_CntTrailZeros
EXPORT CPU_RevBits
;********************************************************************************************************
; CODE GENERATION DIRECTIVES
;********************************************************************************************************
AREA |.text|, CODE, READONLY, ALIGN=2
THUMB
REQUIRE8
PRESERVE8
;$PAGE
;********************************************************************************************************
; DISABLE and ENABLE INTERRUPTS
;
; Description : Disable/Enable interrupts.
;
; Prototypes : void CPU_IntDis(void);
; void CPU_IntEn (void);
;********************************************************************************************************
CPU_IntDis
CPSID I
BX LR
CPU_IntEn
CPSIE I
BX LR
;********************************************************************************************************
; CRITICAL SECTION FUNCTIONS
;
; Description : Disable/Enable interrupts by preserving the state of interrupts. Generally speaking, the
; state of the interrupt disable flag is stored in the local variable 'cpu_sr' & interrupts
; are then disabled ('cpu_sr' is allocated in all functions that need to disable interrupts).
; The previous interrupt state is restored by copying 'cpu_sr' into the CPU's status register.
;
; Prototypes : CPU_SR CPU_SR_Save (void);
; void CPU_SR_Restore(CPU_SR cpu_sr);
;
; Note(s) : (1) These functions are used in general like this :
;
; void Task (void *p_arg)
; {
; CPU_SR_ALLOC(); /* Allocate storage for CPU status register */
; :
; :
; CPU_CRITICAL_ENTER(); /* cpu_sr = CPU_SR_Save(); */
; :
; :
; CPU_CRITICAL_EXIT(); /* CPU_SR_Restore(cpu_sr); */
; :
; }
;********************************************************************************************************
CPU_SR_Save
MRS R0, PRIMASK ; Set prio int mask to mask all (except faults)
CPSID I
BX LR
CPU_SR_Restore ; See Note #2.
MSR PRIMASK, R0
BX LR
;$PAGE
;********************************************************************************************************
; WAIT FOR INTERRUPT
;
; Description : Enters sleep state, which will be exited when an interrupt is received.
;
; Prototypes : void CPU_WaitForInt (void)
;
; Argument(s) : none.
;********************************************************************************************************
CPU_WaitForInt
WFI ; Wait for interrupt
BX LR
;********************************************************************************************************
; WAIT FOR EXCEPTION
;
; Description : Enters sleep state, which will be exited when an exception is received.
;
; Prototypes : void CPU_WaitForExcept (void)
;
; Argument(s) : none.
;********************************************************************************************************
CPU_WaitForExcept
WFE ; Wait for exception
BX LR
;$PAGE
;********************************************************************************************************
; CPU_CntLeadZeros()
; COUNT LEADING ZEROS
;
; Description : Counts the number of contiguous, most-significant, leading zero bits before the
; first binary one bit in a data value.
;
; Prototype : CPU_DATA CPU_CntLeadZeros(CPU_DATA val);
;
; Argument(s) : val Data value to count leading zero bits.
;
; Return(s) : Number of contiguous, most-significant, leading zero bits in 'val'.
;
; Caller(s) : Application.
;
; This function is an INTERNAL CPU module function but MAY be called by application
; function(s).
;
; Note(s) : (1) (a) Supports 32-bit data value size as configured by 'CPU_DATA' (see 'cpu.h
; CPU WORD CONFIGURATION Note #1').
;
; (b) For 32-bit values :
;
; b31 b30 b29 ... b04 b03 b02 b01 b00 # Leading Zeros
; --- --- --- --- --- --- --- --- ---------------
; 1 x x x x x x x 0
; 0 1 x x x x x x 1
; 0 0 1 x x x x x 2
; : : : : : : : : :
; : : : : : : : : :
; 0 0 0 1 x x x x 27
; 0 0 0 0 1 x x x 28
; 0 0 0 0 0 1 x x 29
; 0 0 0 0 0 0 1 x 30
; 0 0 0 0 0 0 0 1 31
; 0 0 0 0 0 0 0 0 32
;
;
; (2) MUST be defined in 'cpu_a.asm' (or 'cpu_c.c') if CPU_CFG_LEAD_ZEROS_ASM_PRESENT is
; #define'd in 'cpu_cfg.h' or 'cpu.h'.
;********************************************************************************************************
CPU_CntLeadZeros
CLZ R0, R0 ; Count leading zeros
BX LR
;$PAGE
;********************************************************************************************************
; CPU_CntTrailZeros()
; COUNT TRAILING ZEROS
;
; Description : Counts the number of contiguous, least-significant, trailing zero bits before the
; first binary one bit in a data value.
;
; Prototype : CPU_DATA CPU_CntTrailZeros(CPU_DATA val);
;
; Argument(s) : val Data value to count trailing zero bits.
;
; Return(s) : Number of contiguous, least-significant, trailing zero bits in 'val'.
;
; Caller(s) : Application.
;
; This function is an INTERNAL CPU module function but MAY be called by application
; function(s).
;
; Note(s) : (1) (a) Supports 32-bit data value size as configured by 'CPU_DATA' (see 'cpu.h
; CPU WORD CONFIGURATION Note #1').
;
; (b) For 32-bit values :
;
; b31 b30 b29 b28 b27 ... b02 b01 b00 # Trailing Zeros
; --- --- --- --- --- --- --- --- ----------------
; x x x x x x x 1 0
; x x x x x x 1 0 1
; x x x x x 1 0 0 2
; : : : : : : : : :
; : : : : : : : : :
; x x x x 1 0 0 0 27
; x x x 1 0 0 0 0 28
; x x 1 0 0 0 0 0 29
; x 1 0 0 0 0 0 0 30
; 1 0 0 0 0 0 0 0 31
; 0 0 0 0 0 0 0 0 32
;
;
; (2) MUST be defined in 'cpu_a.asm' (or 'cpu_c.c') if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT is
; #define'd in 'cpu_cfg.h' or 'cpu.h'.
;********************************************************************************************************
CPU_CntTrailZeros
RBIT R0, R0 ; Reverse bits
CLZ R0, R0 ; Count trailing zeros
BX LR
;$PAGE
;********************************************************************************************************
; CPU_RevBits()
; REVERSE BITS
;
; Description : Reverses the bits in a data value.
;
; Prototypes : CPU_DATA CPU_RevBits(CPU_DATA val);
;
; Argument(s) : val Data value to reverse bits.
;
; Return(s) : Value with all bits in 'val' reversed (see Note #1).
;
; Caller(s) : Application.
;
; This function is an INTERNAL CPU module function but MAY be called by application function(s).
;
; Note(s) : (1) The final, reversed data value for 'val' is such that :
;
; 'val's final bit 0 = 'val's original bit N
; 'val's final bit 1 = 'val's original bit (N - 1)
; 'val's final bit 2 = 'val's original bit (N - 2)
;
; ... ...
;
; 'val's final bit (N - 2) = 'val's original bit 2
; 'val's final bit (N - 1) = 'val's original bit 1
; 'val's final bit N = 'val's original bit 0
;********************************************************************************************************
CPU_RevBits
RBIT R0, R0 ; Reverse bits
BX LR
;$PAGE
;********************************************************************************************************
; CPU ASSEMBLY PORT FILE END
;********************************************************************************************************
END

View File

@@ -0,0 +1,759 @@
/*
*********************************************************************************************************
* uC/CPU
* CPU CONFIGURATION & PORT LAYER
*
* (c) Copyright 2004-2011; Micrium, Inc.; Weston, FL
*
* All rights reserved. Protected by international copyright laws.
*
* uC/CPU is provided in source form to registered licensees ONLY. It is
* illegal to distribute this source code to any third party unless you receive
* written permission by an authorized Micrium representative. Knowledge of
* the source code may NOT be used to develop a similar product.
*
* Please help us continue to provide the Embedded community with the finest
* software available. Your honesty is greatly appreciated.
*
* You can contact us at www.micrium.com.
*********************************************************************************************************
*/
/*
*********************************************************************************************************
*
* CPU PORT FILE
*
* ARM-Cortex-M3
* RealView Development Suite
* RealView Microcontroller Development Kit (MDK)
* ARM Developer Suite (ADS)
* Keil uVision
*
* Filename : cpu_c.c
* Version : V1.29.01.00
* Programmer(s) : JJL
* BAN
* FT
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* INCLUDE FILES
*********************************************************************************************************
*/
#define MICRIUM_SOURCE
#include <cpu.h>
#include <cpu_core.h>
#include <lib_def.h>
/*$PAGE*/
/*
*********************************************************************************************************
* LOCAL DEFINES
*********************************************************************************************************
*/
#define CPU_INT_SRC_POS_MAX ((((CPU_REG_NVIC_NVIC + 1) & 0x1F) * 32) + 16)
#define CPU_BIT_BAND_SRAM_REG_LO 0x20000000
#define CPU_BIT_BAND_SRAM_REG_HI 0x200FFFFF
#define CPU_BIT_BAND_SRAM_BASE 0x22000000
#define CPU_BIT_BAND_PERIPH_REG_LO 0x40000000
#define CPU_BIT_BAND_PERIPH_REG_HI 0x400FFFFF
#define CPU_BIT_BAND_PERIPH_BASE 0x42000000
/*
*********************************************************************************************************
* LOCAL CONSTANTS
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* LOCAL DATA TYPES
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* LOCAL TABLES
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* LOCAL GLOBAL VARIABLES
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* LOCAL FUNCTION PROTOTYPES
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* LOCAL CONFIGURATION ERRORS
*********************************************************************************************************
*/
/*$PAGE*/
/*
*********************************************************************************************************
* CPU_BitBandClr()
*
* Description : Clear bit in bit-band region.
*
* Argument(s) : addr Byte address in memory space.
*
* bit_nbr Bit number in byte.
*
* Return(s) : none.
*
* Caller(s) : Application.
*
* Note(s) : none.
*********************************************************************************************************
*/
void CPU_BitBandClr (CPU_ADDR addr,
CPU_INT08U bit_nbr)
{
CPU_ADDR bit_word_off;
CPU_ADDR bit_word_addr;
if ((addr >= CPU_BIT_BAND_SRAM_REG_LO) &&
(addr <= CPU_BIT_BAND_SRAM_REG_HI)) {
bit_word_off = ((addr - CPU_BIT_BAND_SRAM_REG_LO ) * 32) + (bit_nbr * 4);
bit_word_addr = CPU_BIT_BAND_SRAM_BASE + bit_word_off;
*(volatile CPU_INT32U *)(bit_word_addr) = 0;
} else if ((addr >= CPU_BIT_BAND_PERIPH_REG_LO) &&
(addr <= CPU_BIT_BAND_PERIPH_REG_HI)) {
bit_word_off = ((addr - CPU_BIT_BAND_PERIPH_REG_LO) * 32) + (bit_nbr * 4);
bit_word_addr = CPU_BIT_BAND_PERIPH_BASE + bit_word_off;
*(volatile CPU_INT32U *)(bit_word_addr) = 0;
}
}
/*$PAGE*/
/*
*********************************************************************************************************
* CPU_BitBandSet()
*
* Description : Set bit in bit-band region.
*
* Argument(s) : addr Byte address in memory space.
*
* bit_nbr Bit number in byte.
*
* Return(s) : none.
*
* Caller(s) : Application.
*
* Note(s) : none.
*********************************************************************************************************
*/
void CPU_BitBandSet (CPU_ADDR addr,
CPU_INT08U bit_nbr)
{
CPU_ADDR bit_word_off;
CPU_ADDR bit_word_addr;
if ((addr >= CPU_BIT_BAND_SRAM_REG_LO) &&
(addr <= CPU_BIT_BAND_SRAM_REG_HI)) {
bit_word_off = ((addr - CPU_BIT_BAND_SRAM_REG_LO ) * 32) + (bit_nbr * 4);
bit_word_addr = CPU_BIT_BAND_SRAM_BASE + bit_word_off;
*(volatile CPU_INT32U *)(bit_word_addr) = 1;
} else if ((addr >= CPU_BIT_BAND_PERIPH_REG_LO) &&
(addr <= CPU_BIT_BAND_PERIPH_REG_HI)) {
bit_word_off = ((addr - CPU_BIT_BAND_PERIPH_REG_LO) * 32) + (bit_nbr * 4);
bit_word_addr = CPU_BIT_BAND_PERIPH_BASE + bit_word_off;
*(volatile CPU_INT32U *)(bit_word_addr) = 1;
}
}
/*$PAGE*/
/*
*********************************************************************************************************
* CPU_IntSrcDis()
*
* Description : Disable an interrupt source.
*
* Argument(s) : pos Position of interrupt vector in interrupt table :
*
* 0 Invalid (see Note #1a).
* 1 Invalid (see Note #1b).
* 2 Non-maskable interrupt.
* 3 Hard Fault.
* 4 Memory Management.
* 5 Bus Fault.
* 6 Usage Fault.
* 7-10 Reserved.
* 11 SVCall
* 12 Debug monitor.
* 13 Reserved
* 14 PendSV.
* 15 SysTick.
* 16+ External Interrupt.
*
* Return(s) : none.
*
* Caller(s) : Application.
*
* Note(s) : (1) Several table positions do not contain interrupt sources :
*
* (a) Position 0 contains the stack pointer.
* (b) Positions 7-10, 13 are reserved.
*
* (2) Several interrupts cannot be disabled/enabled :
*
* (a) Reset.
* (b) NMI.
* (c) Hard fault.
* (d) SVCall.
* (e) Debug monitor.
* (f) PendSV.
*
* (3) The maximum Cortex-M3 table position is 256. A particular Cortex-M3 may have fewer
* than 240 external exceptions and, consequently, fewer than 256 table positions.
* This function assumes that the specified table position is valid if the interrupt
* controller type register's INTLINESNUM field is large enough so that the position
* COULD be valid.
*********************************************************************************************************
*/
/*$PAGE*/
void CPU_IntSrcDis (CPU_INT08U pos)
{
CPU_INT08U group;
CPU_INT08U pos_max;
CPU_INT08U nbr;
CPU_SR_ALLOC();
switch (pos) {
case CPU_INT_STK_PTR: /* ---------------- INVALID OR RESERVED --------------- */
case CPU_INT_RSVD_07:
case CPU_INT_RSVD_08:
case CPU_INT_RSVD_09:
case CPU_INT_RSVD_10:
case CPU_INT_RSVD_13:
break;
/* ----------------- SYSTEM EXCEPTIONS ---------------- */
case CPU_INT_RESET: /* Reset (see Note #2). */
case CPU_INT_NMI: /* Non-maskable interrupt (see Note #2). */
case CPU_INT_HFAULT: /* Hard fault (see Note #2). */
case CPU_INT_SVCALL: /* SVCall (see Note #2). */
case CPU_INT_DBGMON: /* Debug monitor (see Note #2). */
case CPU_INT_PENDSV: /* PendSV (see Note #2). */
break;
case CPU_INT_MEM: /* Memory management. */
CPU_CRITICAL_ENTER();
CPU_REG_NVIC_SHCSR &= ~CPU_REG_NVIC_SHCSR_MEMFAULTENA;
CPU_CRITICAL_EXIT();
break;
case CPU_INT_BUSFAULT: /* Bus fault. */
CPU_CRITICAL_ENTER();
CPU_REG_NVIC_SHCSR &= ~CPU_REG_NVIC_SHCSR_BUSFAULTENA;
CPU_CRITICAL_EXIT();
break;
case CPU_INT_USAGEFAULT: /* Usage fault. */
CPU_CRITICAL_ENTER();
CPU_REG_NVIC_SHCSR &= ~CPU_REG_NVIC_SHCSR_USGFAULTENA;
CPU_CRITICAL_EXIT();
break;
case CPU_INT_SYSTICK: /* SysTick. */
CPU_CRITICAL_ENTER();
CPU_REG_NVIC_ST_CTRL &= ~CPU_REG_NVIC_ST_CTRL_ENABLE;
CPU_CRITICAL_EXIT();
break;
/* ---------------- EXTERNAL INTERRUPT ---------------- */
default:
pos_max = CPU_INT_SRC_POS_MAX;
if (pos < pos_max) { /* See Note #3. */
group = (pos - 16) / 32;
nbr = (pos - 16) % 32;
CPU_CRITICAL_ENTER();
CPU_REG_NVIC_CLREN(group) = DEF_BIT(nbr);
CPU_CRITICAL_EXIT();
}
break;
}
}
/*$PAGE*/
/*
*********************************************************************************************************
* CPU_IntSrcEn()
*
* Description : Enable an interrupt source.
*
* Argument(s) : pos Position of interrupt vector in interrupt table (see 'CPU_IntSrcDis()').
*
* Return(s) : none.
*
* Caller(s) : Application.
*
* Note(s) : (1) See 'CPU_IntSrcDis() Note #1'.
*
* (2) See 'CPU_IntSrcDis() Note #2'.
*
* (3) See 'CPU_IntSrcDis() Note #3'.
*********************************************************************************************************
*/
void CPU_IntSrcEn (CPU_INT08U pos)
{
CPU_INT08U group;
CPU_INT08U nbr;
CPU_INT08U pos_max;
CPU_SR_ALLOC();
switch (pos) {
case CPU_INT_STK_PTR: /* ---------------- INVALID OR RESERVED --------------- */
case CPU_INT_RSVD_07:
case CPU_INT_RSVD_08:
case CPU_INT_RSVD_09:
case CPU_INT_RSVD_10:
case CPU_INT_RSVD_13:
break;
/* ----------------- SYSTEM EXCEPTIONS ---------------- */
case CPU_INT_RESET: /* Reset (see Note #2). */
case CPU_INT_NMI: /* Non-maskable interrupt (see Note #2). */
case CPU_INT_HFAULT: /* Hard fault (see Note #2). */
case CPU_INT_SVCALL: /* SVCall (see Note #2). */
case CPU_INT_DBGMON: /* Debug monitor (see Note #2). */
case CPU_INT_PENDSV: /* PendSV (see Note #2). */
break;
case CPU_INT_MEM: /* Memory management. */
CPU_CRITICAL_ENTER();
CPU_REG_NVIC_SHCSR |= CPU_REG_NVIC_SHCSR_MEMFAULTENA;
CPU_CRITICAL_EXIT();
break;
case CPU_INT_BUSFAULT: /* Bus fault. */
CPU_CRITICAL_ENTER();
CPU_REG_NVIC_SHCSR |= CPU_REG_NVIC_SHCSR_BUSFAULTENA;
CPU_CRITICAL_EXIT();
break;
case CPU_INT_USAGEFAULT: /* Usage fault. */
CPU_CRITICAL_ENTER();
CPU_REG_NVIC_SHCSR |= CPU_REG_NVIC_SHCSR_USGFAULTENA;
CPU_CRITICAL_EXIT();
break;
case CPU_INT_SYSTICK: /* SysTick. */
CPU_CRITICAL_ENTER();
CPU_REG_NVIC_ST_CTRL |= CPU_REG_NVIC_ST_CTRL_ENABLE;
CPU_CRITICAL_EXIT();
break;
/* ---------------- EXTERNAL INTERRUPT ---------------- */
default:
pos_max = CPU_INT_SRC_POS_MAX;
if (pos < pos_max) { /* See Note #3. */
group = (pos - 16) / 32;
nbr = (pos - 16) % 32;
CPU_CRITICAL_ENTER();
CPU_REG_NVIC_SETEN(group) = DEF_BIT(nbr);
CPU_CRITICAL_EXIT();
}
break;
}
}
/*$PAGE*/
/*
*********************************************************************************************************
* CPU_IntSrcPendClr()
*
* Description : Clear a pending interrupt.
*
* Argument(s) : pos Position of interrupt vector in interrupt table (see 'CPU_IntSrcDis()').
*
* Return(s) : none.
*
* Caller(s) : Application.
*
* Note(s) : (1) See 'CPU_IntSrcDis() Note #1'.
*
* (2) The pending status of several interrupts cannot be clear/set :
*
* (a) Reset.
* (b) NMI.
* (c) Hard fault.
* (d) Memory Managment.
* (e) Bus Fault.
* (f) Usage Fault.
* (g) SVCall.
* (h) Debug monitor.
* (i) PendSV.
* (j) Systick
*
* (3) See 'CPU_IntSrcDis() Note #3'.
*********************************************************************************************************
*/
void CPU_IntSrcPendClr (CPU_INT08U pos)
{
CPU_INT08U group;
CPU_INT08U nbr;
CPU_INT08U pos_max;
CPU_SR_ALLOC();
switch (pos) {
case CPU_INT_STK_PTR: /* ---------------- INVALID OR RESERVED --------------- */
case CPU_INT_RSVD_07:
case CPU_INT_RSVD_08:
case CPU_INT_RSVD_09:
case CPU_INT_RSVD_10:
case CPU_INT_RSVD_13:
break;
/* ----------------- SYSTEM EXCEPTIONS ---------------- */
case CPU_INT_RESET: /* Reset (see Note #2). */
case CPU_INT_NMI: /* Non-maskable interrupt (see Note #2). */
case CPU_INT_HFAULT: /* Hard fault (see Note #2). */
case CPU_INT_MEM: /* Memory management (see Note #2). */
case CPU_INT_SVCALL: /* SVCall (see Note #2). */
case CPU_INT_DBGMON: /* Debug monitor (see Note #2). */
case CPU_INT_PENDSV: /* PendSV (see Note #2). */
case CPU_INT_BUSFAULT: /* Bus fault. */
case CPU_INT_USAGEFAULT: /* Usage fault. */
case CPU_INT_SYSTICK: /* SysTick. */
break;
/* ---------------- EXTERNAL INTERRUPT ---------------- */
default:
pos_max = CPU_INT_SRC_POS_MAX;
if (pos < pos_max) { /* See Note #3. */
group = (pos - 16) / 32;
nbr = (pos - 16) % 32;
CPU_CRITICAL_ENTER();
CPU_REG_NVIC_CLRPEND(group) = DEF_BIT(nbr);
CPU_CRITICAL_EXIT();
}
break;
}
}
/*$PAGE*/
/*
*********************************************************************************************************
* CPU_IntSrcPrioSet()
*
* Description : Set priority of an interrupt source.
*
* Argument(s) : pos Position of interrupt vector in interrupt table (see 'CPU_IntSrcDis()').
*
* prio Priority. Use a lower priority number for a higher priority.
*
* Return(s) : none.
*
* Caller(s) : Application.
*
* Note(s) : (1) See 'CPU_IntSrcDis() Note #1'.
*
* (2) Several interrupts priorities CANNOT be set :
*
* (a) Reset (always -3).
* (b) NMI (always -2).
* (c) Hard fault (always -1).
*
* (3) See 'CPU_IntSrcDis() Note #3'.
*********************************************************************************************************
*/
void CPU_IntSrcPrioSet (CPU_INT08U pos,
CPU_INT08U prio)
{
CPU_INT08U group;
CPU_INT08U nbr;
CPU_INT08U pos_max;
CPU_INT32U prio_32;
CPU_INT32U temp;
CPU_SR_ALLOC();
prio_32 = CPU_RevBits((CPU_INT08U)prio);
prio = (CPU_INT08U)(prio_32 >> (3 * DEF_OCTET_NBR_BITS));
switch (pos) {
case CPU_INT_STK_PTR: /* ---------------- INVALID OR RESERVED --------------- */
case CPU_INT_RSVD_07:
case CPU_INT_RSVD_08:
case CPU_INT_RSVD_09:
case CPU_INT_RSVD_10:
case CPU_INT_RSVD_13:
break;
/* ----------------- SYSTEM EXCEPTIONS ---------------- */
case CPU_INT_RESET: /* Reset (see Note #2). */
case CPU_INT_NMI: /* Non-maskable interrupt (see Note #2). */
case CPU_INT_HFAULT: /* Hard fault (see Note #2). */
break;
case CPU_INT_MEM: /* Memory management. */
CPU_CRITICAL_ENTER();
temp = CPU_REG_NVIC_SHPRI1;
temp &= ~(DEF_OCTET_MASK << (0 * DEF_OCTET_NBR_BITS));
temp |= (prio << (0 * DEF_OCTET_NBR_BITS));
CPU_REG_NVIC_SHPRI1 = temp;
CPU_CRITICAL_EXIT();
break;
case CPU_INT_BUSFAULT: /* Bus fault. */
CPU_CRITICAL_ENTER();
temp = CPU_REG_NVIC_SHPRI1;
temp &= ~(DEF_OCTET_MASK << (1 * DEF_OCTET_NBR_BITS));
temp |= (prio << (1 * DEF_OCTET_NBR_BITS));
CPU_REG_NVIC_SHPRI1 = temp;
CPU_CRITICAL_EXIT();
break;
case CPU_INT_USAGEFAULT: /* Usage fault. */
CPU_CRITICAL_ENTER();
temp = CPU_REG_NVIC_SHPRI1;
temp &= ~(DEF_OCTET_MASK << (2 * DEF_OCTET_NBR_BITS));
temp |= (prio << (2 * DEF_OCTET_NBR_BITS));
CPU_REG_NVIC_SHPRI1 = temp;
CPU_CRITICAL_EXIT();
break;
case CPU_INT_SVCALL: /* SVCall. */
CPU_CRITICAL_ENTER();
temp = CPU_REG_NVIC_SHPRI2;
temp &= ~((CPU_INT32U)DEF_OCTET_MASK << (3 * DEF_OCTET_NBR_BITS));
temp |= (prio << (3 * DEF_OCTET_NBR_BITS));
CPU_REG_NVIC_SHPRI2 = temp;
CPU_CRITICAL_EXIT();
break;
case CPU_INT_DBGMON: /* Debug monitor. */
CPU_CRITICAL_ENTER();
temp = CPU_REG_NVIC_SHPRI3;
temp &= ~(DEF_OCTET_MASK << (0 * DEF_OCTET_NBR_BITS));
temp |= (prio << (0 * DEF_OCTET_NBR_BITS));
CPU_REG_NVIC_SHPRI3 = temp;
CPU_CRITICAL_EXIT();
break;
case CPU_INT_PENDSV: /* PendSV. */
CPU_CRITICAL_ENTER();
temp = CPU_REG_NVIC_SHPRI3;
temp &= ~(DEF_OCTET_MASK << (2 * DEF_OCTET_NBR_BITS));
temp |= (prio << (2 * DEF_OCTET_NBR_BITS));
CPU_REG_NVIC_SHPRI3 = temp;
CPU_CRITICAL_EXIT();
break;
case CPU_INT_SYSTICK: /* SysTick. */
CPU_CRITICAL_ENTER();
temp = CPU_REG_NVIC_SHPRI3;
temp &= ~((CPU_INT32U)DEF_OCTET_MASK << (3 * DEF_OCTET_NBR_BITS));
temp |= (prio << (3 * DEF_OCTET_NBR_BITS));
CPU_REG_NVIC_SHPRI3 = temp;
CPU_CRITICAL_EXIT();
break;
/* ---------------- EXTERNAL INTERRUPT ---------------- */
default:
pos_max = CPU_INT_SRC_POS_MAX;
if (pos < pos_max) { /* See Note #3. */
group = (pos - 16) / 4;
nbr = (pos - 16) % 4;
CPU_CRITICAL_ENTER();
temp = CPU_REG_NVIC_PRIO(group);
temp &= ~(DEF_OCTET_MASK << (nbr * DEF_OCTET_NBR_BITS));
temp |= (prio << (nbr * DEF_OCTET_NBR_BITS));
CPU_REG_NVIC_PRIO(group) = temp;
CPU_CRITICAL_EXIT();
}
break;
}
}
/*$PAGE*/
/*
*********************************************************************************************************
* CPU_IntSrcPrioGet()
*
* Description : Get priority of an interrupt source.
*
* Argument(s) : pos Position of interrupt vector in interrupt table (see 'CPU_IntSrcDis()').
*
* Return(s) : Priority of interrupt source. If the interrupt source specified is invalid, then
* DEF_INT_16S_MIN_VAL is returned.
*
* Caller(s) : Application.
*
* Note(s) : (1) See 'CPU_IntSrcDis() Note #1'.
*
* (2) See 'CPU_IntSrcPrioSet() Note #2'.
*
* (3) See 'CPU_IntSrcDis() Note #3'.
*********************************************************************************************************
*/
CPU_INT16S CPU_IntSrcPrioGet (CPU_INT08U pos)
{
CPU_INT08U group;
CPU_INT08U nbr;
CPU_INT08U pos_max;
CPU_INT16S prio;
CPU_INT32U prio_32;
CPU_INT32U temp;
CPU_SR_ALLOC();
switch (pos) {
case CPU_INT_STK_PTR: /* ---------------- INVALID OR RESERVED --------------- */
case CPU_INT_RSVD_07:
case CPU_INT_RSVD_08:
case CPU_INT_RSVD_09:
case CPU_INT_RSVD_10:
case CPU_INT_RSVD_13:
prio = DEF_INT_16S_MIN_VAL;
break;
/* ----------------- SYSTEM EXCEPTIONS ---------------- */
case CPU_INT_RESET: /* Reset (see Note #2). */
prio = -3;
break;
case CPU_INT_NMI: /* Non-maskable interrupt (see Note #2). */
prio = -2;
break;
case CPU_INT_HFAULT: /* Hard fault (see Note #2). */
prio = -1;
break;
case CPU_INT_MEM: /* Memory management. */
CPU_CRITICAL_ENTER();
temp = CPU_REG_NVIC_SHPRI1;
prio = (temp >> (0 * DEF_OCTET_NBR_BITS)) & DEF_OCTET_MASK;
CPU_CRITICAL_EXIT();
break;
case CPU_INT_BUSFAULT: /* Bus fault. */
CPU_CRITICAL_ENTER();
temp = CPU_REG_NVIC_SHPRI1;
prio = (temp >> (1 * DEF_OCTET_NBR_BITS)) & DEF_OCTET_MASK;
CPU_CRITICAL_EXIT();
break;
case CPU_INT_USAGEFAULT: /* Usage fault. */
CPU_CRITICAL_ENTER();
temp = CPU_REG_NVIC_SHPRI1;
prio = (temp >> (2 * DEF_OCTET_NBR_BITS)) & DEF_OCTET_MASK;
break;
case CPU_INT_SVCALL: /* SVCall. */
CPU_CRITICAL_ENTER();
temp = CPU_REG_NVIC_SHPRI2;
prio = (temp >> (3 * DEF_OCTET_NBR_BITS)) & DEF_OCTET_MASK;
CPU_CRITICAL_EXIT();
break;
case CPU_INT_DBGMON: /* Debug monitor. */
CPU_CRITICAL_ENTER();
temp = CPU_REG_NVIC_SHPRI3;
prio = (temp >> (0 * DEF_OCTET_NBR_BITS)) & DEF_OCTET_MASK;
CPU_CRITICAL_EXIT();
break;
case CPU_INT_PENDSV: /* PendSV. */
CPU_CRITICAL_ENTER();
temp = CPU_REG_NVIC_SHPRI3;
prio = (temp >> (2 * DEF_OCTET_NBR_BITS)) & DEF_OCTET_MASK;
CPU_CRITICAL_EXIT();
break;
case CPU_INT_SYSTICK: /* SysTick. */
CPU_CRITICAL_ENTER();
temp = CPU_REG_NVIC_SHPRI3;
prio = (temp >> (3 * DEF_OCTET_NBR_BITS)) & DEF_OCTET_MASK;
CPU_CRITICAL_EXIT();
break;
/* ---------------- EXTERNAL INTERRUPT ---------------- */
default:
pos_max = CPU_INT_SRC_POS_MAX;
if (pos < pos_max) { /* See Note #3. */
group = (pos - 16) / 4;
nbr = (pos - 16) % 4;
CPU_CRITICAL_ENTER();
temp = CPU_REG_NVIC_PRIO(group);
CPU_CRITICAL_EXIT();
prio = (temp >> (nbr * DEF_OCTET_NBR_BITS)) & DEF_OCTET_MASK;
} else {
prio = DEF_INT_16S_MIN_VAL;
}
break;
}
if (prio >= 0) {
prio_32 = CPU_RevBits((CPU_INT32U)prio);
prio = (CPU_INT16S)(prio_32 >> (3 * DEF_OCTET_NBR_BITS));
}
return (prio);
}

2361
UCOSIII/uC-CPU/cpu_core.c Normal file

File diff suppressed because it is too large Load Diff

1018
UCOSIII/uC-CPU/cpu_core.h Normal file

File diff suppressed because it is too large Load Diff

221
UCOSIII/uC-CPU/cpu_def.h Normal file
View File

@@ -0,0 +1,221 @@
/*
*********************************************************************************************************
* uC/CPU
* CPU CONFIGURATION & PORT LAYER
*
* (c) Copyright 2004-2011; Micrium, Inc.; Weston, FL
*
* All rights reserved. Protected by international copyright laws.
*
* uC/CPU is provided in source form to registered licensees ONLY. It is
* illegal to distribute this source code to any third party unless you receive
* written permission by an authorized Micrium representative. Knowledge of
* the source code may NOT be used to develop a similar product.
*
* Please help us continue to provide the Embedded community with the finest
* software available. Your honesty is greatly appreciated.
*
* You can contact us at www.micrium.com.
*********************************************************************************************************
*/
/*
*********************************************************************************************************
*
* CPU CONFIGURATION DEFINES
*
* Filename : cpu_def.h
* Version : V1.29.01
* Programmer(s) : ITJ
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* MODULE
*
* Note(s) : (1) This CPU definition header file is protected from multiple pre-processor inclusion
* through use of the CPU definition module present pre-processor macro definition.
*********************************************************************************************************
*/
#ifndef CPU_DEF_MODULE_PRESENT
#define CPU_DEF_MODULE_PRESENT
/*
*********************************************************************************************************
* CORE CPU MODULE VERSION NUMBER
*
* Note(s) : (1) (a) The core CPU module software version is denoted as follows :
*
* Vx.yy.zz
*
* where
* V denotes 'Version' label
* x denotes major software version revision number
* yy denotes minor software version revision number
* zz denotes sub-minor software version revision number
*
* (b) The software version label #define is formatted as follows :
*
* ver = x.yyzz * 100 * 100
*
* where
* ver denotes software version number scaled as an integer value
* x.yyzz denotes software version number, where the unscaled integer
* portion denotes the major version number & the unscaled
* fractional portion denotes the (concatenated) minor
* version numbers
*********************************************************************************************************
*/
#define CPU_CORE_VERSION 12901u /* See Note #1. */
/*$PAGE*/
/*
*********************************************************************************************************
* CPU WORD CONFIGURATION
*
* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE & CPU_CFG_DATA_SIZE in 'cpu.h' with CPU's word sizes :
*
* CPU_WORD_SIZE_08 8-bit word size
* CPU_WORD_SIZE_16 16-bit word size
* CPU_WORD_SIZE_32 32-bit word size
* CPU_WORD_SIZE_64 64-bit word size
*
* (2) Configure CPU_CFG_ENDIAN_TYPE in 'cpu.h' with CPU's data-word-memory order :
*
* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant
* octet @ lowest memory address)
* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant
* octet @ lowest memory address)
*********************************************************************************************************
*/
/* ---------------------- CPU WORD SIZE ----------------------- */
#define CPU_WORD_SIZE_08 1 /* 8-bit word size (in octets). */
#define CPU_WORD_SIZE_16 2 /* 16-bit word size (in octets). */
#define CPU_WORD_SIZE_32 4 /* 32-bit word size (in octets). */
#define CPU_WORD_SIZE_64 8 /* 64-bit word size (in octets). */
/* ------------------ CPU WORD-ENDIAN ORDER ------------------- */
#define CPU_ENDIAN_TYPE_NONE 0u
#define CPU_ENDIAN_TYPE_BIG 1u /* Big- endian word order (see Note #1a). */
#define CPU_ENDIAN_TYPE_LITTLE 2u /* Little-endian word order (see Note #1b). */
/*
*********************************************************************************************************
* CPU STACK CONFIGURATION
*
* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order :
*
* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack
* memory address after data is pushed onto the stack
* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack
* memory address after data is pushed onto the stack
*********************************************************************************************************
*/
/* ------------------ CPU STACK GROWTH ORDER ------------------ */
#define CPU_STK_GROWTH_NONE 0u
#define CPU_STK_GROWTH_LO_TO_HI 1u /* CPU stk incs towards higher mem addrs (see Note #1a). */
#define CPU_STK_GROWTH_HI_TO_LO 2u /* CPU stk decs towards lower mem addrs (see Note #1b). */
/*$PAGE*/
/*
*********************************************************************************************************
* CRITICAL SECTION CONFIGURATION
*
* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method :
*
* Enter/Exit critical sections by ...
*
* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts
* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack
* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable
*
* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support
* multiple levels of interrupts. However, with some CPUs/compilers, this is the only
* available method.
*
* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple
* levels of interrupts. However, this method assumes that the compiler provides C-level
* &/or assembly-level functionality for the following :
*
* ENTER CRITICAL SECTION :
* (1) Push/save interrupt status onto a local stack
* (2) Disable interrupts
*
* EXIT CRITICAL SECTION :
* (3) Pop/restore interrupt status from a local stack
*
* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple
* levels of interrupts. However, this method assumes that the compiler provides C-level
* &/or assembly-level functionality for the following :
*
* ENTER CRITICAL SECTION :
* (1) Save interrupt status into a local variable
* (2) Disable interrupts
*
* EXIT CRITICAL SECTION :
* (3) Restore interrupt status from a local variable
*
* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT
* allow inline assembly in C source files, critical section macro's MUST call an assembly
* subroutine defined in a 'cpu_a.asm' file located in the following software directory :
*
* \<CPU-Compiler Directory>\<cpu>\<compiler>\
*
* where
* <CPU-Compiler Directory> directory path for common CPU-compiler software
* <cpu> directory name for specific CPU
* <compiler> directory name for specific compiler
*
* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need
* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured).
*
* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which,
* if used, MUST be declared following ALL other local variables (see any 'cpu.h
* CRITICAL SECTION CONFIGURATION Note #3a1').
*
* Example :
*
* void Fnct (void)
* {
* CPU_INT08U val_08;
* CPU_INT16U val_16;
* CPU_INT32U val_32;
* CPU_SR_ALLOC(); MUST be declared after ALL other local variables
* :
* :
* }
*
* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to
* completely store the CPU's/compiler's status word.
*********************************************************************************************************
*/
/* --------------- CPU CRITICAL SECTION METHODS --------------- */
#define CPU_CRITICAL_METHOD_NONE 0u /* */
#define CPU_CRITICAL_METHOD_INT_DIS_EN 1u /* DIS/EN ints (see Note #1a). */
#define CPU_CRITICAL_METHOD_STATUS_STK 2u /* Push/Pop int status onto stk (see Note #1b). */
#define CPU_CRITICAL_METHOD_STATUS_LOCAL 3u /* Save/Restore int status to local var (see Note #1c). */
/*$PAGE*/
/*
*********************************************************************************************************
* MODULE END
*
* Note(s) : (1) See 'cpu_def.h MODULE'.
*********************************************************************************************************
*/
#endif /* End of CPU def module include. */

View File

@@ -0,0 +1,309 @@
@********************************************************************************************************
@ uC/LIB
@ CUSTOM LIBRARY MODULES
@
@ (c) Copyright 2004-2011; Micrium, Inc.; Weston, FL
@
@ All rights reserved. Protected by international copyright laws.
@
@ uC/LIB is provided in source form to registered licensees ONLY. It is
@ illegal to distribute this source code to any third party unless you receive
@ written permission by an authorized Micrium representative. Knowledge of
@ the source code may NOT be used to develop a similar product.
@
@ Please help us continue to provide the Embedded community with the finest
@ software available. Your honesty is greatly appreciated.
@
@ You can contact us at www.micrium.com.
@********************************************************************************************************
@********************************************************************************************************
@
@ STANDARD MEMORY OPERATIONS
@
@ ARM-Cortex-M3
@ GNU Compiler
@
@ Filename : lib_mem_a.s
@ Version : V1.36.01.00
@ Programmer(s) : JDH
@ DC
@********************************************************************************************************
@ Note(s) : (1) NO compiler-supplied standard library functions are used in library or product software.
@
@ (a) ALL standard library functions are implemented in the custom library modules :
@
@ (1) \<Custom Library Directory>\lib*.*
@
@ (2) \<Custom Library Directory>\Ports\<cpu>\<compiler>\lib*_a.*
@
@ where
@ <Custom Library Directory> directory path for custom library software
@ <cpu> directory name for specific processor (CPU)
@ <compiler> directory name for specific compiler
@
@ (b) Product-specific library functions are implemented in individual products.
@
@ (2) Assumes ARM CPU mode configured for Little Endian.
@********************************************************************************************************
@********************************************************************************************************
@ PUBLIC FUNCTIONS
@********************************************************************************************************
.global Mem_Copy
@********************************************************************************************************
@ CODE GENERATION DIRECTIVES
@********************************************************************************************************
.text
.align 2
.thumb
.syntax unified
@$PAGE
@********************************************************************************************************
@ Mem_Copy()
@
@ Description : Copy data octets from one buffer to another buffer.
@
@ Argument(s) : pdest Pointer to destination memory buffer.
@
@ psrc Pointer to source memory buffer.
@
@ size Number of data buffer octets to copy.
@
@ Return(s) : none.
@
@ Caller(s) : Application.
@
@ Note(s) : (1) Null copies allowed (i.e. 0-octet size).
@
@ (2) Memory buffers NOT checked for overlapping.
@
@ (3) Modulo arithmetic is used to determine whether a memory buffer starts on a 'CPU_ALIGN'
@ address boundary.
@
@ (4) ARM Cortex-M3 processors use a subset of the ARM Thumb-2 instruction set which does
@ NOT support 16-bit conditional branch instructions but ONLY supports 8-bit conditional
@ branch instructions.
@
@ Therefore, branches exceeding 8-bit, signed, relative offsets :
@
@ (a) CANNOT be implemented with conditional branches@ but ...
@ (b) MUST be implemented with non-conditional branches.
@********************************************************************************************************
@ void Mem_Copy (void *pdest, @ ==> R0
@ void *psrc, @ ==> R1
@ CPU_SIZE_T size) @ ==> R2
.thumb_func
Mem_Copy:
CMP R0, #0
BNE Mem_Copy_1
BX LR @ return if pdest == NULL
Mem_Copy_1:
CMP R1, #0
BNE Mem_Copy_2
BX LR @ return if psrc == NULL
Mem_Copy_2:
CMP R2, #0
BNE Mem_Copy_3
BX LR @ return if size == 0
Mem_Copy_3:
STMFD SP!, {R3-R12} @ save registers on stack
@$PAGE
Chk_Align_32: @ check if both dest & src 32-bit aligned
AND R3, R0, #0x03
AND R4, R1, #0x03
CMP R3, R4
BNE Chk_Align_16 @ not 32-bit aligned, check for 16-bit alignment
RSB R3, R3, #0x04 @ compute 1-2-3 pre-copy bytes (to align to the next 32-bit boundary)
AND R3, R3, #0x03
Pre_Copy_1:
CMP R3, #1 @ copy 1-2-3 bytes (to align to the next 32-bit boundary)
BCC Copy_32_1 @ start real 32-bit copy
CMP R2, #1 @ check if any more data to copy
BCS Pre_Copy_1_Cont
B Mem_Copy_END @ no more data to copy (see Note #4b)
Pre_Copy_1_Cont:
LDRB R4, [R1], #1
STRB R4, [R0], #1
SUB R3, R3, #1
SUB R2, R2, #1
B Pre_Copy_1
Chk_Align_16: @ check if both dest & src 16-bit aligned
AND R3, R0, #0x01
AND R4, R1, #0x01
CMP R3, R4
BEQ Pre_Copy_2
B Copy_08_1 @ not 16-bit aligned, start 8-bit copy (see Note #4b)
Pre_Copy_2:
CMP R3, #1 @ copy 1 byte (to align to the next 16-bit boundary)
BCC Copy_16_1 @ start real 16-bit copy
LDRB R4, [R1], #1
STRB R4, [R0], #1
SUB R3, R3, #1
SUB R2, R2, #1
B Pre_Copy_2
Copy_32_1:
CMP R2, #360 @ Copy 9 chunks of 10 32-bit words (360 octets per loop)
BCC Copy_32_2
LDMIA R1!, {R3-R12}
STMIA R0!, {R3-R12}
LDMIA R1!, {R3-R12}
STMIA R0!, {R3-R12}
LDMIA R1!, {R3-R12}
STMIA R0!, {R3-R12}
LDMIA R1!, {R3-R12}
STMIA R0!, {R3-R12}
LDMIA R1!, {R3-R12}
STMIA R0!, {R3-R12}
LDMIA R1!, {R3-R12}
STMIA R0!, {R3-R12}
LDMIA R1!, {R3-R12}
STMIA R0!, {R3-R12}
LDMIA R1!, {R3-R12}
STMIA R0!, {R3-R12}
LDMIA R1!, {R3-R12}
STMIA R0!, {R3-R12}
SUB R2, R2, #360
B Copy_32_1
Copy_32_2:
CMP R2, #(04*10*01) @ Copy chunks of 10 32-bit words (40 octets per loop)
BCC Copy_32_3
LDMIA R1!, {R3-R12}
STMIA R0!, {R3-R12}
SUB R2, R2, #(04*10*01)
B Copy_32_2
Copy_32_3:
CMP R2, #(04*01*01) @ Copy remaining 32-bit words
BCC Copy_16_1
LDR R3, [R1], #4
STR R3, [R0], #4
SUB R2, R2, #(04*01*01)
B Copy_32_3
@$PAGE
Copy_16_1:
CMP R2, #(02*01*16) @ Copy chunks of 16 16-bit words (32 bytes per loop)
BCC Copy_16_2
LDRH R3, [R1], #2
STRH R3, [R0], #2
LDRH R3, [R1], #2
STRH R3, [R0], #2
LDRH R3, [R1], #2
STRH R3, [R0], #2
LDRH R3, [R1], #2
STRH R3, [R0], #2
LDRH R3, [R1], #2
STRH R3, [R0], #2
LDRH R3, [R1], #2
STRH R3, [R0], #2
LDRH R3, [R1], #2
STRH R3, [R0], #2
LDRH R3, [R1], #2
STRH R3, [R0], #2
LDRH R3, [R1], #2
STRH R3, [R0], #2
LDRH R3, [R1], #2
STRH R3, [R0], #2
LDRH R3, [R1], #2
STRH R3, [R0], #2
LDRH R3, [R1], #2
STRH R3, [R0], #2
LDRH R3, [R1], #2
STRH R3, [R0], #2
LDRH R3, [R1], #2
STRH R3, [R0], #2
LDRH R3, [R1], #2
STRH R3, [R0], #2
LDRH R3, [R1], #2
STRH R3, [R0], #2
SUB R2, R2, #(02*01*16)
B Copy_16_1
Copy_16_2:
CMP R2, #(02*01*01) @ Copy remaining 16-bit words
BCC Copy_08_1
LDRH R3, [R1], #2
STRH R3, [R0], #2
SUB R2, R2, #(02*01*01)
B Copy_16_2
@$PAGE
Copy_08_1:
CMP R2, #(01*01*16) @ Copy chunks of 16 8-bit words (16 bytes per loop)
BCC Copy_08_2
LDRB R3, [R1], #1
STRB R3, [R0], #1
LDRB R3, [R1], #1
STRB R3, [R0], #1
LDRB R3, [R1], #1
STRB R3, [R0], #1
LDRB R3, [R1], #1
STRB R3, [R0], #1
LDRB R3, [R1], #1
STRB R3, [R0], #1
LDRB R3, [R1], #1
STRB R3, [R0], #1
LDRB R3, [R1], #1
STRB R3, [R0], #1
LDRB R3, [R1], #1
STRB R3, [R0], #1
LDRB R3, [R1], #1
STRB R3, [R0], #1
LDRB R3, [R1], #1
STRB R3, [R0], #1
LDRB R3, [R1], #1
STRB R3, [R0], #1
LDRB R3, [R1], #1
STRB R3, [R0], #1
LDRB R3, [R1], #1
STRB R3, [R0], #1
LDRB R3, [R1], #1
STRB R3, [R0], #1
LDRB R3, [R1], #1
STRB R3, [R0], #1
LDRB R3, [R1], #1
STRB R3, [R0], #1
SUB R2, R2, #(01*01*16)
B Copy_08_1
Copy_08_2:
CMP R2, #(01*01*01) @ Copy remaining 8-bit words
BCC Mem_Copy_END
LDRB R3, [R1], #1
STRB R3, [R0], #1
SUB R2, R2, #(01*01*01)
B Copy_08_2
Mem_Copy_END:
LDMFD SP!, {R3-R12} @ restore registers from stack
BX LR @ return
.end

View File

@@ -0,0 +1,306 @@
;********************************************************************************************************
; uC/LIB
; CUSTOM LIBRARY MODULES
;
; (c) Copyright 2004-2011; Micrium, Inc.; Weston, FL
;
; All rights reserved. Protected by international copyright laws.
;
; uC/LIB is provided in source form to registered licensees ONLY. It is
; illegal to distribute this source code to any third party unless you receive
; written permission by an authorized Micrium representative. Knowledge of
; the source code may NOT be used to develop a similar product.
;
; Please help us continue to provide the Embedded community with the finest
; software available. Your honesty is greatly appreciated.
;
; You can contact us at www.micrium.com.
;********************************************************************************************************
;********************************************************************************************************
;
; STANDARD MEMORY OPERATIONS
;
; ARM-Cortex-M3
; IAR Compiler
;
; Filename : lib_mem_a.asm
; Version : V1.36.01.00
; Programmer(s) : JDH
; BAN
;********************************************************************************************************
; Note(s) : (1) NO compiler-supplied standard library functions are used in library or product software.
;
; (a) ALL standard library functions are implemented in the custom library modules :
;
; (1) \<Custom Library Directory>\lib*.*
;
; (2) \<Custom Library Directory>\Ports\<cpu>\<compiler>\lib*_a.*
;
; where
; <Custom Library Directory> directory path for custom library software
; <cpu> directory name for specific processor (CPU)
; <compiler> directory name for specific compiler
;
; (b) Product-specific library functions are implemented in individual products.
;
; (2) Assumes ARM CPU mode configured for Little Endian.
;********************************************************************************************************
;********************************************************************************************************
; PUBLIC FUNCTIONS
;********************************************************************************************************
PUBLIC Mem_Copy
;********************************************************************************************************
; CODE GENERATION DIRECTIVES
;********************************************************************************************************
RSEG CODE:CODE:NOROOT(2)
;$PAGE
;********************************************************************************************************
; Mem_Copy()
;
; Description : Copy data octets from one buffer to another buffer.
;
; Argument(s) : pdest Pointer to destination memory buffer.
;
; psrc Pointer to source memory buffer.
;
; size Number of data buffer octets to copy.
;
; Return(s) : none.
;
; Caller(s) : Application.
;
; Note(s) : (1) Null copies allowed (i.e. 0-octet size).
;
; (2) Memory buffers NOT checked for overlapping.
;
; (3) Modulo arithmetic is used to determine whether a memory buffer starts on a 'CPU_ALIGN'
; address boundary.
;
; (4) ARM Cortex-M3 processors use a subset of the ARM Thumb-2 instruction set which does
; NOT support 16-bit conditional branch instructions but ONLY supports 8-bit conditional
; branch instructions.
;
; Therefore, branches exceeding 8-bit, signed, relative offsets :
;
; (a) CANNOT be implemented with conditional branches; but ...
; (b) MUST be implemented with non-conditional branches.
;********************************************************************************************************
; void Mem_Copy (void *pdest, ; ==> R0
; void *psrc, ; ==> R1
; CPU_SIZE_T size) ; ==> R2
Mem_Copy:
CMP R0, #0
BNE Mem_Copy_1
BX LR ; return if pdest == NULL
Mem_Copy_1:
CMP R1, #0
BNE Mem_Copy_2
BX LR ; return if psrc == NULL
Mem_Copy_2:
CMP R2, #0
BNE Mem_Copy_3
BX LR ; return if size == 0
Mem_Copy_3:
STMFD SP!, {R3-R12} ; save registers on stack
;$PAGE
Chk_Align_32: ; check if both dest & src 32-bit aligned
AND R3, R0, #0x03
AND R4, R1, #0x03
CMP R3, R4
BNE Chk_Align_16 ; not 32-bit aligned, check for 16-bit alignment
RSB R3, R3, #0x04 ; compute 1-2-3 pre-copy bytes (to align to the next 32-bit boundary)
AND R3, R3, #0x03
Pre_Copy_1:
CMP R3, #1 ; copy 1-2-3 bytes (to align to the next 32-bit boundary)
BCC Copy_32_1 ; start real 32-bit copy
CMP R2, #1 ; check if any more data to copy
BCS Pre_Copy_1_Cont
B Mem_Copy_END ; no more data to copy (see Note #4b)
Pre_Copy_1_Cont:
LDRB R4, [R1], #1
STRB R4, [R0], #1
SUB R3, R3, #1
SUB R2, R2, #1
B Pre_Copy_1
Chk_Align_16: ; check if both dest & src 16-bit aligned
AND R3, R0, #0x01
AND R4, R1, #0x01
CMP R3, R4
BEQ Pre_Copy_2
B Copy_08_1 ; not 16-bit aligned, start 8-bit copy (see Note #4b)
Pre_Copy_2:
CMP R3, #1 ; copy 1 byte (to align to the next 16-bit boundary)
BCC Copy_16_1 ; start real 16-bit copy
LDRB R4, [R1], #1
STRB R4, [R0], #1
SUB R3, R3, #1
SUB R2, R2, #1
B Pre_Copy_2
Copy_32_1:
CMP R2, #(04*10*09) ; Copy 9 chunks of 10 32-bit words (360 octets per loop)
BCC Copy_32_2
LDMIA R1!, {R3-R12}
STMIA R0!, {R3-R12}
LDMIA R1!, {R3-R12}
STMIA R0!, {R3-R12}
LDMIA R1!, {R3-R12}
STMIA R0!, {R3-R12}
LDMIA R1!, {R3-R12}
STMIA R0!, {R3-R12}
LDMIA R1!, {R3-R12}
STMIA R0!, {R3-R12}
LDMIA R1!, {R3-R12}
STMIA R0!, {R3-R12}
LDMIA R1!, {R3-R12}
STMIA R0!, {R3-R12}
LDMIA R1!, {R3-R12}
STMIA R0!, {R3-R12}
LDMIA R1!, {R3-R12}
STMIA R0!, {R3-R12}
SUB R2, R2, #(04*10*09)
B Copy_32_1
Copy_32_2:
CMP R2, #(04*10*01) ; Copy chunks of 10 32-bit words (40 octets per loop)
BCC Copy_32_3
LDMIA R1!, {R3-R12}
STMIA R0!, {R3-R12}
SUB R2, R2, #(04*10*01)
B Copy_32_2
Copy_32_3:
CMP R2, #(04*01*01) ; Copy remaining 32-bit words
BCC Copy_16_1
LDR R3, [R1], #4
STR R3, [R0], #4
SUB R2, R2, #(04*01*01)
B Copy_32_3
;$PAGE
Copy_16_1:
CMP R2, #(02*01*16) ; Copy chunks of 16 16-bit words (32 bytes per loop)
BCC Copy_16_2
LDRH R3, [R1], #2
STRH R3, [R0], #2
LDRH R3, [R1], #2
STRH R3, [R0], #2
LDRH R3, [R1], #2
STRH R3, [R0], #2
LDRH R3, [R1], #2
STRH R3, [R0], #2
LDRH R3, [R1], #2
STRH R3, [R0], #2
LDRH R3, [R1], #2
STRH R3, [R0], #2
LDRH R3, [R1], #2
STRH R3, [R0], #2
LDRH R3, [R1], #2
STRH R3, [R0], #2
LDRH R3, [R1], #2
STRH R3, [R0], #2
LDRH R3, [R1], #2
STRH R3, [R0], #2
LDRH R3, [R1], #2
STRH R3, [R0], #2
LDRH R3, [R1], #2
STRH R3, [R0], #2
LDRH R3, [R1], #2
STRH R3, [R0], #2
LDRH R3, [R1], #2
STRH R3, [R0], #2
LDRH R3, [R1], #2
STRH R3, [R0], #2
LDRH R3, [R1], #2
STRH R3, [R0], #2
SUB R2, R2, #(02*01*16)
B Copy_16_1
Copy_16_2:
CMP R2, #(02*01*01) ; Copy remaining 16-bit words
BCC Copy_08_1
LDRH R3, [R1], #2
STRH R3, [R0], #2
SUB R2, R2, #(02*01*01)
B Copy_16_2
;$PAGE
Copy_08_1:
CMP R2, #(01*01*16) ; Copy chunks of 16 8-bit words (16 bytes per loop)
BCC Copy_08_2
LDRB R3, [R1], #1
STRB R3, [R0], #1
LDRB R3, [R1], #1
STRB R3, [R0], #1
LDRB R3, [R1], #1
STRB R3, [R0], #1
LDRB R3, [R1], #1
STRB R3, [R0], #1
LDRB R3, [R1], #1
STRB R3, [R0], #1
LDRB R3, [R1], #1
STRB R3, [R0], #1
LDRB R3, [R1], #1
STRB R3, [R0], #1
LDRB R3, [R1], #1
STRB R3, [R0], #1
LDRB R3, [R1], #1
STRB R3, [R0], #1
LDRB R3, [R1], #1
STRB R3, [R0], #1
LDRB R3, [R1], #1
STRB R3, [R0], #1
LDRB R3, [R1], #1
STRB R3, [R0], #1
LDRB R3, [R1], #1
STRB R3, [R0], #1
LDRB R3, [R1], #1
STRB R3, [R0], #1
LDRB R3, [R1], #1
STRB R3, [R0], #1
LDRB R3, [R1], #1
STRB R3, [R0], #1
SUB R2, R2, #(01*01*16)
B Copy_08_1
Copy_08_2:
CMP R2, #(01*01*01) ; Copy remaining 8-bit words
BCC Mem_Copy_END
LDRB R3, [R1], #1
STRB R3, [R0], #1
SUB R2, R2, #(01*01*01)
B Copy_08_2
Mem_Copy_END:
LDMFD SP!, {R3-R12} ; restore registers from stack
BX LR ; return
END

View File

@@ -0,0 +1,312 @@
;********************************************************************************************************
; uC/LIB
; CUSTOM LIBRARY MODULES
;
; (c) Copyright 2004-2011; Micrium, Inc.; Weston, FL
;
; All rights reserved. Protected by international copyright laws.
;
; uC/LIB is provided in source form to registered licensees ONLY. It is
; illegal to distribute this source code to any third party unless you receive
; written permission by an authorized Micrium representative. Knowledge of
; the source code may NOT be used to develop a similar product.
;
; Please help us continue to provide the Embedded community with the finest
; software available. Your honesty is greatly appreciated.
;
; You can contact us at www.micrium.com.
;********************************************************************************************************
;********************************************************************************************************
;
; STANDARD MEMORY OPERATIONS
;
; ARM-Cortex-M3
; RealView Development Suite
; RealView Microcontroller Development Kit (MDK)
; ARM Developer Suite (ADS)
; Keil uVision
;
; Filename : lib_mem_a.asm
; Version : V1.36.01.00
; Programmer(s) : JDH
; BAN
;********************************************************************************************************
; Note(s) : (1) NO compiler-supplied standard library functions are used in library or product software.
;
; (a) ALL standard library functions are implemented in the custom library modules :
;
; (1) \<Custom Library Directory>\lib*.*
;
; (2) \<Custom Library Directory>\Ports\<cpu>\<compiler>\lib*_a.*
;
; where
; <Custom Library Directory> directory path for custom library software
; <cpu> directory name for specific processor (CPU)
; <compiler> directory name for specific compiler
;
; (b) Product-specific library functions are implemented in individual products.
;
; (2) Assumes ARM CPU mode configured for Little Endian.
;********************************************************************************************************
;********************************************************************************************************
; PUBLIC FUNCTIONS
;********************************************************************************************************
EXPORT Mem_Copy
;********************************************************************************************************
; CODE GENERATION DIRECTIVES
;********************************************************************************************************
AREA |.text|, CODE, READONLY, ALIGN=2
THUMB
REQUIRE8
PRESERVE8
;$PAGE
;********************************************************************************************************
; Mem_Copy()
;
; Description : Copy data octets from one buffer to another buffer.
;
; Argument(s) : pdest Pointer to destination memory buffer.
;
; psrc Pointer to source memory buffer.
;
; size Number of data buffer octets to copy.
;
; Return(s) : none.
;
; Caller(s) : Application.
;
; Note(s) : (1) Null copies allowed (i.e. 0-octet size).
;
; (2) Memory buffers NOT checked for overlapping.
;
; (3) Modulo arithmetic is used to determine whether a memory buffer starts on a 'CPU_ALIGN'
; address boundary.
;
; (4) ARM Cortex-M3 processors use a subset of the ARM Thumb-2 instruction set which does
; NOT support 16-bit conditional branch instructions but ONLY supports 8-bit conditional
; branch instructions.
;
; Therefore, branches exceeding 8-bit, signed, relative offsets :
;
; (a) CANNOT be implemented with conditional branches; but ...
; (b) MUST be implemented with non-conditional branches.
;********************************************************************************************************
; void Mem_Copy (void *pdest, ; ==> R0
; void *psrc, ; ==> R1
; CPU_SIZE_T size) ; ==> R2
Mem_Copy
CMP R0, #0
BNE Mem_Copy_1
BX LR ; return if pdest == NULL
Mem_Copy_1
CMP R1, #0
BNE Mem_Copy_2
BX LR ; return if psrc == NULL
Mem_Copy_2
CMP R2, #0
BNE Mem_Copy_3
BX LR ; return if size == 0
Mem_Copy_3
STMFD SP!, {R3-R12} ; save registers on stack
;$PAGE
Chk_Align_32 ; check if both dest & src 32-bit aligned
AND R3, R0, #0x03
AND R4, R1, #0x03
CMP R3, R4
BNE Chk_Align_16 ; not 32-bit aligned, check for 16-bit alignment
RSB R3, R3, #0x04 ; compute 1-2-3 pre-copy bytes (to align to the next 32-bit boundary)
AND R3, R3, #0x03
Pre_Copy_1
CMP R3, #1 ; copy 1-2-3 bytes (to align to the next 32-bit boundary)
BCC Copy_32_1 ; start real 32-bit copy
CMP R2, #1 ; check if any more data to copy
BCS Pre_Copy_1_Cont
B Mem_Copy_END ; no more data to copy (see Note #4b)
Pre_Copy_1_Cont
LDRB R4, [R1], #1
STRB R4, [R0], #1
SUB R3, R3, #1
SUB R2, R2, #1
B Pre_Copy_1
Chk_Align_16 ; check if both dest & src 16-bit aligned
AND R3, R0, #0x01
AND R4, R1, #0x01
CMP R3, R4
BEQ Pre_Copy_2
B Copy_08_1 ; not 16-bit aligned, start 8-bit copy (see Note #4b)
Pre_Copy_2
CMP R3, #1 ; copy 1 byte (to align to the next 16-bit boundary)
BCC Copy_16_1 ; start real 16-bit copy
LDRB R4, [R1], #1
STRB R4, [R0], #1
SUB R3, R3, #1
SUB R2, R2, #1
B Pre_Copy_2
Copy_32_1
CMP R2, #(04*10*09) ; Copy 9 chunks of 10 32-bit words (360 octets per loop)
BCC Copy_32_2
LDMIA R1!, {R3-R12}
STMIA R0!, {R3-R12}
LDMIA R1!, {R3-R12}
STMIA R0!, {R3-R12}
LDMIA R1!, {R3-R12}
STMIA R0!, {R3-R12}
LDMIA R1!, {R3-R12}
STMIA R0!, {R3-R12}
LDMIA R1!, {R3-R12}
STMIA R0!, {R3-R12}
LDMIA R1!, {R3-R12}
STMIA R0!, {R3-R12}
LDMIA R1!, {R3-R12}
STMIA R0!, {R3-R12}
LDMIA R1!, {R3-R12}
STMIA R0!, {R3-R12}
LDMIA R1!, {R3-R12}
STMIA R0!, {R3-R12}
SUB R2, R2, #(04*10*09)
B Copy_32_1
Copy_32_2
CMP R2, #(04*10*01) ; Copy chunks of 10 32-bit words (40 octets per loop)
BCC Copy_32_3
LDMIA R1!, {R3-R12}
STMIA R0!, {R3-R12}
SUB R2, R2, #(04*10*01)
B Copy_32_2
Copy_32_3
CMP R2, #(04*01*01) ; Copy remaining 32-bit words
BCC Copy_16_1
LDR R3, [R1], #4
STR R3, [R0], #4
SUB R2, R2, #(04*01*01)
B Copy_32_3
;$PAGE
Copy_16_1
CMP R2, #(02*01*16) ; Copy chunks of 16 16-bit words (32 bytes per loop)
BCC Copy_16_2
LDRH R3, [R1], #2
STRH R3, [R0], #2
LDRH R3, [R1], #2
STRH R3, [R0], #2
LDRH R3, [R1], #2
STRH R3, [R0], #2
LDRH R3, [R1], #2
STRH R3, [R0], #2
LDRH R3, [R1], #2
STRH R3, [R0], #2
LDRH R3, [R1], #2
STRH R3, [R0], #2
LDRH R3, [R1], #2
STRH R3, [R0], #2
LDRH R3, [R1], #2
STRH R3, [R0], #2
LDRH R3, [R1], #2
STRH R3, [R0], #2
LDRH R3, [R1], #2
STRH R3, [R0], #2
LDRH R3, [R1], #2
STRH R3, [R0], #2
LDRH R3, [R1], #2
STRH R3, [R0], #2
LDRH R3, [R1], #2
STRH R3, [R0], #2
LDRH R3, [R1], #2
STRH R3, [R0], #2
LDRH R3, [R1], #2
STRH R3, [R0], #2
LDRH R3, [R1], #2
STRH R3, [R0], #2
SUB R2, R2, #(02*01*16)
B Copy_16_1
Copy_16_2
CMP R2, #(02*01*01) ; Copy remaining 16-bit words
BCC Copy_08_1
LDRH R3, [R1], #2
STRH R3, [R0], #2
SUB R2, R2, #(02*01*01)
B Copy_16_2
;$PAGE
Copy_08_1
CMP R2, #(01*01*16) ; Copy chunks of 16 8-bit words (16 bytes per loop)
BCC Copy_08_2
LDRB R3, [R1], #1
STRB R3, [R0], #1
LDRB R3, [R1], #1
STRB R3, [R0], #1
LDRB R3, [R1], #1
STRB R3, [R0], #1
LDRB R3, [R1], #1
STRB R3, [R0], #1
LDRB R3, [R1], #1
STRB R3, [R0], #1
LDRB R3, [R1], #1
STRB R3, [R0], #1
LDRB R3, [R1], #1
STRB R3, [R0], #1
LDRB R3, [R1], #1
STRB R3, [R0], #1
LDRB R3, [R1], #1
STRB R3, [R0], #1
LDRB R3, [R1], #1
STRB R3, [R0], #1
LDRB R3, [R1], #1
STRB R3, [R0], #1
LDRB R3, [R1], #1
STRB R3, [R0], #1
LDRB R3, [R1], #1
STRB R3, [R0], #1
LDRB R3, [R1], #1
STRB R3, [R0], #1
LDRB R3, [R1], #1
STRB R3, [R0], #1
LDRB R3, [R1], #1
STRB R3, [R0], #1
SUB R2, R2, #(01*01*16)
B Copy_08_1
Copy_08_2
CMP R2, #(01*01*01) ; Copy remaining 8-bit words
BCC Mem_Copy_END
LDRB R3, [R1], #1
STRB R3, [R0], #1
SUB R2, R2, #(01*01*01)
B Copy_08_2
Mem_Copy_END
LDMFD SP!, {R3-R12} ; restore registers from stack
BX LR ; return
END

661
UCOSIII/uC-LIB/lib_ascii.c Normal file
View File

@@ -0,0 +1,661 @@
/*
*********************************************************************************************************
* uC/LIB
* CUSTOM LIBRARY MODULES
*
* (c) Copyright 2004-2012; Micrium, Inc.; Weston, FL
*
* All rights reserved. Protected by international copyright laws.
*
* uC/LIB is provided in source form to registered licensees ONLY. It is
* illegal to distribute this source code to any third party unless you receive
* written permission by an authorized Micrium representative. Knowledge of
* the source code may NOT be used to develop a similar product.
*
* Please help us continue to provide the Embedded community with the finest
* software available. Your honesty is greatly appreciated.
*
* You can contact us at www.micrium.com.
*********************************************************************************************************
*/
/*
*********************************************************************************************************
*
* ASCII CHARACTER OPERATIONS
*
* Filename : lib_ascii.c
* Version : V1.37.01
* Programmer(s) : BAN
* ITJ
*********************************************************************************************************
* Note(s) : (1) NO compiler-supplied standard library functions are used in library or product software.
*
* (a) ALL standard library functions are implemented in the custom library modules :
*
* (1) \<Custom Library Directory>\lib_*.*
*
* (2) \<Custom Library Directory>\Ports\<cpu>\<compiler>\lib*_a.*
*
* where
* <Custom Library Directory> directory path for custom library software
* <cpu> directory name for specific processor (CPU)
* <compiler> directory name for specific compiler
*
* (b) Product-specific library functions are implemented in individual products.
*
*
* (2) (a) ECMA-6 '7-Bit coded Character Set' (6th edition), which corresponds to the
* 3rd edition of ISO 646, specifies several versions of a 7-bit character set :
*
* (1) THE GENERAL VERSION, which allows characters at 0x23 and 0x24 to be given a
* set alternate form and allows the characters 0x40, 0x5B, 0x5D, 0x60, 0x7B &
* 0x7D to be assigned a "unique graphic character" or to be declared as unused.
* All other characters are explicitly specified.
*
* (2) THE INTERNATIONAL REFERENCE VERSION, which explicitly specifies all characters
* in the 7-bit character set.
*
* (3) NATIONAL & APPLICATION-ORIENTED VERSIONS, which may be derived from the
* standard in specified ways.
*
* (b) The character set represented in this file reproduces the Internation Reference
* Version. This is identical to the 7-bit character set which occupies Unicode
* characters 0x0000 through 0x007F. The character names are taken from v5.0 of the
* Unicode specification, with certain abbreviations so that the resulting #define
* names will not violate ANSI C naming restriction :
*
* (1) For the Latin capital & lowercase letters, the name components 'LETTER_CAPITAL'
* & 'LETTER_SMALL' are replaced by 'UPPER' & 'LOWER', respectively.
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* INCLUDE FILES
*********************************************************************************************************
*/
#define MICRIUM_SOURCE
#define LIB_ASCII_MODULE
#include <lib_ascii.h>
/*$PAGE*/
/*
*********************************************************************************************************
* LOCAL DEFINES
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* LOCAL CONSTANTS
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* LOCAL DATA TYPES
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* LOCAL TABLES
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* LOCAL GLOBAL VARIABLES
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* LOCAL FUNCTION PROTOTYPES
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* LOCAL CONFIGURATION ERRORS
*********************************************************************************************************
*/
/*$PAGE*/
/*
*********************************************************************************************************
* ASCII_IsAlpha()
*
* Description : Determine whether a character is an alphabetic character.
*
* Argument(s) : c Character to examine.
*
* Return(s) : DEF_YES, if character is an alphabetic character.
*
* DEF_NO, if character is NOT an alphabetic character.
*
* Caller(s) : Application.
*
* Note(s) : (1) ISO/IEC 9899:TC2, Section 7.4.1.2.(2) states that "isalpha() returns true only for the
* characters for which isupper() or islower() is true".
*********************************************************************************************************
*/
CPU_BOOLEAN ASCII_IsAlpha (CPU_CHAR c)
{
CPU_BOOLEAN alpha;
alpha = ASCII_IS_ALPHA(c);
return (alpha);
}
/*
*********************************************************************************************************
* ASCII_IsAlphaNum()
*
* Description : Determine whether a character is an alphanumeric character.
*
* Argument(s) : c Character to examine.
*
* Return(s) : DEF_YES, if character is an alphanumeric character.
*
* DEF_NO, if character is NOT an alphanumeric character.
*
* Caller(s) : Application.
*
* Note(s) : (1) ISO/IEC 9899:TC2, Section 7.4.1.1.(2) states that "isalnum() ... tests for any character
* for which isalpha() or isdigit() is true".
*********************************************************************************************************
*/
CPU_BOOLEAN ASCII_IsAlphaNum (CPU_CHAR c)
{
CPU_BOOLEAN alpha_num;
alpha_num = ASCII_IS_ALPHA_NUM(c);
return (alpha_num);
}
/*$PAGE*/
/*
*********************************************************************************************************
* ASCII_IsLower()
*
* Description : Determine whether a character is a lowercase alphabetic character.
*
* Argument(s) : c Character to examine.
*
* Return(s) : DEF_YES, if character is a lowercase alphabetic character.
*
* DEF_NO, if character is NOT a lowercase alphabetic character.
*
* Caller(s) : Application.
*
* Note(s) : (1) ISO/IEC 9899:TC2, Section 7.4.1.7.(2) states that "islower() returns true only for
* the lowercase letters".
*********************************************************************************************************
*/
CPU_BOOLEAN ASCII_IsLower (CPU_CHAR c)
{
CPU_BOOLEAN lower;
lower = ASCII_IS_LOWER(c);
return (lower);
}
/*
*********************************************************************************************************
* ASCII_IsUpper()
*
* Description : Determine whether a character is an uppercase alphabetic character.
*
* Argument(s) : c Character to examine.
*
* Return(s) : DEF_YES, if character is an uppercase alphabetic character.
*
* DEF_NO, if character is NOT an uppercase alphabetic character.
*
* Caller(s) : Application.
*
* Note(s) : (1) ISO/IEC 9899:TC2, Section 7.4.1.11.(2) states that "isupper() returns true only for
* the uppercase letters".
*********************************************************************************************************
*/
CPU_BOOLEAN ASCII_IsUpper (CPU_CHAR c)
{
CPU_BOOLEAN upper;
upper = ASCII_IS_UPPER(c);
return (upper);
}
/*$PAGE*/
/*
*********************************************************************************************************
* ASCII_IsDig()
*
* Description : Determine whether a character is a decimal-digit character.
*
* Argument(s) : c Character to examine.
*
* Return(s) : DEF_YES, if character is a decimal-digit character.
*
* DEF_NO, if character is NOT a decimal-digit character.
*
* Caller(s) : Application.
*
* Note(s) : (1) ISO/IEC 9899:TC2, Section 7.4.1.5.(2) states that "isdigit() ... tests for any
* decimal-digit character".
*********************************************************************************************************
*/
CPU_BOOLEAN ASCII_IsDig (CPU_CHAR c)
{
CPU_BOOLEAN dig;
dig = ASCII_IS_DIG(c);
return (dig);
}
/*
*********************************************************************************************************
* ASCII_IsDigOct()
*
* Description : Determine whether a character is an octal-digit character.
*
* Argument(s) : c Character to examine.
*
* Return(s) : DEF_YES, if character is an octal-digit character.
*
* DEF_NO, if character is NOT an octal-digit character.
*
* Caller(s) : Application.
*
* Note(s) : none.
*********************************************************************************************************
*/
CPU_BOOLEAN ASCII_IsDigOct (CPU_CHAR c)
{
CPU_BOOLEAN dig_oct;
dig_oct = ASCII_IS_DIG_OCT(c);
return (dig_oct);
}
/*
*********************************************************************************************************
* ASCII_IsDigHex()
*
* Description : Determine whether a character is a hexadecimal-digit character.
*
* Argument(s) : c Character to examine.
*
* Return(s) : DEF_YES, if character is a hexadecimal-digit character.
*
* DEF_NO, if character is NOT a hexadecimal-digit character.
*
* Caller(s) : Application.
*
* Note(s) : (1) ISO/IEC 9899:TC2, Section 7.4.1.12.(2) states that "isxdigit() ... tests for any
* hexadecimal-digit character".
*********************************************************************************************************
*/
CPU_BOOLEAN ASCII_IsDigHex (CPU_CHAR c)
{
CPU_BOOLEAN dig_hex;
dig_hex = ASCII_IS_DIG_HEX(c);
return (dig_hex);
}
/*$PAGE*/
/*
*********************************************************************************************************
* ASCII_IsBlank()
*
* Description : Determine whether a character is a standard blank character.
*
* Argument(s) : c Character to examine.
*
* Return(s) : DEF_YES, if character is a standard blank character.
*
* DEF_NO, if character is NOT a standard blank character.
*
* Caller(s) : Application.
*
* Note(s) : (1) (a) ISO/IEC 9899:TC2, Section 7.4.1.3.(2) states that "isblank() returns true only for
* the standard blank characters".
*
* (b) ISO/IEC 9899:TC2, Section 7.4.1.3.(2) defines "the standard blank characters" as
* the "space (' '), and horizontal tab ('\t')".
*********************************************************************************************************
*/
CPU_BOOLEAN ASCII_IsBlank (CPU_CHAR c)
{
CPU_BOOLEAN blank;
blank = ASCII_IS_BLANK(c);
return (blank);
}
/*
*********************************************************************************************************
* ASCII_IsSpace()
*
* Description : Determine whether a character is a white-space character.
*
* Argument(s) : c Character to examine.
*
* Return(s) : DEF_YES, if character is a white-space character.
*
* DEF_NO, if character is NOT a white-space character.
*
* Caller(s) : Application.
*
* Note(s) : (1) (a) ISO/IEC 9899:TC2, Section 7.4.1.10.(2) states that "isspace() returns true only
* for the standard white-space characters".
*
* (b) ISO/IEC 9899:TC2, Section 7.4.1.10.(2) defines "the standard white-space characters"
* as the "space (' '), form feed ('\f'), new-line ('\n'), carriage return ('\r'),
* horizontal tab ('\t'), and vertical tab ('\v')".
*********************************************************************************************************
*/
CPU_BOOLEAN ASCII_IsSpace (CPU_CHAR c)
{
CPU_BOOLEAN space;
space = ASCII_IS_SPACE(c);
return (space);
}
/*$PAGE*/
/*
*********************************************************************************************************
* ASCII_IsPrint()
*
* Description : Determine whether a character is a printing character.
*
* Argument(s) : c Character to examine.
*
* Return(s) : DEF_YES, if character is a printing character.
*
* DEF_NO, if character is NOT a printing character.
*
* Caller(s) : Application.
*
* Note(s) : (1) (a) ISO/IEC 9899:TC2, Section 7.4.1.8.(2) states that "isprint() ... tests for any
* printing character including space (' ')".
*
* (b) ISO/IEC 9899:TC2, Section 7.4.(3), Note 169, states that in "the seven-bit US
* ASCII character set, the printing characters are those whose values lie from
* 0x20 (space) through 0x7E (tilde)".
*********************************************************************************************************
*/
CPU_BOOLEAN ASCII_IsPrint (CPU_CHAR c)
{
CPU_BOOLEAN print;
print = ASCII_IS_PRINT(c);
return (print);
}
/*
*********************************************************************************************************
* ASCII_IsGraph()
*
* Description : Determine whether a character is any printing character except a space character.
*
* Argument(s) : c Character to examine.
*
* Return(s) : DEF_YES, if character is a graphic character.
*
* DEF_NO, if character is NOT a graphic character.
*
* Caller(s) : Application.
*
* Note(s) : (1) (a) ISO/IEC 9899:TC2, Section 7.4.1.6.(2) states that "isgraph() ... tests for any
* printing character except space (' ')".
*
* (b) ISO/IEC 9899:TC2, Section 7.4.(3), Note 169, states that in "the seven-bit US
* ASCII character set, the printing characters are those whose values lie from
* 0x20 (space) through 0x7E (tilde)".
*********************************************************************************************************
*/
CPU_BOOLEAN ASCII_IsGraph (CPU_CHAR c)
{
CPU_BOOLEAN graph;
graph = ASCII_IS_GRAPH(c);
return (graph);
}
/*$PAGE*/
/*
*********************************************************************************************************
* ASCII_IsPunct()
*
* Description : Determine whether a character is a punctuation character.
*
* Argument(s) : c Character to examine.
*
* Return(s) : DEF_YES, if character is a punctuation character.
*
* DEF_NO, if character is NOT a punctuation character.
*
* Caller(s) : Application.
*
* Note(s) : (1) ISO/IEC 9899:TC2, Section 7.4.1.9.(2) states that "ispunct() returns true for every
* printing character for which neither isspace() nor isalnum() is true".
*********************************************************************************************************
*/
CPU_BOOLEAN ASCII_IsPunct (CPU_CHAR c)
{
CPU_BOOLEAN punct;
punct = ASCII_IS_PUNCT(c);
return (punct);
}
/*
*********************************************************************************************************
* ASCII_IsCtrl()
*
* Description : Determine whether a character is a control character.
*
* Argument(s) : c Character to examine.
*
* Return(s) : DEF_YES, if character is a control character.
*
* DEF_NO, if character is NOT a control character.
*
* Caller(s) : Application.
*
* Note(s) : (1) (a) ISO/IEC 9899:TC2, Section 7.4.1.4.(2) states that "iscntrl() ... tests for any
* control character".
*
* (b) ISO/IEC 9899:TC2, Section 7.4.(3), Note 169, states that in "the seven-bit US
* ASCII character set, ... the control characters are those whose values lie from
* 0 (NUL) through 0x1F (US), and the character 0x7F (DEL)".
*********************************************************************************************************
*/
CPU_BOOLEAN ASCII_IsCtrl (CPU_CHAR c)
{
CPU_BOOLEAN ctrl;
ctrl = ASCII_IS_CTRL(c);
return (ctrl);
}
/*$PAGE*/
/*
*********************************************************************************************************
* ASCII_ToLower()
*
* Description : Convert uppercase alphabetic character to its corresponding lowercase alphabetic character.
*
* Argument(s) : c Character to convert.
*
* Return(s) : Lowercase equivalent of 'c', if character 'c' is an uppercase character (see Note #1b1).
*
* Character 'c', otherwise (see Note #1b2).
*
* Caller(s) : Application.
*
* Note(s) : (1) (a) ISO/IEC 9899:TC2, Section 7.4.2.1.(2) states that "tolower() ... converts an
* uppercase letter to a corresponding lowercase letter".
*
* (b) ISO/IEC 9899:TC2, Section 7.4.2.1.(3) states that :
*
* (1) (A) "if the argument is a character for which isupper() is true and there are
* one or more corresponding characters ... for which islower() is true," ...
* (B) "tolower() ... returns one of the corresponding characters;" ...
*
* (2) "otherwise, the argument is returned unchanged."
*********************************************************************************************************
*/
CPU_CHAR ASCII_ToLower (CPU_CHAR c)
{
CPU_CHAR lower;
lower = ASCII_TO_LOWER(c);
return (lower);
}
/*
*********************************************************************************************************
* ASCII_ToUpper()
*
* Description : Convert lowercase alphabetic character to its corresponding uppercase alphabetic character.
*
* Argument(s) : c Character to convert.
*
* Return(s) : Uppercase equivalent of 'c', if character 'c' is a lowercase character (see Note #1b1).
*
* Character 'c', otherwise (see Note #1b2).
*
* Caller(s) : Application.
*
* Note(s) : (1) (a) ISO/IEC 9899:TC2, Section 7.4.2.2.(2) states that "toupper() ... converts a
* lowercase letter to a corresponding uppercase letter".
*
* (b) ISO/IEC 9899:TC2, Section 7.4.2.2.(3) states that :
*
* (1) (A) "if the argument is a character for which islower() is true and there are
* one or more corresponding characters ... for which isupper() is true," ...
* (B) "toupper() ... returns one of the corresponding characters;" ...
*
* (2) "otherwise, the argument is returned unchanged."
*********************************************************************************************************
*/
CPU_CHAR ASCII_ToUpper (CPU_CHAR c)
{
CPU_CHAR upper;
upper = ASCII_TO_UPPER(c);
return (upper);
}
/*$PAGE*/
/*
*********************************************************************************************************
* ASCII_Cmp()
*
* Description : Determine if two characters are identical (case-insensitive).
*
* Argument(s) : c1 First character.
*
* c2 Second character.
*
* Return(s) : DEF_YES, if the characters are identical.
*
* DEF_NO, if the characters are NOT identical.
*
* Caller(s) : Application.
*
* Note(s) : none.
*********************************************************************************************************
*/
CPU_BOOLEAN ASCII_Cmp (CPU_CHAR c1,
CPU_CHAR c2)
{
CPU_CHAR c1_upper;
CPU_CHAR c2_upper;
CPU_BOOLEAN cmp;
c1_upper = ASCII_ToUpper(c1);
c2_upper = ASCII_ToUpper(c2);
cmp = (c1_upper == c2_upper) ? (DEF_YES) : (DEF_NO);
return (cmp);
}

853
UCOSIII/uC-LIB/lib_ascii.h Normal file
View File

@@ -0,0 +1,853 @@
/*
*********************************************************************************************************
* uC/LIB
* CUSTOM LIBRARY MODULES
*
* (c) Copyright 2004-2012; Micrium, Inc.; Weston, FL
*
* All rights reserved. Protected by international copyright laws.
*
* uC/LIB is provided in source form to registered licensees ONLY. It is
* illegal to distribute this source code to any third party unless you receive
* written permission by an authorized Micrium representative. Knowledge of
* the source code may NOT be used to develop a similar product.
*
* Please help us continue to provide the Embedded community with the finest
* software available. Your honesty is greatly appreciated.
*
* You can contact us at www.micrium.com.
*********************************************************************************************************
*/
/*
*********************************************************************************************************
*
* ASCII CHARACTER OPERATIONS
*
* Filename : lib_ascii.h
* Version : V1.37.01
* Programmer(s) : BAN
*********************************************************************************************************
* Note(s) : (1) NO compiler-supplied standard library functions are used in library or product software.
*
* (a) ALL standard library functions are implemented in the custom library modules :
*
* (1) \<Custom Library Directory>\lib_*.*
*
* (2) \<Custom Library Directory>\Ports\<cpu>\<compiler>\lib*_a.*
*
* where
* <Custom Library Directory> directory path for custom library software
* <cpu> directory name for specific processor (CPU)
* <compiler> directory name for specific compiler
*
* (b) Product-specific library functions are implemented in individual products.
*
*
* (2) (a) ECMA-6 '7-Bit coded Character Set' (6th edition), which corresponds to the
* 3rd edition of ISO 646, specifies several versions of a 7-bit character set :
*
* (1) THE GENERAL VERSION, which allows characters at 0x23 and 0x24 to be given a
* set alternate form and allows the characters 0x40, 0x5B, 0x5D, 0x60, 0x7B &
* 0x7D to be assigned a "unique graphic character" or to be declared as unused.
* All other characters are explicitly specified.
*
* (2) THE INTERNATIONAL REFERENCE VERSION, which explicitly specifies all characters
* in the 7-bit character set.
*
* (3) NATIONAL & APPLICATION-ORIENTED VERSIONS, which may be derived from the
* standard in specified ways.
*
* (b) The character set represented in this file reproduces the Internation Reference
* Version. This is identical to the 7-bit character set which occupies Unicode
* characters 0x0000 through 0x007F. The character names are taken from v5.0 of the
* Unicode specification, with certain abbreviations so that the resulting #define
* names will not violate ANSI C naming restriction :
*
* (1) For the Latin capital & lowercase letters, the name components 'LETTER_CAPITAL'
* & 'LETTER_SMALL' are replaced by 'UPPER' & 'LOWER', respectively.
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* MODULE
*
* Note(s) : (1) This ASCII library header file is protected from multiple pre-processor inclusion through
* use of the ASCII library module present pre-processor macro definition.
*********************************************************************************************************
*/
#ifndef LIB_ASCII_MODULE_PRESENT /* See Note #1. */
#define LIB_ASCII_MODULE_PRESENT
/*$PAGE*/
/*
*********************************************************************************************************
* INCLUDE FILES
*
* Note(s) : (1) The custom library software files are located in the following directories :
*
* (a) \<Custom Library Directory>\lib_*.*
*
* where
* <Custom Library Directory> directory path for custom library software
*
* (2) CPU-configuration software files are located in the following directories :
*
* (a) \<CPU-Compiler Directory>\cpu_*.*
* (b) \<CPU-Compiler Directory>\<cpu>\<compiler>\cpu*.*
*
* where
* <CPU-Compiler Directory> directory path for common CPU-compiler software
* <cpu> directory name for specific processor (CPU)
* <compiler> directory name for specific compiler
*
* (3) Compiler MUST be configured to include as additional include path directories :
*
* (a) '\<Custom Library Directory>\' directory See Note #1a
*
* (b) (1) '\<CPU-Compiler Directory>\' directory See Note #2a
* (2) '\<CPU-Compiler Directory>\<cpu>\<compiler>\' directory See Note #2b
*
* (4) NO compiler-supplied standard library functions SHOULD be used.
*********************************************************************************************************
*/
#include <cpu.h>
#include <lib_def.h>
/*
*********************************************************************************************************
* EXTERNS
*********************************************************************************************************
*/
#ifdef LIB_ASCII_MODULE
#define LIB_ASCII_EXT
#else
#define LIB_ASCII_EXT extern
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* DEFINES
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* ASCII CHARACTER DEFINES
*********************************************************************************************************
*/
/* -------------------- C0 CONTROLS ------------------- */
#define ASCII_CHAR_NULL 0x00 /* '\0' */
#define ASCII_CHAR_START_OF_HEADING 0x01
#define ASCII_CHAR_START_OF_TEXT 0x02
#define ASCII_CHAR_END_OF_TEXT 0x03
#define ASCII_CHAR_END_OF_TRANSMISSION 0x04
#define ASCII_CHAR_ENQUIRY 0x05
#define ASCII_CHAR_ACKNOWLEDGE 0x06
#define ASCII_CHAR_BELL 0x07 /* '\a' */
#define ASCII_CHAR_BACKSPACE 0x08 /* '\b' */
#define ASCII_CHAR_CHARACTER_TABULATION 0x09 /* '\t' */
#define ASCII_CHAR_LINE_FEED 0x0A /* '\n' */
#define ASCII_CHAR_LINE_TABULATION 0x0B /* '\v' */
#define ASCII_CHAR_FORM_FEED 0x0C /* '\f' */
#define ASCII_CHAR_CARRIAGE_RETURN 0x0D /* '\r' */
#define ASCII_CHAR_SHIFT_OUT 0x0E
#define ASCII_CHAR_SHIFT_IN 0x0F
#define ASCII_CHAR_DATA_LINK_ESCAPE 0x10
#define ASCII_CHAR_DEVICE_CONTROL_ONE 0x11
#define ASCII_CHAR_DEVICE_CONTROL_TWO 0x12
#define ASCII_CHAR_DEVICE_CONTROL_THREE 0x13
#define ASCII_CHAR_DEVICE_CONTROL_FOUR 0x14
#define ASCII_CHAR_NEGATIVE_ACKNOWLEDGE 0x15
#define ASCII_CHAR_SYNCHRONOUS_IDLE 0x16
#define ASCII_CHAR_END_OF_TRANSMISSION_BLOCK 0x17
#define ASCII_CHAR_CANCEL 0x18
#define ASCII_CHAR_END_OF_MEDIUM 0x19
#define ASCII_CHAR_SUBSITUTE 0x1A
#define ASCII_CHAR_ESCAPE 0x1B
#define ASCII_CHAR_INFO_SEPARATOR_FOUR 0x1C
#define ASCII_CHAR_INFO_SEPARATOR_THREE 0x1D
#define ASCII_CHAR_INFO_SEPARATOR_TWO 0x1E
#define ASCII_CHAR_INFO_SEPARATOR_ONE 0x1F
#define ASCII_CHAR_NUL ASCII_CHAR_NULL
#define ASCII_CHAR_SOH ASCII_CHAR_START_OF_HEADING
#define ASCII_CHAR_START_HEADING ASCII_CHAR_START_OF_HEADING
#define ASCII_CHAR_STX ASCII_CHAR_START_OF_TEXT
#define ASCII_CHAR_START_TEXT ASCII_CHAR_START_OF_TEXT
#define ASCII_CHAR_ETX ASCII_CHAR_END_OF_TEXT
#define ASCII_CHAR_END_TEXT ASCII_CHAR_END_OF_TEXT
#define ASCII_CHAR_EOT ASCII_CHAR_END_OF_TRANSMISSION
#define ASCII_CHAR_END_TRANSMISSION ASCII_CHAR_END_OF_TRANSMISSION
#define ASCII_CHAR_ENQ ASCII_CHAR_ENQUIRY
#define ASCII_CHAR_ACK ASCII_CHAR_ACKNOWLEDGE
#define ASCII_CHAR_BEL ASCII_CHAR_BELL
#define ASCII_CHAR_BS ASCII_CHAR_BACKSPACE
#define ASCII_CHAR_HT ASCII_CHAR_CHARACTER_TABULATION
#define ASCII_CHAR_TAB ASCII_CHAR_CHARACTER_TABULATION
#define ASCII_CHAR_LF ASCII_CHAR_LINE_FEED
#define ASCII_CHAR_VT ASCII_CHAR_LINE_TABULATION
#define ASCII_CHAR_FF ASCII_CHAR_FORM_FEED
#define ASCII_CHAR_CR ASCII_CHAR_CARRIAGE_RETURN
#define ASCII_CHAR_SO ASCII_CHAR_SHIFT_OUT
#define ASCII_CHAR_SI ASCII_CHAR_SHIFT_IN
#define ASCII_CHAR_DLE ASCII_CHAR_DATA_LINK_ESCAPE
#define ASCII_CHAR_DC1 ASCII_CHAR_DEVICE_CONTROL_ONE
#define ASCII_CHAR_DC2 ASCII_CHAR_DEVICE_CONTROL_TWO
#define ASCII_CHAR_DC3 ASCII_CHAR_DEVICE_CONTROL_THREE
#define ASCII_CHAR_DC4 ASCII_CHAR_DEVICE_CONTROL_FOUR
#define ASCII_CHAR_DEV_CTRL_ONE ASCII_CHAR_DEVICE_CONTROL_ONE
#define ASCII_CHAR_DEV_CTRL_TWO ASCII_CHAR_DEVICE_CONTROL_TWO
#define ASCII_CHAR_DEV_CTRL_THREE ASCII_CHAR_DEVICE_CONTROL_THREE
#define ASCII_CHAR_DEV_CTRL_FOUR ASCII_CHAR_DEVICE_CONTROL_FOUR
#define ASCII_CHAR_NAK ASCII_CHAR_NEGATIVE_ACKNOWLEDGE
#define ASCII_CHAR_NEG_ACK ASCII_CHAR_NEGATIVE_ACKNOWLEDGE
#define ASCII_CHAR_SYN ASCII_CHAR_SYNCHRONOUS_IDLE
#define ASCII_CHAR_SYNC_IDLE ASCII_CHAR_SYNCHRONOUS_IDLE
#define ASCII_CHAR_ETB ASCII_CHAR_END_OF_TRANSMISSION_BLOCK
#define ASCII_CHAR_END_TRANSMISSION_BLK ASCII_CHAR_END_OF_TRANSMISSION_BLOCK
#define ASCII_CHAR_CAN ASCII_CHAR_CANCEL
#define ASCII_CHAR_EM ASCII_CHAR_END_OF_MEDIUM
#define ASCII_CHAR_END_MEDIUM ASCII_CHAR_END_OF_MEDIUM
#define ASCII_CHAR_SUB ASCII_CHAR_SUBSITUTE
#define ASCII_CHAR_ESC ASCII_CHAR_ESCAPE
#define ASCII_CHAR_IS1 ASCII_CHAR_INFO_SEPARATOR_ONE
#define ASCII_CHAR_IS2 ASCII_CHAR_INFO_SEPARATOR_TWO
#define ASCII_CHAR_IS3 ASCII_CHAR_INFO_SEPARATOR_THREE
#define ASCII_CHAR_IS4 ASCII_CHAR_INFO_SEPARATOR_FOUR
/*$PAGE*/
/* ------------ ASCII PUNCTUATION & SYMBOLS ----------- */
#define ASCII_CHAR_SPACE 0x20 /* ' ' */
#define ASCII_CHAR_EXCLAMATION_MARK 0x21 /* '!' */
#define ASCII_CHAR_QUOTATION_MARK 0x22 /* '\"' */
#define ASCII_CHAR_NUMBER_SIGN 0x23 /* '#' */
#define ASCII_CHAR_DOLLAR_SIGN 0x24 /* '$' */
#define ASCII_CHAR_PERCENTAGE_SIGN 0x25 /* '%' */
#define ASCII_CHAR_AMPERSAND 0x26 /* '&' */
#define ASCII_CHAR_APOSTROPHE 0x27 /* '\'' */
#define ASCII_CHAR_LEFT_PARENTHESIS 0x28 /* '(' */
#define ASCII_CHAR_RIGHT_PARENTHESIS 0x29 /* ')' */
#define ASCII_CHAR_ASTERISK 0x2A /* '*' */
#define ASCII_CHAR_PLUS_SIGN 0x2B /* '+' */
#define ASCII_CHAR_COMMA 0x2C /* ',' */
#define ASCII_CHAR_HYPHEN_MINUS 0x2D /* '-' */
#define ASCII_CHAR_FULL_STOP 0x2E /* '.' */
#define ASCII_CHAR_SOLIDUS 0x2F /* '/' */
#define ASCII_CHAR_PAREN_LEFT ASCII_CHAR_LEFT_PARENTHESIS
#define ASCII_CHAR_PAREN_RIGHT ASCII_CHAR_RIGHT_PARENTHESIS
/* ------------------- ASCII DIGITS ------------------- */
#define ASCII_CHAR_DIGIT_ZERO 0x30 /* '0' */
#define ASCII_CHAR_DIGIT_ONE 0x31 /* '1' */
#define ASCII_CHAR_DIGIT_TWO 0x32 /* '2' */
#define ASCII_CHAR_DIGIT_THREE 0x33 /* '3' */
#define ASCII_CHAR_DIGIT_FOUR 0x34 /* '4' */
#define ASCII_CHAR_DIGIT_FIVE 0x35 /* '5' */
#define ASCII_CHAR_DIGIT_SIX 0x36 /* '6' */
#define ASCII_CHAR_DIGIT_SEVEN 0x37 /* '7' */
#define ASCII_CHAR_DIGIT_EIGHT 0x38 /* '8' */
#define ASCII_CHAR_DIGIT_NINE 0x39 /* '9' */
#define ASCII_CHAR_DIG_ZERO ASCII_CHAR_DIGIT_ZERO
#define ASCII_CHAR_DIG_ONE ASCII_CHAR_DIGIT_ONE
#define ASCII_CHAR_DIG_TWO ASCII_CHAR_DIGIT_TWO
#define ASCII_CHAR_DIG_THREE ASCII_CHAR_DIGIT_THREE
#define ASCII_CHAR_DIG_FOUR ASCII_CHAR_DIGIT_FOUR
#define ASCII_CHAR_DIG_FIVE ASCII_CHAR_DIGIT_FIVE
#define ASCII_CHAR_DIG_SIX ASCII_CHAR_DIGIT_SIX
#define ASCII_CHAR_DIG_SEVEN ASCII_CHAR_DIGIT_SEVEN
#define ASCII_CHAR_DIG_EIGHT ASCII_CHAR_DIGIT_EIGHT
#define ASCII_CHAR_DIG_NINE ASCII_CHAR_DIGIT_NINE
/* ------------ ASCII PUNCTUATION & SYMBOLS ----------- */
#define ASCII_CHAR_COLON 0x3A /* ':' */
#define ASCII_CHAR_SEMICOLON 0x3B /* ';' */
#define ASCII_CHAR_LESS_THAN_SIGN 0x3C /* '<' */
#define ASCII_CHAR_EQUALS_SIGN 0x3D /* '=' */
#define ASCII_CHAR_GREATER_THAN_SIGN 0x3E /* '>' */
#define ASCII_CHAR_QUESTION_MARK 0x3F /* '\?' */
#define ASCII_CHAR_COMMERCIAL_AT 0x40 /* '@' */
#define ASCII_CHAR_AT_SIGN ASCII_CHAR_COMMERCIAL_AT
/*$PAGE*/
/* ------------- UPPERCASE LATIN ALPHABET ------------- */
#define ASCII_CHAR_LATIN_UPPER_A 0x41 /* 'A' */
#define ASCII_CHAR_LATIN_UPPER_B 0x42 /* 'B' */
#define ASCII_CHAR_LATIN_UPPER_C 0x43 /* 'C' */
#define ASCII_CHAR_LATIN_UPPER_D 0x44 /* 'D' */
#define ASCII_CHAR_LATIN_UPPER_E 0x45 /* 'E' */
#define ASCII_CHAR_LATIN_UPPER_F 0x46 /* 'F' */
#define ASCII_CHAR_LATIN_UPPER_G 0x47 /* 'G' */
#define ASCII_CHAR_LATIN_UPPER_H 0x48 /* 'H' */
#define ASCII_CHAR_LATIN_UPPER_I 0x49 /* 'I' */
#define ASCII_CHAR_LATIN_UPPER_J 0x4A /* 'J' */
#define ASCII_CHAR_LATIN_UPPER_K 0x4B /* 'K' */
#define ASCII_CHAR_LATIN_UPPER_L 0x4C /* 'L' */
#define ASCII_CHAR_LATIN_UPPER_M 0x4D /* 'M' */
#define ASCII_CHAR_LATIN_UPPER_N 0x4E /* 'N' */
#define ASCII_CHAR_LATIN_UPPER_O 0x4F /* 'O' */
#define ASCII_CHAR_LATIN_UPPER_P 0x50 /* 'P' */
#define ASCII_CHAR_LATIN_UPPER_Q 0x51 /* 'Q' */
#define ASCII_CHAR_LATIN_UPPER_R 0x52 /* 'R' */
#define ASCII_CHAR_LATIN_UPPER_S 0x53 /* 'S' */
#define ASCII_CHAR_LATIN_UPPER_T 0x54 /* 'T' */
#define ASCII_CHAR_LATIN_UPPER_U 0x55 /* 'U' */
#define ASCII_CHAR_LATIN_UPPER_V 0x56 /* 'V' */
#define ASCII_CHAR_LATIN_UPPER_W 0x57 /* 'W' */
#define ASCII_CHAR_LATIN_UPPER_X 0x58 /* 'X' */
#define ASCII_CHAR_LATIN_UPPER_Y 0x59 /* 'Y' */
#define ASCII_CHAR_LATIN_UPPER_Z 0x5A /* 'Z' */
/* ------------ ASCII PUNCTUATION & SYMBOLS ----------- */
#define ASCII_CHAR_LEFT_SQUARE_BRACKET 0x5B /* '[' */
#define ASCII_CHAR_REVERSE_SOLIDUS 0x5C /* '\\' */
#define ASCII_CHAR_RIGHT_SQUARE_BRACKET 0x5D /* ']' */
#define ASCII_CHAR_CIRCUMFLEX_ACCENT 0x5E /* '^' */
#define ASCII_CHAR_LOW_LINE 0x5F /* '_' */
#define ASCII_CHAR_GRAVE_ACCENT 0x60 /* '`' */
#define ASCII_CHAR_BRACKET_SQUARE_LEFT ASCII_CHAR_LEFT_SQUARE_BRACKET
#define ASCII_CHAR_BRACKET_SQUARE_RIGHT ASCII_CHAR_RIGHT_SQUARE_BRACKET
/* ------------- LOWERCASE LATIN ALPHABET ------------- */
#define ASCII_CHAR_LATIN_LOWER_A 0x61 /* 'a' */
#define ASCII_CHAR_LATIN_LOWER_B 0x62 /* 'b' */
#define ASCII_CHAR_LATIN_LOWER_C 0x63 /* 'c' */
#define ASCII_CHAR_LATIN_LOWER_D 0x64 /* 'd' */
#define ASCII_CHAR_LATIN_LOWER_E 0x65 /* 'e' */
#define ASCII_CHAR_LATIN_LOWER_F 0x66 /* 'f' */
#define ASCII_CHAR_LATIN_LOWER_G 0x67 /* 'g' */
#define ASCII_CHAR_LATIN_LOWER_H 0x68 /* 'h' */
#define ASCII_CHAR_LATIN_LOWER_I 0x69 /* 'i' */
#define ASCII_CHAR_LATIN_LOWER_J 0x6A /* 'j' */
#define ASCII_CHAR_LATIN_LOWER_K 0x6B /* 'k' */
#define ASCII_CHAR_LATIN_LOWER_L 0x6C /* 'l' */
#define ASCII_CHAR_LATIN_LOWER_M 0x6D /* 'm' */
#define ASCII_CHAR_LATIN_LOWER_N 0x6E /* 'n' */
#define ASCII_CHAR_LATIN_LOWER_O 0x6F /* 'o' */
#define ASCII_CHAR_LATIN_LOWER_P 0x70 /* 'p' */
#define ASCII_CHAR_LATIN_LOWER_Q 0x71 /* 'q' */
#define ASCII_CHAR_LATIN_LOWER_R 0x72 /* 'r' */
#define ASCII_CHAR_LATIN_LOWER_S 0x73 /* 's' */
#define ASCII_CHAR_LATIN_LOWER_T 0x74 /* 't' */
#define ASCII_CHAR_LATIN_LOWER_U 0x75 /* 'u' */
#define ASCII_CHAR_LATIN_LOWER_V 0x76 /* 'v' */
#define ASCII_CHAR_LATIN_LOWER_W 0x77 /* 'w' */
#define ASCII_CHAR_LATIN_LOWER_X 0x78 /* 'x' */
#define ASCII_CHAR_LATIN_LOWER_Y 0x79 /* 'y' */
#define ASCII_CHAR_LATIN_LOWER_Z 0x7A /* 'z' */
/* ------------ ASCII PUNCTUATION & SYMBOLS ----------- */
#define ASCII_CHAR_LEFT_CURLY_BRACKET 0x7B /* '{' */
#define ASCII_CHAR_VERTICAL_LINE 0x7C /* '|' */
#define ASCII_CHAR_RIGHT_CURLY_BRACKET 0x7D /* '}' */
#define ASCII_CHAR_TILDE 0x7E /* '~' */
#define ASCII_CHAR_BRACKET_CURLY_LEFT ASCII_CHAR_LEFT_CURLY_BRACKET
#define ASCII_CHAR_BRACKET_CURLY_RIGHT ASCII_CHAR_RIGHT_CURLY_BRACKET
/* ---------------- CONTROL CHARACTERS ---------------- */
#define ASCII_CHAR_DELETE 0x7F
#define ASCII_CHAR_DEL ASCII_CHAR_DELETE
/*$PAGE*/
/*
*********************************************************************************************************
* DATA TYPES
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* GLOBAL VARIABLES
*********************************************************************************************************
*/
/*$PAGE*/
/*
*********************************************************************************************************
* MACRO'S
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* ASCII CHARACTER CLASSIFICATION MACRO's
*
* Note(s) : (1) ISO/IEC 9899:TC2, Section 7.4.1.(1) states that "character classification functions ...
* return nonzero (true) if and only if the value of the argument 'c' conforms to ... the
* description of the function."
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* ASCII_IS_DIG()
*
* Description : Determine whether a character is a decimal-digit character.
*
* Argument(s) : c Character to examine.
*
* Return(s) : DEF_YES, if character is a decimal-digit character.
*
* DEF_NO, if character is NOT a decimal-digit character.
*
* Caller(s) : Application.
*
* Note(s) : (1) ISO/IEC 9899:TC2, Section 7.4.1.5.(2) states that "isdigit() ... tests for any
* decimal-digit character".
*********************************************************************************************************
*/
#define ASCII_IS_DIG(c) ((((c) >= ASCII_CHAR_DIG_ZERO) && ((c) <= ASCII_CHAR_DIG_NINE)) ? (DEF_YES) : (DEF_NO))
/*
*********************************************************************************************************
* ASCII_IS_DIG_OCT()
*
* Description : Determine whether a character is an octal-digit character.
*
* Argument(s) : c Character to examine.
*
* Return(s) : DEF_YES, if character is an octal-digit character.
*
* DEF_NO, if character is NOT an octal-digit character.
*
* Caller(s) : Application.
*
* Note(s) : none.
*********************************************************************************************************
*/
#define ASCII_IS_DIG_OCT(c) ((((c) >= ASCII_CHAR_DIG_ZERO) && ((c) <= ASCII_CHAR_DIG_SEVEN)) ? (DEF_YES) : (DEF_NO))
/*
*********************************************************************************************************
* ASCII_IS_DIG_HEX()
*
* Description : Determine whether a character is a hexadecimal-digit character.
*
* Argument(s) : c Character to examine.
*
* Return(s) : DEF_YES, if character is a hexadecimal-digit character.
*
* DEF_NO, if character is NOT a hexadecimal-digit character.
*
* Caller(s) : Application.
*
* Note(s) : (1) ISO/IEC 9899:TC2, Section 7.4.1.12.(2) states that "isxdigit() ... tests for any
* hexadecimal-digit character".
*********************************************************************************************************
*/
#define ASCII_IS_DIG_HEX(c) (((((c) >= ASCII_CHAR_DIG_ZERO ) && ((c) <= ASCII_CHAR_DIG_NINE )) || \
(((c) >= ASCII_CHAR_LATIN_UPPER_A) && ((c) <= ASCII_CHAR_LATIN_UPPER_F)) || \
(((c) >= ASCII_CHAR_LATIN_LOWER_A) && ((c) <= ASCII_CHAR_LATIN_LOWER_F))) ? (DEF_YES) : (DEF_NO))
/*$PAGE*/
/*
*********************************************************************************************************
* ASCII_IS_LOWER()
*
* Description : Determine whether a character is a lowercase alphabetic character.
*
* Argument(s) : c Character to examine.
*
* Return(s) : DEF_YES, if character is a lowercase alphabetic character.
*
* DEF_NO, if character is NOT a lowercase alphabetic character.
*
* Caller(s) : Application.
*
* Note(s) : (1) ISO/IEC 9899:TC2, Section 7.4.1.7.(2) states that "islower() returns true only for
* the lowercase letters".
*********************************************************************************************************
*/
#define ASCII_IS_LOWER(c) ((((c) >= ASCII_CHAR_LATIN_LOWER_A) && ((c) <= ASCII_CHAR_LATIN_LOWER_Z)) ? (DEF_YES) : (DEF_NO))
/*
*********************************************************************************************************
* ASCII_IS_UPPER()
*
* Description : Determine whether a character is an uppercase alphabetic character.
*
* Argument(s) : c Character to examine.
*
* Return(s) : DEF_YES, if character is an uppercase alphabetic character.
*
* DEF_NO, if character is NOT an uppercase alphabetic character.
*
* Caller(s) : Application.
*
* Note(s) : (1) ISO/IEC 9899:TC2, Section 7.4.1.11.(2) states that "isupper() returns true only for
* the uppercase letters".
*********************************************************************************************************
*/
#define ASCII_IS_UPPER(c) ((((c) >= ASCII_CHAR_LATIN_UPPER_A) && ((c) <= ASCII_CHAR_LATIN_UPPER_Z)) ? (DEF_YES) : (DEF_NO))
/*$PAGE*/
/*
*********************************************************************************************************
* ASCII_IS_ALPHA()
*
* Description : Determine whether a character is an alphabetic character.
*
* Argument(s) : c Character to examine.
*
* Return(s) : DEF_YES, if character is an alphabetic character.
*
* DEF_NO, if character is NOT an alphabetic character.
*
* Caller(s) : Application.
*
* Note(s) : (1) ISO/IEC 9899:TC2, Section 7.4.1.2.(2) states that "isalpha() returns true only for the
* characters for which isupper() or islower() is true".
*********************************************************************************************************
*/
#define ASCII_IS_ALPHA(c) ((((ASCII_IS_UPPER(c)) == DEF_YES) || \
((ASCII_IS_LOWER(c)) == DEF_YES)) ? (DEF_YES) : (DEF_NO))
/*
*********************************************************************************************************
* ASCII_IS_ALPHA_NUM()
*
* Description : Determine whether a character is an alphanumeric character.
*
* Argument(s) : c Character to examine.
*
* Return(s) : DEF_YES, if character is an alphanumeric character.
*
* DEF_NO, if character is NOT an alphanumeric character.
*
* Caller(s) : Application.
*
* Note(s) : (1) ISO/IEC 9899:TC2, Section 7.4.1.1.(2) states that "isalnum() ... tests for any character
* for which isalpha() or isdigit() is true".
*********************************************************************************************************
*/
#define ASCII_IS_ALPHA_NUM(c) ((((ASCII_IS_ALPHA(c)) == DEF_YES) || \
((ASCII_IS_DIG (c)) == DEF_YES)) ? (DEF_YES) : (DEF_NO))
/*$PAGE*/
/*
*********************************************************************************************************
* ASCII_IS_BLANK()
*
* Description : Determine whether a character is a standard blank character.
*
* Argument(s) : c Character to examine.
*
* Return(s) : DEF_YES, if character is a standard blank character.
*
* DEF_NO, if character is NOT a standard blank character.
*
* Caller(s) : Application.
*
* Note(s) : (1) (a) ISO/IEC 9899:TC2, Section 7.4.1.3.(2) states that "isblank() returns true only for
* the standard blank characters".
*
* (b) ISO/IEC 9899:TC2, Section 7.4.1.3.(2) defines "the standard blank characters" as
* the "space (' '), and horizontal tab ('\t')".
*********************************************************************************************************
*/
#define ASCII_IS_BLANK(c) ((((c) == ASCII_CHAR_SPACE) || ((c) == ASCII_CHAR_HT)) ? (DEF_YES) : (DEF_NO))
/*
*********************************************************************************************************
* ASCII_IS_SPACE()
*
* Description : Determine whether a character is a white-space character.
*
* Argument(s) : c Character to examine.
*
* Return(s) : DEF_YES, if character is a white-space character.
*
* DEF_NO, if character is NOT a white-space character.
*
* Caller(s) : Application.
*
* Note(s) : (1) (a) ISO/IEC 9899:TC2, Section 7.4.1.10.(2) states that "isspace() returns true only
* for the standard white-space characters".
*
* (b) ISO/IEC 9899:TC2, Section 7.4.1.10.(2) defines "the standard white-space characters"
* as the "space (' '), form feed ('\f'), new-line ('\n'), carriage return ('\r'),
* horizontal tab ('\t'), and vertical tab ('\v')".
*********************************************************************************************************
*/
#define ASCII_IS_SPACE(c) ((((c) == ASCII_CHAR_SPACE) || ((c) == ASCII_CHAR_CR) || \
((c) == ASCII_CHAR_LF ) || ((c) == ASCII_CHAR_FF) || \
((c) == ASCII_CHAR_HT ) || ((c) == ASCII_CHAR_VT)) ? (DEF_YES) : (DEF_NO))
/*$PAGE*/
/*
*********************************************************************************************************
* ASCII_IS_PRINT()
*
* Description : Determine whether a character is a printing character.
*
* Argument(s) : c Character to examine.
*
* Return(s) : DEF_YES, if character is a printing character.
*
* DEF_NO, if character is NOT a printing character.
*
* Caller(s) : Application.
*
* Note(s) : (1) (a) ISO/IEC 9899:TC2, Section 7.4.1.8.(2) states that "isprint() ... tests for any
* printing character including space (' ')".
*
* (b) ISO/IEC 9899:TC2, Section 7.4.(3), Note 169, states that in "the seven-bit US
* ASCII character set, the printing characters are those whose values lie from
* 0x20 (space) through 0x7E (tilde)".
*********************************************************************************************************
*/
#define ASCII_IS_PRINT(c) ((((c) >= ASCII_CHAR_SPACE) && ((c) <= ASCII_CHAR_TILDE)) ? (DEF_YES) : (DEF_NO))
/*
*********************************************************************************************************
* ASCII_IS_GRAPH()
*
* Description : Determine whether a character is any printing character except a space character.
*
* Argument(s) : c Character to examine.
*
* Return(s) : DEF_YES, if character is a graphic character.
*
* DEF_NO, if character is NOT a graphic character.
*
* Caller(s) : Application.
*
* Note(s) : (1) (a) ISO/IEC 9899:TC2, Section 7.4.1.6.(2) states that "isgraph() ... tests for any
* printing character except space (' ')".
*
* (b) ISO/IEC 9899:TC2, Section 7.4.(3), Note 169, states that in "the seven-bit US
* ASCII character set, the printing characters are those whose values lie from
* 0x20 (space) through 0x7E (tilde)".
*********************************************************************************************************
*/
#define ASCII_IS_GRAPH(c) ((((c) >= ASCII_CHAR_EXCLAMATION_MARK) && ((c) <= ASCII_CHAR_TILDE)) ? (DEF_YES) : (DEF_NO))
/*$PAGE*/
/*
*********************************************************************************************************
* ASCII_IS_PUNCT()
*
* Description : Determine whether a character is a punctuation character.
*
* Argument(s) : c Character to examine.
*
* Return(s) : DEF_YES, if character is a punctuation character.
*
* DEF_NO, if character is NOT a punctuation character.
*
* Caller(s) : Application.
*
* Note(s) : (1) ISO/IEC 9899:TC2, Section 7.4.1.9.(2) states that "ispunct() returns true for every
* printing character for which neither isspace() nor isalnum() is true".
*********************************************************************************************************
*/
#define ASCII_IS_PUNCT(c) ((((ASCII_IS_PRINT(c)) == DEF_YES) && \
((ASCII_IS_SPACE(c)) == DEF_NO ) && \
((ASCII_IS_ALPHA_NUM(c)) == DEF_NO )) ? (DEF_YES) : (DEF_NO))
/*
*********************************************************************************************************
* ASCII_IS_CTRL()
*
* Description : Determine whether a character is a control character.
*
* Argument(s) : c Character to examine.
*
* Return(s) : DEF_YES, if character is a control character.
*
* DEF_NO, if character is NOT a control character.
*
* Caller(s) : Application.
*
* Note(s) : (1) (a) ISO/IEC 9899:TC2, Section 7.4.1.4.(2) states that "iscntrl() ... tests for any
* control character".
*
* (b) ISO/IEC 9899:TC2, Section 7.4.(3), Note 169, states that in "the seven-bit US
* ASCII character set, ... the control characters are those whose values lie from
* 0 (NUL) through 0x1F (US), and the character 0x7F (DEL)".
*********************************************************************************************************
*/
#define ASCII_IS_CTRL(c) (((((CPU_INT08S)(c) >= ASCII_CHAR_NULL ) && ((c) <= ASCII_CHAR_IS1)) || \
((c) == ASCII_CHAR_DEL)) ? (DEF_YES) : (DEF_NO))
/*$PAGE*/
/*
*********************************************************************************************************
* ASCII CHARACTER CASE MAPPING MACRO's
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* ASCII_TO_LOWER()
*
* Description : Convert uppercase alphabetic character to its corresponding lowercase alphabetic character.
*
* Argument(s) : c Character to convert.
*
* Return(s) : Lowercase equivalent of 'c', if character 'c' is an uppercase character (see Note #1b1).
*
* Character 'c', otherwise (see Note #1b2).
*
* Caller(s) : Application.
*
* Note(s) : (1) (a) ISO/IEC 9899:TC2, Section 7.4.2.1.(2) states that "tolower() ... converts an
* uppercase letter to a corresponding lowercase letter".
*
* (b) ISO/IEC 9899:TC2, Section 7.4.2.1.(3) states that :
*
* (1) (A) "if the argument is a character for which isupper() is true and there are
* one or more corresponding characters ... for which islower() is true," ...
* (B) "tolower() ... returns one of the corresponding characters;" ...
*
* (2) "otherwise, the argument is returned unchanged."
*********************************************************************************************************
*/
#define ASCII_TO_LOWER(c) (((ASCII_IS_UPPER(c)) == DEF_YES) ? ((c) + (ASCII_CHAR_LATIN_LOWER_A - ASCII_CHAR_LATIN_UPPER_A)) : (c))
/*
*********************************************************************************************************
* ASCII_TO_UPPER()
*
* Description : Convert lowercase alphabetic character to its corresponding uppercase alphabetic character.
*
* Argument(s) : c Character to convert.
*
* Return(s) : Uppercase equivalent of 'c', if character 'c' is a lowercase character (see Note #1b1).
*
* Character 'c', otherwise (see Note #1b2).
*
* Caller(s) : Application.
*
* Note(s) : (1) (a) ISO/IEC 9899:TC2, Section 7.4.2.2.(2) states that "toupper() ... converts a
* lowercase letter to a corresponding uppercase letter".
*
* (b) ISO/IEC 9899:TC2, Section 7.4.2.2.(3) states that :
*
* (1) (A) "if the argument is a character for which islower() is true and there are
* one or more corresponding characters ... for which isupper() is true," ...
* (B) "toupper() ... returns one of the corresponding characters;" ...
*
* (2) "otherwise, the argument is returned unchanged."
*********************************************************************************************************
*/
#define ASCII_TO_UPPER(c) (((ASCII_IS_LOWER(c)) == DEF_YES) ? ((c) - (ASCII_CHAR_LATIN_LOWER_A - ASCII_CHAR_LATIN_UPPER_A)) : (c))
/*$PAGE*/
/*
*********************************************************************************************************
* FUNCTION PROTOTYPES
*********************************************************************************************************
*/
CPU_BOOLEAN ASCII_IsAlpha (CPU_CHAR c);
CPU_BOOLEAN ASCII_IsAlphaNum(CPU_CHAR c);
CPU_BOOLEAN ASCII_IsLower (CPU_CHAR c);
CPU_BOOLEAN ASCII_IsUpper (CPU_CHAR c);
CPU_BOOLEAN ASCII_IsDig (CPU_CHAR c);
CPU_BOOLEAN ASCII_IsDigOct (CPU_CHAR c);
CPU_BOOLEAN ASCII_IsDigHex (CPU_CHAR c);
CPU_BOOLEAN ASCII_IsBlank (CPU_CHAR c);
CPU_BOOLEAN ASCII_IsSpace (CPU_CHAR c);
CPU_BOOLEAN ASCII_IsPrint (CPU_CHAR c);
CPU_BOOLEAN ASCII_IsGraph (CPU_CHAR c);
CPU_BOOLEAN ASCII_IsPunct (CPU_CHAR c);
CPU_BOOLEAN ASCII_IsCtrl (CPU_CHAR c);
CPU_CHAR ASCII_ToLower (CPU_CHAR c);
CPU_CHAR ASCII_ToUpper (CPU_CHAR c);
CPU_BOOLEAN ASCII_Cmp (CPU_CHAR c1,
CPU_CHAR c2);
/*$PAGE*/
/*
*********************************************************************************************************
* CONFIGURATION ERRORS
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* MODULE END
*
* Note(s) : (1) See 'lib_ascii.h MODULE'.
*********************************************************************************************************
*/
#endif /* End of lib ascii module include. */

1323
UCOSIII/uC-LIB/lib_def.h Normal file

File diff suppressed because it is too large Load Diff

283
UCOSIII/uC-LIB/lib_math.c Normal file
View File

@@ -0,0 +1,283 @@
/*
*********************************************************************************************************
* uC/LIB
* CUSTOM LIBRARY MODULES
*
* (c) Copyright 2004-2012; Micrium, Inc.; Weston, FL
*
* All rights reserved. Protected by international copyright laws.
*
* uC/LIB is provided in source form to registered licensees ONLY. It is
* illegal to distribute this source code to any third party unless you receive
* written permission by an authorized Micrium representative. Knowledge of
* the source code may NOT be used to develop a similar product.
*
* Please help us continue to provide the Embedded community with the finest
* software available. Your honesty is greatly appreciated.
*
* You can contact us at www.micrium.com.
*********************************************************************************************************
*/
/*
*********************************************************************************************************
*
* MATHEMATIC OPERATIONS
*
* Filename : lib_math.c
* Version : V1.37.01
* Programmer(s) : SR
* ITJ
*********************************************************************************************************
* Note(s) : (1) NO compiler-supplied standard library functions are used in library or product software.
*
* (a) ALL standard library functions are implemented in the custom library modules :
*
* (1) \<Custom Library Directory>\lib_*.*
*
* (2) \<Custom Library Directory>\Ports\<cpu>\<compiler>\lib*_a.*
*
* where
* <Custom Library Directory> directory path for custom library software
* <cpu> directory name for specific processor (CPU)
* <compiler> directory name for specific compiler
*
* (b) Product-specific library functions are implemented in individual products.
*
*********************************************************************************************************
* Notice(s) : (1) The Institute of Electrical and Electronics Engineers and The Open Group, have given
* us permission to reprint portions of their documentation. Portions of this text are
* reprinted and reproduced in electronic form from the IEEE Std 1003.1, 2004 Edition,
* Standard for Information Technology -- Portable Operating System Interface (POSIX),
* The Open Group Base Specifications Issue 6, Copyright (C) 2001-2004 by the Institute
* of Electrical and Electronics Engineers, Inc and The Open Group. In the event of any
* discrepancy between these versions and the original IEEE and The Open Group Standard,
* the original IEEE and The Open Group Standard is the referee document. The original
* Standard can be obtained online at http://www.opengroup.org/unix/online.html.
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* INCLUDE FILES
*********************************************************************************************************
*/
#define MICRIUM_SOURCE
#define LIB_MATH_MODULE
#include <lib_math.h>
/*$PAGE*/
/*
*********************************************************************************************************
* LOCAL DEFINES
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* LOCAL CONSTANTS
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* LOCAL DATA TYPES
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* LOCAL TABLES
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* LOCAL GLOBAL VARIABLES
*********************************************************************************************************
*/
RAND_NBR Math_RandSeedCur; /* Cur rand nbr seed. */
/*
*********************************************************************************************************
* LOCAL FUNCTION PROTOTYPES
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* LOCAL CONFIGURATION ERRORS
*********************************************************************************************************
*/
/*$PAGE*/
/*
*********************************************************************************************************
* Math_Init()
*
* Description : (1) Initialize Mathematic Module :
*
* (a) Initialize random number seed value
*
*
* Argument(s) : none.
*
* Return(s) : none.
*
* Caller(s) : Application.
*
* Note(s) : (2) IEEE Std 1003.1, 2004 Edition, Section 'rand() : DESCRIPTION' states that "if rand()
* is called before any calls to srand() are made, the same sequence shall be generated
* as when srand() is first called with a seed value of 1".
*********************************************************************************************************
*/
void Math_Init (void)
{
Math_RandSetSeed((RAND_NBR)RAND_SEED_INIT_VAL); /* See Note #2. */
}
/*$PAGE*/
/*
*********************************************************************************************************
* Math_RandSetSeed()
*
* Description : Set the current pseudo-random number generator seed.
*
* Argument(s) : seed Initial (or current) value to set for the pseudo-random number sequence.
*
* Return(s) : none.
*
* Caller(s) : Application.
*
* Note(s) : (1) IEEE Std 1003.1, 2004 Edition, Section 'rand() : DESCRIPTION' states that "srand()
* ... uses the argument as a seed for a new sequence of pseudo-random numbers to be
* returned by subsequent calls to rand()".
*
* (2) 'Math_RandSeedCur' MUST always be accessed exclusively in critical sections.
*
* See also 'Math_Rand() Note #1b'.
*********************************************************************************************************
*/
void Math_RandSetSeed (RAND_NBR seed)
{
CPU_SR_ALLOC();
CPU_CRITICAL_ENTER();
Math_RandSeedCur = seed;
CPU_CRITICAL_EXIT();
}
/*$PAGE*/
/*
*********************************************************************************************************
* Math_Rand()
*
* Description : Calculate the next pseudo-random number.
*
* Argument(s) : none.
*
* Return(s) : Next pseudo-random number in the sequence after 'Math_RandSeedCur'.
*
* Caller(s) : Application.
*
* Note(s) : (1) (a) The pseudo-random number generator is implemented as a Linear Congruential
* Generator (LCG).
*
* (b) The pseudo-random number generated is in the range [0, RAND_LCG_PARAM_M].
*
* See also 'Math_RandSeed() Note #1'.
*
* (2) (a) IEEE Std 1003.1, 2004 Edition, Section 'rand() : DESCRIPTION' states that "rand()
* ... need not be reentrant ... [and] is not required to be thread-safe".
*
* (b) However, in order to implement Math_Rand() as re-entrant; 'Math_RandSeedCur' MUST
* always be accessed & updated exclusively in critical sections.
*
* See also 'Math_RandSeed() Note #2'.
*********************************************************************************************************
*/
RAND_NBR Math_Rand (void)
{
RAND_NBR seed;
RAND_NBR rand_nbr;
CPU_SR_ALLOC();
CPU_CRITICAL_ENTER();
seed = Math_RandSeedCur;
rand_nbr = Math_RandSeed(seed);
Math_RandSeedCur = rand_nbr;
CPU_CRITICAL_EXIT();
return (rand_nbr);
}
/*$PAGE*/
/*
*********************************************************************************************************
* Math_RandSeed()
*
* Description : Calculate the next pseudo-random number.
*
* Argument(s) : seed Initial (or current) value for the pseudo-random number sequence.
*
* Return(s) : Next pseudo-random number in the sequence after 'seed'.
*
* Caller(s) : Math_Rand(),
* Application.
*
* Note(s) : (1) (a) BSD/ANSI-C implements rand() as a Linear Congruential Generator (LCG) :
*
* (A) random_number = [(a * random_number ) + b] modulo m
* n + 1 n
*
* where
* (1) (a) random_number Next random number to generate
* n+1
* (b) random_number Previous random number generated
* n
*
* (2) a = RAND_LCG_PARAM_A LCG multiplier
* (3) b = RAND_LCG_PARAM_B LCG incrementor
* (4) m = RAND_LCG_PARAM_M + 1 LCG modulus
*
* (b) The pseudo-random number generated is in the range [0, RAND_LCG_PARAM_M].
*
See also 'lib_math.h RANDOM NUMBER DEFINES Note #1b'.
*
* (2) (a) IEEE Std 1003.1, 2004 Edition, Section 'rand() : DESCRIPTION' states that "rand()
* ... need not be reentrant ... [and] is not required to be thread-safe".
*
* (b) However, Math_RandSeed() is re-entrant since it calculates the next random number
* using ONLY local variables.
*********************************************************************************************************
*/
RAND_NBR Math_RandSeed (RAND_NBR seed)
{
RAND_NBR rand_nbr;
rand_nbr = (((RAND_NBR)RAND_LCG_PARAM_A * seed) + (RAND_NBR)RAND_LCG_PARAM_B) % ((RAND_NBR)RAND_LCG_PARAM_M + 1u);
return (rand_nbr);
}

230
UCOSIII/uC-LIB/lib_math.h Normal file
View File

@@ -0,0 +1,230 @@
/*
*********************************************************************************************************
* uC/LIB
* CUSTOM LIBRARY MODULES
*
* (c) Copyright 2004-2012; Micrium, Inc.; Weston, FL
*
* All rights reserved. Protected by international copyright laws.
*
* uC/LIB is provided in source form to registered licensees ONLY. It is
* illegal to distribute this source code to any third party unless you receive
* written permission by an authorized Micrium representative. Knowledge of
* the source code may NOT be used to develop a similar product.
*
* Please help us continue to provide the Embedded community with the finest
* software available. Your honesty is greatly appreciated.
*
* You can contact us at www.micrium.com.
*********************************************************************************************************
*/
/*
*********************************************************************************************************
*
* MATHEMATIC OPERATIONS
*
* Filename : lib_math.h
* Version : V1.37.01
* Programmer(s) : SR
* ITJ
*********************************************************************************************************
* Note(s) : (1) NO compiler-supplied standard library functions are used in library or product software.
*
* (a) ALL standard library functions are implemented in the custom library modules :
*
* (1) \<Custom Library Directory>\lib_*.*
*
* (2) \<Custom Library Directory>\Ports\<cpu>\<compiler>\lib*_a.*
*
* where
* <Custom Library Directory> directory path for custom library software
* <cpu> directory name for specific processor (CPU)
* <compiler> directory name for specific compiler
*
* (b) Product-specific library functions are implemented in individual products.
*
*********************************************************************************************************
* Notice(s) : (1) The Institute of Electrical and Electronics Engineers and The Open Group, have given
* us permission to reprint portions of their documentation. Portions of this text are
* reprinted and reproduced in electronic form from the IEEE Std 1003.1, 2004 Edition,
* Standard for Information Technology -- Portable Operating System Interface (POSIX),
* The Open Group Base Specifications Issue 6, Copyright (C) 2001-2004 by the Institute
* of Electrical and Electronics Engineers, Inc and The Open Group. In the event of any
* discrepancy between these versions and the original IEEE and The Open Group Standard,
* the original IEEE and The Open Group Standard is the referee document. The original
* Standard can be obtained online at http://www.opengroup.org/unix/online.html.
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* MODULE
*
* Note(s) : (1) This mathematics library header file is protected from multiple pre-processor inclusion
* through use of the mathematics library module present pre-processor macro definition.
*********************************************************************************************************
*/
#ifndef LIB_MATH_MODULE_PRESENT /* See Note #1. */
#define LIB_MATH_MODULE_PRESENT
/*$PAGE*/
/*
*********************************************************************************************************
* INCLUDE FILES
*
* Note(s) : (1) The custom library software files are located in the following directories :
*
* (a) \<Custom Library Directory>\lib_*.*
*
* where
* <Custom Library Directory> directory path for custom library software
*
* (2) CPU-configuration software files are located in the following directories :
*
* (a) \<CPU-Compiler Directory>\cpu_*.*
* (b) \<CPU-Compiler Directory>\<cpu>\<compiler>\cpu*.*
*
* where
* <CPU-Compiler Directory> directory path for common CPU-compiler software
* <cpu> directory name for specific processor (CPU)
* <compiler> directory name for specific compiler
*
* (3) Compiler MUST be configured to include as additional include path directories :
*
* (a) '\<Custom Library Directory>\' directory See Note #1a
*
* (b) (1) '\<CPU-Compiler Directory>\' directory See Note #2a
* (2) '\<CPU-Compiler Directory>\<cpu>\<compiler>\' directory See Note #2b
*
* (4) NO compiler-supplied standard library functions SHOULD be used.
*********************************************************************************************************
*/
#include <cpu.h>
#include <cpu_core.h>
#include <lib_def.h>
/*
*********************************************************************************************************
* EXTERNS
*********************************************************************************************************
*/
#ifdef LIB_MATH_MODULE
#define LIB_MATH_EXT
#else
#define LIB_MATH_EXT extern
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* DEFINES
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* RANDOM NUMBER DEFINES
*
* Note(s) : (1) (a) IEEE Std 1003.1, 2004 Edition, Section 'rand() : DESCRIPTION' states that "if rand()
* is called before any calls to srand() are made, the same sequence shall be generated
* as when srand() is first called with a seed value of 1".
*
* (b) (1) BSD/ANSI-C implements rand() as a Linear Congruential Generator (LCG) :
*
* (A) random_number = [(a * random_number ) + b] modulo m
* n + 1 n
*
* where
* (1) (a) random_number Next random number to generate
* n+1
* (b) random_number Previous random number generated
* n
* (c) random_number Initial random number seed
* 0 See also Note #1a
*
* (2) a = 1103515245 LCG multiplier
* (3) b = 12345 LCG incrementor
* (4) m = RAND_MAX + 1 LCG modulus See also Note #1b2
*
* (2) (A) IEEE Std 1003.1, 2004 Edition, Section 'rand() : DESCRIPTION' states that
* "rand() ... shall compute a sequence of pseudo-random integers in the range
* [0, {RAND_MAX}] with a period of at least 2^32".
*
* (B) However, BSD/ANSI-C 'stdlib.h' defines "RAND_MAX" as "0x7fffffff", or 2^31;
* which therefore limits the range AND period to no more than 2^31.
*********************************************************************************************************
*/
#define RAND_SEED_INIT_VAL 1u /* See Note #1a. */
#define RAND_LCG_PARAM_M 0x7FFFFFFFu /* See Note #1b2B. */
#define RAND_LCG_PARAM_A 1103515245u /* See Note #1b1A2. */
#define RAND_LCG_PARAM_B 12345u /* See Note #1b1A3. */
/*$PAGE*/
/*
*********************************************************************************************************
* DATA TYPES
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* RANDOM NUMBER DATA TYPE
*********************************************************************************************************
*/
typedef CPU_INT32U RAND_NBR;
/*
*********************************************************************************************************
* GLOBAL VARIABLES
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* FUNCTION PROTOTYPES
*********************************************************************************************************
*/
void Math_Init (void);
/* ------------------ RAND NBR FNCTS ------------------ */
void Math_RandSetSeed(RAND_NBR seed);
RAND_NBR Math_Rand (void);
RAND_NBR Math_RandSeed (RAND_NBR seed);
/*$PAGE*/
/*
*********************************************************************************************************
* CONFIGURATION ERRORS
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* MODULE END
*
* Note(s) : (1) See 'lib_math.h MODULE'.
*********************************************************************************************************
*/
#endif /* End of lib math module include. */

2442
UCOSIII/uC-LIB/lib_mem.c Normal file

File diff suppressed because it is too large Load Diff

1336
UCOSIII/uC-LIB/lib_mem.h Normal file

File diff suppressed because it is too large Load Diff

4070
UCOSIII/uC-LIB/lib_str.c Normal file

File diff suppressed because it is too large Load Diff

433
UCOSIII/uC-LIB/lib_str.h Normal file
View File

@@ -0,0 +1,433 @@
/*
*********************************************************************************************************
* uC/LIB
* CUSTOM LIBRARY MODULES
*
* (c) Copyright 2004-2012; Micrium, Inc.; Weston, FL
*
* All rights reserved. Protected by international copyright laws.
*
* uC/LIB is provided in source form to registered licensees ONLY. It is
* illegal to distribute this source code to any third party unless you receive
* written permission by an authorized Micrium representative. Knowledge of
* the source code may NOT be used to develop a similar product.
*
* Please help us continue to provide the Embedded community with the finest
* software available. Your honesty is greatly appreciated.
*
* You can contact us at www.micrium.com.
*********************************************************************************************************
*/
/*
*********************************************************************************************************
*
* ASCII STRING MANAGEMENT
*
* Filename : lib_str.h
* Version : V1.37.01
* Programmer(s) : ITJ
* JDH
*********************************************************************************************************
* Note(s) : (1) NO compiler-supplied standard library functions are used in library or product software.
*
* (a) ALL standard library functions are implemented in the custom library modules :
*
* (1) \<Custom Library Directory>\lib_*.*
*
* (2) \<Custom Library Directory>\Ports\<cpu>\<compiler>\lib*_a.*
*
* where
* <Custom Library Directory> directory path for custom library software
* <cpu> directory name for specific processor (CPU)
* <compiler> directory name for specific compiler
*
* (b) Product-specific library functions are implemented in individual products.
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* MODULE
*
* Note(s) : (1) This string library header file is protected from multiple pre-processor inclusion through
* use of the string library module present pre-processor macro definition.
*********************************************************************************************************
*/
#ifndef LIB_STR_MODULE_PRESENT /* See Note #1. */
#define LIB_STR_MODULE_PRESENT
/*$PAGE*/
/*
*********************************************************************************************************
* ASCII STRING CONFIGURATION DEFINES
*
* Note(s) : (1) Some ASCII string configuration #define's MUST be available PRIOR to including any
* application configuration (see 'INCLUDE FILES Note #1a').
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* STRING FLOATING POINT DEFINES
*
* Note(s) : (1) (a) (1) The maximum accuracy for 32-bit floating-point numbers :
*
*
* Maximum Accuracy log [Internal-Base ^ (Number-Internal-Base-Digits)]
* 32-bit Floating-point Number = -----------------------------------------------------
* log [External-Base]
*
* log [2 ^ 24]
* = --------------
* log [10]
*
* < 7.225 Base-10 Digits
*
* where
* Internal-Base Internal number base of floating-
* point numbers (i.e. 2)
* External-Base External number base of floating-
* point numbers (i.e. 10)
* Number-Internal-Base-Digits Number of internal number base
* significant digits (i.e. 24)
*
* (2) Also, since some 32-bit floating-point calculations are converted to 32-bit
* unsigned numbers, the maximum accuracy is limited to the maximum accuracy
* for 32-bit unsigned numbers of 9 digits.
*
* (b) Some CPUs' &/or compilers' floating-point implementations MAY further reduce the
* maximum accuracy.
*********************************************************************************************************
*/
#define LIB_STR_FP_MAX_NBR_DIG_SIG_MIN 1u
#define LIB_STR_FP_MAX_NBR_DIG_SIG_MAX 9u /* See Note #1a2. */
#define LIB_STR_FP_MAX_NBR_DIG_SIG_DFLT 7u /* See Note #1a1. */
/*$PAGE*/
/*
*********************************************************************************************************
* INCLUDE FILES
*
* Note(s) : (1) The custom library software files are located in the following directories :
*
* (a) \<Your Product Application>\lib_cfg.h
*
* (b) \<Custom Library Directory>\lib_*.*
*
* where
* <Your Product Application> directory path for Your Product's Application
* <Custom Library Directory> directory path for custom library software
*
* (2) CPU-configuration software files are located in the following directories :
*
* (a) \<CPU-Compiler Directory>\cpu_*.*
* (b) \<CPU-Compiler Directory>\<cpu>\<compiler>\cpu*.*
*
* where
* <CPU-Compiler Directory> directory path for common CPU-compiler software
* <cpu> directory name for specific processor (CPU)
* <compiler> directory name for specific compiler
*
* (3) Compiler MUST be configured to include as additional include path directories :
*
* (a) '\<Your Product Application>\' directory See Note #1a
*
* (b) '\<Custom Library Directory>\' directory See Note #1b
*
* (c) (1) '\<CPU-Compiler Directory>\' directory See Note #2a
* (2) '\<CPU-Compiler Directory>\<cpu>\<compiler>\' directory See Note #2b
*
* (4) NO compiler-supplied standard library functions SHOULD be used.
*
* #### The reference to standard library header files SHOULD be removed once all custom
* library functions are implemented WITHOUT reference to ANY standard library function(s).
*
* See also 'STANDARD LIBRARY MACRO'S Note #1'.
*********************************************************************************************************
*/
#include <cpu.h>
#include <lib_def.h>
#include <lib_ascii.h>
#include <lib_cfg.h>
#if 0 /* See Note #4. */
#include <stdio.h>
#endif
/*
*********************************************************************************************************
* EXTERNS
*********************************************************************************************************
*/
#ifdef LIB_STR_MODULE
#define LIB_STR_EXT
#else
#define LIB_STR_EXT extern
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* DEFAULT CONFIGURATION
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* STRING FLOATING POINT CONFIGURATION
*
* Note(s) : (1) Configure LIB_STR_CFG_FP_EN to enable/disable floating point string function(s).
*
* (2) Configure LIB_STR_CFG_FP_MAX_NBR_DIG_SIG to configure the maximum number of significant
* digits to calculate &/or display for floating point string function(s).
*
* See also 'STRING FLOATING POINT DEFINES Note #1'.
*********************************************************************************************************
*/
/* Configure floating point feature(s) [see Note #1] : */
#ifndef LIB_STR_CFG_FP_EN
#define LIB_STR_CFG_FP_EN DEF_DISABLED
/* DEF_DISABLED Floating point functions DISABLED */
/* DEF_ENABLED Floating point functions ENABLED */
#endif
/* Configure floating point feature(s)' number of ... */
/* ... significant digits (see Note #2). */
#ifndef LIB_STR_CFG_FP_MAX_NBR_DIG_SIG
#define LIB_STR_CFG_FP_MAX_NBR_DIG_SIG LIB_STR_FP_MAX_NBR_DIG_SIG_DFLT
#endif
/*
*********************************************************************************************************
* DEFINES
*********************************************************************************************************
*/
#define STR_CR_LF "\r\n"
#define STR_LF_CR "\n\r"
#define STR_NEW_LINE STR_CR_LF
#define STR_PARENT_PATH ".."
#define STR_CR_LF_LEN (sizeof(STR_CR_LF) - 1)
#define STR_LF_CR_LEN (sizeof(STR_LF_CR) - 1)
#define STR_NEW_LINE_LEN (sizeof(STR_NEW_LINE) - 1)
#define STR_PARENT_PATH_LEN (sizeof(STR_PARENT_PATH) - 1)
/*
*********************************************************************************************************
* DATA TYPES
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* GLOBAL VARIABLES
*********************************************************************************************************
*/
/*$PAGE*/
/*
*********************************************************************************************************
* MACRO'S
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* STANDARD LIBRARY MACRO'S
*
* Note(s) : (1) NO compiler-supplied standard library functions SHOULD be used.
*
* #### The reference to standard memory functions SHOULD be removed once all custom library
* functions are implemented WITHOUT reference to ANY standard library function(s).
*
* See also 'INCLUDE FILES Note #3'.
*********************************************************************************************************
*/
/* See Note #1. */
#define Str_FmtPrint snprintf
#define Str_FmtScan sscanf
/*$PAGE*/
/*
*********************************************************************************************************
* FUNCTION PROTOTYPES
*********************************************************************************************************
*/
/* ------------------ STR LEN FNCTS ------------------ */
CPU_SIZE_T Str_Len (const CPU_CHAR *pstr);
CPU_SIZE_T Str_Len_N (const CPU_CHAR *pstr,
CPU_SIZE_T len_max);
/* ------------------ STR COPY FNCTS ------------------ */
CPU_CHAR *Str_Copy ( CPU_CHAR *pstr_dest,
const CPU_CHAR *pstr_src);
CPU_CHAR *Str_Copy_N ( CPU_CHAR *pstr_dest,
const CPU_CHAR *pstr_src,
CPU_SIZE_T len_max);
CPU_CHAR *Str_Cat ( CPU_CHAR *pstr_dest,
const CPU_CHAR *pstr_cat);
CPU_CHAR *Str_Cat_N ( CPU_CHAR *pstr_dest,
const CPU_CHAR *pstr_cat,
CPU_SIZE_T len_max);
/* ------------------ STR CMP FNCTS ------------------ */
CPU_INT16S Str_Cmp (const CPU_CHAR *p1_str,
const CPU_CHAR *p2_str);
CPU_INT16S Str_Cmp_N (const CPU_CHAR *p1_str,
const CPU_CHAR *p2_str,
CPU_SIZE_T len_max);
CPU_INT16S Str_CmpIgnoreCase (const CPU_CHAR *p1_str,
const CPU_CHAR *p2_str);
CPU_INT16S Str_CmpIgnoreCase_N(const CPU_CHAR *p1_str,
const CPU_CHAR *p2_str,
CPU_SIZE_T len_max);
/* ------------------ STR SRCH FNCTS ------------------ */
CPU_CHAR *Str_Char (const CPU_CHAR *pstr,
CPU_CHAR srch_char);
CPU_CHAR *Str_Char_N (const CPU_CHAR *pstr,
CPU_SIZE_T len_max,
CPU_CHAR srch_char);
CPU_CHAR *Str_Char_Last (const CPU_CHAR *pstr,
CPU_CHAR srch_char);
CPU_CHAR *Str_Char_Last_N (const CPU_CHAR *pstr,
CPU_SIZE_T len_max,
CPU_CHAR srch_char);
CPU_CHAR *Str_Char_Replace ( CPU_CHAR *pstr,
CPU_CHAR char_srch,
CPU_CHAR char_replace);
CPU_CHAR *Str_Char_Replace_N ( CPU_CHAR *pstr,
CPU_CHAR char_srch,
CPU_CHAR char_replace,
CPU_SIZE_T len_max);
CPU_CHAR *Str_Str (const CPU_CHAR *pstr,
const CPU_CHAR *pstr_srch);
CPU_CHAR *Str_Str_N (const CPU_CHAR *pstr,
const CPU_CHAR *pstr_srch,
CPU_SIZE_T len_max);
/*$PAGE*/
/* ------------------ STR FMT FNCTS ------------------ */
CPU_CHAR *Str_FmtNbr_Int32U ( CPU_INT32U nbr,
CPU_INT08U nbr_dig,
CPU_INT08U nbr_base,
CPU_CHAR lead_char,
CPU_BOOLEAN lower_case,
CPU_BOOLEAN nul,
CPU_CHAR *pstr);
CPU_CHAR *Str_FmtNbr_Int32S ( CPU_INT32S nbr,
CPU_INT08U nbr_dig,
CPU_INT08U nbr_base,
CPU_CHAR lead_char,
CPU_BOOLEAN lower_case,
CPU_BOOLEAN nul,
CPU_CHAR *pstr);
#if (LIB_STR_CFG_FP_EN == DEF_ENABLED)
CPU_CHAR *Str_FmtNbr_32 ( CPU_FP32 nbr,
CPU_INT08U nbr_dig,
CPU_INT08U nbr_dp,
CPU_CHAR lead_char,
CPU_BOOLEAN nul,
CPU_CHAR *pstr);
#endif
/* ----------------- STR PARSE FNCTS ------------------ */
CPU_INT32U Str_ParseNbr_Int32U(const CPU_CHAR *pstr,
CPU_CHAR **pstr_next,
CPU_INT08U nbr_base);
CPU_INT32S Str_ParseNbr_Int32S(const CPU_CHAR *pstr,
CPU_CHAR **pstr_next,
CPU_INT08U nbr_base);
/*$PAGE*/
/*
*********************************************************************************************************
* CONFIGURATION ERRORS
*********************************************************************************************************
*/
#ifndef LIB_STR_CFG_FP_EN
#error "LIB_STR_CFG_FP_EN not #define'd in 'lib_cfg.h'"
#error " [MUST be DEF_DISABLED] "
#error " [ || DEF_ENABLED ] "
#elif ((LIB_STR_CFG_FP_EN != DEF_DISABLED) && \
(LIB_STR_CFG_FP_EN != DEF_ENABLED ))
#error "LIB_STR_CFG_FP_EN illegally #define'd in 'lib_cfg.h'"
#error " [MUST be DEF_DISABLED] "
#error " [ || DEF_ENABLED ] "
#elif (LIB_STR_CFG_FP_EN == DEF_ENABLED)
#ifndef LIB_STR_CFG_FP_MAX_NBR_DIG_SIG
#error "LIB_STR_CFG_FP_MAX_NBR_DIG_SIG not #define'd in 'lib_cfg.h' "
#error " [MUST be >= LIB_STR_FP_MAX_NBR_DIG_SIG_MIN]"
#error " [ && <= LIB_STR_FP_MAX_NBR_DIG_SIG_MAX]"
#elif (DEF_CHK_VAL(LIB_STR_CFG_FP_MAX_NBR_DIG_SIG, \
LIB_STR_FP_MAX_NBR_DIG_SIG_MIN, \
LIB_STR_FP_MAX_NBR_DIG_SIG_MAX) != DEF_OK)
#error "LIB_STR_CFG_FP_MAX_NBR_DIG_SIG illegally #define'd in 'lib_cfg.h' "
#error " [MUST be >= LIB_STR_FP_MAX_NBR_DIG_SIG_MIN]"
#error " [ && <= LIB_STR_FP_MAX_NBR_DIG_SIG_MAX]"
#endif
#endif
/*
*********************************************************************************************************
* MODULE END
*
* Note(s) : (1) See 'lib_str.h MODULE'.
*********************************************************************************************************
*/
#endif /* End of lib str module include. */

View File

@@ -0,0 +1,139 @@
/*
*********************************************************************************************************
* uC/OS-III
* The Real-Time Kernel
*
*
* (c) Copyright 2009-2010; Micrium, Inc.; Weston, FL
* All rights reserved. Protected by international copyright laws.
*
* ARM Cortex-M3 Port
*
* File : OS_CPU.H
* Version : V3.01.2
* By : JJL
*
* LICENSING TERMS:
* ---------------
* uC/OS-III is provided in source form to registered licensees ONLY. It is
* illegal to distribute this source code to any third party unless you receive
* written permission by an authorized Micrium representative. Knowledge of
* the source code may NOT be used to develop a similar product.
*
* Please help us continue to provide the Embedded community with the finest
* software available. Your honesty is greatly appreciated.
*
* You can contact us at www.micrium.com.
*
* For : ARMv7M Cortex-M3
* Mode : Thumb2
* Toolchain : GNU C Compiler
*********************************************************************************************************
*/
#ifndef OS_CPU_H
#define OS_CPU_H
#ifdef OS_CPU_GLOBALS
#define OS_CPU_EXT
#else
#define OS_CPU_EXT extern
#endif
/*
*********************************************************************************************************
* MACROS
*********************************************************************************************************
*/
#ifndef NVIC_INT_CTRL
#define NVIC_INT_CTRL *((CPU_REG32 *)0xE000ED04)
#endif
#ifndef NVIC_PENDSVSET
#define NVIC_PENDSVSET 0x10000000
#endif
#define OS_TASK_SW() NVIC_INT_CTRL = NVIC_PENDSVSET
#define OSIntCtxSw() NVIC_INT_CTRL = NVIC_PENDSVSET
/*
*********************************************************************************************************
* TIMESTAMP CONFIGURATION
*
* Note(s) : (1) OS_TS_GET() is generally defined as CPU_TS_Get32() to allow CPU timestamp timer to be of
* any data type size.
*
* (2) For architectures that provide 32-bit or higher precision free running counters
* (i.e. cycle count registers):
*
* (a) OS_TS_GET() may be defined as CPU_TS_TmrRd() to improve performance when retrieving
* the timestamp.
*
* (b) CPU_TS_TmrRd() MUST be configured to be greater or equal to 32-bits to avoid
* truncation of TS.
*********************************************************************************************************
*/
#if OS_CFG_TS_EN == 1u
#define OS_TS_GET() (CPU_TS)CPU_TS_TmrRd() /* See Note #2a. */
#else
#define OS_TS_GET() (CPU_TS)0u
#endif
#if (CPU_CFG_TS_32_EN == DEF_ENABLED) && \
(CPU_CFG_TS_TMR_SIZE < CPU_WORD_SIZE_32)
/* CPU_CFG_TS_TMR_SIZE MUST be >= 32-bit (see Note #2b). */
#error "cpu_cfg.h, CPU_CFG_TS_TMR_SIZE MUST be >= CPU_WORD_SIZE_32"
#endif
/*
*********************************************************************************************************
* OS TICK INTERRUPT PRIORITY CONFIGURATION
*
* Note(s) : (1) For systems that don't need any high, real-time priority interrupts; the tick interrupt
* should be configured as the highest priority interrupt but won't adversely affect system
* operations.
*
* (2) For systems that need one or more high, real-time interrupts; these should be configured
* higher than the tick interrupt which MAY delay execution of the tick interrupt.
*
* (a) If the higher priority interrupts do NOT continually consume CPU cycles but only
* occasionally delay tick interrupts, then the real-time interrupts can successfully
* handle their intermittent/periodic events with the system not losing tick interrupts
* but only increasing the jitter.
*
* (b) If the higher priority interrupts consume enough CPU cycles to continually delay the
* tick interrupt, then the CPU/system is most likely over-burdened & can't be expected
* to handle all its interrupts/tasks. The system time reference gets compromised as a
* result of losing tick interrupts.
*********************************************************************************************************
*/
#define OS_CPU_CFG_SYSTICK_PRIO 0u
/*
*********************************************************************************************************
* GLOBAL VARIABLES
*********************************************************************************************************
*/
OS_CPU_EXT CPU_STK *OS_CPU_ExceptStkBase;
/*
*********************************************************************************************************
* FUNCTION PROTOTYPES
*********************************************************************************************************
*/
void OSStartHighRdy (void);
void OS_CPU_PendSVHandler (void);
void OS_CPU_SysTickHandler(void);
void OS_CPU_SysTickInit (CPU_INT32U cnts);
#endif

View File

@@ -0,0 +1,170 @@
@
@********************************************************************************************************
@ uC/OS-III
@ The Real-Time Kernel
@
@
@ (c) Copyright 2009-2011; Micrium Inc.; Weston, FL
@ All rights reserved. Protected by international copyright laws.
@
@ ARM Cortex-M3 Port
@
@ File : OS_CPU_A.ASM
@ Version : V3.01.2
@ By : JJL
@ FT
@
@ For : ARMv7M Cortex-M3
@ Mode : Thumb2
@ Toolchain : GNU C Compiler
@********************************************************************************************************
@
@********************************************************************************************************
@ PUBLIC FUNCTIONS
@********************************************************************************************************
.extern OSRunning @ External references.
.extern OSPrioCur
.extern OSPrioHighRdy
.extern OSTCBCurPtr
.extern OSTCBHighRdyPtr
.extern OSIntExit
.extern OSTaskSwHook
.extern OS_CPU_ExceptStkBase
.global OSStartHighRdy @ Functions declared in this file.
.global OS_CPU_PendSVHandler
@********************************************************************************************************
@ EQUATES
@********************************************************************************************************
.equ NVIC_INT_CTRL, 0xE000ED04 @ Interrupt control state register.
.equ NVIC_SYSPRI14, 0xE000ED22 @ System priority register (priority 14).
.equ NVIC_PENDSV_PRI, 0xFF @ PendSV priority value (lowest).
.equ NVIC_PENDSVSET, 0x10000000 @ Value to trigger PendSV exception.
@********************************************************************************************************
@ CODE GENERATION DIRECTIVES
@********************************************************************************************************
.text
.align 2
.thumb
.syntax unified
@********************************************************************************************************
@ START MULTITASKING
@ void OSStartHighRdy(void)
@
@ Note(s) : 1) This function triggers a PendSV exception (essentially, causes a context switch) to cause
@ the first task to start.
@
@ 2) OSStartHighRdy() MUST:
@ a) Setup PendSV exception priority to lowest;
@ b) Set initial PSP to 0, to tell context switcher this is first run;
@ c) Set the main stack to OS_CPU_ExceptStkBase
@ d) Trigger PendSV exception;
@ e) Enable interrupts (tasks will run with interrupts enabled).
@********************************************************************************************************
.thumb_func
OSStartHighRdy:
LDR R0, =NVIC_SYSPRI14 @ Set the PendSV exception priority
LDR R1, =NVIC_PENDSV_PRI
STRB R1, [R0]
MOVS R0, #0 @ Set the PSP to 0 for initial context switch call
MSR PSP, R0
LDR R0, =OS_CPU_ExceptStkBase @ Initialize the MSP to the OS_CPU_ExceptStkBase
LDR R1, [R0]
MSR MSP, R1
LDR R0, =NVIC_INT_CTRL @ Trigger the PendSV exception (causes context switch)
LDR R1, =NVIC_PENDSVSET
STR R1, [R0]
CPSIE I @ Enable interrupts at processor level
OSStartHang:
B OSStartHang @ Should never get here
@********************************************************************************************************
@ HANDLE PendSV EXCEPTION
@ void OS_CPU_PendSVHandler(void)
@
@ Note(s) : 1) PendSV is used to cause a context switch. This is a recommended method for performing
@ context switches with Cortex-M3. This is because the Cortex-M3 auto-saves half of the
@ processor context on any exception, and restores same on return from exception. So only
@ saving of R4-R11 is required and fixing up the stack pointers. Using the PendSV exception
@ this way means that context saving and restoring is identical whether it is initiated from
@ a thread or occurs due to an interrupt or exception.
@
@ 2) Pseudo-code is:
@ a) Get the process SP, if 0 then skip (goto d) the saving part (first context switch);
@ b) Save remaining regs r4-r11 on process stack;
@ c) Save the process SP in its TCB, OSTCBCurPtr->OSTCBStkPtr = SP;
@ d) Call OSTaskSwHook();
@ e) Get current high priority, OSPrioCur = OSPrioHighRdy;
@ f) Get current ready thread TCB, OSTCBCurPtr = OSTCBHighRdyPtr;
@ g) Get new process SP from TCB, SP = OSTCBHighRdyPtr->OSTCBStkPtr;
@ h) Restore R4-R11 from new process stack;
@ i) Perform exception return which will restore remaining context.
@
@ 3) On entry into PendSV handler:
@ a) The following have been saved on the process stack (by processor):
@ xPSR, PC, LR, R12, R0-R3
@ b) Processor mode is switched to Handler mode (from Thread mode)
@ c) Stack is Main stack (switched from Process stack)
@ d) OSTCBCurPtr points to the OS_TCB of the task to suspend
@ OSTCBHighRdyPtr points to the OS_TCB of the task to resume
@
@ 4) Since PendSV is set to lowest priority in the system (by OSStartHighRdy() above), we
@ know that it will only be run when no other exception or interrupt is active, and
@ therefore safe to assume that context being switched out was using the process stack (PSP).
@********************************************************************************************************
.thumb_func
OS_CPU_PendSVHandler:
CPSID I @ Prevent interruption during context switch
MRS R0, PSP @ PSP is process stack pointer
CBZ R0, OS_CPU_PendSVHandler_nosave @ Skip register save the first time
SUBS R0, R0, #0x20 @ Save remaining regs r4-11 on process stack
STM R0, {R4-R11}
LDR R1, =OSTCBCurPtr @ OSTCBCurPtr->OSTCBStkPtr = SP;
LDR R1, [R1]
STR R0, [R1] @ R0 is SP of process being switched out
@ At this point, entire context of process has been saved
OS_CPU_PendSVHandler_nosave:
PUSH {R14} @ Save LR exc_return value
LDR R0, =OSTaskSwHook @ OSTaskSwHook();
BLX R0
POP {R14}
LDR R0, =OSPrioCur @ OSPrioCur = OSPrioHighRdy;
LDR R1, =OSPrioHighRdy
LDRB R2, [R1]
STRB R2, [R0]
LDR R0, =OSTCBCurPtr @ OSTCBCurPtr = OSTCBHighRdyPtr;
LDR R1, =OSTCBHighRdyPtr
LDR R2, [R1]
STR R2, [R0]
LDR R0, [R2] @ R0 is new process SP; SP = OSTCBHighRdyPtr->StkPtr;
LDM R0, {R4-R11} @ Restore r4-11 from new process stack
ADDS R0, R0, #0x20
MSR PSP, R0 @ Load PSP with new process SP
ORR LR, LR, #0x04 @ Ensure exception return uses process stack
CPSIE I
BX LR @ Exception return will restore remaining context
.end

View File

@@ -0,0 +1,411 @@
/*
*********************************************************************************************************
* uC/OS-III
* The Real-Time Kernel
*
*
* (c) Copyright 2009-2010; Micrium, Inc.; Weston, FL
* All rights reserved. Protected by international copyright laws.
*
* ARM Cortex-M3 Port
*
* File : OS_CPU_C.C
* Version : V3.01.2
* By : JJL
* FT
*
* LICENSING TERMS:
* ---------------
* uC/OS-III is provided in source form to registered licensees ONLY. It is
* illegal to distribute this source code to any third party unless you receive
* written permission by an authorized Micrium representative. Knowledge of
* the source code may NOT be used to develop a similar product.
*
* Please help us continue to provide the Embedded community with the finest
* software available. Your honesty is greatly appreciated.
*
* You can contact us at www.micrium.com.
*
* For : ARMv7M Cortex-M3
* Mode : Thumb2
* Toolchain : GNU C Compiler
*********************************************************************************************************
*/
#define OS_CPU_GLOBALS
#ifdef VSC_INCLUDE_SOURCE_FILE_NAMES
const CPU_CHAR *os_cpu_c__c = "$Id: $";
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* INCLUDE FILES
*********************************************************************************************************
*/
#include <os.h>
/*
*********************************************************************************************************
* IDLE TASK HOOK
*
* Description: This function is called by the idle task. This hook has been added to allow you to do
* such things as STOP the CPU to conserve power.
*
* Arguments : None.
*
* Note(s) : None.
*********************************************************************************************************
*/
void OSIdleTaskHook (void)
{
#if OS_CFG_APP_HOOKS_EN > 0u
if (OS_AppIdleTaskHookPtr != (OS_APP_HOOK_VOID)0) {
(*OS_AppIdleTaskHookPtr)();
}
#endif
}
/*$PAGE*/
/*
*********************************************************************************************************
* OS INITIALIZATION HOOK
*
* Description: This function is called by OSInit() at the beginning of OSInit().
*
* Arguments : None.
*
* Note(s) : None.
*********************************************************************************************************
*/
void OSInitHook (void)
{
CPU_STK_SIZE i;
CPU_STK *p_stk;
p_stk = OSCfg_ISRStkBasePtr; /* Clear the ISR stack */
for (i = 0u; i < OSCfg_ISRStkSize; i++) {
*p_stk++ = (CPU_STK)0u;
}
OS_CPU_ExceptStkBase = (CPU_STK *)(OSCfg_ISRStkBasePtr + OSCfg_ISRStkSize - 1u);
}
/*$PAGE*/
/*
*********************************************************************************************************
* STATISTIC TASK HOOK
*
* Description: This function is called every second by uC/OS-III's statistics task. This allows your
* application to add functionality to the statistics task.
*
* Arguments : None.
*
* Note(s) : None.
*********************************************************************************************************
*/
void OSStatTaskHook (void)
{
#if OS_CFG_APP_HOOKS_EN > 0u
if (OS_AppStatTaskHookPtr != (OS_APP_HOOK_VOID)0) {
(*OS_AppStatTaskHookPtr)();
}
#endif
}
/*$PAGE*/
/*
*********************************************************************************************************
* TASK CREATION HOOK
*
* Description: This function is called when a task is created.
*
* Arguments : p_tcb Pointer to the task control block of the task being created.
*
* Note(s) : None.
*********************************************************************************************************
*/
void OSTaskCreateHook (OS_TCB *p_tcb)
{
#if OS_CFG_APP_HOOKS_EN > 0u
if (OS_AppTaskCreateHookPtr != (OS_APP_HOOK_TCB)0) {
(*OS_AppTaskCreateHookPtr)(p_tcb);
}
#else
(void)p_tcb; /* Prevent compiler warning */
#endif
}
/*$PAGE*/
/*
*********************************************************************************************************
* TASK DELETION HOOK
*
* Description: This function is called when a task is deleted.
*
* Arguments : p_tcb Pointer to the task control block of the task being deleted.
*
* Note(s) : None.
*********************************************************************************************************
*/
void OSTaskDelHook (OS_TCB *p_tcb)
{
#if OS_CFG_APP_HOOKS_EN > 0u
if (OS_AppTaskDelHookPtr != (OS_APP_HOOK_TCB)0) {
(*OS_AppTaskDelHookPtr)(p_tcb);
}
#else
(void)p_tcb; /* Prevent compiler warning */
#endif
}
/*$PAGE*/
/*
*********************************************************************************************************
* TASK RETURN HOOK
*
* Description: This function is called if a task accidentally returns. In other words, a task should
* either be an infinite loop or delete itself when done.
*
* Arguments : p_tcb Pointer to the task control block of the task that is returning.
*
* Note(s) : None.
*********************************************************************************************************
*/
void OSTaskReturnHook (OS_TCB *p_tcb)
{
#if OS_CFG_APP_HOOKS_EN > 0u
if (OS_AppTaskReturnHookPtr != (OS_APP_HOOK_TCB)0) {
(*OS_AppTaskReturnHookPtr)(p_tcb);
}
#else
(void)p_tcb; /* Prevent compiler warning */
#endif
}
/*$PAGE*/
/*
**********************************************************************************************************
* INITIALIZE A TASK'S STACK
*
* Description: This function is called by OS_Task_Create() or OSTaskCreateExt() to initialize the stack
* frame of the task being created. This function is highly processor specific.
*
* Arguments : p_task Pointer to the task entry point address.
*
* p_arg Pointer to a user supplied data area that will be passed to the task
* when the task first executes.
*
* p_stk_base Pointer to the base address of the stack.
*
* stk_size Size of the stack, in number of CPU_STK elements.
*
* opt Options used to alter the behavior of OS_Task_StkInit().
* (see OS.H for OS_TASK_OPT_xxx).
*
* Returns : Always returns the location of the new top-of-stack' once the processor registers have
* been placed on the stack in the proper order.
*
* Note(s) : 1) Interrupts are enabled when task starts executing.
*
* 2) All tasks run in Thread mode, using process stack.
**********************************************************************************************************
*/
CPU_STK *OSTaskStkInit (OS_TASK_PTR p_task,
void *p_arg,
CPU_STK *p_stk_base,
CPU_STK *p_stk_limit,
CPU_STK_SIZE stk_size,
OS_OPT opt)
{
CPU_STK *p_stk;
(void)opt; /* Prevent compiler warning */
p_stk = &p_stk_base[stk_size]; /* Load stack pointer */
/* Registers stacked as if auto-saved on exception */
*--p_stk = (CPU_STK)0x01000000u; /* xPSR */
*--p_stk = (CPU_STK)p_task; /* Entry Point */
*--p_stk = (CPU_STK)OS_TaskReturn; /* R14 (LR) */
*--p_stk = (CPU_STK)0x12121212u; /* R12 */
*--p_stk = (CPU_STK)0x03030303u; /* R3 */
*--p_stk = (CPU_STK)0x02020202u; /* R2 */
*--p_stk = (CPU_STK)p_stk_limit; /* R1 */
*--p_stk = (CPU_STK)p_arg; /* R0 : argument */
/* Remaining registers saved on process stack */
*--p_stk = (CPU_STK)0x11111111u; /* R11 */
*--p_stk = (CPU_STK)0x10101010u; /* R10 */
*--p_stk = (CPU_STK)0x09090909u; /* R9 */
*--p_stk = (CPU_STK)0x08080808u; /* R8 */
*--p_stk = (CPU_STK)0x07070707u; /* R7 */
*--p_stk = (CPU_STK)0x06060606u; /* R6 */
*--p_stk = (CPU_STK)0x05050505u; /* R5 */
*--p_stk = (CPU_STK)0x04040404u; /* R4 */
return (p_stk);
}
/*$PAGE*/
/*
*********************************************************************************************************
* TASK SWITCH HOOK
*
* Description: This function is called when a task switch is performed. This allows you to perform other
* operations during a context switch.
*
* Arguments : None.
*
* Note(s) : 1) Interrupts are disabled during this call.
* 2) It is assumed that the global pointer 'OSTCBHighRdyPtr' points to the TCB of the task
* that will be 'switched in' (i.e. the highest priority task) and, 'OSTCBCurPtr' points
* to the task being switched out (i.e. the preempted task).
*********************************************************************************************************
*/
void OSTaskSwHook (void)
{
#if OS_CFG_TASK_PROFILE_EN > 0u
CPU_TS ts;
#endif
#ifdef CPU_CFG_INT_DIS_MEAS_EN
CPU_TS int_dis_time;
#endif
#if OS_CFG_APP_HOOKS_EN > 0u
if (OS_AppTaskSwHookPtr != (OS_APP_HOOK_VOID)0) {
(*OS_AppTaskSwHookPtr)();
}
#endif
#if OS_CFG_TASK_PROFILE_EN > 0u
ts = OS_TS_GET();
if (OSTCBCurPtr != OSTCBHighRdyPtr) {
OSTCBCurPtr->CyclesDelta = ts - OSTCBCurPtr->CyclesStart;
OSTCBCurPtr->CyclesTotal += (OS_CYCLES)OSTCBCurPtr->CyclesDelta;
}
OSTCBHighRdyPtr->CyclesStart = ts;
#endif
#ifdef CPU_CFG_INT_DIS_MEAS_EN
int_dis_time = CPU_IntDisMeasMaxCurReset(); /* Keep track of per-task interrupt disable time */
if (OSTCBCurPtr->IntDisTimeMax < int_dis_time) {
OSTCBCurPtr->IntDisTimeMax = int_dis_time;
}
#endif
#if OS_CFG_SCHED_LOCK_TIME_MEAS_EN > 0u
/* Keep track of per-task scheduler lock time */
if (OSTCBCurPtr->SchedLockTimeMax < OSSchedLockTimeMaxCur) {
OSTCBCurPtr->SchedLockTimeMax = OSSchedLockTimeMaxCur;
}
OSSchedLockTimeMaxCur = (CPU_TS)0; /* Reset the per-task value */
#endif
}
/*$PAGE*/
/*
*********************************************************************************************************
* TICK HOOK
*
* Description: This function is called every tick.
*
* Arguments : None.
*
* Note(s) : 1) This function is assumed to be called from the Tick ISR.
*********************************************************************************************************
*/
void OSTimeTickHook (void)
{
#if OS_CFG_APP_HOOKS_EN > 0u
if (OS_AppTimeTickHookPtr != (OS_APP_HOOK_VOID)0) {
(*OS_AppTimeTickHookPtr)();
}
#endif
}
/*$PAGE*/
/*
*********************************************************************************************************
* SYS TICK HANDLER
*
* Description: Handle the system tick (SysTick) interrupt, which is used to generate the uC/OS-II tick
* interrupt.
*
* Arguments : None.
*
* Note(s) : 1) This function MUST be placed on entry 15 of the Cortex-M3 vector table.
*********************************************************************************************************
*/
void OS_CPU_SysTickHandler (void)
{
CPU_SR_ALLOC();
CPU_CRITICAL_ENTER();
OSIntNestingCtr++; /* Tell uC/OS-III that we are starting an ISR */
CPU_CRITICAL_EXIT();
OSTimeTick(); /* Call uC/OS-III's OSTimeTick() */
OSIntExit(); /* Tell uC/OS-III that we are leaving the ISR */
}
/*$PAGE*/
/*
*********************************************************************************************************
* INITIALIZE SYS TICK
*
* Description: Initialize the SysTick.
*
* Arguments : cnts Number of SysTick counts between two OS tick interrupts.
*
* Note(s) : 1) This function MUST be called after OSStart() & after processor initialization.
*********************************************************************************************************
*/
void OS_CPU_SysTickInit (CPU_INT32U cnts)
{
CPU_INT32U prio;
CPU_REG_NVIC_ST_RELOAD = cnts - 1u;
/* Set SysTick handler prio. */
prio = CPU_REG_NVIC_SHPRI3;
prio &= DEF_BIT_FIELD(24, 0);
prio |= DEF_BIT_MASK(OS_CPU_CFG_SYSTICK_PRIO, 24);
CPU_REG_NVIC_SHPRI3 = prio;
/* Enable timer. */
CPU_REG_NVIC_ST_CTRL |= CPU_REG_NVIC_ST_CTRL_CLKSOURCE |
CPU_REG_NVIC_ST_CTRL_ENABLE;
/* Enable timer interrupt. */
CPU_REG_NVIC_ST_CTRL |= CPU_REG_NVIC_ST_CTRL_TICKINT;
}

View File

@@ -0,0 +1,139 @@
/*
*********************************************************************************************************
* uC/OS-III
* The Real-Time Kernel
*
*
* (c) Copyright 2009-2010; Micrium, Inc.; Weston, FL
* All rights reserved. Protected by international copyright laws.
*
* ARM Cortex-M3 Port
*
* File : OS_CPU.H
* Version : V3.01.2
* By : JJL
*
* LICENSING TERMS:
* ---------------
* uC/OS-III is provided in source form to registered licensees ONLY. It is
* illegal to distribute this source code to any third party unless you receive
* written permission by an authorized Micrium representative. Knowledge of
* the source code may NOT be used to develop a similar product.
*
* Please help us continue to provide the Embedded community with the finest
* software available. Your honesty is greatly appreciated.
*
* You can contact us at www.micrium.com.
*
* For : ARMv7M Cortex-M3
* Mode : Thumb2
* Toolchain : IAR EWARM
*********************************************************************************************************
*/
#ifndef OS_CPU_H
#define OS_CPU_H
#ifdef OS_CPU_GLOBALS
#define OS_CPU_EXT
#else
#define OS_CPU_EXT extern
#endif
/*
*********************************************************************************************************
* MACROS
*********************************************************************************************************
*/
#ifndef NVIC_INT_CTRL
#define NVIC_INT_CTRL *((CPU_REG32 *)0xE000ED04)
#endif
#ifndef NVIC_PENDSVSET
#define NVIC_PENDSVSET 0x10000000
#endif
#define OS_TASK_SW() NVIC_INT_CTRL = NVIC_PENDSVSET
#define OSIntCtxSw() NVIC_INT_CTRL = NVIC_PENDSVSET
/*
*********************************************************************************************************
* TIMESTAMP CONFIGURATION
*
* Note(s) : (1) OS_TS_GET() is generally defined as CPU_TS_Get32() to allow CPU timestamp timer to be of
* any data type size.
*
* (2) For architectures that provide 32-bit or higher precision free running counters
* (i.e. cycle count registers):
*
* (a) OS_TS_GET() may be defined as CPU_TS_TmrRd() to improve performance when retrieving
* the timestamp.
*
* (b) CPU_TS_TmrRd() MUST be configured to be greater or equal to 32-bits to avoid
* truncation of TS.
*********************************************************************************************************
*/
#if OS_CFG_TS_EN == 1u
#define OS_TS_GET() (CPU_TS)CPU_TS_TmrRd() /* See Note #2a. */
#else
#define OS_TS_GET() (CPU_TS)0u
#endif
#if (CPU_CFG_TS_32_EN == DEF_ENABLED) && \
(CPU_CFG_TS_TMR_SIZE < CPU_WORD_SIZE_32)
/* CPU_CFG_TS_TMR_SIZE MUST be >= 32-bit (see Note #2b). */
#error "cpu_cfg.h, CPU_CFG_TS_TMR_SIZE MUST be >= CPU_WORD_SIZE_32"
#endif
/*
*********************************************************************************************************
* OS TICK INTERRUPT PRIORITY CONFIGURATION
*
* Note(s) : (1) For systems that don't need any high, real-time priority interrupts; the tick interrupt
* should be configured as the highest priority interrupt but won't adversely affect system
* operations.
*
* (2) For systems that need one or more high, real-time interrupts; these should be configured
* higher than the tick interrupt which MAY delay execution of the tick interrupt.
*
* (a) If the higher priority interrupts do NOT continually consume CPU cycles but only
* occasionally delay tick interrupts, then the real-time interrupts can successfully
* handle their intermittent/periodic events with the system not losing tick interrupts
* but only increasing the jitter.
*
* (b) If the higher priority interrupts consume enough CPU cycles to continually delay the
* tick interrupt, then the CPU/system is most likely over-burdened & can't be expected
* to handle all its interrupts/tasks. The system time reference gets compromised as a
* result of losing tick interrupts.
*********************************************************************************************************
*/
#define OS_CPU_CFG_SYSTICK_PRIO 0u
/*
*********************************************************************************************************
* GLOBAL VARIABLES
*********************************************************************************************************
*/
OS_CPU_EXT CPU_STK *OS_CPU_ExceptStkBase;
/*
*********************************************************************************************************
* FUNCTION PROTOTYPES
*********************************************************************************************************
*/
void OSStartHighRdy (void);
void OS_CPU_PendSVHandler (void);
void OS_CPU_SysTickHandler(void);
void OS_CPU_SysTickInit (CPU_INT32U cnts);
#endif

View File

@@ -0,0 +1,170 @@
;
;********************************************************************************************************
; uC/OS-III
; The Real-Time Kernel
;
;
; (c) Copyright 2009-2010; Micrium, Inc.; Weston, FL
; All rights reserved. Protected by international copyright laws.
;
; ARM Cortex-M3 Port
;
; File : OS_CPU_A.ASM
; Version : V3.01.2
; By : JJL
; BAN
;
; For : ARMv7M Cortex-M3
; Mode : Thumb2
; Toolchain : IAR EWARM
;********************************************************************************************************
;
;********************************************************************************************************
; PUBLIC FUNCTIONS
;********************************************************************************************************
EXTERN OSRunning ; External references
EXTERN OSPrioCur
EXTERN OSPrioHighRdy
EXTERN OSTCBCurPtr
EXTERN OSTCBHighRdyPtr
EXTERN OSIntExit
EXTERN OSTaskSwHook
EXTERN OS_CPU_ExceptStkBase
PUBLIC OSStartHighRdy ; Functions declared in this file
PUBLIC OS_CPU_PendSVHandler
;PAGE
;********************************************************************************************************
; EQUATES
;********************************************************************************************************
NVIC_INT_CTRL EQU 0xE000ED04 ; Interrupt control state register.
NVIC_SYSPRI14 EQU 0xE000ED22 ; System priority register (priority 14).
NVIC_PENDSV_PRI EQU 0xFF ; PendSV priority value (lowest).
NVIC_PENDSVSET EQU 0x10000000 ; Value to trigger PendSV exception.
;********************************************************************************************************
; CODE GENERATION DIRECTIVES
;********************************************************************************************************
RSEG CODE:CODE:NOROOT(2)
THUMB
;PAGE
;********************************************************************************************************
; START MULTITASKING
; void OSStartHighRdy(void)
;
; Note(s) : 1) This function triggers a PendSV exception (essentially, causes a context switch) to cause
; the first task to start.
;
; 2) OSStartHighRdy() MUST:
; a) Setup PendSV exception priority to lowest;
; b) Set initial PSP to 0, to tell context switcher this is first run;
; c) Set the main stack to OS_CPU_ExceptStkBase
; d) Trigger PendSV exception;
; e) Enable interrupts (tasks will run with interrupts enabled).
;********************************************************************************************************
OSStartHighRdy
LDR R0, =NVIC_SYSPRI14 ; Set the PendSV exception priority
LDR R1, =NVIC_PENDSV_PRI
STRB R1, [R0]
MOVS R0, #0 ; Set the PSP to 0 for initial context switch call
MSR PSP, R0
LDR R0, =OS_CPU_ExceptStkBase ; Initialize the MSP to the OS_CPU_ExceptStkBase
LDR R1, [R0]
MSR MSP, R1
LDR R0, =NVIC_INT_CTRL ; Trigger the PendSV exception (causes context switch)
LDR R1, =NVIC_PENDSVSET
STR R1, [R0]
CPSIE I ; Enable interrupts at processor level
OSStartHang
B OSStartHang ; Should never get here
;PAGE
;********************************************************************************************************
; HANDLE PendSV EXCEPTION
; void OS_CPU_PendSVHandler(void)
;
; Note(s) : 1) PendSV is used to cause a context switch. This is a recommended method for performing
; context switches with Cortex-M3. This is because the Cortex-M3 auto-saves half of the
; processor context on any exception, and restores same on return from exception. So only
; saving of R4-R11 is required and fixing up the stack pointers. Using the PendSV exception
; this way means that context saving and restoring is identical whether it is initiated from
; a thread or occurs due to an interrupt or exception.
;
; 2) Pseudo-code is:
; a) Get the process SP, if 0 then skip (goto d) the saving part (first context switch);
; b) Save remaining regs r4-r11 on process stack;
; c) Save the process SP in its TCB, OSTCBCurPtr->OSTCBStkPtr = SP;
; d) Call OSTaskSwHook();
; e) Get current high priority, OSPrioCur = OSPrioHighRdy;
; f) Get current ready thread TCB, OSTCBCurPtr = OSTCBHighRdyPtr;
; g) Get new process SP from TCB, SP = OSTCBHighRdyPtr->OSTCBStkPtr;
; h) Restore R4-R11 from new process stack;
; i) Perform exception return which will restore remaining context.
;
; 3) On entry into PendSV handler:
; a) The following have been saved on the process stack (by processor):
; xPSR, PC, LR, R12, R0-R3
; b) Processor mode is switched to Handler mode (from Thread mode)
; c) Stack is Main stack (switched from Process stack)
; d) OSTCBCurPtr points to the OS_TCB of the task to suspend
; OSTCBHighRdyPtr points to the OS_TCB of the task to resume
;
; 4) Since PendSV is set to lowest priority in the system (by OSStartHighRdy() above), we
; know that it will only be run when no other exception or interrupt is active, and
; therefore safe to assume that context being switched out was using the process stack (PSP).
;********************************************************************************************************
OS_CPU_PendSVHandler
CPSID I ; Prevent interruption during context switch
MRS R0, PSP ; PSP is process stack pointer
CBZ R0, OS_CPU_PendSVHandler_nosave ; Skip register save the first time
SUBS R0, R0, #0x20 ; Save remaining regs r4-11 on process stack
STM R0, {R4-R11}
LDR R1, =OSTCBCurPtr ; OSTCBCurPtr->OSTCBStkPtr = SP;
LDR R1, [R1]
STR R0, [R1] ; R0 is SP of process being switched out
; At this point, entire context of process has been saved
OS_CPU_PendSVHandler_nosave
PUSH {R14} ; Save LR exc_return value
LDR R0, =OSTaskSwHook ; OSTaskSwHook();
BLX R0
POP {R14}
LDR R0, =OSPrioCur ; OSPrioCur = OSPrioHighRdy;
LDR R1, =OSPrioHighRdy
LDRB R2, [R1]
STRB R2, [R0]
LDR R0, =OSTCBCurPtr ; OSTCBCurPtr = OSTCBHighRdyPtr;
LDR R1, =OSTCBHighRdyPtr
LDR R2, [R1]
STR R2, [R0]
LDR R0, [R2] ; R0 is new process SP; SP = OSTCBHighRdyPtr->StkPtr;
LDM R0, {R4-R11} ; Restore r4-11 from new process stack
ADDS R0, R0, #0x20
MSR PSP, R0 ; Load PSP with new process SP
ORR LR, LR, #0x04 ; Ensure exception return uses process stack
CPSIE I
BX LR ; Exception return will restore remaining context
END

View File

@@ -0,0 +1,407 @@
/*
*********************************************************************************************************
* uC/OS-III
* The Real-Time Kernel
*
*
* (c) Copyright 2009-2010; Micrium, Inc.; Weston, FL
* All rights reserved. Protected by international copyright laws.
*
* ARM Cortex-M3 Port
*
* File : OS_CPU_C.C
* Version : V3.02.01
* By : JJL
* BAN
*
* LICENSING TERMS:
* ---------------
* uC/OS-III is provided in source form for FREE short-term evaluation, for educational use or
* for peaceful research. If you plan or intend to use uC/OS-III in a commercial application/
* product then, you need to contact Micrium to properly license uC/OS-III for its use in your
* application/product. We provide ALL the source code for your convenience and to help you
* experience uC/OS-III. The fact that the source is provided does NOT mean that you can use
* it commercially without paying a licensing fee.
*
* Knowledge of the source code may NOT be used to develop a similar product.
*
* Please help us continue to provide the embedded community with the finest software available.
* Your honesty is greatly appreciated.
*
* You can contact us at www.micrium.com, or by phone at +1 (954) 217-2036.
*
* For : ARMv7M Cortex-M3
* Mode : Thumb2
* Toolchain : IAR EWARM
*********************************************************************************************************
*/
#define OS_CPU_GLOBALS
#ifdef VSC_INCLUDE_SOURCE_FILE_NAMES
const CPU_CHAR *os_cpu_c__c = "$Id: $";
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* INCLUDE FILES
*********************************************************************************************************
*/
#include <os.h>
/*
*********************************************************************************************************
* IDLE TASK HOOK
*
* Description: This function is called by the idle task. This hook has been added to allow you to do
* such things as STOP the CPU to conserve power.
*
* Arguments : None.
*
* Note(s) : None.
*********************************************************************************************************
*/
void OSIdleTaskHook (void)
{
#if OS_CFG_APP_HOOKS_EN > 0u
if (OS_AppIdleTaskHookPtr != (OS_APP_HOOK_VOID)0) {
(*OS_AppIdleTaskHookPtr)();
}
#endif
}
/*$PAGE*/
/*
*********************************************************************************************************
* OS INITIALIZATION HOOK
*
* Description: This function is called by OSInit() at the beginning of OSInit().
*
* Arguments : None.
*
* Note(s) : None.
*********************************************************************************************************
*/
void OSInitHook (void)
{
OS_CPU_ExceptStkBase = (CPU_STK *)(OSCfg_ISRStkBasePtr + OSCfg_ISRStkSize - 1u);
}
/*$PAGE*/
/*
*********************************************************************************************************
* STATISTIC TASK HOOK
*
* Description: This function is called every second by uC/OS-III's statistics task. This allows your
* application to add functionality to the statistics task.
*
* Arguments : None.
*
* Note(s) : None.
*********************************************************************************************************
*/
void OSStatTaskHook (void)
{
#if OS_CFG_APP_HOOKS_EN > 0u
if (OS_AppStatTaskHookPtr != (OS_APP_HOOK_VOID)0) {
(*OS_AppStatTaskHookPtr)();
}
#endif
}
/*$PAGE*/
/*
*********************************************************************************************************
* TASK CREATION HOOK
*
* Description: This function is called when a task is created.
*
* Arguments : p_tcb Pointer to the task control block of the task being created.
*
* Note(s) : None.
*********************************************************************************************************
*/
void OSTaskCreateHook (OS_TCB *p_tcb)
{
#if OS_CFG_APP_HOOKS_EN > 0u
if (OS_AppTaskCreateHookPtr != (OS_APP_HOOK_TCB)0) {
(*OS_AppTaskCreateHookPtr)(p_tcb);
}
#else
(void)p_tcb; /* Prevent compiler warning */
#endif
}
/*$PAGE*/
/*
*********************************************************************************************************
* TASK DELETION HOOK
*
* Description: This function is called when a task is deleted.
*
* Arguments : p_tcb Pointer to the task control block of the task being deleted.
*
* Note(s) : None.
*********************************************************************************************************
*/
void OSTaskDelHook (OS_TCB *p_tcb)
{
#if OS_CFG_APP_HOOKS_EN > 0u
if (OS_AppTaskDelHookPtr != (OS_APP_HOOK_TCB)0) {
(*OS_AppTaskDelHookPtr)(p_tcb);
}
#else
(void)p_tcb; /* Prevent compiler warning */
#endif
}
/*$PAGE*/
/*
*********************************************************************************************************
* TASK RETURN HOOK
*
* Description: This function is called if a task accidentally returns. In other words, a task should
* either be an infinite loop or delete itself when done.
*
* Arguments : p_tcb Pointer to the task control block of the task that is returning.
*
* Note(s) : None.
*********************************************************************************************************
*/
void OSTaskReturnHook (OS_TCB *p_tcb)
{
#if OS_CFG_APP_HOOKS_EN > 0u
if (OS_AppTaskReturnHookPtr != (OS_APP_HOOK_TCB)0) {
(*OS_AppTaskReturnHookPtr)(p_tcb);
}
#else
(void)p_tcb; /* Prevent compiler warning */
#endif
}
/*$PAGE*/
/*
**********************************************************************************************************
* INITIALIZE A TASK'S STACK
*
* Description: This function is called by OS_Task_Create() or OSTaskCreateExt() to initialize the stack
* frame of the task being created. This function is highly processor specific.
*
* Arguments : p_task Pointer to the task entry point address.
*
* p_arg Pointer to a user supplied data area that will be passed to the task
* when the task first executes.
*
* p_stk_base Pointer to the base address of the stack.
*
* stk_size Size of the stack, in number of CPU_STK elements.
*
* opt Options used to alter the behavior of OS_Task_StkInit().
* (see OS.H for OS_TASK_OPT_xxx).
*
* Returns : Always returns the location of the new top-of-stack' once the processor registers have
* been placed on the stack in the proper order.
*
* Note(s) : 1) Interrupts are enabled when task starts executing.
*
* 2) All tasks run in Thread mode, using process stack.
**********************************************************************************************************
*/
CPU_STK *OSTaskStkInit (OS_TASK_PTR p_task,
void *p_arg,
CPU_STK *p_stk_base,
CPU_STK *p_stk_limit,
CPU_STK_SIZE stk_size,
OS_OPT opt)
{
CPU_STK *p_stk;
(void)opt; /* Prevent compiler warning */
p_stk = &p_stk_base[stk_size]; /* Load stack pointer */
/* Registers stacked as if auto-saved on exception */
*--p_stk = (CPU_STK)0x01000000u; /* xPSR */
*--p_stk = (CPU_STK)p_task; /* Entry Point */
*--p_stk = (CPU_STK)OS_TaskReturn; /* R14 (LR) */
*--p_stk = (CPU_STK)0x12121212u; /* R12 */
*--p_stk = (CPU_STK)0x03030303u; /* R3 */
*--p_stk = (CPU_STK)0x02020202u; /* R2 */
*--p_stk = (CPU_STK)p_stk_limit; /* R1 */
*--p_stk = (CPU_STK)p_arg; /* R0 : argument */
/* Remaining registers saved on process stack */
*--p_stk = (CPU_STK)0x11111111u; /* R11 */
*--p_stk = (CPU_STK)0x10101010u; /* R10 */
*--p_stk = (CPU_STK)0x09090909u; /* R9 */
*--p_stk = (CPU_STK)0x08080808u; /* R8 */
*--p_stk = (CPU_STK)0x07070707u; /* R7 */
*--p_stk = (CPU_STK)0x06060606u; /* R6 */
*--p_stk = (CPU_STK)0x05050505u; /* R5 */
*--p_stk = (CPU_STK)0x04040404u; /* R4 */
return (p_stk);
}
/*$PAGE*/
/*
*********************************************************************************************************
* TASK SWITCH HOOK
*
* Description: This function is called when a task switch is performed. This allows you to perform other
* operations during a context switch.
*
* Arguments : None.
*
* Note(s) : 1) Interrupts are disabled during this call.
* 2) It is assumed that the global pointer 'OSTCBHighRdyPtr' points to the TCB of the task
* that will be 'switched in' (i.e. the highest priority task) and, 'OSTCBCurPtr' points
* to the task being switched out (i.e. the preempted task).
*********************************************************************************************************
*/
void OSTaskSwHook (void)
{
#if OS_CFG_TASK_PROFILE_EN > 0u
CPU_TS ts;
#endif
#ifdef CPU_CFG_INT_DIS_MEAS_EN
CPU_TS int_dis_time;
#endif
#if OS_CFG_APP_HOOKS_EN > 0u
if (OS_AppTaskSwHookPtr != (OS_APP_HOOK_VOID)0) {
(*OS_AppTaskSwHookPtr)();
}
#endif
#if OS_CFG_TASK_PROFILE_EN > 0u
ts = OS_TS_GET();
if (OSTCBCurPtr != OSTCBHighRdyPtr) {
OSTCBCurPtr->CyclesDelta = ts - OSTCBCurPtr->CyclesStart;
OSTCBCurPtr->CyclesTotal += (OS_CYCLES)OSTCBCurPtr->CyclesDelta;
}
OSTCBHighRdyPtr->CyclesStart = ts;
#endif
#ifdef CPU_CFG_INT_DIS_MEAS_EN
int_dis_time = CPU_IntDisMeasMaxCurReset(); /* Keep track of per-task interrupt disable time */
if (OSTCBCurPtr->IntDisTimeMax < int_dis_time) {
OSTCBCurPtr->IntDisTimeMax = int_dis_time;
}
#endif
#if OS_CFG_SCHED_LOCK_TIME_MEAS_EN > 0u
/* Keep track of per-task scheduler lock time */
if (OSTCBCurPtr->SchedLockTimeMax < OSSchedLockTimeMaxCur) {
OSTCBCurPtr->SchedLockTimeMax = OSSchedLockTimeMaxCur;
}
OSSchedLockTimeMaxCur = (CPU_TS)0; /* Reset the per-task value */
#endif
}
/*$PAGE*/
/*
*********************************************************************************************************
* TICK HOOK
*
* Description: This function is called every tick.
*
* Arguments : None.
*
* Note(s) : 1) This function is assumed to be called from the Tick ISR.
*********************************************************************************************************
*/
void OSTimeTickHook (void)
{
#if OS_CFG_APP_HOOKS_EN > 0u
if (OS_AppTimeTickHookPtr != (OS_APP_HOOK_VOID)0) {
(*OS_AppTimeTickHookPtr)();
}
#endif
}
/*$PAGE*/
/*
*********************************************************************************************************
* SYS TICK HANDLER
*
* Description: Handle the system tick (SysTick) interrupt, which is used to generate the uC/OS-II tick
* interrupt.
*
* Arguments : None.
*
* Note(s) : 1) This function MUST be placed on entry 15 of the Cortex-M3 vector table.
*********************************************************************************************************
*/
void OS_CPU_SysTickHandler (void)
{
CPU_SR_ALLOC();
CPU_CRITICAL_ENTER();
OSIntNestingCtr++; /* Tell uC/OS-III that we are starting an ISR */
CPU_CRITICAL_EXIT();
OSTimeTick(); /* Call uC/OS-III's OSTimeTick() */
OSIntExit(); /* Tell uC/OS-III that we are leaving the ISR */
}
/*$PAGE*/
/*
*********************************************************************************************************
* INITIALIZE SYS TICK
*
* Description: Initialize the SysTick.
*
* Arguments : cnts Number of SysTick counts between two OS tick interrupts.
*
* Note(s) : 1) This function MUST be called after OSStart() & after processor initialization.
*********************************************************************************************************
*/
void OS_CPU_SysTickInit (CPU_INT32U cnts)
{
CPU_INT32U prio;
CPU_REG_NVIC_ST_RELOAD = cnts - 1u;
/* Set SysTick handler prio. */
prio = CPU_REG_NVIC_SHPRI3;
prio &= DEF_BIT_FIELD(24, 0);
prio |= DEF_BIT_MASK(OS_CPU_CFG_SYSTICK_PRIO, 24);
CPU_REG_NVIC_SHPRI3 = prio;
/* Enable timer. */
CPU_REG_NVIC_ST_CTRL |= CPU_REG_NVIC_ST_CTRL_CLKSOURCE |
CPU_REG_NVIC_ST_CTRL_ENABLE;
/* Enable timer interrupt. */
CPU_REG_NVIC_ST_CTRL |= CPU_REG_NVIC_ST_CTRL_TICKINT;
}

View File

@@ -0,0 +1,139 @@
/*
*********************************************************************************************************
* uC/OS-III
* The Real-Time Kernel
*
*
* (c) Copyright 2009-2010; Micrium, Inc.; Weston, FL
* All rights reserved. Protected by international copyright laws.
*
* ARM Cortex-M3 Port
*
* File : OS_CPU.H
* Version : V3.01.2
* By : JJL
*
* LICENSING TERMS:
* ---------------
* uC/OS-III is provided in source form to registered licensees ONLY. It is
* illegal to distribute this source code to any third party unless you receive
* written permission by an authorized Micrium representative. Knowledge of
* the source code may NOT be used to develop a similar product.
*
* Please help us continue to provide the Embedded community with the finest
* software available. Your honesty is greatly appreciated.
*
* You can contact us at www.micrium.com.
*
* For : ARMv7M Cortex-M3
* Mode : Thumb2
* Toolchain : RealView
*********************************************************************************************************
*/
#ifndef OS_CPU_H
#define OS_CPU_H
#ifdef OS_CPU_GLOBALS
#define OS_CPU_EXT
#else
#define OS_CPU_EXT extern
#endif
/*
*********************************************************************************************************
* MACROS
*********************************************************************************************************
*/
#ifndef NVIC_INT_CTRL
#define NVIC_INT_CTRL *((CPU_REG32 *)0xE000ED04)
#endif
#ifndef NVIC_PENDSVSET
#define NVIC_PENDSVSET 0x10000000
#endif
#define OS_TASK_SW() NVIC_INT_CTRL = NVIC_PENDSVSET
#define OSIntCtxSw() NVIC_INT_CTRL = NVIC_PENDSVSET
/*
*********************************************************************************************************
* TIMESTAMP CONFIGURATION
*
* Note(s) : (1) OS_TS_GET() is generally defined as CPU_TS_Get32() to allow CPU timestamp timer to be of
* any data type size.
*
* (2) For architectures that provide 32-bit or higher precision free running counters
* (i.e. cycle count registers):
*
* (a) OS_TS_GET() may be defined as CPU_TS_TmrRd() to improve performance when retrieving
* the timestamp.
*
* (b) CPU_TS_TmrRd() MUST be configured to be greater or equal to 32-bits to avoid
* truncation of TS.
*********************************************************************************************************
*/
#if OS_CFG_TS_EN == 1u
#define OS_TS_GET() (CPU_TS)CPU_TS_TmrRd() /* See Note #2a. */
#else
#define OS_TS_GET() (CPU_TS)0u
#endif
#if (CPU_CFG_TS_32_EN == DEF_ENABLED) && \
(CPU_CFG_TS_TMR_SIZE < CPU_WORD_SIZE_32)
/* CPU_CFG_TS_TMR_SIZE MUST be >= 32-bit (see Note #2b). */
#error "cpu_cfg.h, CPU_CFG_TS_TMR_SIZE MUST be >= CPU_WORD_SIZE_32"
#endif
/*
*********************************************************************************************************
* OS TICK INTERRUPT PRIORITY CONFIGURATION
*
* Note(s) : (1) For systems that don't need any high, real-time priority interrupts; the tick interrupt
* should be configured as the highest priority interrupt but won't adversely affect system
* operations.
*
* (2) For systems that need one or more high, real-time interrupts; these should be configured
* higher than the tick interrupt which MAY delay execution of the tick interrupt.
*
* (a) If the higher priority interrupts do NOT continually consume CPU cycles but only
* occasionally delay tick interrupts, then the real-time interrupts can successfully
* handle their intermittent/periodic events with the system not losing tick interrupts
* but only increasing the jitter.
*
* (b) If the higher priority interrupts consume enough CPU cycles to continually delay the
* tick interrupt, then the CPU/system is most likely over-burdened & can't be expected
* to handle all its interrupts/tasks. The system time reference gets compromised as a
* result of losing tick interrupts.
*********************************************************************************************************
*/
#define OS_CPU_CFG_SYSTICK_PRIO 0u
/*
*********************************************************************************************************
* GLOBAL VARIABLES
*********************************************************************************************************
*/
OS_CPU_EXT CPU_STK *OS_CPU_ExceptStkBase;
/*
*********************************************************************************************************
* FUNCTION PROTOTYPES
*********************************************************************************************************
*/
void OSStartHighRdy (void);
void OS_CPU_PendSVHandler (void);
void OS_CPU_SysTickHandler(void);
void OS_CPU_SysTickInit (CPU_INT32U cnts);
#endif

View File

@@ -0,0 +1,175 @@
;
;********************************************************************************************************
; uC/OS-III
; The Real-Time Kernel
;
;
; (c) Copyright 2009-2010; Micrium, Inc.; Weston, FL
; All rights reserved. Protected by international copyright laws.
;
; ARM Cortex-M3 Port
;
; File : OS_CPU_A.ASM
; Version : V3.01.2
; By : JJL
; BAN
;
; For : ARMv7M Cortex-M3
; Mode : Thumb2
; Toolchain : RealView Development Suite
; RealView Microcontroller Development Kit (MDK)
; ARM Developer Suite (ADS)
; Keil uVision
;********************************************************************************************************
;
;********************************************************************************************************
; PUBLIC FUNCTIONS
;********************************************************************************************************
IMPORT OSRunning ; External references
IMPORT OSPrioCur
IMPORT OSPrioHighRdy
IMPORT OSTCBCurPtr
IMPORT OSTCBHighRdyPtr
IMPORT OSIntExit
IMPORT OSTaskSwHook
IMPORT OS_CPU_ExceptStkBase
EXPORT OSStartHighRdy ; Functions declared in this file
EXPORT OS_CPU_PendSVHandler
;PAGE
;********************************************************************************************************
; EQUATES
;********************************************************************************************************
NVIC_INT_CTRL EQU 0xE000ED04 ; Interrupt control state register.
NVIC_SYSPRI14 EQU 0xE000ED22 ; System priority register (priority 14).
NVIC_PENDSV_PRI EQU 0xFF ; PendSV priority value (lowest).
NVIC_PENDSVSET EQU 0x10000000 ; Value to trigger PendSV exception.
;********************************************************************************************************
; CODE GENERATION DIRECTIVES
;********************************************************************************************************
PRESERVE8
THUMB
AREA CODE, CODE, READONLY
;PAGE
;********************************************************************************************************
; START MULTITASKING
; void OSStartHighRdy(void)
;
; Note(s) : 1) This function triggers a PendSV exception (essentially, causes a context switch) to cause
; the first task to start.
;
; 2) OSStartHighRdy() MUST:
; a) Setup PendSV exception priority to lowest;
; b) Set initial PSP to 0, to tell context switcher this is first run;
; c) Set the main stack to OS_CPU_ExceptStkBase
; d) Trigger PendSV exception;
; e) Enable interrupts (tasks will run with interrupts enabled).
;********************************************************************************************************
OSStartHighRdy
LDR R0, =NVIC_SYSPRI14 ; Set the PendSV exception priority
LDR R1, =NVIC_PENDSV_PRI
STRB R1, [R0]
MOVS R0, #0 ; Set the PSP to 0 for initial context switch call
MSR PSP, R0
LDR R0, =OS_CPU_ExceptStkBase ; Initialize the MSP to the OS_CPU_ExceptStkBase
LDR R1, [R0]
MSR MSP, R1
LDR R0, =NVIC_INT_CTRL ; Trigger the PendSV exception (causes context switch)
LDR R1, =NVIC_PENDSVSET
STR R1, [R0]
CPSIE I ; Enable interrupts at processor level
OSStartHang
B OSStartHang ; Should never get here
;PAGE
;********************************************************************************************************
; HANDLE PendSV EXCEPTION
; void OS_CPU_PendSVHandler(void)
;
; Note(s) : 1) PendSV is used to cause a context switch. This is a recommended method for performing
; context switches with Cortex-M3. This is because the Cortex-M3 auto-saves half of the
; processor context on any exception, and restores same on return from exception. So only
; saving of R4-R11 is required and fixing up the stack pointers. Using the PendSV exception
; this way means that context saving and restoring is identical whether it is initiated from
; a thread or occurs due to an interrupt or exception.
;
; 2) Pseudo-code is:
; a) Get the process SP, if 0 then skip (goto d) the saving part (first context switch);
; b) Save remaining regs r4-r11 on process stack;
; c) Save the process SP in its TCB, OSTCBCurPtr->OSTCBStkPtr = SP;
; d) Call OSTaskSwHook();
; e) Get current high priority, OSPrioCur = OSPrioHighRdy;
; f) Get current ready thread TCB, OSTCBCurPtr = OSTCBHighRdyPtr;
; g) Get new process SP from TCB, SP = OSTCBHighRdyPtr->OSTCBStkPtr;
; h) Restore R4-R11 from new process stack;
; i) Perform exception return which will restore remaining context.
;
; 3) On entry into PendSV handler:
; a) The following have been saved on the process stack (by processor):
; xPSR, PC, LR, R12, R0-R3
; b) Processor mode is switched to Handler mode (from Thread mode)
; c) Stack is Main stack (switched from Process stack)
; d) OSTCBCurPtr points to the OS_TCB of the task to suspend
; OSTCBHighRdyPtr points to the OS_TCB of the task to resume
;
; 4) Since PendSV is set to lowest priority in the system (by OSStartHighRdy() above), we
; know that it will only be run when no other exception or interrupt is active, and
; therefore safe to assume that context being switched out was using the process stack (PSP).
;********************************************************************************************************
OS_CPU_PendSVHandler
CPSID I ; Prevent interruption during context switch
MRS R0, PSP ; PSP is process stack pointer
CBZ R0, OS_CPU_PendSVHandler_nosave ; Skip register save the first time
SUBS R0, R0, #0x20 ; Save remaining regs r4-11 on process stack
STM R0, {R4-R11}
LDR R1, =OSTCBCurPtr ; OSTCBCurPtr->OSTCBStkPtr = SP;
LDR R1, [R1]
STR R0, [R1] ; R0 is SP of process being switched out
; At this point, entire context of process has been saved
OS_CPU_PendSVHandler_nosave
PUSH {R14} ; Save LR exc_return value
LDR R0, =OSTaskSwHook ; OSTaskSwHook();
BLX R0
POP {R14}
LDR R0, =OSPrioCur ; OSPrioCur = OSPrioHighRdy;
LDR R1, =OSPrioHighRdy
LDRB R2, [R1]
STRB R2, [R0]
LDR R0, =OSTCBCurPtr ; OSTCBCurPtr = OSTCBHighRdyPtr;
LDR R1, =OSTCBHighRdyPtr
LDR R2, [R1]
STR R2, [R0]
LDR R0, [R2] ; R0 is new process SP; SP = OSTCBHighRdyPtr->StkPtr;
LDM R0, {R4-R11} ; Restore r4-11 from new process stack
ADDS R0, R0, #0x20
MSR PSP, R0 ; Load PSP with new process SP
ORR LR, LR, #0x04 ; Ensure exception return uses process stack
CPSIE I
BX LR ; Exception return will restore remaining context
END

View File

@@ -0,0 +1,411 @@
/*
*********************************************************************************************************
* uC/OS-III
* The Real-Time Kernel
*
*
* (c) Copyright 2009-2010; Micrium, Inc.; Weston, FL
* All rights reserved. Protected by international copyright laws.
*
* ARM Cortex-M3 Port
*
* File : OS_CPU_C.C
* Version : V3.01.2
* By : JJL
* BAN
*
* LICENSING TERMS:
* ---------------
* uC/OS-III is provided in source form to registered licensees ONLY. It is
* illegal to distribute this source code to any third party unless you receive
* written permission by an authorized Micrium representative. Knowledge of
* the source code may NOT be used to develop a similar product.
*
* Please help us continue to provide the Embedded community with the finest
* software available. Your honesty is greatly appreciated.
*
* You can contact us at www.micrium.com.
*
* For : ARMv7M Cortex-M3
* Mode : Thumb2
* Toolchain : RealView
*********************************************************************************************************
*/
#define OS_CPU_GLOBALS
#ifdef VSC_INCLUDE_SOURCE_FILE_NAMES
const CPU_CHAR *os_cpu_c__c = "$Id: $";
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* INCLUDE FILES
*********************************************************************************************************
*/
#include <os.h>
/*
*********************************************************************************************************
* IDLE TASK HOOK
*
* Description: This function is called by the idle task. This hook has been added to allow you to do
* such things as STOP the CPU to conserve power.
*
* Arguments : None.
*
* Note(s) : None.
*********************************************************************************************************
*/
void OSIdleTaskHook (void)
{
#if OS_CFG_APP_HOOKS_EN > 0u
if (OS_AppIdleTaskHookPtr != (OS_APP_HOOK_VOID)0) {
(*OS_AppIdleTaskHookPtr)();
}
#endif
}
/*$PAGE*/
/*
*********************************************************************************************************
* OS INITIALIZATION HOOK
*
* Description: This function is called by OSInit() at the beginning of OSInit().
*
* Arguments : None.
*
* Note(s) : None.
*********************************************************************************************************
*/
void OSInitHook (void)
{
CPU_STK_SIZE i;
CPU_STK *p_stk;
p_stk = OSCfg_ISRStkBasePtr; /* Clear the ISR stack */
for (i = 0u; i < OSCfg_ISRStkSize; i++) {
*p_stk++ = (CPU_STK)0u;
}
OS_CPU_ExceptStkBase = (CPU_STK *)(OSCfg_ISRStkBasePtr + OSCfg_ISRStkSize - 1u);
}
/*$PAGE*/
/*
*********************************************************************************************************
* STATISTIC TASK HOOK
*
* Description: This function is called every second by uC/OS-III's statistics task. This allows your
* application to add functionality to the statistics task.
*
* Arguments : None.
*
* Note(s) : None.
*********************************************************************************************************
*/
void OSStatTaskHook (void)
{
#if OS_CFG_APP_HOOKS_EN > 0u
if (OS_AppStatTaskHookPtr != (OS_APP_HOOK_VOID)0) {
(*OS_AppStatTaskHookPtr)();
}
#endif
}
/*$PAGE*/
/*
*********************************************************************************************************
* TASK CREATION HOOK
*
* Description: This function is called when a task is created.
*
* Arguments : p_tcb Pointer to the task control block of the task being created.
*
* Note(s) : None.
*********************************************************************************************************
*/
void OSTaskCreateHook (OS_TCB *p_tcb)
{
#if OS_CFG_APP_HOOKS_EN > 0u
if (OS_AppTaskCreateHookPtr != (OS_APP_HOOK_TCB)0) {
(*OS_AppTaskCreateHookPtr)(p_tcb);
}
#else
(void)p_tcb; /* Prevent compiler warning */
#endif
}
/*$PAGE*/
/*
*********************************************************************************************************
* TASK DELETION HOOK
*
* Description: This function is called when a task is deleted.
*
* Arguments : p_tcb Pointer to the task control block of the task being deleted.
*
* Note(s) : None.
*********************************************************************************************************
*/
void OSTaskDelHook (OS_TCB *p_tcb)
{
#if OS_CFG_APP_HOOKS_EN > 0u
if (OS_AppTaskDelHookPtr != (OS_APP_HOOK_TCB)0) {
(*OS_AppTaskDelHookPtr)(p_tcb);
}
#else
(void)p_tcb; /* Prevent compiler warning */
#endif
}
/*$PAGE*/
/*
*********************************************************************************************************
* TASK RETURN HOOK
*
* Description: This function is called if a task accidentally returns. In other words, a task should
* either be an infinite loop or delete itself when done.
*
* Arguments : p_tcb Pointer to the task control block of the task that is returning.
*
* Note(s) : None.
*********************************************************************************************************
*/
void OSTaskReturnHook (OS_TCB *p_tcb)
{
#if OS_CFG_APP_HOOKS_EN > 0u
if (OS_AppTaskReturnHookPtr != (OS_APP_HOOK_TCB)0) {
(*OS_AppTaskReturnHookPtr)(p_tcb);
}
#else
(void)p_tcb; /* Prevent compiler warning */
#endif
}
/*$PAGE*/
/*
**********************************************************************************************************
* INITIALIZE A TASK'S STACK
*
* Description: This function is called by OS_Task_Create() or OSTaskCreateExt() to initialize the stack
* frame of the task being created. This function is highly processor specific.
*
* Arguments : p_task Pointer to the task entry point address.
*
* p_arg Pointer to a user supplied data area that will be passed to the task
* when the task first executes.
*
* p_stk_base Pointer to the base address of the stack.
*
* stk_size Size of the stack, in number of CPU_STK elements.
*
* opt Options used to alter the behavior of OS_Task_StkInit().
* (see OS.H for OS_TASK_OPT_xxx).
*
* Returns : Always returns the location of the new top-of-stack' once the processor registers have
* been placed on the stack in the proper order.
*
* Note(s) : 1) Interrupts are enabled when task starts executing.
*
* 2) All tasks run in Thread mode, using process stack.
**********************************************************************************************************
*/
CPU_STK *OSTaskStkInit (OS_TASK_PTR p_task,
void *p_arg,
CPU_STK *p_stk_base,
CPU_STK *p_stk_limit,
CPU_STK_SIZE stk_size,
OS_OPT opt)
{
CPU_STK *p_stk;
(void)opt; /* Prevent compiler warning */
p_stk = &p_stk_base[stk_size]; /* Load stack pointer */
/* Registers stacked as if auto-saved on exception */
*--p_stk = (CPU_STK)0x01000000u; /* xPSR */
*--p_stk = (CPU_STK)p_task; /* Entry Point */
*--p_stk = (CPU_STK)OS_TaskReturn; /* R14 (LR) */
*--p_stk = (CPU_STK)0x12121212u; /* R12 */
*--p_stk = (CPU_STK)0x03030303u; /* R3 */
*--p_stk = (CPU_STK)0x02020202u; /* R2 */
*--p_stk = (CPU_STK)p_stk_limit; /* R1 */
*--p_stk = (CPU_STK)p_arg; /* R0 : argument */
/* Remaining registers saved on process stack */
*--p_stk = (CPU_STK)0x11111111u; /* R11 */
*--p_stk = (CPU_STK)0x10101010u; /* R10 */
*--p_stk = (CPU_STK)0x09090909u; /* R9 */
*--p_stk = (CPU_STK)0x08080808u; /* R8 */
*--p_stk = (CPU_STK)0x07070707u; /* R7 */
*--p_stk = (CPU_STK)0x06060606u; /* R6 */
*--p_stk = (CPU_STK)0x05050505u; /* R5 */
*--p_stk = (CPU_STK)0x04040404u; /* R4 */
return (p_stk);
}
/*$PAGE*/
/*
*********************************************************************************************************
* TASK SWITCH HOOK
*
* Description: This function is called when a task switch is performed. This allows you to perform other
* operations during a context switch.
*
* Arguments : None.
*
* Note(s) : 1) Interrupts are disabled during this call.
* 2) It is assumed that the global pointer 'OSTCBHighRdyPtr' points to the TCB of the task
* that will be 'switched in' (i.e. the highest priority task) and, 'OSTCBCurPtr' points
* to the task being switched out (i.e. the preempted task).
*********************************************************************************************************
*/
void OSTaskSwHook (void)
{
#if OS_CFG_TASK_PROFILE_EN > 0u
CPU_TS ts;
#endif
#ifdef CPU_CFG_INT_DIS_MEAS_EN
CPU_TS int_dis_time;
#endif
#if OS_CFG_APP_HOOKS_EN > 0u
if (OS_AppTaskSwHookPtr != (OS_APP_HOOK_VOID)0) {
(*OS_AppTaskSwHookPtr)();
}
#endif
#if OS_CFG_TASK_PROFILE_EN > 0u
ts = OS_TS_GET();
if (OSTCBCurPtr != OSTCBHighRdyPtr) {
OSTCBCurPtr->CyclesDelta = ts - OSTCBCurPtr->CyclesStart;
OSTCBCurPtr->CyclesTotal += (OS_CYCLES)OSTCBCurPtr->CyclesDelta;
}
OSTCBHighRdyPtr->CyclesStart = ts;
#endif
#ifdef CPU_CFG_INT_DIS_MEAS_EN
int_dis_time = CPU_IntDisMeasMaxCurReset(); /* Keep track of per-task interrupt disable time */
if (OSTCBCurPtr->IntDisTimeMax < int_dis_time) {
OSTCBCurPtr->IntDisTimeMax = int_dis_time;
}
#endif
#if OS_CFG_SCHED_LOCK_TIME_MEAS_EN > 0u
/* Keep track of per-task scheduler lock time */
if (OSTCBCurPtr->SchedLockTimeMax < OSSchedLockTimeMaxCur) {
OSTCBCurPtr->SchedLockTimeMax = OSSchedLockTimeMaxCur;
}
OSSchedLockTimeMaxCur = (CPU_TS)0; /* Reset the per-task value */
#endif
}
/*$PAGE*/
/*
*********************************************************************************************************
* TICK HOOK
*
* Description: This function is called every tick.
*
* Arguments : None.
*
* Note(s) : 1) This function is assumed to be called from the Tick ISR.
*********************************************************************************************************
*/
void OSTimeTickHook (void)
{
#if OS_CFG_APP_HOOKS_EN > 0u
if (OS_AppTimeTickHookPtr != (OS_APP_HOOK_VOID)0) {
(*OS_AppTimeTickHookPtr)();
}
#endif
}
/*$PAGE*/
/*
*********************************************************************************************************
* SYS TICK HANDLER
*
* Description: Handle the system tick (SysTick) interrupt, which is used to generate the uC/OS-II tick
* interrupt.
*
* Arguments : None.
*
* Note(s) : 1) This function MUST be placed on entry 15 of the Cortex-M3 vector table.
*********************************************************************************************************
*/
void OS_CPU_SysTickHandler (void)
{
CPU_SR_ALLOC();
CPU_CRITICAL_ENTER();
OSIntNestingCtr++; /* Tell uC/OS-III that we are starting an ISR */
CPU_CRITICAL_EXIT();
OSTimeTick(); /* Call uC/OS-III's OSTimeTick() */
OSIntExit(); /* Tell uC/OS-III that we are leaving the ISR */
}
/*$PAGE*/
/*
*********************************************************************************************************
* INITIALIZE SYS TICK
*
* Description: Initialize the SysTick.
*
* Arguments : cnts Number of SysTick counts between two OS tick interrupts.
*
* Note(s) : 1) This function MUST be called after OSStart() & after processor initialization.
*********************************************************************************************************
*/
void OS_CPU_SysTickInit (CPU_INT32U cnts)
{
CPU_INT32U prio;
CPU_REG_NVIC_ST_RELOAD = cnts - 1u;
/* Set SysTick handler prio. */
prio = CPU_REG_NVIC_SHPRI3;
prio &= DEF_BIT_FIELD(24, 0);
prio |= DEF_BIT_MASK(OS_CPU_CFG_SYSTICK_PRIO, 24);
CPU_REG_NVIC_SHPRI3 = prio;
/* Enable timer. */
CPU_REG_NVIC_ST_CTRL |= CPU_REG_NVIC_ST_CTRL_CLKSOURCE |
CPU_REG_NVIC_ST_CTRL_ENABLE;
/* Enable timer interrupt. */
CPU_REG_NVIC_ST_CTRL |= CPU_REG_NVIC_ST_CTRL_TICKINT;
}

2431
UCOSIII/uCOS-III/Source/os.h Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,299 @@
/*
************************************************************************************************************************
* uC/OS-III
* The Real-Time Kernel
*
* (c) Copyright 2009-2012; Micrium, Inc.; Weston, FL
* All rights reserved. Protected by international copyright laws.
*
* OS CONFIGURATION (APPLICATION SPECIFICS)
*
* File : OS_CFG_APP.C
* By : JJL
* Version : V3.03.01
*
* LICENSING TERMS:
* ---------------
* uC/OS-III is provided in source form for FREE short-term evaluation, for educational use or
* for peaceful research. If you plan or intend to use uC/OS-III in a commercial application/
* product then, you need to contact Micrium to properly license uC/OS-III for its use in your
* application/product. We provide ALL the source code for your convenience and to help you
* experience uC/OS-III. The fact that the source is provided does NOT mean that you can use
* it commercially without paying a licensing fee.
*
* Knowledge of the source code may NOT be used to develop a similar product.
*
* Please help us continue to provide the embedded community with the finest software available.
* Your honesty is greatly appreciated.
*
* You can contact us at www.micrium.com, or by phone at +1 (954) 217-2036.
************************************************************************************************************************
* Note(s) : DO NOT CHANGE THIS FILE!
************************************************************************************************************************
*/
#define MICRIUM_SOURCE
#include <os_cfg_app.h>
#include <os.h>
#ifdef VSC_INCLUDE_SOURCE_FILE_NAMES
const CPU_CHAR *os_cfg_app__c = "$Id: $";
#endif
#define OS_CFG_IDLE_TASK_STK_LIMIT ((OS_CFG_IDLE_TASK_STK_SIZE * OS_CFG_TASK_STK_LIMIT_PCT_EMPTY) / 100u)
#define OS_CFG_INT_Q_TASK_STK_LIMIT ((OS_CFG_INT_Q_TASK_STK_SIZE * OS_CFG_TASK_STK_LIMIT_PCT_EMPTY) / 100u)
#define OS_CFG_STAT_TASK_STK_LIMIT ((OS_CFG_STAT_TASK_STK_SIZE * OS_CFG_TASK_STK_LIMIT_PCT_EMPTY) / 100u)
#define OS_CFG_TICK_TASK_STK_LIMIT ((OS_CFG_TICK_TASK_STK_SIZE * OS_CFG_TASK_STK_LIMIT_PCT_EMPTY) / 100u)
#define OS_CFG_TMR_TASK_STK_LIMIT ((OS_CFG_TMR_TASK_STK_SIZE * OS_CFG_TASK_STK_LIMIT_PCT_EMPTY) / 100u)
/*
************************************************************************************************************************
* DATA STORAGE
************************************************************************************************************************
*/
CPU_STK OSCfg_IdleTaskStk [OS_CFG_IDLE_TASK_STK_SIZE];
#if (OS_CFG_ISR_POST_DEFERRED_EN > 0u)
OS_INT_Q OSCfg_IntQ [OS_CFG_INT_Q_SIZE];
CPU_STK OSCfg_IntQTaskStk [OS_CFG_INT_Q_TASK_STK_SIZE];
#endif
#if (OS_CFG_ISR_STK_SIZE > 0u)
CPU_STK OSCfg_ISRStk [OS_CFG_ISR_STK_SIZE];
#endif
#if (OS_MSG_EN > 0u)
OS_MSG OSCfg_MsgPool [OS_CFG_MSG_POOL_SIZE];
#endif
#if (OS_CFG_STAT_TASK_EN > 0u)
CPU_STK OSCfg_StatTaskStk [OS_CFG_STAT_TASK_STK_SIZE];
#endif
CPU_STK OSCfg_TickTaskStk [OS_CFG_TICK_TASK_STK_SIZE];
OS_TICK_SPOKE OSCfg_TickWheel [OS_CFG_TICK_WHEEL_SIZE];
#if (OS_CFG_TMR_EN > 0u)
CPU_STK OSCfg_TmrTaskStk [OS_CFG_TMR_TASK_STK_SIZE];
OS_TMR_SPOKE OSCfg_TmrWheel [OS_CFG_TMR_WHEEL_SIZE];
#endif
/*$PAGE*/
/*
************************************************************************************************************************
* CONSTANTS
************************************************************************************************************************
*/
CPU_STK * const OSCfg_IdleTaskStkBasePtr = (CPU_STK *)&OSCfg_IdleTaskStk[0];
CPU_STK_SIZE const OSCfg_IdleTaskStkLimit = (CPU_STK_SIZE)OS_CFG_IDLE_TASK_STK_LIMIT;
CPU_STK_SIZE const OSCfg_IdleTaskStkSize = (CPU_STK_SIZE)OS_CFG_IDLE_TASK_STK_SIZE;
CPU_INT32U const OSCfg_IdleTaskStkSizeRAM = (CPU_INT32U )sizeof(OSCfg_IdleTaskStk);
#if (OS_CFG_ISR_POST_DEFERRED_EN > 0u)
OS_INT_Q * const OSCfg_IntQBasePtr = (OS_INT_Q *)&OSCfg_IntQ[0];
OS_OBJ_QTY const OSCfg_IntQSize = (OS_OBJ_QTY )OS_CFG_INT_Q_SIZE;
CPU_INT32U const OSCfg_IntQSizeRAM = (CPU_INT32U )sizeof(OSCfg_IntQ);
CPU_STK * const OSCfg_IntQTaskStkBasePtr = (CPU_STK *)&OSCfg_IntQTaskStk[0];
CPU_STK_SIZE const OSCfg_IntQTaskStkLimit = (CPU_STK_SIZE)OS_CFG_INT_Q_TASK_STK_LIMIT;
CPU_STK_SIZE const OSCfg_IntQTaskStkSize = (CPU_STK_SIZE)OS_CFG_INT_Q_TASK_STK_SIZE;
CPU_INT32U const OSCfg_IntQTaskStkSizeRAM = (CPU_INT32U )sizeof(OSCfg_IntQTaskStk);
#else
OS_INT_Q * const OSCfg_IntQBasePtr = (OS_INT_Q *)0;
OS_OBJ_QTY const OSCfg_IntQSize = (OS_OBJ_QTY )0;
CPU_INT32U const OSCfg_IntQSizeRAM = (CPU_INT32U )0;
CPU_STK * const OSCfg_IntQTaskStkBasePtr = (CPU_STK *)0;
CPU_STK_SIZE const OSCfg_IntQTaskStkLimit = (CPU_STK_SIZE)0;
CPU_STK_SIZE const OSCfg_IntQTaskStkSize = (CPU_STK_SIZE)0;
CPU_INT32U const OSCfg_IntQTaskStkSizeRAM = (CPU_INT32U )0;
#endif
#if (OS_CFG_ISR_STK_SIZE > 0u)
CPU_STK * const OSCfg_ISRStkBasePtr = (CPU_STK *)&OSCfg_ISRStk[0];
CPU_STK_SIZE const OSCfg_ISRStkSize = (CPU_STK_SIZE)OS_CFG_ISR_STK_SIZE;
CPU_INT32U const OSCfg_ISRStkSizeRAM = (CPU_INT32U )sizeof(OSCfg_ISRStk);
#else
CPU_STK * const OSCfg_ISRStkBasePtr = (CPU_STK *)0;
CPU_STK_SIZE const OSCfg_ISRStkSize = (CPU_STK_SIZE)0;
CPU_INT32U const OSCfg_ISRStkSizeRAM = (CPU_INT32U )0;
#endif
#if (OS_MSG_EN > 0u)
OS_MSG_SIZE const OSCfg_MsgPoolSize = (OS_MSG_SIZE)OS_CFG_MSG_POOL_SIZE;
CPU_INT32U const OSCfg_MsgPoolSizeRAM = (CPU_INT32U )sizeof(OSCfg_MsgPool);
OS_MSG * const OSCfg_MsgPoolBasePtr = (OS_MSG *)&OSCfg_MsgPool[0];
#else
OS_MSG_SIZE const OSCfg_MsgPoolSize = (OS_MSG_SIZE)0;
CPU_INT32U const OSCfg_MsgPoolSizeRAM = (CPU_INT32U )0;
OS_MSG * const OSCfg_MsgPoolBasePtr = (OS_MSG *)0;
#endif
#if (OS_CFG_STAT_TASK_EN > 0u)
OS_PRIO const OSCfg_StatTaskPrio = (OS_PRIO )OS_CFG_STAT_TASK_PRIO;
OS_RATE_HZ const OSCfg_StatTaskRate_Hz = (OS_RATE_HZ )OS_CFG_STAT_TASK_RATE_HZ;
CPU_STK * const OSCfg_StatTaskStkBasePtr = (CPU_STK *)&OSCfg_StatTaskStk[0];
CPU_STK_SIZE const OSCfg_StatTaskStkLimit = (CPU_STK_SIZE)OS_CFG_STAT_TASK_STK_LIMIT;
CPU_STK_SIZE const OSCfg_StatTaskStkSize = (CPU_STK_SIZE)OS_CFG_STAT_TASK_STK_SIZE;
CPU_INT32U const OSCfg_StatTaskStkSizeRAM = (CPU_INT32U )sizeof(OSCfg_StatTaskStk);
#else
OS_PRIO const OSCfg_StatTaskPrio = (OS_PRIO )0;
OS_RATE_HZ const OSCfg_StatTaskRate_Hz = (OS_RATE_HZ )0;
CPU_STK * const OSCfg_StatTaskStkBasePtr = (CPU_STK *)0;
CPU_STK_SIZE const OSCfg_StatTaskStkLimit = (CPU_STK_SIZE)0;
CPU_STK_SIZE const OSCfg_StatTaskStkSize = (CPU_STK_SIZE)0;
CPU_INT32U const OSCfg_StatTaskStkSizeRAM = (CPU_INT32U )0;
#endif
CPU_STK_SIZE const OSCfg_StkSizeMin = (CPU_STK_SIZE)OS_CFG_STK_SIZE_MIN;
OS_RATE_HZ const OSCfg_TickRate_Hz = (OS_RATE_HZ )OS_CFG_TICK_RATE_HZ;
OS_PRIO const OSCfg_TickTaskPrio = (OS_PRIO )OS_CFG_TICK_TASK_PRIO;
CPU_STK * const OSCfg_TickTaskStkBasePtr = (CPU_STK *)&OSCfg_TickTaskStk[0];
CPU_STK_SIZE const OSCfg_TickTaskStkLimit = (CPU_STK_SIZE)OS_CFG_TICK_TASK_STK_LIMIT;
CPU_STK_SIZE const OSCfg_TickTaskStkSize = (CPU_STK_SIZE)OS_CFG_TICK_TASK_STK_SIZE;
CPU_INT32U const OSCfg_TickTaskStkSizeRAM = (CPU_INT32U )sizeof(OSCfg_TickTaskStk);
OS_OBJ_QTY const OSCfg_TickWheelSize = (OS_OBJ_QTY )OS_CFG_TICK_WHEEL_SIZE;
CPU_INT32U const OSCfg_TickWheelSizeRAM = (CPU_INT32U )sizeof(OSCfg_TickWheel);
#if (OS_CFG_TMR_EN > 0u)
OS_PRIO const OSCfg_TmrTaskPrio = (OS_PRIO )OS_CFG_TMR_TASK_PRIO;
OS_RATE_HZ const OSCfg_TmrTaskRate_Hz = (OS_RATE_HZ )OS_CFG_TMR_TASK_RATE_HZ;
CPU_STK * const OSCfg_TmrTaskStkBasePtr = (CPU_STK *)&OSCfg_TmrTaskStk[0];
CPU_STK_SIZE const OSCfg_TmrTaskStkLimit = (CPU_STK_SIZE)OS_CFG_TMR_TASK_STK_LIMIT;
CPU_STK_SIZE const OSCfg_TmrTaskStkSize = (CPU_STK_SIZE)OS_CFG_TMR_TASK_STK_SIZE;
CPU_INT32U const OSCfg_TmrTaskStkSizeRAM = (CPU_INT32U )sizeof(OSCfg_TmrTaskStk);
OS_OBJ_QTY const OSCfg_TmrWheelSize = (OS_OBJ_QTY )OS_CFG_TMR_WHEEL_SIZE;
CPU_INT32U const OSCfg_TmrWheelSizeRAM = (CPU_INT32U )sizeof(OSCfg_TmrWheel);
#else
OS_PRIO const OSCfg_TmrTaskPrio = (OS_PRIO )0;
OS_RATE_HZ const OSCfg_TmrTaskRate_Hz = (OS_RATE_HZ )0;
CPU_STK * const OSCfg_TmrTaskStkBasePtr = (CPU_STK *)0;
CPU_STK_SIZE const OSCfg_TmrTaskStkLimit = (CPU_STK_SIZE)0;
CPU_STK_SIZE const OSCfg_TmrTaskStkSize = (CPU_STK_SIZE)0;
CPU_INT32U const OSCfg_TmrTaskStkSizeRAM = (CPU_INT32U )0;
OS_OBJ_QTY const OSCfg_TmrWheelSize = (OS_OBJ_QTY )0;
CPU_INT32U const OSCfg_TmrWheelSizeRAM = (CPU_INT32U )0;
#endif
/*$PAGE*/
/*
************************************************************************************************************************
* TOTAL SIZE OF APPLICATION CONFIGURATION
************************************************************************************************************************
*/
CPU_INT32U const OSCfg_DataSizeRAM = sizeof(OSCfg_IdleTaskStk)
#if (OS_CFG_ISR_POST_DEFERRED_EN > 0u)
+ sizeof(OSCfg_IntQ)
+ sizeof(OSCfg_IntQTaskStk)
#endif
#if (OS_MSG_EN > 0u)
+ sizeof(OSCfg_MsgPool)
#endif
#if (OS_CFG_STAT_TASK_EN > 0u)
+ sizeof(OSCfg_StatTaskStk)
#endif
#if (OS_CFG_TMR_EN > 0u)
+ sizeof(OSCfg_TmrTaskStk)
+ sizeof(OSCfg_TmrWheel)
#endif
#if (OS_CFG_ISR_STK_SIZE > 0u)
+ sizeof(OSCfg_ISRStk)
#endif
+ sizeof(OSCfg_TickTaskStk)
+ sizeof(OSCfg_TickWheel);
/*$PAGE*/
/*
************************************************************************************************************************
* OS CONFIGURATION INITIALIZATION
*
* Description: This function is used to make sure that debug variables that are unused in the application are not
* optimized away. This function might not be necessary for all compilers. In this case, you should simply
* DELETE the code in this function while still leaving the declaration of the function itself.
*
* Arguments : none
*
* Returns : none
*
* Note(s) : (1) This code doesn't do anything, it simply prevents the compiler from optimizing out the 'const'
* variables which are declared in this file.
* (2) You may decide to 'compile out' the code (by using #if 0/#endif) INSIDE the function if your compiler
* DOES NOT optimize out the 'const' variables above.
************************************************************************************************************************
*/
void OSCfg_Init (void)
{
(void)&OSCfg_DataSizeRAM;
(void)&OSCfg_IdleTaskStkBasePtr;
(void)&OSCfg_IdleTaskStkLimit;
(void)&OSCfg_IdleTaskStkSize;
(void)&OSCfg_IdleTaskStkSizeRAM;
#if (OS_CFG_ISR_POST_DEFERRED_EN > 0u)
(void)&OSCfg_IntQBasePtr;
(void)&OSCfg_IntQSize;
(void)&OSCfg_IntQSizeRAM;
(void)&OSCfg_IntQTaskStkBasePtr;
(void)&OSCfg_IntQTaskStkLimit;
(void)&OSCfg_IntQTaskStkSize;
(void)&OSCfg_IntQTaskStkSizeRAM;
#endif
(void)&OSCfg_ISRStkBasePtr;
(void)&OSCfg_ISRStkSize;
(void)&OSCfg_ISRStkSizeRAM;
#if (OS_MSG_EN > 0u)
(void)&OSCfg_MsgPoolSize;
(void)&OSCfg_MsgPoolSizeRAM;
(void)&OSCfg_MsgPoolBasePtr;
#endif
#if (OS_CFG_STAT_TASK_EN > 0u)
(void)&OSCfg_StatTaskPrio;
(void)&OSCfg_StatTaskRate_Hz;
(void)&OSCfg_StatTaskStkBasePtr;
(void)&OSCfg_StatTaskStkLimit;
(void)&OSCfg_StatTaskStkSize;
(void)&OSCfg_StatTaskStkSizeRAM;
#endif
(void)&OSCfg_StkSizeMin;
(void)&OSCfg_TickRate_Hz;
(void)&OSCfg_TickTaskPrio;
(void)&OSCfg_TickTaskStkBasePtr;
(void)&OSCfg_TickTaskStkLimit;
(void)&OSCfg_TickTaskStkSize;
(void)&OSCfg_TickTaskStkSizeRAM;
(void)&OSCfg_TickWheelSize;
(void)&OSCfg_TickWheelSizeRAM;
#if (OS_CFG_TMR_EN > 0u)
(void)&OSCfg_TmrTaskPrio;
(void)&OSCfg_TmrTaskRate_Hz;
(void)&OSCfg_TmrTaskStkBasePtr;
(void)&OSCfg_TmrTaskStkLimit;
(void)&OSCfg_TmrTaskStkSize;
(void)&OSCfg_TmrTaskStkSizeRAM;
(void)&OSCfg_TmrWheelSize;
(void)&OSCfg_TmrWheelSizeRAM;
#endif
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,496 @@
/*
************************************************************************************************************************
* uC/OS-III
* The Real-Time Kernel
*
* (c) Copyright 2009-2012; Micrium, Inc.; Weston, FL
* All rights reserved. Protected by international copyright laws.
*
* DEBUGGER CONSTANTS
*
* File : OS_DBG.C
* By : JJL
* Version : V3.03.01
*
* LICENSING TERMS:
* ---------------
* uC/OS-III is provided in source form for FREE short-term evaluation, for educational use or
* for peaceful research. If you plan or intend to use uC/OS-III in a commercial application/
* product then, you need to contact Micrium to properly license uC/OS-III for its use in your
* application/product. We provide ALL the source code for your convenience and to help you
* experience uC/OS-III. The fact that the source is provided does NOT mean that you can use
* it commercially without paying a licensing fee.
*
* Knowledge of the source code may NOT be used to develop a similar product.
*
* Please help us continue to provide the embedded community with the finest software available.
* Your honesty is greatly appreciated.
*
* You can contact us at www.micrium.com, or by phone at +1 (954) 217-2036.
************************************************************************************************************************
*/
#define MICRIUM_SOURCE
#include <os.h>
#ifdef VSC_INCLUDE_SOURCE_FILE_NAMES
const CPU_CHAR *os_dbg__c = "$Id: $";
#endif
CPU_INT08U const OSDbg_DbgEn = OS_CFG_DBG_EN; /* Debug constants are defined below */
#if OS_CFG_DBG_EN > 0u
/*
************************************************************************************************************************
* DEBUG DATA
************************************************************************************************************************
*/
CPU_INT08U const OSDbg_ArgChkEn = OS_CFG_ARG_CHK_EN;
CPU_INT08U const OSDbg_AppHooksEn = OS_CFG_APP_HOOKS_EN;
CPU_INT32U const OSDbg_EndiannessTest = 0x12345678LU; /* Variable to test CPU endianness */
CPU_INT08U const OSDbg_CalledFromISRChkEn = OS_CFG_CALLED_FROM_ISR_CHK_EN;
CPU_INT08U const OSDbg_FlagEn = OS_CFG_FLAG_EN;
OS_FLAG_GRP const OSDbg_FlagGrp = { 0u };
#if OS_CFG_FLAG_EN > 0u
CPU_INT08U const OSDbg_FlagDelEn = OS_CFG_FLAG_DEL_EN;
CPU_INT08U const OSDbg_FlagModeClrEn = OS_CFG_FLAG_MODE_CLR_EN;
CPU_INT08U const OSDbg_FlagPendAbortEn = OS_CFG_FLAG_PEND_ABORT_EN;
CPU_INT16U const OSDbg_FlagGrpSize = sizeof(OS_FLAG_GRP); /* Size in Bytes of OS_FLAG_GRP */
CPU_INT16U const OSDbg_FlagWidth = sizeof(OS_FLAGS); /* Width (in bytes) of OS_FLAGS */
#else
CPU_INT08U const OSDbg_FlagDelEn = 0u;
CPU_INT08U const OSDbg_FlagModeClrEn = 0u;
CPU_INT08U const OSDbg_FlagPendAbortEn = 0u;
CPU_INT16U const OSDbg_FlagGrpSize = 0u;
CPU_INT16U const OSDbg_FlagWidth = 0u;
#endif
#if OS_CFG_ISR_POST_DEFERRED_EN > 0u
CPU_INT16U const OSDbg_IntQ = sizeof(OS_INT_Q);
#else
CPU_INT16U const OSDbg_IntQ = 0u;
#endif
CPU_INT08U const OSDbg_ISRPostDeferredEn = OS_CFG_ISR_POST_DEFERRED_EN;
OS_MEM const OSDbg_Mem = { 0u };
CPU_INT08U const OSDbg_MemEn = OS_CFG_MEM_EN;
#if OS_CFG_MEM_EN > 0u
CPU_INT16U const OSDbg_MemSize = sizeof(OS_MEM); /* Mem. Partition header size (bytes) */
#else
CPU_INT16U const OSDbg_MemSize = 0u;
#endif
#if (OS_MSG_EN) > 0u
CPU_INT08U const OSDbg_MsgEn = 1u;
CPU_INT16U const OSDbg_MsgSize = sizeof(OS_MSG); /* OS_MSG size */
CPU_INT16U const OSDbg_MsgPoolSize = sizeof(OS_MSG_POOL);
CPU_INT16U const OSDbg_MsgQSize = sizeof(OS_MSG_Q);
#else
CPU_INT08U const OSDbg_MsgEn = 0u;
CPU_INT16U const OSDbg_MsgSize = 0u;
CPU_INT16U const OSDbg_MsgPoolSize = 0u;
CPU_INT16U const OSDbg_MsgQSize = 0u;
#endif
OS_MUTEX const OSDbg_Mutex = { 0u };
CPU_INT08U const OSDbg_MutexEn = OS_CFG_MUTEX_EN;
#if OS_CFG_MUTEX_EN > 0u
CPU_INT08U const OSDbg_MutexDelEn = OS_CFG_MUTEX_DEL_EN;
CPU_INT08U const OSDbg_MutexPendAbortEn = OS_CFG_MUTEX_PEND_ABORT_EN;
CPU_INT16U const OSDbg_MutexSize = sizeof(OS_MUTEX); /* Size in bytes of OS_MUTEX */
#else
CPU_INT08U const OSDbg_MutexDelEn = 0u;
CPU_INT08U const OSDbg_MutexPendAbortEn = 0u;
CPU_INT16U const OSDbg_MutexSize = 0u;
#endif
CPU_INT08U const OSDbg_ObjTypeChkEn = OS_CFG_OBJ_TYPE_CHK_EN;
CPU_INT08U const OSDbg_PendMultiEn = OS_CFG_PEND_MULTI_EN;
CPU_INT16U const OSDbg_PendDataSize = sizeof(OS_PEND_DATA);
CPU_INT16U const OSDbg_PendListSize = sizeof(OS_PEND_LIST);
CPU_INT16U const OSDbg_PendObjSize = sizeof(OS_PEND_OBJ);
CPU_INT16U const OSDbg_PrioMax = OS_CFG_PRIO_MAX; /* Maximum number of priorities */
CPU_INT16U const OSDbg_PrioTblSize = sizeof(OSPrioTbl);
CPU_INT16U const OSDbg_PtrSize = sizeof(void *); /* Size in Bytes of a pointer */
OS_Q const OSDbg_Q = { 0u };
CPU_INT08U const OSDbg_QEn = OS_CFG_Q_EN;
#if OS_CFG_Q_EN > 0u
CPU_INT08U const OSDbg_QDelEn = OS_CFG_Q_DEL_EN;
CPU_INT08U const OSDbg_QFlushEn = OS_CFG_Q_FLUSH_EN;
CPU_INT08U const OSDbg_QPendAbortEn = OS_CFG_Q_PEND_ABORT_EN;
CPU_INT16U const OSDbg_QSize = sizeof(OS_Q); /* Size in bytes of OS_Q structure */
#else
CPU_INT08U const OSDbg_QDelEn = 0u;
CPU_INT08U const OSDbg_QFlushEn = 0u;
CPU_INT08U const OSDbg_QPendAbortEn = 0u;
CPU_INT16U const OSDbg_QSize = 0u;
#endif
CPU_INT08U const OSDbg_SchedRoundRobinEn = OS_CFG_SCHED_ROUND_ROBIN_EN;
OS_SEM const OSDbg_Sem = { 0u };
CPU_INT08U const OSDbg_SemEn = OS_CFG_SEM_EN;
#if OS_CFG_SEM_EN > 0u
CPU_INT08U const OSDbg_SemDelEn = OS_CFG_SEM_DEL_EN;
CPU_INT08U const OSDbg_SemPendAbortEn = OS_CFG_SEM_PEND_ABORT_EN;
CPU_INT08U const OSDbg_SemSetEn = OS_CFG_SEM_SET_EN;
CPU_INT16U const OSDbg_SemSize = sizeof(OS_SEM); /* Size in bytes of OS_SEM */
#else
CPU_INT08U const OSDbg_SemDelEn = 0u;
CPU_INT08U const OSDbg_SemPendAbortEn = 0u;
CPU_INT08U const OSDbg_SemSetEn = 0u;
CPU_INT16U const OSDbg_SemSize = 0u;
#endif
CPU_INT16U const OSDbg_RdyList = sizeof(OS_RDY_LIST);
CPU_INT32U const OSDbg_RdyListSize = sizeof(OSRdyList); /* Number of bytes in the ready table */
CPU_INT08U const OSDbg_StkWidth = sizeof(CPU_STK);
CPU_INT08U const OSDbg_StatTaskEn = OS_CFG_STAT_TASK_EN;
CPU_INT08U const OSDbg_StatTaskStkChkEn = OS_CFG_STAT_TASK_STK_CHK_EN;
CPU_INT08U const OSDbg_TaskChangePrioEn = OS_CFG_TASK_CHANGE_PRIO_EN;
CPU_INT08U const OSDbg_TaskDelEn = OS_CFG_TASK_DEL_EN;
CPU_INT08U const OSDbg_TaskQEn = OS_CFG_TASK_Q_EN;
CPU_INT08U const OSDbg_TaskQPendAbortEn = OS_CFG_TASK_Q_PEND_ABORT_EN;
CPU_INT08U const OSDbg_TaskProfileEn = OS_CFG_TASK_PROFILE_EN;
CPU_INT16U const OSDbg_TaskRegTblSize = OS_CFG_TASK_REG_TBL_SIZE;
CPU_INT08U const OSDbg_TaskSemPendAbortEn = OS_CFG_TASK_SEM_PEND_ABORT_EN;
CPU_INT08U const OSDbg_TaskSuspendEn = OS_CFG_TASK_SUSPEND_EN;
CPU_INT16U const OSDbg_TCBSize = sizeof(OS_TCB); /* Size in Bytes of OS_TCB */
CPU_INT16U const OSDbg_TickSpokeSize = sizeof(OS_TICK_SPOKE);
CPU_INT08U const OSDbg_TimeDlyHMSMEn = OS_CFG_TIME_DLY_HMSM_EN;
CPU_INT08U const OSDbg_TimeDlyResumeEn = OS_CFG_TIME_DLY_RESUME_EN;
#if defined(OS_CFG_TLS_TBL_SIZE) && (OS_CFG_TLS_TBL_SIZE > 0u)
CPU_INT16U const OSDbg_TLS_TblSize = OS_CFG_TLS_TBL_SIZE * sizeof(OS_TLS);
#else
CPU_INT16U const OSDbg_TLS_TblSize = 0u;
#endif
OS_TMR const OSDbg_Tmr = { 0u };
CPU_INT08U const OSDbg_TmrEn = OS_CFG_TMR_EN;
#if OS_CFG_TMR_EN > 0u
CPU_INT08U const OSDbg_TmrDelEn = OS_CFG_TMR_DEL_EN;
CPU_INT16U const OSDbg_TmrSize = sizeof(OS_TMR);
CPU_INT16U const OSDbg_TmrSpokeSize = sizeof(OS_TMR_SPOKE);
#else
CPU_INT08U const OSDbg_TmrDelEn = 0u;
CPU_INT16U const OSDbg_TmrSize = 0u;
CPU_INT16U const OSDbg_TmrSpokeSize = 0u;
#endif
CPU_INT16U const OSDbg_VersionNbr = OS_VERSION;
/*$PAGE*/
/*
************************************************************************************************************************
* DEBUG DATA
* TOTAL DATA SPACE (i.e. RAM) USED BY uC/OS-III
************************************************************************************************************************
*/
CPU_INT32U const OSDbg_DataSize = sizeof(OSIntNestingCtr)
#if OS_CFG_APP_HOOKS_EN > 0u
+ sizeof(OS_AppTaskCreateHookPtr)
+ sizeof(OS_AppTaskDelHookPtr)
+ sizeof(OS_AppTaskReturnHookPtr)
+ sizeof(OS_AppIdleTaskHookPtr)
+ sizeof(OS_AppStatTaskHookPtr)
+ sizeof(OS_AppTaskSwHookPtr)
+ sizeof(OS_AppTimeTickHookPtr)
#endif
+ sizeof(OSIdleTaskCtr)
+ sizeof(OSIdleTaskTCB)
#ifdef CPU_CFG_INT_DIS_MEAS_EN
+ sizeof(OSIntDisTimeMax)
#endif
#if OS_CFG_ISR_POST_DEFERRED_EN > 0u
+ sizeof(OSIntQInPtr)
+ sizeof(OSIntQOutPtr)
+ sizeof(OSIntQNbrEntries)
+ sizeof(OSIntQNbrEntriesMax)
+ sizeof(OSIntQOvfCtr)
+ sizeof(OSIntQTaskTCB)
+ sizeof(OSIntQTaskTimeMax)
#endif
+ sizeof(OSRunning)
#ifdef OS_SAFETY_CRITICAL_IEC61508
+ sizeof(OSSafetyCriticalStartFlag)
#endif
#if OS_CFG_FLAG_EN > 0u
+ sizeof(OSFlagDbgListPtr)
+ sizeof(OSFlagQty)
#endif
#if OS_CFG_MEM_EN > 0u
#if OS_CFG_DBG_EN > 0u
+ sizeof(OSMemDbgListPtr)
#endif
+ sizeof(OSMemQty)
#endif
#if OS_MSG_EN > 0u
+ sizeof(OSMsgPool)
#endif
#if OS_CFG_MUTEX_EN > 0u
#if OS_CFG_DBG_EN > 0u
+ sizeof(OSMutexDbgListPtr)
#endif
+ sizeof(OSMutexQty)
#endif
+ sizeof(OSPrioCur)
+ sizeof(OSPrioHighRdy)
+ sizeof(OSPrioSaved)
+ sizeof(OSPrioTbl)
#if OS_CFG_Q_EN > 0u
#if OS_CFG_DBG_EN > 0u
+ sizeof(OSQDbgListPtr)
#endif
+ sizeof(OSQQty)
#endif
+ sizeof(OSRdyList)
+ sizeof(OSSchedLockNestingCtr)
#if OS_CFG_SCHED_LOCK_TIME_MEAS_EN > 0u
+ sizeof(OSSchedLockTimeBegin)
+ sizeof(OSSchedLockTimeMax)
+ sizeof(OSSchedLockTimeMaxCur)
#endif
#if OS_CFG_SCHED_ROUND_ROBIN_EN
+ sizeof(OSSchedRoundRobinDfltTimeQuanta)
+ sizeof(OSSchedRoundRobinEn)
#endif
#if OS_CFG_SEM_EN > 0u
#if OS_CFG_DBG_EN > 0u
+ sizeof(OSSemDbgListPtr)
#endif
+ sizeof(OSSemQty)
#endif
+ sizeof(OSTaskCtxSwCtr)
#if OS_CFG_DBG_EN > 0u
+ sizeof(OSTaskDbgListPtr)
#endif
+ sizeof(OSTaskQty)
#if OS_CFG_STAT_TASK_EN > 0u
+ sizeof(OSStatResetFlag)
+ sizeof(OSStatTaskCPUUsage)
+ sizeof(OSStatTaskCPUUsageMax)
+ sizeof(OSStatTaskCtr)
+ sizeof(OSStatTaskCtrMax)
+ sizeof(OSStatTaskCtrRun)
+ sizeof(OSStatTaskRdy)
+ sizeof(OSStatTaskTCB)
+ sizeof(OSStatTaskTimeMax)
#endif
+ sizeof(OSTickCtr)
+ sizeof(OSTickTaskTCB)
+ sizeof(OSTickTaskTimeMax)
#if OS_CFG_TMR_EN > 0u
#if OS_CFG_DBG_EN > 0u
+ sizeof(OSTmrDbgListPtr)
#endif
+ sizeof(OSTmrQty)
+ sizeof(OSTmrTaskTCB)
+ sizeof(OSTmrTaskTimeMax)
+ sizeof(OSTmrTickCtr)
+ sizeof(OSTmrUpdateCnt)
+ sizeof(OSTmrUpdateCtr)
#endif
#if OS_CFG_TASK_REG_TBL_SIZE > 0u
+ sizeof(OSTaskRegNextAvailID)
#endif
+ sizeof(OSTCBCurPtr)
+ sizeof(OSTCBHighRdyPtr);
/*$PAGE*/
/*
************************************************************************************************************************
* OS DEBUG INITIALIZATION
*
* Description: This function is used to make sure that debug variables that are unused in the application are not
* optimized away. This function might not be necessary for all compilers. In this case, you should simply
* DELETE the code in this function while still leaving the declaration of the function itself.
*
* Arguments : none
*
* Returns : none
*
* Note(s) : (1) This code doesn't do anything, it simply prevents the compiler from optimizing out the 'const'
* variables which are declared in this file.
* (2) You may decide to 'compile out' the code (by using #if 0/#endif) INSIDE the function if your compiler
* DOES NOT optimize out the 'const' variables above.
************************************************************************************************************************
*/
void OS_Dbg_Init (void)
{
CPU_INT08U const *p_temp08;
CPU_INT16U const *p_temp16;
CPU_INT32U const *p_temp32;
p_temp08 = (CPU_INT08U const *)&OSDbg_DbgEn;
p_temp32 = (CPU_INT32U const *)&OSDbg_DataSize;
p_temp08 = (CPU_INT08U const *)&OSDbg_ArgChkEn;
p_temp08 = (CPU_INT08U const *)&OSDbg_AppHooksEn;
p_temp32 = (CPU_INT32U const *)&OSDbg_EndiannessTest;
p_temp08 = (CPU_INT08U const *)&OSDbg_CalledFromISRChkEn;
p_temp16 = (CPU_INT16U const *)&OSDbg_FlagGrp;
p_temp08 = (CPU_INT08U const *)&OSDbg_FlagEn;
#if OS_CFG_FLAG_EN > 0u
p_temp08 = (CPU_INT08U const *)&OSDbg_FlagDelEn;
p_temp08 = (CPU_INT08U const *)&OSDbg_FlagModeClrEn;
p_temp08 = (CPU_INT08U const *)&OSDbg_FlagPendAbortEn;
p_temp16 = (CPU_INT16U const *)&OSDbg_FlagGrpSize;
p_temp16 = (CPU_INT16U const *)&OSDbg_FlagWidth;
#endif
#if OS_CFG_ISR_POST_DEFERRED_EN > 0u
p_temp16 = (CPU_INT16U const *)&OSDbg_IntQ;
#endif
p_temp08 = (CPU_INT08U const *)&OSDbg_ISRPostDeferredEn;
p_temp16 = (CPU_INT16U const *)&OSDbg_Mem;
p_temp08 = (CPU_INT08U const *)&OSDbg_MemEn;
#if OS_CFG_MEM_EN > 0u
p_temp16 = (CPU_INT16U const *)&OSDbg_MemSize;
#endif
p_temp08 = (CPU_INT08U const *)&OSDbg_MsgEn;
#if (OS_MSG_EN) > 0u
p_temp16 = (CPU_INT16U const *)&OSDbg_MsgSize;
p_temp16 = (CPU_INT16U const *)&OSDbg_MsgPoolSize;
p_temp16 = (CPU_INT16U const *)&OSDbg_MsgQSize;
#endif
p_temp16 = (CPU_INT16U const *)&OSDbg_Mutex;
p_temp08 = (CPU_INT08U const *)&OSDbg_MutexEn;
#if (OS_CFG_MUTEX_EN) > 0u
p_temp08 = (CPU_INT08U const *)&OSDbg_MutexDelEn;
p_temp08 = (CPU_INT08U const *)&OSDbg_MutexPendAbortEn;
p_temp16 = (CPU_INT16U const *)&OSDbg_MutexSize;
#endif
p_temp08 = (CPU_INT08U const *)&OSDbg_ObjTypeChkEn;
p_temp08 = (CPU_INT08U const *)&OSDbg_PendMultiEn;
p_temp16 = (CPU_INT16U const *)&OSDbg_PendDataSize;
p_temp16 = (CPU_INT16U const *)&OSDbg_PendListSize;
p_temp16 = (CPU_INT16U const *)&OSDbg_PendObjSize;
p_temp16 = (CPU_INT16U const *)&OSDbg_PrioMax;
p_temp16 = (CPU_INT16U const *)&OSDbg_PrioTblSize;
p_temp16 = (CPU_INT16U const *)&OSDbg_PtrSize;
p_temp16 = (CPU_INT16U const *)&OSDbg_Q;
p_temp08 = (CPU_INT08U const *)&OSDbg_QEn;
#if (OS_CFG_Q_EN) > 0u
p_temp08 = (CPU_INT08U const *)&OSDbg_QDelEn;
p_temp08 = (CPU_INT08U const *)&OSDbg_QFlushEn;
p_temp08 = (CPU_INT08U const *)&OSDbg_QPendAbortEn;
p_temp16 = (CPU_INT16U const *)&OSDbg_QSize;
#endif
p_temp16 = (CPU_INT16U const *)&OSDbg_SchedRoundRobinEn;
p_temp16 = (CPU_INT16U const *)&OSDbg_Sem;
p_temp08 = (CPU_INT08U const *)&OSDbg_SemEn;
#if (OS_CFG_SEM_EN) > 0u
p_temp08 = (CPU_INT08U const *)&OSDbg_SemDelEn;
p_temp08 = (CPU_INT08U const *)&OSDbg_SemPendAbortEn;
p_temp16 = (CPU_INT16U const *)&OSDbg_SemSetEn;
p_temp16 = (CPU_INT16U const *)&OSDbg_SemSize;
#endif
p_temp16 = (CPU_INT16U const *)&OSDbg_RdyList;
p_temp32 = (CPU_INT32U const *)&OSDbg_RdyListSize;
p_temp16 = (CPU_INT16U const *)&OSDbg_StkWidth;
p_temp08 = (CPU_INT08U const *)&OSDbg_StatTaskEn;
p_temp08 = (CPU_INT08U const *)&OSDbg_StatTaskStkChkEn;
p_temp08 = (CPU_INT08U const *)&OSDbg_TaskChangePrioEn;
p_temp08 = (CPU_INT08U const *)&OSDbg_TaskDelEn;
p_temp08 = (CPU_INT08U const *)&OSDbg_TaskQEn;
p_temp08 = (CPU_INT08U const *)&OSDbg_TaskQPendAbortEn;
p_temp08 = (CPU_INT08U const *)&OSDbg_TaskProfileEn;
p_temp16 = (CPU_INT16U const *)&OSDbg_TaskRegTblSize;
p_temp08 = (CPU_INT08U const *)&OSDbg_TaskSemPendAbortEn;
p_temp08 = (CPU_INT08U const *)&OSDbg_TaskSuspendEn;
p_temp16 = (CPU_INT16U const *)&OSDbg_TCBSize;
p_temp16 = (CPU_INT16U const *)&OSDbg_TickSpokeSize;
p_temp08 = (CPU_INT08U const *)&OSDbg_TimeDlyHMSMEn;
p_temp08 = (CPU_INT08U const *)&OSDbg_TimeDlyResumeEn;
p_temp16 = (CPU_INT16U const *)&OSDbg_Tmr;
p_temp08 = (CPU_INT08U const *)&OSDbg_TmrEn;
#if (OS_CFG_TMR_EN) > 0u
p_temp08 = (CPU_INT08U const *)&OSDbg_TmrDelEn;
p_temp16 = (CPU_INT16U const *)&OSDbg_TmrSize;
p_temp16 = (CPU_INT16U const *)&OSDbg_TmrSpokeSize;
#endif
p_temp16 = (CPU_INT16U const *)&OSDbg_VersionNbr;
p_temp08 = p_temp08; /* Prevent compiler warning for not using 'p_temp' */
p_temp16 = p_temp16;
p_temp32 = p_temp32;
}
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,408 @@
/*
************************************************************************************************************************
* uC/OS-III
* The Real-Time Kernel
*
* (c) Copyright 2009-2012; Micrium, Inc.; Weston, FL
* All rights reserved. Protected by international copyright laws.
*
* ISR QUEUE MANAGEMENT
*
* File : OS_INT.C
* By : JJL
* Version : V3.03.01
*
* LICENSING TERMS:
* ---------------
* uC/OS-III is provided in source form for FREE short-term evaluation, for educational use or
* for peaceful research. If you plan or intend to use uC/OS-III in a commercial application/
* product then, you need to contact Micrium to properly license uC/OS-III for its use in your
* application/product. We provide ALL the source code for your convenience and to help you
* experience uC/OS-III. The fact that the source is provided does NOT mean that you can use
* it commercially without paying a licensing fee.
*
* Knowledge of the source code may NOT be used to develop a similar product.
*
* Please help us continue to provide the embedded community with the finest software available.
* Your honesty is greatly appreciated.
*
* You can contact us at www.micrium.com, or by phone at +1 (954) 217-2036.
************************************************************************************************************************
*/
#define MICRIUM_SOURCE
#include <os.h>
#ifdef VSC_INCLUDE_SOURCE_FILE_NAMES
const CPU_CHAR *os_int__c = "$Id: $";
#endif
#if OS_CFG_ISR_POST_DEFERRED_EN > 0u
/*$PAGE*/
/*
************************************************************************************************************************
* POST TO ISR QUEUE
*
* Description: This function places contents of posts into an intermediate queue to help defer processing of interrupts
* at the task level.
*
* Arguments : type is the type of kernel object the post is destined to:
*
* OS_OBJ_TYPE_SEM
* OS_OBJ_TYPE_Q
* OS_OBJ_TYPE_FLAG
* OS_OBJ_TYPE_TASK_MSG
* OS_OBJ_TYPE_TASK_SIGNAL
*
* p_obj is a pointer to the kernel object to post to. This can be a pointer to a semaphore,
* ----- a message queue or a task control clock.
*
* p_void is a pointer to a message that is being posted. This is used when posting to a message
* queue or directly to a task.
*
* msg_size is the size of the message being posted
*
* flags if the post is done to an event flag group then this corresponds to the flags being
* posted
*
* ts is a timestamp as to when the post was done
*
* opt this corresponds to post options and applies to:
*
* OSFlagPost()
* OSSemPost()
* OSQPost()
* OSTaskQPost()
*
* p_err is a pointer to a variable that will contain an error code returned by this function.
*
* OS_ERR_NONE if the post to the ISR queue was successful
* OS_ERR_INT_Q_FULL if the ISR queue is full and cannot accepts any further posts. This
* generally indicates that you are receiving interrupts faster than you
* can process them or, that you didn't make the ISR queue large enough.
*
* Returns : none
*
* Note(s) : none
************************************************************************************************************************
*/
void OS_IntQPost (OS_OBJ_TYPE type,
void *p_obj,
void *p_void,
OS_MSG_SIZE msg_size,
OS_FLAGS flags,
OS_OPT opt,
CPU_TS ts,
OS_ERR *p_err)
{
CPU_SR_ALLOC();
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return;
}
#endif
CPU_CRITICAL_ENTER();
if (OSIntQNbrEntries < OSCfg_IntQSize) { /* Make sure we haven't already filled the ISR queue */
OSIntQNbrEntries++;
if (OSIntQNbrEntriesMax < OSIntQNbrEntries) {
OSIntQNbrEntriesMax = OSIntQNbrEntries;
}
OSIntQInPtr->Type = type; /* Save object type being posted */
OSIntQInPtr->ObjPtr = p_obj; /* Save pointer to object being posted */
OSIntQInPtr->MsgPtr = p_void; /* Save pointer to message if posting to a message queue */
OSIntQInPtr->MsgSize = msg_size; /* Save the message size if posting to a message queue */
OSIntQInPtr->Flags = flags; /* Save the flags if posting to an event flag group */
OSIntQInPtr->Opt = opt; /* Save post options */
OSIntQInPtr->TS = ts; /* Save time stamp */
OSIntQInPtr = OSIntQInPtr->NextPtr; /* Point to the next interrupt handler queue entry */
OSRdyList[0].NbrEntries = (OS_OBJ_QTY)1; /* Make the interrupt handler task ready to run */
OSRdyList[0].HeadPtr = &OSIntQTaskTCB;
OSRdyList[0].TailPtr = &OSIntQTaskTCB;
OS_PrioInsert(0u); /* Add task priority 0 in the priority table */
if (OSPrioCur != 0) { /* Chk if OSIntQTask is not running */
OSPrioSaved = OSPrioCur; /* Save current priority */
}
*p_err = OS_ERR_NONE;
} else {
OSIntQOvfCtr++; /* Count the number of ISR queue overflows */
*p_err = OS_ERR_INT_Q_FULL;
}
CPU_CRITICAL_EXIT();
}
/*$PAGE*/
/*
************************************************************************************************************************
* INTERRUPT QUEUE MANAGEMENT TASK
*
* Description: This task is created by OS_IntQTaskInit().
*
* Arguments : p_arg is a pointer to an optional argument that is passed during task creation. For this function
* the argument is not used and will be a NULL pointer.
*
* Returns : none
************************************************************************************************************************
*/
void OS_IntQRePost (void)
{
CPU_TS ts;
OS_ERR err;
switch (OSIntQOutPtr->Type) { /* Re-post to task */
case OS_OBJ_TYPE_FLAG:
#if OS_CFG_FLAG_EN > 0u
(void)OS_FlagPost((OS_FLAG_GRP *) OSIntQOutPtr->ObjPtr,
(OS_FLAGS ) OSIntQOutPtr->Flags,
(OS_OPT ) OSIntQOutPtr->Opt,
(CPU_TS ) OSIntQOutPtr->TS,
(OS_ERR *)&err);
#endif
break;
case OS_OBJ_TYPE_Q:
#if OS_CFG_Q_EN > 0u
OS_QPost((OS_Q *) OSIntQOutPtr->ObjPtr,
(void *) OSIntQOutPtr->MsgPtr,
(OS_MSG_SIZE) OSIntQOutPtr->MsgSize,
(OS_OPT ) OSIntQOutPtr->Opt,
(CPU_TS ) OSIntQOutPtr->TS,
(OS_ERR *)&err);
#endif
break;
case OS_OBJ_TYPE_SEM:
#if OS_CFG_SEM_EN > 0u
(void)OS_SemPost((OS_SEM *) OSIntQOutPtr->ObjPtr,
(OS_OPT ) OSIntQOutPtr->Opt,
(CPU_TS ) OSIntQOutPtr->TS,
(OS_ERR *)&err);
#endif
break;
case OS_OBJ_TYPE_TASK_MSG:
#if OS_CFG_TASK_Q_EN > 0u
OS_TaskQPost((OS_TCB *) OSIntQOutPtr->ObjPtr,
(void *) OSIntQOutPtr->MsgPtr,
(OS_MSG_SIZE) OSIntQOutPtr->MsgSize,
(OS_OPT ) OSIntQOutPtr->Opt,
(CPU_TS ) OSIntQOutPtr->TS,
(OS_ERR *)&err);
#endif
break;
case OS_OBJ_TYPE_TASK_RESUME:
#if OS_CFG_TASK_SUSPEND_EN > 0u
(void)OS_TaskResume((OS_TCB *) OSIntQOutPtr->ObjPtr,
(OS_ERR *)&err);
#endif
break;
case OS_OBJ_TYPE_TASK_SIGNAL:
(void)OS_TaskSemPost((OS_TCB *) OSIntQOutPtr->ObjPtr,
(OS_OPT ) OSIntQOutPtr->Opt,
(CPU_TS ) OSIntQOutPtr->TS,
(OS_ERR *)&err);
break;
case OS_OBJ_TYPE_TASK_SUSPEND:
#if OS_CFG_TASK_SUSPEND_EN > 0u
(void)OS_TaskSuspend((OS_TCB *) OSIntQOutPtr->ObjPtr,
(OS_ERR *)&err);
#endif
break;
case OS_OBJ_TYPE_TICK:
#if OS_CFG_SCHED_ROUND_ROBIN_EN > 0u
OS_SchedRoundRobin(&OSRdyList[OSPrioSaved]);
#endif
(void)OS_TaskSemPost((OS_TCB *)&OSTickTaskTCB, /* Signal tick task */
(OS_OPT ) OS_OPT_POST_NONE,
(CPU_TS ) OSIntQOutPtr->TS,
(OS_ERR *)&err);
#if OS_CFG_TMR_EN > 0u
OSTmrUpdateCtr--;
if (OSTmrUpdateCtr == (OS_CTR)0u) {
OSTmrUpdateCtr = OSTmrUpdateCnt;
ts = OS_TS_GET(); /* Get timestamp */
(void)OS_TaskSemPost((OS_TCB *)&OSTmrTaskTCB, /* Signal timer task */
(OS_OPT ) OS_OPT_POST_NONE,
(CPU_TS ) ts,
(OS_ERR *)&err);
}
#endif
break;
default:
break;
}
}
/*$PAGE*/
/*
************************************************************************************************************************
* INTERRUPT QUEUE MANAGEMENT TASK
*
* Description: This task is created by OS_IntQTaskInit().
*
* Arguments : p_arg is a pointer to an optional argument that is passed during task creation. For this function
* the argument is not used and will be a NULL pointer.
*
* Returns : none
************************************************************************************************************************
*/
void OS_IntQTask (void *p_arg)
{
CPU_BOOLEAN done;
CPU_TS ts_start;
CPU_TS ts_end;
CPU_SR_ALLOC();
p_arg = p_arg; /* Not using 'p_arg', prevent compiler warning */
while (DEF_ON) {
done = DEF_FALSE;
while (done == DEF_FALSE) {
CPU_CRITICAL_ENTER();
if (OSIntQNbrEntries == (OS_OBJ_QTY)0u) {
OSRdyList[0].NbrEntries = (OS_OBJ_QTY)0u; /* Remove from ready list */
OSRdyList[0].HeadPtr = (OS_TCB *)0;
OSRdyList[0].TailPtr = (OS_TCB *)0;
OS_PrioRemove(0u); /* Remove from the priority table */
CPU_CRITICAL_EXIT();
OSSched();
done = DEF_TRUE; /* No more entries in the queue, we are done */
} else {
CPU_CRITICAL_EXIT();
ts_start = OS_TS_GET();
OS_IntQRePost();
ts_end = OS_TS_GET() - ts_start; /* Measure execution time of tick task */
if (OSIntQTaskTimeMax < ts_end) {
OSIntQTaskTimeMax = ts_end;
}
CPU_CRITICAL_ENTER();
OSIntQOutPtr = OSIntQOutPtr->NextPtr; /* Point to next item in the ISR queue */
OSIntQNbrEntries--;
CPU_CRITICAL_EXIT();
}
}
}
}
/*$PAGE*/
/*
************************************************************************************************************************
* INITIALIZE THE ISR QUEUE
*
* Description: This function is called by OSInit() to initialize the ISR queue.
*
* Arguments : p_err is a pointer to a variable that will contain an error code returned by this function.
*
* OS_ERR_INT_Q If you didn't provide an ISR queue in OS_CFG.C
* OS_ERR_INT_Q_SIZE If you didn't specify a large enough ISR queue.
* OS_ERR_STK_INVALID If you specified a NULL pointer for the task of the ISR task
* handler
* OS_ERR_STK_SIZE_INVALID If you didn't specify a stack size greater than the minimum
* specified by OS_CFG_STK_SIZE_MIN
* OS_ERR_??? An error code returned by OSTaskCreate().
*
* Returns : none
*
* Note(s) : none
************************************************************************************************************************
*/
void OS_IntQTaskInit (OS_ERR *p_err)
{
OS_INT_Q *p_int_q;
OS_INT_Q *p_int_q_next;
OS_OBJ_QTY i;
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return;
}
#endif
OSIntQOvfCtr = (OS_QTY)0u; /* Clear the ISR queue overflow counter */
if (OSCfg_IntQBasePtr == (OS_INT_Q *)0) {
*p_err = OS_ERR_INT_Q;
return;
}
if (OSCfg_IntQSize < (OS_OBJ_QTY)2u) {
*p_err = OS_ERR_INT_Q_SIZE;
return;
}
OSIntQTaskTimeMax = (CPU_TS)0;
p_int_q = OSCfg_IntQBasePtr; /* Initialize the circular ISR queue */
p_int_q_next = p_int_q;
p_int_q_next++;
for (i = 0u; i < OSCfg_IntQSize; i++) {
p_int_q->Type = OS_OBJ_TYPE_NONE;
p_int_q->ObjPtr = (void *)0;
p_int_q->MsgPtr = (void *)0;
p_int_q->MsgSize = (OS_MSG_SIZE)0u;
p_int_q->Flags = (OS_FLAGS )0u;
p_int_q->Opt = (OS_OPT )0u;
p_int_q->NextPtr = p_int_q_next;
p_int_q++;
p_int_q_next++;
}
p_int_q--;
p_int_q_next = OSCfg_IntQBasePtr;
p_int_q->NextPtr = p_int_q_next;
OSIntQInPtr = p_int_q_next;
OSIntQOutPtr = p_int_q_next;
OSIntQNbrEntries = (OS_OBJ_QTY)0u;
OSIntQNbrEntriesMax = (OS_OBJ_QTY)0u;
/* -------------- CREATE THE ISR QUEUE TASK ------------- */
if (OSCfg_IntQTaskStkBasePtr == (CPU_STK *)0) {
*p_err = OS_ERR_INT_Q_STK_INVALID;
return;
}
if (OSCfg_IntQTaskStkSize < OSCfg_StkSizeMin) {
*p_err = OS_ERR_INT_Q_STK_SIZE_INVALID;
return;
}
OSTaskCreate((OS_TCB *)&OSIntQTaskTCB,
(CPU_CHAR *)((void *)"uC/OS-III ISR Queue Task"),
(OS_TASK_PTR )OS_IntQTask,
(void *)0,
(OS_PRIO )0u, /* This task is ALWAYS at priority '0' (i.e. highest) */
(CPU_STK *)OSCfg_IntQTaskStkBasePtr,
(CPU_STK_SIZE)OSCfg_IntQTaskStkLimit,
(CPU_STK_SIZE)OSCfg_IntQTaskStkSize,
(OS_MSG_QTY )0u,
(OS_TICK )0u,
(void *)0,
(OS_OPT )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
(OS_ERR *)p_err);
}
#endif

View File

@@ -0,0 +1,347 @@
/*
************************************************************************************************************************
* uC/OS-III
* The Real-Time Kernel
*
* (c) Copyright 2009-2012; Micrium, Inc.; Weston, FL
* All rights reserved. Protected by international copyright laws.
*
* MEMORY PARTITION MANAGEMENT
*
* File : OS_MEM.C
* By : JJL
* Version : V3.03.01
*
* LICENSING TERMS:
* ---------------
* uC/OS-III is provided in source form for FREE short-term evaluation, for educational use or
* for peaceful research. If you plan or intend to use uC/OS-III in a commercial application/
* product then, you need to contact Micrium to properly license uC/OS-III for its use in your
* application/product. We provide ALL the source code for your convenience and to help you
* experience uC/OS-III. The fact that the source is provided does NOT mean that you can use
* it commercially without paying a licensing fee.
*
* Knowledge of the source code may NOT be used to develop a similar product.
*
* Please help us continue to provide the embedded community with the finest software available.
* Your honesty is greatly appreciated.
*
* You can contact us at www.micrium.com, or by phone at +1 (954) 217-2036.
************************************************************************************************************************
*/
#define MICRIUM_SOURCE
#include <os.h>
#ifdef VSC_INCLUDE_SOURCE_FILE_NAMES
const CPU_CHAR *os_mem__c = "$Id: $";
#endif
#if OS_CFG_MEM_EN > 0u
/*
************************************************************************************************************************
* CREATE A MEMORY PARTITION
*
* Description : Create a fixed-sized memory partition that will be managed by uC/OS-III.
*
* Arguments : p_mem is a pointer to a memory partition control block which is allocated in user memory space.
*
* p_name is a pointer to an ASCII string to provide a name to the memory partition.
*
* p_addr is the starting address of the memory partition
*
* n_blks is the number of memory blocks to create from the partition.
*
* blk_size is the size (in bytes) of each block in the memory partition.
*
* p_err is a pointer to a variable containing an error message which will be set by this function to
* either:
*
* OS_ERR_NONE if the memory partition has been created correctly.
* OS_ERR_ILLEGAL_CREATE_RUN_TIME if you are trying to create the memory partition after you
* called OSSafetyCriticalStart().
* OS_ERR_MEM_INVALID_BLKS user specified an invalid number of blocks (must be >= 2)
* OS_ERR_MEM_INVALID_P_ADDR if you are specifying an invalid address for the memory
* storage of the partition or, the block does not align on a
* pointer boundary
* OS_ERR_MEM_INVALID_SIZE user specified an invalid block size
* - must be greater than the size of a pointer
* - must be able to hold an integral number of pointers
* Returns : none
************************************************************************************************************************
*/
void OSMemCreate (OS_MEM *p_mem,
CPU_CHAR *p_name,
void *p_addr,
OS_MEM_QTY n_blks,
OS_MEM_SIZE blk_size,
OS_ERR *p_err)
{
#if OS_CFG_ARG_CHK_EN > 0u
CPU_DATA align_msk;
#endif
OS_MEM_QTY i;
OS_MEM_QTY loops;
CPU_INT08U *p_blk;
void **p_link;
CPU_SR_ALLOC();
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return;
}
#endif
#ifdef OS_SAFETY_CRITICAL_IEC61508
if (OSSafetyCriticalStartFlag == DEF_TRUE) {
*p_err = OS_ERR_ILLEGAL_CREATE_RUN_TIME;
return;
}
#endif
#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u
if (OSIntNestingCtr > (OS_NESTING_CTR)0) { /* Not allowed to call from an ISR */
*p_err = OS_ERR_MEM_CREATE_ISR;
return;
}
#endif
#if OS_CFG_ARG_CHK_EN > 0u
if (p_addr == (void *)0) { /* Must pass a valid address for the memory part. */
*p_err = OS_ERR_MEM_INVALID_P_ADDR;
return;
}
if (n_blks < (OS_MEM_QTY)2) { /* Must have at least 2 blocks per partition */
*p_err = OS_ERR_MEM_INVALID_BLKS;
return;
}
if (blk_size < sizeof(void *)) { /* Must contain space for at least a pointer */
*p_err = OS_ERR_MEM_INVALID_SIZE;
return;
}
align_msk = sizeof(void *) - 1u;
if (align_msk > 0u) {
if (((CPU_ADDR)p_addr & align_msk) != 0u){ /* Must be pointer size aligned */
*p_err = OS_ERR_MEM_INVALID_P_ADDR;
return;
}
if ((blk_size & align_msk) != 0u) { /* Block size must be a multiple address size */
*p_err = OS_ERR_MEM_INVALID_SIZE;
return;
}
}
#endif
p_link = (void **)p_addr; /* Create linked list of free memory blocks */
p_blk = (CPU_INT08U *)p_addr;
loops = n_blks - 1u;
for (i = 0u; i < loops; i++) {
p_blk += blk_size;
*p_link = (void *)p_blk; /* Save pointer to NEXT block in CURRENT block */
p_link = (void **)(void *)p_blk; /* Position to NEXT block */
}
*p_link = (void *)0; /* Last memory block points to NULL */
OS_CRITICAL_ENTER();
p_mem->Type = OS_OBJ_TYPE_MEM; /* Set the type of object */
p_mem->NamePtr = p_name; /* Save name of memory partition */
p_mem->AddrPtr = p_addr; /* Store start address of memory partition */
p_mem->FreeListPtr = p_addr; /* Initialize pointer to pool of free blocks */
p_mem->NbrFree = n_blks; /* Store number of free blocks in MCB */
p_mem->NbrMax = n_blks;
p_mem->BlkSize = blk_size; /* Store block size of each memory blocks */
#if OS_CFG_DBG_EN > 0u
OS_MemDbgListAdd(p_mem);
#endif
OSMemQty++;
OS_CRITICAL_EXIT_NO_SCHED();
*p_err = OS_ERR_NONE;
}
/*$PAGE*/
/*
************************************************************************************************************************
* GET A MEMORY BLOCK
*
* Description : Get a memory block from a partition
*
* Arguments : p_mem is a pointer to the memory partition control block
*
* p_err is a pointer to a variable containing an error message which will be set by this function to
* either:
*
* OS_ERR_NONE if the memory partition has been created correctly.
* OS_ERR_MEM_INVALID_P_MEM if you passed a NULL pointer for 'p_mem'
* OS_ERR_MEM_NO_FREE_BLKS if there are no more free memory blocks to allocate to the caller
*
* Returns : A pointer to a memory block if no error is detected
* A pointer to NULL if an error is detected
************************************************************************************************************************
*/
void *OSMemGet (OS_MEM *p_mem,
OS_ERR *p_err)
{
void *p_blk;
CPU_SR_ALLOC();
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return ((void *)0);
}
#endif
#if OS_CFG_ARG_CHK_EN > 0u
if (p_mem == (OS_MEM *)0) { /* Must point to a valid memory partition */
*p_err = OS_ERR_MEM_INVALID_P_MEM;
return ((void *)0);
}
#endif
CPU_CRITICAL_ENTER();
if (p_mem->NbrFree == (OS_MEM_QTY)0) { /* See if there are any free memory blocks */
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_MEM_NO_FREE_BLKS; /* No, Notify caller of empty memory partition */
return ((void *)0); /* Return NULL pointer to caller */
}
p_blk = p_mem->FreeListPtr; /* Yes, point to next free memory block */
p_mem->FreeListPtr = *(void **)p_blk; /* Adjust pointer to new free list */
p_mem->NbrFree--; /* One less memory block in this partition */
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_NONE; /* No error */
return (p_blk); /* Return memory block to caller */
}
/*$PAGE*/
/*
************************************************************************************************************************
* RELEASE A MEMORY BLOCK
*
* Description : Returns a memory block to a partition
*
* Arguments : p_mem is a pointer to the memory partition control block
*
* p_blk is a pointer to the memory block being released.
*
* p_err is a pointer to a variable that will contain an error code returned by this function.
*
* OS_ERR_NONE if the memory block was inserted into the partition
* OS_ERR_MEM_FULL if you are returning a memory block to an already FULL memory
* partition (You freed more blocks than you allocated!)
* OS_ERR_MEM_INVALID_P_BLK if you passed a NULL pointer for the block to release.
* OS_ERR_MEM_INVALID_P_MEM if you passed a NULL pointer for 'p_mem'
************************************************************************************************************************
*/
void OSMemPut (OS_MEM *p_mem,
void *p_blk,
OS_ERR *p_err)
{
CPU_SR_ALLOC();
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return;
}
#endif
#if OS_CFG_ARG_CHK_EN > 0u
if (p_mem == (OS_MEM *)0) { /* Must point to a valid memory partition */
*p_err = OS_ERR_MEM_INVALID_P_MEM;
return;
}
if (p_blk == (void *)0) { /* Must release a valid block */
*p_err = OS_ERR_MEM_INVALID_P_BLK;
return;
}
#endif
CPU_CRITICAL_ENTER();
if (p_mem->NbrFree >= p_mem->NbrMax) { /* Make sure all blocks not already returned */
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_MEM_FULL;
return;
}
*(void **)p_blk = p_mem->FreeListPtr; /* Insert released block into free block list */
p_mem->FreeListPtr = p_blk;
p_mem->NbrFree++; /* One more memory block in this partition */
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_NONE; /* Notify caller that memory block was released */
}
/*$PAGE*/
/*
************************************************************************************************************************
* ADD MEMORY PARTITION TO DEBUG LIST
*
* Description : This function is called by OSMemCreate() to add the memory partition to the debug table.
*
* Arguments : p_mem Is a pointer to the memory partition
*
* Returns : none
*
* Note(s) : This function is INTERNAL to uC/OS-III and your application should not call it.
************************************************************************************************************************
*/
#if OS_CFG_DBG_EN > 0u
void OS_MemDbgListAdd (OS_MEM *p_mem)
{
p_mem->DbgPrevPtr = (OS_MEM *)0;
if (OSMemDbgListPtr == (OS_MEM *)0) {
p_mem->DbgNextPtr = (OS_MEM *)0;
} else {
p_mem->DbgNextPtr = OSMemDbgListPtr;
OSMemDbgListPtr->DbgPrevPtr = p_mem;
}
OSMemDbgListPtr = p_mem;
}
#endif
/*$PAGE*/
/*
************************************************************************************************************************
* INITIALIZE MEMORY PARTITION MANAGER
*
* Description : This function is called by uC/OS-III to initialize the memory partition manager. Your
* application MUST NOT call this function.
*
* Arguments : none
*
* Returns : none
*
* Note(s) : This function is INTERNAL to uC/OS-III and your application should not call it.
************************************************************************************************************************
*/
void OS_MemInit (OS_ERR *p_err)
{
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return;
}
#endif
#if OS_CFG_DBG_EN > 0u
OSMemDbgListPtr = (OS_MEM *)0;
#endif
OSMemQty = (OS_OBJ_QTY)0;
*p_err = OS_ERR_NONE;
}
#endif

View File

@@ -0,0 +1,349 @@
/*
************************************************************************************************************************
* uC/OS-III
* The Real-Time Kernel
*
* (c) Copyright 2009-2012; Micrium, Inc.; Weston, FL
* All rights reserved. Protected by international copyright laws.
*
* MESSAGE HANDLING SERVICES
*
* File : OS_MSG.C
* By : JJL
* Version : V3.03.01
*
* LICENSING TERMS:
* ---------------
* uC/OS-III is provided in source form for FREE short-term evaluation, for educational use or
* for peaceful research. If you plan or intend to use uC/OS-III in a commercial application/
* product then, you need to contact Micrium to properly license uC/OS-III for its use in your
* application/product. We provide ALL the source code for your convenience and to help you
* experience uC/OS-III. The fact that the source is provided does NOT mean that you can use
* it commercially without paying a licensing fee.
*
* Knowledge of the source code may NOT be used to develop a similar product.
*
* Please help us continue to provide the embedded community with the finest software available.
* Your honesty is greatly appreciated.
*
* You can contact us at www.micrium.com, or by phone at +1 (954) 217-2036.
************************************************************************************************************************
*/
#define MICRIUM_SOURCE
#include <os.h>
#ifdef VSC_INCLUDE_SOURCE_FILE_NAMES
const CPU_CHAR *os_msg__c = "$Id: $";
#endif
#if OS_MSG_EN > 0u
/*$PAGE*/
/*
************************************************************************************************************************
* INITIALIZE THE POOL OF 'OS_MSG'
*
* Description: This function is called by OSInit() to initialize the free list of OS_MSGs.
*
* Argument(s): p_err is a pointer to a variable that will contain an error code returned by this function.
*
* OS_ERR_MSG_POOL_NULL_PTR
* OS_ERR_MSG_POOL_EMPTY
* OS_ERR_NONE
*
* Returns : none
*
* Note(s) : 1) This function is INTERNAL to uC/OS-III and your application MUST NOT call it.
************************************************************************************************************************
*/
void OS_MsgPoolInit (OS_ERR *p_err)
{
OS_MSG *p_msg1;
OS_MSG *p_msg2;
OS_MSG_QTY i;
OS_MSG_QTY loops;
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return;
}
#endif
#if OS_CFG_ARG_CHK_EN > 0u
if (OSCfg_MsgPoolBasePtr == (OS_MSG *)0) {
*p_err = OS_ERR_MSG_POOL_NULL_PTR;
return;
}
if (OSCfg_MsgPoolSize == (OS_MSG_QTY)0) {
*p_err = OS_ERR_MSG_POOL_EMPTY;
return;
}
#endif
p_msg1 = OSCfg_MsgPoolBasePtr;
p_msg2 = OSCfg_MsgPoolBasePtr;
p_msg2++;
loops = OSCfg_MsgPoolSize - 1u;
for (i = 0u; i < loops; i++) { /* Init. list of free OS_MSGs */
p_msg1->NextPtr = p_msg2;
p_msg1->MsgPtr = (void *)0;
p_msg1->MsgSize = (OS_MSG_SIZE)0u;
p_msg1->MsgTS = (CPU_TS )0u;
p_msg1++;
p_msg2++;
}
p_msg1->NextPtr = (OS_MSG *)0; /* Last OS_MSG */
p_msg1->MsgPtr = (void *)0;
p_msg1->MsgSize = (OS_MSG_SIZE)0u;
p_msg1->MsgTS = (CPU_TS )0u;
OSMsgPool.NextPtr = OSCfg_MsgPoolBasePtr;
OSMsgPool.NbrFree = OSCfg_MsgPoolSize;
OSMsgPool.NbrUsed = (OS_MSG_QTY)0;
OSMsgPool.NbrUsedMax = (OS_MSG_QTY)0;
*p_err = OS_ERR_NONE;
}
/*$PAGE*/
/*
************************************************************************************************************************
* RELEASE ALL MESSAGE IN MESSAGE QUEUE
*
* Description: This function returns all the messages in a message queue to the free list.
*
* Arguments : p_msg_q is a pointer to the OS_MSG_Q structure containing messages to free.
* -------
*
* Returns : the number of OS_MSGs returned to the free list
*
* Note(s) : 1) This function is INTERNAL to uC/OS-III and your application MUST NOT call it.
************************************************************************************************************************
*/
OS_MSG_QTY OS_MsgQFreeAll (OS_MSG_Q *p_msg_q)
{
OS_MSG *p_msg;
OS_MSG_QTY qty;
qty = p_msg_q->NbrEntries; /* Get the number of OS_MSGs being freed */
if (p_msg_q->NbrEntries > (OS_MSG_QTY)0) {
p_msg = p_msg_q->InPtr; /* Point to end of message chain */
p_msg->NextPtr = OSMsgPool.NextPtr;
OSMsgPool.NextPtr = p_msg_q->OutPtr; /* Point to beginning of message chain */
OSMsgPool.NbrUsed -= p_msg_q->NbrEntries; /* Update statistics for free list of messages */
OSMsgPool.NbrFree += p_msg_q->NbrEntries;
p_msg_q->NbrEntries = (OS_MSG_QTY)0; /* Flush the message queue */
p_msg_q->NbrEntriesMax = (OS_MSG_QTY)0;
p_msg_q->InPtr = (OS_MSG *)0;
p_msg_q->OutPtr = (OS_MSG *)0;
}
return (qty);
}
/*$PAGE*/
/*
************************************************************************************************************************
* INITIALIZE A MESSAGE QUEUE
*
* Description: This function is called to initialize a message queue
*
* Arguments : p_msg_q is a pointer to the message queue to initialize
* -------
*
* max is the maximum number of entries that a message queue can have.
*
* Returns : none
*
* Note(s) : 1) This function is INTERNAL to uC/OS-III and your application MUST NOT call it.
************************************************************************************************************************
*/
void OS_MsgQInit (OS_MSG_Q *p_msg_q,
OS_MSG_QTY size)
{
p_msg_q->NbrEntriesSize = (OS_MSG_QTY)size;
p_msg_q->NbrEntries = (OS_MSG_QTY)0;
p_msg_q->NbrEntriesMax = (OS_MSG_QTY)0;
p_msg_q->InPtr = (OS_MSG *)0;
p_msg_q->OutPtr = (OS_MSG *)0;
}
/*$PAGE*/
/*
************************************************************************************************************************
* RETRIEVE MESSAGE FROM MESSAGE QUEUE
*
* Description: This function retrieves a message from a message queue
*
* Arguments : p_msg_q is a pointer to the message queue where we want to extract the message from
* -------
*
* p_msg_size is a pointer to where the size (in bytes) of the message will be placed
*
* p_ts is a pointer to where the time stamp will be placed
*
* p_err is a pointer to an error code that will be returned from this call.
*
* OS_ERR_Q_EMPTY
* OS_ERR_NONE
*
* Returns : The message (a pointer)
*
* Note(s) : 1) This function is INTERNAL to uC/OS-III and your application MUST NOT call it.
************************************************************************************************************************
*/
void *OS_MsgQGet (OS_MSG_Q *p_msg_q,
OS_MSG_SIZE *p_msg_size,
CPU_TS *p_ts,
OS_ERR *p_err)
{
OS_MSG *p_msg;
void *p_void;
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return ((void *)0);
}
#endif
if (p_msg_q->NbrEntries == (OS_MSG_QTY)0) { /* Is the queue empty? */
*p_msg_size = (OS_MSG_SIZE)0; /* Yes */
if (p_ts != (CPU_TS *)0) {
*p_ts = (CPU_TS )0;
}
*p_err = OS_ERR_Q_EMPTY;
return ((void *)0);
}
p_msg = p_msg_q->OutPtr; /* No, get the next message to extract from the queue */
p_void = p_msg->MsgPtr;
*p_msg_size = p_msg->MsgSize;
if (p_ts != (CPU_TS *)0) {
*p_ts = p_msg->MsgTS;
}
p_msg_q->OutPtr = p_msg->NextPtr; /* Point to next message to extract */
if (p_msg_q->OutPtr == (OS_MSG *)0) { /* Are there any more messages in the queue? */
p_msg_q->InPtr = (OS_MSG *)0; /* No */
p_msg_q->NbrEntries = (OS_MSG_QTY)0;
} else {
p_msg_q->NbrEntries--; /* Yes, One less message in the queue */
}
p_msg->NextPtr = OSMsgPool.NextPtr; /* Return message control block to free list */
OSMsgPool.NextPtr = p_msg;
OSMsgPool.NbrFree++;
OSMsgPool.NbrUsed--;
*p_err = OS_ERR_NONE;
return (p_void);
}
/*$PAGE*/
/*
************************************************************************************************************************
* DEPOSIT MESSAGE IN MESSAGE QUEUE
*
* Description: This function places a message in a message queue
*
* Arguments : p_msg_q is a pointer to the OS_TCB of the task to post the message to
* -------
*
* p_void is a pointer to the message to send.
*
* msg_size is the size of the message (in bytes)
*
* opt specifies whether the message will be posted in FIFO or LIFO order
*
* OS_OPT_POST_FIFO
* OS_OPT_POST_LIFO
*
* ts is a timestamp as to when the message was posted
*
* p_err is a pointer to a variable that will contain an error code returned by this function.
*
* OS_ERR_Q_MAX if the queue is full
* OS_ERR_MSG_POOL_EMPTY if we no longer have any OS_MSG to use
* OS_ERR_NONE the message was deposited in the queue
*
* Returns : none
*
* Note(s) : 1) This function is INTERNAL to uC/OS-III and your application MUST NOT call it.
************************************************************************************************************************
*/
void OS_MsgQPut (OS_MSG_Q *p_msg_q,
void *p_void,
OS_MSG_SIZE msg_size,
OS_OPT opt,
CPU_TS ts,
OS_ERR *p_err)
{
OS_MSG *p_msg;
OS_MSG *p_msg_in;
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return;
}
#endif
if (p_msg_q->NbrEntries >= p_msg_q->NbrEntriesSize) {
*p_err = OS_ERR_Q_MAX; /* Message queue cannot accept any more messages */
return;
}
if (OSMsgPool.NbrFree == (OS_MSG_QTY)0) {
*p_err = OS_ERR_MSG_POOL_EMPTY; /* No more OS_MSG to use */
return;
}
p_msg = OSMsgPool.NextPtr; /* Remove message control block from free list */
OSMsgPool.NextPtr = p_msg->NextPtr;
OSMsgPool.NbrFree--;
OSMsgPool.NbrUsed++;
if (OSMsgPool.NbrUsedMax < OSMsgPool.NbrUsed) {
OSMsgPool.NbrUsedMax = OSMsgPool.NbrUsed;
}
if (p_msg_q->NbrEntries == (OS_MSG_QTY)0) { /* Is this first message placed in the queue? */
p_msg_q->InPtr = p_msg; /* Yes */
p_msg_q->OutPtr = p_msg;
p_msg_q->NbrEntries = (OS_MSG_QTY)1;
p_msg->NextPtr = (OS_MSG *)0;
} else { /* No */
if ((opt & OS_OPT_POST_LIFO) == OS_OPT_POST_FIFO) { /* Is it FIFO or LIFO? */
p_msg_in = p_msg_q->InPtr; /* FIFO, add to the head */
p_msg_in->NextPtr = p_msg;
p_msg_q->InPtr = p_msg;
p_msg->NextPtr = (OS_MSG *)0;
} else {
p_msg->NextPtr = p_msg_q->OutPtr; /* LIFO, add to the tail */
p_msg_q->OutPtr = p_msg;
}
p_msg_q->NbrEntries++;
}
if (p_msg_q->NbrEntriesMax < p_msg_q->NbrEntries) {
p_msg_q->NbrEntriesMax = p_msg_q->NbrEntries;
}
p_msg->MsgPtr = p_void; /* Deposit message in the message queue entry */
p_msg->MsgSize = msg_size;
p_msg->MsgTS = ts;
*p_err = OS_ERR_NONE;
}
#endif

View File

@@ -0,0 +1,874 @@
/*
************************************************************************************************************************
* uC/OS-III
* The Real-Time Kernel
*
* (c) Copyright 2009-2012; Micrium, Inc.; Weston, FL
* All rights reserved. Protected by international copyright laws.
*
* MUTEX MANAGEMENT
*
* File : OS_MUTEX.C
* By : JJL
* Version : V3.03.01
*
* LICENSING TERMS:
* ---------------
* uC/OS-III is provided in source form for FREE short-term evaluation, for educational use or
* for peaceful research. If you plan or intend to use uC/OS-III in a commercial application/
* product then, you need to contact Micrium to properly license uC/OS-III for its use in your
* application/product. We provide ALL the source code for your convenience and to help you
* experience uC/OS-III. The fact that the source is provided does NOT mean that you can use
* it commercially without paying a licensing fee.
*
* Knowledge of the source code may NOT be used to develop a similar product.
*
* Please help us continue to provide the embedded community with the finest software available.
* Your honesty is greatly appreciated.
*
* You can contact us at www.micrium.com, or by phone at +1 (954) 217-2036.
************************************************************************************************************************
*/
#define MICRIUM_SOURCE
#include <os.h>
#ifdef VSC_INCLUDE_SOURCE_FILE_NAMES
const CPU_CHAR *os_mutex__c = "$Id: $";
#endif
#if OS_CFG_MUTEX_EN > 0u
/*
************************************************************************************************************************
* CREATE A MUTEX
*
* Description: This function creates a mutex.
*
* Arguments : p_mutex is a pointer to the mutex to initialize. Your application is responsible for allocating
* storage for the mutex.
*
* p_name is a pointer to the name you would like to give the mutex.
*
* p_err is a pointer to a variable that will contain an error code returned by this function.
*
* OS_ERR_NONE if the call was successful
* OS_ERR_CREATE_ISR if you called this function from an ISR
* OS_ERR_ILLEGAL_CREATE_RUN_TIME if you are trying to create the Mutex after you called
* OSSafetyCriticalStart().
* OS_ERR_NAME if 'p_name' is a NULL pointer
* OS_ERR_OBJ_CREATED if the mutex has already been created
* OS_ERR_OBJ_PTR_NULL if 'p_mutex' is a NULL pointer
*
* Returns : none
************************************************************************************************************************
*/
void OSMutexCreate (OS_MUTEX *p_mutex,
CPU_CHAR *p_name,
OS_ERR *p_err)
{
CPU_SR_ALLOC();
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return;
}
#endif
#ifdef OS_SAFETY_CRITICAL_IEC61508
if (OSSafetyCriticalStartFlag == DEF_TRUE) {
*p_err = OS_ERR_ILLEGAL_CREATE_RUN_TIME;
return;
}
#endif
#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u
if (OSIntNestingCtr > (OS_NESTING_CTR)0) { /* Not allowed to be called from an ISR */
*p_err = OS_ERR_CREATE_ISR;
return;
}
#endif
#if OS_CFG_ARG_CHK_EN > 0u
if (p_mutex == (OS_MUTEX *)0) { /* Validate 'p_mutex' */
*p_err = OS_ERR_OBJ_PTR_NULL;
return;
}
#endif
OS_CRITICAL_ENTER();
p_mutex->Type = OS_OBJ_TYPE_MUTEX; /* Mark the data structure as a mutex */
p_mutex->NamePtr = p_name;
p_mutex->OwnerTCBPtr = (OS_TCB *)0;
p_mutex->OwnerNestingCtr = (OS_NESTING_CTR)0; /* Mutex is available */
p_mutex->TS = (CPU_TS )0;
p_mutex->OwnerOriginalPrio = OS_CFG_PRIO_MAX;
OS_PendListInit(&p_mutex->PendList); /* Initialize the waiting list */
#if OS_CFG_DBG_EN > 0u
OS_MutexDbgListAdd(p_mutex);
#endif
OSMutexQty++;
OS_CRITICAL_EXIT_NO_SCHED();
*p_err = OS_ERR_NONE;
}
/*$PAGE*/
/*
************************************************************************************************************************
* DELETE A MUTEX
*
* Description: This function deletes a mutex and readies all tasks pending on the mutex.
*
* Arguments : p_mutex is a pointer to the mutex to delete
*
* opt determines delete options as follows:
*
* OS_OPT_DEL_NO_PEND Delete mutex ONLY if no task pending
* OS_OPT_DEL_ALWAYS Deletes the mutex even if tasks are waiting.
* In this case, all the tasks pending will be readied.
*
* p_err is a pointer to a variable that will contain an error code returned by this function.
*
* OS_ERR_NONE The call was successful and the mutex was deleted
* OS_ERR_DEL_ISR If you attempted to delete the mutex from an ISR
* OS_ERR_OBJ_PTR_NULL If 'p_mutex' is a NULL pointer.
* OS_ERR_OBJ_TYPE If 'p_mutex' is not pointing to a mutex
* OS_ERR_OPT_INVALID An invalid option was specified
* OS_ERR_STATE_INVALID Task is in an invalid state
* OS_ERR_TASK_WAITING One or more tasks were waiting on the mutex
*
* Returns : == 0 if no tasks were waiting on the mutex, or upon error.
* > 0 if one or more tasks waiting on the mutex are now readied and informed.
*
* Note(s) : 1) This function must be used with care. Tasks that would normally expect the presence of the mutex MUST
* check the return code of OSMutexPend().
*
* 2) OSMutexAccept() callers will not know that the intended mutex has been deleted.
*
* 3) Because ALL tasks pending on the mutex will be readied, you MUST be careful in applications where the
* mutex is used for mutual exclusion because the resource(s) will no longer be guarded by the mutex.
************************************************************************************************************************
*/
#if OS_CFG_MUTEX_DEL_EN > 0u
OS_OBJ_QTY OSMutexDel (OS_MUTEX *p_mutex,
OS_OPT opt,
OS_ERR *p_err)
{
OS_OBJ_QTY cnt;
OS_OBJ_QTY nbr_tasks;
OS_PEND_DATA *p_pend_data;
OS_PEND_LIST *p_pend_list;
OS_TCB *p_tcb;
OS_TCB *p_tcb_owner;
CPU_TS ts;
CPU_SR_ALLOC();
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return ((OS_OBJ_QTY)0);
}
#endif
#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u
if (OSIntNestingCtr > (OS_NESTING_CTR)0) { /* Not allowed to delete a mutex from an ISR */
*p_err = OS_ERR_DEL_ISR;
return ((OS_OBJ_QTY)0);
}
#endif
#if OS_CFG_ARG_CHK_EN > 0u
if (p_mutex == (OS_MUTEX *)0) { /* Validate 'p_mutex' */
*p_err = OS_ERR_OBJ_PTR_NULL;
return ((OS_OBJ_QTY)0);
}
switch (opt) { /* Validate 'opt' */
case OS_OPT_DEL_NO_PEND:
case OS_OPT_DEL_ALWAYS:
break;
default:
*p_err = OS_ERR_OPT_INVALID;
return ((OS_OBJ_QTY)0);
}
#endif
#if OS_CFG_OBJ_TYPE_CHK_EN > 0u
if (p_mutex->Type != OS_OBJ_TYPE_MUTEX) { /* Make sure mutex was created */
*p_err = OS_ERR_OBJ_TYPE;
return ((OS_OBJ_QTY)0);
}
#endif
OS_CRITICAL_ENTER();
p_pend_list = &p_mutex->PendList;
cnt = p_pend_list->NbrEntries;
nbr_tasks = cnt;
switch (opt) {
case OS_OPT_DEL_NO_PEND: /* Delete mutex only if no task waiting */
if (nbr_tasks == (OS_OBJ_QTY)0) {
#if OS_CFG_DBG_EN > 0u
OS_MutexDbgListRemove(p_mutex);
#endif
OSMutexQty--;
OS_MutexClr(p_mutex);
OS_CRITICAL_EXIT();
*p_err = OS_ERR_NONE;
} else {
OS_CRITICAL_EXIT();
*p_err = OS_ERR_TASK_WAITING;
}
break;
case OS_OPT_DEL_ALWAYS: /* Always delete the mutex */
p_tcb_owner = p_mutex->OwnerTCBPtr; /* Did we had to change the prio of owner? */
if ((p_tcb_owner != (OS_TCB *)0) &&
(p_tcb_owner->Prio != p_mutex->OwnerOriginalPrio)) {
switch (p_tcb_owner->TaskState) { /* yes */
case OS_TASK_STATE_RDY:
OS_RdyListRemove(p_tcb_owner);
p_tcb_owner->Prio = p_mutex->OwnerOriginalPrio; /* Lower owner's prio back */
OS_PrioInsert(p_tcb_owner->Prio);
OS_RdyListInsertTail(p_tcb_owner); /* Insert owner in ready list at new prio */
break;
case OS_TASK_STATE_DLY:
case OS_TASK_STATE_SUSPENDED:
case OS_TASK_STATE_DLY_SUSPENDED:
p_tcb_owner->Prio = p_mutex->OwnerOriginalPrio; /* Not in any pend list, change the prio */
break;
case OS_TASK_STATE_PEND:
case OS_TASK_STATE_PEND_TIMEOUT:
case OS_TASK_STATE_PEND_SUSPENDED:
case OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED:
OS_PendListChangePrio(p_tcb_owner, /* Owner is pending on another object */
p_mutex->OwnerOriginalPrio);
break;
default:
OS_CRITICAL_EXIT();
*p_err = OS_ERR_STATE_INVALID;
return ((OS_OBJ_QTY)0);
}
}
ts = OS_TS_GET(); /* Get timestamp */
while (cnt > 0u) { /* Remove all tasks from the pend list */
p_pend_data = p_pend_list->HeadPtr;
p_tcb = p_pend_data->TCBPtr;
OS_PendObjDel((OS_PEND_OBJ *)((void *)p_mutex),
p_tcb,
ts);
cnt--;
}
#if OS_CFG_DBG_EN > 0u
OS_MutexDbgListRemove(p_mutex);
#endif
OSMutexQty--;
OS_MutexClr(p_mutex);
OS_CRITICAL_EXIT_NO_SCHED();
OSSched(); /* Find highest priority task ready to run */
*p_err = OS_ERR_NONE;
break;
default:
OS_CRITICAL_EXIT();
*p_err = OS_ERR_OPT_INVALID;
break;
}
return (nbr_tasks);
}
#endif
/*$PAGE*/
/*
************************************************************************************************************************
* PEND ON MUTEX
*
* Description: This function waits for a mutex.
*
* Arguments : p_mutex is a pointer to the mutex
*
* timeout is an optional timeout period (in clock ticks). If non-zero, your task will wait for the
* resource up to the amount of time (in 'ticks') specified by this argument. If you specify
* 0, however, your task will wait forever at the specified mutex or, until the resource
* becomes available.
*
* opt determines whether the user wants to block if the mutex is not available or not:
*
* OS_OPT_PEND_BLOCKING
* OS_OPT_PEND_NON_BLOCKING
*
* p_ts is a pointer to a variable that will receive the timestamp of when the mutex was posted or
* pend aborted or the mutex deleted. If you pass a NULL pointer (i.e. (CPU_TS *)0) then you
* will not get the timestamp. In other words, passing a NULL pointer is valid and indicates
* that you don't need the timestamp.
*
* p_err is a pointer to a variable that will contain an error code returned by this function.
*
* OS_ERR_NONE The call was successful and your task owns the resource
* OS_ERR_MUTEX_OWNER If calling task already owns the mutex
* OS_ERR_OBJ_DEL If 'p_mutex' was deleted
* OS_ERR_OBJ_PTR_NULL If 'p_mutex' is a NULL pointer.
* OS_ERR_OBJ_TYPE If 'p_mutex' is not pointing at a mutex
* OS_ERR_OPT_INVALID If you didn't specify a valid option
* OS_ERR_PEND_ABORT If the pend was aborted by another task
* OS_ERR_PEND_ISR If you called this function from an ISR and the result
* would lead to a suspension.
* OS_ERR_PEND_WOULD_BLOCK If you specified non-blocking but the mutex was not
* available.
* OS_ERR_SCHED_LOCKED If you called this function when the scheduler is locked
* OS_ERR_STATE_INVALID If the task is in an invalid state
* OS_ERR_STATUS_INVALID If the pend status has an invalid value
* OS_ERR_TIMEOUT The mutex was not received within the specified timeout.
*
* Returns : none
************************************************************************************************************************
*/
void OSMutexPend (OS_MUTEX *p_mutex,
OS_TICK timeout,
OS_OPT opt,
CPU_TS *p_ts,
OS_ERR *p_err)
{
OS_PEND_DATA pend_data;
OS_TCB *p_tcb;
CPU_SR_ALLOC();
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return;
}
#endif
#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u
if (OSIntNestingCtr > (OS_NESTING_CTR)0) { /* Not allowed to call from an ISR */
*p_err = OS_ERR_PEND_ISR;
return;
}
#endif
#if OS_CFG_ARG_CHK_EN > 0u
if (p_mutex == (OS_MUTEX *)0) { /* Validate arguments */
*p_err = OS_ERR_OBJ_PTR_NULL;
return;
}
switch (opt) { /* Validate 'opt' */
case OS_OPT_PEND_BLOCKING:
case OS_OPT_PEND_NON_BLOCKING:
break;
default:
*p_err = OS_ERR_OPT_INVALID;
return;
}
#endif
#if OS_CFG_OBJ_TYPE_CHK_EN > 0u
if (p_mutex->Type != OS_OBJ_TYPE_MUTEX) { /* Make sure mutex was created */
*p_err = OS_ERR_OBJ_TYPE;
return;
}
#endif
if (p_ts != (CPU_TS *)0) {
*p_ts = (CPU_TS )0; /* Initialize the returned timestamp */
}
CPU_CRITICAL_ENTER();
if (p_mutex->OwnerNestingCtr == (OS_NESTING_CTR)0) { /* Resource available? */
p_mutex->OwnerTCBPtr = OSTCBCurPtr; /* Yes, caller may proceed */
p_mutex->OwnerOriginalPrio = OSTCBCurPtr->Prio;
p_mutex->OwnerNestingCtr = (OS_NESTING_CTR)1;
if (p_ts != (CPU_TS *)0) {
*p_ts = p_mutex->TS;
}
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_NONE;
return;
}
if (OSTCBCurPtr == p_mutex->OwnerTCBPtr) { /* See if current task is already the owner of the mutex */
p_mutex->OwnerNestingCtr++;
if (p_ts != (CPU_TS *)0) {
*p_ts = p_mutex->TS;
}
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_MUTEX_OWNER; /* Indicate that current task already owns the mutex */
return;
}
if ((opt & OS_OPT_PEND_NON_BLOCKING) != (OS_OPT)0) { /* Caller wants to block if not available? */
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_PEND_WOULD_BLOCK; /* No */
return;
} else {
if (OSSchedLockNestingCtr > (OS_NESTING_CTR)0) { /* Can't pend when the scheduler is locked */
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_SCHED_LOCKED;
return;
}
}
/* Lock the scheduler/re-enable interrupts */
OS_CRITICAL_ENTER_CPU_EXIT();
p_tcb = p_mutex->OwnerTCBPtr; /* Point to the TCB of the Mutex owner */
if (p_tcb->Prio > OSTCBCurPtr->Prio) { /* See if mutex owner has a lower priority than current */
switch (p_tcb->TaskState) {
case OS_TASK_STATE_RDY:
OS_RdyListRemove(p_tcb); /* Remove from ready list at current priority */
p_tcb->Prio = OSTCBCurPtr->Prio; /* Raise owner's priority */
OS_PrioInsert(p_tcb->Prio);
OS_RdyListInsertHead(p_tcb); /* Insert in ready list at new priority */
break;
case OS_TASK_STATE_DLY:
case OS_TASK_STATE_DLY_SUSPENDED:
case OS_TASK_STATE_SUSPENDED:
p_tcb->Prio = OSTCBCurPtr->Prio; /* Only need to raise the owner's priority */
break;
case OS_TASK_STATE_PEND: /* Change the position of the task in the wait list */
case OS_TASK_STATE_PEND_TIMEOUT:
case OS_TASK_STATE_PEND_SUSPENDED:
case OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED:
OS_PendListChangePrio(p_tcb,
OSTCBCurPtr->Prio);
break;
default:
OS_CRITICAL_EXIT();
*p_err = OS_ERR_STATE_INVALID;
return;
}
}
OS_Pend(&pend_data, /* Block task pending on Mutex */
(OS_PEND_OBJ *)((void *)p_mutex),
OS_TASK_PEND_ON_MUTEX,
timeout);
OS_CRITICAL_EXIT_NO_SCHED();
OSSched(); /* Find the next highest priority task ready to run */
CPU_CRITICAL_ENTER();
switch (OSTCBCurPtr->PendStatus) {
case OS_STATUS_PEND_OK: /* We got the mutex */
if (p_ts != (CPU_TS *)0) {
*p_ts = OSTCBCurPtr->TS;
}
*p_err = OS_ERR_NONE;
break;
case OS_STATUS_PEND_ABORT: /* Indicate that we aborted */
if (p_ts != (CPU_TS *)0) {
*p_ts = OSTCBCurPtr->TS;
}
*p_err = OS_ERR_PEND_ABORT;
break;
case OS_STATUS_PEND_TIMEOUT: /* Indicate that we didn't get mutex within timeout */
if (p_ts != (CPU_TS *)0) {
*p_ts = (CPU_TS )0;
}
*p_err = OS_ERR_TIMEOUT;
break;
case OS_STATUS_PEND_DEL: /* Indicate that object pended on has been deleted */
if (p_ts != (CPU_TS *)0) {
*p_ts = OSTCBCurPtr->TS;
}
*p_err = OS_ERR_OBJ_DEL;
break;
default:
*p_err = OS_ERR_STATUS_INVALID;
break;
}
CPU_CRITICAL_EXIT();
}
/*$PAGE*/
/*
************************************************************************************************************************
* ABORT WAITING ON A MUTEX
*
* Description: This function aborts & readies any tasks currently waiting on a mutex. This function should be used
* to fault-abort the wait on the mutex, rather than to normally signal the mutex via OSMutexPost().
*
* Arguments : p_mutex is a pointer to the mutex
*
* opt determines the type of ABORT performed:
*
* OS_OPT_PEND_ABORT_1 ABORT wait for a single task (HPT) waiting on the mutex
* OS_OPT_PEND_ABORT_ALL ABORT wait for ALL tasks that are waiting on the mutex
* OS_OPT_POST_NO_SCHED Do not call the scheduler
*
* p_err is a pointer to a variable that will contain an error code returned by this function.
*
* OS_ERR_NONE At least one task waiting on the mutex was readied and
* informed of the aborted wait; check return value for the
* number of tasks whose wait on the mutex was aborted.
* OS_ERR_OBJ_PTR_NULL If 'p_mutex' is a NULL pointer.
* OS_ERR_OBJ_TYPE If 'p_mutex' is not pointing at a mutex
* OS_ERR_OPT_INVALID If you specified an invalid option
* OS_ERR_PEND_ABORT_ISR If you attempted to call this function from an ISR
* OS_ERR_PEND_ABORT_NONE No task were pending
*
* Returns : == 0 if no tasks were waiting on the mutex, or upon error.
* > 0 if one or more tasks waiting on the mutex are now readied and informed.
************************************************************************************************************************
*/
#if OS_CFG_MUTEX_PEND_ABORT_EN > 0u
OS_OBJ_QTY OSMutexPendAbort (OS_MUTEX *p_mutex,
OS_OPT opt,
OS_ERR *p_err)
{
OS_PEND_LIST *p_pend_list;
OS_TCB *p_tcb;
CPU_TS ts;
OS_OBJ_QTY nbr_tasks;
CPU_SR_ALLOC();
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return ((OS_OBJ_QTY)0u);
}
#endif
#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u
if (OSIntNestingCtr > (OS_NESTING_CTR)0u) { /* Not allowed to Pend Abort from an ISR */
*p_err = OS_ERR_PEND_ABORT_ISR;
return ((OS_OBJ_QTY)0u);
}
#endif
#if OS_CFG_ARG_CHK_EN > 0u
if (p_mutex == (OS_MUTEX *)0) { /* Validate 'p_mutex' */
*p_err = OS_ERR_OBJ_PTR_NULL;
return ((OS_OBJ_QTY)0u);
}
switch (opt) { /* Validate 'opt' */
case OS_OPT_PEND_ABORT_1:
case OS_OPT_PEND_ABORT_ALL:
case OS_OPT_PEND_ABORT_1 | OS_OPT_POST_NO_SCHED:
case OS_OPT_PEND_ABORT_ALL | OS_OPT_POST_NO_SCHED:
break;
default:
*p_err = OS_ERR_OPT_INVALID;
return ((OS_OBJ_QTY)0u);
}
#endif
#if OS_CFG_OBJ_TYPE_CHK_EN > 0u
if (p_mutex->Type != OS_OBJ_TYPE_MUTEX) { /* Make sure mutex was created */
*p_err = OS_ERR_OBJ_TYPE;
return ((OS_OBJ_QTY)0u);
}
#endif
CPU_CRITICAL_ENTER();
p_pend_list = &p_mutex->PendList;
if (p_pend_list->NbrEntries == (OS_OBJ_QTY)0u) { /* Any task waiting on mutex? */
CPU_CRITICAL_EXIT(); /* No */
*p_err = OS_ERR_PEND_ABORT_NONE;
return ((OS_OBJ_QTY)0u);
}
OS_CRITICAL_ENTER_CPU_EXIT();
nbr_tasks = 0u;
ts = OS_TS_GET(); /* Get local time stamp so all tasks get the same time */
while (p_pend_list->NbrEntries > (OS_OBJ_QTY)0u) {
p_tcb = p_pend_list->HeadPtr->TCBPtr;
OS_PendAbort((OS_PEND_OBJ *)((void *)p_mutex),
p_tcb,
ts);
nbr_tasks++;
if (opt != OS_OPT_PEND_ABORT_ALL) { /* Pend abort all tasks waiting? */
break; /* No */
}
}
OS_CRITICAL_EXIT_NO_SCHED();
if ((opt & OS_OPT_POST_NO_SCHED) == (OS_OPT)0u) {
OSSched(); /* Run the scheduler */
}
*p_err = OS_ERR_NONE;
return (nbr_tasks);
}
#endif
/*$PAGE*/
/*
************************************************************************************************************************
* POST TO A MUTEX
*
* Description: This function signals a mutex
*
* Arguments : p_mutex is a pointer to the mutex
*
* opt is an option you can specify to alter the behavior of the post. The choices are:
*
* OS_OPT_POST_NONE No special option selected
* OS_OPT_POST_NO_SCHED If you don't want the scheduler to be called after the post.
*
* p_err is a pointer to a variable that will contain an error code returned by this function.
*
* OS_ERR_NONE The call was successful and the mutex was signaled.
* OS_ERR_MUTEX_NESTING Mutex owner nested its use of the mutex
* OS_ERR_MUTEX_NOT_OWNER If the task posting is not the Mutex owner
* OS_ERR_OBJ_PTR_NULL If 'p_mutex' is a NULL pointer.
* OS_ERR_OBJ_TYPE If 'p_mutex' is not pointing at a mutex
* OS_ERR_POST_ISR If you attempted to post from an ISR
*
* Returns : none
************************************************************************************************************************
*/
void OSMutexPost (OS_MUTEX *p_mutex,
OS_OPT opt,
OS_ERR *p_err)
{
OS_PEND_LIST *p_pend_list;
OS_TCB *p_tcb;
CPU_TS ts;
CPU_SR_ALLOC();
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return;
}
#endif
#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u
if (OSIntNestingCtr > (OS_NESTING_CTR)0) { /* Not allowed to call from an ISR */
*p_err = OS_ERR_POST_ISR;
return;
}
#endif
#if OS_CFG_ARG_CHK_EN > 0u
if (p_mutex == (OS_MUTEX *)0) { /* Validate 'p_mutex' */
*p_err = OS_ERR_OBJ_PTR_NULL;
return;
}
switch (opt) { /* Validate 'opt' */
case OS_OPT_POST_NONE:
case OS_OPT_POST_NO_SCHED:
break;
default:
*p_err = OS_ERR_OPT_INVALID;
return;
}
#endif
#if OS_CFG_OBJ_TYPE_CHK_EN > 0u
if (p_mutex->Type != OS_OBJ_TYPE_MUTEX) { /* Make sure mutex was created */
*p_err = OS_ERR_OBJ_TYPE;
return;
}
#endif
CPU_CRITICAL_ENTER();
if (OSTCBCurPtr != p_mutex->OwnerTCBPtr) { /* Make sure the mutex owner is releasing the mutex */
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_MUTEX_NOT_OWNER;
return;
}
OS_CRITICAL_ENTER_CPU_EXIT();
ts = OS_TS_GET(); /* Get timestamp */
p_mutex->TS = ts;
p_mutex->OwnerNestingCtr--; /* Decrement owner's nesting counter */
if (p_mutex->OwnerNestingCtr > (OS_NESTING_CTR)0) { /* Are we done with all nestings? */
OS_CRITICAL_EXIT(); /* No */
*p_err = OS_ERR_MUTEX_NESTING;
return;
}
p_pend_list = &p_mutex->PendList;
if (p_pend_list->NbrEntries == (OS_OBJ_QTY)0) { /* Any task waiting on mutex? */
p_mutex->OwnerTCBPtr = (OS_TCB *)0; /* No */
p_mutex->OwnerNestingCtr = (OS_NESTING_CTR)0;
OS_CRITICAL_EXIT();
*p_err = OS_ERR_NONE;
return;
}
/* Yes */
if (OSTCBCurPtr->Prio != p_mutex->OwnerOriginalPrio) {
OS_RdyListRemove(OSTCBCurPtr);
OSTCBCurPtr->Prio = p_mutex->OwnerOriginalPrio; /* Lower owner's priority back to its original one */
OS_PrioInsert(OSTCBCurPtr->Prio);
OS_RdyListInsertTail(OSTCBCurPtr); /* Insert owner in ready list at new priority */
OSPrioCur = OSTCBCurPtr->Prio;
}
/* Get TCB from head of pend list */
p_tcb = p_pend_list->HeadPtr->TCBPtr;
p_mutex->OwnerTCBPtr = p_tcb; /* Give mutex to new owner */
p_mutex->OwnerOriginalPrio = p_tcb->Prio;
p_mutex->OwnerNestingCtr = (OS_NESTING_CTR)1;
/* Post to mutex */
OS_Post((OS_PEND_OBJ *)((void *)p_mutex),
(OS_TCB *)p_tcb,
(void *)0,
(OS_MSG_SIZE )0,
(CPU_TS )ts);
OS_CRITICAL_EXIT_NO_SCHED();
if ((opt & OS_OPT_POST_NO_SCHED) == (OS_OPT)0) {
OSSched(); /* Run the scheduler */
}
*p_err = OS_ERR_NONE;
}
/*$PAGE*/
/*
************************************************************************************************************************
* CLEAR THE CONTENTS OF A MUTEX
*
* Description: This function is called by OSMutexDel() to clear the contents of a mutex
*
* Argument(s): p_mutex is a pointer to the mutex to clear
* -------
*
* Returns : none
*
* Note(s) : This function is INTERNAL to uC/OS-III and your application should not call it.
************************************************************************************************************************
*/
void OS_MutexClr (OS_MUTEX *p_mutex)
{
p_mutex->Type = OS_OBJ_TYPE_NONE; /* Mark the data structure as a NONE */
p_mutex->NamePtr = (CPU_CHAR *)((void *)"?MUTEX");
p_mutex->OwnerTCBPtr = (OS_TCB *)0;
p_mutex->OwnerNestingCtr = (OS_NESTING_CTR)0;
p_mutex->TS = (CPU_TS )0;
p_mutex->OwnerOriginalPrio = OS_CFG_PRIO_MAX;
OS_PendListInit(&p_mutex->PendList); /* Initialize the waiting list */
}
/*$PAGE*/
/*
************************************************************************************************************************
* ADD/REMOVE MUTEX TO/FROM DEBUG LIST
*
* Description: These functions are called by uC/OS-III to add or remove a mutex to/from the debug list.
*
* Arguments : p_mutex is a pointer to the mutex to add/remove
*
* Returns : none
*
* Note(s) : These functions are INTERNAL to uC/OS-III and your application should not call it.
************************************************************************************************************************
*/
#if OS_CFG_DBG_EN > 0u
void OS_MutexDbgListAdd (OS_MUTEX *p_mutex)
{
p_mutex->DbgNamePtr = (CPU_CHAR *)((void *)" ");
p_mutex->DbgPrevPtr = (OS_MUTEX *)0;
if (OSMutexDbgListPtr == (OS_MUTEX *)0) {
p_mutex->DbgNextPtr = (OS_MUTEX *)0;
} else {
p_mutex->DbgNextPtr = OSMutexDbgListPtr;
OSMutexDbgListPtr->DbgPrevPtr = p_mutex;
}
OSMutexDbgListPtr = p_mutex;
}
void OS_MutexDbgListRemove (OS_MUTEX *p_mutex)
{
OS_MUTEX *p_mutex_next;
OS_MUTEX *p_mutex_prev;
p_mutex_prev = p_mutex->DbgPrevPtr;
p_mutex_next = p_mutex->DbgNextPtr;
if (p_mutex_prev == (OS_MUTEX *)0) {
OSMutexDbgListPtr = p_mutex_next;
if (p_mutex_next != (OS_MUTEX *)0) {
p_mutex_next->DbgPrevPtr = (OS_MUTEX *)0;
}
p_mutex->DbgNextPtr = (OS_MUTEX *)0;
} else if (p_mutex_next == (OS_MUTEX *)0) {
p_mutex_prev->DbgNextPtr = (OS_MUTEX *)0;
p_mutex->DbgPrevPtr = (OS_MUTEX *)0;
} else {
p_mutex_prev->DbgNextPtr = p_mutex_next;
p_mutex_next->DbgPrevPtr = p_mutex_prev;
p_mutex->DbgNextPtr = (OS_MUTEX *)0;
p_mutex->DbgPrevPtr = (OS_MUTEX *)0;
}
}
#endif
/*$PAGE*/
/*
************************************************************************************************************************
* MUTEX INITIALIZATION
*
* Description: This function is called by OSInit() to initialize the mutex management.
*
* Argument(s): p_err is a pointer to a variable that will contain an error code returned by this function.
*
* OS_ERR_NONE the call was successful
*
* Returns : none
*
* Note(s) : 1) This function is INTERNAL to uC/OS-III and your application MUST NOT call it.
************************************************************************************************************************
*/
void OS_MutexInit (OS_ERR *p_err)
{
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return;
}
#endif
#if OS_CFG_DBG_EN > 0u
OSMutexDbgListPtr = (OS_MUTEX *)0;
#endif
OSMutexQty = (OS_OBJ_QTY)0;
*p_err = OS_ERR_NONE;
}
#endif /* OS_CFG_MUTEX_EN */

View File

@@ -0,0 +1,447 @@
/*
************************************************************************************************************************
* uC/OS-III
* The Real-Time Kernel
*
* (c) Copyright 2009-2012; Micrium, Inc.; Weston, FL
* All rights reserved. Protected by international copyright laws.
*
* PEND ON MULTIPLE OBJECTS
*
* File : OS_PEND_MULTI.C
* By : JJL
* Version : V3.03.01
*
* LICENSING TERMS:
* ---------------
* uC/OS-III is provided in source form for FREE short-term evaluation, for educational use or
* for peaceful research. If you plan or intend to use uC/OS-III in a commercial application/
* product then, you need to contact Micrium to properly license uC/OS-III for its use in your
* application/product. We provide ALL the source code for your convenience and to help you
* experience uC/OS-III. The fact that the source is provided does NOT mean that you can use
* it commercially without paying a licensing fee.
*
* Knowledge of the source code may NOT be used to develop a similar product.
*
* Please help us continue to provide the embedded community with the finest software available.
* Your honesty is greatly appreciated.
*
* You can contact us at www.micrium.com, or by phone at +1 (954) 217-2036.
************************************************************************************************************************
*/
#define MICRIUM_SOURCE
#include <os.h>
#ifdef VSC_INCLUDE_SOURCE_FILE_NAMES
const CPU_CHAR *os_pend_multi__c = "$Id: $";
#endif
#if (((OS_CFG_Q_EN > 0u) || (OS_CFG_SEM_EN > 0u)) && (OS_CFG_PEND_MULTI_EN > 0u))
/*
************************************************************************************************************************
* PEND ON MULTIPLE OBJECTS
*
* Description: This function pends on multiple objects. The objects pended on MUST be either semaphores or message
* queues. If multiple objects are ready at the start of the pend call, then all available objects that
* are ready will be indicated to the caller. If the task must pend on the multiple events then, as soon
* as one of the object is either posted, aborted or deleted, the task will be readied.
*
* This function only allows you to pend on semaphores and/or message queues.
*
* Arguments : p_pend_data_tbl is a pointer to an array of type OS_PEND_DATA which contains a list of all the
* objects we will be waiting on. The caller must declare an array of OS_PEND_DATA
* and initialize the .PendObjPtr (see below) with a pointer to the object (semaphore or
* message queue) to pend on.
*
* OS_PEND_DATA MyPendArray[?];
*
* The OS_PEND_DATA field are as follows:
*
* OS_PEND_DATA *PrevPtr; Used to link OS_PEND_DATA objects
* OS_PEND_DATA *NextPtr; Used to link OS_PEND_DATA objects
* OS_TCB *TCBPtr; Pointer to the TCB that is pending on multiple objects
* OS_PEND_OBJ *PendObjPtr; USER supplied field which is a pointer to the
* semaphore or message queue you want to pend on. When
* you call OSPendMulti() you MUST fill this field for
* each of the objects you want to pend on.
* OS_PEND_OBJ *RdyObjPtr; OSPendMulti() will return the object that was posted,
* aborted or deleted in this field.
* void *RdyMsgPtr; OSPendMulti() will fill in this field if the object
* posted was a message queue. This corresponds to the
* message posted.
* OS_MSG_SIZE RdyMsgSize; OSPendMulti() will fill in this field if the object
* posted was a message queue. This corresponds to the
* size of the message posted.
* CPU_TS RdyTS; OSPendMulti() will fill in this field if the object
* was a message queue. This corresponds to the time
* stamp when the message was posted. However, if the
* object is a semaphore and the object is already ready
* the this field will be set to (CPU_TS)0 because it's
* not possible to know when the semaphore was posted.
*
* tbl_size is the size (in number of elements) of the OS_PEND_DATA array passed to this function. In
* other words, if the called needs to pend on 4 separate objects (semaphores and/or queues)
* then you would pass 4 to this call.
*
* timeout is an optional timeout period (in clock ticks). If non-zero, your task will wait any of
* the objects up to the amount of time specified by this argument. If you specify 0, however,
* your task will wait forever for the specified objects or, until an object is posted,
* aborted or deleted.
*
* opt determines whether the user wants to block if none of the objects are available.
*
* OS_OPT_PEND_BLOCKING
* OS_OPT_PEND_NON_BLOCKING
*
* p_err is a pointer to where an error message will be deposited. Possible error messages are:
*
* OS_ERR_NONE The call was successful and your task owns the resources or,
* the objects you are waiting for occurred. Check the .RdyObjPtr
* fields to know which objects have been posted.
* OS_ERR_OBJ_TYPE If any of the .PendPtr is NOT a semaphore or a message queue
* OS_ERR_OPT_INVALID If you specified an invalid option for 'opt'
* OS_ERR_PEND_ABORT The wait on the events was aborted; check the .RdyObjPtr fields
* for which objects were aborted.
* OS_ERR_PEND_DEL The wait on the events was aborted; check the .RdyObjPtr fields
* for which objects were aborted.
* OS_ERR_PEND_ISR If you called this function from an ISR
* OS_ERR_PEND_LOCKED If you called this function when the scheduler is locked.
* OS_ERR_PEND_WOULD_BLOCK If the caller didn't want to block and no object ready
* OS_ERR_STATUS_INVALID Invalid pend status
* OS_ERR_PTR_INVALID If you passes a NULL pointer of 'p_pend_data_tbl'
* OS_ERR_TIMEOUT The objects were not posted within the specified 'timeout'.
*
* Returns : > 0 the number of objects returned as ready, aborted or deleted
* == 0 if no events are returned as ready because of timeout or upon error.
************************************************************************************************************************
*/
/*$PAGE*/
OS_OBJ_QTY OSPendMulti (OS_PEND_DATA *p_pend_data_tbl,
OS_OBJ_QTY tbl_size,
OS_TICK timeout,
OS_OPT opt,
OS_ERR *p_err)
{
CPU_BOOLEAN valid;
OS_OBJ_QTY nbr_obj_rdy;
CPU_SR_ALLOC();
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return ((OS_OBJ_QTY)0);
}
#endif
#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u
if (OSIntNestingCtr > (OS_NESTING_CTR)0) { /* Can't pend from an ISR */
*p_err = OS_ERR_PEND_ISR;
return ((OS_OBJ_QTY)0);
}
#endif
#if OS_CFG_ARG_CHK_EN > 0u
if (p_pend_data_tbl == (OS_PEND_DATA *)0) { /* Validate 'p_pend_data_tbl' */
*p_err = OS_ERR_PTR_INVALID;
return ((OS_OBJ_QTY)0);
}
if (tbl_size == (OS_OBJ_QTY)0) { /* Array size must be > 0 */
*p_err = OS_ERR_PTR_INVALID;
return ((OS_OBJ_QTY)0);
}
switch (opt) {
case OS_OPT_PEND_BLOCKING:
case OS_OPT_PEND_NON_BLOCKING:
break;
default:
*p_err = OS_ERR_OPT_INVALID;
return ((OS_OBJ_QTY)0);
}
#endif
valid = OS_PendMultiValidate(p_pend_data_tbl, /* -------- Validate objects to be OS_SEM or OS_Q ------- */
tbl_size);
if (valid == DEF_FALSE) {
*p_err = OS_ERR_OBJ_TYPE; /* Invalid, not OS_SEM or OS_Q */
return ((OS_OBJ_QTY)0);
}
/*$PAGE*/
CPU_CRITICAL_ENTER();
nbr_obj_rdy = OS_PendMultiGetRdy(p_pend_data_tbl, /* --------- SEE IF OBJECT(s) HAVE BEEN POSTED ---------- */
tbl_size);
if (nbr_obj_rdy > (OS_OBJ_QTY)0) {
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_NONE;
return ((OS_OBJ_QTY)nbr_obj_rdy);
}
if ((opt & OS_OPT_PEND_NON_BLOCKING) != (OS_OPT)0) { /* Caller wants to block if not available? */
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_PEND_WOULD_BLOCK; /* No */
return ((OS_OBJ_QTY)0);
} else {
if (OSSchedLockNestingCtr > (OS_NESTING_CTR)0) { /* Can't pend when the scheduler is locked */
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_SCHED_LOCKED;
return ((OS_OBJ_QTY)0);
}
}
/* Lock the scheduler/re-enable interrupts */
OS_CRITICAL_ENTER_CPU_EXIT();
/* ------ NO OBJECT READY, PEND ON MULTIPLE OBJECTS ----- */
OS_PendMultiWait(p_pend_data_tbl, /* Suspend task until object posted or timeout occurs */
tbl_size,
timeout);
OS_CRITICAL_EXIT_NO_SCHED();
OSSched(); /* Find next highest priority task ready */
CPU_CRITICAL_ENTER();
switch (OSTCBCurPtr->PendStatus) {
case OS_STATUS_PEND_OK: /* We got one of the objects posted to */
*p_err = OS_ERR_NONE;
break;
case OS_STATUS_PEND_ABORT: /* Indicate that the multi-pend was aborted */
*p_err = OS_ERR_PEND_ABORT;
break;
case OS_STATUS_PEND_TIMEOUT: /* Indicate that we didn't get semaphore within timeout */
*p_err = OS_ERR_TIMEOUT;
break;
case OS_STATUS_PEND_DEL: /* Indicate that an object pended on has been deleted */
*p_err = OS_ERR_OBJ_DEL;
break;
default:
*p_err = OS_ERR_STATUS_INVALID;
break;
}
OSTCBCurPtr->PendStatus = OS_STATUS_PEND_OK;
CPU_CRITICAL_EXIT();
return ((OS_OBJ_QTY)1);
}
/*$PAGE*/
/*
************************************************************************************************************************
* GET A LIST OF OBJECTS READY
*
* Description: This function is called by OSPendMulti() to obtain the list of object that are ready.
*
* Arguments : p_pend_data_tbl is a pointer to an array of OS_PEND_DATA
* ---------------
*
* tbl_size is the size of the array
*
* Returns : > 0 the number of objects ready
* == 0 if no object ready
*
* Note : This function is INTERNAL to uC/OS-III and your application should not call it.
************************************************************************************************************************
*/
OS_OBJ_QTY OS_PendMultiGetRdy (OS_PEND_DATA *p_pend_data_tbl,
OS_OBJ_QTY tbl_size)
{
OS_OBJ_QTY i;
OS_OBJ_QTY nbr_obj_rdy;
#if OS_CFG_Q_EN > 0u
OS_ERR err;
OS_MSG_SIZE msg_size;
OS_Q *p_q;
void *p_void;
CPU_TS ts;
#endif
#if OS_CFG_SEM_EN > 0u
OS_SEM *p_sem;
#endif
nbr_obj_rdy = (OS_OBJ_QTY)0;
for (i = 0u; i < tbl_size; i++) {
p_pend_data_tbl->RdyObjPtr = (OS_PEND_OBJ *)0; /* Clear all fields */
p_pend_data_tbl->RdyMsgPtr = (void *)0;
p_pend_data_tbl->RdyMsgSize = (OS_MSG_SIZE )0;
p_pend_data_tbl->RdyTS = (CPU_TS )0;
p_pend_data_tbl->NextPtr = (OS_PEND_DATA *)0;
p_pend_data_tbl->PrevPtr = (OS_PEND_DATA *)0;
p_pend_data_tbl->TCBPtr = (OS_TCB *)0;
#if OS_CFG_Q_EN > 0u
p_q = (OS_Q *)((void *)p_pend_data_tbl->PendObjPtr); /* Assume we are pointing to a message queue object */
if (p_q->Type == OS_OBJ_TYPE_Q) { /* Is it a message queue? */
p_void = OS_MsgQGet(&p_q->MsgQ, /* Yes, Any message waiting in the message queue? */
&msg_size,
&ts,
&err);
if (err == OS_ERR_NONE) {
p_pend_data_tbl->RdyObjPtr = p_pend_data_tbl->PendObjPtr;
p_pend_data_tbl->RdyMsgPtr = p_void; /* Yes, save the message received */
p_pend_data_tbl->RdyMsgSize = msg_size;
p_pend_data_tbl->RdyTS = ts;
nbr_obj_rdy++;
}
}
#endif
#if OS_CFG_SEM_EN > 0u
p_sem = (OS_SEM *)((void *)p_pend_data_tbl->PendObjPtr); /* Assume we are pointing to a semaphore object */
if (p_sem->Type == OS_OBJ_TYPE_SEM) { /* Is it a semaphore? */
if (p_sem->Ctr > 0u) { /* Yes, Semaphore has been signaled? */
p_sem->Ctr--; /* Yes, caller may proceed */
p_pend_data_tbl->RdyObjPtr = p_pend_data_tbl->PendObjPtr;
p_pend_data_tbl->RdyTS = p_sem->TS;
nbr_obj_rdy++;
}
}
#endif
p_pend_data_tbl++;
}
return (nbr_obj_rdy);
}
/*$PAGE*/
/*
************************************************************************************************************************
* VERIFY THAT OBJECTS PENDED ON ARE EITHER SEMAPHORES or QUEUES
*
* Description: This function is called by OSPendMulti() to verify that we are multi-pending on either semaphores or
* message queues.
*
* Arguments : p_pend_data_tbl is a pointer to an array of OS_PEND_DATA
* ---------------
*
* tbl_size is the size of the array
*
* Returns : TRUE if all objects pended on are either semaphores of queues
* FALSE if at least one object is not a semaphore or queue.
*
* Note : This function is INTERNAL to uC/OS-III and your application should not call it.
************************************************************************************************************************
*/
CPU_BOOLEAN OS_PendMultiValidate (OS_PEND_DATA *p_pend_data_tbl,
OS_OBJ_QTY tbl_size)
{
OS_OBJ_QTY i;
OS_OBJ_QTY ctr;
#if OS_CFG_SEM_EN > 0u
OS_SEM *p_sem;
#endif
#if OS_CFG_Q_EN > 0u
OS_Q *p_q;
#endif
for (i = 0u; i < tbl_size; i++) {
if (p_pend_data_tbl->PendObjPtr == (OS_PEND_OBJ *)0) { /* All .PendObjPtr in the table MUST be non NULL */
return (DEF_FALSE);
}
ctr = 0u;
#if OS_CFG_SEM_EN > 0u
p_sem = (OS_SEM *)((void *)p_pend_data_tbl->PendObjPtr); /* All objects to pend on must be of type OS_SEM ... */
if (p_sem->Type == OS_OBJ_TYPE_SEM) {
ctr++;
}
#endif
#if OS_CFG_Q_EN > 0u
p_q = (OS_Q *)((void *)p_pend_data_tbl->PendObjPtr); /* ... or of type OS_Q */
if (p_q->Type == OS_OBJ_TYPE_Q) {
ctr++;
}
#endif
if (ctr == (OS_OBJ_QTY)0) {
return (DEF_FALSE); /* Found at least one invalid object type */
}
p_pend_data_tbl++;
}
return (DEF_TRUE);
}
/*$PAGE*/
/*
************************************************************************************************************************
* MAKE TASK WAIT FOR ANY OF MULTIPLE EVENTS TO OCCUR
*
* Description: This function is called by OSPendMulti() to suspend a task because any one of multiple objects that have
* not been posted to.
*
* Arguments : p_pend_data_tbl is a pointer to an array of OS_PEND_DATA
* ---------------
*
* tbl_size is the size of the array
*
* timeout is the timeout to wait in case none of the objects become ready
*
* Returns : none
*
* Note : This function is INTERNAL to uC/OS-III and your application should not call it.
************************************************************************************************************************
*/
void OS_PendMultiWait (OS_PEND_DATA *p_pend_data_tbl,
OS_OBJ_QTY tbl_size,
OS_TICK timeout)
{
OS_OBJ_QTY i;
OS_PEND_LIST *p_pend_list;
#if OS_CFG_Q_EN > 0u
OS_Q *p_q;
#endif
#if OS_CFG_SEM_EN > 0u
OS_SEM *p_sem;
#endif
OSTCBCurPtr->PendOn = OS_TASK_PEND_ON_MULTI; /* Resource not available, wait until it is */
OSTCBCurPtr->PendStatus = OS_STATUS_PEND_OK;
OSTCBCurPtr->PendDataTblEntries = tbl_size;
OSTCBCurPtr->PendDataTblPtr = p_pend_data_tbl;
OS_TaskBlock(OSTCBCurPtr, /* Block the task waiting for object to be posted ... */
timeout); /* ... but with a timeout if not */
for (i = 0u; i < tbl_size; i++) {
p_pend_data_tbl->TCBPtr = OSTCBCurPtr; /* Every entry points back to the TCB of the task */
#if OS_CFG_SEM_EN > 0u
p_sem = (OS_SEM *)((void *)p_pend_data_tbl->PendObjPtr);
if (p_sem->Type == OS_OBJ_TYPE_SEM) {
p_pend_list = &p_sem->PendList;
OS_PendListInsertPrio(p_pend_list,
p_pend_data_tbl);
}
#endif
#if OS_CFG_Q_EN > 0u
p_q = (OS_Q *)((void *)p_pend_data_tbl->PendObjPtr);
if (p_q->Type == OS_OBJ_TYPE_Q) {
p_pend_list = &p_q->PendList;
OS_PendListInsertPrio(p_pend_list,
p_pend_data_tbl);
}
#endif
p_pend_data_tbl++;
}
}
#endif

View File

@@ -0,0 +1,155 @@
/*
************************************************************************************************************************
* uC/OS-III
* The Real-Time Kernel
*
* (c) Copyright 2009-2012; Micrium, Inc.; Weston, FL
* All rights reserved. Protected by international copyright laws.
*
* PRIORITY MANAGEMENT
*
* File : OS_PRIO.C
* By : JJL
* Version : V3.03.01
*
* LICENSING TERMS:
* ---------------
* uC/OS-III is provided in source form for FREE short-term evaluation, for educational use or
* for peaceful research. If you plan or intend to use uC/OS-III in a commercial application/
* product then, you need to contact Micrium to properly license uC/OS-III for its use in your
* application/product. We provide ALL the source code for your convenience and to help you
* experience uC/OS-III. The fact that the source is provided does NOT mean that you can use
* it commercially without paying a licensing fee.
*
* Knowledge of the source code may NOT be used to develop a similar product.
*
* Please help us continue to provide the embedded community with the finest software available.
* Your honesty is greatly appreciated.
*
* You can contact us at www.micrium.com, or by phone at +1 (954) 217-2036.
************************************************************************************************************************
*/
#define MICRIUM_SOURCE
#include <os.h>
#ifdef VSC_INCLUDE_SOURCE_FILE_NAMES
const CPU_CHAR *os_prio__c = "$Id: $";
#endif
CPU_DATA OSPrioTbl[OS_PRIO_TBL_SIZE]; /* Declare the array local to this file to allow for ... */
/* ... optimization. In other words, this allows the ... */
/* ... table to be located in fast memory */
/*
************************************************************************************************************************
* INITIALIZE THE PRIORITY LIST
*
* Description: This function is called by uC/OS-III to initialize the list of ready priorities.
*
* Arguments : none
*
* Returns : none
*
* Note : This function is INTERNAL to uC/OS-III and your application should not call it.
************************************************************************************************************************
*/
void OS_PrioInit (void)
{
CPU_DATA i;
/* Clear the bitmap table ... no task is ready */
for (i = 0u; i < OS_PRIO_TBL_SIZE; i++) {
OSPrioTbl[i] = (CPU_DATA)0;
}
}
/*
************************************************************************************************************************
* GET HIGHEST PRIORITY TASK WAITING
*
* Description: This function is called by other uC/OS-III services to determine the highest priority task
* waiting on the event.
*
* Arguments : none
*
* Returns : The priority of the Highest Priority Task (HPT) waiting for the event
*
* Note(s) : 1) This function is INTERNAL to uC/OS-III and your application MUST NOT call it.
************************************************************************************************************************
*/
OS_PRIO OS_PrioGetHighest (void)
{
CPU_DATA *p_tbl;
OS_PRIO prio;
prio = (OS_PRIO)0;
p_tbl = &OSPrioTbl[0];
while (*p_tbl == (CPU_DATA)0) { /* Search the bitmap table for the highest priority */
prio += DEF_INT_CPU_NBR_BITS; /* Compute the step of each CPU_DATA entry */
p_tbl++;
}
prio += (OS_PRIO)CPU_CntLeadZeros(*p_tbl); /* Find the position of the first bit set at the entry */
return (prio);
}
/*
************************************************************************************************************************
* INSERT PRIORITY
*
* Description: This function is called to insert a priority in the priority table.
*
* Arguments : prio is the priority to insert
*
* Returns : none
*
* Note(s) : 1) This function is INTERNAL to uC/OS-III and your application MUST NOT call it.
************************************************************************************************************************
*/
void OS_PrioInsert (OS_PRIO prio)
{
CPU_DATA bit;
CPU_DATA bit_nbr;
OS_PRIO ix;
ix = prio / DEF_INT_CPU_NBR_BITS;
bit_nbr = (CPU_DATA)prio & (DEF_INT_CPU_NBR_BITS - 1u);
bit = 1u;
bit <<= (DEF_INT_CPU_NBR_BITS - 1u) - bit_nbr;
OSPrioTbl[ix] |= bit;
}
/*
************************************************************************************************************************
* REMOVE PRIORITY
*
* Description: This function is called to remove a priority in the priority table.
*
* Arguments : prio is the priority to remove
*
* Returns : none
*
* Note(s) : 1) This function is INTERNAL to uC/OS-III and your application MUST NOT call it.
************************************************************************************************************************
*/
void OS_PrioRemove (OS_PRIO prio)
{
CPU_DATA bit;
CPU_DATA bit_nbr;
OS_PRIO ix;
ix = prio / DEF_INT_CPU_NBR_BITS;
bit_nbr = (CPU_DATA)prio & (DEF_INT_CPU_NBR_BITS - 1u);
bit = 1u;
bit <<= (DEF_INT_CPU_NBR_BITS - 1u) - bit_nbr;
OSPrioTbl[ix] &= ~bit;
}

View File

@@ -0,0 +1,981 @@
/*
************************************************************************************************************************
* uC/OS-III
* The Real-Time Kernel
*
* (c) Copyright 2009-2012; Micrium, Inc.; Weston, FL
* All rights reserved. Protected by international copyright laws.
*
* MESSAGE QUEUE MANAGEMENT
*
* File : OS_Q.C
* By : JJL
* Version : V3.03.01
*
* LICENSING TERMS:
* ---------------
* uC/OS-III is provided in source form for FREE short-term evaluation, for educational use or
* for peaceful research. If you plan or intend to use uC/OS-III in a commercial application/
* product then, you need to contact Micrium to properly license uC/OS-III for its use in your
* application/product. We provide ALL the source code for your convenience and to help you
* experience uC/OS-III. The fact that the source is provided does NOT mean that you can use
* it commercially without paying a licensing fee.
*
* Knowledge of the source code may NOT be used to develop a similar product.
*
* Please help us continue to provide the embedded community with the finest software available.
* Your honesty is greatly appreciated.
*
* You can contact us at www.micrium.com, or by phone at +1 (954) 217-2036.
************************************************************************************************************************
*/
#define MICRIUM_SOURCE
#include <os.h>
#ifdef VSC_INCLUDE_SOURCE_FILE_NAMES
const CPU_CHAR *os_q__c = "$Id: $";
#endif
#if OS_CFG_Q_EN > 0u
/*
************************************************************************************************************************
* CREATE A MESSAGE QUEUE
*
* Description: This function is called by your application to create a message queue. Message queues MUST be created
* before they can be used.
*
* Arguments : p_q is a pointer to the message queue
*
* p_name is a pointer to an ASCII string that will be used to name the message queue
*
* max_qty indicates the maximum size of the message queue (must be non-zero). Note that it's also not
* possible to have a size higher than the maximum number of OS_MSGs available.
*
* p_err is a pointer to a variable that will contain an error code returned by this function.
*
* OS_ERR_NONE the call was successful
* OS_ERR_CREATE_ISR can't create from an ISR
* OS_ERR_ILLEGAL_CREATE_RUN_TIME if you are trying to create the Queue after you called
* OSSafetyCriticalStart().
* OS_ERR_NAME if 'p_name' is a NULL pointer
* OS_ERR_OBJ_CREATED if the message queue has already been created
* OS_ERR_OBJ_PTR_NULL if you passed a NULL pointer for 'p_q'
* OS_ERR_Q_SIZE if the size you specified is 0
*
* Returns : none
************************************************************************************************************************
*/
void OSQCreate (OS_Q *p_q,
CPU_CHAR *p_name,
OS_MSG_QTY max_qty,
OS_ERR *p_err)
{
CPU_SR_ALLOC();
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return;
}
#endif
#ifdef OS_SAFETY_CRITICAL_IEC61508
if (OSSafetyCriticalStartFlag == DEF_TRUE) {
*p_err = OS_ERR_ILLEGAL_CREATE_RUN_TIME;
return;
}
#endif
#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u
if (OSIntNestingCtr > (OS_NESTING_CTR)0) { /* Not allowed to be called from an ISR */
*p_err = OS_ERR_CREATE_ISR;
return;
}
#endif
#if OS_CFG_ARG_CHK_EN > 0u
if (p_q == (OS_Q *)0) { /* Validate arguments */
*p_err = OS_ERR_OBJ_PTR_NULL;
return;
}
if (max_qty == (OS_MSG_QTY)0) { /* Cannot specify a zero size queue */
*p_err = OS_ERR_Q_SIZE;
return;
}
#endif
OS_CRITICAL_ENTER();
p_q->Type = OS_OBJ_TYPE_Q; /* Mark the data structure as a message queue */
p_q->NamePtr = p_name;
OS_MsgQInit(&p_q->MsgQ, /* Initialize the queue */
max_qty);
OS_PendListInit(&p_q->PendList); /* Initialize the waiting list */
#if OS_CFG_DBG_EN > 0u
OS_QDbgListAdd(p_q);
#endif
OSQQty++; /* One more queue created */
OS_CRITICAL_EXIT_NO_SCHED();
*p_err = OS_ERR_NONE;
}
/*$PAGE*/
/*
************************************************************************************************************************
* DELETE A MESSAGE QUEUE
*
* Description: This function deletes a message queue and readies all tasks pending on the queue.
*
* Arguments : p_q is a pointer to the message queue you want to delete
*
* opt determines delete options as follows:
*
* OS_OPT_DEL_NO_PEND Delete the queue ONLY if no task pending
* OS_OPT_DEL_ALWAYS Deletes the queue even if tasks are waiting.
* In this case, all the tasks pending will be readied.
*
* p_err is a pointer to a variable that will contain an error code returned by this function.
*
* OS_ERR_NONE The call was successful and the queue was deleted
* OS_ERR_DEL_ISR If you tried to delete the queue from an ISR
* OS_ERR_OBJ_PTR_NULL if you pass a NULL pointer for 'p_q'
* OS_ERR_OBJ_TYPE if the message queue was not created
* OS_ERR_OPT_INVALID An invalid option was specified
* OS_ERR_TASK_WAITING One or more tasks were waiting on the queue
*
* Returns : == 0 if no tasks were waiting on the queue, or upon error.
* > 0 if one or more tasks waiting on the queue are now readied and informed.
*
* Note(s) : 1) This function must be used with care. Tasks that would normally expect the presence of the queue MUST
* check the return code of OSQPend().
*
* 2) OSQAccept() callers will not know that the intended queue has been deleted.
*
* 3) Because ALL tasks pending on the queue will be readied, you MUST be careful in applications where the
* queue is used for mutual exclusion because the resource(s) will no longer be guarded by the queue.
************************************************************************************************************************
*/
#if OS_CFG_Q_DEL_EN > 0u
OS_OBJ_QTY OSQDel (OS_Q *p_q,
OS_OPT opt,
OS_ERR *p_err)
{
OS_OBJ_QTY cnt;
OS_OBJ_QTY nbr_tasks;
OS_PEND_DATA *p_pend_data;
OS_PEND_LIST *p_pend_list;
OS_TCB *p_tcb;
CPU_TS ts;
CPU_SR_ALLOC();
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return ((OS_OBJ_QTY)0);
}
#endif
#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u
if (OSIntNestingCtr > (OS_NESTING_CTR)0) { /* Can't delete a message queue from an ISR */
*p_err = OS_ERR_DEL_ISR;
return ((OS_OBJ_QTY)0);
}
#endif
#if OS_CFG_ARG_CHK_EN > 0u
if (p_q == (OS_Q *)0) { /* Validate 'p_q' */
*p_err = OS_ERR_OBJ_PTR_NULL;
return ((OS_OBJ_QTY)0u);
}
switch (opt) { /* Validate 'opt' */
case OS_OPT_DEL_NO_PEND:
case OS_OPT_DEL_ALWAYS:
break;
default:
*p_err = OS_ERR_OPT_INVALID;
return ((OS_OBJ_QTY)0u);
}
#endif
#if OS_CFG_OBJ_TYPE_CHK_EN > 0u
if (p_q->Type != OS_OBJ_TYPE_Q) { /* Make sure message queue was created */
*p_err = OS_ERR_OBJ_TYPE;
return ((OS_OBJ_QTY)0);
}
#endif
CPU_CRITICAL_ENTER();
p_pend_list = &p_q->PendList;
cnt = p_pend_list->NbrEntries;
nbr_tasks = cnt;
switch (opt) {
case OS_OPT_DEL_NO_PEND: /* Delete message queue only if no task waiting */
if (nbr_tasks == (OS_OBJ_QTY)0) {
#if OS_CFG_DBG_EN > 0u
OS_QDbgListRemove(p_q);
#endif
OSQQty--;
OS_QClr(p_q);
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_NONE;
} else {
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_TASK_WAITING;
}
break;
case OS_OPT_DEL_ALWAYS: /* Always delete the message queue */
OS_CRITICAL_ENTER_CPU_EXIT();
ts = OS_TS_GET(); /* Get local time stamp so all tasks get the same time */
while (cnt > 0u) { /* Remove all tasks from the pend list */
p_pend_data = p_pend_list->HeadPtr;
p_tcb = p_pend_data->TCBPtr;
OS_PendObjDel((OS_PEND_OBJ *)((void *)p_q),
p_tcb,
ts);
cnt--;
}
#if OS_CFG_DBG_EN > 0u
OS_QDbgListRemove(p_q);
#endif
OSQQty--;
OS_QClr(p_q);
OS_CRITICAL_EXIT_NO_SCHED();
OSSched(); /* Find highest priority task ready to run */
*p_err = OS_ERR_NONE;
break;
default:
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_OPT_INVALID;
break;
}
return (nbr_tasks);
}
#endif
/*$PAGE*/
/*
************************************************************************************************************************
* FLUSH QUEUE
*
* Description : This function is used to flush the contents of the message queue.
*
* Arguments : p_q is a pointer to the message queue to flush
*
* p_err is a pointer to a variable that will contain an error code returned by this function.
*
* OS_ERR_NONE upon success
* OS_ERR_FLUSH_ISR if you called this function from an ISR
* OS_ERR_OBJ_PTR_NULL If you passed a NULL pointer for 'p_q'
* OS_ERR_OBJ_TYPE If you didn't create the message queue
*
* Returns : The number of entries freed from the queue
*
* Note(s) : 1) You should use this function with great care because, when to flush the queue, you LOOSE the
* references to what the queue entries are pointing to and thus, you could cause 'memory leaks'. In
* other words, the data you are pointing to that's being referenced by the queue entries should, most
* likely, need to be de-allocated (i.e. freed).
************************************************************************************************************************
*/
#if OS_CFG_Q_FLUSH_EN > 0u
OS_MSG_QTY OSQFlush (OS_Q *p_q,
OS_ERR *p_err)
{
OS_MSG_QTY entries;
CPU_SR_ALLOC();
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return ((OS_MSG_QTY)0);
}
#endif
#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u
if (OSIntNestingCtr > (OS_NESTING_CTR)0) { /* Can't flush a message queue from an ISR */
*p_err = OS_ERR_FLUSH_ISR;
return ((OS_MSG_QTY)0);
}
#endif
#if OS_CFG_ARG_CHK_EN > 0u
if (p_q == (OS_Q *)0) { /* Validate arguments */
*p_err = OS_ERR_OBJ_PTR_NULL;
return ((OS_MSG_QTY)0);
}
#endif
#if OS_CFG_OBJ_TYPE_CHK_EN > 0u
if (p_q->Type != OS_OBJ_TYPE_Q) { /* Make sure message queue was created */
*p_err = OS_ERR_OBJ_TYPE;
return ((OS_MSG_QTY)0);
}
#endif
OS_CRITICAL_ENTER();
entries = OS_MsgQFreeAll(&p_q->MsgQ); /* Return all OS_MSGs to the OS_MSG pool */
OS_CRITICAL_EXIT();
*p_err = OS_ERR_NONE;
return ((OS_MSG_QTY)entries);
}
#endif
/*$PAGE*/
/*
************************************************************************************************************************
* PEND ON A QUEUE FOR A MESSAGE
*
* Description: This function waits for a message to be sent to a queue
*
* Arguments : p_q is a pointer to the message queue
*
* timeout is an optional timeout period (in clock ticks). If non-zero, your task will wait for a
* message to arrive at the queue up to the amount of time specified by this argument. If you
* specify 0, however, your task will wait forever at the specified queue or, until a message
* arrives.
*
* opt determines whether the user wants to block if the queue is empty or not:
*
* OS_OPT_PEND_BLOCKING
* OS_OPT_PEND_NON_BLOCKING
*
* p_msg_size is a pointer to a variable that will receive the size of the message
*
* p_ts is a pointer to a variable that will receive the timestamp of when the message was
* received, pend aborted or the message queue deleted, If you pass a NULL pointer (i.e.
* (CPU_TS *)0) then you will not get the timestamp. In other words, passing a NULL pointer
* is valid and indicates that you don't need the timestamp.
*
* p_err is a pointer to a variable that will contain an error code returned by this function.
*
* OS_ERR_NONE The call was successful and your task received a message.
* OS_ERR_OBJ_PTR_NULL if you pass a NULL pointer for 'p_q'
* OS_ERR_OBJ_TYPE if the message queue was not created
* OS_ERR_PEND_ABORT the pend was aborted
* OS_ERR_PEND_ISR if you called this function from an ISR
* OS_ERR_PEND_WOULD_BLOCK If you specified non-blocking but the queue was not empty
* OS_ERR_SCHED_LOCKED the scheduler is locked
* OS_ERR_TIMEOUT A message was not received within the specified timeout
* would lead to a suspension.
*
* Returns : != (void *)0 is a pointer to the message received
* == (void *)0 if you received a NULL pointer message or,
* if no message was received or,
* if 'p_q' is a NULL pointer or,
* if you didn't pass a pointer to a queue.
************************************************************************************************************************
*/
void *OSQPend (OS_Q *p_q,
OS_TICK timeout,
OS_OPT opt,
OS_MSG_SIZE *p_msg_size,
CPU_TS *p_ts,
OS_ERR *p_err)
{
OS_PEND_DATA pend_data;
void *p_void;
CPU_SR_ALLOC();
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return ((void *)0);
}
#endif
#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u
if (OSIntNestingCtr > (OS_NESTING_CTR)0) { /* Not allowed to call from an ISR */
*p_err = OS_ERR_PEND_ISR;
return ((void *)0);
}
#endif
#if OS_CFG_ARG_CHK_EN > 0u
if (p_q == (OS_Q *)0) { /* Validate arguments */
*p_err = OS_ERR_OBJ_PTR_NULL;
return ((void *)0);
}
if (p_msg_size == (OS_MSG_SIZE *)0) {
*p_err = OS_ERR_PTR_INVALID;
return ((void *)0);
}
switch (opt) {
case OS_OPT_PEND_BLOCKING:
case OS_OPT_PEND_NON_BLOCKING:
break;
default:
*p_err = OS_ERR_OPT_INVALID;
return ((void *)0);
}
#endif
#if OS_CFG_OBJ_TYPE_CHK_EN > 0u
if (p_q->Type != OS_OBJ_TYPE_Q) { /* Make sure message queue was created */
*p_err = OS_ERR_OBJ_TYPE;
return ((void *)0);
}
#endif
if (p_ts != (CPU_TS *)0) {
*p_ts = (CPU_TS )0; /* Initialize the returned timestamp */
}
CPU_CRITICAL_ENTER();
p_void = OS_MsgQGet(&p_q->MsgQ, /* Any message waiting in the message queue? */
p_msg_size,
p_ts,
p_err);
if (*p_err == OS_ERR_NONE) {
CPU_CRITICAL_EXIT();
return (p_void); /* Yes, Return message received */
}
if ((opt & OS_OPT_PEND_NON_BLOCKING) != (OS_OPT)0) { /* Caller wants to block if not available? */
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_PEND_WOULD_BLOCK; /* No */
return ((void *)0);
} else {
if (OSSchedLockNestingCtr > (OS_NESTING_CTR)0) { /* Can't pend when the scheduler is locked */
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_SCHED_LOCKED;
return ((void *)0);
}
}
/* Lock the scheduler/re-enable interrupts */
OS_CRITICAL_ENTER_CPU_EXIT();
OS_Pend(&pend_data, /* Block task pending on Message Queue */
(OS_PEND_OBJ *)((void *)p_q),
OS_TASK_PEND_ON_Q,
timeout);
OS_CRITICAL_EXIT_NO_SCHED();
OSSched(); /* Find the next highest priority task ready to run */
CPU_CRITICAL_ENTER();
switch (OSTCBCurPtr->PendStatus) {
case OS_STATUS_PEND_OK: /* Extract message from TCB (Put there by Post) */
p_void = OSTCBCurPtr->MsgPtr;
*p_msg_size = OSTCBCurPtr->MsgSize;
if (p_ts != (CPU_TS *)0) {
*p_ts = OSTCBCurPtr->TS;
}
*p_err = OS_ERR_NONE;
break;
case OS_STATUS_PEND_ABORT: /* Indicate that we aborted */
p_void = (void *)0;
*p_msg_size = (OS_MSG_SIZE)0;
if (p_ts != (CPU_TS *)0) {
*p_ts = OSTCBCurPtr->TS;
}
*p_err = OS_ERR_PEND_ABORT;
break;
case OS_STATUS_PEND_TIMEOUT: /* Indicate that we didn't get event within TO */
p_void = (void *)0;
*p_msg_size = (OS_MSG_SIZE)0;
if (p_ts != (CPU_TS *)0) {
*p_ts = (CPU_TS )0;
}
*p_err = OS_ERR_TIMEOUT;
break;
case OS_STATUS_PEND_DEL: /* Indicate that object pended on has been deleted */
p_void = (void *)0;
*p_msg_size = (OS_MSG_SIZE)0;
if (p_ts != (CPU_TS *)0) {
*p_ts = OSTCBCurPtr->TS;
}
*p_err = OS_ERR_OBJ_DEL;
break;
default:
p_void = (void *)0;
*p_msg_size = (OS_MSG_SIZE)0;
*p_err = OS_ERR_STATUS_INVALID;
break;
}
CPU_CRITICAL_EXIT();
return (p_void);
}
/*$PAGE*/
/*
************************************************************************************************************************
* ABORT WAITING ON A MESSAGE QUEUE
*
* Description: This function aborts & readies any tasks currently waiting on a queue. This function should be used to
* fault-abort the wait on the queue, rather than to normally signal the queue via OSQPost().
*
* Arguments : p_q is a pointer to the message queue
*
* opt determines the type of ABORT performed:
*
* OS_OPT_PEND_ABORT_1 ABORT wait for a single task (HPT) waiting on the queue
* OS_OPT_PEND_ABORT_ALL ABORT wait for ALL tasks that are waiting on the queue
* OS_OPT_POST_NO_SCHED Do not call the scheduler
*
* p_err is a pointer to a variable that will contain an error code returned by this function.
*
* OS_ERR_NONE At least one task waiting on the queue was readied and
* informed of the aborted wait; check return value for the
* number of tasks whose wait on the queue was aborted.
* OS_ERR_OPT_INVALID if you specified an invalid option
* OS_ERR_OBJ_PTR_NULL if you pass a NULL pointer for 'p_q'
* OS_ERR_OBJ_TYPE if the message queue was not created
* OS_ERR_PEND_ABORT_ISR If this function was called from an ISR
* OS_ERR_PEND_ABORT_NONE No task were pending
*
* Returns : == 0 if no tasks were waiting on the queue, or upon error.
* > 0 if one or more tasks waiting on the queue are now readied and informed.
************************************************************************************************************************
*/
#if OS_CFG_Q_PEND_ABORT_EN > 0u
OS_OBJ_QTY OSQPendAbort (OS_Q *p_q,
OS_OPT opt,
OS_ERR *p_err)
{
OS_PEND_LIST *p_pend_list;
OS_TCB *p_tcb;
CPU_TS ts;
OS_OBJ_QTY nbr_tasks;
CPU_SR_ALLOC();
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return ((OS_OBJ_QTY)0u);
}
#endif
#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u
if (OSIntNestingCtr > (OS_NESTING_CTR)0u) { /* Not allowed to Pend Abort from an ISR */
*p_err = OS_ERR_PEND_ABORT_ISR;
return ((OS_OBJ_QTY)0u);
}
#endif
#if OS_CFG_ARG_CHK_EN > 0u
if (p_q == (OS_Q *)0) { /* Validate 'p_q' */
*p_err = OS_ERR_OBJ_PTR_NULL;
return ((OS_OBJ_QTY)0u);
}
switch (opt) { /* Validate 'opt' */
case OS_OPT_PEND_ABORT_1:
case OS_OPT_PEND_ABORT_ALL:
case OS_OPT_PEND_ABORT_1 | OS_OPT_POST_NO_SCHED:
case OS_OPT_PEND_ABORT_ALL | OS_OPT_POST_NO_SCHED:
break;
default:
*p_err = OS_ERR_OPT_INVALID;
return ((OS_OBJ_QTY)0u);
}
#endif
#if OS_CFG_OBJ_TYPE_CHK_EN > 0u
if (p_q->Type != OS_OBJ_TYPE_Q) { /* Make sure queue was created */
*p_err = OS_ERR_OBJ_TYPE;
return ((OS_OBJ_QTY)0u);
}
#endif
CPU_CRITICAL_ENTER();
p_pend_list = &p_q->PendList;
if (p_pend_list->NbrEntries == (OS_OBJ_QTY)0u) { /* Any task waiting on queue? */
CPU_CRITICAL_EXIT(); /* No */
*p_err = OS_ERR_PEND_ABORT_NONE;
return ((OS_OBJ_QTY)0u);
}
OS_CRITICAL_ENTER_CPU_EXIT();
nbr_tasks = 0u;
ts = OS_TS_GET(); /* Get local time stamp so all tasks get the same time */
while (p_pend_list->NbrEntries > (OS_OBJ_QTY)0u) {
p_tcb = p_pend_list->HeadPtr->TCBPtr;
OS_PendAbort((OS_PEND_OBJ *)((void *)p_q),
p_tcb,
ts);
nbr_tasks++;
if (opt != OS_OPT_PEND_ABORT_ALL) { /* Pend abort all tasks waiting? */
break; /* No */
}
}
OS_CRITICAL_EXIT_NO_SCHED();
if ((opt & OS_OPT_POST_NO_SCHED) == (OS_OPT)0u) {
OSSched(); /* Run the scheduler */
}
*p_err = OS_ERR_NONE;
return (nbr_tasks);
}
#endif
/*$PAGE*/
/*
************************************************************************************************************************
* POST MESSAGE TO A QUEUE
*
* Description: This function sends a message to a queue. With the 'opt' argument, you can specify whether the message
* is broadcast to all waiting tasks and/or whether you post the message to the front of the queue (LIFO)
* or normally (FIFO) at the end of the queue.
*
* Arguments : p_q is a pointer to a message queue that must have been created by OSQCreate().
*
* p_void is a pointer to the message to send.
*
* msg_size specifies the size of the message (in bytes)
*
* opt determines the type of POST performed:
*
* OS_OPT_POST_ALL POST to ALL tasks that are waiting on the queue. This option
* can be added to either OS_OPT_POST_FIFO or OS_OPT_POST_LIFO
* OS_OPT_POST_FIFO POST message to end of queue (FIFO) and wake up a single
* waiting task.
* OS_OPT_POST_LIFO POST message to the front of the queue (LIFO) and wake up
* a single waiting task.
* OS_OPT_POST_NO_SCHED Do not call the scheduler
*
* Note(s): 1) OS_OPT_POST_NO_SCHED can be added (or OR'd) with one of the other options.
* 2) OS_OPT_POST_ALL can be added (or OR'd) with one of the other options.
* 3) Possible combination of options are:
*
* OS_OPT_POST_FIFO
* OS_OPT_POST_LIFO
* OS_OPT_POST_FIFO + OS_OPT_POST_ALL
* OS_OPT_POST_LIFO + OS_OPT_POST_ALL
* OS_OPT_POST_FIFO + OS_OPT_POST_NO_SCHED
* OS_OPT_POST_LIFO + OS_OPT_POST_NO_SCHED
* OS_OPT_POST_FIFO + OS_OPT_POST_ALL + OS_OPT_POST_NO_SCHED
* OS_OPT_POST_LIFO + OS_OPT_POST_ALL + OS_OPT_POST_NO_SCHED
*
* p_err is a pointer to a variable that will contain an error code returned by this function.
*
* OS_ERR_NONE The call was successful and the message was sent
* OS_ERR_MSG_POOL_EMPTY If there are no more OS_MSGs to use to place the message into
* OS_ERR_OBJ_PTR_NULL If 'p_q' is a NULL pointer
* OS_ERR_OBJ_TYPE If the message queue was not initialized
* OS_ERR_Q_MAX If the queue is full
*
* Returns : None
************************************************************************************************************************
*/
void OSQPost (OS_Q *p_q,
void *p_void,
OS_MSG_SIZE msg_size,
OS_OPT opt,
OS_ERR *p_err)
{
CPU_TS ts;
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return;
}
#endif
#if OS_CFG_ARG_CHK_EN > 0u
if (p_q == (OS_Q *)0) { /* Validate 'p_q' */
*p_err = OS_ERR_OBJ_PTR_NULL;
return;
}
switch (opt) { /* Validate 'opt' */
case OS_OPT_POST_FIFO:
case OS_OPT_POST_LIFO:
case OS_OPT_POST_FIFO | OS_OPT_POST_ALL:
case OS_OPT_POST_LIFO | OS_OPT_POST_ALL:
case OS_OPT_POST_FIFO | OS_OPT_POST_NO_SCHED:
case OS_OPT_POST_LIFO | OS_OPT_POST_NO_SCHED:
case OS_OPT_POST_FIFO | OS_OPT_POST_ALL | OS_OPT_POST_NO_SCHED:
case OS_OPT_POST_LIFO | OS_OPT_POST_ALL | OS_OPT_POST_NO_SCHED:
break;
default:
*p_err = OS_ERR_OPT_INVALID;
return;
}
#endif
#if OS_CFG_OBJ_TYPE_CHK_EN > 0u
if (p_q->Type != OS_OBJ_TYPE_Q) { /* Make sure message queue was created */
*p_err = OS_ERR_OBJ_TYPE;
return;
}
#endif
ts = OS_TS_GET(); /* Get timestamp */
#if OS_CFG_ISR_POST_DEFERRED_EN > 0u
if (OSIntNestingCtr > (OS_NESTING_CTR)0) {
OS_IntQPost((OS_OBJ_TYPE)OS_OBJ_TYPE_Q, /* Post to ISR queue */
(void *)p_q,
(void *)p_void,
(OS_MSG_SIZE)msg_size,
(OS_FLAGS )0,
(OS_OPT )opt,
(CPU_TS )ts,
(OS_ERR *)p_err);
return;
}
#endif
OS_QPost(p_q,
p_void,
msg_size,
opt,
ts,
p_err);
}
/*$PAGE*/
/*
************************************************************************************************************************
* CLEAR THE CONTENTS OF A MESSAGE QUEUE
*
* Description: This function is called by OSQDel() to clear the contents of a message queue
*
* Argument(s): p_q is a pointer to the queue to clear
* ---
*
* Returns : none
*
* Note(s) : 1) This function is INTERNAL to uC/OS-III and your application MUST NOT call it.
************************************************************************************************************************
*/
void OS_QClr (OS_Q *p_q)
{
(void)OS_MsgQFreeAll(&p_q->MsgQ); /* Return all OS_MSGs to the free list */
p_q->Type = OS_OBJ_TYPE_NONE; /* Mark the data structure as a NONE */
p_q->NamePtr = (CPU_CHAR *)((void *)"?Q");
OS_MsgQInit(&p_q->MsgQ, /* Initialize the list of OS_MSGs */
0u);
OS_PendListInit(&p_q->PendList); /* Initialize the waiting list */
}
/*$PAGE*/
/*
************************************************************************************************************************
* ADD/REMOVE MESSAGE QUEUE TO/FROM DEBUG LIST
*
* Description: These functions are called by uC/OS-III to add or remove a message queue to/from a message queue debug
* list.
*
* Arguments : p_q is a pointer to the message queue to add/remove
*
* Returns : none
*
* Note(s) : These functions are INTERNAL to uC/OS-III and your application should not call it.
************************************************************************************************************************
*/
#if OS_CFG_DBG_EN > 0u
void OS_QDbgListAdd (OS_Q *p_q)
{
p_q->DbgNamePtr = (CPU_CHAR *)((void *)" ");
p_q->DbgPrevPtr = (OS_Q *)0;
if (OSQDbgListPtr == (OS_Q *)0) {
p_q->DbgNextPtr = (OS_Q *)0;
} else {
p_q->DbgNextPtr = OSQDbgListPtr;
OSQDbgListPtr->DbgPrevPtr = p_q;
}
OSQDbgListPtr = p_q;
}
void OS_QDbgListRemove (OS_Q *p_q)
{
OS_Q *p_q_next;
OS_Q *p_q_prev;
p_q_prev = p_q->DbgPrevPtr;
p_q_next = p_q->DbgNextPtr;
if (p_q_prev == (OS_Q *)0) {
OSQDbgListPtr = p_q_next;
if (p_q_next != (OS_Q *)0) {
p_q_next->DbgPrevPtr = (OS_Q *)0;
}
p_q->DbgNextPtr = (OS_Q *)0;
} else if (p_q_next == (OS_Q *)0) {
p_q_prev->DbgNextPtr = (OS_Q *)0;
p_q->DbgPrevPtr = (OS_Q *)0;
} else {
p_q_prev->DbgNextPtr = p_q_next;
p_q_next->DbgPrevPtr = p_q_prev;
p_q->DbgNextPtr = (OS_Q *)0;
p_q->DbgPrevPtr = (OS_Q *)0;
}
}
#endif
/*$PAGE*/
/*
************************************************************************************************************************
* MESSAGE QUEUE INITIALIZATION
*
* Description: This function is called by OSInit() to initialize the message queue management.
*
* Arguments : p_err is a pointer to a variable that will receive an error code.
*
* OS_ERR_NONE the call was successful
*
* Returns : none
*
* Note(s) : 1) This function is INTERNAL to uC/OS-III and your application MUST NOT call it.
************************************************************************************************************************
*/
void OS_QInit (OS_ERR *p_err)
{
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return;
}
#endif
#if OS_CFG_DBG_EN > 0u
OSQDbgListPtr = (OS_Q *)0;
#endif
OSQQty = (OS_OBJ_QTY)0;
*p_err = OS_ERR_NONE;
}
/*$PAGE*/
/*
************************************************************************************************************************
* POST MESSAGE TO A QUEUE
*
* Description: This function sends a message to a queue. With the 'opt' argument, you can specify whether the message
* is broadcast to all waiting tasks and/or whether you post the message to the front of the queue (LIFO)
* or normally (FIFO) at the end of the queue.
*
* Arguments : p_q is a pointer to a message queue that must have been created by OSQCreate().
*
* p_void is a pointer to the message to send.
*
* msg_size specifies the size of the message (in bytes)
*
* opt determines the type of POST performed:
*
* OS_OPT_POST_ALL POST to ALL tasks that are waiting on the queue
*
* OS_OPT_POST_FIFO POST as FIFO and wake up single waiting task
* OS_OPT_POST_LIFO POST as LIFO and wake up single waiting task
*
* OS_OPT_POST_NO_SCHED Do not call the scheduler
*
* ts is the timestamp of the post
*
* p_err is a pointer to a variable that will contain an error code returned by this function.
*
* OS_ERR_NONE The call was successful and the message was sent
* OS_ERR_MSG_POOL_EMPTY If there are no more OS_MSGs to use to place the message into
* OS_ERR_OBJ_PTR_NULL If 'p_q' is a NULL pointer
* OS_ERR_OBJ_TYPE If the message queue was not initialized
* OS_ERR_Q_MAX If the queue is full
*
* Returns : None
*
* Note(s) : This function is INTERNAL to uC/OS-III and your application should not call it.
************************************************************************************************************************
*/
void OS_QPost (OS_Q *p_q,
void *p_void,
OS_MSG_SIZE msg_size,
OS_OPT opt,
CPU_TS ts,
OS_ERR *p_err)
{
OS_OBJ_QTY cnt;
OS_OPT post_type;
OS_PEND_LIST *p_pend_list;
OS_PEND_DATA *p_pend_data;
OS_PEND_DATA *p_pend_data_next;
OS_TCB *p_tcb;
CPU_SR_ALLOC();
OS_CRITICAL_ENTER();
p_pend_list = &p_q->PendList;
if (p_pend_list->NbrEntries == (OS_OBJ_QTY)0) { /* Any task waiting on message queue? */
if ((opt & OS_OPT_POST_LIFO) == (OS_OPT)0) { /* Determine whether we post FIFO or LIFO */
post_type = OS_OPT_POST_FIFO;
} else {
post_type = OS_OPT_POST_LIFO;
}
OS_MsgQPut(&p_q->MsgQ, /* Place message in the message queue */
p_void,
msg_size,
post_type,
ts,
p_err);
OS_CRITICAL_EXIT();
return;
}
if ((opt & OS_OPT_POST_ALL) != (OS_OPT)0) { /* Post message to all tasks waiting? */
cnt = p_pend_list->NbrEntries; /* Yes */
} else {
cnt = (OS_OBJ_QTY)1; /* No */
}
p_pend_data = p_pend_list->HeadPtr;
while (cnt > 0u) {
p_tcb = p_pend_data->TCBPtr;
p_pend_data_next = p_pend_data->NextPtr;
OS_Post((OS_PEND_OBJ *)((void *)p_q),
p_tcb,
p_void,
msg_size,
ts);
p_pend_data = p_pend_data_next;
cnt--;
}
OS_CRITICAL_EXIT_NO_SCHED();
if ((opt & OS_OPT_POST_NO_SCHED) == (OS_OPT)0) {
OSSched(); /* Run the scheduler */
}
*p_err = OS_ERR_NONE;
}
#endif

View File

@@ -0,0 +1,965 @@
/*
************************************************************************************************************************
* uC/OS-III
* The Real-Time Kernel
*
* (c) Copyright 2009-2012; Micrium, Inc.; Weston, FL
* All rights reserved. Protected by international copyright laws.
*
* SEMAPHORE MANAGEMENT
*
* File : OS_SEM.C
* By : JJL
* Version : V3.03.01
*
* LICENSING TERMS:
* ---------------
* uC/OS-III is provided in source form for FREE short-term evaluation, for educational use or
* for peaceful research. If you plan or intend to use uC/OS-III in a commercial application/
* product then, you need to contact Micrium to properly license uC/OS-III for its use in your
* application/product. We provide ALL the source code for your convenience and to help you
* experience uC/OS-III. The fact that the source is provided does NOT mean that you can use
* it commercially without paying a licensing fee.
*
* Knowledge of the source code may NOT be used to develop a similar product.
*
* Please help us continue to provide the embedded community with the finest software available.
* Your honesty is greatly appreciated.
*
* You can contact us at www.micrium.com, or by phone at +1 (954) 217-2036.
************************************************************************************************************************
*/
#define MICRIUM_SOURCE
#include <os.h>
#ifdef VSC_INCLUDE_SOURCE_FILE_NAMES
const CPU_CHAR *os_sem__c = "$Id: $";
#endif
#if OS_CFG_SEM_EN > 0u
/*
************************************************************************************************************************
* CREATE A SEMAPHORE
*
* Description: This function creates a semaphore.
*
* Arguments : p_sem is a pointer to the semaphore to initialize. Your application is responsible for
* allocating storage for the semaphore.
*
* p_name is a pointer to the name you would like to give the semaphore.
*
* cnt is the initial value for the semaphore.
* If used to share resources, you should initialize to the number of resources available.
* If used to signal the occurrence of event(s) then you should initialize to 0.
*
* p_err is a pointer to a variable that will contain an error code returned by this function.
*
* OS_ERR_NONE if the call was successful
* OS_ERR_CREATE_ISR if you called this function from an ISR
* OS_ERR_ILLEGAL_CREATE_RUN_TIME if you are trying to create the semaphore after you
* called OSSafetyCriticalStart().
* OS_ERR_NAME if 'p_name' is a NULL pointer
* OS_ERR_OBJ_CREATED if the semaphore has already been created
* OS_ERR_OBJ_PTR_NULL if 'p_sem' is a NULL pointer
* OS_ERR_OBJ_TYPE if 'p_sem' has already been initialized to a different
* object type
*
* Returns : none
************************************************************************************************************************
*/
void OSSemCreate (OS_SEM *p_sem,
CPU_CHAR *p_name,
OS_SEM_CTR cnt,
OS_ERR *p_err)
{
CPU_SR_ALLOC();
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return;
}
#endif
#ifdef OS_SAFETY_CRITICAL_IEC61508
if (OSSafetyCriticalStartFlag == DEF_TRUE) {
*p_err = OS_ERR_ILLEGAL_CREATE_RUN_TIME;
return;
}
#endif
#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u
if (OSIntNestingCtr > (OS_NESTING_CTR)0) { /* Not allowed to be called from an ISR */
*p_err = OS_ERR_CREATE_ISR;
return;
}
#endif
#if OS_CFG_ARG_CHK_EN > 0u
if (p_sem == (OS_SEM *)0) { /* Validate 'p_sem' */
*p_err = OS_ERR_OBJ_PTR_NULL;
return;
}
#endif
OS_CRITICAL_ENTER();
p_sem->Type = OS_OBJ_TYPE_SEM; /* Mark the data structure as a semaphore */
p_sem->Ctr = cnt; /* Set semaphore value */
p_sem->TS = (CPU_TS)0;
p_sem->NamePtr = p_name; /* Save the name of the semaphore */
OS_PendListInit(&p_sem->PendList); /* Initialize the waiting list */
#if OS_CFG_DBG_EN > 0u
OS_SemDbgListAdd(p_sem);
#endif
OSSemQty++;
OS_CRITICAL_EXIT_NO_SCHED();
*p_err = OS_ERR_NONE;
}
/*$PAGE*/
/*
************************************************************************************************************************
* DELETE A SEMAPHORE
*
* Description: This function deletes a semaphore.
*
* Arguments : p_sem is a pointer to the semaphore to delete
*
* opt determines delete options as follows:
*
* OS_OPT_DEL_NO_PEND Delete semaphore ONLY if no task pending
* OS_OPT_DEL_ALWAYS Deletes the semaphore even if tasks are waiting.
* In this case, all the tasks pending will be readied.
*
* p_err is a pointer to a variable that will contain an error code returned by this function.
*
* OS_ERR_NONE The call was successful and the semaphore was deleted
* OS_ERR_DEL_ISR If you attempted to delete the semaphore from an ISR
* OS_ERR_OBJ_PTR_NULL If 'p_sem' is a NULL pointer.
* OS_ERR_OBJ_TYPE If 'p_sem' is not pointing at a semaphore
* OS_ERR_OPT_INVALID An invalid option was specified
* OS_ERR_TASK_WAITING One or more tasks were waiting on the semaphore
*
* Returns : == 0 if no tasks were waiting on the semaphore, or upon error.
* > 0 if one or more tasks waiting on the semaphore are now readied and informed.
*
* Note(s) : 1) This function must be used with care. Tasks that would normally expect the presence of the semaphore
* MUST check the return code of OSSemPend().
* 2) OSSemAccept() callers will not know that the intended semaphore has been deleted.
* 3) Because ALL tasks pending on the semaphore will be readied, you MUST be careful in applications where
* the semaphore is used for mutual exclusion because the resource(s) will no longer be guarded by the
* semaphore.
************************************************************************************************************************
*/
#if OS_CFG_SEM_DEL_EN > 0u
OS_OBJ_QTY OSSemDel (OS_SEM *p_sem,
OS_OPT opt,
OS_ERR *p_err)
{
OS_OBJ_QTY cnt;
OS_OBJ_QTY nbr_tasks;
OS_PEND_DATA *p_pend_data;
OS_PEND_LIST *p_pend_list;
OS_TCB *p_tcb;
CPU_TS ts;
CPU_SR_ALLOC();
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return ((OS_OBJ_QTY)0);
}
#endif
#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u
if (OSIntNestingCtr > (OS_NESTING_CTR)0) { /* Not allowed to delete a semaphore from an ISR */
*p_err = OS_ERR_DEL_ISR;
return ((OS_OBJ_QTY)0);
}
#endif
#if OS_CFG_ARG_CHK_EN > 0u
if (p_sem == (OS_SEM *)0) { /* Validate 'p_sem' */
*p_err = OS_ERR_OBJ_PTR_NULL;
return ((OS_OBJ_QTY)0);
}
switch (opt) { /* Validate 'opt' */
case OS_OPT_DEL_NO_PEND:
case OS_OPT_DEL_ALWAYS:
break;
default:
*p_err = OS_ERR_OPT_INVALID;
return ((OS_OBJ_QTY)0);
}
#endif
#if OS_CFG_OBJ_TYPE_CHK_EN > 0u
if (p_sem->Type != OS_OBJ_TYPE_SEM) { /* Make sure semaphore was created */
*p_err = OS_ERR_OBJ_TYPE;
return ((OS_OBJ_QTY)0);
}
#endif
CPU_CRITICAL_ENTER();
p_pend_list = &p_sem->PendList;
cnt = p_pend_list->NbrEntries;
nbr_tasks = cnt;
switch (opt) {
case OS_OPT_DEL_NO_PEND: /* Delete semaphore only if no task waiting */
if (nbr_tasks == (OS_OBJ_QTY)0) {
#if OS_CFG_DBG_EN > 0u
OS_SemDbgListRemove(p_sem);
#endif
OSSemQty--;
OS_SemClr(p_sem);
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_NONE;
} else {
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_TASK_WAITING;
}
break;
case OS_OPT_DEL_ALWAYS: /* Always delete the semaphore */
OS_CRITICAL_ENTER_CPU_EXIT();
ts = OS_TS_GET(); /* Get local time stamp so all tasks get the same time */
while (cnt > 0u) { /* Remove all tasks on the pend list */
p_pend_data = p_pend_list->HeadPtr;
p_tcb = p_pend_data->TCBPtr;
OS_PendObjDel((OS_PEND_OBJ *)((void *)p_sem),
p_tcb,
ts);
cnt--;
}
#if OS_CFG_DBG_EN > 0u
OS_SemDbgListRemove(p_sem);
#endif
OSSemQty--;
OS_SemClr(p_sem);
OS_CRITICAL_EXIT_NO_SCHED();
OSSched(); /* Find highest priority task ready to run */
*p_err = OS_ERR_NONE;
break;
default:
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_OPT_INVALID;
break;
}
return ((OS_OBJ_QTY)nbr_tasks);
}
#endif
/*$PAGE*/
/*
************************************************************************************************************************
* PEND ON SEMAPHORE
*
* Description: This function waits for a semaphore.
*
* Arguments : p_sem is a pointer to the semaphore
*
* timeout is an optional timeout period (in clock ticks). If non-zero, your task will wait for the
* resource up to the amount of time (in 'ticks') specified by this argument. If you specify
* 0, however, your task will wait forever at the specified semaphore or, until the resource
* becomes available (or the event occurs).
*
* opt determines whether the user wants to block if the semaphore is not available or not:
*
* OS_OPT_PEND_BLOCKING
* OS_OPT_PEND_NON_BLOCKING
*
* p_ts is a pointer to a variable that will receive the timestamp of when the semaphore was posted
* or pend aborted or the semaphore deleted. If you pass a NULL pointer (i.e. (CPU_TS*)0)
* then you will not get the timestamp. In other words, passing a NULL pointer is valid
* and indicates that you don't need the timestamp.
*
* p_err is a pointer to a variable that will contain an error code returned by this function.
*
* OS_ERR_NONE The call was successful and your task owns the resource
* or, the event you are waiting for occurred.
* OS_ERR_OBJ_DEL If 'p_sem' was deleted
* OS_ERR_OBJ_PTR_NULL If 'p_sem' is a NULL pointer.
* OS_ERR_OBJ_TYPE If 'p_sem' is not pointing at a semaphore
* OS_ERR_OPT_INVALID If you specified an invalid value for 'opt'
* OS_ERR_PEND_ABORT If the pend was aborted by another task
* OS_ERR_PEND_ISR If you called this function from an ISR and the result
* would lead to a suspension.
* OS_ERR_PEND_WOULD_BLOCK If you specified non-blocking but the semaphore was not
* available.
* OS_ERR_SCHED_LOCKED If you called this function when the scheduler is locked
* OS_ERR_STATUS_INVALID Pend status is invalid
* OS_ERR_TIMEOUT The semaphore was not received within the specified
* timeout.
*
*
* Returns : The current value of the semaphore counter or 0 if not available.
************************************************************************************************************************
*/
OS_SEM_CTR OSSemPend (OS_SEM *p_sem,
OS_TICK timeout,
OS_OPT opt,
CPU_TS *p_ts,
OS_ERR *p_err)
{
OS_SEM_CTR ctr;
OS_PEND_DATA pend_data;
CPU_SR_ALLOC();
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return ((OS_SEM_CTR)0);
}
#endif
#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u
if (OSIntNestingCtr > (OS_NESTING_CTR)0) { /* Not allowed to call from an ISR */
*p_err = OS_ERR_PEND_ISR;
return ((OS_SEM_CTR)0);
}
#endif
#if OS_CFG_ARG_CHK_EN > 0u
if (p_sem == (OS_SEM *)0) { /* Validate 'p_sem' */
*p_err = OS_ERR_OBJ_PTR_NULL;
return ((OS_SEM_CTR)0);
}
switch (opt) { /* Validate 'opt' */
case OS_OPT_PEND_BLOCKING:
case OS_OPT_PEND_NON_BLOCKING:
break;
default:
*p_err = OS_ERR_OPT_INVALID;
return ((OS_SEM_CTR)0);
}
#endif
#if OS_CFG_OBJ_TYPE_CHK_EN > 0u
if (p_sem->Type != OS_OBJ_TYPE_SEM) { /* Make sure semaphore was created */
*p_err = OS_ERR_OBJ_TYPE;
return ((OS_SEM_CTR)0);
}
#endif
if (p_ts != (CPU_TS *)0) {
*p_ts = (CPU_TS)0; /* Initialize the returned timestamp */
}
CPU_CRITICAL_ENTER();
if (p_sem->Ctr > (OS_SEM_CTR)0) { /* Resource available? */
p_sem->Ctr--; /* Yes, caller may proceed */
if (p_ts != (CPU_TS *)0) {
*p_ts = p_sem->TS; /* get timestamp of last post */
}
ctr = p_sem->Ctr;
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_NONE;
return (ctr);
}
if ((opt & OS_OPT_PEND_NON_BLOCKING) != (OS_OPT)0) { /* Caller wants to block if not available? */
ctr = p_sem->Ctr; /* No */
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_PEND_WOULD_BLOCK;
return (ctr);
} else { /* Yes */
if (OSSchedLockNestingCtr > (OS_NESTING_CTR)0) { /* Can't pend when the scheduler is locked */
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_SCHED_LOCKED;
return ((OS_SEM_CTR)0);
}
}
/* Lock the scheduler/re-enable interrupts */
OS_CRITICAL_ENTER_CPU_EXIT();
OS_Pend(&pend_data, /* Block task pending on Semaphore */
(OS_PEND_OBJ *)((void *)p_sem),
OS_TASK_PEND_ON_SEM,
timeout);
OS_CRITICAL_EXIT_NO_SCHED();
OSSched(); /* Find the next highest priority task ready to run */
CPU_CRITICAL_ENTER();
switch (OSTCBCurPtr->PendStatus) {
case OS_STATUS_PEND_OK: /* We got the semaphore */
if (p_ts != (CPU_TS *)0) {
*p_ts = OSTCBCurPtr->TS;
}
*p_err = OS_ERR_NONE;
break;
case OS_STATUS_PEND_ABORT: /* Indicate that we aborted */
if (p_ts != (CPU_TS *)0) {
*p_ts = OSTCBCurPtr->TS;
}
*p_err = OS_ERR_PEND_ABORT;
break;
case OS_STATUS_PEND_TIMEOUT: /* Indicate that we didn't get semaphore within timeout */
if (p_ts != (CPU_TS *)0) {
*p_ts = (CPU_TS )0;
}
*p_err = OS_ERR_TIMEOUT;
break;
case OS_STATUS_PEND_DEL: /* Indicate that object pended on has been deleted */
if (p_ts != (CPU_TS *)0) {
*p_ts = OSTCBCurPtr->TS;
}
*p_err = OS_ERR_OBJ_DEL;
break;
default:
*p_err = OS_ERR_STATUS_INVALID;
CPU_CRITICAL_EXIT();
return ((OS_SEM_CTR)0);
}
ctr = p_sem->Ctr;
CPU_CRITICAL_EXIT();
return (ctr);
}
/*$PAGE*/
/*
************************************************************************************************************************
* ABORT WAITING ON A SEMAPHORE
*
* Description: This function aborts & readies any tasks currently waiting on a semaphore. This function should be used
* to fault-abort the wait on the semaphore, rather than to normally signal the semaphore via OSSemPost().
*
* Arguments : p_sem is a pointer to the semaphore
*
* opt determines the type of ABORT performed:
*
* OS_OPT_PEND_ABORT_1 ABORT wait for a single task (HPT) waiting on the semaphore
* OS_OPT_PEND_ABORT_ALL ABORT wait for ALL tasks that are waiting on the semaphore
* OS_OPT_POST_NO_SCHED Do not call the scheduler
*
* p_err is a pointer to a variable that will contain an error code returned by this function.
*
* OS_ERR_NONE At least one task waiting on the semaphore was readied and
* informed of the aborted wait; check return value for the
* number of tasks whose wait on the semaphore was aborted.
* OS_ERR_OBJ_PTR_NULL If 'p_sem' is a NULL pointer.
* OS_ERR_OBJ_TYPE If 'p_sem' is not pointing at a semaphore
* OS_ERR_OPT_INVALID If you specified an invalid option
* OS_ERR_PEND_ABORT_ISR If you called this function from an ISR
* OS_ERR_PEND_ABORT_NONE No task were pending
*
* Returns : == 0 if no tasks were waiting on the semaphore, or upon error.
* > 0 if one or more tasks waiting on the semaphore are now readied and informed.
************************************************************************************************************************
*/
#if OS_CFG_SEM_PEND_ABORT_EN > 0u
OS_OBJ_QTY OSSemPendAbort (OS_SEM *p_sem,
OS_OPT opt,
OS_ERR *p_err)
{
OS_PEND_LIST *p_pend_list;
OS_TCB *p_tcb;
CPU_TS ts;
OS_OBJ_QTY nbr_tasks;
CPU_SR_ALLOC();
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return ((OS_OBJ_QTY)0u);
}
#endif
#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u
if (OSIntNestingCtr > (OS_NESTING_CTR)0u) { /* Not allowed to Pend Abort from an ISR */
*p_err = OS_ERR_PEND_ABORT_ISR;
return ((OS_OBJ_QTY)0u);
}
#endif
#if OS_CFG_ARG_CHK_EN > 0u
if (p_sem == (OS_SEM *)0) { /* Validate 'p_sem' */
*p_err = OS_ERR_OBJ_PTR_NULL;
return ((OS_OBJ_QTY)0u);
}
switch (opt) { /* Validate 'opt' */
case OS_OPT_PEND_ABORT_1:
case OS_OPT_PEND_ABORT_ALL:
case OS_OPT_PEND_ABORT_1 | OS_OPT_POST_NO_SCHED:
case OS_OPT_PEND_ABORT_ALL | OS_OPT_POST_NO_SCHED:
break;
default:
*p_err = OS_ERR_OPT_INVALID;
return ((OS_OBJ_QTY)0u);
}
#endif
#if OS_CFG_OBJ_TYPE_CHK_EN > 0u
if (p_sem->Type != OS_OBJ_TYPE_SEM) { /* Make sure semaphore was created */
*p_err = OS_ERR_OBJ_TYPE;
return ((OS_OBJ_QTY)0u);
}
#endif
CPU_CRITICAL_ENTER();
p_pend_list = &p_sem->PendList;
if (p_pend_list->NbrEntries == (OS_OBJ_QTY)0u) { /* Any task waiting on semaphore? */
CPU_CRITICAL_EXIT(); /* No */
*p_err = OS_ERR_PEND_ABORT_NONE;
return ((OS_OBJ_QTY)0u);
}
OS_CRITICAL_ENTER_CPU_EXIT();
nbr_tasks = 0u;
ts = OS_TS_GET(); /* Get local time stamp so all tasks get the same time */
while (p_pend_list->NbrEntries > (OS_OBJ_QTY)0u) {
p_tcb = p_pend_list->HeadPtr->TCBPtr;
OS_PendAbort((OS_PEND_OBJ *)((void *)p_sem),
p_tcb,
ts);
nbr_tasks++;
if (opt != OS_OPT_PEND_ABORT_ALL) { /* Pend abort all tasks waiting? */
break; /* No */
}
}
OS_CRITICAL_EXIT_NO_SCHED();
if ((opt & OS_OPT_POST_NO_SCHED) == (OS_OPT)0u) {
OSSched(); /* Run the scheduler */
}
*p_err = OS_ERR_NONE;
return (nbr_tasks);
}
#endif
/*$PAGE*/
/*
************************************************************************************************************************
* POST TO A SEMAPHORE
*
* Description: This function signals a semaphore
*
* Arguments : p_sem is a pointer to the semaphore
*
* opt determines the type of POST performed:
*
* OS_OPT_POST_1 POST and ready only the highest priority task waiting on semaphore
* (if tasks are waiting).
* OS_OPT_POST_ALL POST to ALL tasks that are waiting on the semaphore
*
* OS_OPT_POST_NO_SCHED Do not call the scheduler
*
* Note(s): 1) OS_OPT_POST_NO_SCHED can be added with one of the other options.
*
* p_err is a pointer to a variable that will contain an error code returned by this function.
*
* OS_ERR_NONE The call was successful and the semaphore was signaled.
* OS_ERR_OBJ_PTR_NULL If 'p_sem' is a NULL pointer.
* OS_ERR_OBJ_TYPE If 'p_sem' is not pointing at a semaphore
* OS_ERR_SEM_OVF If the post would cause the semaphore count to overflow.
*
* Returns : The current value of the semaphore counter or 0 upon error.
************************************************************************************************************************
*/
OS_SEM_CTR OSSemPost (OS_SEM *p_sem,
OS_OPT opt,
OS_ERR *p_err)
{
OS_SEM_CTR ctr;
CPU_TS ts;
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return ((OS_SEM_CTR)0);
}
#endif
#if OS_CFG_ARG_CHK_EN > 0u
if (p_sem == (OS_SEM *)0) { /* Validate 'p_sem' */
*p_err = OS_ERR_OBJ_PTR_NULL;
return ((OS_SEM_CTR)0);
}
switch (opt) { /* Validate 'opt' */
case OS_OPT_POST_1:
case OS_OPT_POST_ALL:
case OS_OPT_POST_1 | OS_OPT_POST_NO_SCHED:
case OS_OPT_POST_ALL | OS_OPT_POST_NO_SCHED:
break;
default:
*p_err = OS_ERR_OPT_INVALID;
return ((OS_SEM_CTR)0u);
}
#endif
#if OS_CFG_OBJ_TYPE_CHK_EN > 0u
if (p_sem->Type != OS_OBJ_TYPE_SEM) { /* Make sure semaphore was created */
*p_err = OS_ERR_OBJ_TYPE;
return ((OS_SEM_CTR)0);
}
#endif
ts = OS_TS_GET(); /* Get timestamp */
#if OS_CFG_ISR_POST_DEFERRED_EN > 0u
if (OSIntNestingCtr > (OS_NESTING_CTR)0) { /* See if called from an ISR */
OS_IntQPost((OS_OBJ_TYPE)OS_OBJ_TYPE_SEM, /* Post to ISR queue */
(void *)p_sem,
(void *)0,
(OS_MSG_SIZE)0,
(OS_FLAGS )0,
(OS_OPT )opt,
(CPU_TS )ts,
(OS_ERR *)p_err);
return ((OS_SEM_CTR)0);
}
#endif
ctr = OS_SemPost(p_sem, /* Post to semaphore */
opt,
ts,
p_err);
return (ctr);
}
/*$PAGE*/
/*
************************************************************************************************************************
* SET SEMAPHORE
*
* Description: This function sets the semaphore count to the value specified as an argument. Typically, this value
* would be 0 but of course, we can set the semaphore to any value.
*
* You would typically use this function when a semaphore is used as a signaling mechanism
* and, you want to reset the count value.
*
* Arguments : p_sem is a pointer to the semaphore
*
* cnt is the new value for the semaphore count. You would pass 0 to reset the semaphore count.
*
* p_err is a pointer to a variable that will contain an error code returned by this function.
*
* OS_ERR_NONE The call was successful and the semaphore value was set.
* OS_ERR_OBJ_PTR_NULL If 'p_sem' is a NULL pointer.
* OS_ERR_OBJ_TYPE If 'p_sem' is not pointing to a semaphore.
* OS_ERR_TASK_WAITING If tasks are waiting on the semaphore.
*
* Returns : None
************************************************************************************************************************
*/
#if OS_CFG_SEM_SET_EN > 0u
void OSSemSet (OS_SEM *p_sem,
OS_SEM_CTR cnt,
OS_ERR *p_err)
{
OS_PEND_LIST *p_pend_list;
CPU_SR_ALLOC();
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return;
}
#endif
#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u
if (OSIntNestingCtr > (OS_NESTING_CTR)0) { /* Can't call this function from an ISR */
*p_err = OS_ERR_SET_ISR;
return;
}
#endif
#if OS_CFG_ARG_CHK_EN > 0u
if (p_sem == (OS_SEM *)0) { /* Validate 'p_sem' */
*p_err = OS_ERR_OBJ_PTR_NULL;
return;
}
#endif
#if OS_CFG_OBJ_TYPE_CHK_EN > 0u
if (p_sem->Type != OS_OBJ_TYPE_SEM) { /* Make sure semaphore was created */
*p_err = OS_ERR_OBJ_TYPE;
return;
}
#endif
*p_err = OS_ERR_NONE;
CPU_CRITICAL_ENTER();
if (p_sem->Ctr > (OS_SEM_CTR)0) { /* See if semaphore already has a count */
p_sem->Ctr = cnt; /* Yes, set it to the new value specified. */
} else {
p_pend_list = &p_sem->PendList; /* No */
if (p_pend_list->NbrEntries == (OS_OBJ_QTY)0) { /* See if task(s) waiting? */
p_sem->Ctr = cnt; /* No, OK to set the value */
} else {
*p_err = OS_ERR_TASK_WAITING;
}
}
CPU_CRITICAL_EXIT();
}
#endif
/*$PAGE*/
/*
************************************************************************************************************************
* CLEAR THE CONTENTS OF A SEMAPHORE
*
* Description: This function is called by OSSemDel() to clear the contents of a semaphore
*
* Argument(s): p_sem is a pointer to the semaphore to clear
* -----
*
* Returns : none
*
* Note(s) : 1) This function is INTERNAL to uC/OS-III and your application MUST NOT call it.
************************************************************************************************************************
*/
void OS_SemClr (OS_SEM *p_sem)
{
p_sem->Type = OS_OBJ_TYPE_NONE; /* Mark the data structure as a NONE */
p_sem->Ctr = (OS_SEM_CTR)0; /* Set semaphore value */
p_sem->TS = (CPU_TS )0; /* Clear the time stamp */
p_sem->NamePtr = (CPU_CHAR *)((void *)"?SEM");
OS_PendListInit(&p_sem->PendList); /* Initialize the waiting list */
}
/*$PAGE*/
/*
************************************************************************************************************************
* ADD/REMOVE SEMAPHORE TO/FROM DEBUG LIST
*
* Description: These functions are called by uC/OS-III to add or remove a semaphore to/from the debug list.
*
* Arguments : p_sem is a pointer to the semaphore to add/remove
*
* Returns : none
*
* Note(s) : These functions are INTERNAL to uC/OS-III and your application should not call it.
************************************************************************************************************************
*/
#if OS_CFG_DBG_EN > 0u
void OS_SemDbgListAdd (OS_SEM *p_sem)
{
p_sem->DbgNamePtr = (CPU_CHAR *)((void *)" ");
p_sem->DbgPrevPtr = (OS_SEM *)0;
if (OSSemDbgListPtr == (OS_SEM *)0) {
p_sem->DbgNextPtr = (OS_SEM *)0;
} else {
p_sem->DbgNextPtr = OSSemDbgListPtr;
OSSemDbgListPtr->DbgPrevPtr = p_sem;
}
OSSemDbgListPtr = p_sem;
}
void OS_SemDbgListRemove (OS_SEM *p_sem)
{
OS_SEM *p_sem_next;
OS_SEM *p_sem_prev;
p_sem_prev = p_sem->DbgPrevPtr;
p_sem_next = p_sem->DbgNextPtr;
if (p_sem_prev == (OS_SEM *)0) {
OSSemDbgListPtr = p_sem_next;
if (p_sem_next != (OS_SEM *)0) {
p_sem_next->DbgPrevPtr = (OS_SEM *)0;
}
p_sem->DbgNextPtr = (OS_SEM *)0;
} else if (p_sem_next == (OS_SEM *)0) {
p_sem_prev->DbgNextPtr = (OS_SEM *)0;
p_sem->DbgPrevPtr = (OS_SEM *)0;
} else {
p_sem_prev->DbgNextPtr = p_sem_next;
p_sem_next->DbgPrevPtr = p_sem_prev;
p_sem->DbgNextPtr = (OS_SEM *)0;
p_sem->DbgPrevPtr = (OS_SEM *)0;
}
}
#endif
/*$PAGE*/
/*
************************************************************************************************************************
* SEMAPHORE INITIALIZATION
*
* Description: This function is called by OSInit() to initialize the semaphore management.
*
* Argument(s): p_err is a pointer to a variable that will contain an error code returned by this function.
*
* OS_ERR_NONE the call was successful
*
* Returns : none
*
* Note(s) : 1) This function is INTERNAL to uC/OS-III and your application MUST NOT call it.
************************************************************************************************************************
*/
void OS_SemInit (OS_ERR *p_err)
{
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return;
}
#endif
#if OS_CFG_DBG_EN > 0u
OSSemDbgListPtr = (OS_SEM *)0;
#endif
OSSemQty = (OS_OBJ_QTY)0;
*p_err = OS_ERR_NONE;
}
/*$PAGE*/
/*
************************************************************************************************************************
* POST TO A SEMAPHORE
*
* Description: This function signals a semaphore
*
* Arguments : p_sem is a pointer to the semaphore
*
* opt determines the type of POST performed:
*
* OS_OPT_POST_1 POST to a single waiting task
* OS_OPT_POST_ALL POST to ALL tasks that are waiting on the semaphore
*
* OS_OPT_POST_NO_SCHED Do not call the scheduler
*
* Note(s): 1) OS_OPT_POST_NO_SCHED can be added with one of the other options.
*
* ts is a timestamp indicating when the post occurred.
*
* p_err is a pointer to a variable that will contain an error code returned by this function.
*
* OS_ERR_NONE The call was successful and the semaphore was signaled.
* OS_ERR_OBJ_PTR_NULL If 'p_sem' is a NULL pointer.
* OS_ERR_OBJ_TYPE If 'p_sem' is not pointing at a semaphore
* OS_ERR_SEM_OVF If the post would cause the semaphore count to overflow.
*
* Returns : The current value of the semaphore counter or 0 upon error.
*
* Note(s) : This function is INTERNAL to uC/OS-III and your application should not call it.
************************************************************************************************************************
*/
OS_SEM_CTR OS_SemPost (OS_SEM *p_sem,
OS_OPT opt,
CPU_TS ts,
OS_ERR *p_err)
{
OS_OBJ_QTY cnt;
OS_SEM_CTR ctr;
OS_PEND_LIST *p_pend_list;
OS_PEND_DATA *p_pend_data;
OS_PEND_DATA *p_pend_data_next;
OS_TCB *p_tcb;
CPU_SR_ALLOC();
CPU_CRITICAL_ENTER();
p_pend_list = &p_sem->PendList;
if (p_pend_list->NbrEntries == (OS_OBJ_QTY)0) { /* Any task waiting on semaphore? */
switch (sizeof(OS_SEM_CTR)) {
case 1u:
if (p_sem->Ctr == DEF_INT_08U_MAX_VAL) {
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_SEM_OVF;
return ((OS_SEM_CTR)0);
}
break;
case 2u:
if (p_sem->Ctr == DEF_INT_16U_MAX_VAL) {
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_SEM_OVF;
return ((OS_SEM_CTR)0);
}
break;
case 4u:
if (p_sem->Ctr == DEF_INT_32U_MAX_VAL) {
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_SEM_OVF;
return ((OS_SEM_CTR)0);
}
break;
default:
break;
}
p_sem->Ctr++; /* No */
ctr = p_sem->Ctr;
p_sem->TS = ts; /* Save timestamp in semaphore control block */
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_NONE;
return (ctr);
}
OS_CRITICAL_ENTER_CPU_EXIT();
if ((opt & OS_OPT_POST_ALL) != (OS_OPT)0) { /* Post message to all tasks waiting? */
cnt = p_pend_list->NbrEntries; /* Yes */
} else {
cnt = (OS_OBJ_QTY)1; /* No */
}
p_pend_data = p_pend_list->HeadPtr;
while (cnt > 0u) {
p_tcb = p_pend_data->TCBPtr;
p_pend_data_next = p_pend_data->NextPtr;
OS_Post((OS_PEND_OBJ *)((void *)p_sem),
p_tcb,
(void *)0,
(OS_MSG_SIZE)0,
ts);
p_pend_data = p_pend_data_next;
cnt--;
}
ctr = p_sem->Ctr;
OS_CRITICAL_EXIT_NO_SCHED();
if ((opt & OS_OPT_POST_NO_SCHED) == (OS_OPT)0) {
OSSched(); /* Run the scheduler */
}
*p_err = OS_ERR_NONE;
return (ctr);
}
#endif

View File

@@ -0,0 +1,518 @@
/*
************************************************************************************************************************
* uC/OS-III
* The Real-Time Kernel
*
* (c) Copyright 2009-2012; Micrium, Inc.; Weston, FL
* All rights reserved. Protected by international copyright laws.
*
* STATISTICS MODULE
*
* File : OS_STAT.C
* By : JJL
* Version : V3.03.01
*
* LICENSING TERMS:
* ---------------
* uC/OS-III is provided in source form for FREE short-term evaluation, for educational use or
* for peaceful research. If you plan or intend to use uC/OS-III in a commercial application/
* product then, you need to contact Micrium to properly license uC/OS-III for its use in your
* application/product. We provide ALL the source code for your convenience and to help you
* experience uC/OS-III. The fact that the source is provided does NOT mean that you can use
* it commercially without paying a licensing fee.
*
* Knowledge of the source code may NOT be used to develop a similar product.
*
* Please help us continue to provide the embedded community with the finest software available.
* Your honesty is greatly appreciated.
*
* You can contact us at www.micrium.com, or by phone at +1 (954) 217-2036.
************************************************************************************************************************
*/
#define MICRIUM_SOURCE
#include <os.h>
#ifdef VSC_INCLUDE_SOURCE_FILE_NAMES
const CPU_CHAR *os_stat__c = "$Id: $";
#endif
#if OS_CFG_STAT_TASK_EN > 0u
/*
************************************************************************************************************************
* RESET STATISTICS
*
* Description: This function is called by your application to reset the statistics.
*
* Argument(s): p_err is a pointer to a variable that will contain an error code returned by this function.
*
* OS_ERR_NONE
*
* Returns : none
************************************************************************************************************************
*/
void OSStatReset (OS_ERR *p_err)
{
#if (OS_CFG_DBG_EN > 0u)
OS_TCB *p_tcb;
#if (OS_MSG_EN > 0u)
OS_MSG_Q *p_msg_q;
#endif
#if (OS_CFG_Q_EN > 0u)
OS_Q *p_q;
#endif
#endif
CPU_SR_ALLOC();
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return;
}
#endif
CPU_CRITICAL_ENTER();
#if OS_CFG_ISR_POST_DEFERRED_EN > 0u
OSIntQTaskTimeMax = (CPU_TS )0; /* Reset the task execution times */
OSIntQNbrEntriesMax = (OS_OBJ_QTY)0; /* Reset the queue maximum number of entries */
#endif
#if OS_CFG_STAT_TASK_EN > 0u
OSStatTaskCPUUsageMax = 0u;
OSStatTaskTimeMax = (CPU_TS)0;
#endif
OSTickTaskTimeMax = (CPU_TS)0;
#if OS_CFG_TMR_EN > 0u
OSTmrTaskTimeMax = (CPU_TS)0;
#endif
#ifdef CPU_CFG_INT_DIS_MEAS_EN
OSIntDisTimeMax = (CPU_TS)0; /* Reset the maximum interrupt disable time */
#endif
#if OS_CFG_SCHED_LOCK_TIME_MEAS_EN > 0u
OSSchedLockTimeMax = (CPU_TS)0; /* Reset the maximum scheduler lock time */
#endif
#if OS_MSG_EN > 0u
OSMsgPool.NbrUsedMax = 0u;
#endif
CPU_CRITICAL_EXIT();
#if OS_CFG_DBG_EN > 0u
CPU_CRITICAL_ENTER();
p_tcb = OSTaskDbgListPtr;
CPU_CRITICAL_EXIT();
while (p_tcb != (OS_TCB *)0) { /* Reset per-Task statistics */
CPU_CRITICAL_ENTER();
#ifdef CPU_CFG_INT_DIS_MEAS_EN
p_tcb->IntDisTimeMax = (CPU_TS )0;
#endif
#if OS_CFG_SCHED_LOCK_TIME_MEAS_EN > 0u
p_tcb->SchedLockTimeMax = (CPU_TS )0;
#endif
#if OS_CFG_TASK_PROFILE_EN > 0u
#if OS_CFG_TASK_Q_EN > 0u
p_tcb->MsgQPendTimeMax = (CPU_TS )0;
#endif
p_tcb->SemPendTimeMax = (CPU_TS )0;
p_tcb->CtxSwCtr = (OS_CTR )0;
p_tcb->CPUUsage = (OS_CPU_USAGE)0;
p_tcb->CPUUsageMax = (OS_CPU_USAGE)0;
p_tcb->CyclesTotal = (OS_CYCLES )0;
p_tcb->CyclesTotalPrev = (OS_CYCLES )0;
p_tcb->CyclesStart = OS_TS_GET();
#endif
#if OS_CFG_TASK_Q_EN > 0u
p_msg_q = &p_tcb->MsgQ;
p_msg_q->NbrEntriesMax = (OS_MSG_QTY )0;
#endif
p_tcb = p_tcb->DbgNextPtr;
CPU_CRITICAL_EXIT();
}
#endif
#if (OS_CFG_Q_EN > 0u) && (OS_CFG_DBG_EN > 0u)
CPU_CRITICAL_ENTER();
p_q = OSQDbgListPtr;
CPU_CRITICAL_EXIT();
while (p_q != (OS_Q *)0) { /* Reset message queues statistics */
CPU_CRITICAL_ENTER();
p_msg_q = &p_q->MsgQ;
p_msg_q->NbrEntriesMax = (OS_MSG_QTY)0;
p_q = p_q->DbgNextPtr;
CPU_CRITICAL_EXIT();
}
#endif
OS_TickListResetPeak(); /* Reset tick wheel statistics */
#if OS_CFG_TMR_EN > 0u
OS_TmrResetPeak();
#endif
*p_err = OS_ERR_NONE;
}
/*$PAGE*/
/*
************************************************************************************************************************
* DETERMINE THE CPU CAPACITY
*
* Description: This function is called by your application to establish CPU usage by first determining how high a 32-bit
* counter would count to in 1/10 second if no other tasks were to execute during that time. CPU usage is
* then determined by a low priority task which keeps track of this 32-bit counter every second but this
* time, with other tasks running. CPU usage is determined by:
*
* OS_Stat_IdleCtr
* CPU Usage (%) = 100 * (1 - ------------------)
* OS_Stat_IdleCtrMax
*
* Argument(s): p_err is a pointer to a variable that will contain an error code returned by this function.
*
* OS_ERR_NONE
*
* Returns : none
************************************************************************************************************************
*/
void OSStatTaskCPUUsageInit (OS_ERR *p_err)
{
OS_ERR err;
OS_TICK dly;
CPU_SR_ALLOC();
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return;
}
#endif
#if (OS_CFG_TMR_EN > 0u)
OSTaskSuspend(&OSTmrTaskTCB, &err);
if (err != OS_ERR_NONE) {
*p_err = err;
return;
}
#endif
OSTimeDly((OS_TICK )2, /* Synchronize with clock tick */
(OS_OPT )OS_OPT_TIME_DLY,
(OS_ERR *)&err);
if (err != OS_ERR_NONE) {
*p_err = err;
return;
}
CPU_CRITICAL_ENTER();
OSStatTaskCtr = (OS_TICK)0; /* Clear idle counter */
CPU_CRITICAL_EXIT();
dly = (OS_TICK)0;
if (OSCfg_TickRate_Hz > OSCfg_StatTaskRate_Hz) {
dly = (OS_TICK)(OSCfg_TickRate_Hz / OSCfg_StatTaskRate_Hz);
}
if (dly == (OS_TICK)0) {
dly = (OS_TICK)(OSCfg_TickRate_Hz / (OS_RATE_HZ)10);
}
OSTimeDly(dly, /* Determine MAX. idle counter value */
OS_OPT_TIME_DLY,
&err);
#if (OS_CFG_TMR_EN > 0u)
OSTaskResume(&OSTmrTaskTCB, &err);
if (err != OS_ERR_NONE) {
*p_err = err;
return;
}
#endif
CPU_CRITICAL_ENTER();
OSStatTaskTimeMax = (CPU_TS)0;
OSStatTaskCtrMax = OSStatTaskCtr; /* Store maximum idle counter count */
OSStatTaskRdy = OS_STATE_RDY;
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_NONE;
}
/*$PAGE*/
/*
************************************************************************************************************************
* STATISTICS TASK
*
* Description: This task is internal to uC/OS-III and is used to compute some statistics about the multitasking
* environment. Specifically, OS_StatTask() computes the CPU usage. CPU usage is determined by:
*
* OSStatTaskCtr
* OSStatTaskCPUUsage = 100 * (1 - ------------------) (units are in %)
* OSStatTaskCtrMax
*
* Arguments : p_arg this pointer is not used at this time.
*
* Returns : none
*
* Note(s) : 1) This task runs at a priority level higher than the idle task.
*
* 2) You can disable this task by setting the configuration #define OS_CFG_STAT_TASK_EN to 0.
*
* 3) You MUST have at least a delay of 2/10 seconds to allow for the system to establish the maximum value
* for the idle counter.
*
* 4) This function is INTERNAL to uC/OS-III and your application should not call it.
************************************************************************************************************************
*/
void OS_StatTask (void *p_arg)
{
#if OS_CFG_DBG_EN > 0u
#if OS_CFG_TASK_PROFILE_EN > 0u
OS_CPU_USAGE usage;
OS_CYCLES cycles_total;
OS_CYCLES cycles_div;
OS_CYCLES cycles_mult;
OS_CYCLES cycles_max;
#endif
OS_TCB *p_tcb;
#endif
OS_TICK ctr_max;
OS_TICK ctr_mult;
OS_TICK ctr_div;
OS_ERR err;
OS_TICK dly;
CPU_TS ts_start;
CPU_TS ts_end;
CPU_SR_ALLOC();
p_arg = p_arg; /* Prevent compiler warning for not using 'p_arg' */
while (OSStatTaskRdy != DEF_TRUE) {
OSTimeDly(2u * OSCfg_StatTaskRate_Hz, /* Wait until statistic task is ready */
OS_OPT_TIME_DLY,
&err);
}
OSStatReset(&err); /* Reset statistics */
dly = (OS_TICK)0; /* Compute statistic task sleep delay */
if (OSCfg_TickRate_Hz > OSCfg_StatTaskRate_Hz) {
dly = (OS_TICK)(OSCfg_TickRate_Hz / OSCfg_StatTaskRate_Hz);
}
if (dly == (OS_TICK)0) {
dly = (OS_TICK)(OSCfg_TickRate_Hz / (OS_RATE_HZ)10);
}
while (DEF_ON) {
ts_start = OS_TS_GET();
#ifdef CPU_CFG_INT_DIS_MEAS_EN
OSIntDisTimeMax = CPU_IntDisMeasMaxGet();
#endif
CPU_CRITICAL_ENTER(); /* ----------------- OVERALL CPU USAGE ------------------ */
OSStatTaskCtrRun = OSStatTaskCtr; /* Obtain the of the stat counter for the past .1 second */
OSStatTaskCtr = (OS_TICK)0; /* Reset the stat counter for the next .1 second */
CPU_CRITICAL_EXIT();
if (OSStatTaskCtrMax > OSStatTaskCtrRun) { /* Compute CPU Usage with best resolution */
if (OSStatTaskCtrMax < 400000u) { /* 1 to 400,000 */
ctr_mult = 10000u;
ctr_div = 1u;
} else if (OSStatTaskCtrMax < 4000000u) { /* 400,000 to 4,000,000 */
ctr_mult = 1000u;
ctr_div = 10u;
} else if (OSStatTaskCtrMax < 40000000u) { /* 4,000,000 to 40,000,000 */
ctr_mult = 100u;
ctr_div = 100u;
} else if (OSStatTaskCtrMax < 400000000u) { /* 40,000,000 to 400,000,000 */
ctr_mult = 10u;
ctr_div = 1000u;
} else { /* 400,000,000 and up */
ctr_mult = 1u;
ctr_div = 10000u;
}
ctr_max = OSStatTaskCtrMax / ctr_div;
OSStatTaskCPUUsage = (OS_CPU_USAGE)((OS_TICK)10000u - ctr_mult * OSStatTaskCtrRun / ctr_max);
if (OSStatTaskCPUUsageMax < OSStatTaskCPUUsage) {
OSStatTaskCPUUsageMax = OSStatTaskCPUUsage;
}
} else {
OSStatTaskCPUUsage = (OS_CPU_USAGE)10000u;
}
OSStatTaskHook(); /* Invoke user definable hook */
#if OS_CFG_DBG_EN > 0u
#if OS_CFG_TASK_PROFILE_EN > 0u
cycles_total = (OS_CYCLES)0;
CPU_CRITICAL_ENTER();
p_tcb = OSTaskDbgListPtr;
CPU_CRITICAL_EXIT();
while (p_tcb != (OS_TCB *)0) { /* ----------------- TOTAL CYCLES COUNT ----------------- */
OS_CRITICAL_ENTER();
p_tcb->CyclesTotalPrev = p_tcb->CyclesTotal; /* Save accumulated # cycles into a temp variable */
p_tcb->CyclesTotal = (OS_CYCLES)0; /* Reset total cycles for task for next run */
OS_CRITICAL_EXIT();
cycles_total += p_tcb->CyclesTotalPrev;/* Perform sum of all task # cycles */
CPU_CRITICAL_ENTER();
p_tcb = p_tcb->DbgNextPtr;
CPU_CRITICAL_EXIT();
}
#endif
#if OS_CFG_TASK_PROFILE_EN > 0u
/* ------------- INDIVIDUAL TASK CPU USAGE -------------- */
if (cycles_total > (OS_CYCLES)0u) { /* 'cycles_total' scaling ... */
if (cycles_total < 400000u) { /* 1 to 400,000 */
cycles_mult = 10000u;
cycles_div = 1u;
} else if (cycles_total < 4000000u) { /* 400,000 to 4,000,000 */
cycles_mult = 1000u;
cycles_div = 10u;
} else if (cycles_total < 40000000u) { /* 4,000,000 to 40,000,000 */
cycles_mult = 100u;
cycles_div = 100u;
} else if (cycles_total < 400000000u) { /* 40,000,000 to 400,000,000 */
cycles_mult = 10u;
cycles_div = 1000u;
} else { /* 400,000,000 and up */
cycles_mult = 1u;
cycles_div = 10000u;
}
cycles_max = cycles_total / cycles_div;
} else {
cycles_mult = 0u;
cycles_max = 1u;
}
#endif
CPU_CRITICAL_ENTER();
p_tcb = OSTaskDbgListPtr;
CPU_CRITICAL_EXIT();
while (p_tcb != (OS_TCB *)0) {
#if OS_CFG_TASK_PROFILE_EN > 0u /* Compute execution time of each task */
usage = (OS_CPU_USAGE)(cycles_mult * p_tcb->CyclesTotalPrev / cycles_max);
if (usage > 10000u) {
usage = 10000u;
}
p_tcb->CPUUsage = usage;
if (p_tcb->CPUUsageMax < usage) { /* Detect peak CPU usage */
p_tcb->CPUUsageMax = usage;
}
#endif
#if OS_CFG_STAT_TASK_STK_CHK_EN > 0u
OSTaskStkChk( p_tcb, /* Compute stack usage of active tasks only */
&p_tcb->StkFree,
&p_tcb->StkUsed,
&err);
#endif
CPU_CRITICAL_ENTER();
p_tcb = p_tcb->DbgNextPtr;
CPU_CRITICAL_EXIT();
}
#endif
if (OSStatResetFlag == DEF_TRUE) { /* Check if need to reset statistics */
OSStatResetFlag = DEF_FALSE;
OSStatReset(&err);
}
ts_end = OS_TS_GET() - ts_start; /* Measure execution time of statistic task */
if (OSStatTaskTimeMax < ts_end) {
OSStatTaskTimeMax = ts_end;
}
OSTimeDly(dly,
OS_OPT_TIME_DLY,
&err);
}
}
/*$PAGE*/
/*
************************************************************************************************************************
* INITIALIZE THE STATISTICS
*
* Description: This function is called by OSInit() to initialize the statistic task.
*
* Argument(s): p_err is a pointer to a variable that will contain an error code returned by this function.
*
* OS_ERR_STK_INVALID If you specified a NULL stack pointer during configuration
* OS_ERR_STK_SIZE_INVALID If you didn't specify a large enough stack.
* OS_ERR_PRIO_INVALID If you specified a priority for the statistic task equal to or
* lower (i.e. higher number) than the idle task.
* OS_ERR_xxx An error code returned by OSTaskCreate()
*
* Returns : none
*
* Note(s) : This function is INTERNAL to uC/OS-III and your application should not call it.
************************************************************************************************************************
*/
void OS_StatTaskInit (OS_ERR *p_err)
{
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return;
}
#endif
OSStatTaskCtr = (OS_TICK)0;
OSStatTaskCtrRun = (OS_TICK)0;
OSStatTaskCtrMax = (OS_TICK)0;
OSStatTaskRdy = OS_STATE_NOT_RDY; /* Statistic task is not ready */
OSStatResetFlag = DEF_FALSE;
/* ---------------- CREATE THE STAT TASK ---------------- */
if (OSCfg_StatTaskStkBasePtr == (CPU_STK *)0) {
*p_err = OS_ERR_STAT_STK_INVALID;
return;
}
if (OSCfg_StatTaskStkSize < OSCfg_StkSizeMin) {
*p_err = OS_ERR_STAT_STK_SIZE_INVALID;
return;
}
if (OSCfg_StatTaskPrio >= (OS_CFG_PRIO_MAX - 1u)) {
*p_err = OS_ERR_STAT_PRIO_INVALID;
return;
}
OSTaskCreate((OS_TCB *)&OSStatTaskTCB,
(CPU_CHAR *)((void *)"uC/OS-III Stat Task"),
(OS_TASK_PTR )OS_StatTask,
(void *)0,
(OS_PRIO )OSCfg_StatTaskPrio,
(CPU_STK *)OSCfg_StatTaskStkBasePtr,
(CPU_STK_SIZE)OSCfg_StatTaskStkLimit,
(CPU_STK_SIZE)OSCfg_StatTaskStkSize,
(OS_MSG_QTY )0,
(OS_TICK )0,
(void *)0,
(OS_OPT )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
(OS_ERR *)p_err);
}
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,517 @@
/*
***********************************************************************************************************************
* uC/OS-III
* The Real-Time Kernel
*
* (c) Copyright 2009-2012; Micrium, Inc.; Weston, FL
* All rights reserved. Protected by international copyright laws.
*
* TICK MANAGEMENT
*
* File : OS_TICK.C
* By : JJL
* Version : V3.03.01
*
* LICENSING TERMS:
* ---------------
* uC/OS-III is provided in source form for FREE short-term evaluation, for educational use or
* for peaceful research. If you plan or intend to use uC/OS-III in a commercial application/
* product then, you need to contact Micrium to properly license uC/OS-III for its use in your
* application/product. We provide ALL the source code for your convenience and to help you
* experience uC/OS-III. The fact that the source is provided does NOT mean that you can use
* it commercially without paying a licensing fee.
*
* Knowledge of the source code may NOT be used to develop a similar product.
*
* Please help us continue to provide the embedded community with the finest software available.
* Your honesty is greatly appreciated.
*
* You can contact us at www.micrium.com, or by phone at +1 (954) 217-2036.
************************************************************************************************************************
*/
#define MICRIUM_SOURCE
#include <os.h>
#ifdef VSC_INCLUDE_SOURCE_FILE_NAMES
const CPU_CHAR *os_tick__c = "$Id: $";
#endif
/*
************************************************************************************************************************
* LOCAL PROTOTYPES
************************************************************************************************************************
*/
/*
************************************************************************************************************************
* TICK TASK
*
* Description: This task is internal to uC/OS-III and is triggered by the tick interrupt.
*
* Arguments : p_arg is an argument passed to the task when the task is created (unused).
*
* Returns : none
*
* Note(s) : This function is INTERNAL to uC/OS-III and your application should not call it.
************************************************************************************************************************
*/
void OS_TickTask (void *p_arg)
{
OS_ERR err;
CPU_TS ts;
p_arg = p_arg; /* Prevent compiler warning */
while (DEF_ON) {
(void)OSTaskSemPend((OS_TICK )0,
(OS_OPT )OS_OPT_PEND_BLOCKING,
(CPU_TS *)&ts,
(OS_ERR *)&err); /* Wait for signal from tick interrupt */
if (err == OS_ERR_NONE) {
if (OSRunning == OS_STATE_OS_RUNNING) {
OS_TickListUpdate(); /* Update all tasks waiting for time */
}
}
}
}
/*$PAGE*/
/*
************************************************************************************************************************
* INITIALIZE TICK TASK
*
* Description: This function is called by OSInit() to create the tick task.
*
* Arguments : p_err is a pointer to a variable that will hold the value of an error code:
*
* OS_ERR_TICK_STK_INVALID if the pointer to the tick task stack is a NULL pointer
* OS_ERR_TICK_STK_SIZE indicates that the specified stack size
* OS_ERR_PRIO_INVALID if the priority you specified in the configuration is invalid
* (There could be only one task at the Idle Task priority)
* (Maybe the priority you specified is higher than OS_CFG_PRIO_MAX-1
* OS_ERR_?? other error code returned by OSTaskCreate()
*
* Returns : none
*
* Note(s) : This function is INTERNAL to uC/OS-III and your application should not call it.
************************************************************************************************************************
*/
void OS_TickTaskInit (OS_ERR *p_err)
{
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return;
}
#endif
OSTickCtr = (OS_TICK)0u; /* Clear the tick counter */
OSTickTaskTimeMax = (CPU_TS)0u;
OS_TickListInit(); /* Initialize the tick list data structures */
/* ---------------- CREATE THE TICK TASK ---------------- */
if (OSCfg_TickTaskStkBasePtr == (CPU_STK *)0) {
*p_err = OS_ERR_TICK_STK_INVALID;
return;
}
if (OSCfg_TickTaskStkSize < OSCfg_StkSizeMin) {
*p_err = OS_ERR_TICK_STK_SIZE_INVALID;
return;
}
if (OSCfg_TickTaskPrio >= (OS_CFG_PRIO_MAX - 1u)) { /* Only one task at the 'Idle Task' priority */
*p_err = OS_ERR_TICK_PRIO_INVALID;
return;
}
OSTaskCreate((OS_TCB *)&OSTickTaskTCB,
(CPU_CHAR *)((void *)"uC/OS-III Tick Task"),
(OS_TASK_PTR )OS_TickTask,
(void *)0,
(OS_PRIO )OSCfg_TickTaskPrio,
(CPU_STK *)OSCfg_TickTaskStkBasePtr,
(CPU_STK_SIZE)OSCfg_TickTaskStkLimit,
(CPU_STK_SIZE)OSCfg_TickTaskStkSize,
(OS_MSG_QTY )0u,
(OS_TICK )0u,
(void *)0,
(OS_OPT )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR | OS_OPT_TASK_NO_TLS),
(OS_ERR *)p_err);
}
/*$PAGE*/
/*
************************************************************************************************************************
* INITIALIZE THE TICK LIST
*
* Description: This function initializes the tick handling data structures of uC/OS-III.
*
* Arguments : none
*
* Returns : None
*
* Note(s) : This function is INTERNAL to uC/OS-III and your application MUST NOT call it.
************************************************************************************************************************
*/
void OS_TickListInit (void)
{
OS_TICK_SPOKE_IX i;
OS_TICK_SPOKE *p_spoke;
for (i = 0u; i < OSCfg_TickWheelSize; i++) {
p_spoke = (OS_TICK_SPOKE *)&OSCfg_TickWheel[i];
p_spoke->FirstPtr = (OS_TCB *)0;
p_spoke->NbrEntries = (OS_OBJ_QTY )0u;
p_spoke->NbrEntriesMax = (OS_OBJ_QTY )0u;
}
}
/*$PAGE*/
/*
************************************************************************************************************************
* ADD TASK TO TICK LIST
*
* Description: This function is called to place a task in a list of task waiting for either time to expire or waiting to
* timeout on a pend call.
*
* Arguments : p_tcb is a pointer to the OS_TCB of the task to add to the tick list
* -----
*
* time represents either the 'match' value of OSTickCtr or a relative time from the current
* value of OSTickCtr as specified by the 'opt' argument..
*
* relative when 'opt' is set to OS_OPT_TIME_DLY
* relative when 'opt' is set to OS_OPT_TIME_TIMEOUT
* match when 'opt' is set to OS_OPT_TIME_MATCH
* periodic when 'opt' is set to OS_OPT_TIME_PERIODIC
*
* opt is an option specifying how to calculate time. The valid values are:
* ---
* OS_OPT_TIME_DLY
* OS_OPT_TIME_TIMEOUT
* OS_OPT_TIME_PERIODIC
* OS_OPT_TIME_MATCH
*
* p_err is a pointer to a variable that will contain an error code returned by this function.
* -----
* OS_ERR_NONE the call was successful and the time delay was scheduled.
* OS_ERR_TIME_ZERO_DLY if delay is zero or already occurred.
*
* Returns : None
*
* Note(s) : 1) This function is INTERNAL to uC/OS-III and your application MUST NOT call it.
*
* 2) This function is assumed to be called with interrupts disabled.
************************************************************************************************************************
*/
void OS_TickListInsert (OS_TCB *p_tcb,
OS_TICK time,
OS_OPT opt,
OS_ERR *p_err)
{
OS_TICK tick_delta;
OS_TICK tick_next;
OS_TICK_SPOKE *p_spoke;
OS_TCB *p_tcb0;
OS_TCB *p_tcb1;
OS_TICK_SPOKE_IX spoke;
if (opt == OS_OPT_TIME_MATCH) { /* Task time is absolute. */
tick_delta = time - OSTickCtr - 1u;
if (tick_delta > OS_TICK_TH_RDY) { /* If delay already occurred, ... */
p_tcb->TickCtrMatch = (OS_TICK )0u;
p_tcb->TickRemain = (OS_TICK )0u;
p_tcb->TickSpokePtr = (OS_TICK_SPOKE *)0;
*p_err = OS_ERR_TIME_ZERO_DLY; /* ... do NOT delay. */
return;
}
p_tcb->TickCtrMatch = time;
p_tcb->TickRemain = tick_delta + 1u;
} else if (time > (OS_TICK)0u) {
if (opt == OS_OPT_TIME_PERIODIC) { /* Task time is periodic. */
tick_next = p_tcb->TickCtrPrev + time;
tick_delta = tick_next - OSTickCtr - 1u;
if (tick_delta < time) { /* If next periodic delay did NOT already occur, ... */
p_tcb->TickCtrMatch = tick_next; /* ... set next periodic delay; ... */
} else {
p_tcb->TickCtrMatch = OSTickCtr + time; /* ... else reset periodic delay. */
}
p_tcb->TickRemain = p_tcb->TickCtrMatch - OSTickCtr;
p_tcb->TickCtrPrev = p_tcb->TickCtrMatch;
} else { /* Task time is relative to current. */
p_tcb->TickCtrMatch = OSTickCtr + time;
p_tcb->TickRemain = time;
}
} else { /* Zero time delay; ... */
p_tcb->TickCtrMatch = (OS_TICK )0u;
p_tcb->TickRemain = (OS_TICK )0u;
p_tcb->TickSpokePtr = (OS_TICK_SPOKE *)0;
*p_err = OS_ERR_TIME_ZERO_DLY; /* ... do NOT delay. */
return;
}
spoke = (OS_TICK_SPOKE_IX)(p_tcb->TickCtrMatch % OSCfg_TickWheelSize);
p_spoke = &OSCfg_TickWheel[spoke];
if (p_spoke->NbrEntries == (OS_OBJ_QTY)0u) { /* First entry in the spoke */
p_tcb->TickNextPtr = (OS_TCB *)0;
p_tcb->TickPrevPtr = (OS_TCB *)0;
p_spoke->FirstPtr = p_tcb;
p_spoke->NbrEntries = (OS_OBJ_QTY)1u;
} else {
p_tcb1 = p_spoke->FirstPtr; /* Point to current first TCB in the list */
while (p_tcb1 != (OS_TCB *)0) {
p_tcb1->TickRemain = p_tcb1->TickCtrMatch /* Compute time remaining of current TCB in list */
- OSTickCtr;
if (p_tcb->TickRemain > p_tcb1->TickRemain) { /* Do we need to insert AFTER current TCB in list? */
if (p_tcb1->TickNextPtr != (OS_TCB *)0) { /* Yes, are we pointing at the last TCB in the list? */
p_tcb1 = p_tcb1->TickNextPtr; /* No, Point to next TCB in the list */
} else {
p_tcb->TickNextPtr = (OS_TCB *)0;
p_tcb->TickPrevPtr = p_tcb1;
p_tcb1->TickNextPtr = p_tcb; /* Yes, TCB to add is now new last entry in the list */
p_tcb1 = (OS_TCB *)0; /* Break loop */
}
} else { /* Insert before the current TCB */
if (p_tcb1->TickPrevPtr == (OS_TCB *)0) { /* Are we inserting before the first TCB? */
p_tcb->TickPrevPtr = (OS_TCB *)0;
p_tcb->TickNextPtr = p_tcb1;
p_tcb1->TickPrevPtr = p_tcb;
p_spoke->FirstPtr = p_tcb;
} else { /* Insert in between 2 TCBs already in the list */
p_tcb0 = p_tcb1->TickPrevPtr;
p_tcb->TickPrevPtr = p_tcb0;
p_tcb->TickNextPtr = p_tcb1;
p_tcb0->TickNextPtr = p_tcb;
p_tcb1->TickPrevPtr = p_tcb;
}
p_tcb1 = (OS_TCB *)0; /* Break loop */
}
}
p_spoke->NbrEntries++;
}
if (p_spoke->NbrEntriesMax < p_spoke->NbrEntries) { /* Keep track of maximum # of entries in each spoke */
p_spoke->NbrEntriesMax = p_spoke->NbrEntries;
}
p_tcb->TickSpokePtr = p_spoke; /* Link back to tick spoke */
*p_err = OS_ERR_NONE;
}
/*$PAGE*/
/*
************************************************************************************************************************
* REMOVE A TASK FROM THE TICK LIST
*
* Description: This function is called to remove a task from the tick list
*
* Arguments : p_tcb Is a pointer to the OS_TCB to remove.
* -----
*
* Returns : none
*
* Note(s) : 1) This function is INTERNAL to uC/OS-III and your application MUST NOT call it.
*
* 2) This function is assumed to be called with interrupts disabled.
************************************************************************************************************************
*/
void OS_TickListRemove (OS_TCB *p_tcb)
{
OS_TICK_SPOKE *p_spoke;
OS_TCB *p_tcb1;
OS_TCB *p_tcb2;
p_spoke = p_tcb->TickSpokePtr;
if (p_spoke != (OS_TICK_SPOKE *)0) { /* Confirm that task is in tick list */
p_tcb->TickRemain = (OS_TICK)0u;
if (p_spoke->FirstPtr == p_tcb) { /* Is timer to remove at the beginning of list? */
p_tcb1 = (OS_TCB *)p_tcb->TickNextPtr; /* Yes */
p_spoke->FirstPtr = p_tcb1;
if (p_tcb1 != (OS_TCB *)0) {
p_tcb1->TickPrevPtr = (OS_TCB *)0;
}
} else {
p_tcb1 = p_tcb->TickPrevPtr; /* No, remove timer from somewhere in the list */
p_tcb2 = p_tcb->TickNextPtr;
p_tcb1->TickNextPtr = p_tcb2;
if (p_tcb2 != (OS_TCB *)0) {
p_tcb2->TickPrevPtr = p_tcb1;
}
}
p_tcb->TickNextPtr = (OS_TCB *)0;
p_tcb->TickPrevPtr = (OS_TCB *)0;
p_tcb->TickSpokePtr = (OS_TICK_SPOKE *)0;
p_tcb->TickCtrMatch = (OS_TICK )0u;
p_spoke->NbrEntries--;
}
}
/*$PAGE*/
/*
************************************************************************************************************************
* RESET TICK LIST PEAK DETECTOR
*
* Description: This function is used to reset the peak detector for the number of entries in each spoke.
*
* Arguments : void
*
* Returns : none
*
* Note(s) : This function is INTERNAL to uC/OS-III and your application should not call it.
************************************************************************************************************************
*/
void OS_TickListResetPeak (void)
{
OS_TICK_SPOKE_IX i;
OS_TICK_SPOKE *p_spoke;
for (i = 0u; i < OSCfg_TickWheelSize; i++) {
p_spoke = (OS_TICK_SPOKE *)&OSCfg_TickWheel[i];
p_spoke->NbrEntriesMax = (OS_OBJ_QTY )0u;
}
}
/*$PAGE*/
/*
************************************************************************************************************************
* UPDATE THE TICK LIST
*
* Description: This function is called when a tick occurs and determines if the timeout waiting for a kernel object has
* expired or a delay has expired.
*
* Arguments : non
*
* Returns : none
*
* Note(s) : 1) This function is INTERNAL to uC/OS-III and your application MUST NOT call it.
************************************************************************************************************************
*/
void OS_TickListUpdate (void)
{
CPU_BOOLEAN done;
OS_TICK_SPOKE *p_spoke;
OS_TCB *p_tcb;
OS_TCB *p_tcb_next;
OS_TICK_SPOKE_IX spoke;
CPU_TS ts_start;
CPU_TS ts_end;
CPU_SR_ALLOC();
OS_CRITICAL_ENTER();
ts_start = OS_TS_GET();
OSTickCtr++; /* Keep track of the number of ticks */
spoke = (OS_TICK_SPOKE_IX)(OSTickCtr % OSCfg_TickWheelSize);
p_spoke = &OSCfg_TickWheel[spoke];
p_tcb = p_spoke->FirstPtr;
done = DEF_FALSE;
while (done == DEF_FALSE) {
if (p_tcb != (OS_TCB *)0) {
p_tcb_next = p_tcb->TickNextPtr; /* Point to next TCB to update */
switch (p_tcb->TaskState) {
case OS_TASK_STATE_RDY:
case OS_TASK_STATE_PEND:
case OS_TASK_STATE_SUSPENDED:
case OS_TASK_STATE_PEND_SUSPENDED:
break;
case OS_TASK_STATE_DLY:
p_tcb->TickRemain = p_tcb->TickCtrMatch /* Compute time remaining of current TCB */
- OSTickCtr;
if (OSTickCtr == p_tcb->TickCtrMatch) { /* Process each TCB that expires */
p_tcb->TaskState = OS_TASK_STATE_RDY;
OS_TaskRdy(p_tcb); /* Make task ready to run */
} else {
done = DEF_TRUE; /* Don't find a match, we're done! */
}
break;
case OS_TASK_STATE_PEND_TIMEOUT:
p_tcb->TickRemain = p_tcb->TickCtrMatch /* Compute time remaining of current TCB */
- OSTickCtr;
if (OSTickCtr == p_tcb->TickCtrMatch) { /* Process each TCB that expires */
#if (OS_MSG_EN > 0u)
p_tcb->MsgPtr = (void *)0;
p_tcb->MsgSize = (OS_MSG_SIZE)0u;
#endif
p_tcb->TS = OS_TS_GET();
OS_PendListRemove(p_tcb); /* Remove from wait list */
OS_TaskRdy(p_tcb);
p_tcb->TaskState = OS_TASK_STATE_RDY;
p_tcb->PendStatus = OS_STATUS_PEND_TIMEOUT; /* Indicate pend timed out */
p_tcb->PendOn = OS_TASK_PEND_ON_NOTHING; /* Indicate no longer pending */
} else {
done = DEF_TRUE; /* Don't find a match, we're done! */
}
break;
case OS_TASK_STATE_DLY_SUSPENDED:
p_tcb->TickRemain = p_tcb->TickCtrMatch /* Compute time remaining of current TCB */
- OSTickCtr;
if (OSTickCtr == p_tcb->TickCtrMatch) { /* Process each TCB that expires */
p_tcb->TaskState = OS_TASK_STATE_SUSPENDED;
OS_TickListRemove(p_tcb); /* Remove from current wheel spoke */
} else {
done = DEF_TRUE; /* Don't find a match, we're done! */
}
break;
case OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED:
p_tcb->TickRemain = p_tcb->TickCtrMatch /* Compute time remaining of current TCB */
- OSTickCtr;
if (OSTickCtr == p_tcb->TickCtrMatch) { /* Process each TCB that expires */
#if (OS_MSG_EN > 0u)
p_tcb->MsgPtr = (void *)0;
p_tcb->MsgSize = (OS_MSG_SIZE)0u;
#endif
p_tcb->TS = OS_TS_GET();
OS_PendListRemove(p_tcb); /* Remove from wait list */
OS_TickListRemove(p_tcb); /* Remove from current wheel spoke */
p_tcb->TaskState = OS_TASK_STATE_SUSPENDED;
p_tcb->PendStatus = OS_STATUS_PEND_TIMEOUT; /* Indicate pend timed out */
p_tcb->PendOn = OS_TASK_PEND_ON_NOTHING; /* Indicate no longer pending */
} else {
done = DEF_TRUE; /* Don't find a match, we're done! */
}
break;
default:
break;
}
p_tcb = p_tcb_next;
} else {
done = DEF_TRUE;
}
}
ts_end = OS_TS_GET() - ts_start; /* Measure execution time of tick task */
if (OSTickTaskTimeMax < ts_end) {
OSTickTaskTimeMax = ts_end;
}
OS_CRITICAL_EXIT();
}

View File

@@ -0,0 +1,572 @@
/*
************************************************************************************************************************
* uC/OS-III
* The Real-Time Kernel
*
* (c) Copyright 2009-2012; Micrium, Inc.; Weston, FL
* All rights reserved. Protected by international copyright laws.
*
* TIME MANAGEMENT
*
* File : OS_TIME.C
* By : JJL
* Version : V3.03.01
*
* LICENSING TERMS:
* ---------------
* uC/OS-III is provided in source form for FREE short-term evaluation, for educational use or
* for peaceful research. If you plan or intend to use uC/OS-III in a commercial application/
* product then, you need to contact Micrium to properly license uC/OS-III for its use in your
* application/product. We provide ALL the source code for your convenience and to help you
* experience uC/OS-III. The fact that the source is provided does NOT mean that you can use
* it commercially without paying a licensing fee.
*
* Knowledge of the source code may NOT be used to develop a similar product.
*
* Please help us continue to provide the embedded community with the finest software available.
* Your honesty is greatly appreciated.
*
* You can contact us at www.micrium.com, or by phone at +1 (954) 217-2036.
************************************************************************************************************************
*/
#define MICRIUM_SOURCE
#include <os.h>
#ifdef VSC_INCLUDE_SOURCE_FILE_NAMES
const CPU_CHAR *os_time__c = "$Id: $";
#endif
/*
************************************************************************************************************************
* DELAY TASK 'n' TICKS
*
* Description: This function is called to delay execution of the currently running task until the specified number of
* system ticks expires. This, of course, directly equates to delaying the current task for some time to
* expire. No delay will result if the specified delay is 0. If the specified delay is greater than 0
* then, a context switch will result.
*
* Arguments : dly is a value in 'clock ticks' that the task will either delay for or, the target match value
* of the tick counter (OSTickCtr). Note that specifying 0 means the task is not to delay.
*
* depending on the option argument, the task will wake up when OSTickCtr reaches:
*
* OS_OPT_TIME_DLY : OSTickCtr + dly
* OS_OPT_TIME_TIMEOUT : OSTickCtr + dly
* OS_OPT_TIME_MATCH : dly
* OS_OPT_TIME_PERIODIC : OSTCBCurPtr->TickCtrPrev + dly
*
* opt specifies whether 'dly' represents absolute or relative time; default option marked with *** :
*
* *** OS_OPT_TIME_DLY specifies a relative time from the current value of OSTickCtr.
* OS_OPT_TIME_TIMEOUT same as OS_OPT_TIME_DLY.
* OS_OPT_TIME_MATCH indicates that 'dly' specifies the absolute value that OSTickCtr
* must reach before the task will be resumed.
* OS_OPT_TIME_PERIODIC indicates that 'dly' specifies the periodic value that OSTickCtr
* must reach before the task will be resumed.
*
* p_err is a pointer to a variable that will contain an error code from this call.
*
* OS_ERR_NONE the call was successful and the delay occurred.
* OS_ERR_OPT_INVALID if you specified an invalid option for this function.
* OS_ERR_SCHED_LOCKED can't delay when the scheduler is locked.
* OS_ERR_TIME_DLY_ISR if you called this function from an ISR.
* OS_ERR_TIME_ZERO_DLY if you specified a delay of zero.
*
* Returns : none
************************************************************************************************************************
*/
void OSTimeDly (OS_TICK dly,
OS_OPT opt,
OS_ERR *p_err)
{
CPU_SR_ALLOC();
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return;
}
#endif
#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u
if (OSIntNestingCtr > (OS_NESTING_CTR)0u) { /* Not allowed to call from an ISR */
*p_err = OS_ERR_TIME_DLY_ISR;
return;
}
#endif
if (OSSchedLockNestingCtr > (OS_NESTING_CTR)0u) { /* Can't delay when the scheduler is locked */
*p_err = OS_ERR_SCHED_LOCKED;
return;
}
switch (opt) {
case OS_OPT_TIME_DLY:
case OS_OPT_TIME_TIMEOUT:
case OS_OPT_TIME_PERIODIC:
if (dly == (OS_TICK)0u) { /* 0 means no delay! */
*p_err = OS_ERR_TIME_ZERO_DLY;
return;
}
break;
case OS_OPT_TIME_MATCH:
break;
default:
*p_err = OS_ERR_OPT_INVALID;
return;
}
OS_CRITICAL_ENTER();
OSTCBCurPtr->TaskState = OS_TASK_STATE_DLY;
OS_TickListInsert(OSTCBCurPtr,
dly,
opt,
p_err);
if (*p_err != OS_ERR_NONE) {
OS_CRITICAL_EXIT_NO_SCHED();
return;
}
OS_RdyListRemove(OSTCBCurPtr); /* Remove current task from ready list */
OS_CRITICAL_EXIT_NO_SCHED();
OSSched(); /* Find next task to run! */
*p_err = OS_ERR_NONE;
}
/*$PAGE*/
/*
************************************************************************************************************************
* DELAY TASK FOR SPECIFIED TIME
*
* Description: This function is called to delay execution of the currently running task until some time expires. This
* call allows you to specify the delay time in HOURS, MINUTES, SECONDS and MILLISECONDS instead of ticks.
*
* Arguments : hours specifies the number of hours that the task will be delayed (max. is 999 if the tick rate is
* 1000 Hz or less otherwise, a higher value would overflow a 32-bit unsigned counter).
*
* minutes specifies the number of minutes (max. 59 if 'opt' is OS_OPT_TIME_HMSM_STRICT)
*
* seconds specifies the number of seconds (max. 59 if 'opt' is OS_OPT_TIME_HMSM_STRICT)
*
* milli specifies the number of milliseconds (max. 999 if 'opt' is OS_OPT_TIME_HMSM_STRICT)
*
* opt specifies time delay bit-field options logically OR'd; default options marked with *** :
*
* *** OS_OPT_TIME_DLY specifies a relative time from the current value of OSTickCtr.
* OS_OPT_TIME_TIMEOUT same as OS_OPT_TIME_DLY.
* OS_OPT_TIME_MATCH indicates that the delay specifies the absolute value that OSTickCtr
* must reach before the task will be resumed.
* OS_OPT_TIME_PERIODIC indicates that the delay specifies the periodic value that OSTickCtr
* must reach before the task will be resumed.
*
* *** OS_OPT_TIME_HMSM_STRICT strictly allow only hours (0...99)
* minutes (0...59)
* seconds (0...59)
* milliseconds (0...999)
* OS_OPT_TIME_HMSM_NON_STRICT allow any value of hours (0...999)
* minutes (0...9999)
* seconds (0...65535)
* milliseconds (0...4294967295)
*
* p_err is a pointer to a variable that will receive an error code from this call.
*
* OS_ERR_NONE If the function returns from the desired delay
* OS_ERR_OPT_INVALID If you specified an invalid option for 'opt'
* OS_ERR_SCHED_LOCKED Can't delay when the scheduler is locked
* OS_ERR_TIME_DLY_ISR If called from an ISR
* OS_ERR_TIME_INVALID_HOURS If you didn't specify a valid value for 'hours'
* OS_ERR_TIME_INVALID_MINUTES If you didn't specify a valid value for 'minutes'
* OS_ERR_TIME_INVALID_SECONDS If you didn't specify a valid value for 'seconds'
* OS_ERR_TIME_INVALID_MILLISECONDS If you didn't specify a valid value for 'milli'
* OS_ERR_TIME_ZERO_DLY If hours, minutes, seconds and milli are all 0
*
* Returns : none
*
* Note(s) : 1) The resolution on the milliseconds depends on the tick rate. For example, you can't do a 10 mS delay
* if the ticker interrupts every 100 mS. In this case, the delay would be set to 0. The actual delay
* is rounded to the nearest tick.
*
* 2) Although this function allows you to delay a task for many, many hours, it's not recommended to put
* a task to sleep for that long.
************************************************************************************************************************
*/
#if OS_CFG_TIME_DLY_HMSM_EN > 0u
void OSTimeDlyHMSM (CPU_INT16U hours,
CPU_INT16U minutes,
CPU_INT16U seconds,
CPU_INT32U milli,
OS_OPT opt,
OS_ERR *p_err)
{
#if OS_CFG_ARG_CHK_EN > 0u
CPU_BOOLEAN opt_invalid;
CPU_BOOLEAN opt_non_strict;
#endif
OS_OPT opt_time;
OS_RATE_HZ tick_rate;
OS_TICK ticks;
CPU_SR_ALLOC();
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return;
}
#endif
#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u
if (OSIntNestingCtr > (OS_NESTING_CTR)0u) { /* Not allowed to call from an ISR */
*p_err = OS_ERR_TIME_DLY_ISR;
return;
}
#endif
if (OSSchedLockNestingCtr > (OS_NESTING_CTR)0u) { /* Can't delay when the scheduler is locked */
*p_err = OS_ERR_SCHED_LOCKED;
return;
}
opt_time = opt & OS_OPT_TIME_MASK; /* Retrieve time options only. */
switch (opt_time) {
case OS_OPT_TIME_DLY:
case OS_OPT_TIME_TIMEOUT:
case OS_OPT_TIME_PERIODIC:
if (milli == (CPU_INT32U)0u) { /* Make sure we didn't specify a 0 delay */
if (seconds == (CPU_INT16U)0u) {
if (minutes == (CPU_INT16U)0u) {
if (hours == (CPU_INT16U)0u) {
*p_err = OS_ERR_TIME_ZERO_DLY;
return;
}
}
}
}
break;
case OS_OPT_TIME_MATCH:
break;
default:
*p_err = OS_ERR_OPT_INVALID;
return;
}
#if OS_CFG_ARG_CHK_EN > 0u /* Validate arguments to be within range */
opt_invalid = DEF_BIT_IS_SET_ANY(opt, ~OS_OPT_TIME_OPTS_MASK);
if (opt_invalid == DEF_YES) {
*p_err = OS_ERR_OPT_INVALID;
return;
}
opt_non_strict = DEF_BIT_IS_SET(opt, OS_OPT_TIME_HMSM_NON_STRICT);
if (opt_non_strict != DEF_YES) {
if (milli > (CPU_INT32U)999u) {
*p_err = OS_ERR_TIME_INVALID_MILLISECONDS;
return;
}
if (seconds > (CPU_INT16U)59u) {
*p_err = OS_ERR_TIME_INVALID_SECONDS;
return;
}
if (minutes > (CPU_INT16U)59u) {
*p_err = OS_ERR_TIME_INVALID_MINUTES;
return;
}
if (hours > (CPU_INT16U)99u) {
*p_err = OS_ERR_TIME_INVALID_HOURS;
return;
}
} else {
if (minutes > (CPU_INT16U)9999u) {
*p_err = OS_ERR_TIME_INVALID_MINUTES;
return;
}
if (hours > (CPU_INT16U)999u) {
*p_err = OS_ERR_TIME_INVALID_HOURS;
return;
}
}
#endif
/* Compute the total number of clock ticks required.. */
/* .. (rounded to the nearest tick) */
tick_rate = OSCfg_TickRate_Hz;
ticks = ((OS_TICK)hours * (OS_TICK)3600u + (OS_TICK)minutes * (OS_TICK)60u + (OS_TICK)seconds) * tick_rate
+ (tick_rate * ((OS_TICK)milli + (OS_TICK)500u / tick_rate)) / (OS_TICK)1000u;
if (ticks > (OS_TICK)0u) {
OS_CRITICAL_ENTER();
OSTCBCurPtr->TaskState = OS_TASK_STATE_DLY;
OS_TickListInsert(OSTCBCurPtr,
ticks,
opt_time,
p_err);
if (*p_err != OS_ERR_NONE) {
OS_CRITICAL_EXIT_NO_SCHED();
return;
}
OS_RdyListRemove(OSTCBCurPtr); /* Remove current task from ready list */
OS_CRITICAL_EXIT_NO_SCHED();
OSSched(); /* Find next task to run! */
*p_err = OS_ERR_NONE;
} else {
*p_err = OS_ERR_TIME_ZERO_DLY;
}
}
#endif
/*$PAGE*/
/*
************************************************************************************************************************
* RESUME A DELAYED TASK
*
* Description: This function is used resume a task that has been delayed through a call to either OSTimeDly() or
* OSTimeDlyHMSM(). Note that cannot call this function to resume a task that is waiting for an event
* with timeout.
*
* Arguments : p_tcb is a pointer to the TCB of the task to resume.
*
* p_err is a pointer to a variable that will receive an error code
*
* OS_ERR_NONE Task has been resumed
* OS_ERR_STATE_INVALID Task is in an invalid state
* OS_ERR_TIME_DLY_RESUME_ISR If called from an ISR
* OS_ERR_TIME_NOT_DLY Task is not waiting for time to expire
* OS_ERR_TASK_SUSPENDED Task cannot be resumed, it was suspended by OSTaskSuspend()
*
* Note(s) : none
************************************************************************************************************************
*/
#if OS_CFG_TIME_DLY_RESUME_EN > 0u
void OSTimeDlyResume (OS_TCB *p_tcb,
OS_ERR *p_err)
{
CPU_SR_ALLOC();
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return;
}
#endif
#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u
if (OSIntNestingCtr > (OS_NESTING_CTR)0u) { /* Not allowed to call from an ISR */
*p_err = OS_ERR_TIME_DLY_RESUME_ISR;
return;
}
#endif
#if OS_CFG_ARG_CHK_EN > 0u
if (p_tcb == (OS_TCB *)0) { /* Not possible for the running task to be delayed! */
*p_err = OS_ERR_TASK_NOT_DLY;
return;
}
#endif
CPU_CRITICAL_ENTER();
if (p_tcb == OSTCBCurPtr) { /* Not possible for the running task to be delayed! */
*p_err = OS_ERR_TASK_NOT_DLY;
CPU_CRITICAL_EXIT();
return;
}
switch (p_tcb->TaskState) {
case OS_TASK_STATE_RDY: /* Cannot Abort delay if task is ready */
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_TASK_NOT_DLY;
break;
case OS_TASK_STATE_DLY:
OS_CRITICAL_ENTER_CPU_EXIT();
p_tcb->TaskState = OS_TASK_STATE_RDY;
OS_TickListRemove(p_tcb); /* Remove task from tick list */
OS_RdyListInsert(p_tcb); /* Add to ready list */
OS_CRITICAL_EXIT_NO_SCHED();
*p_err = OS_ERR_NONE;
break;
case OS_TASK_STATE_PEND:
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_TASK_NOT_DLY;
break;
case OS_TASK_STATE_PEND_TIMEOUT:
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_TASK_NOT_DLY;
break;
case OS_TASK_STATE_SUSPENDED:
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_TASK_NOT_DLY;
break;
case OS_TASK_STATE_DLY_SUSPENDED:
OS_CRITICAL_ENTER_CPU_EXIT();
p_tcb->TaskState = OS_TASK_STATE_SUSPENDED;
OS_TickListRemove(p_tcb); /* Remove task from tick list */
OS_CRITICAL_EXIT_NO_SCHED();
*p_err = OS_ERR_TASK_SUSPENDED;
break;
case OS_TASK_STATE_PEND_SUSPENDED:
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_TASK_NOT_DLY;
break;
case OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED:
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_TASK_NOT_DLY;
break;
default:
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_STATE_INVALID;
break;
}
OSSched();
}
#endif
/*$PAGE*/
/*
************************************************************************************************************************
* GET CURRENT SYSTEM TIME
*
* Description: This function is used by your application to obtain the current value of the counter which keeps track of
* the number of clock ticks.
*
* Arguments : p_err is a pointer to a variable that will receive an error code
*
* OS_ERR_NONE If the call was successful
*
* Returns : The current value of OSTickCtr
************************************************************************************************************************
*/
OS_TICK OSTimeGet (OS_ERR *p_err)
{
OS_TICK ticks;
CPU_SR_ALLOC();
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return ((OS_TICK)0);
}
#endif
CPU_CRITICAL_ENTER();
ticks = OSTickCtr;
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_NONE;
return (ticks);
}
/*
************************************************************************************************************************
* SET SYSTEM CLOCK
*
* Description: This function sets the counter which keeps track of the number of clock ticks.
*
* Arguments : ticks is the desired tick value
*
* p_err is a pointer to a variable that will receive an error code
*
* OS_ERR_NONE If the call was successful
*
* Returns : none
************************************************************************************************************************
*/
void OSTimeSet (OS_TICK ticks,
OS_ERR *p_err)
{
CPU_SR_ALLOC();
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return;
}
#endif
CPU_CRITICAL_ENTER();
OSTickCtr = ticks;
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_NONE;
}
/*$PAGE*/
/*
************************************************************************************************************************
* PROCESS SYSTEM TICK
*
* Description: This function is used to signal to uC/OS-III the occurrence of a 'system tick' (also known as a
* 'clock tick'). This function should be called by the tick ISR.
*
* Arguments : none
*
* Returns : none
************************************************************************************************************************
*/
void OSTimeTick (void)
{
OS_ERR err;
#if OS_CFG_ISR_POST_DEFERRED_EN > 0u
CPU_TS ts;
#endif
OSTimeTickHook(); /* Call user definable hook */
#if OS_CFG_ISR_POST_DEFERRED_EN > 0u
ts = OS_TS_GET(); /* Get timestamp */
OS_IntQPost((OS_OBJ_TYPE) OS_OBJ_TYPE_TICK, /* Post to ISR queue */
(void *)&OSRdyList[OSPrioCur],
(void *) 0,
(OS_MSG_SIZE) 0u,
(OS_FLAGS ) 0u,
(OS_OPT ) 0u,
(CPU_TS ) ts,
(OS_ERR *)&err);
#else
(void)OSTaskSemPost((OS_TCB *)&OSTickTaskTCB, /* Signal tick task */
(OS_OPT ) OS_OPT_POST_NONE,
(OS_ERR *)&err);
#if OS_CFG_SCHED_ROUND_ROBIN_EN > 0u
OS_SchedRoundRobin(&OSRdyList[OSPrioCur]);
#endif
#if OS_CFG_TMR_EN > 0u
OSTmrUpdateCtr--;
if (OSTmrUpdateCtr == (OS_CTR)0u) {
OSTmrUpdateCtr = OSTmrUpdateCnt;
OSTaskSemPost((OS_TCB *)&OSTmrTaskTCB, /* Signal timer task */
(OS_OPT ) OS_OPT_POST_NONE,
(OS_ERR *)&err);
}
#endif
#endif
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,93 @@
/*
************************************************************************************************************************
* uC/OS-III
* The Real-Time Kernel
*
* (c) Copyright 2009-2012; Micrium, Inc.; Weston, FL
* All rights reserved. Protected by international copyright laws.
*
* File : OS_TYPE.H
* By : JJL
* Version : V3.03.01
*
* LICENSING TERMS:
* ---------------
* uC/OS-III is provided in source form for FREE short-term evaluation, for educational use or
* for peaceful research. If you plan or intend to use uC/OS-III in a commercial application/
* product then, you need to contact Micrium to properly license uC/OS-III for its use in your
* application/product. We provide ALL the source code for your convenience and to help you
* experience uC/OS-III. The fact that the source is provided does NOT mean that you can use
* it commercially without paying a licensing fee.
*
* Knowledge of the source code may NOT be used to develop a similar product.
*
* Please help us continue to provide the embedded community with the finest software available.
* Your honesty is greatly appreciated.
*
* You can contact us at www.micrium.com, or by phone at +1 (954) 217-2036.
************************************************************************************************************************
*/
#ifndef OS_TYPE_H
#define OS_TYPE_H
#ifdef VSC_INCLUDE_H_FILE_NAMES
const CPU_CHAR *os_type__h = "$Id: $";
#endif
/*
************************************************************************************************************************
* INCLUDE HEADER FILES
************************************************************************************************************************
*/
/* Description # Bits */
/* <recommended> */
/* ----------------------------------------------------------- */
typedef CPU_INT16U OS_CPU_USAGE; /* CPU Usage 0..10000 <16>/32 */
typedef CPU_INT32U OS_CTR; /* Counter, 32 */
typedef CPU_INT32U OS_CTX_SW_CTR; /* Counter of context switches, 32 */
typedef CPU_INT32U OS_CYCLES; /* CPU clock cycles, <32>/64 */
typedef CPU_INT32U OS_FLAGS; /* Event flags, 8/16/<32> */
typedef CPU_INT32U OS_IDLE_CTR; /* Holds the number of times the idle task runs, <32>/64 */
typedef CPU_INT16U OS_MEM_QTY; /* Number of memory blocks, <16>/32 */
typedef CPU_INT16U OS_MEM_SIZE; /* Size in bytes of a memory block, <16>/32 */
typedef CPU_INT16U OS_MSG_QTY; /* Number of OS_MSGs in the msg pool, <16>/32 */
typedef CPU_INT16U OS_MSG_SIZE; /* Size of messages in number of bytes, <16>/32 */
typedef CPU_INT08U OS_NESTING_CTR; /* Interrupt and scheduler nesting, <8>/16/32 */
typedef CPU_INT16U OS_OBJ_QTY; /* Number of kernel objects counter, <16>/32 */
typedef CPU_INT32U OS_OBJ_TYPE; /* Special flag to determine object type, 32 */
typedef CPU_INT16U OS_OPT; /* Holds function options <16>/32 */
typedef CPU_INT08U OS_PRIO; /* Priority of a task, <8>/16/32 */
typedef CPU_INT16U OS_QTY; /* Quantity <16>/32 */
typedef CPU_INT32U OS_RATE_HZ; /* Rate in Hertz 32 */
typedef CPU_INT32U OS_REG; /* Task register 8/16/<32> */
typedef CPU_INT08U OS_REG_ID; /* Index to task register <8>/16/32 */
typedef CPU_INT32U OS_SEM_CTR; /* Semaphore value 16/<32> */
typedef CPU_INT08U OS_STATE; /* State variable <8>/16/32 */
typedef CPU_INT08U OS_STATUS; /* Status <8>/16/32 */
typedef CPU_INT32U OS_TICK; /* Clock tick counter <32>/64 */
typedef CPU_INT16U OS_TICK_SPOKE_IX; /* Tick wheel spoke position 8/<16>/32 */
typedef CPU_INT16U OS_TMR_SPOKE_IX; /* Timer wheel spoke position 8/<16>/32 */
#endif

View File

@@ -0,0 +1,40 @@
/*
************************************************************************************************************************
* uC/OS-III
* The Real-Time Kernel
*
* (c) Copyright 2009-2012; Micrium, Inc.; Weston, FL
* All rights reserved. Protected by international copyright laws.
*
* VARIABLES
*
* File : OS_VAR.C
* By : JJL
* Version : V3.03.01
*
* LICENSING TERMS:
* ---------------
* uC/OS-III is provided in source form for FREE short-term evaluation, for educational use or
* for peaceful research. If you plan or intend to use uC/OS-III in a commercial application/
* product then, you need to contact Micrium to properly license uC/OS-III for its use in your
* application/product. We provide ALL the source code for your convenience and to help you
* experience uC/OS-III. The fact that the source is provided does NOT mean that you can use
* it commercially without paying a licensing fee.
*
* Knowledge of the source code may NOT be used to develop a similar product.
*
* Please help us continue to provide the embedded community with the finest software available.
* Your honesty is greatly appreciated.
*
* You can contact us at www.micrium.com, or by phone at +1 (954) 217-2036.
************************************************************************************************************************
*/
#define OS_GLOBALS
#define MICRIUM_SOURCE
#include <os.h>
#ifdef VSC_INCLUDE_SOURCE_FILE_NAMES
const CPU_CHAR *os_var__c = "$Id: $";
#endif

View File

@@ -0,0 +1,54 @@
/*
*********************************************************************************************************
* EXAMPLE CODE
*
* (c) Copyright 2009-2013; Micrium, Inc.; Weston, FL
*
* All rights reserved. Protected by international copyright laws.
* Knowledge of the source code may NOT be used to develop a similar product.
* Please help us continue to provide the Embedded community with the finest
* software available. Your honesty is greatly appreciated.
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* APPLICATION CONFIGURATION
*
* ST Microelectronics STM32
* on the
*
* Micrium uC-Eval-STM32F107
* Evaluation Board
*
* Filename : app_cfg.h
* Version : V1.00
* Programmer(s) : JJL
* EHS
* DC
*********************************************************************************************************
*/
#ifndef __APP_CFG_H__
#define __APP_CFG_H__
/*
*********************************************************************************************************
* TRACE / DEBUG CONFIGURATION
*********************************************************************************************************
*/
#if 0
#define TRACE_LEVEL_OFF 0
#define TRACE_LEVEL_INFO 1
#define TRACE_LEVEL_DEBUG 2
#endif
#define APP_TRACE_LEVEL TRACE_LEVEL_INFO
#define APP_TRACE BSP_Ser_Printf
#define APP_TRACE_INFO(x) ((APP_TRACE_LEVEL >= TRACE_LEVEL_INFO) ? (void)(APP_TRACE x) : (void)0)
#define APP_TRACE_DEBUG(x) ((APP_TRACE_LEVEL >= TRACE_LEVEL_DEBUG) ? (void)(APP_TRACE x) : (void)0)
#endif

View File

@@ -0,0 +1,175 @@
/*
*********************************************************************************************************
* uC/CPU
* CPU CONFIGURATION & PORT LAYER
*
* (c) Copyright 2004-2010; Micrium, Inc.; Weston, FL
*
* All rights reserved. Protected by international copyright laws.
*
* uC/CPU is provided in source form to registered licensees ONLY. It is
* illegal to distribute this source code to any third party unless you receive
* written permission by an authorized Micrium representative. Knowledge of
* the source code may NOT be used to develop a similar product.
*
* Please help us continue to provide the Embedded community with the finest
* software available. Your honesty is greatly appreciated.
*
* You can contact us at www.micrium.com.
*********************************************************************************************************
*/
/*
*********************************************************************************************************
*
* CPU CONFIGURATION FILE
*
* TEMPLATE
*
* Filename : cpu_cfg.h
* Version : V1.25
* Programmer(s) : SR
* ITJ
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* MODULE
*********************************************************************************************************
*/
#ifndef CPU_CFG_MODULE_PRESENT
#define CPU_CFG_MODULE_PRESENT
/*
*********************************************************************************************************
* CPU NAME CONFIGURATION
*
* Note(s) : (1) Configure CPU_CFG_NAME_EN to enable/disable CPU host name feature :
*
* (a) CPU host name storage
* (b) CPU host name API functions
*
* (2) Configure CPU_CFG_NAME_SIZE with the desired ASCII string size of the CPU host name,
* including the terminating NULL character.
*
* See also 'cpu_core.h GLOBAL VARIABLES Note #1'.
*********************************************************************************************************
*/
/* Configure CPU host name feature (see Note #1) : */
#define CPU_CFG_NAME_EN DEF_ENABLED
/* DEF_DISABLED CPU host name DISABLED */
/* DEF_ENABLED CPU host name ENABLED */
/* Configure CPU host name ASCII string size ... */
#define CPU_CFG_NAME_SIZE 16u /* ... (see Note #2). */
/*$PAGE*/
/*
*********************************************************************************************************
* CPU TIMESTAMP CONFIGURATION
*
* Note(s) : (1) Configure CPU_CFG_TS_xx_EN to enable/disable CPU timestamp features :
*
* (a) CPU_CFG_TS_32_EN enable/disable 32-bit CPU timestamp feature
* (b) CPU_CFG_TS_64_EN enable/disable 64-bit CPU timestamp feature
*
* (2) (a) Configure CPU_CFG_TS_TMR_SIZE with the CPU timestamp timer's word size :
*
* CPU_WORD_SIZE_08 8-bit word size
* CPU_WORD_SIZE_16 16-bit word size
* CPU_WORD_SIZE_32 32-bit word size
* CPU_WORD_SIZE_64 64-bit word size
*
* (b) If the size of the CPU timestamp timer is not a binary multiple of 8-bit octets
* (e.g. 20-bits or even 24-bits), then the next lower, binary-multiple octet word
* size SHOULD be configured (e.g. to 16-bits). However, the minimum supported word
* size for CPU timestamp timers is 8-bits.
*
* See also 'cpu_core.h FUNCTION PROTOTYPES CPU_TS_TmrRd() Note #2a'.
*********************************************************************************************************
*/
/* Configure CPU timestamp features (see Note #1) : */
#define CPU_CFG_TS_32_EN DEF_ENABLED
#define CPU_CFG_TS_64_EN DEF_DISABLED
/* DEF_DISABLED CPU timestamps DISABLED */
/* DEF_ENABLED CPU timestamps ENABLED */
/* Configure CPU timestamp timer word size ... */
/* ... (see Note #2) : */
#define CPU_CFG_TS_TMR_SIZE CPU_WORD_SIZE_32
/*
*********************************************************************************************************
* CPU INTERRUPTS DISABLED TIME MEASUREMENT CONFIGURATION
*
* Note(s) : (1) (a) Configure CPU_CFG_INT_DIS_MEAS_EN to enable/disable measuring CPU's interrupts
* disabled time :
*
* (a) Enabled, if CPU_CFG_INT_DIS_MEAS_EN #define'd in 'cpu_cfg.h'
*
* (b) Disabled, if CPU_CFG_INT_DIS_MEAS_EN NOT #define'd in 'cpu_cfg.h'
*
* See also 'cpu_core.h FUNCTION PROTOTYPES Note #1'
* & 'cpu_core.h CPU INCLUDE FILES Note #3'.
*
* (b) Configure CPU_CFG_INT_DIS_MEAS_OVRHD_NBR with the number of times to measure &
* average the interrupts disabled time measurements overhead.
*
* Recommend a single (1) overhead time measurement, even for instruction-cache-enabled
* CPUs, since critical sections are NOT typically called within instruction-cached loops.
* Thus, a single non-cached/non-averaged time measurement is a more realistic overhead
* for the majority of non-cached interrupts disabled time measurements.
*
* See also 'cpu_core.c CPU_IntDisMeasInit() Note #3a'.
*********************************************************************************************************
*/
#if 0 /* Configure CPU interrupts disabled time ... */
#define CPU_CFG_INT_DIS_MEAS_EN /* ... measurements feature (see Note #1a). */
#endif
/* Configure number of interrupts disabled overhead ... */
#define CPU_CFG_INT_DIS_MEAS_OVRHD_NBR 1u /* ... time measurements (see Note #1b). */
/*$PAGE*/
/*
*********************************************************************************************************
* CPU COUNT LEADING ZEROS CONFIGURATION
*
* Note(s) : (1) Configure CPU_CFG_LEAD_ZEROS_ASM_PRESENT to prototype/define count leading zeros bits
* function(s) in :
*
* (a) 'cpu.h'/'cpu_a.asm', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/
* 'cpu_cfg.h' to enable assembly-version function(s)
*
* (b) 'cpu_core.h'/'cpu_core.c', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/
* 'cpu_cfg.h' to enable C-source-version function(s) otherwise
*
* See also 'cpu_core.h FUNCTION PROTOTYPES Note #2'
* & 'cpu_core.h CPU INCLUDE FILES Note #3'.
*********************************************************************************************************
*/
#if 1 /* Configure CPU count leading zeros bits ... */
#define CPU_CFG_LEAD_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1). */
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* MODULE END
*********************************************************************************************************
*/
#endif /* End of CPU cfg module include. */

View File

@@ -0,0 +1,101 @@
/*
*********************************************************************************************************
* EXAMPLE CODE
*
* (c) Copyright 2003-2013; Micrium, Inc.; Weston, FL
*
* All rights reserved. Protected by international copyright laws.
* Knowledge of the source code may NOT be used to develop a similar product.
* Please help us continue to provide the Embedded community with the finest
* software available. Your honesty is greatly appreciated.
*********************************************************************************************************
*/
/*
*********************************************************************************************************
*
* MASTER INCLUDES
*
* ST Microelectronics STM32
* on the
*
* Micrium uC-Eval-STM32F107
* Evaluation Board
*
* Filename : includes.h
* Version : V1.00
* Programmer(s) : EHS
* DC
*********************************************************************************************************
*/
#ifndef INCLUDES_PRESENT
#define INCLUDES_PRESENT
/*
*********************************************************************************************************
* STANDARD LIBRARIES
*********************************************************************************************************
*/
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
/*
*********************************************************************************************************
* LIBRARIES
*********************************************************************************************************
*/
#include <cpu.h>
#include <lib_def.h>
#include <lib_ascii.h>
#include <lib_math.h>
#include <lib_mem.h>
#include <lib_str.h>
/*
*********************************************************************************************************
* APP / BSP
*********************************************************************************************************
*/
#include <app_cfg.h>
#include <bsp.h>
/*
*********************************************************************************************************
* OS
*********************************************************************************************************
*/
#include <os.h>
#include <os_app_hooks.h>
/*
*********************************************************************************************************
* ST
*********************************************************************************************************
*/
//#include <stm32f10x_lib.h>
/*
*********************************************************************************************************
* INCLUDES END
*********************************************************************************************************
*/
#define false 0
#define true 1
#endif

View File

@@ -0,0 +1,166 @@
/*
*********************************************************************************************************
* uC/LIB
* CUSTOM LIBRARY MODULES
*
* (c) Copyright 2004-2013; Micrium, Inc.; Weston, FL
*
* All rights reserved. Protected by international copyright laws.
*
* uC/LIB is provided in source form to registered licensees ONLY. It is
* illegal to distribute this source code to any third party unless you receive
* written permission by an authorized Micrium representative. Knowledge of
* the source code may NOT be used to develop a similar product.
*
* Please help us continue to provide the Embedded community with the finest
* software available. Your honesty is greatly appreciated.
*
* You can contact us at www.micrium.com.
*********************************************************************************************************
*/
/*
*********************************************************************************************************
*
* CUSTOM LIBRARY CONFIGURATION FILE
*
* ST Microelectronics STM32
* on the
*
* Micrium uC-Eval-STM32F107
* Evaluation Board
*
* Filename : lib_cfg.h
* Version : V1.35.00
* Programmer(s) : ITJ
* DC
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* MODULE
*********************************************************************************************************
*/
#ifndef LIB_CFG_MODULE_PRESENT
#define LIB_CFG_MODULE_PRESENT
/*$PAGE*/
/*
*********************************************************************************************************
*********************************************************************************************************
* MEMORY LIBRARY CONFIGURATION
*********************************************************************************************************
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* MEMORY LIBRARY ARGUMENT CHECK CONFIGURATION
*
* Note(s) : (1) Configure LIB_MEM_CFG_ARG_CHK_EXT_EN to enable/disable the memory library suite external
* argument check feature :
*
* (a) When ENABLED, arguments received from any port interface provided by the developer
* or application are checked/validated.
*
* (b) When DISABLED, NO arguments received from any port interface provided by the developer
* or application are checked/validated.
*********************************************************************************************************
*/
/* Configure external argument check feature (see Note #1) : */
#define LIB_MEM_CFG_ARG_CHK_EXT_EN DEF_DISABLED
/* DEF_DISABLED Argument check DISABLED */
/* DEF_ENABLED Argument check ENABLED */
/*
*********************************************************************************************************
* MEMORY LIBRARY ASSEMBLY OPTIMIZATION CONFIGURATION
*
* Note(s) : (1) Configure LIB_MEM_CFG_OPTIMIZE_ASM_EN to enable/disable assembly-optimized memory function(s).
*********************************************************************************************************
*/
/* Configure assembly-optimized function(s) [see Note #1] : */
#define LIB_MEM_CFG_OPTIMIZE_ASM_EN DEF_ENABLED
/* DEF_DISABLED Assembly-optimized function(s) DISABLED */
/* DEF_ENABLED Assembly-optimized function(s) ENABLED */
/*
*********************************************************************************************************
* MEMORY ALLOCATION CONFIGURATION
*
* Note(s) : (1) Configure LIB_MEM_CFG_ALLOC_EN to enable/disable memory allocation functions.
*
* (2) (a) Configure LIB_MEM_CFG_HEAP_SIZE with the desired size of heap memory (in octets).
*
* (b) Configure LIB_MEM_CFG_HEAP_BASE_ADDR to specify a base address for heap memory :
*
* (1) Heap initialized to specified application memory, if LIB_MEM_CFG_HEAP_BASE_ADDR
* #define'd in 'app_cfg.h';
* CANNOT #define to address 0x0
*
* (2) Heap declared to Mem_Heap[] in 'lib_mem.c', if LIB_MEM_CFG_HEAP_BASE_ADDR
* NOT #define'd in 'app_cfg.h'
*********************************************************************************************************
*/
/* Configure memory allocation feature (see Note #1) : */
#define LIB_MEM_CFG_ALLOC_EN DEF_ENABLED
/* DEF_DISABLED Memory allocation DISABLED */
/* DEF_ENABLED Memory allocation ENABLED */
#define LIB_MEM_CFG_HEAP_SIZE 27u * 1024u /* Configure heap memory size [see Note #2a]. */
#if 0 /* Configure heap memory base address (see Note #2b). */
#define LIB_MEM_CFG_HEAP_BASE_ADDR 0x00000000u
#endif
/*$PAGE*/
/*
*********************************************************************************************************
*********************************************************************************************************
* STRING LIBRARY CONFIGURATION
*********************************************************************************************************
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* STRING FLOATING POINT CONFIGURATION
*
* Note(s) : (1) Configure LIB_STR_CFG_FP_EN to enable/disable floating point string function(s).
*
* (2) Configure LIB_STR_CFG_FP_MAX_NBR_DIG_SIG to configure the maximum number of significant
* digits to calculate &/or display for floating point string function(s).
*
* See also 'lib_str.h STRING FLOATING POINT DEFINES Note #1'.
*********************************************************************************************************
*/
/* Configure floating point feature(s) [see Note #1] : */
#define LIB_STR_CFG_FP_EN DEF_DISABLED
/* DEF_DISABLED Floating point functions DISABLED */
/* DEF_ENABLED Floating point functions ENABLED */
/* Configure floating point feature(s)' number of ... */
/* ... significant digits (see Note #2). */
#define LIB_STR_CFG_FP_MAX_NBR_DIG_SIG LIB_STR_FP_MAX_NBR_DIG_SIG_DFLT
/*$PAGE*/
/*
*********************************************************************************************************
* MODULE END
*********************************************************************************************************
*/
#endif /* End of lib cfg module include. */

View File

@@ -0,0 +1,246 @@
/*
************************************************************************************************************************
* uC/OS-III
* The Real-Time Kernel
*
* (c) Copyright 2009-2010; Micrium, Inc.; Weston, FL
* All rights reserved. Protected by international copyright laws.
*
* APPLICATION HOOKS
*
* File : OS_APP_HOOKS.C
* By : JJL
* Version : V3.01.2
*
* LICENSING TERMS:
* ---------------
* uC/OS-III is provided in source form to registered licensees ONLY. It is
* illegal to distribute this source code to any third party unless you receive
* written permission by an authorized Micrium representative. Knowledge of
* the source code may NOT be used to develop a similar product.
*
* Please help us continue to provide the Embedded community with the finest
* software available. Your honesty is greatly appreciated.
*
* You can contact us at www.micrium.com.
************************************************************************************************************************
*/
#include <os.h>
#include <os_app_hooks.h>
#include "brtc.h"
/*$PAGE*/
/*
************************************************************************************************************************
* SET ALL APPLICATION HOOKS
*
* Description: Set ALL application hooks.
*
* Arguments : none.
*
* Note(s) : none
************************************************************************************************************************
*/
void App_OS_SetAllHooks (void)
{
#if OS_CFG_APP_HOOKS_EN > 0u
CPU_SR_ALLOC();
CPU_CRITICAL_ENTER();
OS_AppTaskCreateHookPtr = App_OS_TaskCreateHook;
OS_AppTaskDelHookPtr = App_OS_TaskDelHook;
OS_AppTaskReturnHookPtr = App_OS_TaskReturnHook;
OS_AppIdleTaskHookPtr = App_OS_IdleTaskHook;
OS_AppStatTaskHookPtr = App_OS_StatTaskHook;
OS_AppTaskSwHookPtr = App_OS_TaskSwHook;
OS_AppTimeTickHookPtr = App_OS_TimeTickHook;
CPU_CRITICAL_EXIT();
#endif
}
/*$PAGE*/
/*
************************************************************************************************************************
* CLEAR ALL APPLICATION HOOKS
*
* Description: Clear ALL application hooks.
*
* Arguments : none.
*
* Note(s) : none
************************************************************************************************************************
*/
void App_OS_ClrAllHooks (void)
{
#if OS_CFG_APP_HOOKS_EN > 0u
CPU_SR_ALLOC();
CPU_CRITICAL_ENTER();
OS_AppTaskCreateHookPtr = (OS_APP_HOOK_TCB)0;
OS_AppTaskDelHookPtr = (OS_APP_HOOK_TCB)0;
OS_AppTaskReturnHookPtr = (OS_APP_HOOK_TCB)0;
OS_AppIdleTaskHookPtr = (OS_APP_HOOK_VOID)0;
OS_AppStatTaskHookPtr = (OS_APP_HOOK_VOID)0;
OS_AppTaskSwHookPtr = (OS_APP_HOOK_VOID)0;
OS_AppTimeTickHookPtr = (OS_APP_HOOK_VOID)0;
CPU_CRITICAL_EXIT();
#endif
}
/*$PAGE*/
/*
************************************************************************************************************************
* APPLICATION TASK CREATION HOOK
*
* Description: This function is called when a task is created.
*
* Arguments : p_tcb is a pointer to the task control block of the task being created.
*
* Note(s) : none
************************************************************************************************************************
*/
void App_OS_TaskCreateHook (OS_TCB *p_tcb)
{
(void)&p_tcb;
}
/*$PAGE*/
/*
************************************************************************************************************************
* APPLICATION TASK DELETION HOOK
*
* Description: This function is called when a task is deleted.
*
* Arguments : p_tcb is a pointer to the task control block of the task being deleted.
*
* Note(s) : none
************************************************************************************************************************
*/
void App_OS_TaskDelHook (OS_TCB *p_tcb)
{
(void)&p_tcb;
}
/*$PAGE*/
/*
************************************************************************************************************************
* APPLICATION TASK RETURN HOOK
*
* Description: This function is called if a task accidentally returns. In other words, a task should either be an
* infinite loop or delete itself when done.
*
* Arguments : p_tcb is a pointer to the OS_TCB of the task that is returning.
*
* Note(s) : none
************************************************************************************************************************
*/
void App_OS_TaskReturnHook (OS_TCB *p_tcb)
{
(void)&p_tcb;
}
/*$PAGE*/
/*
************************************************************************************************************************
* APPLICATION IDLE TASK HOOK
*
* Description: This function is called by the idle task. This hook has been added to allow you to do such things as
* STOP the CPU to conserve power.
*
* Arguments : none
*
* Note(s) : none
************************************************************************************************************************
*/
void App_OS_IdleTaskHook (void)
{
}
/*$PAGE*/
/*
************************************************************************************************************************
* APPLICATION OS INITIALIZATION HOOK
*
* Description: This function is called by OSInit() at the beginning of OSInit().
*
* Arguments : none
*
* Note(s) : none
************************************************************************************************************************
*/
void App_OS_InitHook (void)
{
}
/*$PAGE*/
/*
************************************************************************************************************************
* APPLICATION STATISTIC TASK HOOK
*
* Description: This function is called every second by uC/OS-III's statistics task. This allows your application to add
* functionality to the statistics task.
*
* Arguments : none
*
* Note(s) : none
************************************************************************************************************************
*/
void App_OS_StatTaskHook (void)
{
}
/*$PAGE*/
/*
************************************************************************************************************************
* APPLICATION TASK SWITCH HOOK
*
* Description: This function is called when a task switch is performed. This allows you to perform other operations
* during a context switch.
*
* Arguments : none
*
* Note(s) : 1) Interrupts are disabled during this call.
* 2) It is assumed that the global pointer 'OSTCBHighRdyPtr' points to the TCB of the task that will be
* 'switched in' (i.e. the highest priority task) and, 'OSTCBCurPtr' points to the task being switched out
* (i.e. the preempted task).
************************************************************************************************************************
*/
void App_OS_TaskSwHook (void)
{
}
/*$PAGE*/
/*
************************************************************************************************************************
* APPLICATION TICK HOOK
*
* Description: This function is called every tick.
*
* Arguments : none
*
* Note(s) : 1) This function is assumed to be called from the Tick ISR.
************************************************************************************************************************
*/
#include <stdio.h>
void App_OS_TimeTickHook (void)
{
// Time_Update(0, 0);
}

View File

@@ -0,0 +1,68 @@
/*
************************************************************************************************************************
* uC/OS-III
* The Real-Time Kernel
*
* (c) Copyright 2009-2010; Micrium, Inc.; Weston, FL
* All rights reserved. Protected by international copyright laws.
*
* APPLICATION HOOKS
*
* File : OS_APP_HOOKS.H
* By : JJL
* Version : V3.01.2
*
* LICENSING TERMS:
* ---------------
* uC/OS-III is provided in source form to registered licensees ONLY. It is
* illegal to distribute this source code to any third party unless you receive
* written permission by an authorized Micrium representative. Knowledge of
* the source code may NOT be used to develop a similar product.
*
* Please help us continue to provide the Embedded community with the finest
* software available. Your honesty is greatly appreciated.
*
* You can contact us at www.micrium.com.
************************************************************************************************************************
*/
#ifndef OS_APP_HOOKS_H
#define OS_APP_HOOKS_H
#ifdef OS_APP_HOOKS_H_GLOBALS
#define OS_APP_HOOKS_H_EXT
#else
#define OS_APP_HOOKS_H_EXT extern
#endif
/*
************************************************************************************************************************
* INCLUDE HEADER FILES
************************************************************************************************************************
*/
#include <os.h>
/*
************************************************************************************************************************
* FUNCTION PROTOTYPES
************************************************************************************************************************
*/
void App_OS_SetAllHooks (void);
void App_OS_ClrAllHooks (void);
/* ---------------------- HOOKS --------------------- */
void App_OS_TaskCreateHook(OS_TCB *p_tcb);
void App_OS_TaskDelHook (OS_TCB *p_tcb);
void App_OS_TaskReturnHook(OS_TCB *p_tcb);
void App_OS_IdleTaskHook (void);
void App_OS_InitHook (void);
void App_OS_StatTaskHook (void);
void App_OS_TaskSwHook (void);
void App_OS_TimeTickHook (void);
#endif

View File

@@ -0,0 +1,105 @@
/*
************************************************************************************************************************
* uC/OS-III
* The Real-Time Kernel
*
* (c) Copyright 2009-2010; Micrium, Inc.; Weston, FL
* All rights reserved. Protected by international copyright laws.
*
* CONFIGURATION FILE
*
* File : OS_CFG.H
* By : JJL
* Version : V3.01.2
*
* LICENSING TERMS:
* ---------------
* uC/OS-III is provided in source form to registered licensees ONLY. It is
* illegal to distribute this source code to any third party unless you receive
* written permission by an authorized Micrium representative. Knowledge of
* the source code may NOT be used to develop a similar product.
*
* Please help us continue to provide the Embedded community with the finest
* software available. Your honesty is greatly appreciated.
*
* You can contact us at www.micrium.com.
************************************************************************************************************************
*/
#ifndef OS_CFG_H
#define OS_CFG_H
/* ---------------------------- MISCELLANEOUS -------------------------- */
#define OS_CFG_APP_HOOKS_EN 1u /* Enable (1) or Disable (0) application specific hooks */
#define OS_CFG_ARG_CHK_EN 1u /* Enable (1) or Disable (0) argument checking */
#define OS_CFG_CALLED_FROM_ISR_CHK_EN 1u /* Enable (1) or Disable (0) check for called from ISR */
#define OS_CFG_DBG_EN 1u /* Enable (1) debug code/variables */
#define OS_CFG_ISR_POST_DEFERRED_EN 1u /* Enable (1) or Disable (0) Deferred ISR posts */
#define OS_CFG_OBJ_TYPE_CHK_EN 1u /* Enable (1) or Disable (0) object type checking */
#define OS_CFG_TS_EN 1u /* Enable (1) or Disable (0) time stamping */
#define OS_CFG_PEND_MULTI_EN 1u /* Enable (1) or Disable (0) code generation for multi-pend feature */
#define OS_CFG_PRIO_MAX 16u /* Defines the maximum number of task priorities (see OS_PRIO data type) */
#define OS_CFG_SCHED_LOCK_TIME_MEAS_EN 1u /* Include code to measure scheduler lock time */
#define OS_CFG_SCHED_ROUND_ROBIN_EN 1u /* Include code for Round-Robin scheduling */
#define OS_CFG_STK_SIZE_MIN 64u /* Minimum allowable task stack size */
/* ----------------------------- EVENT FLAGS --------------------------- */
#define OS_CFG_FLAG_EN 1u /* Enable (1) or Disable (0) code generation for EVENT FLAGS */
#define OS_CFG_FLAG_DEL_EN 1u /* Include code for OSFlagDel() */
#define OS_CFG_FLAG_MODE_CLR_EN 1u /* Include code for Wait on Clear EVENT FLAGS */
#define OS_CFG_FLAG_PEND_ABORT_EN 1u /* Include code for OSFlagPendAbort() */
/* -------------------------- MEMORY MANAGEMENT ------------------------ */
#define OS_CFG_MEM_EN 1u /* Enable (1) or Disable (0) code generation for MEMORY MANAGER */
/* --------------------- MUTUAL EXCLUSION SEMAPHORES ------------------- */
#define OS_CFG_MUTEX_EN 1u /* Enable (1) or Disable (0) code generation for MUTEX */
#define OS_CFG_MUTEX_DEL_EN 1u /* Include code for OSMutexDel() */
#define OS_CFG_MUTEX_PEND_ABORT_EN 1u /* Include code for OSMutexPendAbort() */
/* --------------------------- MESSAGE QUEUES -------------------------- */
#define OS_CFG_Q_EN 1u /* Enable (1) or Disable (0) code generation for QUEUES */
#define OS_CFG_Q_DEL_EN 1u /* Include code for OSQDel() */
#define OS_CFG_Q_FLUSH_EN 1u /* Include code for OSQFlush() */
#define OS_CFG_Q_PEND_ABORT_EN 1u /* Include code for OSQPendAbort() */
/* ----------------------------- SEMAPHORES ---------------------------- */
#define OS_CFG_SEM_EN 1u /* Enable (1) or Disable (0) code generation for SEMAPHORES */
#define OS_CFG_SEM_DEL_EN 1u /* Include code for OSSemDel() */
#define OS_CFG_SEM_PEND_ABORT_EN 1u /* Include code for OSSemPendAbort() */
#define OS_CFG_SEM_SET_EN 1u /* Include code for OSSemSet() */
/* -------------------------- TASK MANAGEMENT -------------------------- */
#define OS_CFG_STAT_TASK_EN 1u /* Enable (1) or Disable(0) the statistics task */
#define OS_CFG_STAT_TASK_STK_CHK_EN 1u /* Check task stacks from statistic task */
#define OS_CFG_TASK_CHANGE_PRIO_EN 1u /* Include code for OSTaskChangePrio() */
#define OS_CFG_TASK_DEL_EN 1u /* Include code for OSTaskDel() */
#define OS_CFG_TASK_Q_EN 1u /* Include code for OSTaskQXXXX() */
#define OS_CFG_TASK_Q_PEND_ABORT_EN 1u /* Include code for OSTaskQPendAbort() */
#define OS_CFG_TASK_PROFILE_EN 1u /* Include variables in OS_TCB for profiling */
#define OS_CFG_TASK_REG_TBL_SIZE 1u /* Number of task specific registers */
#define OS_CFG_TASK_SEM_PEND_ABORT_EN 1u /* Include code for OSTaskSemPendAbort() */
#define OS_CFG_TASK_SUSPEND_EN 1u /* Include code for OSTaskSuspend() and OSTaskResume() */
/* -------------------------- TIME MANAGEMENT -------------------------- */
#define OS_CFG_TIME_DLY_HMSM_EN 1u /* Include code for OSTimeDlyHMSM() */
#define OS_CFG_TIME_DLY_RESUME_EN 1u /* Include code for OSTimeDlyResume() */
/* ------------------------- TIMER MANAGEMENT -------------------------- */
#define OS_CFG_TMR_EN 1u /* Enable (1) or Disable (0) code generation for TIMERS */
#define OS_CFG_TMR_DEL_EN 1u /* Enable (1) or Disable (0) code generation for OSTmrDel() */
#endif

View File

@@ -0,0 +1,72 @@
/*
************************************************************************************************************************
* uC/OS-III
* The Real-Time Kernel
*
* (c) Copyright 2009-2010; Micrium, Inc.; Weston, FL
* All rights reserved. Protected by international copyright laws.
*
* OS CONFIGURATION (APPLICATION SPECIFICS)
*
* File : OS_CFG_APP.H
* By : JJL
* Version : V3.01.2
*
* LICENSING TERMS:
* ---------------
* uC/OS-III is provided in source form to registered licensees ONLY. It is
* illegal to distribute this source code to any third party unless you receive
* written permission by an authorized Micrium representative. Knowledge of
* the source code may NOT be used to develop a similar product.
*
* Please help us continue to provide the Embedded community with the finest
* software available. Your honesty is greatly appreciated.
*
* You can contact us at www.micrium.com.
************************************************************************************************************************
*/
#ifndef OS_CFG_APP_H
#define OS_CFG_APP_H
/*
************************************************************************************************************************
* CONSTANTS
************************************************************************************************************************
*/
/* --------------------- MISCELLANEOUS ------------------ */
#define OS_CFG_MSG_POOL_SIZE 100u /* Maximum number of messages */
#define OS_CFG_ISR_STK_SIZE 128u /* Stack size of ISR stack (number of CPU_STK elements) */
#define OS_CFG_TASK_STK_LIMIT_PCT_EMPTY 10u /* Stack limit position in percentage to empty */
/* ---------------------- IDLE TASK --------------------- */
#define OS_CFG_IDLE_TASK_STK_SIZE 128u /* Stack size (number of CPU_STK elements) */
/* ------------------ ISR HANDLER TASK ------------------ */
#define OS_CFG_INT_Q_SIZE 10u /* Size of ISR handler task queue */
#define OS_CFG_INT_Q_TASK_STK_SIZE 128u /* Stack size (number of CPU_STK elements) */
/* ------------------- STATISTIC TASK ------------------- */
#define OS_CFG_STAT_TASK_PRIO (OS_CFG_PRIO_MAX-2u) /* Priority */
#define OS_CFG_STAT_TASK_RATE_HZ 10u /* Rate of execution (10 Hz Typ.) */
#define OS_CFG_STAT_TASK_STK_SIZE 128u /* Stack size (number of CPU_STK elements) */
/* ------------------------ TICKS ----------------------- */
#define OS_CFG_TICK_RATE_HZ 1000u /* Tick rate in Hertz (10 to 1000 Hz) */
#define OS_CFG_TICK_TASK_PRIO 1u /* Priority */
#define OS_CFG_TICK_TASK_STK_SIZE 128u /* Stack size (number of CPU_STK elements) */
#define OS_CFG_TICK_WHEEL_SIZE 17u /* Number of 'spokes' in tick wheel; SHOULD be prime */
/* ----------------------- TIMERS ----------------------- */
#define OS_CFG_TMR_TASK_PRIO 2u /* Priority of 'Timer Task' */
#define OS_CFG_TMR_TASK_RATE_HZ 100u /* Rate for timers (10 Hz Typ.) */
#define OS_CFG_TMR_TASK_STK_SIZE 128u /* Stack size (number of CPU_STK elements) */
#define OS_CFG_TMR_WHEEL_SIZE 17u /* Number of 'spokes' in timer wheel; SHOULD be prime */
#endif