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.
File | Directory |
---|---|
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
.
File | Directory |
---|---|
|
|
|
|
|
|
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 int
, short
, long
, char
, etc. 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 typedef
s below are not all grouped together in cpu.h
and also, cpu.h
contains additional comments about these 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()
.