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

View File

@@ -0,0 +1,354 @@
/*
*********************************************************************************************************
*
* 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();
IWDG_ReloadCounter();
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;
/* Set the Vector Table base location at 0x08020000 */
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x3000);
/* Set the NVIC priority preemptive priorities grouped into Group2:0-3, 0-3-response priority */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
/* 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

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);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

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

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);
}

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. */

File diff suppressed because it is too large Load Diff

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);
}

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. */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

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,158 @@
@
@********************************************************************************************************
@ 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
@********************************************************************************************************
.section .text, "ax"
.align 2
.thumb
.syntax unified
.global OSStartHighRdy
.type OSStartHighRdy, %function
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).
@********************************************************************************************************
.global OS_CPU_PendSVHandler
.type OS_CPU_PendSVHandler, %function
.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,414 @@
/*
*********************************************************************************************************
* 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>
#include <stdio.h>
static CPU_INT32U sw_debug_count = 0;
static CPU_INT32U tick_debug_count = 0;
/*
*********************************************************************************************************
* 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_VOID)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;
}

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,100 @@
/*
*********************************************************************************************************
* 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 <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_DISABLED
/* DEF_DISABLED Memory allocation DISABLED */
/* DEF_ENABLED Memory allocation ENABLED */
#define LIB_MEM_CFG_HEAP_SIZE 8u * 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