Adding uC-OS3
This commit is contained in:
parent
b2d613f38b
commit
4ece7f9e71
|
|
@ -0,0 +1,655 @@
|
|||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/CPU
|
||||
* CPU CONFIGURATION & PORT LAYER
|
||||
*
|
||||
* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com
|
||||
*
|
||||
* SPDX-License-Identifier: APACHE-2.0
|
||||
*
|
||||
* This software is subject to an open source license and is distributed by
|
||||
* Silicon Laboratories Inc. pursuant to the terms of the Apache License,
|
||||
* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
*
|
||||
* CPU PORT FILE
|
||||
*
|
||||
* ARMv6-M
|
||||
* GNU C Compiler
|
||||
*
|
||||
* Filename : cpu.h
|
||||
* Version : v1.32.00
|
||||
*********************************************************************************************************
|
||||
* Note(s) : This port supports the ARM Cortex-M0, and Cortex-M0+ architectures.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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. */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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. */
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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
|
||||
*
|
||||
* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for
|
||||
* cpu stacks.
|
||||
*
|
||||
* (a) ARM Procedure Calls Standard requires an 8 bytes stack alignment.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */
|
||||
|
||||
#define CPU_CFG_STK_ALIGN_BYTES (8u) /* Defines CPU stack alignment in bytes. (see Note #2). */
|
||||
|
||||
typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */
|
||||
typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
/* 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
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* MEMORY BARRIERS CONFIGURATION
|
||||
*
|
||||
* Note(s) : (1) (a) Configure memory barriers if required by the architecture.
|
||||
*
|
||||
* CPU_MB Full memory barrier.
|
||||
* CPU_RMB Read (Loads) memory barrier.
|
||||
* CPU_WMB Write (Stores) memory barrier.
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#define CPU_MB() __asm__ __volatile__ ("dsb" : : : "memory")
|
||||
#define CPU_RMB() __asm__ __volatile__ ("dsb" : : : "memory")
|
||||
#define CPU_WMB() __asm__ __volatile__ ("dsb" : : : "memory")
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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); /* C-code replacement for asm function */
|
||||
|
||||
void CPU_BitBandClr (CPU_ADDR addr,
|
||||
CPU_INT08U bit_nbr);
|
||||
void CPU_BitBandSet (CPU_ADDR addr,
|
||||
CPU_INT08U bit_nbr);
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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_RSVD_04 4u /* RSVD interrupts may be designated on newer models */
|
||||
#define CPU_INT_RSVD_05 5u
|
||||
#define CPU_INT_RSVD_06 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_RSVD_12 12u
|
||||
#define CPU_INT_RSVD_13 13u
|
||||
#define CPU_INT_PENDSV 14u
|
||||
#define CPU_INT_SYSTICK 15u
|
||||
#define CPU_INT_EXT0 16u
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* CPU REGISTERS
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
/* -------- SYSTICK REGISTERS --------- */
|
||||
#define CPU_REG_SYST_CSR (*((CPU_REG32 *)(0xE000E010))) /* SysTick Ctrl & Status Reg. */
|
||||
#define CPU_REG_SYST_RVR (*((CPU_REG32 *)(0xE000E014))) /* SysTick Reload Value Reg. */
|
||||
#define CPU_REG_SYST_CVR (*((CPU_REG32 *)(0xE000E018))) /* SysTick Current Value Reg. */
|
||||
#define CPU_REG_SYST_CALIB (*((CPU_REG32 *)(0xE000E01C))) /* SysTick Calibration Value Reg. */
|
||||
|
||||
/* ---------- NVIC REGISTERS ---------- */
|
||||
#define CPU_REG_NVIC_ISER(n) (*((CPU_REG32 *)(0xE000E100 + (n) * 4u))) /* IRQ Set En Reg. */
|
||||
#define CPU_REG_NVIC_ICER(n) (*((CPU_REG32 *)(0xE000E180 + (n) * 4u))) /* IRQ Clr En Reg. */
|
||||
#define CPU_REG_NVIC_ISPR(n) (*((CPU_REG32 *)(0xE000E200 + (n) * 4u))) /* IRQ Set Pending Reg. */
|
||||
#define CPU_REG_NVIC_ICPR(n) (*((CPU_REG32 *)(0xE000E280 + (n) * 4u))) /* IRQ Clr Pending Reg. */
|
||||
#define CPU_REG_NVIC_IPR(n) (*((CPU_REG32 *)(0xE000E400 + (n) * 4u))) /* IRQ Prio Reg. */
|
||||
|
||||
/* -- SYSTEM CONTROL BLOCK(SCB) REG -- */
|
||||
#define CPU_REG_SCB_CPUID (*((CPU_REG32 *)(0xE000ED00))) /* CPUID Base Reg. */
|
||||
#define CPU_REG_SCB_ICSR (*((CPU_REG32 *)(0xE000ED04))) /* Int Ctrl State Reg. */
|
||||
#define CPU_REG_SCB_VTOR (*((CPU_REG32 *)(0xE000ED08))) /* Vect Tbl Offset Reg. */
|
||||
#define CPU_REG_SCB_AIRCR (*((CPU_REG32 *)(0xE000ED0C))) /* App Int/Reset Ctrl Reg. */
|
||||
#define CPU_REG_SCB_SCR (*((CPU_REG32 *)(0xE000ED10))) /* System Ctrl Reg. */
|
||||
#define CPU_REG_SCB_CCR (*((CPU_REG32 *)(0xE000ED14))) /* Cfg Ctrl Reg. */
|
||||
#define CPU_REG_SCB_SHPRI2 (*((CPU_REG32 *)(0xE000ED1C))) /* System Handlers 8 to 11 Prio. */
|
||||
#define CPU_REG_SCB_SHPRI3 (*((CPU_REG32 *)(0xE000ED20))) /* System Handlers 12 to 15 Prio. */
|
||||
#define CPU_REG_SCB_SHCSR (*((CPU_REG32 *)(0xE000ED24))) /* System Handler Ctrl & State Reg. */
|
||||
#define CPU_REG_SCB_DFSR (*((CPU_REG32 *)(0xE000ED30))) /* Debug Fault Status Reg. */
|
||||
|
||||
/* ---------- CPUID REGISTERS --------- */
|
||||
#define CPU_REG_CPUID_MMFR0 (*((CPU_REG32 *)(0xE000ED50))) /* Memory Model Feature Reg 0. */
|
||||
#define CPU_REG_CPUID_MMFR1 (*((CPU_REG32 *)(0xE000ED54))) /* Memory Model Feature Reg 1. */
|
||||
#define CPU_REG_CPUID_MMFR2 (*((CPU_REG32 *)(0xE000ED58))) /* Memory Model Feature Reg 2. */
|
||||
#define CPU_REG_CPUID_MMFR3 (*((CPU_REG32 *)(0xE000ED5C))) /* Memory Model Feature Reg 3. */
|
||||
#define CPU_REG_CPUID_ISAFR0 (*((CPU_REG32 *)(0xE000ED60))) /* ISA Feature Reg 0. */
|
||||
#define CPU_REG_CPUID_ISAFR1 (*((CPU_REG32 *)(0xE000ED64))) /* ISA Feature Reg 1. */
|
||||
#define CPU_REG_CPUID_ISAFR2 (*((CPU_REG32 *)(0xE000ED68))) /* ISA Feature Reg 2. */
|
||||
#define CPU_REG_CPUID_ISAFR3 (*((CPU_REG32 *)(0xE000ED6C))) /* ISA Feature Reg 3. */
|
||||
#define CPU_REG_CPUID_ISAFR4 (*((CPU_REG32 *)(0xE000ED70))) /* ISA Feature Reg 4. */
|
||||
|
||||
/* ----------- MPU REGISTERS ---------- */
|
||||
#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_RNR (*((CPU_REG32 *)(0xE000ED98))) /* MPU Region Nbr Reg. */
|
||||
#define CPU_REG_MPU_RBAR (*((CPU_REG32 *)(0xE000ED9C))) /* MPU Region Base Addr Reg. */
|
||||
#define CPU_REG_MPU_RASR (*((CPU_REG32 *)(0xE000EDA0))) /* MPU Region Attrib & Size Reg. */
|
||||
|
||||
/* ----- REGISTERS NOT IN THE SCB ----- */
|
||||
#define CPU_REG_ICTR (*((CPU_REG32 *)(0xE000E004))) /* Int Ctrl'er Type Reg. */
|
||||
#define CPU_REG_DCRSR (*((CPU_REG32 *)(0xE000EDF4))) /* Debug Core Reg Selector Reg. */
|
||||
#define CPU_REG_DCRDR (*((CPU_REG32 *)(0xE000EDF8))) /* Debug Core Reg Data Reg. */
|
||||
#define CPU_REG_DEMCR (*((CPU_REG32 *)(0xE000EDFC))) /* Debug Except & Monitor Ctrl Reg. */
|
||||
#define CPU_REG_STIR (*((CPU_REG32 *)(0xE000EF00))) /* Software Trigger Int Reg. */
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* CPU REGISTER BITS
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
/* ---------- SYSTICK CTRL & STATUS REG BITS ---------- */
|
||||
#define CPU_REG_SYST_CSR_COUNTFLAG 0x00010000
|
||||
#define CPU_REG_SYST_CSR_CLKSOURCE 0x00000004
|
||||
#define CPU_REG_SYST_CSR_TICKINT 0x00000002
|
||||
#define CPU_REG_SYST_CSR_ENABLE 0x00000001
|
||||
|
||||
/* -------- SYSTICK CALIBRATION VALUE REG BITS -------- */
|
||||
#define CPU_REG_SYST_CALIB_NOREF 0x80000000
|
||||
#define CPU_REG_SYST_CALIB_SKEW 0x40000000
|
||||
|
||||
/* -------------- INT CTRL STATE REG BITS ------------- */
|
||||
#define CPU_REG_SCB_ICSR_NMIPENDSET 0x80000000
|
||||
#define CPU_REG_SCB_ICSR_PENDSVSET 0x10000000
|
||||
#define CPU_REG_SCB_ICSR_PENDSVCLR 0x08000000
|
||||
#define CPU_REG_SCB_ICSR_PENDSTSET 0x04000000
|
||||
#define CPU_REG_SCB_ICSR_PENDSTCLR 0x02000000
|
||||
#define CPU_REG_SCB_ICSR_ISRPREEMPT 0x00800000
|
||||
#define CPU_REG_SCB_ICSR_ISRPENDING 0x00400000
|
||||
|
||||
/* ------------- VECT TBL OFFSET REG BITS ------------- */
|
||||
#define CPU_REG_SCB_VTOR_TBLBASE 0x20000000
|
||||
|
||||
/* ------------ APP INT/RESET CTRL REG BITS ----------- */
|
||||
#define CPU_REG_SCB_AIRCR_ENDIANNESS 0x00008000
|
||||
#define CPU_REG_SCB_AIRCR_SYSRESETREQ 0x00000004
|
||||
#define CPU_REG_SCB_AIRCR_VECTCLRACTIVE 0x00000002
|
||||
|
||||
/* --------------- SYSTEM CTRL REG BITS --------------- */
|
||||
#define CPU_REG_SCB_SCR_SEVONPEND 0x00000010
|
||||
#define CPU_REG_SCB_SCR_SLEEPDEEP 0x00000004
|
||||
#define CPU_REG_SCB_SCR_SLEEPONEXIT 0x00000002
|
||||
|
||||
/* ----------------- CFG CTRL REG BITS ---------------- */
|
||||
#define CPU_REG_SCB_CCR_STKALIGN 0x00000200
|
||||
#define CPU_REG_SCB_CCR_UNALIGN_TRP 0x00000008
|
||||
|
||||
/* ------- SYSTEM HANDLER CTRL & STATE REG BITS ------- */
|
||||
#define CPU_REG_SCB_SHCSR_SVCALLPENDED 0x00008000
|
||||
|
||||
/* ------------ DEBUG FAULT STATUS REG BITS ----------- */
|
||||
#define CPU_REG_SCB_DFSR_EXTERNAL 0x00000010
|
||||
#define CPU_REG_SCB_DFSR_VCATCH 0x00000008
|
||||
#define CPU_REG_SCB_DFSR_DWTTRAP 0x00000004
|
||||
#define CPU_REG_SCB_DFSR_BKPT 0x00000002
|
||||
#define CPU_REG_SCB_DFSR_HALTED 0x00000001
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* CPU REGISTER MASK
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#define CPU_MSK_SCB_ICSR_VECT_ACTIVE 0x000001FF
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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
|
||||
|
||||
|
||||
|
||||
|
||||
#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
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* MODULE END
|
||||
*
|
||||
* Note(s) : (1) See 'cpu.h MODULE'.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* End of CPU module include. */
|
||||
|
||||
|
|
@ -0,0 +1,148 @@
|
|||
@********************************************************************************************************
|
||||
@ uC/CPU
|
||||
@ CPU CONFIGURATION & PORT LAYER
|
||||
@
|
||||
@ Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com
|
||||
@
|
||||
@ SPDX-License-Identifier: APACHE-2.0
|
||||
@
|
||||
@ This software is subject to an open source license and is distributed by
|
||||
@ Silicon Laboratories Inc. pursuant to the terms of the Apache License,
|
||||
@ Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
|
||||
@
|
||||
@********************************************************************************************************
|
||||
|
||||
@********************************************************************************************************
|
||||
@
|
||||
@ CPU PORT FILE
|
||||
@
|
||||
@ ARMv6-M
|
||||
@ GNU C Compiler
|
||||
@
|
||||
@ Filename : cpu_a.s
|
||||
@ Version : v1.32.00
|
||||
@********************************************************************************************************
|
||||
@ Note(s) : This port supports the ARM Cortex-M0, and Cortex-M0+ architectures.
|
||||
@********************************************************************************************************
|
||||
|
||||
|
||||
@********************************************************************************************************
|
||||
@ PUBLIC FUNCTIONS
|
||||
@********************************************************************************************************
|
||||
|
||||
.global CPU_IntDis
|
||||
.global CPU_IntEn
|
||||
|
||||
.global CPU_SR_Save
|
||||
.global CPU_SR_Restore
|
||||
|
||||
.global CPU_WaitForInt
|
||||
.global CPU_WaitForExcept
|
||||
|
||||
|
||||
@********************************************************************************************************
|
||||
@ CODE GENERATION DIRECTIVES
|
||||
@********************************************************************************************************
|
||||
|
||||
.text
|
||||
.align 2
|
||||
.thumb
|
||||
.syntax unified
|
||||
|
||||
|
||||
@********************************************************************************************************
|
||||
@ 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
|
||||
|
||||
|
||||
@********************************************************************************************************
|
||||
@ 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
|
||||
|
||||
|
||||
@********************************************************************************************************
|
||||
@ CPU ASSEMBLY PORT FILE END
|
||||
@********************************************************************************************************
|
||||
|
||||
.end
|
||||
|
||||
|
|
@ -0,0 +1,695 @@
|
|||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/CPU
|
||||
* CPU CONFIGURATION & PORT LAYER
|
||||
*
|
||||
* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com
|
||||
*
|
||||
* SPDX-License-Identifier: APACHE-2.0
|
||||
*
|
||||
* This software is subject to an open source license and is distributed by
|
||||
* Silicon Laboratories Inc. pursuant to the terms of the Apache License,
|
||||
* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
*
|
||||
* CPU PORT FILE
|
||||
*
|
||||
* ARMv6-M
|
||||
*
|
||||
* Filename : cpu_c.c
|
||||
* Version : v1.32.00
|
||||
*********************************************************************************************************
|
||||
* Note(s) : This port supports the ARM Cortex-M0, and Cortex-M0+ architectures.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* INCLUDE FILES
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#define MICRIUM_SOURCE
|
||||
#include <cpu.h>
|
||||
#include <cpu_core.h>
|
||||
|
||||
#include <lib_def.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* LOCAL DEFINES
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#define CPU_INT_SRC_POS_MAX ((((CPU_REG_ICTR + 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
|
||||
*
|
||||
* Note(s) : (1) Determines the interrupt programmable priority levels. This is normally specified in the
|
||||
* Microcontroller reference manual. 2-bits gives us 4 programmable priority levels.
|
||||
*
|
||||
* NVIC_IPRx
|
||||
* 7 0
|
||||
* +------------------+
|
||||
* | PRIO |
|
||||
* +------------------+
|
||||
*
|
||||
* Bits[7:6] Priority mask bits
|
||||
* Bits[5:0] Reserved
|
||||
*
|
||||
* In this example our CPU_CFG_NVIC_PRIO_BITS define should be set to 2 due to the processor
|
||||
* implementing only bits[7:6].
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef CPU_CFG_NVIC_PRIO_BITS
|
||||
#error "CPU_CFG_NVIC_PRIO_BITS not #define'd in 'cpu_cfg.h' " /* See Note # 1 */
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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.
|
||||
*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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.
|
||||
*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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.
|
||||
*
|
||||
* 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-M0 table position is 256. A particular Cortex-M0 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.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
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_PENDSV: /* PendSV (see Note #2). */
|
||||
break;
|
||||
|
||||
case CPU_INT_SYSTICK: /* SysTick. */
|
||||
CPU_CRITICAL_ENTER();
|
||||
CPU_REG_SYST_CSR &= ~CPU_REG_SYST_CSR_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_ICER(group) = DEF_BIT(nbr); /* Disable interrupt. */
|
||||
CPU_CRITICAL_EXIT();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* CPU_IntSrcEn()
|
||||
*
|
||||
* Description : Enable an interrupt source.
|
||||
*
|
||||
* Argument(s) : pos Position of interrupt vector in interrupt table (see 'CPU_IntSrcDis()').
|
||||
*
|
||||
* Return(s) : none.
|
||||
*
|
||||
* 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_PENDSV: /* PendSV (see Note #2). */
|
||||
break;
|
||||
|
||||
case CPU_INT_SYSTICK: /* SysTick. */
|
||||
CPU_CRITICAL_ENTER();
|
||||
CPU_REG_SYST_CSR |= CPU_REG_SYST_CSR_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_ISER(group) = DEF_BIT(nbr); /* Enable interrupt. */
|
||||
CPU_CRITICAL_EXIT();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* CPU_IntSrcPendClr()
|
||||
*
|
||||
* Description : Clear a pending interrupt.
|
||||
*
|
||||
* Argument(s) : pos Position of interrupt vector in interrupt table (see 'CPU_IntSrcDis()').
|
||||
*
|
||||
* Return(s) : none.
|
||||
*
|
||||
* 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_SVCALL: /* SVCall (see Note #2). */
|
||||
case CPU_INT_PENDSV: /* PendSV (see Note #2). */
|
||||
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_ICPR(group) = DEF_BIT(nbr); /* Clear Pending interrupt. */
|
||||
CPU_CRITICAL_EXIT();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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.
|
||||
*
|
||||
* 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 temp;
|
||||
CPU_INT32U prio_offset;
|
||||
CPU_SR_ALLOC();
|
||||
|
||||
|
||||
prio_offset = (prio << (DEF_OCTET_NBR_BITS - CPU_CFG_NVIC_PRIO_BITS));
|
||||
if (prio >= (1u << CPU_CFG_NVIC_PRIO_BITS)) { /* Priority should not exceed the max allowed by MCU */
|
||||
CPU_SW_Exception();
|
||||
}
|
||||
|
||||
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_SVCALL: /* SVCall. */
|
||||
CPU_CRITICAL_ENTER();
|
||||
temp = CPU_REG_SCB_SHPRI2;
|
||||
temp &= ~((CPU_INT32U)DEF_OCTET_MASK << (3 * DEF_OCTET_NBR_BITS));
|
||||
temp |= ((CPU_INT32U)prio_offset << (3 * DEF_OCTET_NBR_BITS));
|
||||
CPU_REG_SCB_SHPRI2 = temp;
|
||||
CPU_CRITICAL_EXIT();
|
||||
break;
|
||||
|
||||
case CPU_INT_PENDSV: /* PendSV. */
|
||||
CPU_CRITICAL_ENTER();
|
||||
temp = CPU_REG_SCB_SHPRI3;
|
||||
temp &= ~((CPU_INT32U)DEF_OCTET_MASK << (2 * DEF_OCTET_NBR_BITS));
|
||||
temp |= ((CPU_INT32U)prio_offset << (2 * DEF_OCTET_NBR_BITS));
|
||||
CPU_REG_SCB_SHPRI3 = temp;
|
||||
CPU_CRITICAL_EXIT();
|
||||
break;
|
||||
|
||||
case CPU_INT_SYSTICK: /* SysTick. */
|
||||
CPU_CRITICAL_ENTER();
|
||||
temp = CPU_REG_SCB_SHPRI3;
|
||||
temp &= ~((CPU_INT32U)DEF_OCTET_MASK << (3 * DEF_OCTET_NBR_BITS));
|
||||
temp |= ((CPU_INT32U)prio_offset << (3 * DEF_OCTET_NBR_BITS));
|
||||
CPU_REG_SCB_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_IPR(group);
|
||||
temp &= ~((CPU_INT32U)DEF_OCTET_MASK << (nbr * DEF_OCTET_NBR_BITS));
|
||||
temp |= ((CPU_INT32U)prio_offset << (nbr * DEF_OCTET_NBR_BITS));
|
||||
CPU_REG_NVIC_IPR(group) = temp; /* Set interrupt priority. */
|
||||
CPU_CRITICAL_EXIT();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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.
|
||||
*
|
||||
* 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 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_SVCALL: /* SVCall. */
|
||||
CPU_CRITICAL_ENTER();
|
||||
temp = CPU_REG_SCB_SHPRI2;
|
||||
prio = (temp >> (3 * DEF_OCTET_NBR_BITS)) & DEF_OCTET_MASK;
|
||||
CPU_CRITICAL_EXIT();
|
||||
break;
|
||||
|
||||
case CPU_INT_PENDSV: /* PendSV. */
|
||||
CPU_CRITICAL_ENTER();
|
||||
temp = CPU_REG_SCB_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_SCB_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_IPR(group); /* Read group interrupt priority. */
|
||||
CPU_CRITICAL_EXIT();
|
||||
|
||||
prio = (temp >> (nbr * DEF_OCTET_NBR_BITS)) & DEF_OCTET_MASK;
|
||||
} else {
|
||||
prio = DEF_INT_16S_MIN_VAL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (prio != DEF_INT_16S_MIN_VAL) {
|
||||
prio = (prio >> (DEF_OCTET_NBR_BITS - CPU_CFG_NVIC_PRIO_BITS));
|
||||
}
|
||||
|
||||
return (prio);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* CPU_RevBits()
|
||||
*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).
|
||||
*
|
||||
* Note(s) : (1) val is a 32-bit number
|
||||
* (2) Goes through a number and checks for sets bits which are then set
|
||||
* in the reverse locations:
|
||||
*
|
||||
* reverse_val => 0b00000....00
|
||||
* val => 0101100....10
|
||||
* val's 2nd bit is set => reverse_val's bit (num_bits - 1 - count)
|
||||
* val's 5th bit is set => reverse_val's bit (num_bits - 1 - count)
|
||||
* ... ...
|
||||
* ... ...
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
CPU_DATA CPU_RevBits(CPU_DATA val)
|
||||
{
|
||||
CPU_DATA reverse_val;
|
||||
CPU_INT08U nbr_bits; /* establish how many bits are in val */
|
||||
CPU_INT32U cnt; /* for stepping through each bit in val */
|
||||
CPU_INT32U tmp; /* gets shifted off bit to check if set or not */
|
||||
|
||||
|
||||
nbr_bits = sizeof(CPU_DATA) * 8;
|
||||
reverse_val = 0; /* make sure reverse_val is cleared out to zeros */
|
||||
|
||||
for (cnt = 0; cnt < nbr_bits; cnt++)
|
||||
{
|
||||
tmp = (val & (1 << cnt)); /* shift the next bit into tmp */
|
||||
|
||||
if(tmp) {
|
||||
reverse_val |= (1 << ((nbr_bits - 1) - cnt)); /* shift in a 1 bit to reverse equivalent bit */
|
||||
}
|
||||
}
|
||||
|
||||
return (reverse_val);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,762 @@
|
|||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/CPU
|
||||
* CPU CONFIGURATION & PORT LAYER
|
||||
*
|
||||
* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com
|
||||
*
|
||||
* SPDX-License-Identifier: APACHE-2.0
|
||||
*
|
||||
* This software is subject to an open source license and is distributed by
|
||||
* Silicon Laboratories Inc. pursuant to the terms of the Apache License,
|
||||
* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
*
|
||||
* CPU PORT FILE
|
||||
*
|
||||
* ARMv7-M
|
||||
* GNU C Compiler
|
||||
*
|
||||
* Filename : cpu.h
|
||||
* Version : v1.32.00
|
||||
*********************************************************************************************************
|
||||
* Note(s) : This port supports the ARM Cortex-M3, Cortex-M4 and Cortex-M7 architectures.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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. */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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. */
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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
|
||||
*
|
||||
* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for
|
||||
* cpu stacks.
|
||||
*
|
||||
* (a) ARM Procedure Calls Standard requires an 8 bytes stack alignment.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */
|
||||
|
||||
#define CPU_CFG_STK_ALIGN_BYTES (8u) /* Defines CPU stack alignment in bytes. (see Note #2). */
|
||||
|
||||
typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */
|
||||
typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
/* 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
|
||||
/* Save CPU current BASEPRI priority lvl for exception. */
|
||||
#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(CPU_CFG_KA_IPL_BOUNDARY << (8u - CPU_CFG_NVIC_PRIO_BITS));} while (0)
|
||||
#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU BASEPRI priority level. */
|
||||
|
||||
|
||||
#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
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* MEMORY BARRIERS CONFIGURATION
|
||||
*
|
||||
* Note(s) : (1) (a) Configure memory barriers if required by the architecture.
|
||||
*
|
||||
* CPU_MB Full memory barrier.
|
||||
* CPU_RMB Read (Loads) memory barrier.
|
||||
* CPU_WMB Write (Stores) memory barrier.
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#define CPU_MB() __asm__ __volatile__ ("dsb" : : : "memory")
|
||||
#define CPU_RMB() __asm__ __volatile__ ("dsb" : : : "memory")
|
||||
#define CPU_WMB() __asm__ __volatile__ ("dsb" : : : "memory")
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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). */
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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_INT08U type);
|
||||
|
||||
|
||||
CPU_SR CPU_SR_Save (CPU_SR new_basepri);
|
||||
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);
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* INTERRUPT TYPE
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#define CPU_INT_KA 0u /* Kernel Aware interrupt request. */
|
||||
#define CPU_INT_NKA 1u /* Non-Kernel Aware interrupt request. */
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* CPU REGISTERS
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
/* -------- SYSTICK REGISTERS --------- */
|
||||
#define CPU_REG_SYST_CSR (*((CPU_REG32 *)(0xE000E010))) /* SysTick Ctrl & Status Reg. */
|
||||
#define CPU_REG_SYST_RVR (*((CPU_REG32 *)(0xE000E014))) /* SysTick Reload Value Reg. */
|
||||
#define CPU_REG_SYST_CVR (*((CPU_REG32 *)(0xE000E018))) /* SysTick Current Value Reg. */
|
||||
#define CPU_REG_SYST_CALIB (*((CPU_REG32 *)(0xE000E01C))) /* SysTick Calibration Value Reg. */
|
||||
|
||||
/* ---------- NVIC REGISTERS ---------- */
|
||||
#define CPU_REG_NVIC_ISER(n) (*((CPU_REG32 *)(0xE000E100 + (n) * 4u))) /* IRQ Set En Reg. */
|
||||
#define CPU_REG_NVIC_ICER(n) (*((CPU_REG32 *)(0xE000E180 + (n) * 4u))) /* IRQ Clr En Reg. */
|
||||
#define CPU_REG_NVIC_ISPR(n) (*((CPU_REG32 *)(0xE000E200 + (n) * 4u))) /* IRQ Set Pending Reg. */
|
||||
#define CPU_REG_NVIC_ICPR(n) (*((CPU_REG32 *)(0xE000E280 + (n) * 4u))) /* IRQ Clr Pending Reg. */
|
||||
#define CPU_REG_NVIC_IABR(n) (*((CPU_REG32 *)(0xE000E300 + (n) * 4u))) /* IRQ Active Reg. */
|
||||
#define CPU_REG_NVIC_IPR(n) (*((CPU_REG32 *)(0xE000E400 + (n) * 4u))) /* IRQ Prio Reg. */
|
||||
|
||||
/* -- SYSTEM CONTROL BLOCK(SCB) REG -- */
|
||||
#define CPU_REG_SCB_CPUID (*((CPU_REG32 *)(0xE000ED00))) /* CPUID Base Reg. */
|
||||
#define CPU_REG_SCB_ICSR (*((CPU_REG32 *)(0xE000ED04))) /* Int Ctrl State Reg. */
|
||||
#define CPU_REG_SCB_VTOR (*((CPU_REG32 *)(0xE000ED08))) /* Vect Tbl Offset Reg. */
|
||||
#define CPU_REG_SCB_AIRCR (*((CPU_REG32 *)(0xE000ED0C))) /* App Int/Reset Ctrl Reg. */
|
||||
#define CPU_REG_SCB_SCR (*((CPU_REG32 *)(0xE000ED10))) /* System Ctrl Reg. */
|
||||
#define CPU_REG_SCB_CCR (*((CPU_REG32 *)(0xE000ED14))) /* Cfg Ctrl Reg. */
|
||||
#define CPU_REG_SCB_SHPRI1 (*((CPU_REG32 *)(0xE000ED18))) /* System Handlers 4 to 7 Prio. */
|
||||
#define CPU_REG_SCB_SHPRI2 (*((CPU_REG32 *)(0xE000ED1C))) /* System Handlers 8 to 11 Prio. */
|
||||
#define CPU_REG_SCB_SHPRI3 (*((CPU_REG32 *)(0xE000ED20))) /* System Handlers 12 to 15 Prio. */
|
||||
#define CPU_REG_SCB_SHCSR (*((CPU_REG32 *)(0xE000ED24))) /* System Handler Ctrl & State Reg. */
|
||||
#define CPU_REG_SCB_CFSR (*((CPU_REG32 *)(0xE000ED28))) /* Configurable Fault Status Reg. */
|
||||
#define CPU_REG_SCB_HFSR (*((CPU_REG32 *)(0xE000ED2C))) /* Hard Fault Status Reg. */
|
||||
#define CPU_REG_SCB_DFSR (*((CPU_REG32 *)(0xE000ED30))) /* Debug Fault Status Reg. */
|
||||
#define CPU_REG_SCB_MMFAR (*((CPU_REG32 *)(0xE000ED34))) /* Mem Manage Addr Reg. */
|
||||
#define CPU_REG_SCB_BFAR (*((CPU_REG32 *)(0xE000ED38))) /* Bus Fault Addr Reg. */
|
||||
#define CPU_REG_SCB_AFSR (*((CPU_REG32 *)(0xE000ED3C))) /* Aux Fault Status Reg. */
|
||||
#define CPU_REG_SCB_CPACR (*((CPU_REG32 *)(0xE000ED88))) /* Coprocessor Access Control Reg. */
|
||||
|
||||
/* ----- SCB REG FOR FP EXTENSION ----- */
|
||||
#define CPU_REG_SCB_FPCCR (*((CPU_REG32 *)(0xE000EF34))) /* Floating-Point Context Control Reg. */
|
||||
#define CPU_REG_SCB_FPCAR (*((CPU_REG32 *)(0xE000EF38))) /* Floating-Point Context Address Reg. */
|
||||
#define CPU_REG_SCB_FPDSCR (*((CPU_REG32 *)(0xE000EF3C))) /* FP Default Status Control Reg. */
|
||||
|
||||
/* ---------- CPUID REGISTERS --------- */
|
||||
#define CPU_REG_CPUID_PFR0 (*((CPU_REG32 *)(0xE000ED40))) /* Processor Feature Reg 0. */
|
||||
#define CPU_REG_CPUID_PFR1 (*((CPU_REG32 *)(0xE000ED44))) /* Processor Feature Reg 1. */
|
||||
#define CPU_REG_CPUID_DFR0 (*((CPU_REG32 *)(0xE000ED48))) /* Debug Feature Reg 0. */
|
||||
#define CPU_REG_CPUID_AFR0 (*((CPU_REG32 *)(0xE000ED4C))) /* Aux Feature Reg 0. */
|
||||
#define CPU_REG_CPUID_MMFR0 (*((CPU_REG32 *)(0xE000ED50))) /* Memory Model Feature Reg 0. */
|
||||
#define CPU_REG_CPUID_MMFR1 (*((CPU_REG32 *)(0xE000ED54))) /* Memory Model Feature Reg 1. */
|
||||
#define CPU_REG_CPUID_MMFR2 (*((CPU_REG32 *)(0xE000ED58))) /* Memory Model Feature Reg 2. */
|
||||
#define CPU_REG_CPUID_MMFR3 (*((CPU_REG32 *)(0xE000ED5C))) /* Memory Model Feature Reg 3. */
|
||||
#define CPU_REG_CPUID_ISAFR0 (*((CPU_REG32 *)(0xE000ED60))) /* ISA Feature Reg 0. */
|
||||
#define CPU_REG_CPUID_ISAFR1 (*((CPU_REG32 *)(0xE000ED64))) /* ISA Feature Reg 1. */
|
||||
#define CPU_REG_CPUID_ISAFR2 (*((CPU_REG32 *)(0xE000ED68))) /* ISA Feature Reg 2. */
|
||||
#define CPU_REG_CPUID_ISAFR3 (*((CPU_REG32 *)(0xE000ED6C))) /* ISA Feature Reg 3. */
|
||||
#define CPU_REG_CPUID_ISAFR4 (*((CPU_REG32 *)(0xE000ED70))) /* ISA Feature Reg 4. */
|
||||
|
||||
/* ----------- MPU REGISTERS ---------- */
|
||||
#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_RNR (*((CPU_REG32 *)(0xE000ED98))) /* MPU Region Nbr Reg. */
|
||||
#define CPU_REG_MPU_RBAR (*((CPU_REG32 *)(0xE000ED9C))) /* MPU Region Base Addr Reg. */
|
||||
#define CPU_REG_MPU_RASR (*((CPU_REG32 *)(0xE000EDA0))) /* MPU Region Attrib & Size Reg. */
|
||||
|
||||
/* ----- REGISTERS NOT IN THE SCB ----- */
|
||||
#define CPU_REG_ICTR (*((CPU_REG32 *)(0xE000E004))) /* Int Ctrl'er Type Reg. */
|
||||
#define CPU_REG_DHCSR (*((CPU_REG32 *)(0xE000EDF0))) /* Debug Halting Ctrl & Status Reg. */
|
||||
#define CPU_REG_DCRSR (*((CPU_REG32 *)(0xE000EDF4))) /* Debug Core Reg Selector Reg. */
|
||||
#define CPU_REG_DCRDR (*((CPU_REG32 *)(0xE000EDF8))) /* Debug Core Reg Data Reg. */
|
||||
#define CPU_REG_DEMCR (*((CPU_REG32 *)(0xE000EDFC))) /* Debug Except & Monitor Ctrl Reg. */
|
||||
#define CPU_REG_STIR (*((CPU_REG32 *)(0xE000EF00))) /* Software Trigger Int Reg. */
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* CPU REGISTER BITS
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
/* ---------- SYSTICK CTRL & STATUS REG BITS ---------- */
|
||||
#define CPU_REG_SYST_CSR_COUNTFLAG 0x00010000
|
||||
#define CPU_REG_SYST_CSR_CLKSOURCE 0x00000004
|
||||
#define CPU_REG_SYST_CSR_TICKINT 0x00000002
|
||||
#define CPU_REG_SYST_CSR_ENABLE 0x00000001
|
||||
|
||||
/* -------- SYSTICK CALIBRATION VALUE REG BITS -------- */
|
||||
#define CPU_REG_SYST_CALIB_NOREF 0x80000000
|
||||
#define CPU_REG_SYST_CALIB_SKEW 0x40000000
|
||||
|
||||
/* -------------- INT CTRL STATE REG BITS ------------- */
|
||||
#define CPU_REG_SCB_ICSR_NMIPENDSET 0x80000000
|
||||
#define CPU_REG_SCB_ICSR_PENDSVSET 0x10000000
|
||||
#define CPU_REG_SCB_ICSR_PENDSVCLR 0x08000000
|
||||
#define CPU_REG_SCB_ICSR_PENDSTSET 0x04000000
|
||||
#define CPU_REG_SCB_ICSR_PENDSTCLR 0x02000000
|
||||
#define CPU_REG_SCB_ICSR_ISRPREEMPT 0x00800000
|
||||
#define CPU_REG_SCB_ICSR_ISRPENDING 0x00400000
|
||||
#define CPU_REG_SCB_ICSR_RETTOBASE 0x00000800
|
||||
|
||||
/* ------------- VECT TBL OFFSET REG BITS ------------- */
|
||||
#define CPU_REG_SCB_VTOR_TBLBASE 0x20000000
|
||||
|
||||
/* ------------ APP INT/RESET CTRL REG BITS ----------- */
|
||||
#define CPU_REG_SCB_AIRCR_ENDIANNESS 0x00008000
|
||||
#define CPU_REG_SCB_AIRCR_SYSRESETREQ 0x00000004
|
||||
#define CPU_REG_SCB_AIRCR_VECTCLRACTIVE 0x00000002
|
||||
#define CPU_REG_SCB_AIRCR_VECTRESET 0x00000001
|
||||
|
||||
/* --------------- SYSTEM CTRL REG BITS --------------- */
|
||||
#define CPU_REG_SCB_SCR_SEVONPEND 0x00000010
|
||||
#define CPU_REG_SCB_SCR_SLEEPDEEP 0x00000004
|
||||
#define CPU_REG_SCB_SCR_SLEEPONEXIT 0x00000002
|
||||
|
||||
/* ----------------- CFG CTRL REG BITS ---------------- */
|
||||
#define CPU_REG_SCB_CCR_STKALIGN 0x00000200
|
||||
#define CPU_REG_SCB_CCR_BFHFNMIGN 0x00000100
|
||||
#define CPU_REG_SCB_CCR_DIV_0_TRP 0x00000010
|
||||
#define CPU_REG_SCB_CCR_UNALIGN_TRP 0x00000008
|
||||
#define CPU_REG_SCB_CCR_USERSETMPEND 0x00000002
|
||||
#define CPU_REG_SCB_CCR_NONBASETHRDENA 0x00000001
|
||||
|
||||
/* ------- SYSTEM HANDLER CTRL & STATE REG BITS ------- */
|
||||
#define CPU_REG_SCB_SHCSR_USGFAULTENA 0x00040000
|
||||
#define CPU_REG_SCB_SHCSR_BUSFAULTENA 0x00020000
|
||||
#define CPU_REG_SCB_SHCSR_MEMFAULTENA 0x00010000
|
||||
#define CPU_REG_SCB_SHCSR_SVCALLPENDED 0x00008000
|
||||
#define CPU_REG_SCB_SHCSR_BUSFAULTPENDED 0x00004000
|
||||
#define CPU_REG_SCB_SHCSR_MEMFAULTPENDED 0x00002000
|
||||
#define CPU_REG_SCB_SHCSR_USGFAULTPENDED 0x00001000
|
||||
#define CPU_REG_SCB_SHCSR_SYSTICKACT 0x00000800
|
||||
#define CPU_REG_SCB_SHCSR_PENDSVACT 0x00000400
|
||||
#define CPU_REG_SCB_SHCSR_MONITORACT 0x00000100
|
||||
#define CPU_REG_SCB_SHCSR_SVCALLACT 0x00000080
|
||||
#define CPU_REG_SCB_SHCSR_USGFAULTACT 0x00000008
|
||||
#define CPU_REG_SCB_SHCSR_BUSFAULTACT 0x00000002
|
||||
#define CPU_REG_SCB_SHCSR_MEMFAULTACT 0x00000001
|
||||
|
||||
/* -------- CONFIGURABLE FAULT STATUS REG BITS -------- */
|
||||
#define CPU_REG_SCB_CFSR_DIVBYZERO 0x02000000
|
||||
#define CPU_REG_SCB_CFSR_UNALIGNED 0x01000000
|
||||
#define CPU_REG_SCB_CFSR_NOCP 0x00080000
|
||||
#define CPU_REG_SCB_CFSR_INVPC 0x00040000
|
||||
#define CPU_REG_SCB_CFSR_INVSTATE 0x00020000
|
||||
#define CPU_REG_SCB_CFSR_UNDEFINSTR 0x00010000
|
||||
#define CPU_REG_SCB_CFSR_BFARVALID 0x00008000
|
||||
#define CPU_REG_SCB_CFSR_STKERR 0x00001000
|
||||
#define CPU_REG_SCB_CFSR_UNSTKERR 0x00000800
|
||||
#define CPU_REG_SCB_CFSR_IMPRECISERR 0x00000400
|
||||
#define CPU_REG_SCB_CFSR_PRECISERR 0x00000200
|
||||
#define CPU_REG_SCB_CFSR_IBUSERR 0x00000100
|
||||
#define CPU_REG_SCB_CFSR_MMARVALID 0x00000080
|
||||
#define CPU_REG_SCB_CFSR_MSTKERR 0x00000010
|
||||
#define CPU_REG_SCB_CFSR_MUNSTKERR 0x00000008
|
||||
#define CPU_REG_SCB_CFSR_DACCVIOL 0x00000002
|
||||
#define CPU_REG_SCB_CFSR_IACCVIOL 0x00000001
|
||||
|
||||
/* ------------ HARD FAULT STATUS REG BITS ------------ */
|
||||
#define CPU_REG_SCB_HFSR_DEBUGEVT 0x80000000
|
||||
#define CPU_REG_SCB_HFSR_FORCED 0x40000000
|
||||
#define CPU_REG_SCB_HFSR_VECTTBL 0x00000002
|
||||
|
||||
/* ------------ DEBUG FAULT STATUS REG BITS ----------- */
|
||||
#define CPU_REG_SCB_DFSR_EXTERNAL 0x00000010
|
||||
#define CPU_REG_SCB_DFSR_VCATCH 0x00000008
|
||||
#define CPU_REG_SCB_DFSR_DWTTRAP 0x00000004
|
||||
#define CPU_REG_SCB_DFSR_BKPT 0x00000002
|
||||
#define CPU_REG_SCB_DFSR_HALTED 0x00000001
|
||||
|
||||
/* -------- COPROCESSOR ACCESS CONTROL REG BITS ------- */
|
||||
#define CPU_REG_SCB_CPACR_CP10_FULL_ACCESS 0x00300000
|
||||
#define CPU_REG_SCB_CPACR_CP11_FULL_ACCESS 0x00C00000
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* CPU REGISTER MASK
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#define CPU_MSK_SCB_ICSR_VECT_ACTIVE 0x000001FF
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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
|
||||
|
||||
|
||||
|
||||
|
||||
#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
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* MODULE END
|
||||
*
|
||||
* Note(s) : (1) See 'cpu.h MODULE'.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* End of CPU module include. */
|
||||
|
||||
|
|
@ -0,0 +1,295 @@
|
|||
@********************************************************************************************************
|
||||
@ uC/CPU
|
||||
@ CPU CONFIGURATION & PORT LAYER
|
||||
@
|
||||
@ Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com
|
||||
@
|
||||
@ SPDX-License-Identifier: APACHE-2.0
|
||||
@
|
||||
@ This software is subject to an open source license and is distributed by
|
||||
@ Silicon Laboratories Inc. pursuant to the terms of the Apache License,
|
||||
@ Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
|
||||
@
|
||||
@********************************************************************************************************
|
||||
|
||||
@********************************************************************************************************
|
||||
@
|
||||
@ CPU PORT FILE
|
||||
@
|
||||
@ ARMv7-M
|
||||
@ GNU C Compiler
|
||||
@
|
||||
@ Filename : cpu_a.s
|
||||
@ Version : v1.32.00
|
||||
@********************************************************************************************************
|
||||
@ Note(s) : This port supports the ARM Cortex-M3, Cortex-M4 and Cortex-M7 architectures.
|
||||
@********************************************************************************************************
|
||||
|
||||
|
||||
@********************************************************************************************************
|
||||
@ 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
|
||||
.syntax unified
|
||||
|
||||
|
||||
@********************************************************************************************************
|
||||
@ 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 Kernel aware interrupts by preserving the state of BASEPRI. Generally speaking,
|
||||
@ the state of the BASEPRI interrupt exception processing is stored in the local variable
|
||||
@ 'cpu_sr' & Kernel Aware interrupts are then disabled ('cpu_sr' is allocated in all functions
|
||||
@ that need to disable Kernel aware interrupts). The previous BASEPRI interrupt state is restored
|
||||
@ by copying 'cpu_sr' into the BASEPRI register.
|
||||
@
|
||||
@ Prototypes : CPU_SR CPU_SR_Save (CPU_SR new_basepri);
|
||||
@ 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); */
|
||||
@ :
|
||||
@ }
|
||||
@
|
||||
@ (2) Increasing priority using a write to BASEPRI does not take effect immediately.
|
||||
@ (a) IMPLICATION This erratum means that the instruction after an MSR to boost BASEPRI
|
||||
@ might incorrectly be preempted by an insufficient high priority exception.
|
||||
@
|
||||
@ (b) WORKAROUND The MSR to boost BASEPRI can be replaced by the following code sequence:
|
||||
@
|
||||
@ CPSID i
|
||||
@ MSR to BASEPRI
|
||||
@ DSB
|
||||
@ ISB
|
||||
@ CPSIE i
|
||||
@********************************************************************************************************
|
||||
|
||||
.thumb_func
|
||||
CPU_SR_Save:
|
||||
CPSID I @ Cortex-M7 errata notice. See Note #2
|
||||
PUSH {R1}
|
||||
MRS R1, BASEPRI
|
||||
MSR BASEPRI, R0
|
||||
DSB
|
||||
ISB
|
||||
MOV R0, R1
|
||||
POP {R1}
|
||||
CPSIE I
|
||||
BX LR
|
||||
|
||||
|
||||
.thumb_func
|
||||
CPU_SR_Restore:
|
||||
CPSID I @ Cortex-M7 errata notice. See Note #2
|
||||
MSR BASEPRI, R0
|
||||
DSB
|
||||
ISB
|
||||
CPSIE I
|
||||
BX LR
|
||||
|
||||
|
||||
@********************************************************************************************************
|
||||
@ 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
|
||||
|
||||
|
||||
@********************************************************************************************************
|
||||
@ 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'.
|
||||
@
|
||||
@ 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
|
||||
|
||||
|
||||
@********************************************************************************************************
|
||||
@ 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'.
|
||||
@
|
||||
@ 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 trailing zeros
|
||||
BX LR
|
||||
|
||||
|
||||
@********************************************************************************************************
|
||||
@ 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).
|
||||
@
|
||||
@ 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
|
||||
|
||||
|
||||
@********************************************************************************************************
|
||||
@ CPU ASSEMBLY PORT FILE END
|
||||
@********************************************************************************************************
|
||||
|
||||
.end
|
||||
|
||||
|
|
@ -0,0 +1,772 @@
|
|||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/CPU
|
||||
* CPU CONFIGURATION & PORT LAYER
|
||||
*
|
||||
* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com
|
||||
*
|
||||
* SPDX-License-Identifier: APACHE-2.0
|
||||
*
|
||||
* This software is subject to an open source license and is distributed by
|
||||
* Silicon Laboratories Inc. pursuant to the terms of the Apache License,
|
||||
* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
*
|
||||
* CPU PORT FILE
|
||||
*
|
||||
* ARMv7-M
|
||||
*
|
||||
* Filename : cpu_c.c
|
||||
* Version : v1.32.00
|
||||
*********************************************************************************************************
|
||||
* Note(s) : This port supports the ARM Cortex-M3, Cortex-M4 and Cortex-M7 architectures.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* INCLUDE FILES
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#define MICRIUM_SOURCE
|
||||
#include <cpu.h>
|
||||
#include <cpu_core.h>
|
||||
|
||||
#include <lib_def.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* LOCAL DEFINES
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#define CPU_INT_SRC_POS_MAX ((((CPU_REG_ICTR & 0xF) + 1) * 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
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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.
|
||||
*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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.
|
||||
*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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.
|
||||
*
|
||||
* 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, Cortex-M4, and Cortex-M7 table position is 256. A particular
|
||||
* Cortex-M 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.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void CPU_IntSrcDis (CPU_INT08U pos)
|
||||
{
|
||||
CPU_INT08U group;
|
||||
CPU_INT16U 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_SCB_SHCSR &= ~CPU_REG_SCB_SHCSR_MEMFAULTENA;
|
||||
CPU_CRITICAL_EXIT();
|
||||
break;
|
||||
|
||||
case CPU_INT_BUSFAULT: /* Bus fault. */
|
||||
CPU_CRITICAL_ENTER();
|
||||
CPU_REG_SCB_SHCSR &= ~CPU_REG_SCB_SHCSR_BUSFAULTENA;
|
||||
CPU_CRITICAL_EXIT();
|
||||
break;
|
||||
|
||||
case CPU_INT_USAGEFAULT: /* Usage fault. */
|
||||
CPU_CRITICAL_ENTER();
|
||||
CPU_REG_SCB_SHCSR &= ~CPU_REG_SCB_SHCSR_USGFAULTENA;
|
||||
CPU_CRITICAL_EXIT();
|
||||
break;
|
||||
|
||||
case CPU_INT_SYSTICK: /* SysTick. */
|
||||
CPU_CRITICAL_ENTER();
|
||||
CPU_REG_SYST_CSR &= ~CPU_REG_SYST_CSR_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_ICER(group) = DEF_BIT(nbr); /* Disable interrupt. */
|
||||
CPU_CRITICAL_EXIT();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* CPU_IntSrcEn()
|
||||
*
|
||||
* Description : Enable an interrupt source.
|
||||
*
|
||||
* Argument(s) : pos Position of interrupt vector in interrupt table (see 'CPU_IntSrcDis()').
|
||||
*
|
||||
* Return(s) : none.
|
||||
*
|
||||
* 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_INT16U 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_SCB_SHCSR |= CPU_REG_SCB_SHCSR_MEMFAULTENA;
|
||||
CPU_CRITICAL_EXIT();
|
||||
break;
|
||||
|
||||
case CPU_INT_BUSFAULT: /* Bus fault. */
|
||||
CPU_CRITICAL_ENTER();
|
||||
CPU_REG_SCB_SHCSR |= CPU_REG_SCB_SHCSR_BUSFAULTENA;
|
||||
CPU_CRITICAL_EXIT();
|
||||
break;
|
||||
|
||||
case CPU_INT_USAGEFAULT: /* Usage fault. */
|
||||
CPU_CRITICAL_ENTER();
|
||||
CPU_REG_SCB_SHCSR |= CPU_REG_SCB_SHCSR_USGFAULTENA;
|
||||
CPU_CRITICAL_EXIT();
|
||||
break;
|
||||
|
||||
case CPU_INT_SYSTICK: /* SysTick. */
|
||||
CPU_CRITICAL_ENTER();
|
||||
CPU_REG_SYST_CSR |= CPU_REG_SYST_CSR_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_ISER(group) = DEF_BIT(nbr); /* Enable interrupt. */
|
||||
CPU_CRITICAL_EXIT();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* CPU_IntSrcPendClr()
|
||||
*
|
||||
* Description : Clear a pending interrupt.
|
||||
*
|
||||
* Argument(s) : pos Position of interrupt vector in interrupt table (see 'CPU_IntSrcDis()').
|
||||
*
|
||||
* Return(s) : none.
|
||||
*
|
||||
* 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_INT16U 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_ICPR(group) = DEF_BIT(nbr); /* Clear Pending interrupt. */
|
||||
CPU_CRITICAL_EXIT();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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.
|
||||
*
|
||||
* type Kernel/Non-Kernel aware priority type.
|
||||
* CPU_INT_KA Kernel Aware interrupt request. See Note #4
|
||||
* CPU_INT_NKA Non-Kernel Aware interrupt request. See Note #5
|
||||
*
|
||||
* Return(s) : none.
|
||||
*
|
||||
* 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'.
|
||||
*
|
||||
* (4) A Kernel Aware ISR can make OS service calls in its handler (Mutex, Flags, etc.).
|
||||
* It follows the template below:
|
||||
*
|
||||
* static void KA_ISR_Handler (void)
|
||||
* {
|
||||
* CPU_SR_ALLOC();
|
||||
*
|
||||
* CPU_CRITICAL_ENTER();
|
||||
* OSIntEnter(); Tell OS we are starting an ISR
|
||||
* CPU_CRITICAL_EXIT();
|
||||
*
|
||||
* --------------- HANDLER YOUR ISR HERE ---------------
|
||||
*
|
||||
* OSIntExit(); Tell OS we are leaving the ISR
|
||||
* }
|
||||
*
|
||||
* (5) A Non-Kernel Aware ISR must never make OS service calls. It follows the template below:
|
||||
*
|
||||
* static void NKA_ISR_Handler (void)
|
||||
* {
|
||||
* --------------- HANDLER YOUR ISR HERE ---------------
|
||||
* }
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void CPU_IntSrcPrioSet (CPU_INT08U pos,
|
||||
CPU_INT08U prio,
|
||||
CPU_INT08U type)
|
||||
{
|
||||
CPU_INT08U group;
|
||||
CPU_INT08U nbr;
|
||||
CPU_INT16U pos_max;
|
||||
CPU_INT32U temp;
|
||||
CPU_INT32U prio_offset;
|
||||
CPU_SR_ALLOC();
|
||||
|
||||
|
||||
prio_offset = (prio << (DEF_OCTET_NBR_BITS - CPU_CFG_NVIC_PRIO_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_SCB_SHPRI1;
|
||||
temp &= ~((CPU_INT32U)DEF_OCTET_MASK << (0 * DEF_OCTET_NBR_BITS));
|
||||
temp |= ((CPU_INT32U)prio_offset << (0 * DEF_OCTET_NBR_BITS));
|
||||
CPU_REG_SCB_SHPRI1 = temp;
|
||||
CPU_CRITICAL_EXIT();
|
||||
break;
|
||||
|
||||
case CPU_INT_BUSFAULT: /* Bus fault. */
|
||||
CPU_CRITICAL_ENTER();
|
||||
temp = CPU_REG_SCB_SHPRI1;
|
||||
temp &= ~((CPU_INT32U)DEF_OCTET_MASK << (1 * DEF_OCTET_NBR_BITS));
|
||||
temp |= ((CPU_INT32U)prio_offset << (1 * DEF_OCTET_NBR_BITS));
|
||||
CPU_REG_SCB_SHPRI1 = temp;
|
||||
CPU_CRITICAL_EXIT();
|
||||
break;
|
||||
|
||||
case CPU_INT_USAGEFAULT: /* Usage fault. */
|
||||
CPU_CRITICAL_ENTER();
|
||||
temp = CPU_REG_SCB_SHPRI1;
|
||||
temp &= ~((CPU_INT32U)DEF_OCTET_MASK << (2 * DEF_OCTET_NBR_BITS));
|
||||
temp |= ((CPU_INT32U)prio_offset << (2 * DEF_OCTET_NBR_BITS));
|
||||
CPU_REG_SCB_SHPRI1 = temp;
|
||||
CPU_CRITICAL_EXIT();
|
||||
break;
|
||||
|
||||
case CPU_INT_SVCALL: /* SVCall. */
|
||||
CPU_CRITICAL_ENTER();
|
||||
temp = CPU_REG_SCB_SHPRI2;
|
||||
temp &= ~((CPU_INT32U)DEF_OCTET_MASK << (3 * DEF_OCTET_NBR_BITS));
|
||||
temp |= ((CPU_INT32U)prio_offset << (3 * DEF_OCTET_NBR_BITS));
|
||||
CPU_REG_SCB_SHPRI2 = temp;
|
||||
CPU_CRITICAL_EXIT();
|
||||
break;
|
||||
|
||||
case CPU_INT_DBGMON: /* Debug monitor. */
|
||||
CPU_CRITICAL_ENTER();
|
||||
temp = CPU_REG_SCB_SHPRI3;
|
||||
temp &= ~((CPU_INT32U)DEF_OCTET_MASK << (0 * DEF_OCTET_NBR_BITS));
|
||||
temp |= ((CPU_INT32U)prio_offset << (0 * DEF_OCTET_NBR_BITS));
|
||||
CPU_REG_SCB_SHPRI3 = temp;
|
||||
CPU_CRITICAL_EXIT();
|
||||
break;
|
||||
|
||||
case CPU_INT_PENDSV: /* PendSV. */
|
||||
CPU_CRITICAL_ENTER();
|
||||
temp = CPU_REG_SCB_SHPRI3;
|
||||
temp &= ~((CPU_INT32U)DEF_OCTET_MASK << (2 * DEF_OCTET_NBR_BITS));
|
||||
temp |= ((CPU_INT32U)prio_offset << (2 * DEF_OCTET_NBR_BITS));
|
||||
CPU_REG_SCB_SHPRI3 = temp;
|
||||
CPU_CRITICAL_EXIT();
|
||||
break;
|
||||
|
||||
case CPU_INT_SYSTICK: /* SysTick. */
|
||||
CPU_CRITICAL_ENTER();
|
||||
temp = CPU_REG_SCB_SHPRI3;
|
||||
temp &= ~((CPU_INT32U)DEF_OCTET_MASK << (3 * DEF_OCTET_NBR_BITS));
|
||||
temp |= ((CPU_INT32U)prio_offset << (3 * DEF_OCTET_NBR_BITS));
|
||||
CPU_REG_SCB_SHPRI3 = temp;
|
||||
CPU_CRITICAL_EXIT();
|
||||
break;
|
||||
|
||||
|
||||
/* ---------------- EXTERNAL INTERRUPT ---------------- */
|
||||
default:
|
||||
pos_max = CPU_INT_SRC_POS_MAX;
|
||||
if (pos < pos_max) { /* See Note #3. */
|
||||
|
||||
if (type == CPU_INT_NKA) { /* Check if NKA priority goes beyond KA boundary */
|
||||
if (prio >= CPU_CFG_KA_IPL_BOUNDARY) { /* Priority must be < CPU_CFG_KA_IPL_BOUNDARY */
|
||||
CPU_SW_Exception();
|
||||
}
|
||||
|
||||
} else { /* Check if KA priority is less than KA boundary */
|
||||
if (prio < CPU_CFG_KA_IPL_BOUNDARY) { /* Priority must be >= CPU_CFG_KA_IPL_BOUNDARY */
|
||||
CPU_SW_Exception();
|
||||
}
|
||||
}
|
||||
|
||||
group = (pos - 16) / 4;
|
||||
nbr = (pos - 16) % 4;
|
||||
|
||||
CPU_CRITICAL_ENTER();
|
||||
temp = CPU_REG_NVIC_IPR(group);
|
||||
temp &= ~((CPU_INT32U)DEF_OCTET_MASK << (nbr * DEF_OCTET_NBR_BITS));
|
||||
temp |= ((CPU_INT32U)prio_offset << (nbr * DEF_OCTET_NBR_BITS));
|
||||
CPU_REG_NVIC_IPR(group) = temp; /* Set interrupt priority. */
|
||||
CPU_CRITICAL_EXIT();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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.
|
||||
*
|
||||
* 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_INT16U pos_max;
|
||||
CPU_INT16S prio;
|
||||
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_SCB_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_SCB_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_SCB_SHPRI1;
|
||||
prio = (temp >> (2 * DEF_OCTET_NBR_BITS)) & DEF_OCTET_MASK;
|
||||
CPU_CRITICAL_EXIT();
|
||||
break;
|
||||
|
||||
case CPU_INT_SVCALL: /* SVCall. */
|
||||
CPU_CRITICAL_ENTER();
|
||||
temp = CPU_REG_SCB_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_SCB_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_SCB_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_SCB_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_IPR(group); /* Read group interrupt priority. */
|
||||
CPU_CRITICAL_EXIT();
|
||||
|
||||
prio = (temp >> (nbr * DEF_OCTET_NBR_BITS)) & DEF_OCTET_MASK;
|
||||
} else {
|
||||
prio = DEF_INT_16S_MIN_VAL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (prio != DEF_INT_16S_MIN_VAL) {
|
||||
prio = (prio >> (DEF_OCTET_NBR_BITS - CPU_CFG_NVIC_PRIO_BITS));
|
||||
}
|
||||
|
||||
return (prio);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,254 @@
|
|||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/CPU
|
||||
* CPU CONFIGURATION & PORT LAYER
|
||||
*
|
||||
* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com
|
||||
*
|
||||
* SPDX-License-Identifier: APACHE-2.0
|
||||
*
|
||||
* This software is subject to an open source license and is distributed by
|
||||
* Silicon Laboratories Inc. pursuant to the terms of the Apache License,
|
||||
* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
*
|
||||
* CPU CONFIGURATION FILE
|
||||
*
|
||||
* TEMPLATE
|
||||
*
|
||||
* Filename : cpu_cfg.h
|
||||
* Version : v1.32.00
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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_DISABLED
|
||||
/* DEF_DISABLED CPU host name DISABLED */
|
||||
/* DEF_ENABLED CPU host name ENABLED */
|
||||
|
||||
/* Configure CPU host name ASCII string size ... */
|
||||
#define CPU_CFG_NAME_SIZE 16 /* ... (see Note #2). */
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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_DISABLED
|
||||
#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'.
|
||||
*
|
||||
* (b) Configure CPU_CFG_INT_DIS_MEAS_OVRHD_NBR with the number of times to measure &
|
||||
* average the interrupts disabled time measurements overhead.
|
||||
*
|
||||
* 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). */
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#if 0 /* Configure CPU count leading zeros bits ... */
|
||||
#define CPU_CFG_LEAD_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1a). */
|
||||
#endif
|
||||
|
||||
#if 0 /* Configure CPU count trailing zeros bits ... */
|
||||
#define CPU_CFG_TRAIL_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1b). */
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* CPU ENDIAN TYPE OVERRIDE
|
||||
*
|
||||
* Note(s) : (1) Configure CPU_CFG_ENDIAN_TYPE to override the default CPU endian type defined in cpu.h.
|
||||
*
|
||||
* (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)
|
||||
*
|
||||
* (2) Defining CPU_CFG_ENDIAN_TYPE here is only valid for supported bi-endian architectures.
|
||||
* See 'cpu.h CPU WORD CONFIGURATION Note #3' for details
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#if 0
|
||||
#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_BIG /* Defines CPU data word-memory order (see Note #2). */
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* CACHE MANAGEMENT
|
||||
*
|
||||
* Note(s) : (1) Configure CPU_CFG_CACHE_MGMT_EN to enable the cache management API.
|
||||
*
|
||||
* (2) This option only enables the cache management functions.
|
||||
* It does not enable any hardware caches, which should be configured in startup code.
|
||||
* Caches must be configured and enabled by the time CPU_Init() is called.
|
||||
*
|
||||
* (3) This option is usually required for device drivers which use a DMA engine to transmit
|
||||
* buffers that are located in cached memory.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#define CPU_CFG_CACHE_MGMT_EN DEF_DISABLED /* Defines CPU data word-memory order (see Note #1). */
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* KERNEL AWARE IPL BOUNDARY
|
||||
*
|
||||
* Note(s) : (1) Determines the IPL level that establishes the boundary for ISRs that are kernel-aware and
|
||||
* those that are not. All ISRs at this level or lower are kernel-aware.
|
||||
*
|
||||
* (2) ARMv7-M: Since the port is using BASEPRI to separate kernel vs non-kernel aware ISR, please
|
||||
* make sure your external interrupt priorities are set accordingly. For example, if
|
||||
* CPU_CFG_KA_IPL_BOUNDARY is set to 4 then external interrupt priorities 4-15 will be kernel
|
||||
* aware while priorities 0-3 will be use as non-kernel aware.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#define CPU_CFG_KA_IPL_BOUNDARY 4u
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* ARM CORTEX-M
|
||||
*
|
||||
* Note(s) : (1) Determines the interrupt programmable priority levels. This is normally specified in the
|
||||
* Microcontroller reference manual. 4-bits gives us 16 programmable priority levels.
|
||||
*
|
||||
* Example 1 Example 2
|
||||
* NVIC_IPRx NVIC_IPRx
|
||||
* 7 0 7 0
|
||||
* +------------------+ +------------------+
|
||||
* | PRIO | | PRIO |
|
||||
* +------------------+ +------------------+
|
||||
*
|
||||
* Bits[7:4] Priority mask bits Bits[7:6] Priority mask bits
|
||||
* Bits[3:0] Reserved Bits[5:0] Reserved
|
||||
*
|
||||
* Example 1: CPU_CFG_NVIC_PRIO_BITS should be set to 4 due to the processor
|
||||
* implementing only bits[7:4].
|
||||
*
|
||||
* Example 2: CPU_CFG_NVIC_PRIO_BITS should be set to 2 due to the processor
|
||||
* implementing only bits[7:6].
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
#if 0
|
||||
#define CPU_CFG_NVIC_PRIO_BITS 4u
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* MODULE END
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#endif /* End of CPU cfg module include. */
|
||||
|
||||
|
|
@ -0,0 +1,202 @@
|
|||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
ATTENTION ALL USERS OF THIS REPOSITORY:
|
||||
|
||||
The original work found in this repository is provided by Silicon Labs under the
|
||||
Apache License, Version 2.0.
|
||||
|
||||
Any third party may contribute derivative works to the original work in which
|
||||
modifications are clearly identified as being licensed under:
|
||||
|
||||
(1) the Apache License, Version 2.0 or a compatible open source license; or
|
||||
(2) under a proprietary license with a copy of such license deposited.
|
||||
|
||||
All posted derivative works must clearly identify which license choice has been
|
||||
elected.
|
||||
|
||||
No such posted derivative works will be considered to be a “Contribution” under
|
||||
the Apache License, Version 2.0.
|
||||
|
||||
SILICON LABS MAKES NO WARRANTY WITH RESPECT TO ALL POSTED THIRD PARTY CONTENT
|
||||
AND DISCLAIMS ALL OTHER WARRANTIES OR LIABILITIES, INCLUDING ALL WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE, OWNERSHIP,
|
||||
NON-INFRINGEMENT, AND NON-MISAPPROPRIATION.
|
||||
|
||||
In the event a derivative work is desired to be submitted to Silicon Labs as a
|
||||
“Contribution” under the Apache License, Version 2.0, a “Contributor” must give
|
||||
written email notice to micrium@weston-embedded.com. Unless an email response in
|
||||
the affirmative to accept the derivative work as a “Contribution”, such email
|
||||
submission should be considered to have not been incorporated into the original
|
||||
work.
|
||||
|
|
@ -0,0 +1,535 @@
|
|||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/CPU
|
||||
* CPU CONFIGURATION & PORT LAYER
|
||||
*
|
||||
* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com
|
||||
*
|
||||
* SPDX-License-Identifier: APACHE-2.0
|
||||
*
|
||||
* This software is subject to an open source license and is distributed by
|
||||
* Silicon Laboratories Inc. pursuant to the terms of the Apache License,
|
||||
* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
*
|
||||
* CPU PORT FILE
|
||||
*
|
||||
* Linux i86pc & amd64
|
||||
* GNU Toolchain
|
||||
*
|
||||
* Filename : cpu.h
|
||||
* Version : v1.32.00
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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 <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include <cpu_def.h>
|
||||
#include <cpu_cfg.h> /* See Note #3. */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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 uint8_t CPU_BOOLEAN; /* 8-bit boolean or logical */
|
||||
typedef uint8_t CPU_INT08U; /* 8-bit unsigned integer */
|
||||
typedef int8_t CPU_INT08S; /* 8-bit signed integer */
|
||||
typedef uint16_t CPU_INT16U; /* 16-bit unsigned integer */
|
||||
typedef int16_t CPU_INT16S; /* 16-bit signed integer */
|
||||
typedef uint32_t CPU_INT32U; /* 32-bit unsigned integer */
|
||||
typedef int32_t CPU_INT32S; /* 32-bit signed integer */
|
||||
typedef uint64_t CPU_INT64U; /* 64-bit unsigned integer */
|
||||
typedef int64_t 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. */
|
||||
|
||||
|
||||
|
||||
typedef struct CPU_Interrupt CPU_INTERRUPT;
|
||||
|
||||
struct CPU_Interrupt {
|
||||
void (*ISR_Fnct)(void);
|
||||
CPU_INT08U Prio;
|
||||
CPU_BOOLEAN En;
|
||||
CPU_CHAR *NamePtr;
|
||||
CPU_BOOLEAN TraceEn;
|
||||
};
|
||||
|
||||
|
||||
typedef struct CPU_Tmr_Interrupt CPU_TMR_INTERRUPT;
|
||||
|
||||
struct CPU_Tmr_Interrupt {
|
||||
CPU_INTERRUPT Interrupt;
|
||||
CPU_BOOLEAN OneShot;
|
||||
CPU_INT32U PeriodSec;
|
||||
CPU_INT32U PeriodMuSec;
|
||||
};
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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) : */
|
||||
#ifdef _LP64
|
||||
#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_64 /* Defines CPU address word size (in octets). */
|
||||
#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_64 /* Defines CPU data word size (in octets). */
|
||||
#else
|
||||
#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). */
|
||||
#endif
|
||||
|
||||
|
||||
#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */
|
||||
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */
|
||||
#else
|
||||
#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_BIG /* Defines CPU data word-memory order (see Note #2). */
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* CONFIGURE CPU ADDRESS & DATA TYPES
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
/* CPU address type based on address bus size. */
|
||||
#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_64)
|
||||
typedef CPU_INT64U CPU_ADDR;
|
||||
#elif (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_64)
|
||||
typedef CPU_INT64U CPU_DATA;
|
||||
#elif (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 size_t 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
|
||||
*
|
||||
* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for
|
||||
* cpu stacks.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */
|
||||
|
||||
#define CPU_CFG_STK_ALIGN_BYTES (sizeof(CPU_ALIGN)) /* Defines CPU stack alignment in bytes. (see Note #2). */
|
||||
|
||||
typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */
|
||||
typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
/* Configure CPU critical method (see Note #1) : */
|
||||
#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_INT_DIS_EN
|
||||
|
||||
typedef CPU_BOOLEAN 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_IntDis(); } while (0) /* Disable interrupts. */
|
||||
#define CPU_INT_EN() do { CPU_IntEn(); } while (0) /* Enable interrupts. */
|
||||
|
||||
|
||||
#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
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* MEMORY BARRIERS CONFIGURATION
|
||||
*
|
||||
* Note(s) : (1) (a) Configure memory barriers if required by the architecture.
|
||||
*
|
||||
* CPU_MB Full memory barrier.
|
||||
* CPU_RMB Read (Loads) memory barrier.
|
||||
* CPU_WMB Write (Stores) memory barrier.
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#define CPU_MB()
|
||||
#define CPU_RMB()
|
||||
#define CPU_WMB()
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* FUNCTION PROTOTYPES
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void CPU_IntInit (void);
|
||||
void CPU_IntEnd (void);
|
||||
|
||||
void CPU_IntDis (void);
|
||||
void CPU_IntEn (void);
|
||||
|
||||
void CPU_ISR_End (void);
|
||||
|
||||
void CPU_TmrInterruptCreate (CPU_TMR_INTERRUPT *p_tmr_interrupt);
|
||||
|
||||
void CPU_InterruptTrigger (CPU_INTERRUPT *p_interrupt);
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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
|
||||
|
||||
|
||||
|
||||
|
||||
#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
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* MODULE END
|
||||
*
|
||||
* Note(s) : (1) See 'cpu.h MODULE'.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* End of CPU module include. */
|
||||
|
||||
|
|
@ -0,0 +1,885 @@
|
|||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/CPU
|
||||
* CPU CONFIGURATION & PORT LAYER
|
||||
*
|
||||
* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com
|
||||
*
|
||||
* SPDX-License-Identifier: APACHE-2.0
|
||||
*
|
||||
* This software is subject to an open source license and is distributed by
|
||||
* Silicon Laboratories Inc. pursuant to the terms of the Apache License,
|
||||
* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
*
|
||||
* CPU PORT FILE
|
||||
*
|
||||
* POSIX
|
||||
*
|
||||
* Filename : cpu_c.c
|
||||
* Version : v1.32.00
|
||||
*********************************************************************************************************
|
||||
* Notes : (1) Requires a Single UNIX Specification, Version 3 compliant operating environment.
|
||||
* On Linux _XOPEN_SOURCE must be defined to at least 600, generally by passing the
|
||||
* -D_XOPEN_SOURCE=600 command line option to GCC.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* INCLUDE FILES
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <pthread.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/resource.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <cpu.h>
|
||||
#include <cpu_core.h>
|
||||
|
||||
#if (CPU_CFG_TS_TMR_EN == DEF_ENABLED)
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* LOCAL FUNCTION PROTOTYPES
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* LOCAL GLOBAL VARIABLES
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* LOCAL DEFINES
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#define CPU_TMR_INT_TASK_PRIO sched_get_priority_max(SCHED_RR) /* Tmr interrupt task priority. */
|
||||
#define CPU_IRQ_SIG (SIGURG) /* IRQ trigger signal. */
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* LOCAL DATA TYPES
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
typedef struct cpu_interrupt_node CPU_INTERRUPT_NODE;
|
||||
|
||||
struct cpu_interrupt_node {
|
||||
CPU_INTERRUPT *InterruptPtr;
|
||||
CPU_INTERRUPT_NODE *NextPtr;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* LOCAL VARIABLES
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
static pthread_mutex_t CPU_InterruptQueueMutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_mutexattr_t CPU_InterruptQueueMutexAttr;
|
||||
|
||||
static CPU_INTERRUPT_NODE *CPU_InterruptPendListHeadPtr;
|
||||
static CPU_INTERRUPT_NODE *CPU_InterruptRunningListHeadPtr;
|
||||
|
||||
static sigset_t CPU_IRQ_SigMask;
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* LOCAL FUNCTION PROTOTYPES
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#if (_POSIX_C_SOURCE < 199309L)
|
||||
#error "_POSIX_C_SOURCE is required to be at least 199309L"
|
||||
#endif
|
||||
|
||||
static void CPU_IRQ_Handler (int sig);
|
||||
|
||||
static void CPU_InterruptTriggerInternal (CPU_INTERRUPT *p_interrupt);
|
||||
|
||||
static void CPU_InterruptQueue (CPU_INTERRUPT *p_isr);
|
||||
|
||||
static void *CPU_TmrInterruptTask (void *p_arg);
|
||||
|
||||
static void CPU_ISR_Sched (void);
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* CPU_IntInit()
|
||||
*
|
||||
* Description : This function initializes the critical section.
|
||||
*
|
||||
* Argument(s) : none.
|
||||
*
|
||||
* Return(s) : none.
|
||||
*
|
||||
* Note(s) : 1) CPU_IntInit() MUST be called prior to use any of the CPU_IntEn(), and CPU_IntDis()
|
||||
* functions.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void CPU_IntInit (void)
|
||||
{
|
||||
struct sigaction on_isr_trigger_sig_action;
|
||||
int res;
|
||||
|
||||
|
||||
CPU_InterruptPendListHeadPtr = DEF_NULL;
|
||||
CPU_InterruptRunningListHeadPtr = DEF_NULL;
|
||||
|
||||
sigemptyset(&CPU_IRQ_SigMask);
|
||||
sigaddset(&CPU_IRQ_SigMask, CPU_IRQ_SIG);;
|
||||
|
||||
pthread_mutexattr_init(&CPU_InterruptQueueMutexAttr);
|
||||
pthread_mutexattr_settype(&CPU_InterruptQueueMutexAttr, PTHREAD_MUTEX_RECURSIVE);
|
||||
pthread_mutex_init(&CPU_InterruptQueueMutex, &CPU_InterruptQueueMutexAttr);
|
||||
|
||||
/* Register interrupt trigger signal handler. */
|
||||
memset(&on_isr_trigger_sig_action, 0, sizeof(on_isr_trigger_sig_action));
|
||||
res = sigemptyset(&on_isr_trigger_sig_action.sa_mask);
|
||||
if (res != 0u) {
|
||||
raise(SIGABRT);
|
||||
}
|
||||
on_isr_trigger_sig_action.sa_flags = SA_NODEFER;
|
||||
on_isr_trigger_sig_action.sa_handler = CPU_IRQ_Handler;
|
||||
res = sigaction(CPU_IRQ_SIG, &on_isr_trigger_sig_action, NULL);
|
||||
if (res != 0u) {
|
||||
raise(SIGABRT);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* CPU_IntDis()
|
||||
*
|
||||
* Description : This function disables interrupts for critical sections of code.
|
||||
*
|
||||
* Argument(s) : none.
|
||||
*
|
||||
* Return(s) : none.
|
||||
*
|
||||
* Note(s) : none.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void CPU_IntDis (void)
|
||||
{
|
||||
pthread_sigmask(SIG_BLOCK, &CPU_IRQ_SigMask, DEF_NULL);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* CPU_IntEn()
|
||||
*
|
||||
* Description : This function enables interrupts after critical sections of code.
|
||||
*
|
||||
* Argument(s) : none.
|
||||
*
|
||||
* Return(s) : none.
|
||||
*
|
||||
* Note(s) : none.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void CPU_IntEn (void)
|
||||
{
|
||||
pthread_sigmask(SIG_UNBLOCK, &CPU_IRQ_SigMask, DEF_NULL);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* CPU_ISR_End()
|
||||
*
|
||||
* Description : Ends an ISR.
|
||||
*
|
||||
* Argument(s) : none.
|
||||
*
|
||||
* Return(s) : none.
|
||||
*
|
||||
* Note(s) : (1) This function MUST be called at the end of an ISR.
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void CPU_ISR_End (void)
|
||||
{
|
||||
CPU_INTERRUPT_NODE *p_interrupt_node;
|
||||
|
||||
|
||||
CPU_INT_DIS();
|
||||
pthread_mutex_lock(&CPU_InterruptQueueMutex);
|
||||
if (CPU_InterruptRunningListHeadPtr == DEF_NULL) {
|
||||
raise(SIGABRT);
|
||||
}
|
||||
p_interrupt_node = CPU_InterruptRunningListHeadPtr;
|
||||
CPU_InterruptRunningListHeadPtr = CPU_InterruptRunningListHeadPtr->NextPtr;
|
||||
pthread_mutex_unlock(&CPU_InterruptQueueMutex);
|
||||
CPU_INT_EN();
|
||||
|
||||
free(p_interrupt_node);
|
||||
|
||||
CPU_ISR_Sched();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* CPU_TmrInterruptCreate()
|
||||
*
|
||||
* Description : Simulated hardware timer instance creation.
|
||||
*
|
||||
* Argument(s) : p_tmr_interrupt Pointer to a timer interrupt descriptor.
|
||||
*
|
||||
* Return(s) : none.
|
||||
*
|
||||
* Note(s) : none.
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void CPU_TmrInterruptCreate (CPU_TMR_INTERRUPT *p_tmr_interrupt)
|
||||
{
|
||||
pthread_t thread;
|
||||
pthread_attr_t attr;
|
||||
struct sched_param param;
|
||||
int res;
|
||||
|
||||
|
||||
res = pthread_attr_init(&attr);
|
||||
if (res != 0u) {
|
||||
raise(SIGABRT);
|
||||
}
|
||||
res = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
|
||||
if (res != 0u) {
|
||||
raise(SIGABRT);
|
||||
}
|
||||
param.__sched_priority = CPU_TMR_INT_TASK_PRIO;
|
||||
pthread_attr_setschedpolicy(&attr, SCHED_RR);
|
||||
if (res != 0u) {
|
||||
raise(SIGABRT);
|
||||
}
|
||||
pthread_attr_setschedparam(&attr, ¶m);
|
||||
if (res != 0u) {
|
||||
raise(SIGABRT);
|
||||
}
|
||||
|
||||
pthread_create(&thread, &attr, CPU_TmrInterruptTask, p_tmr_interrupt);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* CPU_InterruptTrigger()
|
||||
*
|
||||
* Description : Queue an interrupt and send the IRQ signal.
|
||||
*
|
||||
* Argument(s) : p_interrupt Interrupt to be queued.
|
||||
*
|
||||
* Return(s) : none.
|
||||
*
|
||||
* Note(s) : none.
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void CPU_InterruptTrigger (CPU_INTERRUPT *p_interrupt)
|
||||
{
|
||||
CPU_INT_DIS();
|
||||
CPU_InterruptTriggerInternal(p_interrupt); /* Signal are now blocked: rest of Trigger is internal. */
|
||||
CPU_INT_EN();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* CPU_Printf()
|
||||
*
|
||||
* Description: This function is analog of printf.
|
||||
*
|
||||
* Arguments : p_str Pointer to format string output.
|
||||
*
|
||||
* Returns : Number of characters written.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#ifdef CPU_CFG_MSG_TRACE_EN
|
||||
static int CPU_Printf (char *p_str, ...)
|
||||
{
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* CPU_CntLeadZeros()
|
||||
*
|
||||
* Description : Count the number of contiguous, most-significant, leading zero bits in a data value.
|
||||
*
|
||||
* Argument(s) : val Data value to count leading zero bits.
|
||||
*
|
||||
* Return(s) : Number of contiguous, most-significant, leading zero bits in 'val', if NO error(s).
|
||||
*
|
||||
* 0, otherwise.
|
||||
*
|
||||
* Note(s) : (1) (a) Supports the following data value sizes :
|
||||
*
|
||||
* (1) 8-bits
|
||||
* (2) 16-bits
|
||||
* (3) 32-bits
|
||||
*
|
||||
* See also 'cpu_def.h CPU WORD CONFIGURATION Note #1'.
|
||||
*
|
||||
* (b) (1) For 8-bit values :
|
||||
*
|
||||
* b07 b06 b05 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 3
|
||||
* 0 0 0 0 1 x x x 4
|
||||
* 0 0 0 0 0 1 x x 5
|
||||
* 0 0 0 0 0 0 1 x 6
|
||||
* 0 0 0 0 0 0 0 1 7
|
||||
* 0 0 0 0 0 0 0 0 8
|
||||
*
|
||||
*
|
||||
* (2) For 16-bit values :
|
||||
*
|
||||
* b15 b14 b13 ... 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 11
|
||||
* 0 0 0 0 1 x x x 12
|
||||
* 0 0 0 0 0 1 x x 13
|
||||
* 0 0 0 0 0 0 1 x 14
|
||||
* 0 0 0 0 0 0 0 1 15
|
||||
* 0 0 0 0 0 0 0 0 16
|
||||
*
|
||||
*
|
||||
* (3) 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
|
||||
*
|
||||
*
|
||||
* See also 'CPU COUNT LEAD ZEROs LOOKUP TABLE Note #1'.
|
||||
*
|
||||
* (2) MUST be implemented in cpu_a.asm if and only if CPU_CFG_LEAD_ZEROS_ASM_PRESENT
|
||||
* is #define'd in 'cpu_cfg.h' or 'cpu.h'.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#ifdef CPU_CFG_LEAD_ZEROS_ASM_PRESENT
|
||||
CPU_DATA CPU_CntLeadZeros (CPU_DATA val)
|
||||
{
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* CPU_CntTrailZeros()
|
||||
*
|
||||
* Description : Count the number of contiguous, least-significant, trailing zero bits in a data value.
|
||||
*
|
||||
* Argument(s) : val Data value to count trailing zero bits.
|
||||
*
|
||||
* Return(s) : Number of contiguous, least-significant, trailing zero bits in 'val'.
|
||||
*
|
||||
* Note(s) : (1) (a) Supports the following data value sizes :
|
||||
*
|
||||
* (1) 8-bits
|
||||
* (2) 16-bits
|
||||
* (3) 32-bits
|
||||
* (4) 64-bits
|
||||
*
|
||||
* See also 'cpu_def.h CPU WORD CONFIGURATION Note #1'.
|
||||
*
|
||||
* (b) (1) For 8-bit values :
|
||||
*
|
||||
* b07 b06 b05 b04 b03 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 3
|
||||
* x x x 1 0 0 0 0 4
|
||||
* x x 1 0 0 0 0 0 5
|
||||
* x 1 0 0 0 0 0 0 6
|
||||
* 1 0 0 0 0 0 0 0 7
|
||||
* 0 0 0 0 0 0 0 0 8
|
||||
*
|
||||
*
|
||||
* (2) For 16-bit values :
|
||||
*
|
||||
* b15 b14 b13 b12 b11 ... 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 11
|
||||
* x x x 1 0 0 0 0 12
|
||||
* x x 1 0 0 0 0 0 13
|
||||
* x 1 0 0 0 0 0 0 14
|
||||
* 1 0 0 0 0 0 0 0 15
|
||||
* 0 0 0 0 0 0 0 0 16
|
||||
*
|
||||
*
|
||||
* (3) 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
|
||||
*
|
||||
*
|
||||
* (4) For 64-bit values :
|
||||
*
|
||||
* b63 b62 b61 b60 b59 ... 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 59
|
||||
* x x x 1 0 0 0 0 60
|
||||
* x x 1 0 0 0 0 0 61
|
||||
* x 1 0 0 0 0 0 0 62
|
||||
* 1 0 0 0 0 0 0 0 63
|
||||
* 0 0 0 0 0 0 0 0 64
|
||||
*
|
||||
* (2) For non-zero values, the returned number of contiguous, least-significant, trailing
|
||||
* zero bits is also equivalent to the bit position of the least-significant set bit.
|
||||
*
|
||||
* (3) 'val' SHOULD be validated for non-'0' PRIOR to all other counting zero calculations :
|
||||
*
|
||||
* (a) CPU_CntTrailZeros()'s final conditional statement calculates 'val's number of
|
||||
* trailing zeros based on its return data size, 'CPU_CFG_DATA_SIZE', & 'val's
|
||||
* calculated number of lead zeros ONLY if the initial 'val' is non-'0' :
|
||||
*
|
||||
* if (val != 0u) {
|
||||
* nbr_trail_zeros = ((CPU_CFG_DATA_SIZE * DEF_OCTET_NBR_BITS) - 1u) - nbr_lead_zeros;
|
||||
* } else {
|
||||
* nbr_trail_zeros = nbr_lead_zeros;
|
||||
* }
|
||||
*
|
||||
* Therefore, initially validating all non-'0' values avoids having to conditionally
|
||||
* execute the final statement.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#ifdef CPU_CFG_TRAIL_ZEROS_ASM_PRESENT
|
||||
CPU_DATA CPU_CntTrailZeros (CPU_DATA val)
|
||||
{
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* CPU_TS_TmrInit()
|
||||
*
|
||||
* Description : Initialize & start CPU timestamp timer.
|
||||
*
|
||||
* Argument(s) : none.
|
||||
*
|
||||
* Return(s) : none.
|
||||
*
|
||||
* 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)
|
||||
{
|
||||
struct timespec res;
|
||||
|
||||
|
||||
res.tv_sec = 0;
|
||||
res.tv_nsec = 0;
|
||||
|
||||
(void)clock_settime(CLOCK_MONOTONIC, &res);
|
||||
|
||||
CPU_TS_TmrFreqSet(1000000000);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* CPU_TS_TmrRd()
|
||||
*
|
||||
* Description : Get current CPU timestamp timer count value.
|
||||
*
|
||||
* Argument(s) : none.
|
||||
*
|
||||
* Return(s) : Timestamp timer count (see Notes #2a & #2b).
|
||||
*
|
||||
* 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)
|
||||
{
|
||||
struct timespec res;
|
||||
CPU_TS_TMR ts;
|
||||
|
||||
|
||||
(void)clock_gettime(CLOCK_MONOTONIC, &res);
|
||||
|
||||
ts = (CPU_TS_TMR)(res.tv_sec * 1000000000u + res.tv_nsec);
|
||||
|
||||
return (ts);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
*********************************************************************************************************
|
||||
* LOCAL FUNCTIONS
|
||||
*********************************************************************************************************
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* CPU_IRQ_Handler()
|
||||
*
|
||||
* Description : CPU_IRQ_SIG signal handler.
|
||||
*
|
||||
* Argument(s) : sig Signal that triggered the handler (unused).
|
||||
*
|
||||
* Return(s) : none.
|
||||
*
|
||||
* Note(s) : none.
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
static void CPU_IRQ_Handler (int sig)
|
||||
{
|
||||
(void)&sig;
|
||||
CPU_ISR_Sched();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* CPU_InterruptTriggerInternal()
|
||||
*
|
||||
* Description : Queue an interrupt and send the IRQ signal.
|
||||
*
|
||||
* Argument(s) : p_interrupt Interrupt to be queued.
|
||||
*
|
||||
* Return(s) : none.
|
||||
*
|
||||
* Note(s) : (1) The Interrupt signal must be blocked before calling this function.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void CPU_InterruptTriggerInternal (CPU_INTERRUPT *p_interrupt)
|
||||
{
|
||||
if (p_interrupt->En == DEF_NO) {
|
||||
return;
|
||||
}
|
||||
|
||||
CPU_InterruptQueue(p_interrupt);
|
||||
|
||||
kill(getpid(), CPU_IRQ_SIG);
|
||||
|
||||
if (p_interrupt->TraceEn == DEF_ENABLED) {
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
printf("@ %lu:%06lu", ts.tv_sec, ts.tv_nsec / 1000u);
|
||||
printf(" %s interrupt fired.\r\n", p_interrupt->NamePtr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* CPU_InterruptQueue()
|
||||
*
|
||||
* Description : Queue an interrupt.
|
||||
*
|
||||
* Argument(s) : p_interrupt Pointer to the interrupt to be queued.
|
||||
*
|
||||
* Return(s) : none.
|
||||
*
|
||||
* Note(s) : (1) The signals for this thread are already blocked during this function call.
|
||||
*
|
||||
* (2) Since the signal are already blocked, it is safe to lock and release the mutex.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
static void CPU_InterruptQueue (CPU_INTERRUPT *p_interrupt)
|
||||
{
|
||||
CPU_INTERRUPT_NODE *p_cur_interrupt_node;
|
||||
CPU_INTERRUPT_NODE *p_prev_interrupt_node;
|
||||
CPU_INTERRUPT_NODE *p_interrupt_node;
|
||||
|
||||
|
||||
p_interrupt_node = (CPU_INTERRUPT_NODE *)malloc(sizeof(CPU_INTERRUPT_NODE));
|
||||
p_interrupt_node->InterruptPtr = p_interrupt;
|
||||
|
||||
pthread_mutex_lock(&CPU_InterruptQueueMutex);
|
||||
if ((CPU_InterruptPendListHeadPtr == DEF_NULL) ||
|
||||
(CPU_InterruptPendListHeadPtr->InterruptPtr->Prio < p_interrupt->Prio)) {
|
||||
p_interrupt_node->NextPtr = CPU_InterruptPendListHeadPtr;
|
||||
CPU_InterruptPendListHeadPtr = p_interrupt_node;
|
||||
} else {
|
||||
p_cur_interrupt_node = CPU_InterruptPendListHeadPtr;
|
||||
while ((p_cur_interrupt_node != DEF_NULL) &&
|
||||
(p_cur_interrupt_node->InterruptPtr->Prio >= p_interrupt->Prio)) {
|
||||
p_prev_interrupt_node = p_cur_interrupt_node;
|
||||
p_cur_interrupt_node = p_cur_interrupt_node->NextPtr;
|
||||
}
|
||||
p_prev_interrupt_node->NextPtr = p_interrupt_node;
|
||||
p_interrupt_node->NextPtr = p_cur_interrupt_node;
|
||||
}
|
||||
pthread_mutex_unlock(&CPU_InterruptQueueMutex);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* CPU_ISR_Sched()
|
||||
*
|
||||
* Description : Schedules the highest priority pending interrupt.
|
||||
*
|
||||
* Argument(s) : none.
|
||||
*
|
||||
* Return(s) : none.
|
||||
*
|
||||
* Note(s) : none.
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
static void CPU_ISR_Sched (void)
|
||||
{
|
||||
CPU_INTERRUPT_NODE *p_isr_node;
|
||||
|
||||
|
||||
CPU_INT_DIS();
|
||||
pthread_mutex_lock(&CPU_InterruptQueueMutex);
|
||||
p_isr_node = CPU_InterruptPendListHeadPtr;
|
||||
if ((p_isr_node != DEF_NULL) &&
|
||||
((CPU_InterruptRunningListHeadPtr == DEF_NULL) ||
|
||||
(p_isr_node->InterruptPtr->Prio > CPU_InterruptRunningListHeadPtr->InterruptPtr->Prio))) {
|
||||
CPU_InterruptPendListHeadPtr = CPU_InterruptPendListHeadPtr->NextPtr;
|
||||
p_isr_node->NextPtr = CPU_InterruptRunningListHeadPtr;
|
||||
CPU_InterruptRunningListHeadPtr = p_isr_node;
|
||||
pthread_mutex_unlock(&CPU_InterruptQueueMutex);
|
||||
CPU_INT_EN();
|
||||
p_isr_node->InterruptPtr->ISR_Fnct();
|
||||
} else {
|
||||
pthread_mutex_unlock(&CPU_InterruptQueueMutex);
|
||||
CPU_INT_EN();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* CPU_TmrInterruptTask()
|
||||
*
|
||||
* Description : Hardware timer interrupt simulation function.
|
||||
*
|
||||
* Argument(s) : p_arg Pointer to a timer interrupt descriptor.
|
||||
*
|
||||
* Return(s) : none.
|
||||
*
|
||||
* Note(s) : none.
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
static void *CPU_TmrInterruptTask (void *p_arg) {
|
||||
|
||||
struct timespec tspec, tspec_rem;
|
||||
int res;
|
||||
CPU_TMR_INTERRUPT *p_tmr_int;
|
||||
CPU_BOOLEAN one_shot;
|
||||
|
||||
CPU_INT_DIS();
|
||||
|
||||
p_tmr_int = (CPU_TMR_INTERRUPT *)p_arg;
|
||||
|
||||
tspec.tv_nsec = p_tmr_int->PeriodMuSec * 1000u;
|
||||
tspec.tv_sec = p_tmr_int->PeriodSec;
|
||||
|
||||
one_shot = p_tmr_int->OneShot;
|
||||
|
||||
do {
|
||||
tspec_rem = tspec;
|
||||
do {res = clock_nanosleep(CLOCK_MONOTONIC, 0u, &tspec_rem, &tspec_rem); } while (res == EINTR);
|
||||
if (res != 0u) { raise(SIGABRT); }
|
||||
CPU_InterruptTriggerInternal(&(p_tmr_int->Interrupt)); /* See Note #2. */
|
||||
} while (one_shot != DEF_YES);
|
||||
|
||||
pthread_exit(DEF_NULL);
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/CPU
|
||||
* CPU CONFIGURATION & PORT LAYER
|
||||
*
|
||||
* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com
|
||||
*
|
||||
* SPDX-License-Identifier: APACHE-2.0
|
||||
*
|
||||
* This software is subject to an open source license and is distributed by
|
||||
* Silicon Laboratories Inc. pursuant to the terms of the Apache License,
|
||||
* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
*
|
||||
* CACHE CPU MODULE
|
||||
*
|
||||
* Filename : cpu_cache.h
|
||||
* Version : v1.32.00
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* MODULE
|
||||
*
|
||||
* Note(s) : (1) This cache CPU header file is protected from multiple pre-processor inclusion through use of
|
||||
* the cache CPU module present pre-processor macro definition.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef CPU_CACHE_MODULE_PRESENT /* See Note #1. */
|
||||
#define CPU_CACHE_MODULE_PRESENT
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* EXTERNS
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#ifdef CPU_CACHE_MODULE
|
||||
#define CPU_CACHE_EXT
|
||||
#else
|
||||
#define CPU_CACHE_EXT extern
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* INCLUDE FILES
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#include <cpu.h>
|
||||
#include <lib_def.h>
|
||||
#include <cpu_cfg.h>
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* CACHE CONFIGURATION
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef CPU_CFG_CACHE_MGMT_EN
|
||||
#define CPU_CFG_CACHE_MGMT_EN DEF_DISABLED
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* CACHE OPERATIONS DEFINES
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#if (CPU_CFG_CACHE_MGMT_EN == DEF_ENABLED)
|
||||
#ifndef CPU_DCACHE_RANGE_FLUSH
|
||||
#define CPU_DCACHE_RANGE_FLUSH(addr_start, len) CPU_DCache_RangeFlush(addr_start, len)
|
||||
#endif /* CPU_DCACHE_RANGE_FLUSH */
|
||||
#else
|
||||
#define CPU_DCACHE_RANGE_FLUSH(addr_start, len)
|
||||
#endif /* CPU_CFG_CACHE_MGMT_EN) */
|
||||
|
||||
|
||||
#if (CPU_CFG_CACHE_MGMT_EN == DEF_ENABLED)
|
||||
#ifndef CPU_DCACHE_RANGE_INV
|
||||
#define CPU_DCACHE_RANGE_INV(addr_start, len) CPU_DCache_RangeInv(addr_start, len)
|
||||
#endif /* CPU_DCACHE_RANGE_INV */
|
||||
#else
|
||||
#define CPU_DCACHE_RANGE_INV(addr_start, len)
|
||||
#endif /* CPU_CFG_CACHE_MGMT_EN) */
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* FUNCTION PROTOTYPES
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#if (CPU_CFG_CACHE_MGMT_EN == DEF_ENABLED)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void CPU_Cache_Init (void);
|
||||
|
||||
void CPU_DCache_RangeFlush(void *addr_start,
|
||||
CPU_ADDR len);
|
||||
|
||||
void CPU_DCache_RangeInv (void *addr_start,
|
||||
CPU_ADDR len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CPU_CFG_CACHE_MGMT_EN */
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* MODULE END
|
||||
*
|
||||
* Note(s) : (1) See 'cpu_core.h MODULE'.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#endif /* End of CPU core module include. */
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,212 @@
|
|||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/CPU
|
||||
* CPU CONFIGURATION & PORT LAYER
|
||||
*
|
||||
* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com
|
||||
*
|
||||
* SPDX-License-Identifier: APACHE-2.0
|
||||
*
|
||||
* This software is subject to an open source license and is distributed by
|
||||
* Silicon Laboratories Inc. pursuant to the terms of the Apache License,
|
||||
* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
*
|
||||
* CPU CONFIGURATION DEFINES
|
||||
*
|
||||
* Filename : cpu_def.h
|
||||
* Version : v1.32.00
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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 13200u /* See Note #1. */
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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 1u /* 8-bit word size (in octets). */
|
||||
#define CPU_WORD_SIZE_16 2u /* 16-bit word size (in octets). */
|
||||
#define CPU_WORD_SIZE_32 4u /* 32-bit word size (in octets). */
|
||||
#define CPU_WORD_SIZE_64 8u /* 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). */
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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). */
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* MODULE END
|
||||
*
|
||||
* Note(s) : (1) See 'cpu_def.h MODULE'.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#endif /* End of CPU def module include. */
|
||||
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
# uC/CPU
|
||||
|
||||
Designed with Micriμm’s renowned quality, scalability and reliability, the purpose of μC/ CPU is to provide a clean, organized ANSI C implementation of each processor’s/ compiler’s hardware-dependent.
|
||||
|
||||
## For the complete documentation, visit https://doc.micrium.com/display/ucos/
|
||||
|
|
@ -0,0 +1,163 @@
|
|||
/*
|
||||
*********************************************************************************************************
|
||||
* EXAMPLE CODE
|
||||
*
|
||||
* This file is provided as an example on how to use Micrium products.
|
||||
*
|
||||
* Please feel free to use any application code labeled as 'EXAMPLE CODE' in
|
||||
* your application products. Example code may be used as is, in whole or in
|
||||
* part, or may be used as a reference only. This file can be modified as
|
||||
* required to meet the end-product requirements.
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
*
|
||||
* CUSTOM LIBRARY CONFIGURATION FILE
|
||||
*
|
||||
* TEMPLATE
|
||||
*
|
||||
* Filename : lib_cfg.h
|
||||
* Version : V1.39.00
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* MODULE
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef LIB_CFG_MODULE_PRESENT
|
||||
#define LIB_CFG_MODULE_PRESENT
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
*********************************************************************************************************
|
||||
* 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.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
/* External argument check. */
|
||||
/* Indicates if arguments received from any port ... */
|
||||
/* ... interface provided by the developer or ... */
|
||||
/* ... application are checked/validated. */
|
||||
#define LIB_MEM_CFG_ARG_CHK_EXT_EN DEF_DISABLED
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* MEMORY LIBRARY ASSEMBLY OPTIMIZATION CONFIGURATION
|
||||
*
|
||||
* Note(s) : (1) Configure LIB_MEM_CFG_OPTIMIZE_ASM_EN to enable/disable assembly-optimized memory function(s).
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
/* Assembly-optimized function(s). */
|
||||
/* Enable/disable assembly-optimized memory ... */
|
||||
/* ... function(s). [see Note #1] */
|
||||
#define LIB_MEM_CFG_OPTIMIZE_ASM_EN DEF_DISABLED
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* MEMORY ALLOCATION CONFIGURATION
|
||||
*
|
||||
* Note(s) : (1) Configure LIB_MEM_CFG_DBG_INFO_EN to enable/disable memory allocation usage tracking
|
||||
* that associates a name with each segment or dynamic pool allocated.
|
||||
*
|
||||
* (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 'lib_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 'lib_cfg.h'
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
/* Allocation debugging information. */
|
||||
/* Enable/disable allocation of debug information ... */
|
||||
/* ... associated to each memory allocation. */
|
||||
#define LIB_MEM_CFG_DBG_INFO_EN DEF_DISABLED
|
||||
|
||||
|
||||
/* Heap memory size (in bytes). */
|
||||
/* Configure the desired size of the heap memory. ... */
|
||||
/* ... Set to 0 to disable heap allocation features. */
|
||||
#define LIB_MEM_CFG_HEAP_SIZE 1024u
|
||||
|
||||
|
||||
/* Heap memory padding alignment (in bytes). */
|
||||
/* Configure the desired size of padding alignment ... */
|
||||
/* ... of each buffer allocated from the heap. */
|
||||
#define LIB_MEM_CFG_HEAP_PADDING_ALIGN LIB_MEM_PADDING_ALIGN_NONE
|
||||
|
||||
#if 0 /* Remove this to have heap alloc at specified addr. */
|
||||
#define LIB_MEM_CFG_HEAP_BASE_ADDR 0x00000000 /* Configure heap memory base address (see Note #2b). */
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
*********************************************************************************************************
|
||||
* 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'.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
/* Floating point feature(s). */
|
||||
/* Enable/disable floating point to string functions. */
|
||||
#define LIB_STR_CFG_FP_EN DEF_DISABLED
|
||||
|
||||
|
||||
/* Floating point number of significant digits. */
|
||||
/* Configure the maximum number of significant ... */
|
||||
/* ... digits to calculate &/or display for ... */
|
||||
/* ... floating point string function(s). */
|
||||
#define LIB_STR_CFG_FP_MAX_NBR_DIG_SIG LIB_STR_FP_MAX_NBR_DIG_SIG_DFLT
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* MODULE END
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#endif /* End of lib cfg module include. */
|
||||
|
||||
|
|
@ -0,0 +1,202 @@
|
|||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
ATTENTION ALL USERS OF THIS REPOSITORY:
|
||||
|
||||
The original work found in this repository is provided by Silicon Labs under the
|
||||
Apache License, Version 2.0.
|
||||
|
||||
Any third party may contribute derivative works to the original work in which
|
||||
modifications are clearly identified as being licensed under:
|
||||
|
||||
(1) the Apache License, Version 2.0 or a compatible open source license; or
|
||||
(2) under a proprietary license with a copy of such license deposited.
|
||||
|
||||
All posted derivative works must clearly identify which license choice has been
|
||||
elected.
|
||||
|
||||
No such posted derivative works will be considered to be a “Contribution” under
|
||||
the Apache License, Version 2.0.
|
||||
|
||||
SILICON LABS MAKES NO WARRANTY WITH RESPECT TO ALL POSTED THIRD PARTY CONTENT
|
||||
AND DISCLAIMS ALL OTHER WARRANTIES OR LIABILITIES, INCLUDING ALL WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE, OWNERSHIP,
|
||||
NON-INFRINGEMENT, AND NON-MISAPPROPRIATION.
|
||||
|
||||
In the event a derivative work is desired to be submitted to Silicon Labs as a
|
||||
“Contribution” under the Apache License, Version 2.0, a “Contributor” must give
|
||||
written email notice to micrium@weston-embedded.com. Unless an email response in
|
||||
the affirmative to accept the derivative work as a “Contribution”, such email
|
||||
submission should be considered to have not been incorporated into the original
|
||||
work.
|
||||
|
|
@ -0,0 +1,298 @@
|
|||
@********************************************************************************************************
|
||||
@ uC/LIB
|
||||
@ Custom Library Modules
|
||||
@
|
||||
@ Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com
|
||||
@
|
||||
@ SPDX-License-Identifier: APACHE-2.0
|
||||
@
|
||||
@ This software is subject to an open source license and is distributed by
|
||||
@ Silicon Laboratories Inc. pursuant to the terms of the Apache License,
|
||||
@ Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
|
||||
@
|
||||
@********************************************************************************************************
|
||||
|
||||
|
||||
@********************************************************************************************************
|
||||
@
|
||||
@ STANDARD MEMORY OPERATIONS
|
||||
@
|
||||
@ ARM-Cortex-M3
|
||||
@ GNU Compiler
|
||||
@
|
||||
@ Filename : lib_mem_a.s
|
||||
@ Version : V1.39.00
|
||||
@********************************************************************************************************
|
||||
@ 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
|
||||
|
||||
@********************************************************************************************************
|
||||
@ 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
|
||||
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
|
|
@ -0,0 +1,298 @@
|
|||
@********************************************************************************************************
|
||||
@ uC/LIB
|
||||
@ Custom Library Modules
|
||||
@
|
||||
@ Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com
|
||||
@
|
||||
@ SPDX-License-Identifier: APACHE-2.0
|
||||
@
|
||||
@ This software is subject to an open source license and is distributed by
|
||||
@ Silicon Laboratories Inc. pursuant to the terms of the Apache License,
|
||||
@ Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
|
||||
@
|
||||
@********************************************************************************************************
|
||||
|
||||
|
||||
@********************************************************************************************************
|
||||
@
|
||||
@ STANDARD MEMORY OPERATIONS
|
||||
@
|
||||
@ ARM-Cortex-M4
|
||||
@ GNU Compiler
|
||||
@
|
||||
@ Filename : lib_mem_a.s
|
||||
@ Version : V1.39.00
|
||||
@********************************************************************************************************
|
||||
@ 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
|
||||
|
||||
@********************************************************************************************************
|
||||
@ 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
|
||||
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
|
|
@ -0,0 +1,644 @@
|
|||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/LIB
|
||||
* Custom Library Modules
|
||||
*
|
||||
* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com
|
||||
*
|
||||
* SPDX-License-Identifier: APACHE-2.0
|
||||
*
|
||||
* This software is subject to an open source license and is distributed by
|
||||
* Silicon Laboratories Inc. pursuant to the terms of the Apache License,
|
||||
* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
*
|
||||
* ASCII CHARACTER OPERATIONS
|
||||
*
|
||||
* Filename : lib_ascii.c
|
||||
* Version : V1.39.00
|
||||
*********************************************************************************************************
|
||||
* 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>
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* LOCAL DEFINES
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* LOCAL CONSTANTS
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* LOCAL DATA TYPES
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* LOCAL TABLES
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* LOCAL GLOBAL VARIABLES
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* LOCAL FUNCTION PROTOTYPES
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* LOCAL CONFIGURATION ERRORS
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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);
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,833 @@
|
|||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/LIB
|
||||
* Custom Library Modules
|
||||
*
|
||||
* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com
|
||||
*
|
||||
* SPDX-License-Identifier: APACHE-2.0
|
||||
*
|
||||
* This software is subject to an open source license and is distributed by
|
||||
* Silicon Laboratories Inc. pursuant to the terms of the Apache License,
|
||||
* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
*
|
||||
* ASCII CHARACTER OPERATIONS
|
||||
*
|
||||
* Filename : lib_ascii.h
|
||||
* Version : V1.39.00
|
||||
*********************************************************************************************************
|
||||
* 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
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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
|
||||
|
||||
|
||||
/* ------------ 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
|
||||
|
||||
|
||||
/* ------------- 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
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* DATA TYPES
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* GLOBAL VARIABLES
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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))
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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))
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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))
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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))
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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))
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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) (((((c) > ASCII_CHAR_SPACE) && ((c) < ASCII_CHAR_DIGIT_ZERO)) || \
|
||||
(((c) > ASCII_CHAR_DIGIT_NINE) && ((c) < ASCII_CHAR_LATIN_UPPER_A)) || \
|
||||
(((c) > ASCII_CHAR_LATIN_UPPER_Z) && ((c) < ASCII_CHAR_LATIN_LOWER_A)) || \
|
||||
(((c) > ASCII_CHAR_LATIN_LOWER_Z) && ((c) < ASCII_CHAR_DELETE))) ? (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))
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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))
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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);
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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
|
|
@ -0,0 +1,270 @@
|
|||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/LIB
|
||||
* Custom Library Modules
|
||||
*
|
||||
* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com
|
||||
*
|
||||
* SPDX-License-Identifier: APACHE-2.0
|
||||
*
|
||||
* This software is subject to an open source license and is distributed by
|
||||
* Silicon Laboratories Inc. pursuant to the terms of the Apache License,
|
||||
* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
*
|
||||
* MATHEMATIC OPERATIONS
|
||||
*
|
||||
* Filename : lib_math.c
|
||||
* Version : V1.39.00
|
||||
*********************************************************************************************************
|
||||
* 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>
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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. */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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);
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,287 @@
|
|||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/LIB
|
||||
* Custom Library Modules
|
||||
*
|
||||
* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com
|
||||
*
|
||||
* SPDX-License-Identifier: APACHE-2.0
|
||||
*
|
||||
* This software is subject to an open source license and is distributed by
|
||||
* Silicon Laboratories Inc. pursuant to the terms of the Apache License,
|
||||
* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
*
|
||||
* MATHEMATIC OPERATIONS
|
||||
*
|
||||
* Filename : lib_math.h
|
||||
* Version : V1.39.00
|
||||
*********************************************************************************************************
|
||||
* 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
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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. */
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* DATA TYPES
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* RANDOM NUMBER DATA TYPE
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
typedef CPU_INT32U RAND_NBR;
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* GLOBAL VARIABLES
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* MACROS
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* MATH_IS_PWR2()
|
||||
*
|
||||
* Description : Determine if a value is a power of 2.
|
||||
*
|
||||
* Argument(s) : nbr Value.
|
||||
*
|
||||
* Return(s) : DEF_YES, 'nbr' is a power of 2.
|
||||
*
|
||||
* DEF_NO, 'nbr' is not a power of 2.
|
||||
*
|
||||
* Caller(s) : Application.
|
||||
*
|
||||
* Note(s) : none.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#define MATH_IS_PWR2(nbr) ((((nbr) != 0u) && (((nbr) & ((nbr) - 1u)) == 0u)) ? DEF_YES : DEF_NO)
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* MATH_ROUND_INC_UP_PWR2()
|
||||
*
|
||||
* Description : Round value up to the next (power of 2) increment.
|
||||
*
|
||||
* Argument(s) : nbr Value to round.
|
||||
*
|
||||
* inc Increment to use. MUST be a power of 2.
|
||||
*
|
||||
* Return(s) : Rounded up value.
|
||||
*
|
||||
* Caller(s) : Application.
|
||||
*
|
||||
* Note(s) : none.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#define MATH_ROUND_INC_UP_PWR2(nbr, inc) (((nbr) & ~((inc) - 1)) + (((nbr) & ((inc) - 1)) == 0 ? 0 : (inc)))
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* MATH_ROUND_INC_UP()
|
||||
*
|
||||
* Description : Round value up to the next increment.
|
||||
*
|
||||
* Argument(s) : nbr Value to round.
|
||||
*
|
||||
* inc Increment to use.
|
||||
*
|
||||
* Return(s) : Rounded up value.
|
||||
*
|
||||
* Caller(s) : Application.
|
||||
*
|
||||
* Note(s) : none.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#define MATH_ROUND_INC_UP(nbr, inc) (((nbr) + ((inc) - 1)) / (inc) * (inc))
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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);
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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
|
|
@ -0,0 +1,418 @@
|
|||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/LIB
|
||||
* Custom Library Modules
|
||||
*
|
||||
* Copyright 2004-2020 Silicon Laboratories Inc. www.silabs.com
|
||||
*
|
||||
* SPDX-License-Identifier: APACHE-2.0
|
||||
*
|
||||
* This software is subject to an open source license and is distributed by
|
||||
* Silicon Laboratories Inc. pursuant to the terms of the Apache License,
|
||||
* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
*
|
||||
* ASCII STRING MANAGEMENT
|
||||
*
|
||||
* Filename : lib_str.h
|
||||
* Version : V1.39.00
|
||||
*********************************************************************************************************
|
||||
* 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
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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. */
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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);
|
||||
|
||||
|
||||
/* ------------------ 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);
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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. */
|
||||
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
# uC/LIB
|
||||
|
||||
Designed with Micrium’s renowned quality, scalability and reliability, the purpose of µC/LIB is to provide a clean, organized ANSI C implementation of the most common standard library functions, macros, and constants.
|
||||
|
||||
## For the complete documentation, visit https://doc.micrium.com/display/ucos/
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
*********************************************************************************************************
|
||||
* EXAMPLE CODE
|
||||
*
|
||||
* (c) Copyright 2009-2013; Micrium, Inc.; Weston, FL
|
||||
*
|
||||
* All rights reserved. Protected by international copyright laws.
|
||||
*
|
||||
* Please feel free to use any application code labeled as 'EXAMPLE CODE' in
|
||||
* your application products. Example code may be used as is, in whole or in
|
||||
* part, or may be used as a reference only.
|
||||
*
|
||||
* 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.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
*
|
||||
* APPLICATION CONFIGURATION
|
||||
*
|
||||
* uC/OS-III on POSIX
|
||||
*
|
||||
* Filename : app.c
|
||||
* Version : V1.00
|
||||
* Programmer(s) : EJ
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* MODULE
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef APP_CFG_MODULE_PRESENT
|
||||
#define APP_CFG_MODULE_PRESENT
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* INCLUDE
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* TASK PRIORITIES
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#define APP_CFG_TASK_START_PRIO 33
|
||||
|
||||
#define OS_TASK_TMR_PRIO (OS_LOWEST_PRIO - 2)
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* TASK STACK SIZES
|
||||
* Size of the task stacks (# of OS_STK entries)
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#define APP_CFG_TASK_START_STK_SIZE 4096
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/TCP-IP v2.10
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* TRACE / DEBUG CONFIGURATION
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
#ifndef TRACE_LEVEL_OFF
|
||||
#define TRACE_LEVEL_OFF 0
|
||||
#endif
|
||||
|
||||
#ifndef TRACE_LEVEL_INFO
|
||||
#define TRACE_LEVEL_INFO 1
|
||||
#endif
|
||||
|
||||
#ifndef TRACE_LEVEL_DEBUG
|
||||
#define TRACE_LEVEL_DEBUG 2
|
||||
#endif
|
||||
|
||||
#define APP_TRACE_LEVEL TRACE_LEVEL_OFF
|
||||
#define APP_TRACE printf
|
||||
|
||||
#define APP_TRACE_INFO(x) ((APP_TRACE_LEVEL >= TRACE_LEVEL_INFO) ? (void)(APP_TRACE x) : (void)0)
|
||||
#define APP_TRACE_DBG(x) ((APP_TRACE_LEVEL >= TRACE_LEVEL_DEBUG) ? (void)(APP_TRACE x) : (void)0)
|
||||
|
||||
#define APP_TRACE_DEBUG(x) APP_TRACE_DBG(x)
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,262 @@
|
|||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/OS-III
|
||||
* The Real-Time Kernel
|
||||
*
|
||||
* Copyright 2009-2020 Silicon Laboratories Inc. www.silabs.com
|
||||
*
|
||||
* SPDX-License-Identifier: APACHE-2.0
|
||||
*
|
||||
* This software is subject to an open source license and is distributed by
|
||||
* Silicon Laboratories Inc. pursuant to the terms of the Apache License,
|
||||
* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
*
|
||||
* APPLICATION HOOKS
|
||||
*
|
||||
* Filename : os_app_hooks.c
|
||||
* Version : V3.08.00
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#define MICRIUM_SOURCE
|
||||
#include <os.h>
|
||||
#include "os_app_hooks.h"
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* 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_AppIdleTaskHookPtr = App_OS_IdleTaskHook;
|
||||
|
||||
#if (OS_CFG_TASK_STK_REDZONE_EN > 0u)
|
||||
OS_AppRedzoneHitHookPtr = App_OS_RedzoneHitHook;
|
||||
#endif
|
||||
|
||||
OS_AppStatTaskHookPtr = App_OS_StatTaskHook;
|
||||
|
||||
OS_AppTaskCreateHookPtr = App_OS_TaskCreateHook;
|
||||
|
||||
OS_AppTaskDelHookPtr = App_OS_TaskDelHook;
|
||||
|
||||
OS_AppTaskReturnHookPtr = App_OS_TaskReturnHook;
|
||||
|
||||
OS_AppTaskSwHookPtr = App_OS_TaskSwHook;
|
||||
|
||||
OS_AppTimeTickHookPtr = App_OS_TimeTickHook;
|
||||
CPU_CRITICAL_EXIT();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* 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_AppIdleTaskHookPtr = (OS_APP_HOOK_VOID)0;
|
||||
|
||||
#if (OS_CFG_TASK_STK_REDZONE_EN > 0u)
|
||||
OS_AppRedzoneHitHookPtr = (OS_APP_HOOK_TCB)0;
|
||||
#endif
|
||||
|
||||
OS_AppStatTaskHookPtr = (OS_APP_HOOK_VOID)0;
|
||||
|
||||
OS_AppTaskCreateHookPtr = (OS_APP_HOOK_TCB)0;
|
||||
|
||||
OS_AppTaskDelHookPtr = (OS_APP_HOOK_TCB)0;
|
||||
|
||||
OS_AppTaskReturnHookPtr = (OS_APP_HOOK_TCB)0;
|
||||
|
||||
OS_AppTaskSwHookPtr = (OS_APP_HOOK_VOID)0;
|
||||
|
||||
OS_AppTimeTickHookPtr = (OS_APP_HOOK_VOID)0;
|
||||
CPU_CRITICAL_EXIT();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* 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)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* APPLICATION REDZONE HIT HOOK
|
||||
*
|
||||
* Description: This function is called when a task's stack overflowed.
|
||||
*
|
||||
* Arguments : p_tcb is a pointer to the task control block of the offending task. NULL if ISR.
|
||||
*
|
||||
* Note(s) : None.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
#if (OS_CFG_TASK_STK_REDZONE_EN > 0u)
|
||||
void App_OS_RedzoneHitHook (OS_TCB *p_tcb)
|
||||
{
|
||||
(void)&p_tcb;
|
||||
CPU_SW_EXCEPTION(;);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* 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)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* 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;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* 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;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* 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;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* 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)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* 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.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
|
||||
void App_OS_TimeTickHook (void)
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/OS-III
|
||||
* The Real-Time Kernel
|
||||
*
|
||||
* Copyright 2009-2020 Silicon Laboratories Inc. www.silabs.com
|
||||
*
|
||||
* SPDX-License-Identifier: APACHE-2.0
|
||||
*
|
||||
* This software is subject to an open source license and is distributed by
|
||||
* Silicon Laboratories Inc. pursuant to the terms of the Apache License,
|
||||
* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
*
|
||||
* APPLICATION HOOKS
|
||||
*
|
||||
* Filename : os_app_hooks.h
|
||||
* Version : V3.08.00
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#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_IdleTaskHook (void);
|
||||
|
||||
#if (OS_CFG_TASK_STK_REDZONE_EN > 0u)
|
||||
void App_OS_RedzoneHitHook(OS_TCB *p_tcb);
|
||||
#endif
|
||||
|
||||
void App_OS_StatTaskHook (void);
|
||||
|
||||
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_TaskSwHook (void);
|
||||
|
||||
void App_OS_TimeTickHook (void);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/OS-III
|
||||
* The Real-Time Kernel
|
||||
*
|
||||
* Copyright 2009-2020 Silicon Laboratories Inc. www.silabs.com
|
||||
*
|
||||
* SPDX-License-Identifier: APACHE-2.0
|
||||
*
|
||||
* This software is subject to an open source license and is distributed by
|
||||
* Silicon Laboratories Inc. pursuant to the terms of the Apache License,
|
||||
* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
*
|
||||
* CONFIGURATION FILE
|
||||
*
|
||||
* Filename : os_cfg.h
|
||||
* Version : V3.08.00
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#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) or Disable (0) debug code/variables */
|
||||
#define OS_CFG_TICK_EN 1u /* Enable (1) or Disable (0) the kernel tick */
|
||||
#define OS_CFG_DYN_TICK_EN 0u /* Enable (1) or Disable (0) the Dynamic Tick */
|
||||
#define OS_CFG_INVALID_OS_CALLS_CHK_EN 1u /* Enable (1) or Disable (0) checks for invalid kernel calls */
|
||||
#define OS_CFG_OBJ_TYPE_CHK_EN 1u /* Enable (1) or Disable (0) object type checking */
|
||||
#define OS_CFG_TS_EN 0u /* Enable (1) or Disable (0) time stamping */
|
||||
|
||||
#define OS_CFG_PRIO_MAX 64u /* Defines the maximum number of task priorities (see OS_PRIO data type) */
|
||||
|
||||
#define OS_CFG_SCHED_LOCK_TIME_MEAS_EN 0u /* 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 the 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 the 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_IDLE_EN 1u /* Include the idle task */
|
||||
#define OS_CFG_TASK_PROFILE_EN 1u /* Include variables in OS_TCB for profiling */
|
||||
#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_REG_TBL_SIZE 1u /* Number of task specific registers */
|
||||
|
||||
#define OS_CFG_TASK_STK_REDZONE_EN 0u /* Enable (1) or Disable (0) stack redzone */
|
||||
#define OS_CFG_TASK_STK_REDZONE_DEPTH 8u /* Depth of the stack redzone */
|
||||
|
||||
#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() */
|
||||
|
||||
|
||||
/* ------------------ TASK LOCAL STORAGE MANAGEMENT ------------------- */
|
||||
#define OS_CFG_TLS_TBL_SIZE 0u /* Include code for Task Local Storage (TLS) registers */
|
||||
|
||||
|
||||
/* ------------------------- 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() */
|
||||
|
||||
|
||||
/* ------------------------- TRACE RECORDER ---------------------------- */
|
||||
#define OS_CFG_TRACE_EN 0u /* Enable (1) or Disable (0) uC/OS-III Trace instrumentation */
|
||||
#define OS_CFG_TRACE_API_ENTER_EN 0u /* Enable (1) or Disable (0) uC/OS-III Trace API enter instrumentation */
|
||||
#define OS_CFG_TRACE_API_EXIT_EN 0u /* Enable (1) or Disable (0) uC/OS-III Trace API exit instrumentation */
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/OS-III
|
||||
* The Real-Time Kernel
|
||||
*
|
||||
* Copyright 2009-2020 Silicon Laboratories Inc. www.silabs.com
|
||||
*
|
||||
* SPDX-License-Identifier: APACHE-2.0
|
||||
*
|
||||
* This software is subject to an open source license and is distributed by
|
||||
* Silicon Laboratories Inc. pursuant to the terms of the Apache License,
|
||||
* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
*
|
||||
* OS CONFIGURATION (APPLICATION SPECIFICS)
|
||||
*
|
||||
* Filename : os_cfg_app.h
|
||||
* Version : V3.08.00
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef OS_CFG_APP_H
|
||||
#define OS_CFG_APP_H
|
||||
|
||||
/*
|
||||
**************************************************************************************************************************
|
||||
* CONSTANTS
|
||||
**************************************************************************************************************************
|
||||
*/
|
||||
/* ------------------ MISCELLANEOUS ------------------- */
|
||||
/* Stack size of ISR stack (number of CPU_STK elements) */
|
||||
#define OS_CFG_ISR_STK_SIZE 128u
|
||||
/* Maximum number of messages */
|
||||
#define OS_CFG_MSG_POOL_SIZE 32u
|
||||
/* Stack limit position in percentage to empty */
|
||||
#define OS_CFG_TASK_STK_LIMIT_PCT_EMPTY 10u
|
||||
|
||||
|
||||
/* -------------------- IDLE TASK --------------------- */
|
||||
/* Stack size (number of CPU_STK elements) */
|
||||
#define OS_CFG_IDLE_TASK_STK_SIZE 64u
|
||||
|
||||
|
||||
/* ------------------ STATISTIC TASK ------------------ */
|
||||
/* Priority */
|
||||
#define OS_CFG_STAT_TASK_PRIO ((OS_PRIO)(OS_CFG_PRIO_MAX-2u))
|
||||
/* Rate of execution (1 to 10 Hz) */
|
||||
#define OS_CFG_STAT_TASK_RATE_HZ 10u
|
||||
/* Stack size (number of CPU_STK elements) */
|
||||
#define OS_CFG_STAT_TASK_STK_SIZE 100u
|
||||
|
||||
|
||||
/* ---------------------- TICKS ----------------------- */
|
||||
/* Tick rate in Hertz (10 to 1000 Hz) */
|
||||
#define OS_CFG_TICK_RATE_HZ 1000u
|
||||
|
||||
|
||||
/* --------------------- TIMERS ----------------------- */
|
||||
/* Priority of 'Timer Task' */
|
||||
#define OS_CFG_TMR_TASK_PRIO ((OS_PRIO)(OS_CFG_PRIO_MAX-3u))
|
||||
/* Stack size (number of CPU_STK elements) */
|
||||
#define OS_CFG_TMR_TASK_STK_SIZE 128u
|
||||
|
||||
/* DEPRECATED - Rate for timers (10 Hz Typ.) */
|
||||
/* The timer task now calculates its timeouts based */
|
||||
/* on the timers in the list. It no longer runs at a */
|
||||
/* static frequency. */
|
||||
/* This define is included for compatibility reasons. */
|
||||
/* It will determine the period of a timer tick. */
|
||||
/* We recommend setting it to OS_CFG_TICK_RATE_HZ */
|
||||
/* for new projects. */
|
||||
#define OS_CFG_TMR_TASK_RATE_HZ 10u
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,202 @@
|
|||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
ATTENTION ALL USERS OF THIS REPOSITORY:
|
||||
|
||||
The original work found in this repository is provided by Silicon Labs under the
|
||||
Apache License, Version 2.0.
|
||||
|
||||
Any third party may contribute derivative works to the original work in which
|
||||
modifications are clearly identified as being licensed under:
|
||||
|
||||
(1) the Apache License, Version 2.0 or a compatible open source license; or
|
||||
(2) under a proprietary license with a copy of such license deposited.
|
||||
|
||||
All posted derivative works must clearly identify which license choice has been
|
||||
elected.
|
||||
|
||||
No such posted derivative works will be considered to be a “Contribution” under
|
||||
the Apache License, Version 2.0.
|
||||
|
||||
SILICON LABS MAKES NO WARRANTY WITH RESPECT TO ALL POSTED THIRD PARTY CONTENT
|
||||
AND DISCLAIMS ALL OTHER WARRANTIES OR LIABILITIES, INCLUDING ALL WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE, OWNERSHIP,
|
||||
NON-INFRINGEMENT, AND NON-MISAPPROPRIATION.
|
||||
|
||||
In the event a derivative work is desired to be submitted to Silicon Labs as a
|
||||
“Contribution” under the Apache License, Version 2.0, a “Contributor” must give
|
||||
written email notice to micrium@weston-embedded.com. Unless an email response in
|
||||
the affirmative to accept the derivative work as a “Contribution”, such email
|
||||
submission should be considered to have not been incorporated into the original
|
||||
work.
|
||||
|
|
@ -0,0 +1,177 @@
|
|||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/OS-III
|
||||
* The Real-Time Kernel
|
||||
*
|
||||
* Copyright 2009-2020 Silicon Laboratories Inc. www.silabs.com
|
||||
*
|
||||
* SPDX-License-Identifier: APACHE-2.0
|
||||
*
|
||||
* This software is subject to an open source license and is distributed by
|
||||
* Silicon Laboratories Inc. pursuant to the terms of the Apache License,
|
||||
* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
*
|
||||
* ARMv6-M Port
|
||||
*
|
||||
* File : os_cpu.h
|
||||
* Version : V3.08.00
|
||||
*********************************************************************************************************
|
||||
* For : ARMv6-M Cortex-M0 or Cortex-M0+
|
||||
* Mode : Thumb2
|
||||
* Toolchain : GNU C Compiler
|
||||
*********************************************************************************************************
|
||||
* Note(s) : (1) This port supports the ARM Cortex-M0 and Cortex-M0+ architectures.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef OS_CPU_H
|
||||
#define OS_CPU_H
|
||||
|
||||
#ifdef OS_CPU_GLOBALS
|
||||
#define OS_CPU_EXT
|
||||
#else
|
||||
#define OS_CPU_EXT extern
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* EXTERNAL C LANGUAGE LINKAGE
|
||||
*
|
||||
* Note(s) : (1) C++ compilers MUST 'extern'ally declare ALL C function prototypes & variable/object
|
||||
* declarations for correct C language linkage.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" { /* See Note #1. */
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* DEFINES
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* MACROS
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#define OS_TASK_SW() OSCtxSw()
|
||||
|
||||
#define OS_TASK_SW_SYNC() __asm__ __volatile__ ("isb" : : : "memory")
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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 > 0u) && \
|
||||
(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.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef OS_CPU_CFG_SYSTICK_PRIO
|
||||
#define OS_CPU_CFG_SYSTICK_PRIO 0u
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* GLOBAL VARIABLES
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
OS_CPU_EXT CPU_STK *OS_CPU_ExceptStkBase;
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* FUNCTION PROTOTYPES
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
/* See OS_CPU_A.ASM */
|
||||
void OSCtxSw (void);
|
||||
void OSIntCtxSw (void);
|
||||
void OSStartHighRdy (void);
|
||||
|
||||
void OS_CPU_PendSVHandler (void);
|
||||
|
||||
|
||||
void OS_CPU_SysTickHandler(void);
|
||||
void OS_CPU_SysTickInit (CPU_INT32U cnts);
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* EXTERNAL C LANGUAGE LINKAGE END
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* End of 'extern'al C lang linkage. */
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* MODULE END
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,235 @@
|
|||
@********************************************************************************************************
|
||||
@ uC/OS-III
|
||||
@ The Real-Time Kernel
|
||||
@
|
||||
@ Copyright 2009-2020 Silicon Laboratories Inc. www.silabs.com
|
||||
@
|
||||
@ SPDX-License-Identifier: APACHE-2.0
|
||||
@
|
||||
@ This software is subject to an open source license and is distributed by
|
||||
@ Silicon Laboratories Inc. pursuant to the terms of the Apache License,
|
||||
@ Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
|
||||
@
|
||||
@********************************************************************************************************
|
||||
|
||||
@********************************************************************************************************
|
||||
@
|
||||
@ ARMv6-M Port
|
||||
@
|
||||
@ File : os_cpu_a.s
|
||||
@ Version : V3.08.00
|
||||
@********************************************************************************************************
|
||||
@ For : ARMv6-M Cortex-M0 or Cortex-M0+
|
||||
@ Mode : Thumb2
|
||||
@ Toolchain : GNU C Compiler
|
||||
@********************************************************************************************************
|
||||
@ Note(s) : (1) This port supports the ARM Cortex-M0 and Cortex-M0+ architectures.
|
||||
@********************************************************************************************************
|
||||
|
||||
@********************************************************************************************************
|
||||
@ PUBLIC FUNCTIONS
|
||||
@********************************************************************************************************
|
||||
|
||||
@ 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 OSCtxSw
|
||||
.global OSIntCtxSw
|
||||
.global OS_CPU_PendSVHandler
|
||||
|
||||
@********************************************************************************************************
|
||||
@ EQUATES
|
||||
@********************************************************************************************************
|
||||
|
||||
.equ NVIC_INT_CTRL, 0xE000ED04 @ Interrupt control state register.
|
||||
.equ NVIC_SYSPRI14, 0xE000ED20 @ System priority register (priority 14).
|
||||
.equ NVIC_PENDSV_PRI, 0x00FF0000 @ PendSV priority value (lowest).
|
||||
.equ NVIC_PENDSVSET, 0x10000000 @ Value to trigger PendSV exception.
|
||||
|
||||
|
||||
@********************************************************************************************************
|
||||
@ CODE GENERATION DIRECTIVES
|
||||
@********************************************************************************************************
|
||||
|
||||
.text
|
||||
.align 2
|
||||
.thumb
|
||||
.syntax unified
|
||||
|
||||
|
||||
@********************************************************************************************************
|
||||
@ START MULTITASKING
|
||||
@ void OSStartHighRdy(void)
|
||||
@
|
||||
@ Note(s) : 1) This function triggers a PendSV exception (essentially, causes a context switch) to cause
|
||||
@ the first task to start.
|
||||
@
|
||||
@ 2) OSStartHighRdy() MUST:
|
||||
@ a) Setup PendSV exception priority to lowest;
|
||||
@ b) Set initial PSP to 0, to tell context switcher this is first run;
|
||||
@ c) Set the main stack to OS_CPU_ExceptStkBase
|
||||
@ d) Trigger PendSV exception;
|
||||
@ e) Enable interrupts (tasks will run with interrupts enabled).
|
||||
@********************************************************************************************************
|
||||
|
||||
.thumb_func
|
||||
OSStartHighRdy:
|
||||
CPSID I @ Prevent interruption during context switch
|
||||
LDR R0, =NVIC_SYSPRI14 @ Set the PendSV exception priority
|
||||
LDR R1, =NVIC_PENDSV_PRI
|
||||
STR R1, [R0]
|
||||
|
||||
MOVS R0, #0 @ Set the PSP to 0 for initial context switch call
|
||||
MSR PSP, R0
|
||||
BL OSTaskSwHook
|
||||
|
||||
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
|
||||
|
||||
|
||||
@********************************************************************************************************
|
||||
@ PERFORM A CONTEXT SWITCH (From task level) - OSCtxSw()
|
||||
@
|
||||
@ Note(s) : 1) OSCtxSw() is called when OS wants to perform a task context switch. This function
|
||||
@ triggers the PendSV exception which is where the real work is done.
|
||||
@********************************************************************************************************
|
||||
|
||||
.thumb_func
|
||||
OSCtxSw:
|
||||
LDR R0, =NVIC_INT_CTRL @ Trigger the PendSV exception (causes context switch)
|
||||
LDR R1, =NVIC_PENDSVSET
|
||||
STR R1, [R0]
|
||||
BX LR
|
||||
|
||||
|
||||
@********************************************************************************************************
|
||||
@ PERFORM A CONTEXT SWITCH (From interrupt level) - OSIntCtxSw()
|
||||
@
|
||||
@ Note(s) : 1) OSIntCtxSw() is called by OSIntExit() when it determines a context switch is needed as
|
||||
@ the result of an interrupt. This function simply triggers a PendSV exception which will
|
||||
@ be handled when there are no more interrupts active and interrupts are enabled.
|
||||
@********************************************************************************************************
|
||||
|
||||
.thumb_func
|
||||
OSIntCtxSw:
|
||||
LDR R0, =NVIC_INT_CTRL @ Trigger the PendSV exception (causes context switch)
|
||||
LDR R1, =NVIC_PENDSVSET
|
||||
STR R1, [R0]
|
||||
BX LR
|
||||
|
||||
|
||||
@********************************************************************************************************
|
||||
@ 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-M0. This is because the Cortex-M0 auto-saves half of the
|
||||
@ processor context on any exception, and restores same on return from exception. So only
|
||||
@ saving of R4-R11, LR 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) Adjust SP to make space for R4-R11 and LR register
|
||||
@ c) Save the process SP in its TCB, OSTCBCurPtr->StkPtr = SP;
|
||||
@ d) Save remaining regs R4-R11, LR on process stack;
|
||||
@ e) Call OSTaskSwHook();
|
||||
@ f) Get current high priority, OSPrioCur = OSPrioHighRdy;
|
||||
@ g) Get current ready thread TCB, OSTCBCurPtr = OSTCBHighRdyPtr;
|
||||
@ h) Get new process SP from TCB, SP = OSTCBHighRdyPtr->StkPtr;
|
||||
@ i) Adjust SP to the High Registers(R8-R11) & LR location
|
||||
@ j) Restore R8-R11, and LR from new process stack;
|
||||
@ k) Load PSP with new process SP
|
||||
@ m) Restore remaining R4-R7 from new process stack
|
||||
@ n) Perform exception return which will restore remaining context.
|
||||
@
|
||||
@ 3) On entry into PendSV handler:
|
||||
@ a) The following have been saved on the process stack (by processor):
|
||||
@ xPSR, PC, LR, R12, R0-R3
|
||||
@ b) Processor mode is switched to Handler mode (from Thread mode)
|
||||
@ c) Stack is Main stack (switched from Process stack)
|
||||
@ d) OSTCBCurPtr points to the OS_TCB of the task to suspend
|
||||
@ OSTCBHighRdyPtr points to the OS_TCB of the task to resume
|
||||
@
|
||||
@ 4) Since PendSV is set to lowest priority in the system (by OSStartHighRdy() above), we
|
||||
@ know that it will only be run when no other exception or interrupt is active, and
|
||||
@ therefore safe to assume that context being switched out was using the process stack (PSP).
|
||||
@********************************************************************************************************
|
||||
|
||||
.thumb_func
|
||||
OS_CPU_PendSVHandler:
|
||||
CPSID I @ Prevent interruption during context switch
|
||||
MRS R0, PSP @ PSP is process stack pointer
|
||||
|
||||
CMP R0, #0
|
||||
BEQ OS_CPU_PendSVHandler_nosave @ equivalent code to CBZ from M3 arch to M0 arch
|
||||
@ Except that it does not change the condition code flags
|
||||
|
||||
SUBS R0, R0, #0x24 @ Adjust SP to make space for Low, High & LR registers
|
||||
LDR R1, =OSTCBCurPtr @ OSTCBCurPtr->StkPtr = SP;
|
||||
LDR R1, [R1]
|
||||
STR R0, [R1] @ R0 is SP of process being switched out
|
||||
|
||||
STMIA R0!, {R4-R7} @ Store R4-R7(Low Registers) on process stack
|
||||
MOV R4, R8 @ Move R8-R11 values to R4-R7 registers.
|
||||
MOV R5, R9
|
||||
MOV R6, R10
|
||||
MOV R7, R11
|
||||
STMIA R0!, {R4-R7} @ Store R8-R11(High Registers) on process stack
|
||||
MOV R3, R14 @ R3 is LR of process being switched out
|
||||
STMIA R0!, {R3} @ Store LR (EXC_RETURN) on process stack.
|
||||
|
||||
@ At this point, entire context of process has been saved
|
||||
OS_CPU_PendSVHandler_nosave:
|
||||
BL OSTaskSwHook @ OSTaskSwHook();
|
||||
|
||||
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;
|
||||
|
||||
ADDS R0, #0x10 @ Adjust SP to High Registers(R8-R11) location
|
||||
LDMFD R0!, {R4-R7} @ Load R8-R11 values from new process stack into R4-R7
|
||||
MOV R8, R4 @ Restore R8-R11 by moving their values from R4-R7
|
||||
MOV R9, R5
|
||||
MOV R10, R6
|
||||
MOV R11, R7
|
||||
|
||||
LDMFD R0!, {R3} @ R3 has the new process LR; R3 = LR (EXEC_RETURN)
|
||||
MOV R14, R3 @ Restore LR (EXEC_RETURN)
|
||||
|
||||
MSR PSP, R0 @ Load PSP with new process SP
|
||||
|
||||
SUBS R0, #0x24 @ Adjust SP to Low registers(R4-R7) location
|
||||
LDMFD R0!, {R4-R7} @ Restore remaining R4-R7 from new process stack
|
||||
|
||||
CPSIE I
|
||||
BX LR @ Exception return will restore remaining context
|
||||
|
||||
.end
|
||||
|
|
@ -0,0 +1,511 @@
|
|||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/OS-III
|
||||
* The Real-Time Kernel
|
||||
*
|
||||
* Copyright 2009-2020 Silicon Laboratories Inc. www.silabs.com
|
||||
*
|
||||
* SPDX-License-Identifier: APACHE-2.0
|
||||
*
|
||||
* This software is subject to an open source license and is distributed by
|
||||
* Silicon Laboratories Inc. pursuant to the terms of the Apache License,
|
||||
* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
*
|
||||
* ARMv6-M Port
|
||||
*
|
||||
* File : os_cpu_c.c
|
||||
* Version : V3.08.00
|
||||
*********************************************************************************************************
|
||||
* For : ARMv6-M Cortex-M0 or Cortex-M0+
|
||||
* Mode : Thumb2
|
||||
*********************************************************************************************************
|
||||
* Note(s) : (1) This port supports the ARM Cortex-M0 and Cortex-M0+ architectures.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#define OS_CPU_GLOBALS
|
||||
|
||||
#ifdef VSC_INCLUDE_SOURCE_FILE_NAMES
|
||||
const CPU_CHAR *os_cpu_c__c = "$Id: $";
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* INCLUDE FILES
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#include "../../../Source/os.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* OS INITIALIZATION HOOK
|
||||
*
|
||||
* Description: This function is called by OSInit() at the beginning of OSInit().
|
||||
*
|
||||
* Arguments : None.
|
||||
*
|
||||
* Note(s) : None.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void OSInitHook (void)
|
||||
{
|
||||
/* 8-byte align the ISR stack. */
|
||||
OS_CPU_ExceptStkBase = (CPU_STK *)(OSCfg_ISRStkBasePtr + OSCfg_ISRStkSize);
|
||||
OS_CPU_ExceptStkBase = (CPU_STK *)((CPU_STK)(OS_CPU_ExceptStkBase) & 0xFFFFFFF8);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* REDZONE HIT HOOK
|
||||
*
|
||||
* Description: This function is called when a task's stack overflowed.
|
||||
*
|
||||
* Arguments : p_tcb Pointer to the task control block of the offending task. NULL if ISR.
|
||||
*
|
||||
* Note(s) : None.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
#if (OS_CFG_TASK_STK_REDZONE_EN > 0u)
|
||||
void OSRedzoneHitHook (OS_TCB *p_tcb)
|
||||
{
|
||||
#if OS_CFG_APP_HOOKS_EN > 0u
|
||||
if (OS_AppRedzoneHitHookPtr != (OS_APP_HOOK_TCB)0) {
|
||||
(*OS_AppRedzoneHitHookPtr)(p_tcb);
|
||||
} else {
|
||||
CPU_SW_EXCEPTION(;);
|
||||
}
|
||||
#else
|
||||
(void)p_tcb; /* Prevent compiler warning */
|
||||
CPU_SW_EXCEPTION(;);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* INITIALIZE A TASK'S STACK
|
||||
*
|
||||
* Description: This function is called by either OSTaskCreate() 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.
|
||||
*
|
||||
* (3) The SP must be 8-byte aligned in conforming to the Procedure Call Standard for the ARM architecture
|
||||
*
|
||||
* (a) Section 2.1 of the ABI for the ARM Architecture Advisory Note. SP must be 8-byte aligned
|
||||
* on entry to AAPCS-Conforming functions states :
|
||||
*
|
||||
* The Procedure Call Standard for the ARM Architecture [AAPCS] requires primitive
|
||||
* data types to be naturally aligned according to their sizes (for size = 1, 2, 4, 8 bytes).
|
||||
* Doing otherwise creates more problems than it solves.
|
||||
*
|
||||
* In return for preserving the natural alignment of data, conforming code is permitted
|
||||
* to rely on that alignment. To support aligning data allocated on the stack, the stack
|
||||
* pointer (SP) is required to be 8-byte aligned on entry to a conforming function. In
|
||||
* practice this requirement is met if:
|
||||
*
|
||||
* (1) At each call site, the current size of the calling function's stack frame is a multiple of 8 bytes.
|
||||
* This places an obligation on compilers and assembly language programmers.
|
||||
*
|
||||
* (2) SP is a multiple of 8 when control first enters a program.
|
||||
* This places an obligation on authors of low level OS, RTOS, and runtime library
|
||||
* code to align SP at all points at which control first enters
|
||||
* a body of (AAPCS-conforming) code.
|
||||
*
|
||||
* In turn, this requires the value of SP to be aligned to 0 modulo 8:
|
||||
*
|
||||
* (3) By exception handlers, before calling AAPCS-conforming code.
|
||||
*
|
||||
* (4) By OS/RTOS/run-time system code, before giving control to an application.
|
||||
*
|
||||
* (b) Section 2.3.1 corrective steps from the the SP must be 8-byte aligned on entry
|
||||
* to AAPCS-conforming functions advisory note also states.
|
||||
*
|
||||
* " This requirement extends to operating systems and run-time code for all architecture versions
|
||||
* prior to ARMV7 and to the A, R and M architecture profiles thereafter. Special considerations
|
||||
* associated with ARMV7M are discussed in section 2.3.3"
|
||||
*
|
||||
* (1) Even if the SP 8-byte aligment is not a requirement for the ARMv7M profile, the stack is aligned
|
||||
* to 8-byte boundaries to support legacy execution enviroments.
|
||||
*
|
||||
* (c) Section 5.2.1.2 from the Procedure Call Standard for the ARM
|
||||
* architecture states : "The stack must also conform to the following
|
||||
* constraint at a public interface:
|
||||
*
|
||||
* (1) SP mod 8 = 0. The stack must be double-word aligned"
|
||||
*
|
||||
* (d) From the ARM Technical Support Knowledge Base. 8 Byte stack aligment.
|
||||
*
|
||||
* "8 byte stack alignment is a requirement of the ARM Architecture Procedure
|
||||
* Call Standard [AAPCS]. This specifies that functions must maintain an 8 byte
|
||||
* aligned stack address (e.g. 0x00, 0x08, 0x10, 0x18, 0x20) on all external
|
||||
* interfaces. In practice this requirement is met if:
|
||||
*
|
||||
* (1) At each external interface, the current stack pointer
|
||||
* is a multiple of 8 bytes.
|
||||
*
|
||||
* (2) Your OS maintains 8 byte stack alignment on its external interfaces
|
||||
* e.g. on task switches"
|
||||
*
|
||||
* (4) Exception Return Behavior(EXEC_RETURN)
|
||||
* 0xFFFFFFF1 Return to Thread mode. Exception return gets state from the Main Stack.
|
||||
* On Return execution uses the Main Stack.
|
||||
*
|
||||
* 0xFFFFFFF9 Return to Thread mode. Exception return gets state from the Main Stack.
|
||||
* On Return execution uses the Main Stack.
|
||||
*
|
||||
* 0xFFFFFFFD Return to Thread mode. Exception return gets state from the Process Stack.
|
||||
* On Return execution uses the 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; /* 'opt' is not used, prevent warning */
|
||||
|
||||
p_stk = &p_stk_base[stk_size]; /* Load stack pointer */
|
||||
/* Align the stack to 8-bytes. */
|
||||
p_stk = (CPU_STK *)((CPU_STK)(p_stk) & 0xFFFFFFF8u);
|
||||
/* 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)0xFFFFFFFDuL; /* R14: EXEC_RETURN; See Note 4 */
|
||||
*(--p_stk) = (CPU_STK)0x11111111uL; /* R11 */
|
||||
*(--p_stk) = (CPU_STK)0x10101010uL; /* R10 */
|
||||
*(--p_stk) = (CPU_STK)0x09090909uL; /* R9 */
|
||||
*(--p_stk) = (CPU_STK)0x08080808uL; /* R8 */
|
||||
*(--p_stk) = (CPU_STK)0x07070707uL; /* R7 */
|
||||
*(--p_stk) = (CPU_STK)0x06060606uL; /* R6 */
|
||||
*(--p_stk) = (CPU_STK)0x05050505uL; /* R5 */
|
||||
*(--p_stk) = (CPU_STK)0x04040404uL; /* R4 */
|
||||
|
||||
return (p_stk);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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_TASK_STK_REDZONE_EN > 0u)
|
||||
CPU_BOOLEAN stk_status;
|
||||
#endif
|
||||
|
||||
#if OS_CFG_APP_HOOKS_EN > 0u
|
||||
if (OS_AppTaskSwHookPtr != (OS_APP_HOOK_VOID)0) {
|
||||
(*OS_AppTaskSwHookPtr)();
|
||||
}
|
||||
#endif
|
||||
|
||||
OS_TRACE_TASK_SWITCHED_IN(OSTCBHighRdyPtr);
|
||||
|
||||
#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
|
||||
|
||||
#if (OS_CFG_TASK_STK_REDZONE_EN > 0u)
|
||||
/* Check if stack overflowed. */
|
||||
stk_status = OSTaskStkRedzoneChk((OS_TCB *)0u);
|
||||
if (stk_status != OS_TRUE) {
|
||||
OSRedzoneHitHook(OSTCBCurPtr);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* SYS TICK HANDLER
|
||||
*
|
||||
* Description: Handle the system tick (SysTick) interrupt, which is used to generate the uC/OS-III tick
|
||||
* interrupt.
|
||||
*
|
||||
* Arguments : None.
|
||||
*
|
||||
* Note(s) : 1) This function MUST be placed on entry 15 of the Cortex-M0 vector table.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void OS_CPU_SysTickHandler (void)
|
||||
{
|
||||
CPU_SR_ALLOC();
|
||||
|
||||
|
||||
CPU_CRITICAL_ENTER();
|
||||
OSIntEnter(); /* 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 */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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_SYST_RVR = cnts - 1u; /* Set Reload Register */
|
||||
|
||||
/* Set SysTick handler prio. */
|
||||
prio = CPU_REG_SCB_SHPRI3;
|
||||
prio &= 0x00FFFFFFu;
|
||||
prio |= (OS_CPU_CFG_SYSTICK_PRIO << 24u);
|
||||
|
||||
CPU_REG_SCB_SHPRI3 = prio;
|
||||
|
||||
/* Enable timer. */
|
||||
CPU_REG_SYST_CSR |= CPU_REG_SYST_CSR_CLKSOURCE |
|
||||
CPU_REG_SYST_CSR_ENABLE;
|
||||
|
||||
CPU_REG_SYST_CSR |= CPU_REG_SYST_CSR_TICKINT; /* Enable timer interrupt. */
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,183 @@
|
|||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/OS-III
|
||||
* The Real-Time Kernel
|
||||
*
|
||||
* Copyright 2009-2020 Silicon Laboratories Inc. www.silabs.com
|
||||
*
|
||||
* SPDX-License-Identifier: APACHE-2.0
|
||||
*
|
||||
* This software is subject to an open source license and is distributed by
|
||||
* Silicon Laboratories Inc. pursuant to the terms of the Apache License,
|
||||
* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
*
|
||||
* ARMv7-M Port
|
||||
*
|
||||
* File : os_cpu.h
|
||||
* Version : V3.08.00
|
||||
*********************************************************************************************************
|
||||
* For : ARMv7-M Cortex-M
|
||||
* Mode : Thumb-2 ISA
|
||||
* Toolchain : GNU C Compiler
|
||||
*********************************************************************************************************
|
||||
* Note(s) : (1) This port supports the ARM Cortex-M3, Cortex-M4 and Cortex-M7 architectures.
|
||||
* (2) It has been tested with the following Hardware Floating Point Unit.
|
||||
* (a) Single-precision: FPv4-SP-D16-M and FPv5-SP-D16-M
|
||||
* (b) Double-precision: FPv5-D16-M
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef OS_CPU_H
|
||||
#define OS_CPU_H
|
||||
|
||||
#ifdef OS_CPU_GLOBALS
|
||||
#define OS_CPU_EXT
|
||||
#else
|
||||
#define OS_CPU_EXT extern
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* EXTERNAL C LANGUAGE LINKAGE
|
||||
*
|
||||
* Note(s) : (1) C++ compilers MUST 'extern'ally declare ALL C function prototypes & variable/object
|
||||
* declarations for correct C language linkage.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" { /* See Note #1. */
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* DEFINES
|
||||
* Note(s) : (1) Determines the interrupt programmable priority levels. This is normally specified in the
|
||||
* Microcontroller reference manual. 4-bits gives us 16 programmable priority levels.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
|
||||
#define OS_CPU_ARM_FP_EN 1u
|
||||
#else
|
||||
#define OS_CPU_ARM_FP_EN 0u
|
||||
#endif
|
||||
|
||||
#ifndef CPU_CFG_KA_IPL_BOUNDARY
|
||||
#error "CPU_CFG_KA_IPL_BOUNDARY not #define'd in 'cpu_cfg.h' "
|
||||
#else
|
||||
#if (CPU_CFG_KA_IPL_BOUNDARY == 0u)
|
||||
#error "CPU_CFG_KA_IPL_BOUNDARY should be > 0 "
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef CPU_CFG_NVIC_PRIO_BITS
|
||||
#error "CPU_CFG_NVIC_PRIO_BITS not #define'd in 'cpu_cfg.h' " /* See Note # 1 */
|
||||
#else
|
||||
#if (CPU_CFG_KA_IPL_BOUNDARY >= (1u << CPU_CFG_NVIC_PRIO_BITS))
|
||||
#error "CPU_CFG_KA_IPL_BOUNDARY should not be set to higher than max programable priority level "
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* MACROS
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#define OS_TASK_SW() OSCtxSw()
|
||||
|
||||
#define OS_TASK_SW_SYNC() __asm__ __volatile__ ("isb" : : : "memory")
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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 > 0u) && \
|
||||
(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
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* GLOBAL VARIABLES
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
OS_CPU_EXT CPU_STK *OS_CPU_ExceptStkBase;
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* FUNCTION PROTOTYPES
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
/* See OS_CPU_A.ASM */
|
||||
void OSCtxSw (void);
|
||||
void OSIntCtxSw (void);
|
||||
void OSStartHighRdy (void);
|
||||
|
||||
/* See OS_CPU_C.C */
|
||||
void OS_CPU_SysTickInit (CPU_INT32U cnts);
|
||||
void OS_CPU_SysTickInitFreq(CPU_INT32U cpu_freq);
|
||||
|
||||
void OS_CPU_SysTickHandler (void);
|
||||
void OS_CPU_PendSVHandler (void);
|
||||
|
||||
#if (OS_CPU_ARM_FP_EN > 0u)
|
||||
void OS_CPU_FP_Reg_Push (CPU_STK *stkPtr);
|
||||
void OS_CPU_FP_Reg_Pop (CPU_STK *stkPtr);
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* EXTERNAL C LANGUAGE LINKAGE END
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* End of 'extern'al C lang linkage. */
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* MODULE END
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,308 @@
|
|||
@********************************************************************************************************
|
||||
@ uC/OS-III
|
||||
@ The Real-Time Kernel
|
||||
@
|
||||
@ Copyright 2009-2020 Silicon Laboratories Inc. www.silabs.com
|
||||
@
|
||||
@ SPDX-License-Identifier: APACHE-2.0
|
||||
@
|
||||
@ This software is subject to an open source license and is distributed by
|
||||
@ Silicon Laboratories Inc. pursuant to the terms of the Apache License,
|
||||
@ Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
|
||||
@
|
||||
@********************************************************************************************************
|
||||
|
||||
@********************************************************************************************************
|
||||
@
|
||||
@ ARMv7-M Port
|
||||
@
|
||||
@ For : ARMv7-M Cortex-M
|
||||
@ Mode : Thumb-2 ISA
|
||||
@ Toolchain : GNU C Compiler
|
||||
@********************************************************************************************************
|
||||
@ Note(s) : (1) This port supports the ARM Cortex-M3, Cortex-M4 and Cortex-M7 architectures.
|
||||
@ (2) It has been tested with the following Hardware Floating Point Unit.
|
||||
@ (a) Single-precision: FPv4-SP-D16-M and FPv5-SP-D16-M
|
||||
@ (b) Double-precision: FPv5-D16-M
|
||||
@********************************************************************************************************
|
||||
|
||||
@********************************************************************************************************
|
||||
@ PUBLIC FUNCTIONS
|
||||
@********************************************************************************************************
|
||||
|
||||
@ External references.
|
||||
.extern OSPrioCur
|
||||
.extern OSPrioHighRdy
|
||||
.extern OSTCBCurPtr
|
||||
.extern OSTCBHighRdyPtr
|
||||
.extern OSIntExit
|
||||
.extern OSTaskSwHook
|
||||
.extern OS_CPU_ExceptStkBase
|
||||
.extern OS_KA_BASEPRI_Boundary
|
||||
|
||||
|
||||
.global OSStartHighRdy @ Functions declared in this file
|
||||
.global OSCtxSw
|
||||
.global OSIntCtxSw
|
||||
.global OS_CPU_PendSVHandler
|
||||
|
||||
#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
|
||||
.global OS_CPU_FP_Reg_Push
|
||||
.global OS_CPU_FP_Reg_Pop
|
||||
#endif
|
||||
|
||||
|
||||
@********************************************************************************************************
|
||||
@ EQUATES
|
||||
@********************************************************************************************************
|
||||
|
||||
.equ NVIC_INT_CTRL, 0xE000ED04 @ Interrupt control state register.
|
||||
.equ NVIC_SYSPRI14, 0xE000ED22 @ System priority register (priority 14).
|
||||
.equ NVIC_PENDSV_PRI, 0xFF @ PendSV priority value (lowest).
|
||||
.equ NVIC_PENDSVSET, 0x10000000 @ Value to trigger PendSV exception.
|
||||
|
||||
|
||||
@********************************************************************************************************
|
||||
@ CODE GENERATION DIRECTIVES
|
||||
@********************************************************************************************************
|
||||
|
||||
.text
|
||||
.align 2
|
||||
.thumb
|
||||
.syntax unified
|
||||
|
||||
|
||||
@********************************************************************************************************
|
||||
@ FLOATING POINT REGISTERS PUSH
|
||||
@ void OS_CPU_FP_Reg_Push (CPU_STK *stkPtr)
|
||||
@
|
||||
@ Note(s) : 1) This function saves S16-S31 registers of the Floating Point Unit.
|
||||
@
|
||||
@ 2) Pseudo-code is:
|
||||
@ a) Push remaining FPU regs S16-S31 on process stack;
|
||||
@ b) Update OSTCBCurPtr->StkPtr;
|
||||
@********************************************************************************************************
|
||||
|
||||
#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
|
||||
|
||||
.thumb_func
|
||||
OS_CPU_FP_Reg_Push:
|
||||
MRS R1, PSP @ PSP is process stack pointer
|
||||
CBZ R1, OS_CPU_FP_nosave @ Skip FP register save the first time
|
||||
|
||||
VSTMDB R0!, {S16-S31}
|
||||
LDR R1, =OSTCBCurPtr
|
||||
LDR R2, [R1]
|
||||
STR R0, [R2]
|
||||
OS_CPU_FP_nosave:
|
||||
BX LR
|
||||
#endif
|
||||
|
||||
|
||||
@********************************************************************************************************
|
||||
@ FLOATING POINT REGISTERS POP
|
||||
@ void OS_CPU_FP_Reg_Pop (CPU_STK *stkPtr)
|
||||
@
|
||||
@ Note(s) : 1) This function restores S16-S31 of the Floating Point Unit.
|
||||
@
|
||||
@ 2) Pseudo-code is:
|
||||
@ a) Restore regs S16-S31 of new process stack;
|
||||
@ b) Update OSTCBHighRdyPtr->StkPtr pointer of new proces stack;
|
||||
@********************************************************************************************************
|
||||
|
||||
#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
|
||||
|
||||
.thumb_func
|
||||
OS_CPU_FP_Reg_Pop:
|
||||
VLDMIA R0!, {S16-S31}
|
||||
LDR R1, =OSTCBHighRdyPtr
|
||||
LDR R2, [R1]
|
||||
STR R0, [R2]
|
||||
BX LR
|
||||
#endif
|
||||
|
||||
|
||||
@********************************************************************************************************
|
||||
@ 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) During task execution, PSP is used as the stack pointer.
|
||||
@ When an exception occurs, the core will switch to MSP until the exception return.
|
||||
@
|
||||
@ 3) 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) Get current high priority, OSPrioCur = OSPrioHighRdy;
|
||||
@ e) Get current ready thread TCB, OSTCBCurPtr = OSTCBHighRdyPtr;
|
||||
@ f) Get new process SP from TCB, SP = OSTCBHighRdyPtr->StkPtr;
|
||||
@ g) Restore R0-R11 and R14 from new process stack;
|
||||
@ h) Enable interrupts (tasks will run with interrupts enabled).
|
||||
@********************************************************************************************************
|
||||
|
||||
.thumb_func
|
||||
OSStartHighRdy:
|
||||
CPSID I @ Prevent interruption during context switch
|
||||
MOVW R0, #:lower16:NVIC_SYSPRI14 @ Set the PendSV exception priority
|
||||
MOVT R0, #:upper16:NVIC_SYSPRI14
|
||||
|
||||
MOVW R1, #:lower16:NVIC_PENDSV_PRI
|
||||
MOVT R1, #:upper16:NVIC_PENDSV_PRI
|
||||
STRB R1, [R0]
|
||||
|
||||
MOVS R0, #0 @ Set the PSP to 0 for initial context switch call
|
||||
MSR PSP, R0
|
||||
|
||||
MOVW R0, #:lower16:OS_CPU_ExceptStkBase @ Initialize the MSP to the OS_CPU_ExceptStkBase
|
||||
MOVT R0, #:upper16:OS_CPU_ExceptStkBase
|
||||
LDR R1, [R0]
|
||||
MSR MSP, R1
|
||||
|
||||
BL OSTaskSwHook @ Call OSTaskSwHook() for FPU Push & Pop
|
||||
|
||||
MOVW R0, #:lower16:OSPrioCur @ OSPrioCur = OSPrioHighRdy;
|
||||
MOVT R0, #:upper16:OSPrioCur
|
||||
MOVW R1, #:lower16:OSPrioHighRdy
|
||||
MOVT R1, #:upper16:OSPrioHighRdy
|
||||
LDRB R2, [R1]
|
||||
STRB R2, [R0]
|
||||
|
||||
MOVW R0, #:lower16:OSTCBCurPtr @ OSTCBCurPtr = OSTCBHighRdyPtr;
|
||||
MOVT R0, #:upper16:OSTCBCurPtr
|
||||
MOVW R1, #:lower16:OSTCBHighRdyPtr
|
||||
MOVT R1, #:upper16:OSTCBHighRdyPtr
|
||||
LDR R2, [R1]
|
||||
STR R2, [R0]
|
||||
|
||||
LDR R0, [R2] @ R0 is new process SP; SP = OSTCBHighRdyPtr->StkPtr;
|
||||
MSR PSP, R0 @ Load PSP with new process SP
|
||||
|
||||
MRS R0, CONTROL
|
||||
ORR R0, R0, #2
|
||||
MSR CONTROL, R0
|
||||
ISB @ Sync instruction stream
|
||||
|
||||
LDMFD SP!, {R4-R11, LR} @ Restore r4-11, lr from new process stack
|
||||
LDMFD SP!, {R0-R3} @ Restore r0, r3
|
||||
LDMFD SP!, {R12, LR} @ Load R12 and LR
|
||||
LDMFD SP!, {R1, R2} @ Load PC and discard xPSR
|
||||
CPSIE I
|
||||
BX R1
|
||||
|
||||
|
||||
@********************************************************************************************************
|
||||
@ PERFORM A CONTEXT SWITCH (From task level) - OSCtxSw()
|
||||
@ PERFORM A CONTEXT SWITCH (From interrupt level) - OSIntCtxSw()
|
||||
@
|
||||
@ Note(s) : 1) OSCtxSw() is called when OS wants to perform a task context switch. This function
|
||||
@ triggers the PendSV exception which is where the real work is done.
|
||||
@
|
||||
@ 2) OSIntCtxSw() is called by OSIntExit() when it determines a context switch is needed as
|
||||
@ the result of an interrupt. This function simply triggers a PendSV exception which will
|
||||
@ be handled when there are no more interrupts active and interrupts are enabled.
|
||||
@********************************************************************************************************
|
||||
|
||||
.thumb_func
|
||||
OSCtxSw:
|
||||
OSIntCtxSw:
|
||||
LDR R0, =NVIC_INT_CTRL @ Trigger the PendSV exception (causes context switch)
|
||||
LDR R1, =NVIC_PENDSVSET
|
||||
STR R1, [R0]
|
||||
BX LR
|
||||
|
||||
|
||||
@********************************************************************************************************
|
||||
@ 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-M. This is because the Cortex-M auto-saves half of the
|
||||
@ processor context on any exception, and restores same on return from exception. So only
|
||||
@ saving of R4-R11 & R14 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
|
||||
@ b) Save remaining regs r4-r11 & r14 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 and R14 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).
|
||||
@
|
||||
@ 5) Increasing priority using a write to BASEPRI does not take effect immediately.
|
||||
@ (a) IMPLICATION This erratum means that the instruction after an MSR to boost BASEPRI
|
||||
@ might incorrectly be preempted by an insufficient high priority exception.
|
||||
@
|
||||
@ (b) WORKAROUND The MSR to boost BASEPRI can be replaced by the following code sequence:
|
||||
@
|
||||
@ CPSID i
|
||||
@ MSR to BASEPRI
|
||||
@ DSB
|
||||
@ ISB
|
||||
@ CPSIE i
|
||||
@********************************************************************************************************
|
||||
|
||||
.thumb_func
|
||||
OS_CPU_PendSVHandler:
|
||||
CPSID I @ Cortex-M7 errata notice. See Note #5
|
||||
MOVW R2, #:lower16:OS_KA_BASEPRI_Boundary @ Set BASEPRI priority level required for exception preemption
|
||||
MOVT R2, #:upper16:OS_KA_BASEPRI_Boundary
|
||||
LDR R1, [R2]
|
||||
MSR BASEPRI, R1
|
||||
DSB
|
||||
ISB
|
||||
CPSIE I
|
||||
|
||||
MRS R0, PSP @ PSP is process stack pointer
|
||||
STMFD R0!, {R4-R11, R14} @ Save remaining regs r4-11, R14 on process stack
|
||||
|
||||
MOVW R5, #:lower16:OSTCBCurPtr @ OSTCBCurPtr->StkPtr = SP;
|
||||
MOVT R5, #:upper16:OSTCBCurPtr
|
||||
LDR R1, [R5]
|
||||
STR R0, [R1] @ R0 is SP of process being switched out
|
||||
|
||||
@ At this point, entire context of process has been saved
|
||||
MOV R4, LR @ Save LR exc_return value
|
||||
BL OSTaskSwHook @ Call OSTaskSwHook() for FPU Push & Pop
|
||||
|
||||
MOVW R0, #:lower16:OSPrioCur @ OSPrioCur = OSPrioHighRdy;
|
||||
MOVT R0, #:upper16:OSPrioCur
|
||||
MOVW R1, #:lower16:OSPrioHighRdy
|
||||
MOVT R1, #:upper16:OSPrioHighRdy
|
||||
LDRB R2, [R1]
|
||||
STRB R2, [R0]
|
||||
|
||||
MOVW R1, #:lower16:OSTCBHighRdyPtr @ OSTCBCurPtr = OSTCBHighRdyPtr;
|
||||
MOVT R1, #:upper16:OSTCBHighRdyPtr
|
||||
LDR R2, [R1]
|
||||
STR R2, [R5]
|
||||
|
||||
ORR LR, R4, #0x04 @ Ensure exception return uses process stack
|
||||
LDR R0, [R2] @ R0 is new process SP; SP = OSTCBHighRdyPtr->StkPtr;
|
||||
LDMFD R0!, {R4-R11, R14} @ Restore r4-11, R14 from new process stack
|
||||
MSR PSP, R0 @ Load PSP with new process SP
|
||||
|
||||
MOV R2, #0 @ Restore BASEPRI priority level to 0
|
||||
MSR BASEPRI, R2
|
||||
BX LR @ Exception return will restore remaining context
|
||||
|
||||
.end
|
||||
|
|
@ -0,0 +1,725 @@
|
|||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/OS-III
|
||||
* The Real-Time Kernel
|
||||
*
|
||||
* Copyright 2009-2020 Silicon Laboratories Inc. www.silabs.com
|
||||
*
|
||||
* SPDX-License-Identifier: APACHE-2.0
|
||||
*
|
||||
* This software is subject to an open source license and is distributed by
|
||||
* Silicon Laboratories Inc. pursuant to the terms of the Apache License,
|
||||
* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
*
|
||||
* ARMv7-M Port
|
||||
*
|
||||
* File : os_cpu_c.c
|
||||
* Version : V3.08.00
|
||||
*********************************************************************************************************
|
||||
* For : ARMv7-M Cortex-M
|
||||
* Mode : Thumb-2 ISA
|
||||
*********************************************************************************************************
|
||||
* Note(s) : (1) This port supports the ARM Cortex-M3, Cortex-M4 and Cortex-M7 architectures.
|
||||
* (2) It has been tested with the following Hardware Floating Point Unit.
|
||||
* (a) Single-precision: FPv4-SP-D16-M and FPv5-SP-D16-M
|
||||
* (b) Double-precision: FPv5-D16-M
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#define OS_CPU_GLOBALS
|
||||
|
||||
#ifdef VSC_INCLUDE_SOURCE_FILE_NAMES
|
||||
const CPU_CHAR *os_cpu_c__c = "$Id: $";
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* INCLUDE FILES
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#include "../../../Source/os.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* LOCAL GLOBAL VARIABLES
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
CPU_INT32U OS_KA_BASEPRI_Boundary; /* Base Priority boundary. */
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* FLOATING POINT DEFINES
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#define CPU_REG_FP_FPCCR (*((CPU_REG32 *)0xE000EF34uL)) /* Floating-Point Context Control Reg. */
|
||||
|
||||
/* Enabled FP lazy stacking and enable .. */
|
||||
/* ..automatic state saving. */
|
||||
#define CPU_REG_FPCCR_LAZY_STK 0xC0000000uL
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* OS INITIALIZATION HOOK
|
||||
*
|
||||
* Description: This function is called by OSInit() at the beginning of OSInit().
|
||||
*
|
||||
* Arguments : None.
|
||||
*
|
||||
* Note(s) : 1) When using hardware floating point please do the following during the reset handler:
|
||||
* a) Set full access for CP10 & CP11 bits in CPACR register.
|
||||
* b) Set bits ASPEN and LSPEN in FPCCR register.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void OSInitHook (void)
|
||||
{
|
||||
#if (OS_CPU_ARM_FP_EN > 0u)
|
||||
CPU_INT32U reg_val;
|
||||
#endif
|
||||
/* 8-byte align the ISR stack. */
|
||||
OS_CPU_ExceptStkBase = (CPU_STK *)(OSCfg_ISRStkBasePtr + OSCfg_ISRStkSize);
|
||||
OS_CPU_ExceptStkBase = (CPU_STK *)((CPU_STK)(OS_CPU_ExceptStkBase) & 0xFFFFFFF8);
|
||||
|
||||
#if (OS_CPU_ARM_FP_EN > 0u)
|
||||
reg_val = CPU_REG_FP_FPCCR; /* Check the floating point mode. */
|
||||
if ((reg_val & CPU_REG_FPCCR_LAZY_STK) != CPU_REG_FPCCR_LAZY_STK) {
|
||||
while (1u) { /* See Note (1). */
|
||||
;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* Set BASEPRI boundary from the configuration. */
|
||||
OS_KA_BASEPRI_Boundary = (CPU_INT32U)(CPU_CFG_KA_IPL_BOUNDARY << (8u - CPU_CFG_NVIC_PRIO_BITS));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* REDZONE HIT HOOK
|
||||
*
|
||||
* Description: This function is called when a task's stack overflowed.
|
||||
*
|
||||
* Arguments : p_tcb Pointer to the task control block of the offending task. NULL if ISR.
|
||||
*
|
||||
* Note(s) : None.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
#if (OS_CFG_TASK_STK_REDZONE_EN > 0u)
|
||||
void OSRedzoneHitHook (OS_TCB *p_tcb)
|
||||
{
|
||||
#if OS_CFG_APP_HOOKS_EN > 0u
|
||||
if (OS_AppRedzoneHitHookPtr != (OS_APP_HOOK_TCB)0) {
|
||||
(*OS_AppRedzoneHitHookPtr)(p_tcb);
|
||||
} else {
|
||||
CPU_SW_EXCEPTION(;);
|
||||
}
|
||||
#else
|
||||
(void)p_tcb; /* Prevent compiler warning */
|
||||
CPU_SW_EXCEPTION(;);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* INITIALIZE A TASK'S STACK
|
||||
*
|
||||
* Description: This function is called by either OSTaskCreate() 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.
|
||||
*
|
||||
* (3) There are two different stack frames depending on whether the Floating-Point(FP)
|
||||
* co-processor is enabled or not.
|
||||
*
|
||||
* (a) The stack frame shown in the diagram is used when the Co-processor Access Control
|
||||
* Register(CPACR) is disabling the Floating Point Unit. In this case, the FP
|
||||
* registers(S0- S31) & FP Status Control(FPSCR) register are not saved in the stack frame.
|
||||
*
|
||||
* (b) The stack frame shown in the diagram is used when the Floating Point Unit is enabled,
|
||||
* that is, CP10 and CP11 field in CPACR are ones and FPCCR sets bits ASPEN and LSPEN to 1.
|
||||
*
|
||||
* (1) When enabling the FPU through CPACR, make sure to set bits ASPEN and LSPEN in the
|
||||
* Floating-Point Context Control Register (FPCCR).
|
||||
*
|
||||
* +-------------+
|
||||
* | |
|
||||
* +-------------+
|
||||
* | |
|
||||
* +-------------+
|
||||
* | FPSCR |
|
||||
* +-------------+
|
||||
* | S15 |
|
||||
* +-------------+
|
||||
* | S14 |
|
||||
* +-------------+
|
||||
* | S13 |
|
||||
* +-------------+
|
||||
* .
|
||||
* .
|
||||
* .
|
||||
* +-------------+
|
||||
* | S2 |
|
||||
* +-------------+
|
||||
* | S1 |
|
||||
* +-------------+ +-------------+
|
||||
* | | | S0 |
|
||||
* +-------------+ +-------------+
|
||||
* | xPSR | | xPSR |
|
||||
* +-------------+ +-------------+
|
||||
* | Return Addr | | Return Addr |
|
||||
* +-------------+ +-------------+
|
||||
* | LR(R14) | | LR(R14) |
|
||||
* +-------------+ +-------------+
|
||||
* | R12 | | R12 |
|
||||
* +-------------+ +-------------+
|
||||
* | R3 | | R3 |
|
||||
* +-------------+ +-------------+
|
||||
* | R2 | | R0 |
|
||||
* +-------------+ +-------------+
|
||||
* | R1 | | R1 |
|
||||
* +-------------+ +-------------+
|
||||
* | R0 | | R0 |
|
||||
* +-------------+ +-------------+
|
||||
* | EXEC_RETURN | | EXEC_RETURN |
|
||||
* +-------------+ +-------------+
|
||||
* | R11 | | R11 |
|
||||
* +-------------+ +-------------+
|
||||
* | R10 | | R10 |
|
||||
* +-------------+ +-------------+
|
||||
* | R9 | | R9 |
|
||||
* +-------------+ +-------------+
|
||||
* | R8 | | R8 |
|
||||
* +-------------+ +-------------+
|
||||
* | R7 | | R7 |
|
||||
* +-------------+ +-------------+
|
||||
* | R6 | | R6 |
|
||||
* +-------------+ +-------------+
|
||||
* | R5 | | R5 |
|
||||
* +-------------+ +-------------+
|
||||
* | R4 | | R4 |
|
||||
* +-------------+ +-------------+
|
||||
* (a) | S31 |
|
||||
* +-------------+
|
||||
* | S30 |
|
||||
* +-------------+
|
||||
* | S29 |
|
||||
+-------------+
|
||||
* .
|
||||
* .
|
||||
* .
|
||||
* +-------------+
|
||||
* | S17 |
|
||||
+-------------+
|
||||
* | S16 |
|
||||
* +-------------+
|
||||
* (b)
|
||||
*
|
||||
* (4) The SP must be 8-byte aligned in conforming to the Procedure Call Standard for the ARM architecture
|
||||
*
|
||||
* (a) Section 2.1 of the ABI for the ARM Architecture Advisory Note. SP must be 8-byte aligned
|
||||
* on entry to AAPCS-Conforming functions states :
|
||||
*
|
||||
* The Procedure Call Standard for the ARM Architecture [AAPCS] requires primitive
|
||||
* data types to be naturally aligned according to their sizes (for size = 1, 2, 4, 8 bytes).
|
||||
* Doing otherwise creates more problems than it solves.
|
||||
*
|
||||
* In return for preserving the natural alignment of data, conforming code is permitted
|
||||
* to rely on that alignment. To support aligning data allocated on the stack, the stack
|
||||
* pointer (SP) is required to be 8-byte aligned on entry to a conforming function. In
|
||||
* practice this requirement is met if:
|
||||
*
|
||||
* (1) At each call site, the current size of the calling function's stack frame is a multiple of 8 bytes.
|
||||
* This places an obligation on compilers and assembly language programmers.
|
||||
*
|
||||
* (2) SP is a multiple of 8 when control first enters a program.
|
||||
* This places an obligation on authors of low level OS, RTOS, and runtime library
|
||||
* code to align SP at all points at which control first enters
|
||||
* a body of (AAPCS-conforming) code.
|
||||
*
|
||||
* In turn, this requires the value of SP to be aligned to 0 modulo 8:
|
||||
*
|
||||
* (3) By exception handlers, before calling AAPCS-conforming code.
|
||||
*
|
||||
* (4) By OS/RTOS/run-time system code, before giving control to an application.
|
||||
*
|
||||
* (b) Section 2.3.1 corrective steps from the the SP must be 8-byte aligned on entry
|
||||
* to AAPCS-conforming functions advisory note also states.
|
||||
*
|
||||
* " This requirement extends to operating systems and run-time code for all architecture versions
|
||||
* prior to ARMV7 and to the A, R and M architecture profiles thereafter. Special considerations
|
||||
* associated with ARMV7M are discussed in section 2.3.3"
|
||||
*
|
||||
* (1) Even if the SP 8-byte aligment is not a requirement for the ARMv7M profile, the stack is aligned
|
||||
* to 8-byte boundaries to support legacy execution enviroments.
|
||||
*
|
||||
* (c) Section 5.2.1.2 from the Procedure Call Standard for the ARM
|
||||
* architecture states : "The stack must also conform to the following
|
||||
* constraint at a public interface:
|
||||
*
|
||||
* (1) SP mod 8 = 0. The stack must be double-word aligned"
|
||||
*
|
||||
* (d) From the ARM Technical Support Knowledge Base. 8 Byte stack aligment.
|
||||
*
|
||||
* "8 byte stack alignment is a requirement of the ARM Architecture Procedure
|
||||
* Call Standard [AAPCS]. This specifies that functions must maintain an 8 byte
|
||||
* aligned stack address (e.g. 0x00, 0x08, 0x10, 0x18, 0x20) on all external
|
||||
* interfaces. In practice this requirement is met if:
|
||||
*
|
||||
* (1) At each external interface, the current stack pointer
|
||||
* is a multiple of 8 bytes.
|
||||
*
|
||||
* (2) Your OS maintains 8 byte stack alignment on its external interfaces
|
||||
* e.g. on task switches"
|
||||
*
|
||||
* (5) Exception Return Behavior(EXEC_RETURN)
|
||||
* 0xFFFFFFFD Return to Thread mode, exception return uses non-floating point state
|
||||
* from the PSP and execution uses PSP after return.
|
||||
*
|
||||
* 0xFFFFFFED Return to Thread mode, exception return uses floating point state
|
||||
* from the PSP and execution uses PSP after return.
|
||||
**********************************************************************************************************
|
||||
*/
|
||||
|
||||
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; /* 'opt' is not used, prevent warning */
|
||||
|
||||
p_stk = &p_stk_base[stk_size]; /* Load stack pointer */
|
||||
/* Align the stack to 8-bytes. */
|
||||
p_stk = (CPU_STK *)((CPU_STK)(p_stk) & 0xFFFFFFF8u);
|
||||
/* Registers stacked as if auto-saved on exception */
|
||||
#if (OS_CPU_ARM_FP_EN > 0u) /* FPU auto-saved registers. */
|
||||
--p_stk;
|
||||
*(--p_stk) = (CPU_STK)0x02000000u; /* FPSCR */
|
||||
/* Initialize S0-S15 floating point registers */
|
||||
*(--p_stk) = (CPU_STK)0x41700000u; /* S15 */
|
||||
*(--p_stk) = (CPU_STK)0x41600000u; /* S14 */
|
||||
*(--p_stk) = (CPU_STK)0x41500000u; /* S13 */
|
||||
*(--p_stk) = (CPU_STK)0x41400000u; /* S12 */
|
||||
*(--p_stk) = (CPU_STK)0x41300000u; /* S11 */
|
||||
*(--p_stk) = (CPU_STK)0x41200000u; /* S10 */
|
||||
*(--p_stk) = (CPU_STK)0x41100000u; /* S9 */
|
||||
*(--p_stk) = (CPU_STK)0x41000000u; /* S8 */
|
||||
*(--p_stk) = (CPU_STK)0x40E00000u; /* S7 */
|
||||
*(--p_stk) = (CPU_STK)0x40C00000u; /* S6 */
|
||||
*(--p_stk) = (CPU_STK)0x40A00000u; /* S5 */
|
||||
*(--p_stk) = (CPU_STK)0x40800000u; /* S4 */
|
||||
*(--p_stk) = (CPU_STK)0x40400000u; /* S3 */
|
||||
*(--p_stk) = (CPU_STK)0x40000000u; /* S2 */
|
||||
*(--p_stk) = (CPU_STK)0x3F800000u; /* S1 */
|
||||
*(--p_stk) = (CPU_STK)0x00000000u; /* S0 */
|
||||
#endif
|
||||
*(--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 */
|
||||
|
||||
#if (OS_CPU_ARM_FP_EN > 0u)
|
||||
*(--p_stk) = (CPU_STK)0xFFFFFFEDuL; /* R14: EXEC_RETURN; See Note 5 */
|
||||
#else
|
||||
*(--p_stk) = (CPU_STK)0xFFFFFFFDuL; /* R14: EXEC_RETURN; See Note 5 */
|
||||
#endif
|
||||
/* Remaining registers saved on process stack */
|
||||
*(--p_stk) = (CPU_STK)0x11111111uL; /* R11 */
|
||||
*(--p_stk) = (CPU_STK)0x10101010uL; /* R10 */
|
||||
*(--p_stk) = (CPU_STK)0x09090909uL; /* R9 */
|
||||
*(--p_stk) = (CPU_STK)0x08080808uL; /* R8 */
|
||||
*(--p_stk) = (CPU_STK)0x07070707uL; /* R7 */
|
||||
*(--p_stk) = (CPU_STK)0x06060606uL; /* R6 */
|
||||
*(--p_stk) = (CPU_STK)0x05050505uL; /* R5 */
|
||||
*(--p_stk) = (CPU_STK)0x04040404uL; /* R4 */
|
||||
|
||||
#if (OS_CPU_ARM_FP_EN > 0u)
|
||||
/* Initialize S16-S31 floating point registers */
|
||||
*(--p_stk) = (CPU_STK)0x41F80000u; /* S31 */
|
||||
*(--p_stk) = (CPU_STK)0x41F00000u; /* S30 */
|
||||
*(--p_stk) = (CPU_STK)0x41E80000u; /* S29 */
|
||||
*(--p_stk) = (CPU_STK)0x41E00000u; /* S28 */
|
||||
*(--p_stk) = (CPU_STK)0x41D80000u; /* S27 */
|
||||
*(--p_stk) = (CPU_STK)0x41D00000u; /* S26 */
|
||||
*(--p_stk) = (CPU_STK)0x41C80000u; /* S25 */
|
||||
*(--p_stk) = (CPU_STK)0x41C00000u; /* S24 */
|
||||
*(--p_stk) = (CPU_STK)0x41B80000u; /* S23 */
|
||||
*(--p_stk) = (CPU_STK)0x41B00000u; /* S22 */
|
||||
*(--p_stk) = (CPU_STK)0x41A80000u; /* S21 */
|
||||
*(--p_stk) = (CPU_STK)0x41A00000u; /* S20 */
|
||||
*(--p_stk) = (CPU_STK)0x41980000u; /* S19 */
|
||||
*(--p_stk) = (CPU_STK)0x41900000u; /* S18 */
|
||||
*(--p_stk) = (CPU_STK)0x41880000u; /* S17 */
|
||||
*(--p_stk) = (CPU_STK)0x41800000u; /* S16 */
|
||||
#endif
|
||||
|
||||
return (p_stk);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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_TASK_STK_REDZONE_EN > 0u)
|
||||
CPU_BOOLEAN stk_status;
|
||||
#endif
|
||||
|
||||
#if (OS_CPU_ARM_FP_EN > 0u)
|
||||
OS_CPU_FP_Reg_Push(OSTCBCurPtr->StkPtr); /* Push the FP registers of the current task. */
|
||||
#endif
|
||||
|
||||
#if OS_CFG_APP_HOOKS_EN > 0u
|
||||
if (OS_AppTaskSwHookPtr != (OS_APP_HOOK_VOID)0) {
|
||||
(*OS_AppTaskSwHookPtr)();
|
||||
}
|
||||
#endif
|
||||
|
||||
OS_TRACE_TASK_SWITCHED_IN(OSTCBHighRdyPtr);
|
||||
|
||||
#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
|
||||
|
||||
#if (OS_CFG_TASK_STK_REDZONE_EN > 0u)
|
||||
/* Check if stack overflowed. */
|
||||
stk_status = OSTaskStkRedzoneChk((OS_TCB *)0u);
|
||||
if (stk_status != OS_TRUE) {
|
||||
OSRedzoneHitHook(OSTCBCurPtr);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (OS_CPU_ARM_FP_EN > 0u)
|
||||
OS_CPU_FP_Reg_Pop(OSTCBHighRdyPtr->StkPtr); /* Pop the FP registers of the highest ready task. */
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* SYS TICK HANDLER
|
||||
*
|
||||
* Description: Handle the system tick (SysTick) interrupt, which is used to generate the uC/OS-III tick
|
||||
* interrupt.
|
||||
*
|
||||
* Arguments : None.
|
||||
*
|
||||
* Note(s) : 1) This function MUST be placed on entry 15 of the Cortex-M vector table.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void OS_CPU_SysTickHandler (void)
|
||||
{
|
||||
CPU_SR_ALLOC();
|
||||
|
||||
|
||||
CPU_CRITICAL_ENTER();
|
||||
OSIntEnter(); /* 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 */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* INITIALIZE SYS TICK
|
||||
*
|
||||
* Description: Initialize the SysTick using the CPU clock frequency.
|
||||
*
|
||||
* Arguments : cpu_freq CPU clock frequency.
|
||||
*
|
||||
* Note(s) : 1) This function MUST be called after OSStart() & after processor initialization.
|
||||
*
|
||||
* 2) Either OS_CPU_SysTickInitFreq or OS_CPU_SysTickInit() can be called.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void OS_CPU_SysTickInitFreq (CPU_INT32U cpu_freq)
|
||||
{
|
||||
#if (OS_CFG_TICK_EN > 0u)
|
||||
CPU_INT32U cnts;
|
||||
|
||||
|
||||
cnts = (cpu_freq / (CPU_INT32U)OSCfg_TickRate_Hz); /* Determine nbr SysTick cnts between two OS tick intr. */
|
||||
|
||||
OS_CPU_SysTickInit(cnts);
|
||||
#else
|
||||
(void)cpu_freq;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* INITIALIZE SYS TICK
|
||||
*
|
||||
* Description: Initialize the SysTick using the number of countes between two ticks.
|
||||
*
|
||||
* Arguments : cnts Number of SysTick counts between two OS tick interrupts.
|
||||
*
|
||||
* Note(s) : 1) This function MUST be called after OSStart() & after processor initialization.
|
||||
*
|
||||
* 2) Either OS_CPU_SysTickInitFreq or OS_CPU_SysTickInit() can be called.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void OS_CPU_SysTickInit (CPU_INT32U cnts)
|
||||
{
|
||||
#if (OS_CFG_TICK_EN > 0u)
|
||||
CPU_INT32U prio;
|
||||
CPU_INT32U basepri;
|
||||
|
||||
|
||||
/* Set BASEPRI boundary from the configuration. */
|
||||
basepri = (CPU_INT32U)(CPU_CFG_KA_IPL_BOUNDARY << (8u - CPU_CFG_NVIC_PRIO_BITS));
|
||||
CPU_REG_SYST_RVR = cnts - 1u; /* Set Reload Register */
|
||||
|
||||
/* Set SysTick handler prio. */
|
||||
prio = CPU_REG_SCB_SHPRI3;
|
||||
prio &= 0x00FFFFFFu;
|
||||
prio |= (basepri << 24u);
|
||||
|
||||
CPU_REG_SCB_SHPRI3 = prio;
|
||||
|
||||
/* Enable timer. */
|
||||
CPU_REG_SYST_CSR |= CPU_REG_SYST_CSR_CLKSOURCE |
|
||||
CPU_REG_SYST_CSR_ENABLE;
|
||||
|
||||
CPU_REG_SYST_CSR |= CPU_REG_SYST_CSR_TICKINT; /* Enable timer interrupt. */
|
||||
#else
|
||||
(void)cnts;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/OS-III
|
||||
* The Real-Time Kernel
|
||||
*
|
||||
* Copyright 2009-2020 Silicon Laboratories Inc. www.silabs.com
|
||||
*
|
||||
* SPDX-License-Identifier: APACHE-2.0
|
||||
*
|
||||
* This software is subject to an open source license and is distributed by
|
||||
* Silicon Laboratories Inc. pursuant to the terms of the Apache License,
|
||||
* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* POSIX GNU Port
|
||||
*
|
||||
* File : os_cpu.h
|
||||
* Version : V3.08.00
|
||||
*********************************************************************************************************
|
||||
* For : POSIX
|
||||
* Toolchain : GNU
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef OS_CPU_H
|
||||
#define OS_CPU_H
|
||||
|
||||
#ifdef OS_CPU_GLOBALS
|
||||
#define OS_CPU_EXT
|
||||
#else
|
||||
#define OS_CPU_EXT extern
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* MACROS
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#define OS_TASK_SW() OSCtxSw()
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* FUNCTION PROTOTYPES
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void OSCtxSw (void);
|
||||
void OSIntCtxSw (void);
|
||||
|
||||
void OSStartHighRdy (void);
|
||||
|
||||
void OS_CPU_SysTickInit (void);
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,730 @@
|
|||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/OS-III
|
||||
* The Real-Time Kernel
|
||||
*
|
||||
* Copyright 2009-2020 Silicon Laboratories Inc. www.silabs.com
|
||||
*
|
||||
* SPDX-License-Identifier: APACHE-2.0
|
||||
*
|
||||
* This software is subject to an open source license and is distributed by
|
||||
* Silicon Laboratories Inc. pursuant to the terms of the Apache License,
|
||||
* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* POSIX GNU Port
|
||||
*
|
||||
* File : os_cpu_c.c
|
||||
* Version : V3.08.00
|
||||
*********************************************************************************************************
|
||||
* For : POSIX
|
||||
* Toolchain : GNU
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
#define OS_CPU_GLOBALS
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#ifdef VSC_INCLUDE_SOURCE_FILE_NAMES
|
||||
const CPU_CHAR *os_cpu_c__c = "$Id: $";
|
||||
#endif
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* INCLUDE FILES
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#include "../../Source/os.h"
|
||||
#include <os_cfg_app.h>
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <pthread.h>
|
||||
#include <stdint.h>
|
||||
#include <signal.h>
|
||||
#include <semaphore.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/resource.h>
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* LOCAL DEFINES
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#define THREAD_CREATE_PRIO 50u /* Tasks underlying posix threads prio. */
|
||||
|
||||
/* Err handling convenience macro. */
|
||||
#define ERR_CHK(func) do {int res = func; \
|
||||
if (res != 0u) { \
|
||||
printf("Error in call '%s' from %s(): %s\r\n", #func, __FUNCTION__, strerror(res)); \
|
||||
perror(" \\->'errno' indicates (might not be relevant if function doesn't use 'errno')"); \
|
||||
raise(SIGABRT); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* LOCAL DATA TYPES
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
typedef struct os_tcb_ext_posix {
|
||||
pthread_t Thread;
|
||||
pid_t ProcessId;
|
||||
sem_t InitSem;
|
||||
sem_t Sem;
|
||||
} OS_TCB_EXT_POSIX;
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* LOCAL FUNCTION PROTOTYPES
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
static void *OSTaskPosix (void *p_arg);
|
||||
|
||||
static void OSTaskTerminate (OS_TCB *p_tcb);
|
||||
|
||||
static void OSThreadCreate (pthread_t *p_thread,
|
||||
void *p_task,
|
||||
void *p_arg,
|
||||
int prio);
|
||||
|
||||
static void OSTimeTickHandler (void);
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* LOCAL VARIABLES
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
/* Tick timer cfg. */
|
||||
static CPU_TMR_INTERRUPT OSTickTmrInterrupt = { .Interrupt.NamePtr = "Tick tmr interrupt",
|
||||
.Interrupt.Prio = 10u,
|
||||
.Interrupt.TraceEn = 0u,
|
||||
.Interrupt.ISR_Fnct = OSTimeTickHandler,
|
||||
.Interrupt.En = 1u,
|
||||
.OneShot = 0u,
|
||||
.PeriodSec = 0u,
|
||||
.PeriodMuSec = (1000000u / OS_CFG_TICK_RATE_HZ)
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* LOCAL CONFIGURATION ERRORS
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#if (OS_CFG_TICK_RATE_HZ > 100u)
|
||||
#warning "Time accuracy cannot be maintained with OS_CFG_TICK_RATE_HZ > 100u.\n\n",
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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
|
||||
|
||||
sleep(1u); /* Reduce CPU utilization. */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* OS INITIALIZATION HOOK
|
||||
*
|
||||
* Description: This function is called by OSInit() at the beginning of OSInit().
|
||||
*
|
||||
* Arguments : None.
|
||||
*
|
||||
* Note(s) : 1) Interrupts should be disabled during this call.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
void OSInitHook (void)
|
||||
{
|
||||
struct rlimit rtprio_limits;
|
||||
|
||||
|
||||
ERR_CHK(getrlimit(RLIMIT_RTPRIO, &rtprio_limits));
|
||||
if (rtprio_limits.rlim_cur != RLIM_INFINITY) {
|
||||
printf("Error: RTPRIO limit is too low. Set to 'unlimited' via 'ulimit -r' or /etc/security/limits.conf\r\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
CPU_IntInit(); /* Initialize critical section objects. */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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) : 1) Interrupts are disabled during this call.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void OSTaskCreateHook (OS_TCB *p_tcb)
|
||||
{
|
||||
OS_TCB_EXT_POSIX *p_tcb_ext;
|
||||
int ret;
|
||||
|
||||
|
||||
#if OS_CFG_APP_HOOKS_EN > 0u
|
||||
if (OS_AppTaskCreateHookPtr != (OS_APP_HOOK_TCB)0) {
|
||||
(*OS_AppTaskCreateHookPtr)(p_tcb);
|
||||
}
|
||||
#endif
|
||||
|
||||
p_tcb_ext = malloc(sizeof(OS_TCB_EXT_POSIX));
|
||||
p_tcb->ExtPtr = p_tcb_ext;
|
||||
|
||||
ERR_CHK(sem_init(&p_tcb_ext->InitSem, 0u, 0u));
|
||||
ERR_CHK(sem_init(&p_tcb_ext->Sem, 0u, 0u));
|
||||
|
||||
OSThreadCreate(&p_tcb_ext->Thread, OSTaskPosix, p_tcb, THREAD_CREATE_PRIO);
|
||||
|
||||
do {
|
||||
ret = sem_wait(&p_tcb_ext->InitSem); /* Wait for init. */
|
||||
if (ret != 0 && errno != EINTR) {
|
||||
raise(SIGABRT);
|
||||
}
|
||||
} while (ret != 0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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) : 1) Interrupts are disabled during this call.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void OSTaskDelHook (OS_TCB *p_tcb)
|
||||
{
|
||||
OS_TCB_EXT_POSIX *p_tcb_ext = (OS_TCB_EXT_POSIX *)p_tcb->ExtPtr;
|
||||
pthread_t self;
|
||||
CPU_BOOLEAN same;
|
||||
|
||||
|
||||
#if OS_CFG_APP_HOOKS_EN > 0u
|
||||
if (OS_AppTaskDelHookPtr != (OS_APP_HOOK_TCB)0) {
|
||||
(*OS_AppTaskDelHookPtr)(p_tcb);
|
||||
}
|
||||
#endif
|
||||
|
||||
self = pthread_self();
|
||||
same = (pthread_equal(self, p_tcb_ext->Thread) != 0u);
|
||||
if (same != 1u) {
|
||||
ERR_CHK(pthread_cancel(p_tcb_ext->Thread));
|
||||
}
|
||||
|
||||
OSTaskTerminate(p_tcb);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
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)
|
||||
{
|
||||
return (p_stk_base);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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 < (CPU_TS)OSSchedLockTimeMaxCur) {
|
||||
OSTCBCurPtr->SchedLockTimeMax = (CPU_TS)OSSchedLockTimeMaxCur;
|
||||
}
|
||||
OSSchedLockTimeMaxCur = (CPU_TS)0; /* Reset the per-task value */
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* 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
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* START HIGHEST PRIORITY TASK READY-TO-RUN
|
||||
*
|
||||
* Description: This function is called by OSStart() to start the highest priority task that was created
|
||||
* by your application before calling OSStart().
|
||||
*
|
||||
* Arguments : None.
|
||||
*
|
||||
* Note(s) : 1) OSStartHighRdy() MUST:
|
||||
* a) Call OSTaskSwHook() then,
|
||||
* b) Switch to the highest priority task.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void OSStartHighRdy (void)
|
||||
{
|
||||
OS_TCB_EXT_POSIX *p_tcb_ext;
|
||||
sigset_t sig_set;
|
||||
int signo;
|
||||
|
||||
|
||||
OSTaskSwHook();
|
||||
|
||||
p_tcb_ext = (OS_TCB_EXT_POSIX *)OSTCBCurPtr->ExtPtr;
|
||||
|
||||
CPU_INT_DIS();
|
||||
|
||||
ERR_CHK(sem_post(&p_tcb_ext->Sem));
|
||||
|
||||
ERR_CHK(sigemptyset(&sig_set));
|
||||
ERR_CHK(sigaddset(&sig_set, SIGTERM));
|
||||
ERR_CHK(sigwait(&sig_set, &signo));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* TASK LEVEL CONTEXT SWITCH
|
||||
*
|
||||
* Description: This function is called when a task makes a higher priority task ready-to-run.
|
||||
*
|
||||
* Arguments : None.
|
||||
*
|
||||
* Note(s) : 1) Upon entry,
|
||||
* OSTCBCur points to the OS_TCB of the task to suspend
|
||||
* OSTCBHighRdy points to the OS_TCB of the task to resume
|
||||
*
|
||||
* 2) OSCtxSw() MUST:
|
||||
* a) Save processor registers then,
|
||||
* b) Save current task's stack pointer into the current task's OS_TCB,
|
||||
* c) Call OSTaskSwHook(),
|
||||
* d) Set OSTCBCur = OSTCBHighRdy,
|
||||
* e) Set OSPrioCur = OSPrioHighRdy,
|
||||
* f) Switch to the highest priority task.
|
||||
*
|
||||
* pseudo-code:
|
||||
* void OSCtxSw (void)
|
||||
* {
|
||||
* Save processor registers;
|
||||
*
|
||||
* OSTCBCur->OSTCBStkPtr = SP;
|
||||
*
|
||||
* OSTaskSwHook();
|
||||
*
|
||||
* OSTCBCur = OSTCBHighRdy;
|
||||
* OSPrioCur = OSPrioHighRdy;
|
||||
*
|
||||
* Restore processor registers from (OSTCBHighRdy->OSTCBStkPtr);
|
||||
* }
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void OSCtxSw (void)
|
||||
{
|
||||
OS_TCB_EXT_POSIX *p_tcb_ext_old;
|
||||
OS_TCB_EXT_POSIX *p_tcb_ext_new;
|
||||
int ret;
|
||||
CPU_BOOLEAN detach = 0u;
|
||||
|
||||
|
||||
OSTaskSwHook();
|
||||
|
||||
p_tcb_ext_new = (OS_TCB_EXT_POSIX *)OSTCBHighRdyPtr->ExtPtr;
|
||||
p_tcb_ext_old = (OS_TCB_EXT_POSIX *)OSTCBCurPtr->ExtPtr;
|
||||
|
||||
if (OSTCBCurPtr->TaskState == OS_TASK_STATE_DEL) {
|
||||
detach = 1u;
|
||||
}
|
||||
|
||||
OSTCBCurPtr = OSTCBHighRdyPtr;
|
||||
OSPrioCur = OSPrioHighRdy;
|
||||
|
||||
ERR_CHK(sem_post(&p_tcb_ext_new->Sem));
|
||||
|
||||
if (detach == 0u) {
|
||||
do {
|
||||
ret = sem_wait(&p_tcb_ext_old->Sem);
|
||||
if (ret != 0 && errno != EINTR) {
|
||||
raise(SIGABRT);
|
||||
}
|
||||
} while (ret != 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* INTERRUPT LEVEL CONTEXT SWITCH
|
||||
*
|
||||
* Description: This function is called by OSIntExit() to perform a context switch from an ISR.
|
||||
*
|
||||
* Arguments : None.
|
||||
*
|
||||
* Note(s) : 1) OSIntCtxSw() MUST:
|
||||
* a) Call OSTaskSwHook() then,
|
||||
* b) Set OSTCBCurPtr = OSTCBHighRdyPtr,
|
||||
* c) Set OSPrioCur = OSPrioHighRdy,
|
||||
* d) Switch to the highest priority task.
|
||||
*
|
||||
* 2) OSIntCurTaskSuspend() MUST be called prior to OSIntEnter().
|
||||
*
|
||||
* 3) OSIntCurTaskResume() MUST be called after OSIntExit() to switch to the highest
|
||||
* priority task.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void OSIntCtxSw (void)
|
||||
{
|
||||
if (OSTCBCurPtr != OSTCBHighRdyPtr) {
|
||||
OSCtxSw();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* INITIALIZE SYS TICK
|
||||
*
|
||||
* Description: Initialize the SysTick.
|
||||
*
|
||||
* Arguments : none.
|
||||
*
|
||||
* Note(s) : 1) This function MUST be called after OSStart() & after processor initialization.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
void OS_CPU_SysTickInit (void)
|
||||
{
|
||||
CPU_TmrInterruptCreate(&OSTickTmrInterrupt);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
*********************************************************************************************************
|
||||
* LOCAL FUNCTIONS
|
||||
*********************************************************************************************************
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
static void OSTimeTickHandler (void)
|
||||
{
|
||||
OSIntEnter();
|
||||
OSTimeTick();
|
||||
CPU_ISR_End();
|
||||
OSIntExit();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* OSTaskPosix()
|
||||
*
|
||||
* Description: This function is a generic POSIX task wrapper for uC/OS-III tasks.
|
||||
*
|
||||
* Arguments : p_arg Pointer to argument of the task's TCB.
|
||||
*
|
||||
* Note(s) : 1) Priorities of these tasks are very important.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
static void *OSTaskPosix (void *p_arg)
|
||||
{
|
||||
OS_TCB_EXT_POSIX *p_tcb_ext;
|
||||
OS_TCB *p_tcb;
|
||||
OS_ERR err;
|
||||
|
||||
|
||||
p_tcb = (OS_TCB *)p_arg;
|
||||
p_tcb_ext = (OS_TCB_EXT_POSIX *)p_tcb->ExtPtr;
|
||||
|
||||
p_tcb_ext->ProcessId = syscall(SYS_gettid);
|
||||
ERR_CHK(sem_post(&p_tcb_ext->InitSem));
|
||||
|
||||
#ifdef OS_CFG_MSG_TRACE_EN
|
||||
if (p_tcb->NamePtr != (CPU_CHAR *)0) {
|
||||
printf("Task[%3.1d] '%-32s' running\n", p_tcb->Prio, p_tcb->NamePtr);
|
||||
}
|
||||
#endif
|
||||
|
||||
CPU_INT_DIS();
|
||||
{
|
||||
int ret = -1u;
|
||||
while (ret != 0u) {
|
||||
ret = sem_wait(&p_tcb_ext->Sem); /* Wait until first CTX SW. */
|
||||
if ((ret != 0) && (ret != -EINTR)) {
|
||||
ERR_CHK(ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
CPU_INT_EN();
|
||||
|
||||
((void (*)(void *))p_tcb->TaskEntryAddr)(p_tcb->TaskEntryArg);
|
||||
|
||||
OSTaskDel(p_tcb, &err); /* Thread may exit at OSCtxSw(). */
|
||||
|
||||
return (0u);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* OSTaskTerminate()
|
||||
*
|
||||
* Description: This function handles task termination control signals.
|
||||
*
|
||||
* Arguments : p_task Pointer to the task information structure of the task to clear its control
|
||||
* signals.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
static void OSTaskTerminate (OS_TCB *p_tcb)
|
||||
{
|
||||
#ifdef OS_CFG_MSG_TRACE_EN
|
||||
if (p_tcb->NamePtr != (CPU_CHAR *)0) {
|
||||
printf("Task[%3.1d] '%-32s' deleted\n", p_tcb->Prio, p_tcb->NamePtr);
|
||||
}
|
||||
#endif
|
||||
|
||||
free(p_tcb->ExtPtr);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* OSThreadCreate()
|
||||
*
|
||||
* Description : Create new posix thread.
|
||||
*
|
||||
* Argument(s) : p_thread Pointer to preallocated thread variable.
|
||||
*
|
||||
* p_task Pointer to associated function.
|
||||
*
|
||||
* p_arg Pointer to associated function's argument.
|
||||
*
|
||||
* prio Thread priority.
|
||||
*
|
||||
* Return(s) : Thread's corresponding LWP pid.
|
||||
*
|
||||
* Note(s) : none.
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
static void OSThreadCreate (pthread_t *p_thread,
|
||||
void *p_task,
|
||||
void *p_arg,
|
||||
int prio)
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
struct sched_param param;
|
||||
|
||||
|
||||
if (prio < sched_get_priority_min(SCHED_RR) ||
|
||||
prio > sched_get_priority_max(SCHED_RR)) {
|
||||
#ifdef OS_CFG_MSG_TRACE_EN
|
||||
printf("ThreadCreate(): Invalid prio arg.\n");
|
||||
#endif
|
||||
raise(SIGABRT);
|
||||
}
|
||||
|
||||
ERR_CHK(pthread_attr_init(&attr));
|
||||
ERR_CHK(pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED));
|
||||
param.__sched_priority = prio;
|
||||
ERR_CHK(pthread_attr_setschedpolicy(&attr, SCHED_RR));
|
||||
ERR_CHK(pthread_attr_setschedparam(&attr, ¶m));
|
||||
ERR_CHK(pthread_create(p_thread, &attr, p_task, p_arg));
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/OS-III
|
||||
* The Real-Time Kernel
|
||||
*
|
||||
* Copyright 2009-2020 Silicon Laboratories Inc. www.silabs.com
|
||||
*
|
||||
* SPDX-License-Identifier: APACHE-2.0
|
||||
*
|
||||
* This software is subject to an open source license and is distributed by
|
||||
* Silicon Laboratories Inc. pursuant to the terms of the Apache License,
|
||||
* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* VARIABLES
|
||||
*
|
||||
* File : __dbg_uCOS-III.C
|
||||
* Version : V3.08.00
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#define OS_GLOBALS
|
||||
|
||||
#include "os.h"
|
||||
|
||||
#ifdef VSC_INCLUDE_SOURCE_FILE_NAMES
|
||||
const CPU_CHAR *__dbg_uCOS_III__c = "$Id: $";
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,253 @@
|
|||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/OS-III
|
||||
* The Real-Time Kernel
|
||||
*
|
||||
* Copyright 2009-2020 Silicon Laboratories Inc. www.silabs.com
|
||||
*
|
||||
* SPDX-License-Identifier: APACHE-2.0
|
||||
*
|
||||
* This software is subject to an open source license and is distributed by
|
||||
* Silicon Laboratories Inc. pursuant to the terms of the Apache License,
|
||||
* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* OS CONFIGURATION (APPLICATION SPECIFICS)
|
||||
*
|
||||
* File : os_cfg_app.c
|
||||
* Version : V3.08.00
|
||||
*********************************************************************************************************
|
||||
* 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
|
||||
|
||||
#if (OS_CFG_TASK_IDLE_EN > 0u)
|
||||
#define OS_CFG_IDLE_TASK_STK_LIMIT ((OS_CFG_IDLE_TASK_STK_SIZE * OS_CFG_TASK_STK_LIMIT_PCT_EMPTY) / 100u)
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_STAT_TASK_EN > 0u)
|
||||
#define OS_CFG_STAT_TASK_STK_LIMIT ((OS_CFG_STAT_TASK_STK_SIZE * OS_CFG_TASK_STK_LIMIT_PCT_EMPTY) / 100u)
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_TMR_EN > 0u)
|
||||
#define OS_CFG_TMR_TASK_STK_LIMIT ((OS_CFG_TMR_TASK_STK_SIZE * OS_CFG_TASK_STK_LIMIT_PCT_EMPTY) / 100u)
|
||||
#endif
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* DATA STORAGE
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
|
||||
#if (OS_CFG_TASK_IDLE_EN > 0u)
|
||||
CPU_STK OSCfg_IdleTaskStk [OS_CFG_IDLE_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
|
||||
|
||||
#if (OS_CFG_TMR_EN > 0u)
|
||||
CPU_STK OSCfg_TmrTaskStk [OS_CFG_TMR_TASK_STK_SIZE];
|
||||
#endif
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* CONSTANTS
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
|
||||
#if (OS_CFG_TASK_IDLE_EN > 0u)
|
||||
CPU_STK * const OSCfg_IdleTaskStkBasePtr = &OSCfg_IdleTaskStk[0];
|
||||
CPU_STK_SIZE const OSCfg_IdleTaskStkLimit = OS_CFG_IDLE_TASK_STK_LIMIT;
|
||||
CPU_STK_SIZE const OSCfg_IdleTaskStkSize = OS_CFG_IDLE_TASK_STK_SIZE;
|
||||
CPU_INT32U const OSCfg_IdleTaskStkSizeRAM = sizeof(OSCfg_IdleTaskStk);
|
||||
#else
|
||||
CPU_STK * const OSCfg_IdleTaskStkBasePtr = (CPU_STK *)0;
|
||||
CPU_STK_SIZE const OSCfg_IdleTaskStkLimit = 0u;
|
||||
CPU_STK_SIZE const OSCfg_IdleTaskStkSize = 0u;
|
||||
CPU_INT32U const OSCfg_IdleTaskStkSizeRAM = 0u;
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_ISR_STK_SIZE > 0u)
|
||||
CPU_STK * const OSCfg_ISRStkBasePtr = &OSCfg_ISRStk[0];
|
||||
CPU_STK_SIZE const OSCfg_ISRStkSize = OS_CFG_ISR_STK_SIZE;
|
||||
CPU_INT32U const OSCfg_ISRStkSizeRAM = sizeof(OSCfg_ISRStk);
|
||||
#else
|
||||
CPU_STK * const OSCfg_ISRStkBasePtr = (CPU_STK *)0;
|
||||
CPU_STK_SIZE const OSCfg_ISRStkSize = 0u;
|
||||
CPU_INT32U const OSCfg_ISRStkSizeRAM = 0u;
|
||||
#endif
|
||||
|
||||
|
||||
#if (OS_MSG_EN > 0u)
|
||||
OS_MSG_SIZE const OSCfg_MsgPoolSize = OS_CFG_MSG_POOL_SIZE;
|
||||
CPU_INT32U const OSCfg_MsgPoolSizeRAM = sizeof(OSCfg_MsgPool);
|
||||
OS_MSG * const OSCfg_MsgPoolBasePtr = &OSCfg_MsgPool[0];
|
||||
#else
|
||||
OS_MSG_SIZE const OSCfg_MsgPoolSize = 0u;
|
||||
CPU_INT32U const OSCfg_MsgPoolSizeRAM = 0u;
|
||||
OS_MSG * const OSCfg_MsgPoolBasePtr = (OS_MSG *)0;
|
||||
#endif
|
||||
|
||||
|
||||
#if (OS_CFG_STAT_TASK_EN > 0u)
|
||||
OS_PRIO const OSCfg_StatTaskPrio = OS_CFG_STAT_TASK_PRIO;
|
||||
OS_RATE_HZ const OSCfg_StatTaskRate_Hz = OS_CFG_STAT_TASK_RATE_HZ;
|
||||
CPU_STK * const OSCfg_StatTaskStkBasePtr = &OSCfg_StatTaskStk[0];
|
||||
CPU_STK_SIZE const OSCfg_StatTaskStkLimit = OS_CFG_STAT_TASK_STK_LIMIT;
|
||||
CPU_STK_SIZE const OSCfg_StatTaskStkSize = OS_CFG_STAT_TASK_STK_SIZE;
|
||||
CPU_INT32U const OSCfg_StatTaskStkSizeRAM = sizeof(OSCfg_StatTaskStk);
|
||||
#else
|
||||
OS_PRIO const OSCfg_StatTaskPrio = 0u;
|
||||
OS_RATE_HZ const OSCfg_StatTaskRate_Hz = 0u;
|
||||
CPU_STK * const OSCfg_StatTaskStkBasePtr = (CPU_STK *)0;
|
||||
CPU_STK_SIZE const OSCfg_StatTaskStkLimit = 0u;
|
||||
CPU_STK_SIZE const OSCfg_StatTaskStkSize = 0u;
|
||||
CPU_INT32U const OSCfg_StatTaskStkSizeRAM = 0u;
|
||||
#endif
|
||||
|
||||
|
||||
CPU_STK_SIZE const OSCfg_StkSizeMin = OS_CFG_STK_SIZE_MIN;
|
||||
|
||||
|
||||
#if (OS_CFG_TICK_EN > 0u)
|
||||
OS_RATE_HZ const OSCfg_TickRate_Hz = OS_CFG_TICK_RATE_HZ;
|
||||
#else
|
||||
OS_RATE_HZ const OSCfg_TickRate_Hz = 0u;
|
||||
#endif
|
||||
|
||||
|
||||
#if (OS_CFG_TMR_EN > 0u)
|
||||
OS_PRIO const OSCfg_TmrTaskPrio = OS_CFG_TMR_TASK_PRIO;
|
||||
OS_RATE_HZ const OSCfg_TmrTaskRate_Hz = OS_CFG_TMR_TASK_RATE_HZ;
|
||||
CPU_STK * const OSCfg_TmrTaskStkBasePtr = &OSCfg_TmrTaskStk[0];
|
||||
CPU_STK_SIZE const OSCfg_TmrTaskStkLimit = OS_CFG_TMR_TASK_STK_LIMIT;
|
||||
CPU_STK_SIZE const OSCfg_TmrTaskStkSize = OS_CFG_TMR_TASK_STK_SIZE;
|
||||
CPU_INT32U const OSCfg_TmrTaskStkSizeRAM = sizeof(OSCfg_TmrTaskStk);
|
||||
#else
|
||||
OS_PRIO const OSCfg_TmrTaskPrio = 0u;
|
||||
OS_RATE_HZ const OSCfg_TmrTaskRate_Hz = 0u;
|
||||
CPU_STK * const OSCfg_TmrTaskStkBasePtr = (CPU_STK *)0;
|
||||
CPU_STK_SIZE const OSCfg_TmrTaskStkLimit = 0u;
|
||||
CPU_STK_SIZE const OSCfg_TmrTaskStkSize = 0u;
|
||||
CPU_INT32U const OSCfg_TmrTaskStkSizeRAM = 0u;
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* TOTAL SIZE OF APPLICATION CONFIGURATION
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
|
||||
CPU_INT32U const OSCfg_DataSizeRAM = 0u
|
||||
|
||||
#if (OS_CFG_TASK_IDLE_EN > 0u)
|
||||
+ sizeof(OSCfg_IdleTaskStk)
|
||||
#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)
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_ISR_STK_SIZE > 0u)
|
||||
+ sizeof(OSCfg_ISRStk)
|
||||
#endif
|
||||
|
||||
+ 0u;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* 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;
|
||||
|
||||
#if (OS_CFG_TASK_IDLE_EN > 0u)
|
||||
(void)OSCfg_IdleTaskStkBasePtr;
|
||||
(void)OSCfg_IdleTaskStkLimit;
|
||||
(void)OSCfg_IdleTaskStkSize;
|
||||
(void)OSCfg_IdleTaskStkSizeRAM;
|
||||
#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;
|
||||
|
||||
#if (OS_CFG_TICK_EN > 0u)
|
||||
(void)OSCfg_TickRate_Hz;
|
||||
#endif
|
||||
|
||||
#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;
|
||||
#endif
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,520 @@
|
|||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/OS-III
|
||||
* The Real-Time Kernel
|
||||
*
|
||||
* Copyright 2009-2020 Silicon Laboratories Inc. www.silabs.com
|
||||
*
|
||||
* SPDX-License-Identifier: APACHE-2.0
|
||||
*
|
||||
* This software is subject to an open source license and is distributed by
|
||||
* Silicon Laboratories Inc. pursuant to the terms of the Apache License,
|
||||
* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* DEBUGGER CONSTANTS
|
||||
*
|
||||
* File : os_dbg.c
|
||||
* Version : V3.08.00
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#define MICRIUM_SOURCE
|
||||
#include "os.h"
|
||||
|
||||
#ifdef VSC_INCLUDE_SOURCE_FILE_NAMES
|
||||
const CPU_CHAR *os_dbg__c = "$Id: $";
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* CONSTANTS
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
|
||||
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
|
||||
|
||||
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_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_TickListSize = sizeof(OS_TICK_LIST);
|
||||
|
||||
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);
|
||||
#else
|
||||
CPU_INT08U const OSDbg_TmrDelEn = 0u;
|
||||
CPU_INT16U const OSDbg_TmrSize = 0u;
|
||||
#endif
|
||||
|
||||
CPU_INT16U const OSDbg_VersionNbr = OS_VERSION;
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* 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)
|
||||
#if (OS_CFG_TASK_STK_REDZONE_EN > 0u)
|
||||
+ sizeof(OS_AppRedzoneHitHookPtr)
|
||||
#endif
|
||||
+ sizeof(OS_AppTaskCreateHookPtr)
|
||||
+ sizeof(OS_AppTaskDelHookPtr)
|
||||
+ sizeof(OS_AppTaskReturnHookPtr)
|
||||
|
||||
+ sizeof(OS_AppIdleTaskHookPtr)
|
||||
+ sizeof(OS_AppStatTaskHookPtr)
|
||||
+ sizeof(OS_AppTaskSwHookPtr)
|
||||
+ sizeof(OS_AppTimeTickHookPtr)
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_DBG_EN > 0u)
|
||||
+ sizeof(OSIdleTaskCtr)
|
||||
#endif
|
||||
#if (OS_CFG_TASK_IDLE_EN > 0u)
|
||||
+ sizeof(OSIdleTaskTCB)
|
||||
#endif
|
||||
|
||||
#ifdef CPU_CFG_INT_DIS_MEAS_EN
|
||||
#if (OS_CFG_TS_EN > 0u)
|
||||
+ sizeof(OSIntDisTimeMax)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_STAT_TASK_STK_CHK_EN > 0u) && (OS_CFG_ISR_STK_SIZE > 0)
|
||||
+ sizeof(OSISRStkFree)
|
||||
+ sizeof(OSISRStkUsed)
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_ISR_STK_SIZE > 0)
|
||||
+ OS_CFG_ISR_STK_SIZE * sizeof(CPU_STK)
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_TASK_IDLE_EN > 0u)
|
||||
+ OS_CFG_IDLE_TASK_STK_SIZE * sizeof(CPU_STK)
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_TASK_STAT_EN > 0u)
|
||||
+ OS_CFG_STAT_TASK_STK_SIZE * sizeof(CPU_STK)
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_TMR_EN > 0u)
|
||||
+ OS_CFG_TMR_TASK_STK_SIZE * sizeof(CPU_STK)
|
||||
#endif
|
||||
|
||||
+ sizeof(OSRunning)
|
||||
+ sizeof(OSInitialized)
|
||||
|
||||
#ifdef OS_SAFETY_CRITICAL_IEC61508
|
||||
+ sizeof(OSSafetyCriticalStartFlag)
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_FLAG_EN > 0u)
|
||||
#if (OS_CFG_DBG_EN > 0u)
|
||||
+ sizeof(OSFlagDbgListPtr)
|
||||
+ sizeof(OSFlagQty)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_MEM_EN > 0u)
|
||||
#if (OS_CFG_DBG_EN > 0u)
|
||||
+ sizeof(OSMemDbgListPtr)
|
||||
+ sizeof(OSMemQty)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (OS_MSG_EN > 0u)
|
||||
+ sizeof(OSMsgPool)
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_MUTEX_EN > 0u)
|
||||
#if (OS_CFG_DBG_EN > 0u)
|
||||
+ sizeof(OSMutexDbgListPtr)
|
||||
+ sizeof(OSMutexQty)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
+ sizeof(OSPrioCur)
|
||||
+ sizeof(OSPrioHighRdy)
|
||||
+ sizeof(OSPrioTbl)
|
||||
|
||||
#if (OS_CFG_Q_EN > 0u)
|
||||
#if (OS_CFG_DBG_EN > 0u)
|
||||
+ sizeof(OSQDbgListPtr)
|
||||
+ sizeof(OSQQty)
|
||||
#endif
|
||||
#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 > 0u)
|
||||
+ sizeof(OSSchedRoundRobinDfltTimeQuanta)
|
||||
+ sizeof(OSSchedRoundRobinEn)
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_SEM_EN > 0u)
|
||||
#if (OS_CFG_DBG_EN > 0u)
|
||||
+ sizeof(OSSemDbgListPtr)
|
||||
#endif
|
||||
+ sizeof(OSSemQty)
|
||||
#endif
|
||||
#if ((OS_CFG_TASK_PROFILE_EN > 0u) || (OS_CFG_DBG_EN > 0u))
|
||||
+ sizeof(OSTaskCtxSwCtr)
|
||||
#if (OS_CFG_DBG_EN > 0u)
|
||||
+ sizeof(OSTaskDbgListPtr)
|
||||
#endif
|
||||
#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)
|
||||
#if (OS_CFG_TS_EN > 0u)
|
||||
+ sizeof(OSStatTaskTime)
|
||||
+ sizeof(OSStatTaskTimeMax)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_TICK_EN > 0u)
|
||||
+ sizeof(OSTickCtr)
|
||||
+ sizeof(OSTickList)
|
||||
#if (OS_CFG_TS_EN > 0u)
|
||||
+ sizeof(OSTickTime)
|
||||
+ sizeof(OSTickTimeMax)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_TMR_EN > 0u)
|
||||
#if (OS_CFG_DBG_EN > 0u)
|
||||
+ sizeof(OSTmrDbgListPtr)
|
||||
+ sizeof(OSTmrListEntries)
|
||||
#endif
|
||||
+ sizeof(OSTmrListPtr)
|
||||
+ sizeof(OSTmrMutex)
|
||||
+ sizeof(OSTmrCond)
|
||||
#if (OS_CFG_DBG_EN > 0u)
|
||||
+ sizeof(OSTmrQty)
|
||||
#endif
|
||||
+ sizeof(OSTmrTaskTCB)
|
||||
+ sizeof(OSTmrTaskTickBase)
|
||||
+ sizeof(OSTmrToTicksMult)
|
||||
#if (OS_CFG_TS_EN > 0u)
|
||||
+ sizeof(OSTmrTaskTime)
|
||||
+ sizeof(OSTmrTaskTimeMax)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_TASK_REG_TBL_SIZE > 0u)
|
||||
+ sizeof(OSTaskRegNextAvailID)
|
||||
#endif
|
||||
|
||||
+ sizeof(OSTCBCurPtr)
|
||||
+ sizeof(OSTCBHighRdyPtr);
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* 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 * volatile p_temp08;
|
||||
CPU_INT16U const * volatile p_temp16;
|
||||
CPU_INT32U const * volatile 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
|
||||
|
||||
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_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_TickListSize;
|
||||
|
||||
p_temp08 = (CPU_INT08U const *)&OSDbg_TimeDlyHMSMEn;
|
||||
p_temp08 = (CPU_INT08U const *)&OSDbg_TimeDlyResumeEn;
|
||||
|
||||
p_temp16 = (CPU_INT16U const *)&OSDbg_TLS_TblSize;
|
||||
|
||||
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;
|
||||
#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
|
|
@ -0,0 +1,391 @@
|
|||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/OS-III
|
||||
* The Real-Time Kernel
|
||||
*
|
||||
* Copyright 2009-2020 Silicon Laboratories Inc. www.silabs.com
|
||||
*
|
||||
* SPDX-License-Identifier: APACHE-2.0
|
||||
*
|
||||
* This software is subject to an open source license and is distributed by
|
||||
* Silicon Laboratories Inc. pursuant to the terms of the Apache License,
|
||||
* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* MEMORY PARTITION MANAGEMENT
|
||||
*
|
||||
* File : os_mem.c
|
||||
* Version : V3.08.00
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#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_CREATE_ISR If you called this function from an ISR
|
||||
* 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
|
||||
* OS_ERR_OBJ_CREATED If the memory partition was already created
|
||||
* Returns : none
|
||||
*
|
||||
* Note(s) : 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 == OS_TRUE) {
|
||||
*p_err = OS_ERR_ILLEGAL_CREATE_RUN_TIME;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u)
|
||||
if (OSIntNestingCtr > 0u) { /* 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 < 2u) { /* 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 */
|
||||
|
||||
CPU_CRITICAL_ENTER();
|
||||
#if (OS_OBJ_TYPE_REQ > 0u)
|
||||
if (p_mem->Type == OS_OBJ_TYPE_MEM) {
|
||||
CPU_CRITICAL_EXIT();
|
||||
*p_err = OS_ERR_OBJ_CREATED;
|
||||
return;
|
||||
}
|
||||
p_mem->Type = OS_OBJ_TYPE_MEM; /* Set the type of object */
|
||||
#endif
|
||||
#if (OS_CFG_DBG_EN > 0u)
|
||||
p_mem->NamePtr = p_name; /* Save name of memory partition */
|
||||
#else
|
||||
(void)p_name;
|
||||
#endif
|
||||
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);
|
||||
OSMemQty++;
|
||||
#endif
|
||||
|
||||
OS_TRACE_MEM_CREATE(p_mem, p_name);
|
||||
CPU_CRITICAL_EXIT();
|
||||
*p_err = OS_ERR_NONE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* 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
|
||||
* OS_ERR_OBJ_TYPE If 'p_mem' is not pointing at a memory partition
|
||||
*
|
||||
* Returns : A pointer to a memory block if no error is detected
|
||||
* A pointer to NULL if an error is detected
|
||||
*
|
||||
* Note(s) : none
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
|
||||
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
|
||||
|
||||
OS_TRACE_MEM_GET_ENTER(p_mem);
|
||||
|
||||
#if (OS_CFG_ARG_CHK_EN > 0u)
|
||||
if (p_mem == (OS_MEM *)0) { /* Must point to a valid memory partition */
|
||||
OS_TRACE_MEM_GET_FAILED(p_mem);
|
||||
OS_TRACE_MEM_GET_EXIT(OS_ERR_MEM_INVALID_P_MEM);
|
||||
*p_err = OS_ERR_MEM_INVALID_P_MEM;
|
||||
return ((void *)0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_OBJ_TYPE_CHK_EN > 0u)
|
||||
if (p_mem->Type != OS_OBJ_TYPE_MEM) { /* Make sure the memory block was created */
|
||||
OS_TRACE_MEM_GET_EXIT(OS_ERR_OBJ_TYPE);
|
||||
*p_err = OS_ERR_OBJ_TYPE;
|
||||
return ((void *)0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
CPU_CRITICAL_ENTER();
|
||||
if (p_mem->NbrFree == 0u) { /* See if there are any free memory blocks */
|
||||
CPU_CRITICAL_EXIT();
|
||||
OS_TRACE_MEM_GET_FAILED(p_mem);
|
||||
OS_TRACE_MEM_GET_EXIT(OS_ERR_MEM_NO_FREE_BLKS);
|
||||
*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();
|
||||
OS_TRACE_MEM_GET(p_mem);
|
||||
OS_TRACE_MEM_GET_EXIT(OS_ERR_NONE);
|
||||
*p_err = OS_ERR_NONE; /* No error */
|
||||
return (p_blk); /* Return memory block to caller */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* 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'
|
||||
* OS_ERR_OBJ_TYPE If 'p_mem' is not pointing at a memory partition
|
||||
*
|
||||
* Returns : none
|
||||
*
|
||||
* Note(s) : none
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
|
||||
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
|
||||
|
||||
OS_TRACE_MEM_PUT_ENTER(p_mem, p_blk);
|
||||
|
||||
#if (OS_CFG_ARG_CHK_EN > 0u)
|
||||
if (p_mem == (OS_MEM *)0) { /* Must point to a valid memory partition */
|
||||
OS_TRACE_MEM_PUT_FAILED(p_mem);
|
||||
OS_TRACE_MEM_PUT_EXIT(OS_ERR_MEM_INVALID_P_MEM);
|
||||
*p_err = OS_ERR_MEM_INVALID_P_MEM;
|
||||
return;
|
||||
}
|
||||
if (p_blk == (void *)0) { /* Must release a valid block */
|
||||
OS_TRACE_MEM_PUT_FAILED(p_mem);
|
||||
OS_TRACE_MEM_PUT_EXIT(OS_ERR_MEM_INVALID_P_BLK);
|
||||
*p_err = OS_ERR_MEM_INVALID_P_BLK;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_OBJ_TYPE_CHK_EN > 0u)
|
||||
if (p_mem->Type != OS_OBJ_TYPE_MEM) { /* Make sure the memory block was created */
|
||||
OS_TRACE_MEM_PUT_EXIT(OS_ERR_OBJ_TYPE);
|
||||
*p_err = OS_ERR_OBJ_TYPE;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
CPU_CRITICAL_ENTER();
|
||||
if (p_mem->NbrFree >= p_mem->NbrMax) { /* Make sure all blocks not already returned */
|
||||
CPU_CRITICAL_EXIT();
|
||||
OS_TRACE_MEM_PUT_FAILED(p_mem);
|
||||
OS_TRACE_MEM_PUT_EXIT(OS_ERR_MEM_FULL);
|
||||
*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();
|
||||
OS_TRACE_MEM_PUT(p_mem);
|
||||
OS_TRACE_MEM_PUT_EXIT(OS_ERR_NONE);
|
||||
*p_err = OS_ERR_NONE; /* Notify caller that memory block was released */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* 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
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* 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)
|
||||
{
|
||||
#if (OS_CFG_DBG_EN > 0u)
|
||||
OSMemDbgListPtr = (OS_MEM *)0;
|
||||
OSMemQty = 0u;
|
||||
#endif
|
||||
*p_err = OS_ERR_NONE;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,349 @@
|
|||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/OS-III
|
||||
* The Real-Time Kernel
|
||||
*
|
||||
* Copyright 2009-2020 Silicon Laboratories Inc. www.silabs.com
|
||||
*
|
||||
* SPDX-License-Identifier: APACHE-2.0
|
||||
*
|
||||
* This software is subject to an open source license and is distributed by
|
||||
* Silicon Laboratories Inc. pursuant to the terms of the Apache License,
|
||||
* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* MESSAGE HANDLING SERVICES
|
||||
*
|
||||
* File : os_msg.c
|
||||
* Version : V3.08.00
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#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)
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* 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;
|
||||
|
||||
|
||||
#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 == 0u) {
|
||||
*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 = 0u;
|
||||
#if (OS_CFG_TS_EN > 0u)
|
||||
p_msg1->MsgTS = 0u;
|
||||
#endif
|
||||
p_msg1++;
|
||||
p_msg2++;
|
||||
}
|
||||
p_msg1->NextPtr = (OS_MSG *)0; /* Last OS_MSG */
|
||||
p_msg1->MsgPtr = (void *)0;
|
||||
p_msg1->MsgSize = 0u;
|
||||
#if (OS_CFG_TS_EN > 0u)
|
||||
p_msg1->MsgTS = 0u;
|
||||
#endif
|
||||
|
||||
OSMsgPool.NextPtr = OSCfg_MsgPoolBasePtr;
|
||||
OSMsgPool.NbrFree = OSCfg_MsgPoolSize;
|
||||
OSMsgPool.NbrUsed = 0u;
|
||||
#if (OS_CFG_DBG_EN > 0u)
|
||||
OSMsgPool.NbrUsedMax = 0u;
|
||||
#endif
|
||||
*p_err = OS_ERR_NONE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* 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 > 0u) {
|
||||
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 = 0u; /* Flush the message queue */
|
||||
#if (OS_CFG_DBG_EN > 0u)
|
||||
p_msg_q->NbrEntriesMax = 0u;
|
||||
#endif
|
||||
p_msg_q->InPtr = (OS_MSG *)0;
|
||||
p_msg_q->OutPtr = (OS_MSG *)0;
|
||||
}
|
||||
return (qty);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* 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
|
||||
* -------
|
||||
*
|
||||
* size 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 = size;
|
||||
p_msg_q->NbrEntries = 0u;
|
||||
#if (OS_CFG_DBG_EN > 0u)
|
||||
p_msg_q->NbrEntriesMax = 0u;
|
||||
#endif
|
||||
p_msg_q->InPtr = (OS_MSG *)0;
|
||||
p_msg_q->OutPtr = (OS_MSG *)0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* 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;
|
||||
|
||||
|
||||
#if (OS_CFG_TS_EN == 0u)
|
||||
(void)p_ts; /* Prevent compiler warning for not using 'ts' */
|
||||
#endif
|
||||
|
||||
if (p_msg_q->NbrEntries == 0u) { /* Is the queue empty? */
|
||||
*p_msg_size = 0u; /* Yes */
|
||||
#if (OS_CFG_TS_EN > 0u)
|
||||
if (p_ts != (CPU_TS *)0) {
|
||||
*p_ts = 0u;
|
||||
}
|
||||
#endif
|
||||
*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 (OS_CFG_TS_EN > 0u)
|
||||
if (p_ts != (CPU_TS *)0) {
|
||||
*p_ts = p_msg->MsgTS;
|
||||
}
|
||||
#endif
|
||||
|
||||
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 = 0u;
|
||||
} 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);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* 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;
|
||||
|
||||
|
||||
#if (OS_CFG_TS_EN == 0u)
|
||||
(void)ts; /* Prevent compiler warning for not using 'ts' */
|
||||
#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 == 0u) {
|
||||
*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 (OS_CFG_DBG_EN > 0u)
|
||||
if (OSMsgPool.NbrUsedMax < OSMsgPool.NbrUsed) {
|
||||
OSMsgPool.NbrUsedMax = OSMsgPool.NbrUsed;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (p_msg_q->NbrEntries == 0u) { /* 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 = 1u;
|
||||
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 (OS_CFG_DBG_EN > 0u)
|
||||
if (p_msg_q->NbrEntriesMax < p_msg_q->NbrEntries) {
|
||||
p_msg_q->NbrEntriesMax = p_msg_q->NbrEntries;
|
||||
}
|
||||
#endif
|
||||
|
||||
p_msg->MsgPtr = p_void; /* Deposit message in the message queue entry */
|
||||
p_msg->MsgSize = msg_size;
|
||||
#if (OS_CFG_TS_EN > 0u)
|
||||
p_msg->MsgTS = ts;
|
||||
#endif
|
||||
*p_err = OS_ERR_NONE;
|
||||
}
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,183 @@
|
|||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/OS-III
|
||||
* The Real-Time Kernel
|
||||
*
|
||||
* Copyright 2009-2020 Silicon Laboratories Inc. www.silabs.com
|
||||
*
|
||||
* SPDX-License-Identifier: APACHE-2.0
|
||||
*
|
||||
* This software is subject to an open source license and is distributed by
|
||||
* Silicon Laboratories Inc. pursuant to the terms of the Apache License,
|
||||
* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* PRIORITY MANAGEMENT
|
||||
*
|
||||
* File : os_prio.c
|
||||
* Version : V3.08.00
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#define MICRIUM_SOURCE
|
||||
#include "os.h"
|
||||
|
||||
#ifdef VSC_INCLUDE_SOURCE_FILE_NAMES
|
||||
const CPU_CHAR *os_prio__c = "$Id: $";
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* 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] = 0u;
|
||||
}
|
||||
|
||||
#if (OS_CFG_TASK_IDLE_EN == 0u)
|
||||
OS_PrioInsert ((OS_PRIO)(OS_CFG_PRIO_MAX - 1u)); /* Insert what would be the idle task */
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* 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)
|
||||
{
|
||||
#if (OS_CFG_PRIO_MAX <= (CPU_CFG_DATA_SIZE * 8u)) /* Optimize for less than word size nbr of priorities */
|
||||
return ((OS_PRIO)CPU_CntLeadZeros(OSPrioTbl[0]));
|
||||
|
||||
|
||||
#elif (OS_CFG_PRIO_MAX <= (2u * (CPU_CFG_DATA_SIZE * 8u))) /* Optimize for 2x the word size nbr of priorities */
|
||||
if (OSPrioTbl[0] == 0u) {
|
||||
return ((OS_PRIO)((OS_PRIO)CPU_CntLeadZeros(OSPrioTbl[1]) + (CPU_CFG_DATA_SIZE * 8u)));
|
||||
} else {
|
||||
return ((OS_PRIO)((OS_PRIO)CPU_CntLeadZeros(OSPrioTbl[0])));
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
CPU_DATA *p_tbl;
|
||||
OS_PRIO prio;
|
||||
|
||||
|
||||
prio = 0u;
|
||||
p_tbl = &OSPrioTbl[0];
|
||||
while (*p_tbl == 0u) { /* Search the bitmap table for the highest priority */
|
||||
prio = (OS_PRIO)(prio + (CPU_CFG_DATA_SIZE * 8u)); /* 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);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* 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)
|
||||
{
|
||||
#if (OS_CFG_PRIO_MAX <= (CPU_CFG_DATA_SIZE * 8u)) /* Optimize for less than word size nbr of priorities */
|
||||
OSPrioTbl[0] |= (CPU_DATA)1u << (((CPU_CFG_DATA_SIZE * 8u) - 1u) - prio);
|
||||
|
||||
|
||||
#elif (OS_CFG_PRIO_MAX <= (2u * (CPU_CFG_DATA_SIZE * 8u))) /* Optimize for 2x the word size nbr of priorities */
|
||||
if (prio < (CPU_CFG_DATA_SIZE * 8u)) {
|
||||
OSPrioTbl[0] |= (CPU_DATA)1u << (((CPU_CFG_DATA_SIZE * 8u) - 1u) - prio);
|
||||
} else {
|
||||
OSPrioTbl[1] |= (CPU_DATA)1u << (((CPU_CFG_DATA_SIZE * 8u) - 1u) - (prio - (CPU_CFG_DATA_SIZE * 8u)));
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
CPU_DATA bit_nbr;
|
||||
OS_PRIO ix;
|
||||
|
||||
ix = (OS_PRIO)(prio / (CPU_CFG_DATA_SIZE * 8u));
|
||||
bit_nbr = (CPU_DATA)prio & ((CPU_CFG_DATA_SIZE * 8u) - 1u);
|
||||
OSPrioTbl[ix] |= (CPU_DATA)1u << (((CPU_CFG_DATA_SIZE * 8u) - 1u) - bit_nbr);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* 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)
|
||||
{
|
||||
#if (OS_CFG_PRIO_MAX <= (CPU_CFG_DATA_SIZE * 8u)) /* Optimize for less than word size nbr of priorities */
|
||||
OSPrioTbl[0] &= ~((CPU_DATA)1u << (((CPU_CFG_DATA_SIZE * 8u) - 1u) - prio));
|
||||
|
||||
|
||||
#elif (OS_CFG_PRIO_MAX <= (2u * (CPU_CFG_DATA_SIZE * 8u))) /* Optimize for 2x the word size nbr of priorities */
|
||||
if (prio < (CPU_CFG_DATA_SIZE * 8u)) {
|
||||
OSPrioTbl[0] &= ~((CPU_DATA)1u << (((CPU_CFG_DATA_SIZE * 8u) - 1u) - prio));
|
||||
} else {
|
||||
OSPrioTbl[1] &= ~((CPU_DATA)1u << (((CPU_CFG_DATA_SIZE * 8u) - 1u) - (prio - (CPU_CFG_DATA_SIZE * 8u))));
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
CPU_DATA bit_nbr;
|
||||
OS_PRIO ix;
|
||||
|
||||
ix = (OS_PRIO)(prio / (CPU_CFG_DATA_SIZE * 8u));
|
||||
bit_nbr = (CPU_DATA)prio & ((CPU_CFG_DATA_SIZE * 8u) - 1u);
|
||||
OSPrioTbl[ix] &= ~((CPU_DATA) 1u << (((CPU_CFG_DATA_SIZE * 8u) - 1u) - bit_nbr));
|
||||
#endif
|
||||
}
|
||||
|
|
@ -0,0 +1,987 @@
|
|||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/OS-III
|
||||
* The Real-Time Kernel
|
||||
*
|
||||
* Copyright 2009-2020 Silicon Laboratories Inc. www.silabs.com
|
||||
*
|
||||
* SPDX-License-Identifier: APACHE-2.0
|
||||
*
|
||||
* This software is subject to an open source license and is distributed by
|
||||
* Silicon Laboratories Inc. pursuant to the terms of the Apache License,
|
||||
* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* MESSAGE QUEUE MANAGEMENT
|
||||
*
|
||||
* File : os_q.c
|
||||
* Version : V3.08.00
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#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_OBJ_PTR_NULL If you passed a NULL pointer for 'p_q'
|
||||
* OS_ERR_Q_SIZE If the size you specified is 0
|
||||
* OS_ERR_OBJ_CREATED If the message queue was already created
|
||||
*
|
||||
* Returns : none
|
||||
*
|
||||
* Note(s) : 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 == OS_TRUE) {
|
||||
*p_err = OS_ERR_ILLEGAL_CREATE_RUN_TIME;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u)
|
||||
if (OSIntNestingCtr > 0u) { /* 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 == 0u) { /* Cannot specify a zero size queue */
|
||||
*p_err = OS_ERR_Q_SIZE;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
CPU_CRITICAL_ENTER();
|
||||
#if (OS_OBJ_TYPE_REQ > 0u)
|
||||
if (p_q->Type == OS_OBJ_TYPE_Q) {
|
||||
CPU_CRITICAL_EXIT();
|
||||
*p_err = OS_ERR_OBJ_CREATED;
|
||||
return;
|
||||
}
|
||||
p_q->Type = OS_OBJ_TYPE_Q; /* Mark the data structure as a message queue */
|
||||
#endif
|
||||
#if (OS_CFG_DBG_EN > 0u)
|
||||
p_q->NamePtr = p_name;
|
||||
#else
|
||||
(void)p_name;
|
||||
#endif
|
||||
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);
|
||||
OSQQty++; /* One more queue created */
|
||||
#endif
|
||||
OS_TRACE_Q_CREATE(p_q, p_name);
|
||||
CPU_CRITICAL_EXIT();
|
||||
*p_err = OS_ERR_NONE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* 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_ILLEGAL_DEL_RUN_TIME If you are trying to delete the message queue after you
|
||||
* called OSStart()
|
||||
* 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_OS_NOT_RUNNING If uC/OS-III is not running yet
|
||||
* 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) 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 nbr_tasks;
|
||||
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 (0u);
|
||||
}
|
||||
#endif
|
||||
|
||||
OS_TRACE_Q_DEL_ENTER(p_q, opt);
|
||||
|
||||
#ifdef OS_SAFETY_CRITICAL_IEC61508
|
||||
if (OSSafetyCriticalStartFlag == OS_TRUE) {
|
||||
OS_TRACE_Q_DEL_EXIT(OS_ERR_ILLEGAL_DEL_RUN_TIME);
|
||||
*p_err = OS_ERR_ILLEGAL_DEL_RUN_TIME;
|
||||
return (0u);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u)
|
||||
if (OSIntNestingCtr > 0u) { /* Can't delete a message queue from an ISR */
|
||||
OS_TRACE_Q_DEL_EXIT(OS_ERR_DEL_ISR);
|
||||
*p_err = OS_ERR_DEL_ISR;
|
||||
return (0u);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_INVALID_OS_CALLS_CHK_EN > 0u)
|
||||
if (OSRunning != OS_STATE_OS_RUNNING) { /* Is the kernel running? */
|
||||
OS_TRACE_Q_DEL_EXIT(OS_ERR_OS_NOT_RUNNING);
|
||||
*p_err = OS_ERR_OS_NOT_RUNNING;
|
||||
return (0u);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_ARG_CHK_EN > 0u)
|
||||
if (p_q == (OS_Q *)0) { /* Validate 'p_q' */
|
||||
OS_TRACE_Q_DEL_EXIT(OS_ERR_OBJ_PTR_NULL);
|
||||
*p_err = OS_ERR_OBJ_PTR_NULL;
|
||||
return (0u);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_OBJ_TYPE_CHK_EN > 0u)
|
||||
if (p_q->Type != OS_OBJ_TYPE_Q) { /* Make sure message queue was created */
|
||||
OS_TRACE_Q_DEL_EXIT(OS_ERR_OBJ_TYPE);
|
||||
*p_err = OS_ERR_OBJ_TYPE;
|
||||
return (0u);
|
||||
}
|
||||
#endif
|
||||
|
||||
CPU_CRITICAL_ENTER();
|
||||
p_pend_list = &p_q->PendList;
|
||||
nbr_tasks = 0u;
|
||||
switch (opt) {
|
||||
case OS_OPT_DEL_NO_PEND: /* Delete message queue only if no task waiting */
|
||||
if (p_pend_list->HeadPtr == (OS_TCB *)0) {
|
||||
#if (OS_CFG_DBG_EN > 0u)
|
||||
OS_QDbgListRemove(p_q);
|
||||
OSQQty--;
|
||||
#endif
|
||||
OS_TRACE_Q_DEL(p_q);
|
||||
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 */
|
||||
#if (OS_CFG_TS_EN > 0u)
|
||||
ts = OS_TS_GET(); /* Get local time stamp so all tasks get the same time */
|
||||
#else
|
||||
ts = 0u;
|
||||
#endif
|
||||
while (p_pend_list->HeadPtr != (OS_TCB *)0) { /* Remove all tasks from the pend list */
|
||||
p_tcb = p_pend_list->HeadPtr;
|
||||
OS_PendAbort(p_tcb,
|
||||
ts,
|
||||
OS_STATUS_PEND_DEL);
|
||||
nbr_tasks++;
|
||||
}
|
||||
#if (OS_CFG_DBG_EN > 0u)
|
||||
OS_QDbgListRemove(p_q);
|
||||
OSQQty--;
|
||||
#endif
|
||||
OS_TRACE_Q_DEL(p_q);
|
||||
OS_QClr(p_q);
|
||||
CPU_CRITICAL_EXIT();
|
||||
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;
|
||||
}
|
||||
OS_TRACE_Q_DEL_EXIT(*p_err);
|
||||
return (nbr_tasks);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* 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
|
||||
* OS_ERR_OS_NOT_RUNNING If uC/OS-III is not running yet
|
||||
*
|
||||
* Returns : == 0 if no entries were freed, or upon error.
|
||||
* > 0 the number of freed entries.
|
||||
*
|
||||
* 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 (0u);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u)
|
||||
if (OSIntNestingCtr > 0u) { /* Can't flush a message queue from an ISR */
|
||||
*p_err = OS_ERR_FLUSH_ISR;
|
||||
return (0u);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_INVALID_OS_CALLS_CHK_EN > 0u)
|
||||
if (OSRunning != OS_STATE_OS_RUNNING) { /* Is the kernel running? */
|
||||
*p_err = OS_ERR_OS_NOT_RUNNING;
|
||||
return (0u);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_ARG_CHK_EN > 0u)
|
||||
if (p_q == (OS_Q *)0) { /* Validate arguments */
|
||||
*p_err = OS_ERR_OBJ_PTR_NULL;
|
||||
return (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 (0u);
|
||||
}
|
||||
#endif
|
||||
|
||||
CPU_CRITICAL_ENTER();
|
||||
entries = OS_MsgQFreeAll(&p_q->MsgQ); /* Return all OS_MSGs to the OS_MSG pool */
|
||||
CPU_CRITICAL_EXIT();
|
||||
*p_err = OS_ERR_NONE;
|
||||
return (entries);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* 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_DEL If 'p_q' was deleted
|
||||
* 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 You specified an invalid option
|
||||
* OS_ERR_OS_NOT_RUNNING If uC/OS-III is not running yet
|
||||
* 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_PTR_INVALID If you passed a NULL pointer of 'p_msg_size'
|
||||
* OS_ERR_SCHED_LOCKED The scheduler is locked
|
||||
* OS_ERR_STATUS_INVALID If the pend status has an invalid value
|
||||
* OS_ERR_TIMEOUT A message was not received within the specified timeout
|
||||
* would lead to a suspension.
|
||||
* OS_ERR_TICK_DISABLED If kernel ticks are disabled and a timeout is specified
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Note(s) : This API 'MUST NOT' be called from a timer callback function.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
|
||||
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)
|
||||
{
|
||||
void *p_void;
|
||||
CPU_SR_ALLOC();
|
||||
|
||||
|
||||
#ifdef OS_SAFETY_CRITICAL
|
||||
if (p_err == (OS_ERR *)0) {
|
||||
OS_SAFETY_CRITICAL_EXCEPTION();
|
||||
return ((void *)0);
|
||||
}
|
||||
#endif
|
||||
|
||||
OS_TRACE_Q_PEND_ENTER(p_q, timeout, opt, p_msg_size, p_ts);
|
||||
|
||||
#if (OS_CFG_TICK_EN == 0u)
|
||||
if (timeout != 0u) {
|
||||
*p_err = OS_ERR_TICK_DISABLED;
|
||||
OS_TRACE_Q_PEND_FAILED(p_q);
|
||||
OS_TRACE_Q_PEND_EXIT(OS_ERR_TICK_DISABLED);
|
||||
return ((void *)0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u)
|
||||
if (OSIntNestingCtr > 0u) { /* Not allowed to call from an ISR */
|
||||
if ((opt & OS_OPT_PEND_NON_BLOCKING) != OS_OPT_PEND_NON_BLOCKING) {
|
||||
OS_TRACE_Q_PEND_FAILED(p_q);
|
||||
OS_TRACE_Q_PEND_EXIT(OS_ERR_PEND_ISR);
|
||||
*p_err = OS_ERR_PEND_ISR;
|
||||
return ((void *)0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_INVALID_OS_CALLS_CHK_EN > 0u)
|
||||
if (OSRunning != OS_STATE_OS_RUNNING) { /* Is the kernel running? */
|
||||
OS_TRACE_Q_PEND_EXIT(OS_ERR_OS_NOT_RUNNING);
|
||||
*p_err = OS_ERR_OS_NOT_RUNNING;
|
||||
return ((void *)0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_ARG_CHK_EN > 0u)
|
||||
if (p_q == (OS_Q *)0) { /* Validate arguments */
|
||||
OS_TRACE_Q_PEND_FAILED(p_q);
|
||||
OS_TRACE_Q_PEND_EXIT(OS_ERR_OBJ_PTR_NULL);
|
||||
*p_err = OS_ERR_OBJ_PTR_NULL;
|
||||
return ((void *)0);
|
||||
}
|
||||
if (p_msg_size == (OS_MSG_SIZE *)0) {
|
||||
OS_TRACE_Q_PEND_FAILED(p_q);
|
||||
OS_TRACE_Q_PEND_EXIT(OS_ERR_PTR_INVALID);
|
||||
*p_err = OS_ERR_PTR_INVALID;
|
||||
return ((void *)0);
|
||||
}
|
||||
switch (opt) {
|
||||
case OS_OPT_PEND_BLOCKING:
|
||||
case OS_OPT_PEND_NON_BLOCKING:
|
||||
break;
|
||||
|
||||
default:
|
||||
OS_TRACE_Q_PEND_FAILED(p_q);
|
||||
OS_TRACE_Q_PEND_EXIT(OS_ERR_OPT_INVALID);
|
||||
*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 */
|
||||
OS_TRACE_Q_PEND_FAILED(p_q);
|
||||
OS_TRACE_Q_PEND_EXIT(OS_ERR_OBJ_TYPE);
|
||||
*p_err = OS_ERR_OBJ_TYPE;
|
||||
return ((void *)0);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (p_ts != (CPU_TS *)0) {
|
||||
*p_ts = 0u; /* 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) {
|
||||
OS_TRACE_Q_PEND(p_q);
|
||||
CPU_CRITICAL_EXIT();
|
||||
OS_TRACE_Q_PEND_EXIT(OS_ERR_NONE);
|
||||
return (p_void); /* Yes, Return message received */
|
||||
}
|
||||
|
||||
if ((opt & OS_OPT_PEND_NON_BLOCKING) != 0u) { /* Caller wants to block if not available? */
|
||||
CPU_CRITICAL_EXIT();
|
||||
OS_TRACE_Q_PEND_FAILED(p_q);
|
||||
OS_TRACE_Q_PEND_EXIT(OS_ERR_PEND_WOULD_BLOCK);
|
||||
*p_err = OS_ERR_PEND_WOULD_BLOCK; /* No */
|
||||
return ((void *)0);
|
||||
} else {
|
||||
if (OSSchedLockNestingCtr > 0u) { /* Can't pend when the scheduler is locked */
|
||||
CPU_CRITICAL_EXIT();
|
||||
OS_TRACE_Q_PEND_FAILED(p_q);
|
||||
OS_TRACE_Q_PEND_EXIT(OS_ERR_SCHED_LOCKED);
|
||||
*p_err = OS_ERR_SCHED_LOCKED;
|
||||
return ((void *)0);
|
||||
}
|
||||
}
|
||||
|
||||
OS_Pend((OS_PEND_OBJ *)((void *)p_q), /* Block task pending on Message Queue */
|
||||
OSTCBCurPtr,
|
||||
OS_TASK_PEND_ON_Q,
|
||||
timeout);
|
||||
CPU_CRITICAL_EXIT();
|
||||
OS_TRACE_Q_PEND_BLOCK(p_q);
|
||||
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 (OS_CFG_TS_EN > 0u)
|
||||
if (p_ts != (CPU_TS *)0) {
|
||||
*p_ts = OSTCBCurPtr->TS;
|
||||
}
|
||||
#endif
|
||||
OS_TRACE_Q_PEND(p_q);
|
||||
*p_err = OS_ERR_NONE;
|
||||
break;
|
||||
|
||||
case OS_STATUS_PEND_ABORT: /* Indicate that we aborted */
|
||||
p_void = (void *)0;
|
||||
*p_msg_size = 0u;
|
||||
#if (OS_CFG_TS_EN > 0u)
|
||||
if (p_ts != (CPU_TS *)0) {
|
||||
*p_ts = OSTCBCurPtr->TS;
|
||||
}
|
||||
#endif
|
||||
OS_TRACE_Q_PEND_FAILED(p_q);
|
||||
*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 = 0u;
|
||||
OS_TRACE_Q_PEND_FAILED(p_q);
|
||||
*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 = 0u;
|
||||
#if (OS_CFG_TS_EN > 0u)
|
||||
if (p_ts != (CPU_TS *)0) {
|
||||
*p_ts = OSTCBCurPtr->TS;
|
||||
}
|
||||
#endif
|
||||
OS_TRACE_Q_PEND_FAILED(p_q);
|
||||
*p_err = OS_ERR_OBJ_DEL;
|
||||
break;
|
||||
|
||||
default:
|
||||
p_void = (void *)0;
|
||||
*p_msg_size = 0u;
|
||||
OS_TRACE_Q_PEND_FAILED(p_q);
|
||||
*p_err = OS_ERR_STATUS_INVALID;
|
||||
break;
|
||||
}
|
||||
CPU_CRITICAL_EXIT();
|
||||
OS_TRACE_Q_PEND_EXIT(*p_err);
|
||||
return (p_void);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* 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_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 You specified an invalid option
|
||||
* OS_ERR_OS_NOT_RUNNING If uC/OS-III is not running yet
|
||||
* 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.
|
||||
*
|
||||
* Note(s) : none
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
|
||||
#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 (0u);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u)
|
||||
if (OSIntNestingCtr > 0u) { /* Not allowed to Pend Abort from an ISR */
|
||||
*p_err = OS_ERR_PEND_ABORT_ISR;
|
||||
return (0u);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_INVALID_OS_CALLS_CHK_EN > 0u)
|
||||
if (OSRunning != OS_STATE_OS_RUNNING) { /* Is the kernel running? */
|
||||
*p_err = OS_ERR_OS_NOT_RUNNING;
|
||||
return (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 (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 (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 (0u);
|
||||
}
|
||||
#endif
|
||||
|
||||
CPU_CRITICAL_ENTER();
|
||||
p_pend_list = &p_q->PendList;
|
||||
if (p_pend_list->HeadPtr == (OS_TCB *)0) { /* Any task waiting on queue? */
|
||||
CPU_CRITICAL_EXIT(); /* No */
|
||||
*p_err = OS_ERR_PEND_ABORT_NONE;
|
||||
return (0u);
|
||||
}
|
||||
|
||||
nbr_tasks = 0u;
|
||||
#if (OS_CFG_TS_EN > 0u)
|
||||
ts = OS_TS_GET(); /* Get local time stamp so all tasks get the same time */
|
||||
#else
|
||||
ts = 0u;
|
||||
#endif
|
||||
while (p_pend_list->HeadPtr != (OS_TCB *)0) {
|
||||
p_tcb = p_pend_list->HeadPtr;
|
||||
OS_PendAbort(p_tcb,
|
||||
ts,
|
||||
OS_STATUS_PEND_ABORT);
|
||||
nbr_tasks++;
|
||||
if (opt != OS_OPT_PEND_ABORT_ALL) { /* Pend abort all tasks waiting? */
|
||||
break; /* No */
|
||||
}
|
||||
}
|
||||
CPU_CRITICAL_EXIT();
|
||||
|
||||
if ((opt & OS_OPT_POST_NO_SCHED) == 0u) {
|
||||
OSSched(); /* Run the scheduler */
|
||||
}
|
||||
|
||||
*p_err = OS_ERR_NONE;
|
||||
return (nbr_tasks);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* 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_OPT_INVALID You specified an invalid option
|
||||
* OS_ERR_OS_NOT_RUNNING If uC/OS-III is not running yet
|
||||
* OS_ERR_Q_MAX If the queue is full
|
||||
*
|
||||
* Returns : None
|
||||
*
|
||||
* Note(s) : none
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
|
||||
void OSQPost (OS_Q *p_q,
|
||||
void *p_void,
|
||||
OS_MSG_SIZE msg_size,
|
||||
OS_OPT opt,
|
||||
OS_ERR *p_err)
|
||||
{
|
||||
OS_OPT post_type;
|
||||
OS_PEND_LIST *p_pend_list;
|
||||
OS_TCB *p_tcb;
|
||||
OS_TCB *p_tcb_next;
|
||||
CPU_TS ts;
|
||||
CPU_SR_ALLOC();
|
||||
|
||||
|
||||
#ifdef OS_SAFETY_CRITICAL
|
||||
if (p_err == (OS_ERR *)0) {
|
||||
OS_SAFETY_CRITICAL_EXCEPTION();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
OS_TRACE_Q_POST_ENTER(p_q, p_void, msg_size, opt);
|
||||
|
||||
#if (OS_CFG_INVALID_OS_CALLS_CHK_EN > 0u)
|
||||
if (OSRunning != OS_STATE_OS_RUNNING) { /* Is the kernel running? */
|
||||
OS_TRACE_Q_POST_EXIT(OS_ERR_OS_NOT_RUNNING);
|
||||
*p_err = OS_ERR_OS_NOT_RUNNING;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_ARG_CHK_EN > 0u)
|
||||
if (p_q == (OS_Q *)0) { /* Validate 'p_q' */
|
||||
OS_TRACE_Q_POST_FAILED(p_q);
|
||||
OS_TRACE_Q_POST_EXIT(OS_ERR_OBJ_PTR_NULL);
|
||||
*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)(OS_OPT_POST_ALL | OS_OPT_POST_NO_SCHED):
|
||||
case OS_OPT_POST_LIFO | (OS_OPT)(OS_OPT_POST_ALL | OS_OPT_POST_NO_SCHED):
|
||||
break;
|
||||
|
||||
default:
|
||||
OS_TRACE_Q_POST_FAILED(p_q);
|
||||
OS_TRACE_Q_POST_EXIT(OS_ERR_OPT_INVALID);
|
||||
*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 */
|
||||
OS_TRACE_Q_POST_FAILED(p_q);
|
||||
OS_TRACE_Q_POST_EXIT(OS_ERR_OBJ_TYPE);
|
||||
*p_err = OS_ERR_OBJ_TYPE;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#if (OS_CFG_TS_EN > 0u)
|
||||
ts = OS_TS_GET(); /* Get timestamp */
|
||||
#else
|
||||
ts = 0u;
|
||||
#endif
|
||||
|
||||
OS_TRACE_Q_POST(p_q);
|
||||
|
||||
CPU_CRITICAL_ENTER();
|
||||
p_pend_list = &p_q->PendList;
|
||||
if (p_pend_list->HeadPtr == (OS_TCB *)0) { /* Any task waiting on message queue? */
|
||||
if ((opt & OS_OPT_POST_LIFO) == 0u) { /* 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);
|
||||
CPU_CRITICAL_EXIT();
|
||||
OS_TRACE_Q_POST_EXIT(*p_err);
|
||||
return;
|
||||
}
|
||||
|
||||
p_tcb = p_pend_list->HeadPtr;
|
||||
while (p_tcb != (OS_TCB *)0) {
|
||||
p_tcb_next = p_tcb->PendNextPtr;
|
||||
OS_Post((OS_PEND_OBJ *)((void *)p_q),
|
||||
p_tcb,
|
||||
p_void,
|
||||
msg_size,
|
||||
ts);
|
||||
if ((opt & OS_OPT_POST_ALL) == 0u) { /* Post message to all tasks waiting? */
|
||||
break; /* No */
|
||||
}
|
||||
p_tcb = p_tcb_next;
|
||||
}
|
||||
|
||||
CPU_CRITICAL_EXIT();
|
||||
|
||||
if ((opt & OS_OPT_POST_NO_SCHED) == 0u) {
|
||||
OSSched(); /* Run the scheduler */
|
||||
}
|
||||
|
||||
*p_err = OS_ERR_NONE;
|
||||
OS_TRACE_Q_POST_EXIT(*p_err);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* 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 */
|
||||
#if (OS_OBJ_TYPE_REQ > 0u)
|
||||
p_q->Type = OS_OBJ_TYPE_NONE; /* Mark the data structure as a NONE */
|
||||
#endif
|
||||
#if (OS_CFG_DBG_EN > 0u)
|
||||
p_q->NamePtr = (CPU_CHAR *)((void *)"?Q");
|
||||
#endif
|
||||
OS_MsgQInit(&p_q->MsgQ, /* Initialize the list of OS_MSGs */
|
||||
0u);
|
||||
OS_PendListInit(&p_q->PendList); /* Initialize the waiting list */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* 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
|
||||
#endif
|
||||
|
|
@ -0,0 +1,966 @@
|
|||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/OS-III
|
||||
* The Real-Time Kernel
|
||||
*
|
||||
* Copyright 2009-2020 Silicon Laboratories Inc. www.silabs.com
|
||||
*
|
||||
* SPDX-License-Identifier: APACHE-2.0
|
||||
*
|
||||
* This software is subject to an open source license and is distributed by
|
||||
* Silicon Laboratories Inc. pursuant to the terms of the Apache License,
|
||||
* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* SEMAPHORE MANAGEMENT
|
||||
*
|
||||
* File : os_sem.c
|
||||
* Version : V3.08.00
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#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_OBJ_PTR_NULL If 'p_sem' is a NULL pointer
|
||||
* OS_ERR_OBJ_CREATED If the semaphore was already created
|
||||
*
|
||||
* Returns : none
|
||||
*
|
||||
* Note(s) : 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 == OS_TRUE) {
|
||||
*p_err = OS_ERR_ILLEGAL_CREATE_RUN_TIME;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u)
|
||||
if (OSIntNestingCtr > 0u) { /* 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
|
||||
|
||||
CPU_CRITICAL_ENTER();
|
||||
#if (OS_OBJ_TYPE_REQ > 0u)
|
||||
if (p_sem->Type == OS_OBJ_TYPE_SEM) {
|
||||
CPU_CRITICAL_EXIT();
|
||||
*p_err = OS_ERR_OBJ_CREATED;
|
||||
return;
|
||||
}
|
||||
p_sem->Type = OS_OBJ_TYPE_SEM; /* Mark the data structure as a semaphore */
|
||||
#endif
|
||||
p_sem->Ctr = cnt; /* Set semaphore value */
|
||||
#if (OS_CFG_TS_EN > 0u)
|
||||
p_sem->TS = 0u;
|
||||
#endif
|
||||
#if (OS_CFG_DBG_EN > 0u)
|
||||
p_sem->NamePtr = p_name; /* Save the name of the semaphore */
|
||||
#else
|
||||
(void)p_name;
|
||||
#endif
|
||||
OS_PendListInit(&p_sem->PendList); /* Initialize the waiting list */
|
||||
|
||||
#if (OS_CFG_DBG_EN > 0u)
|
||||
OS_SemDbgListAdd(p_sem);
|
||||
OSSemQty++;
|
||||
#endif
|
||||
|
||||
OS_TRACE_SEM_CREATE(p_sem, p_name);
|
||||
|
||||
CPU_CRITICAL_EXIT();
|
||||
*p_err = OS_ERR_NONE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* 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_ILLEGAL_DEL_RUN_TIME If you are trying to delete the semaphore after you called
|
||||
* OSStart()
|
||||
* 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_OS_NOT_RUNNING If uC/OS-III is not running yet
|
||||
* 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) 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 nbr_tasks;
|
||||
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 (0u);
|
||||
}
|
||||
#endif
|
||||
|
||||
OS_TRACE_SEM_DEL_ENTER(p_sem, opt);
|
||||
|
||||
#ifdef OS_SAFETY_CRITICAL_IEC61508
|
||||
if (OSSafetyCriticalStartFlag == OS_TRUE) {
|
||||
OS_TRACE_SEM_DEL_EXIT(OS_ERR_ILLEGAL_DEL_RUN_TIME);
|
||||
*p_err = OS_ERR_ILLEGAL_DEL_RUN_TIME;
|
||||
return (0u);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u)
|
||||
if (OSIntNestingCtr > 0u) { /* Not allowed to delete a semaphore from an ISR */
|
||||
OS_TRACE_SEM_DEL_EXIT(OS_ERR_DEL_ISR);
|
||||
*p_err = OS_ERR_DEL_ISR;
|
||||
return (0u);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_INVALID_OS_CALLS_CHK_EN > 0u)
|
||||
if (OSRunning != OS_STATE_OS_RUNNING) { /* Is the kernel running? */
|
||||
OS_TRACE_SEM_DEL_EXIT(OS_ERR_OS_NOT_RUNNING);
|
||||
*p_err = OS_ERR_OS_NOT_RUNNING;
|
||||
return (0u);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_ARG_CHK_EN > 0u)
|
||||
if (p_sem == (OS_SEM *)0) { /* Validate 'p_sem' */
|
||||
OS_TRACE_SEM_DEL_EXIT(OS_ERR_OBJ_PTR_NULL);
|
||||
*p_err = OS_ERR_OBJ_PTR_NULL;
|
||||
return (0u);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_OBJ_TYPE_CHK_EN > 0u)
|
||||
if (p_sem->Type != OS_OBJ_TYPE_SEM) { /* Make sure semaphore was created */
|
||||
OS_TRACE_SEM_DEL_EXIT(OS_ERR_OBJ_TYPE);
|
||||
*p_err = OS_ERR_OBJ_TYPE;
|
||||
return (0u);
|
||||
}
|
||||
#endif
|
||||
|
||||
CPU_CRITICAL_ENTER();
|
||||
p_pend_list = &p_sem->PendList;
|
||||
nbr_tasks = 0u;
|
||||
switch (opt) {
|
||||
case OS_OPT_DEL_NO_PEND: /* Delete semaphore only if no task waiting */
|
||||
if (p_pend_list->HeadPtr == (OS_TCB *)0) {
|
||||
#if (OS_CFG_DBG_EN > 0u)
|
||||
OS_SemDbgListRemove(p_sem);
|
||||
OSSemQty--;
|
||||
#endif
|
||||
OS_TRACE_SEM_DEL(p_sem);
|
||||
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 */
|
||||
#if (OS_CFG_TS_EN > 0u)
|
||||
ts = OS_TS_GET(); /* Get local time stamp so all tasks get the same time */
|
||||
#else
|
||||
ts = 0u;
|
||||
#endif
|
||||
while (p_pend_list->HeadPtr != (OS_TCB *)0) { /* Remove all tasks on the pend list */
|
||||
p_tcb = p_pend_list->HeadPtr;
|
||||
OS_PendAbort(p_tcb,
|
||||
ts,
|
||||
OS_STATUS_PEND_DEL);
|
||||
nbr_tasks++;
|
||||
}
|
||||
#if (OS_CFG_DBG_EN > 0u)
|
||||
OS_SemDbgListRemove(p_sem);
|
||||
OSSemQty--;
|
||||
#endif
|
||||
OS_TRACE_SEM_DEL(p_sem);
|
||||
OS_SemClr(p_sem);
|
||||
CPU_CRITICAL_EXIT();
|
||||
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;
|
||||
}
|
||||
|
||||
OS_TRACE_SEM_DEL_EXIT(*p_err);
|
||||
|
||||
return (nbr_tasks);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* 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 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_OS_NOT_RUNNING If uC/OS-III is not running yet
|
||||
* 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
|
||||
* OS_ERR_TICK_DISABLED If kernel ticks are disabled and a timeout is specified
|
||||
*
|
||||
*
|
||||
* Returns : The current value of the semaphore counter or 0 if not available.
|
||||
*
|
||||
* Note(s) : This API 'MUST NOT' be called from a timer callback function.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
|
||||
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;
|
||||
CPU_SR_ALLOC();
|
||||
|
||||
|
||||
#if (OS_CFG_TS_EN == 0u)
|
||||
(void)p_ts; /* Prevent compiler warning for not using 'ts' */
|
||||
#endif
|
||||
|
||||
#ifdef OS_SAFETY_CRITICAL
|
||||
if (p_err == (OS_ERR *)0) {
|
||||
OS_SAFETY_CRITICAL_EXCEPTION();
|
||||
return (0u);
|
||||
}
|
||||
#endif
|
||||
|
||||
OS_TRACE_SEM_PEND_ENTER(p_sem, timeout, opt, p_ts);
|
||||
|
||||
#if (OS_CFG_TICK_EN == 0u)
|
||||
if (timeout != 0u) {
|
||||
*p_err = OS_ERR_TICK_DISABLED;
|
||||
OS_TRACE_SEM_PEND_FAILED(p_sem);
|
||||
OS_TRACE_SEM_PEND_EXIT(OS_ERR_TICK_DISABLED);
|
||||
return (0u);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u)
|
||||
if (OSIntNestingCtr > 0u) { /* Not allowed to call from an ISR */
|
||||
if ((opt & OS_OPT_PEND_NON_BLOCKING) != OS_OPT_PEND_NON_BLOCKING) {
|
||||
OS_TRACE_SEM_PEND_FAILED(p_sem);
|
||||
OS_TRACE_SEM_PEND_EXIT(OS_ERR_PEND_ISR);
|
||||
*p_err = OS_ERR_PEND_ISR;
|
||||
return (0u);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_INVALID_OS_CALLS_CHK_EN > 0u)
|
||||
if (OSRunning != OS_STATE_OS_RUNNING) { /* Is the kernel running? */
|
||||
OS_TRACE_SEM_PEND_EXIT(OS_ERR_OS_NOT_RUNNING);
|
||||
*p_err = OS_ERR_OS_NOT_RUNNING;
|
||||
return (0u);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_ARG_CHK_EN > 0u)
|
||||
if (p_sem == (OS_SEM *)0) { /* Validate 'p_sem' */
|
||||
OS_TRACE_SEM_PEND_EXIT(OS_ERR_OBJ_PTR_NULL);
|
||||
*p_err = OS_ERR_OBJ_PTR_NULL;
|
||||
return (0u);
|
||||
}
|
||||
switch (opt) { /* Validate 'opt' */
|
||||
case OS_OPT_PEND_BLOCKING:
|
||||
case OS_OPT_PEND_NON_BLOCKING:
|
||||
break;
|
||||
|
||||
default:
|
||||
OS_TRACE_SEM_PEND_FAILED(p_sem);
|
||||
OS_TRACE_SEM_PEND_EXIT(OS_ERR_OPT_INVALID);
|
||||
*p_err = OS_ERR_OPT_INVALID;
|
||||
return (0u);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_OBJ_TYPE_CHK_EN > 0u)
|
||||
if (p_sem->Type != OS_OBJ_TYPE_SEM) { /* Make sure semaphore was created */
|
||||
OS_TRACE_SEM_PEND_FAILED(p_sem);
|
||||
OS_TRACE_SEM_PEND_EXIT(OS_ERR_OBJ_TYPE);
|
||||
*p_err = OS_ERR_OBJ_TYPE;
|
||||
return (0u);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
CPU_CRITICAL_ENTER();
|
||||
if (p_sem->Ctr > 0u) { /* Resource available? */
|
||||
p_sem->Ctr--; /* Yes, caller may proceed */
|
||||
#if (OS_CFG_TS_EN > 0u)
|
||||
if (p_ts != (CPU_TS *)0) {
|
||||
*p_ts = p_sem->TS; /* get timestamp of last post */
|
||||
}
|
||||
#endif
|
||||
ctr = p_sem->Ctr;
|
||||
OS_TRACE_SEM_PEND(p_sem);
|
||||
CPU_CRITICAL_EXIT();
|
||||
OS_TRACE_SEM_PEND_EXIT(OS_ERR_NONE);
|
||||
*p_err = OS_ERR_NONE;
|
||||
return (ctr);
|
||||
}
|
||||
|
||||
if ((opt & OS_OPT_PEND_NON_BLOCKING) != 0u) { /* Caller wants to block if not available? */
|
||||
#if (OS_CFG_TS_EN > 0u)
|
||||
if (p_ts != (CPU_TS *)0) {
|
||||
*p_ts = 0u;
|
||||
}
|
||||
#endif
|
||||
ctr = p_sem->Ctr; /* No */
|
||||
CPU_CRITICAL_EXIT();
|
||||
OS_TRACE_SEM_PEND_FAILED(p_sem);
|
||||
OS_TRACE_SEM_PEND_EXIT(OS_ERR_PEND_WOULD_BLOCK);
|
||||
*p_err = OS_ERR_PEND_WOULD_BLOCK;
|
||||
return (ctr);
|
||||
} else { /* Yes */
|
||||
if (OSSchedLockNestingCtr > 0u) { /* Can't pend when the scheduler is locked */
|
||||
#if (OS_CFG_TS_EN > 0u)
|
||||
if (p_ts != (CPU_TS *)0) {
|
||||
*p_ts = 0u;
|
||||
}
|
||||
#endif
|
||||
CPU_CRITICAL_EXIT();
|
||||
OS_TRACE_SEM_PEND_FAILED(p_sem);
|
||||
OS_TRACE_SEM_PEND_EXIT(OS_ERR_SCHED_LOCKED);
|
||||
*p_err = OS_ERR_SCHED_LOCKED;
|
||||
return (0u);
|
||||
}
|
||||
}
|
||||
|
||||
OS_Pend((OS_PEND_OBJ *)((void *)p_sem), /* Block task pending on Semaphore */
|
||||
OSTCBCurPtr,
|
||||
OS_TASK_PEND_ON_SEM,
|
||||
timeout);
|
||||
CPU_CRITICAL_EXIT();
|
||||
OS_TRACE_SEM_PEND_BLOCK(p_sem);
|
||||
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 (OS_CFG_TS_EN > 0u)
|
||||
if (p_ts != (CPU_TS *)0) {
|
||||
*p_ts = OSTCBCurPtr->TS;
|
||||
}
|
||||
#endif
|
||||
OS_TRACE_SEM_PEND(p_sem);
|
||||
*p_err = OS_ERR_NONE;
|
||||
break;
|
||||
|
||||
case OS_STATUS_PEND_ABORT: /* Indicate that we aborted */
|
||||
#if (OS_CFG_TS_EN > 0u)
|
||||
if (p_ts != (CPU_TS *)0) {
|
||||
*p_ts = OSTCBCurPtr->TS;
|
||||
}
|
||||
#endif
|
||||
OS_TRACE_SEM_PEND_FAILED(p_sem);
|
||||
*p_err = OS_ERR_PEND_ABORT;
|
||||
break;
|
||||
|
||||
case OS_STATUS_PEND_TIMEOUT: /* Indicate that we didn't get semaphore within timeout */
|
||||
#if (OS_CFG_TS_EN > 0u)
|
||||
if (p_ts != (CPU_TS *)0) {
|
||||
*p_ts = 0u;
|
||||
}
|
||||
#endif
|
||||
OS_TRACE_SEM_PEND_FAILED(p_sem);
|
||||
*p_err = OS_ERR_TIMEOUT;
|
||||
break;
|
||||
|
||||
case OS_STATUS_PEND_DEL: /* Indicate that object pended on has been deleted */
|
||||
#if (OS_CFG_TS_EN > 0u)
|
||||
if (p_ts != (CPU_TS *)0) {
|
||||
*p_ts = OSTCBCurPtr->TS;
|
||||
}
|
||||
#endif
|
||||
OS_TRACE_SEM_PEND_FAILED(p_sem);
|
||||
*p_err = OS_ERR_OBJ_DEL;
|
||||
break;
|
||||
|
||||
default:
|
||||
OS_TRACE_SEM_PEND_FAILED(p_sem);
|
||||
*p_err = OS_ERR_STATUS_INVALID;
|
||||
CPU_CRITICAL_EXIT();
|
||||
OS_TRACE_SEM_PEND_EXIT(*p_err);
|
||||
return (0u);
|
||||
}
|
||||
ctr = p_sem->Ctr;
|
||||
CPU_CRITICAL_EXIT();
|
||||
OS_TRACE_SEM_PEND_EXIT(*p_err);
|
||||
return (ctr);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* 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_OS_NOT_RUNNING If uC/OS-III is not running yet
|
||||
* 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.
|
||||
*
|
||||
* Note(s) : none
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
|
||||
#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 (0u);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u)
|
||||
if (OSIntNestingCtr > 0u) { /* Not allowed to Pend Abort from an ISR */
|
||||
*p_err = OS_ERR_PEND_ABORT_ISR;
|
||||
return (0u);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_INVALID_OS_CALLS_CHK_EN > 0u)
|
||||
if (OSRunning != OS_STATE_OS_RUNNING) { /* Is the kernel running? */
|
||||
*p_err = OS_ERR_OS_NOT_RUNNING;
|
||||
return (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 (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 (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 (0u);
|
||||
}
|
||||
#endif
|
||||
|
||||
CPU_CRITICAL_ENTER();
|
||||
p_pend_list = &p_sem->PendList;
|
||||
if (p_pend_list->HeadPtr == (OS_TCB *)0) { /* Any task waiting on semaphore? */
|
||||
CPU_CRITICAL_EXIT(); /* No */
|
||||
*p_err = OS_ERR_PEND_ABORT_NONE;
|
||||
return (0u);
|
||||
}
|
||||
|
||||
nbr_tasks = 0u;
|
||||
#if (OS_CFG_TS_EN > 0u)
|
||||
ts = OS_TS_GET(); /* Get local time stamp so all tasks get the same time */
|
||||
#else
|
||||
ts = 0u;
|
||||
#endif
|
||||
while (p_pend_list->HeadPtr != (OS_TCB *)0) {
|
||||
p_tcb = p_pend_list->HeadPtr;
|
||||
OS_PendAbort(p_tcb,
|
||||
ts,
|
||||
OS_STATUS_PEND_ABORT);
|
||||
nbr_tasks++;
|
||||
if (opt != OS_OPT_PEND_ABORT_ALL) { /* Pend abort all tasks waiting? */
|
||||
break; /* No */
|
||||
}
|
||||
}
|
||||
CPU_CRITICAL_EXIT();
|
||||
|
||||
if ((opt & OS_OPT_POST_NO_SCHED) == 0u) {
|
||||
OSSched(); /* Run the scheduler */
|
||||
}
|
||||
|
||||
*p_err = OS_ERR_NONE;
|
||||
return (nbr_tasks);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* 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
|
||||
*
|
||||
*
|
||||
* 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_OPT_INVALID If you specified an invalid option
|
||||
* OS_ERR_OS_NOT_RUNNING If uC/OS-III is not running yet
|
||||
* 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) : 1) OS_OPT_POST_NO_SCHED can be added with one of the other options.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
|
||||
OS_SEM_CTR OSSemPost (OS_SEM *p_sem,
|
||||
OS_OPT opt,
|
||||
OS_ERR *p_err)
|
||||
{
|
||||
OS_SEM_CTR ctr;
|
||||
OS_PEND_LIST *p_pend_list;
|
||||
OS_TCB *p_tcb;
|
||||
OS_TCB *p_tcb_next;
|
||||
CPU_TS ts;
|
||||
CPU_SR_ALLOC();
|
||||
|
||||
|
||||
#ifdef OS_SAFETY_CRITICAL
|
||||
if (p_err == (OS_ERR *)0) {
|
||||
OS_SAFETY_CRITICAL_EXCEPTION();
|
||||
return (0u);
|
||||
}
|
||||
#endif
|
||||
|
||||
OS_TRACE_SEM_POST_ENTER(p_sem, opt);
|
||||
|
||||
#if (OS_CFG_INVALID_OS_CALLS_CHK_EN > 0u)
|
||||
if (OSRunning != OS_STATE_OS_RUNNING) { /* Is the kernel running? */
|
||||
OS_TRACE_SEM_POST_EXIT(OS_ERR_OS_NOT_RUNNING);
|
||||
*p_err = OS_ERR_OS_NOT_RUNNING;
|
||||
return (0u);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_ARG_CHK_EN > 0u)
|
||||
if (p_sem == (OS_SEM *)0) { /* Validate 'p_sem' */
|
||||
OS_TRACE_SEM_POST_FAILED(p_sem);
|
||||
OS_TRACE_SEM_POST_EXIT(OS_ERR_OBJ_PTR_NULL);
|
||||
*p_err = OS_ERR_OBJ_PTR_NULL;
|
||||
return (0u);
|
||||
}
|
||||
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:
|
||||
OS_TRACE_SEM_POST_FAILED(p_sem);
|
||||
OS_TRACE_SEM_POST_EXIT(OS_ERR_OPT_INVALID);
|
||||
*p_err = OS_ERR_OPT_INVALID;
|
||||
return (0u);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_OBJ_TYPE_CHK_EN > 0u)
|
||||
if (p_sem->Type != OS_OBJ_TYPE_SEM) { /* Make sure semaphore was created */
|
||||
OS_TRACE_SEM_POST_FAILED(p_sem);
|
||||
OS_TRACE_SEM_POST_EXIT(OS_ERR_OBJ_TYPE);
|
||||
*p_err = OS_ERR_OBJ_TYPE;
|
||||
return (0u);
|
||||
}
|
||||
#endif
|
||||
#if (OS_CFG_TS_EN > 0u)
|
||||
ts = OS_TS_GET(); /* Get timestamp */
|
||||
#else
|
||||
ts = 0u;
|
||||
#endif
|
||||
|
||||
OS_TRACE_SEM_POST(p_sem);
|
||||
CPU_CRITICAL_ENTER();
|
||||
p_pend_list = &p_sem->PendList;
|
||||
if (p_pend_list->HeadPtr == (OS_TCB *)0) { /* Any task waiting on semaphore? */
|
||||
if (p_sem->Ctr == (OS_SEM_CTR)-1) {
|
||||
CPU_CRITICAL_EXIT();
|
||||
*p_err = OS_ERR_SEM_OVF;
|
||||
OS_TRACE_SEM_POST_EXIT(*p_err);
|
||||
return (0u);
|
||||
}
|
||||
p_sem->Ctr++; /* No */
|
||||
ctr = p_sem->Ctr;
|
||||
#if (OS_CFG_TS_EN > 0u)
|
||||
p_sem->TS = ts; /* Save timestamp in semaphore control block */
|
||||
#endif
|
||||
CPU_CRITICAL_EXIT();
|
||||
*p_err = OS_ERR_NONE;
|
||||
OS_TRACE_SEM_POST_EXIT(*p_err);
|
||||
return (ctr);
|
||||
}
|
||||
|
||||
p_tcb = p_pend_list->HeadPtr;
|
||||
while (p_tcb != (OS_TCB *)0) {
|
||||
p_tcb_next = p_tcb->PendNextPtr;
|
||||
OS_Post((OS_PEND_OBJ *)((void *)p_sem),
|
||||
p_tcb,
|
||||
(void *)0,
|
||||
0u,
|
||||
ts);
|
||||
if ((opt & OS_OPT_POST_ALL) == 0u) { /* Post to all tasks waiting? */
|
||||
break; /* No */
|
||||
}
|
||||
p_tcb = p_tcb_next;
|
||||
}
|
||||
CPU_CRITICAL_EXIT();
|
||||
if ((opt & OS_OPT_POST_NO_SCHED) == 0u) {
|
||||
OSSched(); /* Run the scheduler */
|
||||
}
|
||||
*p_err = OS_ERR_NONE;
|
||||
|
||||
OS_TRACE_SEM_POST_EXIT(*p_err);
|
||||
return (0u);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* 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_SET_ISR If called from an ISR
|
||||
* OS_ERR_TASK_WAITING If tasks are waiting on the semaphore
|
||||
*
|
||||
* Returns : None
|
||||
*
|
||||
* Note(s) : 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 > 0u) { /* 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 > 0u) { /* 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->HeadPtr == (OS_TCB *)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
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* 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)
|
||||
{
|
||||
#if (OS_OBJ_TYPE_REQ > 0u)
|
||||
p_sem->Type = OS_OBJ_TYPE_NONE; /* Mark the data structure as a NONE */
|
||||
#endif
|
||||
p_sem->Ctr = 0u; /* Set semaphore value */
|
||||
#if (OS_CFG_TS_EN > 0u)
|
||||
p_sem->TS = 0u; /* Clear the time stamp */
|
||||
#endif
|
||||
#if (OS_CFG_DBG_EN > 0u)
|
||||
p_sem->NamePtr = (CPU_CHAR *)((void *)"?SEM");
|
||||
#endif
|
||||
OS_PendListInit(&p_sem->PendList); /* Initialize the waiting list */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* 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
|
||||
#endif
|
||||
|
|
@ -0,0 +1,571 @@
|
|||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/OS-III
|
||||
* The Real-Time Kernel
|
||||
*
|
||||
* Copyright 2009-2020 Silicon Laboratories Inc. www.silabs.com
|
||||
*
|
||||
* SPDX-License-Identifier: APACHE-2.0
|
||||
*
|
||||
* This software is subject to an open source license and is distributed by
|
||||
* Silicon Laboratories Inc. pursuant to the terms of the Apache License,
|
||||
* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* STATISTICS MODULE
|
||||
*
|
||||
* File : os_stat.c
|
||||
* Version : V3.08.00
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#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 The call succeeded
|
||||
*
|
||||
* Returns : none
|
||||
*
|
||||
* Note(s) : 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_STAT_TASK_EN > 0u)
|
||||
OSStatTaskCPUUsageMax = 0u;
|
||||
#if (OS_CFG_TS_EN > 0u)
|
||||
OSStatTaskTimeMax = 0u;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_TS_EN > 0u) && (OS_CFG_TICK_EN > 0u)
|
||||
OSTickTime = 0u;
|
||||
OSTickTimeMax = 0u;
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_TMR_EN > 0u)
|
||||
#if (OS_CFG_TS_EN > 0u)
|
||||
OSTmrTaskTime = 0u;
|
||||
OSTmrTaskTimeMax = 0u;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CPU_CFG_INT_DIS_MEAS_EN
|
||||
#if (OS_CFG_TS_EN > 0u)
|
||||
OSIntDisTimeMax = 0u; /* Reset the maximum interrupt disable time */
|
||||
CPU_StatReset(); /* Reset CPU-specific performance monitors. */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_SCHED_LOCK_TIME_MEAS_EN > 0u)
|
||||
OSSchedLockTimeMax = 0u; /* Reset the maximum scheduler lock time */
|
||||
#endif
|
||||
|
||||
#if ((OS_MSG_EN > 0u) && (OS_CFG_DBG_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 = 0u;
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_SCHED_LOCK_TIME_MEAS_EN > 0u)
|
||||
p_tcb->SchedLockTimeMax = 0u;
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_TASK_PROFILE_EN > 0u)
|
||||
#if (OS_CFG_TASK_Q_EN > 0u)
|
||||
p_tcb->MsgQPendTimeMax = 0u;
|
||||
#endif
|
||||
p_tcb->SemPendTimeMax = 0u;
|
||||
p_tcb->CtxSwCtr = 0u;
|
||||
p_tcb->CPUUsage = 0u;
|
||||
p_tcb->CPUUsageMax = 0u;
|
||||
p_tcb->CyclesTotal = 0u;
|
||||
p_tcb->CyclesTotalPrev = 0u;
|
||||
#if (OS_CFG_TS_EN > 0u)
|
||||
p_tcb->CyclesStart = OS_TS_GET();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_TASK_Q_EN > 0u)
|
||||
p_msg_q = &p_tcb->MsgQ;
|
||||
p_msg_q->NbrEntriesMax = 0u;
|
||||
#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 = 0u;
|
||||
p_q = p_q->DbgNextPtr;
|
||||
CPU_CRITICAL_EXIT();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
*p_err = OS_ERR_NONE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* 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 The call was successfu
|
||||
* OS_ERR_OS_NOT_RUNNING If uC/OS-III is not running yet
|
||||
*
|
||||
* Returns : none
|
||||
*
|
||||
* Note(s) : none
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
|
||||
void OSStatTaskCPUUsageInit (OS_ERR *p_err)
|
||||
{
|
||||
OS_ERR err;
|
||||
OS_TICK dly;
|
||||
CPU_SR_ALLOC();
|
||||
|
||||
|
||||
err = OS_ERR_NONE; /* Initialize err explicitly for static analysis. */
|
||||
|
||||
#ifdef OS_SAFETY_CRITICAL
|
||||
if (p_err == (OS_ERR *)0) {
|
||||
OS_SAFETY_CRITICAL_EXCEPTION();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_INVALID_OS_CALLS_CHK_EN > 0u)
|
||||
if (OSRunning != OS_STATE_OS_RUNNING) { /* Is the kernel running? */
|
||||
*p_err = OS_ERR_OS_NOT_RUNNING;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ((OS_CFG_TMR_EN > 0u) && (OS_CFG_TASK_SUSPEND_EN > 0u))
|
||||
OSTaskSuspend(&OSTmrTaskTCB, &err);
|
||||
if (err != OS_ERR_NONE) {
|
||||
*p_err = err;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
OSTimeDly(2u, /* 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 = 0u; /* Clear idle counter */
|
||||
CPU_CRITICAL_EXIT();
|
||||
|
||||
dly = 0u;
|
||||
if (OSCfg_TickRate_Hz > OSCfg_StatTaskRate_Hz) {
|
||||
dly = (OS_TICK)(OSCfg_TickRate_Hz / OSCfg_StatTaskRate_Hz);
|
||||
}
|
||||
if (dly == 0u) {
|
||||
dly = (OSCfg_TickRate_Hz / 10u);
|
||||
}
|
||||
|
||||
OSTimeDly(dly, /* Determine MAX. idle counter value */
|
||||
OS_OPT_TIME_DLY,
|
||||
&err);
|
||||
|
||||
#if ((OS_CFG_TMR_EN > 0u) && (OS_CFG_TASK_SUSPEND_EN > 0u))
|
||||
OSTaskResume(&OSTmrTaskTCB, &err);
|
||||
if (err != OS_ERR_NONE) {
|
||||
*p_err = err;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
CPU_CRITICAL_ENTER();
|
||||
#if (OS_CFG_TS_EN > 0u)
|
||||
OSStatTaskTimeMax = 0u;
|
||||
#endif
|
||||
|
||||
OSStatTaskCtrMax = OSStatTaskCtr; /* Store maximum idle counter count */
|
||||
OSStatTaskRdy = OS_STATE_RDY;
|
||||
CPU_CRITICAL_EXIT();
|
||||
*p_err = OS_ERR_NONE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* 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;
|
||||
#if (OS_CFG_TS_EN > 0u)
|
||||
CPU_TS ts_start;
|
||||
#endif
|
||||
#if (OS_CFG_STAT_TASK_STK_CHK_EN > 0u) && (OS_CFG_ISR_STK_SIZE > 0u)
|
||||
CPU_STK *p_stk;
|
||||
CPU_INT32U free_stk;
|
||||
CPU_INT32U size_stk;
|
||||
#endif
|
||||
CPU_SR_ALLOC();
|
||||
|
||||
|
||||
(void)p_arg; /* Prevent compiler warning for not using 'p_arg' */
|
||||
|
||||
while (OSStatTaskRdy != OS_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 = (OSCfg_TickRate_Hz / OSCfg_StatTaskRate_Hz);
|
||||
}
|
||||
if (dly == 0u) {
|
||||
dly = (OSCfg_TickRate_Hz / 10u);
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
#if (OS_CFG_TS_EN > 0u)
|
||||
ts_start = OS_TS_GET();
|
||||
#ifdef CPU_CFG_INT_DIS_MEAS_EN
|
||||
OSIntDisTimeMax = CPU_IntDisMeasMaxGet();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
CPU_CRITICAL_ENTER(); /* ---------------- OVERALL CPU USAGE ----------------- */
|
||||
OSStatTaskCtrRun = OSStatTaskCtr; /* Obtain the of the stat counter for the past .1 second*/
|
||||
OSStatTaskCtr = 0u; /* 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 = 0u;
|
||||
}
|
||||
|
||||
OSStatTaskHook(); /* Invoke user definable hook */
|
||||
|
||||
|
||||
#if (OS_CFG_DBG_EN > 0u)
|
||||
#if (OS_CFG_TASK_PROFILE_EN > 0u)
|
||||
cycles_total = 0u;
|
||||
|
||||
CPU_CRITICAL_ENTER();
|
||||
p_tcb = OSTaskDbgListPtr;
|
||||
CPU_CRITICAL_EXIT();
|
||||
while (p_tcb != (OS_TCB *)0) { /* ---------------- TOTAL CYCLES COUNT ---------------- */
|
||||
CPU_CRITICAL_ENTER();
|
||||
p_tcb->CyclesTotalPrev = p_tcb->CyclesTotal; /* Save accumulated # cycles into a temp variable */
|
||||
p_tcb->CyclesTotal = 0u; /* Reset total cycles for task for next run */
|
||||
CPU_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 > 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
|
||||
|
||||
/*------------------ Check ISR Stack -------------------*/
|
||||
#if (OS_CFG_STAT_TASK_STK_CHK_EN > 0u) && (OS_CFG_ISR_STK_SIZE > 0u)
|
||||
free_stk = 0u;
|
||||
#if (CPU_CFG_STK_GROWTH == CPU_STK_GROWTH_HI_TO_LO)
|
||||
p_stk = OSCfg_ISRStkBasePtr; /* Start at the lowest memory and go up */
|
||||
#if (OS_CFG_TASK_STK_REDZONE_EN > 0u)
|
||||
p_stk += OS_CFG_TASK_STK_REDZONE_DEPTH;
|
||||
size_stk = OSCfg_ISRStkSize - OS_CFG_TASK_STK_REDZONE_DEPTH;
|
||||
#else
|
||||
size_stk = OSCfg_ISRStkSize;
|
||||
#endif
|
||||
while ((*p_stk == 0u) && (free_stk < size_stk)) { /* Compute the number of zero entries on the stk */
|
||||
p_stk++;
|
||||
free_stk++;
|
||||
}
|
||||
#else
|
||||
p_stk = OSCfg_ISRStkBasePtr + OSCfg_ISRStkSize - 1u;/* Start at the highest memory and go down */
|
||||
#if (OS_CFG_TASK_STK_REDZONE_EN > 0u)
|
||||
p_stk -= OS_CFG_TASK_STK_REDZONE_DEPTH;
|
||||
size_stk = OSCfg_ISRStkSize - OS_CFG_TASK_STK_REDZONE_DEPTH;
|
||||
#else
|
||||
size_stk = OSCfg_ISRStkSize;
|
||||
#endif
|
||||
while ((*p_stk == 0u) && (free_stk < size_stk)) { /* Compute the number of zero entries on the stk */
|
||||
free_stk++;
|
||||
p_stk--;
|
||||
}
|
||||
#endif
|
||||
OSISRStkFree = free_stk;
|
||||
OSISRStkUsed = OSCfg_ISRStkSize - free_stk;
|
||||
#endif
|
||||
|
||||
if (OSStatResetFlag == OS_TRUE) { /* Check if need to reset statistics */
|
||||
OSStatResetFlag = OS_FALSE;
|
||||
OSStatReset(&err);
|
||||
}
|
||||
|
||||
#if (OS_CFG_TS_EN > 0u)
|
||||
OSStatTaskTime = OS_TS_GET() - ts_start; /*----- Measure execution time of statistic task -------*/
|
||||
if (OSStatTaskTimeMax < OSStatTaskTime) {
|
||||
OSStatTaskTimeMax = OSStatTaskTime;
|
||||
}
|
||||
#endif
|
||||
|
||||
OSTimeDly(dly,
|
||||
OS_OPT_TIME_DLY,
|
||||
&err);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* 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_STAT_STK_INVALID If you specified a NULL stack pointer during configuration
|
||||
* OS_ERR_STAT_STK_SIZE_INVALID If you didn't specify a large enough stack.
|
||||
* OS_ERR_STAT_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)
|
||||
{
|
||||
OSStatTaskCtr = 0u;
|
||||
OSStatTaskCtrRun = 0u;
|
||||
OSStatTaskCtrMax = 0u;
|
||||
OSStatTaskRdy = OS_STATE_NOT_RDY; /* Statistic task is not ready */
|
||||
OSStatResetFlag = OS_FALSE;
|
||||
|
||||
#if (OS_CFG_STAT_TASK_STK_CHK_EN > 0u) && (OS_CFG_ISR_STK_SIZE > 0u)
|
||||
OSISRStkFree = 0u;
|
||||
OSISRStkUsed = 0u;
|
||||
#endif
|
||||
/* --------------- 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(&OSStatTaskTCB,
|
||||
#if (OS_CFG_DBG_EN == 0u)
|
||||
(CPU_CHAR *)0,
|
||||
#else
|
||||
(CPU_CHAR *)"uC/OS-III Stat Task",
|
||||
#endif
|
||||
OS_StatTask,
|
||||
(void *)0,
|
||||
OSCfg_StatTaskPrio,
|
||||
OSCfg_StatTaskStkBasePtr,
|
||||
OSCfg_StatTaskStkLimit,
|
||||
OSCfg_StatTaskStkSize,
|
||||
0u,
|
||||
0u,
|
||||
(void *)0,
|
||||
(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
|
||||
p_err);
|
||||
}
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,577 @@
|
|||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/OS-III
|
||||
* The Real-Time Kernel
|
||||
*
|
||||
* Copyright 2009-2020 Silicon Laboratories Inc. www.silabs.com
|
||||
*
|
||||
* SPDX-License-Identifier: APACHE-2.0
|
||||
*
|
||||
* This software is subject to an open source license and is distributed by
|
||||
* Silicon Laboratories Inc. pursuant to the terms of the Apache License,
|
||||
* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* TICK MANAGEMENT
|
||||
*
|
||||
* File : os_tick.c
|
||||
* Version : V3.08.00
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#define MICRIUM_SOURCE
|
||||
#include "os.h"
|
||||
|
||||
#ifdef VSC_INCLUDE_SOURCE_FILE_NAMES
|
||||
const CPU_CHAR *os_tick__c = "$Id: $";
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_TICK_EN > 0u)
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* FUNCTION PROTOTYPES
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
|
||||
static void OS_TickListUpdate (OS_TICK ticks);
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* TICK INIT
|
||||
*
|
||||
* Description: This function initializes the variables related to the tick handler.
|
||||
* The function is internal to uC/OS-III.
|
||||
*
|
||||
* Arguments : p_err is a pointer to a variable that will contain an error code returned by this function.
|
||||
* -----
|
||||
* OS_ERR_NONE the tick variables were initialized successfully
|
||||
*
|
||||
* Returns : none
|
||||
*
|
||||
* Note(s) : This function is INTERNAL to uC/OS-III and your application should not call it.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
|
||||
void OS_TickInit (OS_ERR *p_err)
|
||||
{
|
||||
*p_err = OS_ERR_NONE;
|
||||
|
||||
OSTickCtr = 0u; /* Clear the tick counter */
|
||||
|
||||
#if (OS_CFG_DYN_TICK_EN > 0u)
|
||||
OSTickCtrStep = 0u;
|
||||
#endif
|
||||
|
||||
OSTickList.TCB_Ptr = (OS_TCB *)0;
|
||||
|
||||
#if (OS_CFG_DBG_EN > 0u)
|
||||
OSTickList.NbrEntries = 0u;
|
||||
OSTickList.NbrUpdated = 0u;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* TICK UPDATE
|
||||
*
|
||||
* Description: This function updates the list of task either delayed pending with timeout.
|
||||
* The function is internal to uC/OS-III.
|
||||
*
|
||||
* Arguments : ticks the number of ticks which have elapsed
|
||||
* -----
|
||||
*
|
||||
* Returns : none
|
||||
*
|
||||
* Note(s) : This function is INTERNAL to uC/OS-III and your application should not call it.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
|
||||
void OS_TickUpdate (OS_TICK ticks)
|
||||
{
|
||||
#if (OS_CFG_TS_EN > 0u)
|
||||
CPU_TS ts_start;
|
||||
#endif
|
||||
CPU_SR_ALLOC();
|
||||
|
||||
|
||||
CPU_CRITICAL_ENTER();
|
||||
|
||||
OSTickCtr += ticks; /* Keep track of the number of ticks */
|
||||
|
||||
OS_TRACE_TICK_INCREMENT(OSTickCtr);
|
||||
|
||||
#if (OS_CFG_TS_EN > 0u)
|
||||
ts_start = OS_TS_GET();
|
||||
OS_TickListUpdate(ticks);
|
||||
OSTickTime = OS_TS_GET() - ts_start;
|
||||
if (OSTickTimeMax < OSTickTime) {
|
||||
OSTickTimeMax = OSTickTime;
|
||||
}
|
||||
#else
|
||||
OS_TickListUpdate(ticks);
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_DYN_TICK_EN > 0u)
|
||||
if (OSTickList.TCB_Ptr != (OS_TCB *)0) {
|
||||
OSTickCtrStep = OSTickList.TCB_Ptr->TickRemain;
|
||||
} else {
|
||||
OSTickCtrStep = 0u;
|
||||
}
|
||||
|
||||
OS_DynTickSet(OSTickCtrStep);
|
||||
#endif
|
||||
CPU_CRITICAL_EXIT();
|
||||
}
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* INSERT
|
||||
*
|
||||
* Description: This task is internal to uC/OS-III and allows the insertion of a task in a tick list.
|
||||
*
|
||||
* Arguments : p_tcb is a pointer to the TCB to insert in the list
|
||||
*
|
||||
* elapsed is the number of elapsed ticks since the last tick interrupt
|
||||
*
|
||||
* tick_base is value of OSTickCtr from which time is offset
|
||||
*
|
||||
* time is the amount of time remaining (in ticks) for the task to become ready
|
||||
*
|
||||
* Returns : OS_TRUE if time is valid for the given tick base
|
||||
*
|
||||
* OS_FALSE if time is invalid (i.e. zero delay)
|
||||
*
|
||||
* Note(s) : 1) This function is INTERNAL to uC/OS-III and your application should not call it.
|
||||
*
|
||||
* 2) This function supports both Periodic Tick Mode (PTM) and Dynamic Tick Mode (DTM).
|
||||
*
|
||||
* 3) PTM should always call this function with elapsed == 0u.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
|
||||
CPU_BOOLEAN OS_TickListInsert (OS_TCB *p_tcb,
|
||||
OS_TICK elapsed,
|
||||
OS_TICK tick_base,
|
||||
OS_TICK time)
|
||||
{
|
||||
OS_TCB *p_tcb1;
|
||||
OS_TCB *p_tcb2;
|
||||
OS_TICK_LIST *p_list;
|
||||
OS_TICK delta;
|
||||
OS_TICK remain;
|
||||
|
||||
|
||||
delta = (time + tick_base) - (OSTickCtr + elapsed); /* How many ticks until our delay expires? */
|
||||
|
||||
if (delta == 0u) {
|
||||
p_tcb->TickRemain = 0u;
|
||||
return (OS_FALSE);
|
||||
}
|
||||
|
||||
OS_TRACE_TASK_DLY(delta);
|
||||
|
||||
p_list = &OSTickList;
|
||||
if (p_list->TCB_Ptr == (OS_TCB *)0) { /* Is the list empty? */
|
||||
p_tcb->TickRemain = delta; /* Yes, Store time in TCB */
|
||||
p_tcb->TickNextPtr = (OS_TCB *)0;
|
||||
p_tcb->TickPrevPtr = (OS_TCB *)0;
|
||||
p_list->TCB_Ptr = p_tcb; /* Point to TCB of task to place in the list */
|
||||
#if (OS_CFG_DYN_TICK_EN > 0u)
|
||||
if (elapsed != 0u) {
|
||||
OSTickCtr += elapsed; /* Update OSTickCtr before we set a new tick step. */
|
||||
OS_TRACE_TICK_INCREMENT(OSTickCtr);
|
||||
}
|
||||
|
||||
OSTickCtrStep = delta;
|
||||
OS_DynTickSet(OSTickCtrStep);
|
||||
#endif
|
||||
#if (OS_CFG_DBG_EN > 0u)
|
||||
p_list->NbrEntries = 1u; /* List contains 1 entry */
|
||||
#endif
|
||||
return (OS_TRUE);
|
||||
}
|
||||
|
||||
|
||||
#if (OS_CFG_DBG_EN > 0u)
|
||||
p_list->NbrEntries++; /* Update debug counter to reflect the new entry. */
|
||||
#endif
|
||||
|
||||
p_tcb2 = p_list->TCB_Ptr;
|
||||
remain = p_tcb2->TickRemain - elapsed; /* How many ticks until the head's delay expires? */
|
||||
|
||||
if ((delta < remain) && /* If our entry is the new head of the tick list ... */
|
||||
(p_tcb2->TickPrevPtr == (OS_TCB *)0)) {
|
||||
p_tcb->TickRemain = delta; /* ... the delta is equivalent to the full delay ... */
|
||||
p_tcb2->TickRemain = remain - delta; /* ... the previous head's delta is now relative to it. */
|
||||
|
||||
p_tcb->TickPrevPtr = (OS_TCB *)0;
|
||||
p_tcb->TickNextPtr = p_tcb2;
|
||||
p_tcb2->TickPrevPtr = p_tcb;
|
||||
p_list->TCB_Ptr = p_tcb;
|
||||
#if (OS_CFG_DYN_TICK_EN > 0u)
|
||||
if (elapsed != 0u) {
|
||||
OSTickCtr += elapsed; /* Update OSTickCtr before we set a new tick step. */
|
||||
OS_TRACE_TICK_INCREMENT(OSTickCtr);
|
||||
}
|
||||
/* In DTM, a new list head must update the tick ... */
|
||||
OSTickCtrStep = delta; /* ... timer to interrupt at the new delay value. */
|
||||
OS_DynTickSet(OSTickCtrStep);
|
||||
#endif
|
||||
|
||||
return (OS_TRUE);
|
||||
}
|
||||
|
||||
/* Our entry comes after the current list head. */
|
||||
delta -= remain; /* Make delta relative to the head. */
|
||||
p_tcb1 = p_tcb2;
|
||||
p_tcb2 = p_tcb1->TickNextPtr;
|
||||
|
||||
while ((p_tcb2 != (OS_TCB *)0) && /* Find the appropriate position in the delta list. */
|
||||
(delta >= p_tcb2->TickRemain)) {
|
||||
delta -= p_tcb2->TickRemain;
|
||||
p_tcb1 = p_tcb2;
|
||||
p_tcb2 = p_tcb2->TickNextPtr;
|
||||
}
|
||||
|
||||
if (p_tcb2 != (OS_TCB *)0) { /* Our entry is not the last element in the list. */
|
||||
p_tcb1 = p_tcb2->TickPrevPtr;
|
||||
p_tcb->TickRemain = delta; /* Store remaining time */
|
||||
p_tcb->TickPrevPtr = p_tcb1;
|
||||
p_tcb->TickNextPtr = p_tcb2;
|
||||
p_tcb2->TickRemain -= delta; /* Reduce time of next entry in the list */
|
||||
p_tcb2->TickPrevPtr = p_tcb;
|
||||
p_tcb1->TickNextPtr = p_tcb;
|
||||
|
||||
} else { /* Our entry belongs at the end of the list. */
|
||||
p_tcb->TickRemain = delta;
|
||||
p_tcb->TickPrevPtr = p_tcb1;
|
||||
p_tcb->TickNextPtr = (OS_TCB *)0;
|
||||
p_tcb1->TickNextPtr = p_tcb;
|
||||
}
|
||||
|
||||
return (OS_TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* ADD DELAYED TASK TO TICK LIST
|
||||
*
|
||||
* Description: This function is called to place a task in a list of task waiting for time to expire
|
||||
*
|
||||
* 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
|
||||
* system time 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 the effective delay is zero
|
||||
*
|
||||
* 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_TickListInsertDly (OS_TCB *p_tcb,
|
||||
OS_TICK time,
|
||||
OS_OPT opt,
|
||||
OS_ERR *p_err)
|
||||
{
|
||||
OS_TICK elapsed;
|
||||
OS_TICK tick_base;
|
||||
OS_TICK base_offset;
|
||||
CPU_BOOLEAN valid_dly;
|
||||
|
||||
|
||||
#if (OS_CFG_DYN_TICK_EN > 0u)
|
||||
elapsed = OS_DynTickGet();
|
||||
#else
|
||||
elapsed = 0u;
|
||||
#endif
|
||||
|
||||
if (opt == OS_OPT_TIME_MATCH) { /* MATCH to absolute tick ctr value mode */
|
||||
tick_base = 0u; /* tick_base + time == time */
|
||||
|
||||
} else if (opt == OS_OPT_TIME_PERIODIC) { /* PERIODIC mode. */
|
||||
if (time == 0u) {
|
||||
*p_err = OS_ERR_TIME_ZERO_DLY; /* Infinite frequency is invalid. */
|
||||
return;
|
||||
}
|
||||
|
||||
tick_base = p_tcb->TickCtrPrev;
|
||||
|
||||
#if (OS_CFG_DYN_TICK_EN > 0u) /* How far is our tick-base from the system time? */
|
||||
base_offset = OSTickCtr + elapsed - tick_base;
|
||||
#else
|
||||
base_offset = OSTickCtr - tick_base;
|
||||
#endif
|
||||
|
||||
if (base_offset >= time) { /* If our task missed the last period, move ... */
|
||||
tick_base += time * (base_offset / time); /* ... tick_base up to the next one. */
|
||||
if ((base_offset % time) != 0u) {
|
||||
tick_base += time; /* Account for rounding errors with integer division */
|
||||
}
|
||||
|
||||
p_tcb->TickCtrPrev = tick_base; /* Adjust the periodic tick base */
|
||||
}
|
||||
|
||||
p_tcb->TickCtrPrev += time; /* Update for the next time we perform a periodic dly. */
|
||||
|
||||
} else { /* RELATIVE time delay mode */
|
||||
#if (OS_CFG_DYN_TICK_EN > 0u) /* Our base is always the current system time. */
|
||||
tick_base = OSTickCtr + elapsed;
|
||||
#else
|
||||
tick_base = OSTickCtr;
|
||||
#endif
|
||||
}
|
||||
|
||||
valid_dly = OS_TickListInsert(p_tcb, elapsed, tick_base, time);
|
||||
|
||||
if (valid_dly == OS_TRUE) {
|
||||
p_tcb->TaskState = OS_TASK_STATE_DLY;
|
||||
*p_err = OS_ERR_NONE;
|
||||
} else {
|
||||
*p_err = OS_ERR_TIME_ZERO_DLY;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* 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_TCB *p_tcb1;
|
||||
OS_TCB *p_tcb2;
|
||||
OS_TICK_LIST *p_list;
|
||||
#if (OS_CFG_DYN_TICK_EN > 0u)
|
||||
OS_TICK elapsed;
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_DYN_TICK_EN > 0u)
|
||||
elapsed = OS_DynTickGet();
|
||||
#endif
|
||||
|
||||
p_tcb1 = p_tcb->TickPrevPtr;
|
||||
p_tcb2 = p_tcb->TickNextPtr;
|
||||
p_list = &OSTickList;
|
||||
if (p_tcb1 == (OS_TCB *)0) {
|
||||
if (p_tcb2 == (OS_TCB *)0) { /* Remove the ONLY entry in the list? */
|
||||
p_list->TCB_Ptr = (OS_TCB *)0;
|
||||
#if (OS_CFG_DBG_EN > 0u)
|
||||
p_list->NbrEntries = 0u;
|
||||
#endif
|
||||
p_tcb->TickRemain = 0u;
|
||||
#if (OS_CFG_DYN_TICK_EN > 0u)
|
||||
if (elapsed != 0u) {
|
||||
OSTickCtr += elapsed; /* Keep track of time. */
|
||||
OS_TRACE_TICK_INCREMENT(OSTickCtr);
|
||||
}
|
||||
OSTickCtrStep = 0u;
|
||||
OS_DynTickSet(OSTickCtrStep);
|
||||
#endif
|
||||
} else {
|
||||
p_tcb2->TickPrevPtr = (OS_TCB *)0;
|
||||
p_tcb2->TickRemain += p_tcb->TickRemain; /* Add back the ticks to the delta */
|
||||
p_list->TCB_Ptr = p_tcb2;
|
||||
#if (OS_CFG_DBG_EN > 0u)
|
||||
p_list->NbrEntries--;
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_DYN_TICK_EN > 0u)
|
||||
if (p_tcb2->TickRemain != p_tcb->TickRemain) { /* Only set a new tick if tcb2 had a longer delay. */
|
||||
if (elapsed != 0u) {
|
||||
OSTickCtr += elapsed; /* Keep track of time. */
|
||||
OS_TRACE_TICK_INCREMENT(OSTickCtr);
|
||||
p_tcb2->TickRemain -= elapsed; /* We must account for any time which has passed. */
|
||||
}
|
||||
OSTickCtrStep = p_tcb2->TickRemain;
|
||||
OS_DynTickSet(OSTickCtrStep);
|
||||
}
|
||||
#endif
|
||||
p_tcb->TickNextPtr = (OS_TCB *)0;
|
||||
p_tcb->TickRemain = 0u;
|
||||
}
|
||||
} else {
|
||||
p_tcb1->TickNextPtr = p_tcb2;
|
||||
if (p_tcb2 != (OS_TCB *)0) {
|
||||
p_tcb2->TickPrevPtr = p_tcb1;
|
||||
p_tcb2->TickRemain += p_tcb->TickRemain; /* Add back the ticks to the delta list */
|
||||
}
|
||||
p_tcb->TickPrevPtr = (OS_TCB *)0;
|
||||
#if (OS_CFG_DBG_EN > 0u)
|
||||
p_list->NbrEntries--;
|
||||
#endif
|
||||
p_tcb->TickNextPtr = (OS_TCB *)0;
|
||||
p_tcb->TickRemain = 0u;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* UPDATE THE LIST OF TASKS DELAYED OR PENDING WITH TIMEOUT
|
||||
*
|
||||
* Description: This function updates the delta list which contains tasks that are delayed or pending with a timeout.
|
||||
*
|
||||
* Arguments : ticks the number of ticks which have elapsed.
|
||||
*
|
||||
* Returns : none
|
||||
*
|
||||
* Note(s) : 1) This function is INTERNAL to uC/OS-III and your application MUST NOT call it.
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
|
||||
static void OS_TickListUpdate (OS_TICK ticks)
|
||||
{
|
||||
OS_TCB *p_tcb;
|
||||
OS_TICK_LIST *p_list;
|
||||
#if (OS_CFG_DBG_EN > 0u)
|
||||
OS_OBJ_QTY nbr_updated;
|
||||
#endif
|
||||
#if (OS_CFG_MUTEX_EN > 0u)
|
||||
OS_TCB *p_tcb_owner;
|
||||
OS_PRIO prio_new;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if (OS_CFG_DBG_EN > 0u)
|
||||
nbr_updated = 0u;
|
||||
#endif
|
||||
p_list = &OSTickList;
|
||||
p_tcb = p_list->TCB_Ptr;
|
||||
if (p_tcb != (OS_TCB *)0) {
|
||||
if (p_tcb->TickRemain <= ticks) {
|
||||
ticks = ticks - p_tcb->TickRemain;
|
||||
p_tcb->TickRemain = 0u;
|
||||
} else {
|
||||
p_tcb->TickRemain -= ticks;
|
||||
}
|
||||
|
||||
while (p_tcb->TickRemain == 0u) {
|
||||
#if (OS_CFG_DBG_EN > 0u)
|
||||
nbr_updated++;
|
||||
#endif
|
||||
|
||||
switch (p_tcb->TaskState) {
|
||||
case OS_TASK_STATE_DLY:
|
||||
p_tcb->TaskState = OS_TASK_STATE_RDY;
|
||||
OS_RdyListInsert(p_tcb); /* Insert the task in the ready list */
|
||||
break;
|
||||
|
||||
case OS_TASK_STATE_DLY_SUSPENDED:
|
||||
p_tcb->TaskState = OS_TASK_STATE_SUSPENDED;
|
||||
break;
|
||||
|
||||
default:
|
||||
#if (OS_CFG_MUTEX_EN > 0u)
|
||||
p_tcb_owner = (OS_TCB *)0;
|
||||
if (p_tcb->PendOn == OS_TASK_PEND_ON_MUTEX) {
|
||||
p_tcb_owner = (OS_TCB *)((OS_MUTEX *)((void *)p_tcb->PendObjPtr))->OwnerTCBPtr;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (OS_MSG_EN > 0u)
|
||||
p_tcb->MsgPtr = (void *)0;
|
||||
p_tcb->MsgSize = 0u;
|
||||
#endif
|
||||
#if (OS_CFG_TS_EN > 0u)
|
||||
p_tcb->TS = OS_TS_GET();
|
||||
#endif
|
||||
OS_PendListRemove(p_tcb); /* Remove task from pend list */
|
||||
|
||||
switch (p_tcb->TaskState) {
|
||||
case OS_TASK_STATE_PEND_TIMEOUT:
|
||||
OS_RdyListInsert(p_tcb); /* Insert the task in the ready list */
|
||||
p_tcb->TaskState = OS_TASK_STATE_RDY;
|
||||
break;
|
||||
|
||||
case OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED:
|
||||
p_tcb->TaskState = OS_TASK_STATE_SUSPENDED;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
p_tcb->PendStatus = OS_STATUS_PEND_TIMEOUT; /* Indicate pend timed out */
|
||||
p_tcb->PendOn = OS_TASK_PEND_ON_NOTHING; /* Indicate no longer pending */
|
||||
|
||||
#if (OS_CFG_MUTEX_EN > 0u)
|
||||
if (p_tcb_owner != (OS_TCB *)0) {
|
||||
if ((p_tcb_owner->Prio != p_tcb_owner->BasePrio) &&
|
||||
(p_tcb_owner->Prio == p_tcb->Prio)) { /* Has the owner inherited a priority? */
|
||||
prio_new = OS_MutexGrpPrioFindHighest(p_tcb_owner);
|
||||
prio_new = (prio_new > p_tcb_owner->BasePrio) ? p_tcb_owner->BasePrio : prio_new;
|
||||
if (prio_new != p_tcb_owner->Prio) {
|
||||
OS_TaskChangePrio(p_tcb_owner, prio_new);
|
||||
OS_TRACE_MUTEX_TASK_PRIO_DISINHERIT(p_tcb_owner, p_tcb_owner->Prio);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
p_list->TCB_Ptr = p_tcb->TickNextPtr;
|
||||
p_tcb = p_list->TCB_Ptr; /* Get 'p_tcb' again for loop */
|
||||
if (p_tcb == (OS_TCB *)0) {
|
||||
#if (OS_CFG_DBG_EN > 0u)
|
||||
p_list->NbrEntries = 0u;
|
||||
#endif
|
||||
break;
|
||||
} else {
|
||||
#if (OS_CFG_DBG_EN > 0u)
|
||||
p_list->NbrEntries--;
|
||||
#endif
|
||||
p_tcb->TickPrevPtr = (OS_TCB *)0;
|
||||
if (p_tcb->TickRemain <= ticks) {
|
||||
ticks = ticks - p_tcb->TickRemain;
|
||||
p_tcb->TickRemain = 0u;
|
||||
} else {
|
||||
p_tcb->TickRemain -= ticks;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#if (OS_CFG_DBG_EN > 0u)
|
||||
p_list->NbrUpdated = nbr_updated;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* #if OS_CFG_TICK_EN */
|
||||
|
||||
|
|
@ -0,0 +1,600 @@
|
|||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/OS-III
|
||||
* The Real-Time Kernel
|
||||
*
|
||||
* Copyright 2009-2020 Silicon Laboratories Inc. www.silabs.com
|
||||
*
|
||||
* SPDX-License-Identifier: APACHE-2.0
|
||||
*
|
||||
* This software is subject to an open source license and is distributed by
|
||||
* Silicon Laboratories Inc. pursuant to the terms of the Apache License,
|
||||
* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* TIME MANAGEMENT
|
||||
*
|
||||
* File : os_time.c
|
||||
* Version : V3.08.00
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#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_OS_NOT_RUNNING If uC/OS-III is not running yet
|
||||
* 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 the effective delay is zero
|
||||
* OS_ERR_TICK_DISABLED If kernel ticks are disabled
|
||||
*
|
||||
* Returns : none
|
||||
*
|
||||
* Note(s) : none
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
|
||||
void OSTimeDly (OS_TICK dly,
|
||||
OS_OPT opt,
|
||||
OS_ERR *p_err)
|
||||
{
|
||||
#if (OS_CFG_TICK_EN > 0u)
|
||||
CPU_SR_ALLOC();
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef OS_SAFETY_CRITICAL
|
||||
if (p_err == (OS_ERR *)0) {
|
||||
OS_SAFETY_CRITICAL_EXCEPTION();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_TICK_EN == 0u)
|
||||
*p_err = OS_ERR_TICK_DISABLED;
|
||||
return;
|
||||
#else
|
||||
|
||||
#if (OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u)
|
||||
if (OSIntNestingCtr > 0u) { /* Not allowed to call from an ISR */
|
||||
*p_err = OS_ERR_TIME_DLY_ISR;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_INVALID_OS_CALLS_CHK_EN > 0u)
|
||||
if (OSRunning != OS_STATE_OS_RUNNING) { /* Is the kernel running? */
|
||||
*p_err = OS_ERR_OS_NOT_RUNNING;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (OSSchedLockNestingCtr > 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:
|
||||
case OS_OPT_TIME_MATCH:
|
||||
break;
|
||||
|
||||
default:
|
||||
*p_err = OS_ERR_OPT_INVALID;
|
||||
return;
|
||||
}
|
||||
|
||||
#if (OS_CFG_TICK_EN > 0u)
|
||||
CPU_CRITICAL_ENTER();
|
||||
OS_TickListInsertDly(OSTCBCurPtr,
|
||||
dly,
|
||||
opt,
|
||||
p_err);
|
||||
if (*p_err != OS_ERR_NONE) {
|
||||
CPU_CRITICAL_EXIT();
|
||||
return;
|
||||
}
|
||||
|
||||
OS_RdyListRemove(OSTCBCurPtr); /* Remove current task from ready list */
|
||||
CPU_CRITICAL_EXIT();
|
||||
OSSched(); /* Find next task to run! */
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* 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_OS_NOT_RUNNING If uC/OS-III is not running yet
|
||||
* 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 the effective delay is zero
|
||||
* OS_ERR_TICK_DISABLED If kernel ticks are disabled
|
||||
*
|
||||
* 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_TICK_EN > 0u)
|
||||
#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();
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef OS_SAFETY_CRITICAL
|
||||
if (p_err == (OS_ERR *)0) {
|
||||
OS_SAFETY_CRITICAL_EXCEPTION();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_TICK_EN == 0u)
|
||||
*p_err = OS_ERR_TICK_DISABLED;
|
||||
return;
|
||||
#else
|
||||
#if (OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u)
|
||||
if (OSIntNestingCtr > 0u) { /* Not allowed to call from an ISR */
|
||||
*p_err = OS_ERR_TIME_DLY_ISR;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_INVALID_OS_CALLS_CHK_EN > 0u)
|
||||
if (OSRunning != OS_STATE_OS_RUNNING) { /* Is the kernel running? */
|
||||
*p_err = OS_ERR_OS_NOT_RUNNING;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (OSSchedLockNestingCtr > 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:
|
||||
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 = ((((opt) & (~OS_OPT_TIME_OPTS_MASK)) == 0u) ? (OS_FALSE) : (OS_TRUE));
|
||||
if (opt_invalid == OS_TRUE) {
|
||||
*p_err = OS_ERR_OPT_INVALID;
|
||||
return;
|
||||
}
|
||||
|
||||
opt_non_strict = ((((opt) & (OS_OPT_TIME_HMSM_NON_STRICT)) == 0u) ? (OS_FALSE) : (OS_TRUE));
|
||||
|
||||
if (opt_non_strict != OS_TRUE) {
|
||||
if (milli > 999u) {
|
||||
*p_err = OS_ERR_TIME_INVALID_MILLISECONDS;
|
||||
return;
|
||||
}
|
||||
if (seconds > 59u) {
|
||||
*p_err = OS_ERR_TIME_INVALID_SECONDS;
|
||||
return;
|
||||
}
|
||||
if (minutes > 59u) {
|
||||
*p_err = OS_ERR_TIME_INVALID_MINUTES;
|
||||
return;
|
||||
}
|
||||
if (hours > 99u) {
|
||||
*p_err = OS_ERR_TIME_INVALID_HOURS;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (minutes > 9999u) {
|
||||
*p_err = OS_ERR_TIME_INVALID_MINUTES;
|
||||
return;
|
||||
}
|
||||
if (hours > 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);
|
||||
|
||||
|
||||
CPU_CRITICAL_ENTER();
|
||||
OS_TickListInsertDly(OSTCBCurPtr,
|
||||
ticks,
|
||||
opt_time,
|
||||
p_err);
|
||||
if (*p_err != OS_ERR_NONE) {
|
||||
CPU_CRITICAL_EXIT();
|
||||
return;
|
||||
}
|
||||
|
||||
OS_RdyListRemove(OSTCBCurPtr); /* Remove current task from ready list */
|
||||
CPU_CRITICAL_EXIT();
|
||||
OSSched(); /* Find next task to run! */
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* 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 you 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_OS_NOT_RUNNING If uC/OS-III is not running yet
|
||||
* OS_ERR_STATE_INVALID Task is in an invalid state
|
||||
* OS_ERR_TASK_NOT_DLY Task is not waiting for time to expire
|
||||
* OS_ERR_TASK_SUSPENDED Task cannot be resumed, it was suspended by OSTaskSuspend()
|
||||
* OS_ERR_TCB_INVALID If 'p_tcb' is a NULL pointer
|
||||
* OS_ERR_TIME_DLY_RESUME_ISR If called from an ISR
|
||||
*
|
||||
* Returns : none
|
||||
*
|
||||
* 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 > 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) /* ---------------- VALIDATE ARGUMENTS ---------------- */
|
||||
if (p_tcb == (OS_TCB *)0) { /* User must supply a valid OS_TCB */
|
||||
*p_err = OS_ERR_TCB_INVALID;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_INVALID_OS_CALLS_CHK_EN > 0u)
|
||||
if (OSRunning != OS_STATE_OS_RUNNING) { /* Is the kernel running? */
|
||||
*p_err = OS_ERR_OS_NOT_RUNNING;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
CPU_CRITICAL_ENTER();
|
||||
switch (p_tcb->TaskState) {
|
||||
case OS_TASK_STATE_RDY: /* Cannot Abort delay if task is ready */
|
||||
case OS_TASK_STATE_PEND:
|
||||
case OS_TASK_STATE_PEND_TIMEOUT:
|
||||
case OS_TASK_STATE_SUSPENDED:
|
||||
case OS_TASK_STATE_PEND_SUSPENDED:
|
||||
case OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED:
|
||||
CPU_CRITICAL_EXIT();
|
||||
*p_err = OS_ERR_TASK_NOT_DLY;
|
||||
break;
|
||||
|
||||
case OS_TASK_STATE_DLY:
|
||||
p_tcb->TaskState = OS_TASK_STATE_RDY;
|
||||
#if (OS_CFG_TICK_EN > 0u)
|
||||
OS_TickListRemove(p_tcb); /* Remove task from tick list */
|
||||
OS_RdyListInsert(p_tcb); /* Add to ready list */
|
||||
#endif
|
||||
CPU_CRITICAL_EXIT();
|
||||
*p_err = OS_ERR_NONE;
|
||||
break;
|
||||
|
||||
case OS_TASK_STATE_DLY_SUSPENDED:
|
||||
p_tcb->TaskState = OS_TASK_STATE_SUSPENDED;
|
||||
#if (OS_CFG_TICK_EN > 0u)
|
||||
OS_TickListRemove(p_tcb); /* Remove task from tick list */
|
||||
#endif
|
||||
CPU_CRITICAL_EXIT();
|
||||
*p_err = OS_ERR_TASK_SUSPENDED;
|
||||
break;
|
||||
|
||||
default:
|
||||
CPU_CRITICAL_EXIT();
|
||||
*p_err = OS_ERR_STATE_INVALID;
|
||||
break;
|
||||
}
|
||||
|
||||
OSSched();
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* 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
|
||||
* OS_ERR_TICK_DISABLED If kernel ticks are disabled
|
||||
*
|
||||
* Returns : The current value of OSTickCtr
|
||||
*
|
||||
* Note(s) : none
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
|
||||
OS_TICK OSTimeGet (OS_ERR *p_err)
|
||||
{
|
||||
OS_TICK ticks;
|
||||
#if (OS_CFG_TICK_EN > 0u)
|
||||
CPU_SR_ALLOC();
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef OS_SAFETY_CRITICAL
|
||||
if (p_err == (OS_ERR *)0) {
|
||||
OS_SAFETY_CRITICAL_EXCEPTION();
|
||||
return (0u);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if (OS_CFG_TICK_EN > 0u)
|
||||
CPU_CRITICAL_ENTER();
|
||||
#if (OS_CFG_DYN_TICK_EN > 0u)
|
||||
if (OSRunning == OS_STATE_OS_RUNNING) {
|
||||
ticks = OSTickCtr + OS_DynTickGet();
|
||||
} else {
|
||||
ticks = OSTickCtr;
|
||||
}
|
||||
#else
|
||||
ticks = OSTickCtr;
|
||||
#endif
|
||||
CPU_CRITICAL_EXIT();
|
||||
*p_err = OS_ERR_NONE;
|
||||
#else
|
||||
ticks = 0u;
|
||||
*p_err = OS_ERR_TICK_DISABLED;
|
||||
#endif
|
||||
|
||||
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
|
||||
* OS_ERR_TICK_DISABLED If kernel ticks are disabled
|
||||
*
|
||||
* Returns : none
|
||||
*
|
||||
* Note(s) : none
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
|
||||
void OSTimeSet (OS_TICK ticks,
|
||||
OS_ERR *p_err)
|
||||
{
|
||||
#if (OS_CFG_TICK_EN > 0u)
|
||||
CPU_SR_ALLOC();
|
||||
|
||||
#else
|
||||
(void)ticks;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef OS_SAFETY_CRITICAL
|
||||
if (p_err == (OS_ERR *)0) {
|
||||
OS_SAFETY_CRITICAL_EXCEPTION();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_TICK_EN > 0u)
|
||||
CPU_CRITICAL_ENTER();
|
||||
OSTickCtr = ticks;
|
||||
OS_TRACE_TICK_INCREMENT(OSTickCtr);
|
||||
CPU_CRITICAL_EXIT();
|
||||
*p_err = OS_ERR_NONE;
|
||||
#else
|
||||
*p_err = OS_ERR_TICK_DISABLED;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* 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
|
||||
*
|
||||
* Note(s) : none
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
|
||||
void OSTimeTick (void)
|
||||
{
|
||||
if (OSRunning != OS_STATE_OS_RUNNING) {
|
||||
return;
|
||||
}
|
||||
|
||||
OSTimeTickHook(); /* Call user definable hook */
|
||||
|
||||
#if (OS_CFG_SCHED_ROUND_ROBIN_EN > 0u)
|
||||
OS_SchedRoundRobin(&OSRdyList[OSPrioCur]); /* Update quanta ctr for the task which just ran */
|
||||
#endif
|
||||
|
||||
#if (OS_CFG_TICK_EN > 0u)
|
||||
OS_TickUpdate(1u); /* Update from the ISR */
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
************************************************************************************************************************
|
||||
* PROCESS SYSTEM TICK (DYNAMIC)
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* Note(s) : none
|
||||
************************************************************************************************************************
|
||||
*/
|
||||
|
||||
#if (OS_CFG_DYN_TICK_EN > 0u)
|
||||
void OSTimeDynTick (OS_TICK ticks)
|
||||
{
|
||||
if (OSRunning != OS_STATE_OS_RUNNING) {
|
||||
return;
|
||||
}
|
||||
|
||||
OSTimeTickHook();
|
||||
|
||||
OS_TickUpdate(ticks); /* Update from the ISR */
|
||||
}
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,476 @@
|
|||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/OS-III
|
||||
* The Real-Time Kernel
|
||||
*
|
||||
* Copyright 2009-2020 Silicon Laboratories Inc. www.silabs.com
|
||||
*
|
||||
* SPDX-License-Identifier: APACHE-2.0
|
||||
*
|
||||
* This software is subject to an open source license and is distributed by
|
||||
* Silicon Laboratories Inc. pursuant to the terms of the Apache License,
|
||||
* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* File : os_trace.h
|
||||
* Version : V3.08.00
|
||||
*********************************************************************************************************
|
||||
* Note(s) : (1) The header file os_trace_events.h is the interface between uC/OS-III and your
|
||||
* trace recorder of choice. To support trace recording, include one of the sub-folders
|
||||
* at uCOS-III/Trace/ into your project.
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef OS_TRACE_H
|
||||
#define OS_TRACE_H
|
||||
|
||||
|
||||
#include <os_cfg.h>
|
||||
|
||||
#if (defined(OS_CFG_TRACE_EN) && (OS_CFG_TRACE_EN > 0u))
|
||||
#include <os_trace_events.h> /* See Note #1. */
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
**************************************************************************************************************************
|
||||
* uC/OS-III Trace Default Macros (Empty)
|
||||
**************************************************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef OS_TRACE_INIT
|
||||
#define OS_TRACE_INIT()
|
||||
#endif
|
||||
#ifndef OS_TRACE_START
|
||||
#define OS_TRACE_START()
|
||||
#endif
|
||||
#ifndef OS_TRACE_STOP
|
||||
#define OS_TRACE_STOP()
|
||||
#endif
|
||||
#ifndef OS_TRACE_CLEAR
|
||||
#define OS_TRACE_CLEAR()
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_ISR_ENTER
|
||||
#define OS_TRACE_ISR_ENTER()
|
||||
#endif
|
||||
#ifndef OS_TRACE_ISR_EXIT
|
||||
#define OS_TRACE_ISR_EXIT()
|
||||
#endif
|
||||
#ifndef OS_TRACE_ISR_EXIT_TO_SCHEDULER
|
||||
#define OS_TRACE_ISR_EXIT_TO_SCHEDULER()
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_TICK_INCREMENT
|
||||
#define OS_TRACE_TICK_INCREMENT(OSTickCtr)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_TASK_CREATE
|
||||
#define OS_TRACE_TASK_CREATE(p_tcb)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_TASK_CREATE_FAILED
|
||||
#define OS_TRACE_TASK_CREATE_FAILED(p_tcb)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_TASK_DEL
|
||||
#define OS_TRACE_TASK_DEL(p_tcb)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_TASK_READY
|
||||
#define OS_TRACE_TASK_READY(p_tcb)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_TASK_SWITCHED_IN
|
||||
#define OS_TRACE_TASK_SWITCHED_IN(p_tcb)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_TASK_DLY
|
||||
#define OS_TRACE_TASK_DLY(dly_ticks)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_TASK_SUSPEND
|
||||
#define OS_TRACE_TASK_SUSPEND(p_tcb)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_TASK_SUSPENDED
|
||||
#define OS_TRACE_TASK_SUSPENDED(p_tcb)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_TASK_RESUME
|
||||
#define OS_TRACE_TASK_RESUME(p_tcb)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_TASK_PREEMPT
|
||||
#define OS_TRACE_TASK_PREEMPT(p_tcb)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_TASK_PRIO_CHANGE
|
||||
#define OS_TRACE_TASK_PRIO_CHANGE(p_tcb, prio)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_ISR_REGISTER
|
||||
#define OS_TRACE_ISR_REGISTER(isr_id, isr_name, isr_prio)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_ISR_BEGIN
|
||||
#define OS_TRACE_ISR_BEGIN(isr_id)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_ISR_END
|
||||
#define OS_TRACE_ISR_END()
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_TASK_MSG_Q_CREATE
|
||||
#define OS_TRACE_TASK_MSG_Q_CREATE(p_msg_q, p_name)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_TASK_MSG_Q_POST
|
||||
#define OS_TRACE_TASK_MSG_Q_POST(p_msg_q)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_TASK_MSG_Q_POST_FAILED
|
||||
#define OS_TRACE_TASK_MSG_Q_POST_FAILED(p_msg_q)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_TASK_MSG_Q_PEND
|
||||
#define OS_TRACE_TASK_MSG_Q_PEND(p_msg_q)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_TASK_MSG_Q_PEND_FAILED
|
||||
#define OS_TRACE_TASK_MSG_Q_PEND_FAILED(p_msg_q)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_TASK_MSG_Q_PEND_BLOCK
|
||||
#define OS_TRACE_TASK_MSG_Q_PEND_BLOCK(p_msg_q)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_TASK_SEM_CREATE
|
||||
#define OS_TRACE_TASK_SEM_CREATE(p_tcb, p_name)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_TASK_SEM_POST
|
||||
#define OS_TRACE_TASK_SEM_POST(p_tcb)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_TASK_SEM_POST_FAILED
|
||||
#define OS_TRACE_TASK_SEM_POST_FAILED(p_tcb)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_TASK_SEM_PEND
|
||||
#define OS_TRACE_TASK_SEM_PEND(p_tcb)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_TASK_SEM_PEND_FAILED
|
||||
#define OS_TRACE_TASK_SEM_PEND_FAILED(p_tcb)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_TASK_SEM_PEND_BLOCK
|
||||
#define OS_TRACE_TASK_SEM_PEND_BLOCK(p_tcb)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_MUTEX_CREATE
|
||||
#define OS_TRACE_MUTEX_CREATE(p_mutex, p_name)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_MUTEX_DEL
|
||||
#define OS_TRACE_MUTEX_DEL(p_mutex)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_MUTEX_POST
|
||||
#define OS_TRACE_MUTEX_POST(p_mutex)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_MUTEX_POST_FAILED
|
||||
#define OS_TRACE_MUTEX_POST_FAILED(p_mutex)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_MUTEX_PEND
|
||||
#define OS_TRACE_MUTEX_PEND(p_mutex)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_MUTEX_PEND_FAILED
|
||||
#define OS_TRACE_MUTEX_PEND_FAILED(p_mutex)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_MUTEX_PEND_BLOCK
|
||||
#define OS_TRACE_MUTEX_PEND_BLOCK(p_mutex)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_MUTEX_TASK_PRIO_INHERIT
|
||||
#define OS_TRACE_MUTEX_TASK_PRIO_INHERIT(p_tcb, prio)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_MUTEX_TASK_PRIO_DISINHERIT
|
||||
#define OS_TRACE_MUTEX_TASK_PRIO_DISINHERIT(p_tcb, prio)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_SEM_CREATE
|
||||
#define OS_TRACE_SEM_CREATE(p_sem, p_name)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_SEM_DEL
|
||||
#define OS_TRACE_SEM_DEL(p_sem)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_SEM_POST
|
||||
#define OS_TRACE_SEM_POST(p_sem)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_SEM_POST_FAILED
|
||||
#define OS_TRACE_SEM_POST_FAILED(p_sem)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_SEM_PEND
|
||||
#define OS_TRACE_SEM_PEND(p_sem)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_SEM_PEND_FAILED
|
||||
#define OS_TRACE_SEM_PEND_FAILED(p_sem)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_SEM_PEND_BLOCK
|
||||
#define OS_TRACE_SEM_PEND_BLOCK(p_sem)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_Q_CREATE
|
||||
#define OS_TRACE_Q_CREATE(p_q, p_name)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_Q_DEL
|
||||
#define OS_TRACE_Q_DEL(p_q)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_Q_POST
|
||||
#define OS_TRACE_Q_POST(p_q)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_Q_POST_FAILED
|
||||
#define OS_TRACE_Q_POST_FAILED(p_q)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_Q_PEND
|
||||
#define OS_TRACE_Q_PEND(p_q)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_Q_PEND_FAILED
|
||||
#define OS_TRACE_Q_PEND_FAILED(p_q)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_Q_PEND_BLOCK
|
||||
#define OS_TRACE_Q_PEND_BLOCK(p_q)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_FLAG_CREATE
|
||||
#define OS_TRACE_FLAG_CREATE(p_grp, p_name)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_FLAG_DEL
|
||||
#define OS_TRACE_FLAG_DEL(p_grp)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_FLAG_POST
|
||||
#define OS_TRACE_FLAG_POST(p_grp)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_FLAG_POST_FAILED
|
||||
#define OS_TRACE_FLAG_POST_FAILED(p_grp)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_FLAG_PEND
|
||||
#define OS_TRACE_FLAG_PEND(p_grp)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_FLAG_PEND_FAILED
|
||||
#define OS_TRACE_FLAG_PEND_FAILED(p_grp)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_FLAG_PEND_BLOCK
|
||||
#define OS_TRACE_FLAG_PEND_BLOCK(p_grp)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_MEM_CREATE
|
||||
#define OS_TRACE_MEM_CREATE(p_mem, p_name)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_MEM_PUT
|
||||
#define OS_TRACE_MEM_PUT(p_mem)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_MEM_PUT_FAILED
|
||||
#define OS_TRACE_MEM_PUT_FAILED(p_mem)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_MEM_GET
|
||||
#define OS_TRACE_MEM_GET(p_mem)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_MEM_GET_FAILED
|
||||
#define OS_TRACE_MEM_GET_FAILED(p_mem)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_MUTEX_DEL_ENTER
|
||||
#define OS_TRACE_MUTEX_DEL_ENTER(p_mutex, opt)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_MUTEX_POST_ENTER
|
||||
#define OS_TRACE_MUTEX_POST_ENTER(p_mutex, opt)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_MUTEX_PEND_ENTER
|
||||
#define OS_TRACE_MUTEX_PEND_ENTER(p_mutex, timeout, opt, p_ts)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_TASK_MSG_Q_POST_ENTER
|
||||
#define OS_TRACE_TASK_MSG_Q_POST_ENTER(p_msg_q, p_void, msg_size, opt)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_TASK_MSG_Q_PEND_ENTER
|
||||
#define OS_TRACE_TASK_MSG_Q_PEND_ENTER(p_msg_q, timeout, opt, p_msg_size, p_ts)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_TASK_SEM_POST_ENTER
|
||||
#define OS_TRACE_TASK_SEM_POST_ENTER(p_tcb, opt)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_TASK_SEM_PEND_ENTER
|
||||
#define OS_TRACE_TASK_SEM_PEND_ENTER(p_tcb, timeout, opt, p_ts)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_TASK_RESUME_ENTER
|
||||
#define OS_TRACE_TASK_RESUME_ENTER(p_tcb)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_TASK_SUSPEND_ENTER
|
||||
#define OS_TRACE_TASK_SUSPEND_ENTER(p_tcb)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_SEM_DEL_ENTER
|
||||
#define OS_TRACE_SEM_DEL_ENTER(p_sem, opt)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_SEM_POST_ENTER
|
||||
#define OS_TRACE_SEM_POST_ENTER(p_sem, opt)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_SEM_PEND_ENTER
|
||||
#define OS_TRACE_SEM_PEND_ENTER(p_sem, timeout, opt, p_ts)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_Q_DEL_ENTER
|
||||
#define OS_TRACE_Q_DEL_ENTER(p_q, opt)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_Q_POST_ENTER
|
||||
#define OS_TRACE_Q_POST_ENTER(p_q, p_void, msg_size, opt)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_Q_PEND_ENTER
|
||||
#define OS_TRACE_Q_PEND_ENTER(p_q, timeout, opt, p_msg_size, p_ts)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_FLAG_DEL_ENTER
|
||||
#define OS_TRACE_FLAG_DEL_ENTER(p_grp, opt)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_FLAG_POST_ENTER
|
||||
#define OS_TRACE_FLAG_POST_ENTER(p_grp, flags, opt)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_FLAG_PEND_ENTER
|
||||
#define OS_TRACE_FLAG_PEND_ENTER(p_grp, flags, timeout, opt, p_ts)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_MEM_PUT_ENTER
|
||||
#define OS_TRACE_MEM_PUT_ENTER(p_mem, p_blk)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_MEM_GET_ENTER
|
||||
#define OS_TRACE_MEM_GET_ENTER(p_mem)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_MUTEX_DEL_EXIT
|
||||
#define OS_TRACE_MUTEX_DEL_EXIT(RetVal)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_MUTEX_POST_EXIT
|
||||
#define OS_TRACE_MUTEX_POST_EXIT(RetVal)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_MUTEX_PEND_EXIT
|
||||
#define OS_TRACE_MUTEX_PEND_EXIT(RetVal)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_TASK_MSG_Q_POST_EXIT
|
||||
#define OS_TRACE_TASK_MSG_Q_POST_EXIT(RetVal)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_TASK_MSG_Q_PEND_EXIT
|
||||
#define OS_TRACE_TASK_MSG_Q_PEND_EXIT(RetVal)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_TASK_SEM_POST_EXIT
|
||||
#define OS_TRACE_TASK_SEM_POST_EXIT(RetVal)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_TASK_SEM_PEND_EXIT
|
||||
#define OS_TRACE_TASK_SEM_PEND_EXIT(RetVal)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_TASK_RESUME_EXIT
|
||||
#define OS_TRACE_TASK_RESUME_EXIT(RetVal)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_TASK_SUSPEND_EXIT
|
||||
#define OS_TRACE_TASK_SUSPEND_EXIT(RetVal)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_SEM_DEL_EXIT
|
||||
#define OS_TRACE_SEM_DEL_EXIT(RetVal)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_SEM_POST_EXIT
|
||||
#define OS_TRACE_SEM_POST_EXIT(RetVal)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_SEM_PEND_EXIT
|
||||
#define OS_TRACE_SEM_PEND_EXIT(RetVal)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_Q_DEL_EXIT
|
||||
#define OS_TRACE_Q_DEL_EXIT(RetVal)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_Q_POST_EXIT
|
||||
#define OS_TRACE_Q_POST_EXIT(RetVal)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_Q_PEND_EXIT
|
||||
#define OS_TRACE_Q_PEND_EXIT(RetVal)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_FLAG_DEL_EXIT
|
||||
#define OS_TRACE_FLAG_DEL_EXIT(RetVal)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_FLAG_POST_EXIT
|
||||
#define OS_TRACE_FLAG_POST_EXIT(RetVal)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_FLAG_PEND_EXIT
|
||||
#define OS_TRACE_FLAG_PEND_EXIT(RetVal)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_MEM_PUT_EXIT
|
||||
#define OS_TRACE_MEM_PUT_EXIT(RetVal)
|
||||
#endif
|
||||
|
||||
#ifndef OS_TRACE_MEM_GET_EXIT
|
||||
#define OS_TRACE_MEM_GET_EXIT(RetVal)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/OS-III
|
||||
* The Real-Time Kernel
|
||||
*
|
||||
* Copyright 2009-2020 Silicon Laboratories Inc. www.silabs.com
|
||||
*
|
||||
* SPDX-License-Identifier: APACHE-2.0
|
||||
*
|
||||
* This software is subject to an open source license and is distributed by
|
||||
* Silicon Laboratories Inc. pursuant to the terms of the Apache License,
|
||||
* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* File : os_type.h
|
||||
* Version : V3.08.00
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#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 */
|
||||
|
||||
#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_64) /* Task register 8/16/<32/64> */
|
||||
typedef CPU_INT64U OS_REG;
|
||||
#else
|
||||
typedef CPU_INT32U OS_REG;
|
||||
#endif
|
||||
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 */
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
*********************************************************************************************************
|
||||
* uC/OS-III
|
||||
* The Real-Time Kernel
|
||||
*
|
||||
* Copyright 2009-2020 Silicon Laboratories Inc. www.silabs.com
|
||||
*
|
||||
* SPDX-License-Identifier: APACHE-2.0
|
||||
*
|
||||
* This software is subject to an open source license and is distributed by
|
||||
* Silicon Laboratories Inc. pursuant to the terms of the Apache License,
|
||||
* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*********************************************************************************************************
|
||||
* VARIABLES
|
||||
*
|
||||
* File : os_var.c
|
||||
* Version : V3.08.00
|
||||
*********************************************************************************************************
|
||||
*/
|
||||
|
||||
#define OS_GLOBALS
|
||||
|
||||
#define MICRIUM_SOURCE
|
||||
#include "os.h"
|
||||
|
||||
#ifdef VSC_INCLUDE_SOURCE_FILE_NAMES
|
||||
const CPU_CHAR *os_var__c = "$Id: $";
|
||||
#endif
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
# uC/OS-III
|
||||
|
||||
µC/OS-III is a highly portable, ROMable, scalable, preemptive, real-time, deterministic, multitasking kernel for microprocessors, microcontrollers and DSPs.
|
||||
|
||||
Offering unprecedented ease-of-use, μC/OS-III is delivered with complete 100% ANSI C source code and in-depth documentation. μC/OS-III runs on the largest number of processor architectures, with ports available for download from the Micrium Web site.
|
||||
|
||||
## For the complete documentation, visit https://doc.micrium.com/display/ucos/
|
||||
Loading…
Reference in New Issue