uC-CPU

About µC/CPU

µC/CPU is a module that provides CPU-specific functionality that is independent of µC/OS-III. Specifically, µC/CPU defines compiler and CPU dependent data types, the word width of the stack, whether the stack grows from high-to-low memory or from low-to-high memory, functions for disabling and enabling interrupts and more. Additional information about this module is provided in the µC/CPU User Manual.

The table below shows the name of µC/CPU files and where they should be placed on the computer used to develop a µC/OS-III-based application. The file names in bold are files you will need to create or modify for your own port.

FileDirectory
cpu_bsp.c\Micrium\Software\uC-CPU\BSP\Template\cpu_bsp.c
cpu_def.h\Micrium\Software\uC-CPU\
cpu_cfg.h\Micrium\Software\uC-CPU\CFG\Template
cpu_core.c\Micrium\Software\uC-CPU\
cpu_core.h\Micrium\Software\uC-CPU\
cpu.h\Micrium\Software\uC-CPU\<processor>\<compiler>
cpu_c.c\Micrium\Software\uC-CPU\<processor>\<compiler>
cpu_a.asm\Micrium\Software\uC-CPU\<processor>\<compiler>


<processor> is the name of the processor that the cpu*.* files apply to.

<compiler> is the name of the toolchain (compiler, assembler, linker/locator) used. Each has its own directory because they may have different features that makes them different from one another.

cpu_bsp.c

This file contains skeleton functions for CPU_TS_TmrInit()CPU_TS_TmrRd() and other time stamp related functions. You can copy this file to your Board Support Package (BSP) directory, modify its content and add it to your build.

cpu_def.h

This file should not require any changes. cpu_def.h declares #define constants that are used by Micriµm software components.

cpu_cfg.h

This is a configuration file to be copied into the product directory and changed based on the options to exercise in µC/CPU. cpu_cfg.h is not considered a ‘port file’ but more an application specific file. However, it’s discussed here for completeness. The file contains #define constants that may need to be changed based on the desired use of µC/CPU.

CPU_CFG_NAME_EN

This #define determines whether you will be assigning a ‘name’ to the CPU port. This name can then be read by application code.

CPU_CFG_NAME_SIZE

This #define specifies the length of the ASCII string used to assign a name to the CPU.

CPU_CFG_TS_32_EN

This #define specifies whether 32-bit time stamps are available for this CPU. A 32-bit timestamp is typically the value of a free-running 32-bit counter that is used to make accurate time measurements. The application code can obtain the current value of this free-running timer at any point in time and use such value to determine when an event occurred or, measure the time difference between two events. The free-running counter is generally incremented at a fairly high rate, for example 1 MHz or more.

CPU_CFG_TS_64_EN

This #define specifies whether 64-bit time stamps are available for this CPU. A 64-bit timestamp is typically the value of a free-running 64-bit counter (possibly made up by counting overflows of a 32-bit counter) that is used to make accurate time measurements. The application code can obtain the current value of this free-running timer at any point in time and use such value to determine when an event occurred or, measure the time difference between two events. The free-running counter is generally incremented at a fairly high rate, for example 100 MHz or more.

CPU_CFG_TS_TMR_SIZE

This #define specifies the size, in number of bytes, of a timestamp. A 32-bit timestamp is 4 bytes long while a 64-bit timestamp is 8 bytes long.

CPU_CFG_INT_DIS_MEAS_EN

This #define specifies whether extra code will be inserted to measure interrupt disable time when the code uses CPU_CRITICAL_ENTER() and CPU_CRITICAL_EXIT(). This extra code obviously adds additional interrupt latency because of the measurement artifacts.

CPU_CFG_INT_DIS_MEAS_OVRHD_NBR

This #define is used to account for the interrupt disable time measurement artifacts. The value should typically be 1.

CPU_CFG_LEAD_ZEROS_ASM_PRESENT

This #define specifies whether or not your processor offers assembly language instructions to count the number of consecutive zeros from the left most bit position of an integer.

CPU_CFG_TRAIL_ZEROS_ASM_PRESENT

