STAR
Cal STAR — firmware, DAQ server, and engine design
Loading...
Searching...
No Matches
emmc_log.h
Go to the documentation of this file.
1
#ifndef STAR_EMMC_LOG_H
2
#define STAR_EMMC_LOG_H
3
4
/*
5
* The flight log on the eMMC (U9, THGBMTG5D1LBAIL, 4 GB).
6
*
7
* What it does
8
* Recording starts when the state machine enters ARMED and continues
9
* through LAUNCHED and RECOVERY; Un-arm closes the session. Self-test and
10
* Idle never touch the eMMC. (flight_state_logs_to_emmc.)
11
*
12
* How (see EMMC-ARCHITECTURE.md for why)
13
* - Raw blocks, no filesystem. An append-only run of self-checking 512 B
14
* blocks: each carries the volume epoch, its own position, its session
15
* and a CRC32. Nothing on the card is rewritten in place, so a power cut
16
* can only lose the tail that was in flight.
17
* - The end of the log is found at mount by binary search over "is this
18
* block valid and where it claims to be" (~23 reads for 4 GB), so there
19
* is no directory or pointer block to wear out or tear.
20
* - Two sides that never wait on each other. emmc_log_append() (sensor
21
* tasks) copies a record into a RAM chunk and returns. emmc_log_service()
22
* (one low-priority writer task) does every card transfer, one 16 KB
23
* chunk per call. If the card stalls and every chunk is full, records
24
* are dropped and counted, and a DROPPED record says how many.
25
* - All card I/O, including bring-up and mount, happens in
26
* emmc_log_service(), never in the caller of emmc_log_on_state().
27
*
28
* On-disk layout (little-endian)
29
* LBA 0 superblock: magic, layout version, epoch, data start,
30
* capacity, CRC32
31
* LBA data_start.. log blocks, block k at data_start + k:
32
* 0 u32 magic EMMC_LOG_BLOCK_MAGIC
33
* 4 u32 epoch changes on every format; older blocks are invalid
34
* 8 u32 seq = k (its own position)
35
* 12 u32 session numbered from 1 across power cycles
36
* 16 u8 kind EMMC_LOG_KIND_DATA or _PAD
37
* 17 u8 0
38
* 18 u16 used payload bytes in use
39
* 20 payload records, never split across blocks
40
* 508 u32 crc32 over bytes 0..507
41
* record: u8 type, u8 len, u32 t_ms, len bytes of data
42
*/
43
44
#include <stdbool.h>
45
#include <stdint.h>
46
47
#include "
emmc_port.h
"
48
#include "
flight_state.h
"
49
50
#ifdef __cplusplus
51
extern
"C"
{
52
#endif
53
54
/* 16 KB: OPTIMAL_WRITE_SIZE (EXT_CSD[265] = 4, in 4 KB units). */
55
#define EMMC_LOG_CHUNK_BLOCKS 32U
56
#define EMMC_LOG_CHUNK_BYTES (EMMC_LOG_CHUNK_BLOCKS * EMMC_BLOCK_SIZE)
57
#define EMMC_LOG_MAX_CHUNKS 16U
58
59
#define EMMC_LOG_HEADER_BYTES 20U
60
#define EMMC_LOG_PAYLOAD_BYTES (EMMC_BLOCK_SIZE - EMMC_LOG_HEADER_BYTES - 4U)
61
#define EMMC_LOG_RECORD_HEADER_BYTES 6U
62
63
#define EMMC_LOG_SUPER_MAGIC 0x31425353UL
/* "SSB1" */
64
#define EMMC_LOG_BLOCK_MAGIC 0x31474C53UL
/* "SLG1" */
65
#define EMMC_LOG_LAYOUT_VERSION 1U
66
67
#define EMMC_LOG_KIND_DATA 1U
68
#define EMMC_LOG_KIND_PAD 2U
69
70
/* Record types below 0x10 belong to the log; sensors use 0x10 and up. */
71
#define EMMC_REC_SESSION_START 0x01U
/* data: u8 state entered */
72
#define EMMC_REC_STATE 0x02U
/* data: u8 from, u8 to */
73
#define EMMC_REC_SESSION_END 0x03U
/* data: u8 state entered */
74
#define EMMC_REC_DROPPED 0x04U
/* data: u32 records lost before this */
75
#define EMMC_REC_USER_FIRST 0x10U
76
77
/* Default data start: 8192 blocks = 4 MB = one HC erase group (EXT_CSD). */
78
#define EMMC_LOG_DEFAULT_DATA_START 8192UL
79
80
typedef
struct
{
81
uint8_t
bytes
[
EMMC_LOG_CHUNK_BYTES
];
82
}
emmc_log_chunk_t
;
83
84
typedef
struct
{
85
uint32_t
data_start_lba
;
/* first log block; > 0 (LBA 0 is super) */
86
uint32_t
flush_interval_ms
;
/* max age of a partly filled chunk */
87
uint32_t
read_budget_ms
;
/* per read() call */
88
uint32_t
write_budget_ms
;
/* per write() call (one chunk) */
89
uint8_t
write_attempts
;
/* tries per chunk before FAULT */
90
}
emmc_log_config_t
;
91
92
typedef
enum
{
93
EMMC_DISK_UNMOUNTED
= 0,
/* not brought up yet (nothing armed so far) */
94
EMMC_DISK_MOUNTED
,
95
EMMC_DISK_FULL
,
/* no room for another chunk; recording stops */
96
EMMC_DISK_FAULT
/* start, mount or writes failed; recording stops */
97
}
emmc_disk_state_t
;
98
99
typedef
struct
{
100
uint32_t
records
;
/* records accepted into RAM */
101
uint32_t
dropped
;
/* records refused while recording (no room) */
102
uint32_t
chunks_written
;
/* chunks on the card */
103
uint32_t
chunks_lost
;
/* sealed chunks discarded (FULL/FAULT) */
104
uint32_t
write_errors
;
/* failed write() calls, retried or not */
105
uint32_t
pad_blocks
;
/* blocks padded out by flushes */
106
}
emmc_log_stats_t
;
107
108
typedef
enum
{
109
EMMC_CHUNK_FREE
= 0,
110
EMMC_CHUNK_FILLING
,
111
EMMC_CHUNK_READY
112
}
emmc_chunk_state_t
;
113
114
typedef
struct
{
115
/* Fixed at init. */
116
emmc_port_t
port
;
117
void
*
context
;
118
emmc_log_config_t
config
;
119
emmc_log_chunk_t
*
chunks
;
120
uint8_t
chunk_count
;
121
uint8_t*
scratch
;
/* one block, for mount reads */
122
123
/* Producer side (under lock). */
124
bool
recording
;
125
uint32_t
arm_index
;
/* arms since power-up, from 1 */
126
bool
has_fill
;
127
uint8_t
fill_chunk
;
128
uint8_t
fill_block
;
129
uint16_t
fill_offset
;
130
bool
fill_aged
;
/* the writer has seen this chunk filling */
131
uint32_t
fill_started_ms
;
/* when it first saw it (writer's clock) */
132
uint32_t
unreported_drops
;
133
emmc_chunk_state_t
chunk_state
[
EMMC_LOG_MAX_CHUNKS
];
134
uint32_t
chunk_arm
[
EMMC_LOG_MAX_CHUNKS
];
135
136
/* Writer side. */
137
uint8_t
write_chunk
;
138
uint8_t
write_tries
;
139
emmc_disk_state_t
disk
;
140
uint32_t
capacity
;
/* blocks, from start() */
141
uint32_t
epoch
;
142
uint32_t
head
;
/* next LBA to write */
143
uint32_t
base_session
;
/* last session on the card at mount */
144
145
emmc_log_stats_t
stats
;
146
}
emmc_log_t
;
147
148
/* Defaults: data start 4 MB, flush 1 s, read 100 ms, write 1 s, 3 tries. */
149
emmc_log_config_t
emmc_log_default_config
(
void
);
150
151
/*
152
* No I/O. `chunks` (chunk_count of 2..EMMC_LOG_MAX_CHUNKS) and `scratch`
153
* (EMMC_BLOCK_SIZE bytes) must stay valid and be DMA-reachable and 32-byte
154
* aligned on the board. Returns EMMC_ERR_PARAM on a bad argument.
155
*/
156
emmc_status_t
emmc_log_init
(
emmc_log_t
* log,
const
emmc_port_t
*
port
,
157
void
* context,
const
emmc_log_config_t
*
config
,
158
emmc_log_chunk_t
*
chunks
, uint8_t chunk_count,
159
uint8_t*
scratch
);
160
161
/*
162
* Tell the log about a state change. Entering a recording state from a
163
* non-recording one opens a session; leaving closes it and flushes; a change
164
* between recording states is logged as a STATE record. No I/O. Returns
165
* false if recording should have started but the disk is FULL or FAULT.
166
*/
167
bool
emmc_log_on_state
(
emmc_log_t
* log,
flight_state_t
from,
flight_state_t
to,
168
uint32_t now_ms);
169
170
/*
171
* Copy one record into RAM. False when not recording (Self-test, Idle, a
172
* FULL/FAULT disk) or when no chunk is free (counted in stats.dropped).
173
* `type` >= EMMC_REC_USER_FIRST for sensor data. Never blocks on the card.
174
*/
175
bool
emmc_log_append
(
emmc_log_t
* log, uint8_t type, uint32_t t_ms,
176
const
void
* data, uint8_t len);
177
178
/* Seal the partly filled chunk now (padding the rest) so it gets written. */
179
void
emmc_log_flush
(
emmc_log_t
* log);
180
181
/*
182
* The writer. Seals a chunk older than flush_interval_ms, brings the card up
183
* and mounts on first need, then writes at most one chunk. Call it in a loop
184
* from one task. Returns the result of the I/O it did (EMMC_OK if none).
185
*/
186
emmc_status_t
emmc_log_service
(
emmc_log_t
* log, uint32_t now_ms);
187
188
/* Sealed chunks waiting for the card (0 = everything is on the card). */
189
uint8_t
emmc_log_backlog
(
const
emmc_log_t
* log);
190
191
/* IEEE CRC-32 (reflected 0xEDB88320, init/xorout 0xFFFFFFFF). */
192
uint32_t
emmc_log_crc32
(
const
void
* data, uint32_t len);
193
194
#ifdef __cplusplus
195
}
196
#endif
197
#endif
flight_state.h
flight_state_t
flight_state_t
Definition
flight_state.h:25
emmc_log_on_state
bool emmc_log_on_state(emmc_log_t *log, flight_state_t from, flight_state_t to, uint32_t now_ms)
Definition
emmc_log.c:200
emmc_disk_state_t
emmc_disk_state_t
Definition
emmc_log.h:92
EMMC_DISK_FULL
@ EMMC_DISK_FULL
Definition
emmc_log.h:95
EMMC_DISK_FAULT
@ EMMC_DISK_FAULT
Definition
emmc_log.h:96
EMMC_DISK_UNMOUNTED
@ EMMC_DISK_UNMOUNTED
Definition
emmc_log.h:93
EMMC_DISK_MOUNTED
@ EMMC_DISK_MOUNTED
Definition
emmc_log.h:94
emmc_log_crc32
uint32_t emmc_log_crc32(const void *data, uint32_t len)
Definition
emmc_log.c:31
emmc_log_service
emmc_status_t emmc_log_service(emmc_log_t *log, uint32_t now_ms)
Definition
emmc_log.c:424
EMMC_LOG_MAX_CHUNKS
#define EMMC_LOG_MAX_CHUNKS
Definition
emmc_log.h:57
emmc_log_init
emmc_status_t emmc_log_init(emmc_log_t *log, const emmc_port_t *port, void *context, const emmc_log_config_t *config, emmc_log_chunk_t *chunks, uint8_t chunk_count, uint8_t *scratch)
Definition
emmc_log.c:177
emmc_chunk_state_t
emmc_chunk_state_t
Definition
emmc_log.h:108
EMMC_CHUNK_FREE
@ EMMC_CHUNK_FREE
Definition
emmc_log.h:109
EMMC_CHUNK_READY
@ EMMC_CHUNK_READY
Definition
emmc_log.h:111
EMMC_CHUNK_FILLING
@ EMMC_CHUNK_FILLING
Definition
emmc_log.h:110
emmc_log_backlog
uint8_t emmc_log_backlog(const emmc_log_t *log)
Definition
emmc_log.c:252
emmc_log_append
bool emmc_log_append(emmc_log_t *log, uint8_t type, uint32_t t_ms, const void *data, uint8_t len)
Definition
emmc_log.c:235
EMMC_LOG_CHUNK_BYTES
#define EMMC_LOG_CHUNK_BYTES
Definition
emmc_log.h:56
emmc_log_flush
void emmc_log_flush(emmc_log_t *log)
Definition
emmc_log.c:246
emmc_log_default_config
emmc_log_config_t emmc_log_default_config(void)
Definition
emmc_log.c:167
emmc_port.h
emmc_status_t
emmc_status_t
Definition
emmc_port.h:22
port
static const emmc_port_t port
Definition
emmc_stm32.c:210
chunks
std::vector< daq::SensorDataChunkCollection > chunks
Definition
main.cpp:55
config
static const idle_config_t config
Definition
idle_task.c:17
emmc_log_chunk_t
Definition
emmc_log.h:80
emmc_log_chunk_t::bytes
uint8_t bytes[EMMC_LOG_CHUNK_BYTES]
Definition
emmc_log.h:81
emmc_log_config_t
Definition
emmc_log.h:84
emmc_log_config_t::write_budget_ms
uint32_t write_budget_ms
Definition
emmc_log.h:88
emmc_log_config_t::read_budget_ms
uint32_t read_budget_ms
Definition
emmc_log.h:87
emmc_log_config_t::write_attempts
uint8_t write_attempts
Definition
emmc_log.h:89
emmc_log_config_t::flush_interval_ms
uint32_t flush_interval_ms
Definition
emmc_log.h:86
emmc_log_config_t::data_start_lba
uint32_t data_start_lba
Definition
emmc_log.h:85
emmc_log_stats_t
Definition
emmc_log.h:99
emmc_log_stats_t::records
uint32_t records
Definition
emmc_log.h:100
emmc_log_stats_t::chunks_lost
uint32_t chunks_lost
Definition
emmc_log.h:103
emmc_log_stats_t::write_errors
uint32_t write_errors
Definition
emmc_log.h:104
emmc_log_stats_t::chunks_written
uint32_t chunks_written
Definition
emmc_log.h:102
emmc_log_stats_t::pad_blocks
uint32_t pad_blocks
Definition
emmc_log.h:105
emmc_log_stats_t::dropped
uint32_t dropped
Definition
emmc_log.h:101
emmc_log_t
Definition
emmc_log.h:114
emmc_log_t::arm_index
uint32_t arm_index
Definition
emmc_log.h:125
emmc_log_t::fill_started_ms
uint32_t fill_started_ms
Definition
emmc_log.h:131
emmc_log_t::recording
bool recording
Definition
emmc_log.h:124
emmc_log_t::stats
emmc_log_stats_t stats
Definition
emmc_log.h:145
emmc_log_t::unreported_drops
uint32_t unreported_drops
Definition
emmc_log.h:132
emmc_log_t::chunk_state
emmc_chunk_state_t chunk_state[EMMC_LOG_MAX_CHUNKS]
Definition
emmc_log.h:133
emmc_log_t::config
emmc_log_config_t config
Definition
emmc_log.h:118
emmc_log_t::disk
emmc_disk_state_t disk
Definition
emmc_log.h:139
emmc_log_t::chunk_arm
uint32_t chunk_arm[EMMC_LOG_MAX_CHUNKS]
Definition
emmc_log.h:134
emmc_log_t::capacity
uint32_t capacity
Definition
emmc_log.h:140
emmc_log_t::epoch
uint32_t epoch
Definition
emmc_log.h:141
emmc_log_t::has_fill
bool has_fill
Definition
emmc_log.h:126
emmc_log_t::scratch
uint8_t * scratch
Definition
emmc_log.h:121
emmc_log_t::chunk_count
uint8_t chunk_count
Definition
emmc_log.h:120
emmc_log_t::port
emmc_port_t port
Definition
emmc_log.h:116
emmc_log_t::write_chunk
uint8_t write_chunk
Definition
emmc_log.h:137
emmc_log_t::context
void * context
Definition
emmc_log.h:117
emmc_log_t::fill_aged
bool fill_aged
Definition
emmc_log.h:130
emmc_log_t::fill_block
uint8_t fill_block
Definition
emmc_log.h:128
emmc_log_t::write_tries
uint8_t write_tries
Definition
emmc_log.h:138
emmc_log_t::base_session
uint32_t base_session
Definition
emmc_log.h:143
emmc_log_t::fill_offset
uint16_t fill_offset
Definition
emmc_log.h:129
emmc_log_t::fill_chunk
uint8_t fill_chunk
Definition
emmc_log.h:127
emmc_log_t::head
uint32_t head
Definition
emmc_log.h:142
emmc_log_t::chunks
emmc_log_chunk_t * chunks
Definition
emmc_log.h:119
emmc_port_t
Definition
emmc_port.h:30
scratch
static uint8_t scratch[BS]
Definition
test_emmc_log.c:128
firmware
Flight_Computer
src
app
emmc_log.h
Generated by
1.15.0