Files
templates/c/global-time/include/global_time.h
Andrey 2da7e7b525 feat(global-time): Добавь общие часы и порт TMS320F28335
Вынеси программные часы, коррекцию по ProtoCAN RTCSETUP и атомарную метку логгера в переносимое ядро без глобального состояния.

Подключи eCAN-A и CPU Timer2 отдельным портом F28335; зафиксируй календарные границы, переполнение, задержку RX и защиту IRQ в хостовых тестах.
2026-10-23 14:16:21 +03:00

66 lines
8.7 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#ifndef GLOBAL_TIME_H /* Защищает единый контракт часов от повторного включения. */
#define GLOBAL_TIME_H /* Отмечает подключённый интерфейс программных глобальных часов. */
#include <stdint.h> /* Фиксирует разрядность счётчиков и поддерживает 16-битный char TI C28x. */
#ifdef __cplusplus /* Сохраняет совместимость C-библиотеки с приложениями C++. */
extern "C" { /* Экспортирует функции без изменения имён компилятором C++. */
#endif /* Завершает условное объявление C ABI. */
#define GT_RTC_ID 0x00000030UL /* ProtoCAN: Route=0, Type/ID=0, BROADCAST=0, RTCSETUP=3 в Body[15:4]. */
#define GT_READY_BODY 0x3000U /* Контракт GLOBAL_TIME.md: DISCRETE/FLAGS=3, страница общих флагов=0. */
#define GT_READY_RETRY_MS 1000UL /* Повторяет сообщение готовности раз в секунду до первой синхронизации. */
typedef struct gt_frame { /* Описывает classic CAN независимо от регистров и размера char процессора. */
uint32_t id; /* Хранит только 29 бит идентификатора, без служебных битов драйвера. */
uint16_t extended; /* Единица означает IDE=1; стандартные кадры часы игнорируют. */
uint16_t remote; /* Единица означает RTR; удалённый запрос не содержит время. */
uint16_t dlc; /* Считает октеты на линии, а не sizeof элементов массива C28x. */
uint16_t data[8]; /* Каждый элемент содержит один октет 0..255 даже при CHAR_BIT=16. */
} gt_frame; /* Завершает переносимый контейнер кадра. */
typedef struct gt_datetime { /* Представляет календарь без зависимости от time_t и часового пояса ОС. */
uint16_t year; /* Полный год; входной ProtoCAN поддерживает 2000..2099. */
uint16_t month; /* Номер месяца 1..12, без BCD-кодирования. */
uint16_t day; /* Число месяца с проверкой високосного февраля. */
uint16_t weekday; /* День недели 0..6; профиль использует 0=воскресенье, 1=понедельник. */
uint16_t hour; /* Часы 0..23 в 24-часовом формате. */
uint16_t minute; /* Минуты 0..59; leap seconds протокол не передаёт. */
uint16_t second; /* Секунды 0..59 согласно существующему RTCSETUP. */
uint16_t millisecond; /* Доля секунды 0..999; RTCSETUP задаёт нулевую долю. */
} gt_datetime; /* Завершает публичный календарный тип. */
typedef struct gt_stamp { /* Даёт логгеру согласованную метку и её качество одним чтением. */
uint32_t seconds; /* Секунды от 2000-01-01 00:00:00 в шкале времени мастера. */
uint16_t millisecond; /* Миллисекундная доля текущей секунды. */
uint16_t synchronized; /* Ноль до первого корректного RTCSETUP, единица после него. */
uint32_t uptime_ms; /* Независимый счётчик работы modulo 2^32; коррекции его не меняют. */
uint32_t sync_uptime_ms; /* Момент приёма последнего RTCSETUP для оценки давности синхронизации. */
uint32_t generation; /* Число коррекций; логгер отличает участки до и после перевода часов. */
int64_t correction_ms; /* Последнее смещение новых часов относительно старых, в миллисекундах. */
uint16_t weekday; /* Принятый день недели, продвигаемый при каждом переходе через полночь. */
} gt_stamp; /* Завершает атомарно читаемый снимок. */
typedef struct gt_port { /* Передаёт ядру короткие критические секции и неблокирующую отправку CAN. */
void *user; /* Контекст платформы, передаваемый каждому callback без преобразования. */
uint16_t (*enter)(void *user); /* Запрещает IRQ и возвращает прежнее состояние для вложенных вызовов. */
void (*leave)(void *user, uint16_t state); /* Восстанавливает прежнее состояние IRQ, включая вызовы из ISR. */
int (*send)(void *user, const gt_frame *frame); /* Копирует кадр до возврата; 1=принят, 0=занято/ошибка. */
} gt_port; /* Завершает платформенный контракт; heap и аппаратный RTC не нужны. */
typedef struct gt_clock { /* Хранит состояние одного узла; инициализация обязательна до разрешения ISR. */
gt_port port; /* Содержит проверенные callbacks и контекст платформы. */
volatile gt_stamp stamp; /* Меняется только при удержании блокировки IRQ. */
uint16_t device_type; /* Три адресных бита ProtoCAN, диапазон 0..7. */
uint16_t device_id; /* Четыре адресных бита экземпляра, диапазон 0..15. */
uint16_t ready; /* Устанавливается приложением после завершения всей инициализации платы. */
uint16_t announced; /* Помнит принятую транспортом отправку готовности, даже если часы уже синхронизированы. */
uint32_t sent_uptime_ms; /* Ограничивает частоту повторов готовности монотонной шкалой. */
} gt_clock; /* Состояние допускает статическое выделение памяти на микроконтроллере. */
int gt_init(gt_clock *clock, const gt_port *port, uint16_t device_type, uint16_t device_id); /* Проверяет адрес/callbacks и явно очищает RAM, включая TI COFF. */
void gt_tick_1ms(gt_clock *clock); /* Вызывается ровно один раз за аппаратную миллисекунду и выполняет только короткую арифметику. */
void gt_get(gt_clock *clock, gt_stamp *out); /* Атомарно копирует всю метку; допустим вызов из main, логгера и ISR. */
void gt_ready(gt_clock *clock); /* Идемпотентно разрешает сообщение «плата инициализирована»; CAN отправляется из poll. */
void gt_poll(gt_clock *clock); /* Вызывается единственным потребителем в main; не ждёт освобождения CAN. */
int gt_receive(gt_clock *clock, const gt_frame *frame, uint32_t received_uptime_ms); /* Проверяет RTCSETUP и компенсирует задержку от приёма до обработки, менее 2^32 мс. */
int gt_make_rtc(const gt_datetime *date, gt_frame *out); /* Даёт верхнему уровню кодировщик штатного 7-октетного broadcast. */
int gt_parse_ready(const gt_frame *frame, uint16_t *device_type, uint16_t *device_id); /* Позволяет мастеру распознать готовность и выбрать ответ RTCSETUP. */
int gt_calendar(const gt_stamp *stamp, gt_datetime *out); /* Преобразует согласованный снимок в календарь; до синхронизации возвращает 0. */
uint64_t gt_timestamp_ms(const gt_stamp *stamp); /* Возвращает широкую метку от 2000 года без переполнения через 49,7 суток. */
#ifdef __cplusplus /* Закрывает C ABI только для компилятора C++. */
} /* Завершает блок функций с C-связыванием. */
#endif /* Завершает проверку языка потребителя. */
#endif /* Завершает защиту публичного заголовка. */