This #define specifies whether or not your processor offers assembly language instructions to count the number of consecutive zeros from the right most bit position of an integer.

cpu_core.c

This file is generic and does not need to be changed. However it must be included in all builds. cpu_core.c defines such functions as CPU_Init()CPU_CntLeadZeros(), and code to measure maximum CPU interrupt disable time. A few functions are explained here since they are used in µC/OS-III-based applications.

CPU_Init()

CPU_Init() must be called before calling OSInit().

CPU_CntLeadZeros()

CPU_CntLeadZeros() is used by the µC/OS-III scheduler to find the highest priority ready task (see Scheduling). cpu_core.c implements a count leading zeros in C. However, if the processor used provides a built-in instruction to count leading zeros, define CPU_CFG_LEAD_ZEROS_ASM_PRESENT, and replace this function by an assembly language equivalent (in cpu_a.asm). It is important to properly declare CPU_CFG_DATA_SIZE in cpu.h for this function to work.

CPU_TS_TmrFreqGet()

CPU_TS_TmrFreqGet() is a function that can be called by your application so it knows what the timestamp increment frequency is set to. In other words, if the timestamp timer is incremented at a rate of 1 MHz then this function would return 1000000.

CPU_TS_TmrFreqSet()

CPU_TS_TmrFreqSet() is a function that needs to be called by the application code to notify µC/CPU about the increment frequency of the timer used for timestamps. In other words, if the timestamp timer is incremented at a rate of 1 MHz then your application code would need to call CPU_TS_TmrFreqSet() and pass 1000000.

CPU_TS_Get32()

CPU_TS_Get32() is a function that returns a 32-bit timestamp. The macro OS_TS_GET() (see os_cpu.h) generally maps to this function.

cpu_core.h

This header file is required by cpu_core.c to define function prototypes.

The table below shows the name of µC/CPU ‘template’ files you should use as a starting point should you decide to start a µC/CPU port from scratch. It’s highly recommended that you copy these files to folders that matches the layout shown in this table. You would then edit these files to build up your own µC/CPU port files. Again, refer to the µC/CPU User’s Manual (uC-CPU-Manual.pdf) found in \Micrium\Software\uC-CPU\Doc.

µC/CPU Template Files

File

Directory

cpu.h

\Micrium\Software\uC-CPU\Template

cpu_c.c

\Micrium\Software\uC-CPU\Template

cpu_a.asm

\Micrium\Software\uC-CPU\Template

cpu.h

Many CPUs have different word lengths and cpu.h declares a series of type definitions that ensure portability. Specifically, we don’t use the C data types intshortlongcharetc. at Micrium. Instead, clearer data types are defined. Consult your compiler documentation to determine whether the standard declarations described below need to be changed for the CPU/compiler you are using. You should note that the typedefs below are not all grouped together in cpu.h and also, cpu.h contains additional comments about these data types.

µC/CPU Data Types
          typedef            void        CPU_VOID;
          typedef  unsigned  char        CPU_CHAR;              
          typedef  unsigned  char        CPU_BOOLEAN;           
          typedef  unsigned  char        CPU_INT08U;            
          typedef    signed  char        CPU_INT08S;            
          typedef  unsigned  short       CPU_INT16U;            
          typedef    signed  short       CPU_INT16S;            
          typedef  unsigned  int         CPU_INT32U;            
          typedef    signed  int         CPU_INT32S;            
          typedef  unsigned  long  long  CPU_INT64U;            
          typedef    signed  long  long  CPU_INT64S;            
          typedef            float       CPU_FP32;              
          typedef            double      CPU_FP64;              
          typedef  volatile  CPU_INT08U  CPU_REG08;             
          typedef  volatile  CPU_INT16U  CPU_REG16;             
          typedef  volatile  CPU_INT32U  CPU_REG32;             
          typedef  volatile  CPU_INT64U  CPU_REG64;             
          typedef            void      (*CPU_FNCT_VOID)(void);  
          typedef            void      (*CPU_FNCT_PTR )(void *);
          typedef  CPU_INT32U            CPU_ADDR;
          typedef  CPU_INT32U            CPU_DATA;
          typedef  CPU_DATA              CPU_ALIGN; 
          typedef  CPU_ADDR              CPU_SIZE_T;
          typedef  CPU_INT32U            CPU_STK;             (1)
          typedef  CPU_ADDR              CPU_STK_SIZE;
          typedef  CPU_INT16U            CPU_ERR;
          typedef  CPU_INT32U            CPU_SR;              (2)
          typedef  CPU_INT32U            CPU_TS;              (3)

