GEX core repository.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
gex-core/framework/unit.h

156 lines
4.2 KiB

7 years ago
//
// Created by MightyPork on 2017/11/24.
//
// Structures and basic scaffolding for defining unit drivers
//
7 years ago
#ifndef GEX_UNIT_H
#define GEX_UNIT_H
#include "platform.h"
#include <TinyFrame.h>
#include "utils/ini_writer.h"
#include "utils/payload_builder.h"
#include "utils/payload_parser.h"
#include "rsc_enum.h"
7 years ago
/** Helper macro that returns E_BAD_UNIT_TYPE if unit is not of the given type */
#define CHECK_TYPE(_unit, _driver) do { \
if (((_unit)->driver) != (_driver)) \
return E_BAD_UNIT_TYPE; \
} while (0)
/** Shared unit scratch buffer */
extern char unit_tmp512[UNIT_TMP_LEN]; // temporary static buffer - not expected to be accessed asynchronously
7 years ago
// TODO add mutex?
7 years ago
/** Unit typedef - a instance */
7 years ago
typedef struct unit Unit;
/** Unit driver typedef - type handlers / props object */
7 years ago
typedef struct unit_driver UnitDriver;
/**
* Unit instance structure
*/
7 years ago
struct unit {
/** Reference to the used driver */
7 years ago
const UnitDriver *driver;
/** Unit name (used in error messages) */
const char *name;
/**
* Storage for arbitrary unit data (allocated in 'preInit' and freed in 'deInit' or when init/load fails)
*/
void *data;
/** Unit call sign for messages */
uint8_t callsign;
7 years ago
/** Unit init status */
error_t status;
/** If RSC not avail. error is caught, the resource is stored here. */
Resource failed_rsc;
/** Bit-map of held resources */
ResourceMap resources;
/** Tick interval to run the updateTick() function, if defined */
uint16_t tick_interval;
/** Current number of ticks since last interval completion */
uint16_t _tick_cnt;
7 years ago
};
/**
* Unit instance - statically or dynamically allocated (depends whether it's system or user unit)
*/
struct unit_driver {
/** Driver ID */
const char *name;
/** Unit type description (for use in comments) */
const char *description;
/**
* Pre-init: allocate data object, init defaults
*/
error_t (*preInit)(Unit *unit);
7 years ago
/**
* Load settings from binary storage, parse and store them in the data object.
* Don't do any validation, that's left for the init() function
*
* @param pp - parser
*/
void (*cfgLoadBinary)(Unit *unit, PayloadParser *pp);
/**
* Write settings to binary storage.
*
* @param pb - builder
*/
void (*cfgWriteBinary)(Unit *unit, PayloadBuilder *pb);
/**
* Load settings from a INI file.
* Name has already been parsed and assigned.
* This function is called repeatedly as kv-pairs are encountered in the stream.
*
* @param key - key from the INI file
* @param value - value from the ini file; strings have already removed quotes and replaced escape sequences with ASCII as needed
*/
error_t (*cfgLoadIni)(Unit *unit, const char *key, const char *value);
7 years ago
/**
* Export settings to a INI file.
*
* @param buffer - destination buffer
* @param capacity - buffer size
* @return nubmer of bytes used
*/
void (*cfgWriteIni)(Unit *unit, IniWriter *iw);
/**
* Finalize the init sequence, validate settings, enable peripherals and prepare for operation
*/
error_t (*init)(Unit *unit);
7 years ago
/**
* De-initialize the unit: de-init peripheral, free resources, free data object...
* This is called when disabling all units in order to reload new config.
*/
void (*deInit)(Unit *unit);
/**
* Handle an incoming request. Return true if command was OK.
*/
error_t (*handleRequest)(Unit *unit, TF_ID frame_id, uint8_t command, PayloadParser *pp);
/**
* Periodic update call.
* This is run from the SysTick interrupt handler,
* any communication should be deferred via the job queue.
*/
void (*updateTick)(Unit *unit);
7 years ago
};
/**
* De-init a partially initialized unit (before 'init' succeeds)
* This releases all held resources and frees *data and *name.
7 years ago
*
* Does NOT free the unit struct itself
*
* @param unit - unit to discard
*/
void clean_failed_unit(Unit *unit);
/** Marks peripherals claimed by the system */
extern Unit UNIT_SYSTEM;
/** Marks peripherals not available on the platform */
extern Unit UNIT_PLATFORM;
#endif //GEX_UNIT_H