file/log_file/main.c
/*
* EVALUATION AND USE OF THIS SOFTWARE IS SUBJECT TO THE TERMS AND
* CONDITIONS OF THE CONTROLLING LICENSE AGREEMENT FOUND AT LICENSE.md
* IN THIS SDK. IF YOU DO NOT AGREE TO THE LICENSE TERMS AND CONDITIONS,
* PLEASE RETURN ALL SOURCE FILES TO SILICON LABORATORIES.
* (c) Copyright 2018, Silicon Laboratories Inc. All rights reserved.
*/
/* Documentation for this app is available online.
* See https://docs.silabs.com/gecko-os/4/standard/latest/sdk/examples/file/log-file
*/
#include "gos.h"
#define MAX_LOG_FILE_SIZE (1024 * 5)
#define LOG_FILENAME "test.log"
#define LOG_PERIOD 50
#define LOG_COUNT 10
#define APPLICATION_START_LINE "'log_file' demo running ..."
// An individual log record will contain the following info ...
typedef struct
{
uint32_t log_id;
gos_utc_ms_t time;
uint32_t gpio_mask;
} log_record_t;
static void log_event_logfile_handler(void *arg);
static void print_log_records(void);
static void partial_read_test(uint32_t log_to_read);
static gos_handle_t logfile_handle;
static uint32_t log_id;
static uint32_t end_id;
/*************************************************************************************************/
void gos_app_init(void)
{
gos_result_t result;
gos_log_file_stats_t stats;
logfile_handle = GOS_NULL_HANDLE;
GOS_LOG(APPLICATION_START_LINE);
// Create (or open) the log file
{
GOS_LOG("Failed to create/open log file: %d", result);
return;
}
// Read stats of existing log file
gos_log_file_get_stats(logfile_handle, &stats);
end_id = log_id + LOG_COUNT; // ID of the last log that will be appended to the file
// Display stats for existing logs (if any)
GOS_LOG("Log file statistics:");
GOS_LOG(" ");
print_log_records(); // Print all records in the logfile
partial_read_test(3); // Read and print log #3
// Setup a periodic event to start logging to file
GOS_LOG(" ");
GOS_LOG("Taking %d logs...", LOG_COUNT);
gos_event_register_periodic(log_event_logfile_handler, NULL, LOG_PERIOD, GOS_EVENT_FLAGS1(RUN_NOW));
}
/*************************************************************************************************/
void gos_app_deinit(void)
{
if (logfile_handle != GOS_NULL_HANDLE)
{
GOS_LOG("\r\n'log_file' demo shutting down, run the demo again to view saved logs.\r\n");
gos_file_close(logfile_handle);
}
}
/*************************************************************************************************
* Take a log sample and write it to the log file
*/
static void log_event_logfile_handler(void *arg)
{
gos_result_t result;
log_record_t record;
record.log_id = log_id;
record.gpio_mask = gos_gpio_mask_get(UINT32_MAX);
{
GOS_LOG("Failed to append new log: %d", result);
}
else
{
GOS_LOG("Saved log: %d", log_id);
++log_id;
}
// Unregister the event to stop logging once we reach the end
{
gos_event_unregister(log_event_logfile_handler, NULL);
}
}
/*************************************************************************************************
* Sequentially read the log records and print
*/
static void print_log_records(void)
{
log_record_t record;
gos_buffer_t buffer =
{
.data = (uint8_t*)&record,
.size = sizeof(log_record_t)
};
do
{
{
GOS_LOG("Empty log file, no records to display.");
break;
}
else
{
gos_iso8601_str_t time_str;
gos_time_utc_ms_to_iso8601_str(record.time, 0, &time_str);
GOS_LOG("Log %d:", record.log_id);
GOS_LOG(" GPIO mask: 0x%08X", record.gpio_mask);
}
} while(1);
}
/*************************************************************************************************
* Test reading a log record in chunks
*/
static void partial_read_test(uint32_t log_to_read)
{
log_record_t record;
uint8_t *ptr = (uint8_t*)&record;
gos_buffer_t buffer;
gos_iso8601_str_t time_str;
do
{
gos_result_t result;
buffer.data = ptr;
buffer.size = 5;
{
GOS_LOG("Failed to read log: %d", result);
return;
}
ptr += buffer.size;
// When the size is 0, there's no more log data to read
} while(buffer.size > 0);
gos_time_utc_ms_to_iso8601_str(record.time, 0, &time_str);
GOS_LOG(" ");
GOS_LOG("Partial read test, Log ID: %d", record.log_id);
GOS_LOG(" GPIO mask: 0x%08X", record.gpio_mask);;
}