(1) Especially important for µC/OS-III is the definition of the CPU_STK data type, which sets the width of a stack entry. Specifically, is the width of data pushed to and popped from the stack 8 bits, 16 bits, 32 bits or 64 bits?

(2) CPU_SR defines the data type for the processor’s status register (SR) that generally holds the interrupt disable status.

(3) The CPU_TS is a time stamp used to determine when an operation occurred, or to measure the execution time of code.


cpu.h also declares macros to disable and enable interrupts: CPU_CRITICAL_ENTER() and CPU_CRITICAL_EXIT(), respectively. The documentation in the template file explains how to declare these macros.

cpu.h is also where you need to define configuration constants:

CPU_CFG_ENDIAN_TYPE

This #define specifies whether your CPU is a little-endian machine or a big-endian machine. cpu_def.h offers the following choices:

CPU_ENDIAN_TYPE_BIG
CPU_ENDIAN_TYPE_LITTLE

CPU_CFG_ADDR_SIZE

This #define specifies the size of an address for the processor, in number of bytes. cpu_def.h offers the following choices:

CPU_WORD_SIZE_08
CPU_WORD_SIZE_16
CPU_WORD_SIZE_32
CPU_WORD_SIZE_64

CPU_CFG_DATA_SIZE

This #define specifies the ‘natural’ data width of the processor, in number of bytes. cpu_def.h offers the following choices:

CPU_WORD_SIZE_08
CPU_WORD_SIZE_16
CPU_WORD_SIZE_32
CPU_WORD_SIZE_64

CPU_DATA_SIZE_MAX

This #define specifies the maximum word size of the processor, in number of bytes. cpu_def.h offers the following choices:

CPU_WORD_SIZE_08
CPU_WORD_SIZE_16
CPU_WORD_SIZE_32
CPU_WORD_SIZE_64

CPU_CFG_STK_GROWTH

This #define specifies whether the stack grows from high to low memory or from low to high memory addresses. cpu_def.h offers the following choices:

CPU_STK_GROWTH_LO_TO_HI
CPU_STK_GROWTH_HI_TO_LO

CPU_CFG_CRITICAL_METHOD

This #define establishes how interrupts will be disabled when processing critical sections. Specifically, will we simply disable interrupts when entering a critical section, irrespective of whether or not interrupts were already disabled? Will we save the status of the interrupt disable state before we disable interrupts? cpu_def.h offers the following choices:

CPU_CRITICAL_METHOD_INT_DIS_EN
CPU_CRITICAL_METHOD_STATUS_STK
CPU_CRITICAL_METHOD_STATUS_LOCAL

cpu.h also declares function prototypes for a number of functions found in either cpu_c.c or cpu_a.asm.

cpu_c.c

This is an optional file containing CPU-specific functions to set the interrupt controller, timer prescalers, and more. Most implementations will not contain this file.

cpu_a.asm

This file contains assembly language code to implement such functions as disabling and enabling interrupts, a more efficient count leading zeros function, and more. At a minimum, this file should implement CPU_SR_Save() and CPU_SR_Restore().

CPU_SR_Save()

CPU_SR_Save() reads the current value of the CPU status register where the current interrupt disable flag resides and returns this value to the caller. However, before returning, CPU_SR_Save() must disable all interrupts. CPU_SR_Save() is actually called by the macro CPU_CRITICAL_ENTER().

CPU_SR_Restore()

CPU_SR_Restore() restores the CPU’s status register to a previously saved value. CPU_SR_Restore() is called from the macro CPU_CRITICAL_EXIT().