77 lines
3.4 KiB
C
77 lines
3.4 KiB
C
/*
|
||
* Непрерывная запись каналов в два банка и выдача согласованного снимка через регистровый
|
||
* интерфейс. Адреса и количества регистратора считаются в 16-битных словах, включая C28x;
|
||
* чтение снимка отделено от текущего сбора.
|
||
*/
|
||
|
||
/* Portable continuous recorder. All addresses/counts are 16-bit WORDS,
|
||
* including on C28x (CHAR_BIT=16). No heap, UART, HAL or global state. */
|
||
#ifndef GAS_LOGGER_H
|
||
#define GAS_LOGGER_H
|
||
#include <stdint.h>
|
||
#ifdef __cplusplus
|
||
extern "C" {
|
||
#endif
|
||
#define GL_MAGIC 0x474CU
|
||
#define GL_VERSION 1U
|
||
#define GL_HEADER_WORDS 5U /* time_ms:u32, sequence:u32, event:u16, values... */
|
||
#define GL_DATA_OFFSET 0x100U
|
||
#define GL_MAX_CHANNELS 64U
|
||
#define GL_COMMAND 18U
|
||
#define GL_RELEASE_LO 19U
|
||
#define GL_RELEASE_HI 20U
|
||
#define GL_START 1U
|
||
#define GL_SNAPSHOT 2U
|
||
#define GL_RELEASE 3U
|
||
typedef enum { GL_OK=0, GL_ADDRESS, GL_ARGUMENT, GL_BUSY, GL_EMPTY,
|
||
GL_STALE, GL_SOURCE_ERROR } gl_result;
|
||
typedef struct {
|
||
uint16_t gas, modbus, can;
|
||
} gl_channel;
|
||
typedef struct {
|
||
uint16_t base, channels, capacity;
|
||
uint32_t schema_id;
|
||
const gl_channel *map;
|
||
} gl_config;
|
||
/* enter returns the previous IRQ state; leave MUST restore it, not enable
|
||
* IRQs unconditionally. source executes under this lock: bounded RAM reads
|
||
* only, never I/O/waits. Cache remote CAN values before sampling. */
|
||
typedef struct {
|
||
void *user;
|
||
uint32_t (*enter)(void *user);
|
||
void (*leave)(void *user, uint32_t state);
|
||
int (*source)(void *user, uint16_t gas, uint16_t *value);
|
||
} gl_port;
|
||
typedef struct {
|
||
gl_config config;
|
||
gl_port port;
|
||
uint16_t *banks[2];
|
||
uint16_t active, count, next, recording, pinned, snap_count, snap_next;
|
||
uint32_t generation, release_generation, sequence, missed, source_errors;
|
||
} gas_logger;
|
||
/* Each distinct bank must have >=capacity*(channels+5) uint16_t elements.
|
||
* All callbacks and a nonoverlapping register map are required. */
|
||
gl_result gl_init(gas_logger *log, const gl_config *config, const gl_port *port,
|
||
uint16_t *bank0, uint16_t *bank1, uint32_t bank_words);
|
||
/* Called by the project timer/event hook. A failed source discards the whole
|
||
* sample. Sequence/time remain uint32, wrapping modulo 2^32. */
|
||
gl_result gl_capture(gas_logger *log, uint32_t time_ms, uint16_t event);
|
||
/* Snapshot swaps banks, pins the old one, and NEVER stops acquisition.
|
||
* Another snapshot while pinned returns BUSY and increments missed. */
|
||
gl_result gl_snapshot(gas_logger *log);
|
||
/* Atomic, all-or-nothing block read. Snapshot records are chronological;
|
||
* reads past snap_count are rejected, not zero-filled. */
|
||
gl_result gl_read(gas_logger *log, uint16_t address, uint16_t *out, uint16_t count);
|
||
/* No STOP/reset command. START is idempotent. RELEASE requires the generation
|
||
* staged in base+19/20. One controlling client per device. */
|
||
gl_result gl_write(gas_logger *log, uint16_t address, uint16_t value);
|
||
/* Register aliases for FC03/06 and ProtoCAN GAS. Transports keep their own
|
||
* framing/CRC; addresses are zero-based and words preserve their values. */
|
||
gl_result gl_modbus_read(gas_logger *log, uint16_t address, uint16_t *out, uint16_t count);
|
||
gl_result gl_modbus_write(gas_logger *log, uint16_t address, uint16_t value);
|
||
gl_result gl_can_read(gas_logger *log, uint16_t address, uint16_t *out, uint16_t count);
|
||
#ifdef __cplusplus
|
||
}
|
||
#endif
|
||
#endif
|