rasProject_01 / weSweetHome
R. 240
process control / RasPi software by weinert-automation
|
Basic types and constants. More...
#include <stdint.h>
Data Structures | |
union | dualReg_t |
A 32 bit union. More... | |
union | sdm124regs_t |
A type for 124 registers respectively 62 values of 32 bit. More... | |
union | sdm80regs_t |
A type for 80 registers respectively 40 values of 32 bit. More... | |
struct | smdX30modbus_t |
A structure for SMDx30 smart meters. More... | |
Macros | |
#define | clearArray(a) |
Clear an array. More... | |
#define | DAYs |
seconds in days w/o DST switch or leap seconds | |
#define | ERAend |
A point in time far away. More... | |
#define | FALSE |
false off aus arrêt stop halt. More... | |
#define | FOURYEARS |
days in four years (3 * YEAR + LEAPYEAR) | |
#define | HOURs |
seconds in hours | |
#define | LEAPYEAR |
days in leap year | |
#define | memBarrier() |
Memory barrier. More... | |
#define | MILLIARD |
MILLIARD 1/nano = Giga = 10**9. More... | |
#define | MILLION |
Million 1/‹¨« = 1/micro = Mega = 10**6. More... | |
#define | MINUTEs |
seconds in minutes | |
#define | OFF |
false Off Aus arrêt stop halt. More... | |
#define | ON |
true On An marche go. More... | |
#define | PLATFlittlE |
The target platform is little endian. More... | |
#define | TRUE |
true on an marche go. More... | |
#define | YEAR |
Days in normal year. More... | |
Typedefs | |
typedef enum modBusLinkState_t | modBusLinkState_t |
A set of possible states of a Modbus link. More... | |
Enumerations | |
enum | modBusLinkState_t { ML_OFF , ML_ON , ML_IDLE , ML_INITED , ML_REQSEND , ML_RESPREC , ML_LISTEN , ML_REQREC , ML_RESPOND , ML_ERR_ANY , ML_ERR_INIT , ML_ERR_REQ , ML_ERR_RESP } |
A set of possible states of a Modbus link. More... | |
Basic types and constants.
This file contains some basic type definitions and values, i.e. macro constants. It does not contain function definitions and, hence, has no implementing .c file.
Revision history
#define PLATFlittlE |
The target platform is little endian.
values: 0 : no (known at compile time); 1 : yes (dto.); littleEndian() : compute at runtime as no commonly used target information macros are available
#define ON |
true On An marche go.
value: 1
#define OFF |
false Off Aus arrêt stop halt.
value: 0
#define TRUE |
true on an marche go.
value: 1
#define FALSE |
false off aus arrêt stop halt.
value: 0
#define MILLIARD |
MILLIARD 1/nano = Giga = 10**9.
The constant Milliard. (Amercians, wrongly, call that Billion.)
value: 1000000000
#define MILLION |
Million 1/‹¨« = 1/micro = Mega = 10**6.
value: 1000000
#define YEAR |
Days in normal year.
value: 365
#define ERAend |
A point in time far away.
This is 2.2.2106 in Unix seconds and very near the end of the unsigned 32 bit era. In the sense of small embedded control applications we consider this (for tasks timers etc.) as beyond end of life and, hence, infinity.
value: 4294512000U
#define clearArray | ( | a | ) |
Clear an array.
This is to set a real fixed size array to zero (0). Using this instead of looping or own optimising gets better code on almost all gcc compilers. Note: "Real" array means an array declared and defined with a fixed length; and no malloced pointer.
a | the array to be set all 0 (not NULL, fixed length array) |
#define memBarrier | ( | ) |
Memory barrier.
This macro is an ARM memory fence instruction insuring cache updates.
Memory mapped IO, as used in Raspberries' ARM ¶æPs BCM2835, BCM2835 and BCM2836 is quite problematic. As the semantics of memory is (non regarding caches and multiprocessing) extremely simple both compilers and processors may optimise memory access by all kinds of re-ordering and dropping.
A variable is an abstractions of memory cell respectively a pointer or reference is an abstraction of a memory cell address. If such variable points neither to nor is a memory cell but an IO register (say a USART buffer FIFO e.g.) this optimising by re-ordering or dropping would be disastrous. This has to be inhibited at compile time as well as at run time. Indeed, at runtime too as those newer ¶æPs are clever enough to re-order and drop memory accesses by them self.
Compile time memory access optimisation is inhibited by the volatile keyword for every variable and reference meaning an IO register. Just one omission is good for effects hard to diagnose.
Run time optimisation and especially re-ordering is inhibited by putting memory fence instructions (this one) at the right places. The BCM2835 data sheet says: "Accesses to the same peripheral will always arrive and return in-order. It is only when switching from one peripheral to another that data can arrive out-of-order. The simplest way to make sure that data is processed in-order is to place a memory barrier instruction at critical positions in the code. You should place: * A memory write barrier before the first write to a peripheral. * A memory read barrier after the last read of a peripheral. It is not required to put a memory barrier instruction after each read or write access. Only at those places in the code where it is possible that a peripheral read or write may be followed by a read or write of a different peripheral. This is normally at the entry and exit points of the peripheral service code. As interrupts can appear anywhere in the code so you should safeguard those. If an interrupt routine reads from a peripheral the routine should start with a memory read barrier. If an interrupt routine writes to a peripheral the routine should end with a memory write barrier."
That's quite clear and applies to BCM2836 and BCM2837, too (we have no data sheet for those, only for BCM2835). And to repeat: Too many volatiles and memory fences makes programs longer and slower. But one too less is good for disaster.
Language hint: In Java this would be volatile, transient and synchronised. Implementation hint: This macro is __sync_synchronize() Interrupt hint: We and most of us do not make a sequence of IO accesses atomic by interrupt disable. We rely on interrupt routines doing it right as described in the data sheet.
typedef enum modBusLinkState_t modBusLinkState_t |
A set of possible states of a Modbus link.
Modbus link here means a connection to a concrete Modbus slave/server seen by the master/client.
Note: The numbering may change in future but the ordering off < operational < operated < error will not.
The set of states is limited by the interface type (RS485, Ethernet, ..) and may be further limited by the device or application. The subset ML_OFF ML_ON ML_INITED ML_ERR_REQ ML_ERR_RESP will be enough for some RS485 slaves.
enum modBusLinkState_t |
A set of possible states of a Modbus link.
Modbus link here means a connection to a concrete Modbus slave/server seen by the master/client.
Note: The numbering may change in future but the ordering off < operational < operated < error will not.
The set of states is limited by the interface type (RS485, Ethernet, ..) and may be further limited by the device or application. The subset ML_OFF ML_ON ML_INITED ML_ERR_REQ ML_ERR_RESP will be enough for some RS485 slaves.