/** * @file main.c * @brief Пример использования библиотеки blf для создания BLF-файла. * @details Демонстрирует создание контейнера с CAN, LIN, LIN Error и ENV_DATA объектами. * Контекст создаётся на стеке (без динамической памяти). * * Компиляция для обычного ПК: * gcc -o create_blf main.c blf.c -std=c99 -D_GNU_SOURCE * Компиляция для встраиваемой системы с FatFS: * arm-none-eabi-gcc -DUSE_FATFS -Ipath/to/fatfs -o create_blf main.c blf.c * * @author (Ваше имя) * @date 2026-03-20 */ #include "blf.h" /* Вспомогательная структура для хранения семплов АЦП (используется только в примере) */ typedef struct { uint16_t channel1; uint16_t channel2; uint16_t channel3; uint16_t channel4; uint16_t channel5; } AdcSample; int main() { BLFContext ctx; int ret; // Задаём время начала измерения (1 января 2025 года, 00:00:00.000) /* SYSTEMTIME startTime = { .year = 2025, .month = 1, .dayOfWeek = 3, // не критично .day = 1, .hour = 0, .minute = 0, .second = 0, .milliseconds = 0 }; */ SYSTEMTIME startTime = { .year = 0, .month = 0, .dayOfWeek = 0, // не критично .day = 0, .hour = 0, .minute = 0, .second = 0, .milliseconds = 0 }; ret = blf_open(&ctx, "log.blf", &startTime); if (ret != 0) { BLF_ERROR_PRINTF("Failed to open file, exiting.\n"); return 1; } // 2. Начинаем контейнер с временной меткой 0 секунда (1e9 нс) if (blf_start_container(&ctx, 0000000000ULL) != 0) { BLF_ERROR_PRINTF("Failed to start container\n"); blf_close(&ctx); return 1; } // 3. Добавляем CAN-сообщение /* CanMessageStruct canMsg = { .channel = 1, .id = 0x538, .flags = CAN_MSG_FLAGS(CAN_DIR_RX, 0), .dlc = 8, .data = {0x99, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22}, .timestamp = 9000 // 9 секунд (миллисекунды) }; if (blf_add_can_message_struct(&ctx, &canMsg) != 0) { BLF_ERROR_PRINTF("Failed to add CAN message\n"); blf_close(&ctx); return 1; } */ CanMessageStruct canMsg = { .channel = 1, .id = 0x3F1, .flags = CAN_MSG_FLAGS(CAN_DIR_TX, 0), .dlc = 8, .data = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, .timestamp = 0 // 9 секунд (миллисекунды) }; uint8_t j = 0; for (uint32_t i = 0; i < 100000; ++i) { canMsg.data[0] = j; canMsg.data[1] = j / 2; canMsg.data[2] = j / 3; canMsg.data[3] = j / 4; canMsg.data[4] = j / 5; canMsg.data[5] = j / 6; canMsg.data[6] = j / 7; canMsg.data[7] = j / 8; canMsg.timestamp += 100; if (blf_add_can_message_struct(&ctx, &canMsg) != 0) { BLF_ERROR_PRINTF("Failed to add CAN message\n"); blf_close(&ctx); return 1; } ++j; if (j > 100) { ++j; } } /* // 4. Добавляем LIN-сообщение LinMessageStruct linMsg = { .channel = 1, .id = 0x45, .dlc = 4, .data = {0xAA, 0xBB, 0xCC, 0xDD}, .dir = LIN_DIR_TX, .timestamp = 9100, .checksum = 0x5678 }; if (blf_add_lin_message_struct(&ctx, &linMsg) != 0) { BLF_ERROR_PRINTF("Failed to add LIN message\n"); blf_close(&ctx); return 1; } // 5. Добавляем LIN-ошибку отсутствия ответа LinSendErrorStruct sendErr = { .channel = 1, .id = 0x12, .dlc = 8, .timestamp = 9200 }; if (blf_add_lin_send_error_struct(&ctx, &sendErr) != 0) { BLF_ERROR_PRINTF("Failed to add LIN send error\n"); blf_close(&ctx); return 1; } // 6. Добавляем данные окружения (АЦП) AdcSample samples; samples.channel1 = (uint16_t) (1); samples.channel2 = (uint16_t) (2); samples.channel3 = (uint16_t) (3); samples.channel4 = (uint16_t) (4); samples.channel5 = (uint16_t) (5); EnvDataStruct envData = { .name = "ADC", .data = (uint8_t *) &samples, .data_len = sizeof(samples), .timestamp = 9300 }; if (blf_add_env_data_struct(&ctx, &envData) != 0) { BLF_ERROR_PRINTF("Failed to add ENV_DATA\n"); blf_close(&ctx); return 1; } */ // 7. Завершаем контейнер if (blf_end_container(&ctx) != 0) { BLF_ERROR_PRINTF("Failed to end container\n"); blf_close(&ctx); return 1; } // 8. Закрываем файл (заголовок обновляется автоматически) ret = blf_close(&ctx); if (ret != 0) { BLF_ERROR_PRINTF("Failed to close file\n"); return 1; } BLF_ERROR_PRINTF("File log.blf created. Top-level objects: %d\n", ctx.objectCount); return 0; }