mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2025-02-22 12:54:14 +01:00
OP-1395 - Pack several objects on a single Debug Log "slot", after ten consecutive failures (log full) gives up trying to save to prevent wasting time. Use PIOS_Delay for timestamp
This commit is contained in:
parent
3f60e75d2c
commit
55b325966a
@ -49,6 +49,9 @@ static xSemaphoreHandle mutex = 0;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static bool logging_enabled = false;
|
static bool logging_enabled = false;
|
||||||
|
#define MAX_CONSECUTIVE_FAILS_COUNT 10
|
||||||
|
static bool log_is_full = false;
|
||||||
|
static uint8_t fails_count = 0;
|
||||||
static uint16_t flightnum = 0;
|
static uint16_t flightnum = 0;
|
||||||
static uint16_t lognum = 0;
|
static uint16_t lognum = 0;
|
||||||
static DebugLogEntryData *buffer = 0;
|
static DebugLogEntryData *buffer = 0;
|
||||||
@ -56,8 +59,16 @@ static DebugLogEntryData *buffer = 0;
|
|||||||
static DebugLogEntryData staticbuffer;
|
static DebugLogEntryData staticbuffer;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Private Function Prototypes */
|
#define LOG_ENTRY_MAX_DATA_SIZE (sizeof(((DebugLogEntryData *)0)->Data))
|
||||||
|
#define LOG_ENTRY_HEADER_SIZE (sizeof(DebugLogEntryData) - LOG_ENTRY_MAX_DATA_SIZE)
|
||||||
|
// build the obj_id as a DEBUGLOGENTRY ID with least significant byte zeroed and filled with flight number
|
||||||
|
#define LOG_GET_FLIGHT_OBJID(x) ((DEBUGLOGENTRY_OBJID & ~0xFF) | (x & 0xFF))
|
||||||
|
|
||||||
|
static uint32_t used_buffer_space = 0;
|
||||||
|
|
||||||
|
/* Private Function Prototypes */
|
||||||
|
static void enqueue_data(uint32_t objid, uint16_t instid, size_t size, uint8_t *data);
|
||||||
|
static bool write_current_buffer();
|
||||||
/**
|
/**
|
||||||
* @brief Initialize the log facility
|
* @brief Initialize the log facility
|
||||||
*/
|
*/
|
||||||
@ -75,9 +86,12 @@ void PIOS_DEBUGLOG_Initialize()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mutexlock();
|
mutexlock();
|
||||||
lognum = 0;
|
lognum = 0;
|
||||||
flightnum = 0;
|
flightnum = 0;
|
||||||
while (PIOS_FLASHFS_ObjLoad(pios_user_fs_id, flightnum * 256, lognum, (uint8_t *)buffer, sizeof(DebugLogEntryData)) == 0) {
|
fails_count = 0;
|
||||||
|
used_buffer_space = 0;
|
||||||
|
log_is_full = false;
|
||||||
|
while (PIOS_FLASHFS_ObjLoad(pios_user_fs_id, LOG_GET_FLIGHT_OBJID(flightnum), lognum, (uint8_t *)buffer, sizeof(DebugLogEntryData)) == 0) {
|
||||||
flightnum++;
|
flightnum++;
|
||||||
}
|
}
|
||||||
mutexunlock();
|
mutexunlock();
|
||||||
@ -103,30 +117,13 @@ void PIOS_DEBUGLOG_Enable(uint8_t enabled)
|
|||||||
*/
|
*/
|
||||||
void PIOS_DEBUGLOG_UAVObject(uint32_t objid, uint16_t instid, size_t size, uint8_t *data)
|
void PIOS_DEBUGLOG_UAVObject(uint32_t objid, uint16_t instid, size_t size, uint8_t *data)
|
||||||
{
|
{
|
||||||
if (!logging_enabled || !buffer) {
|
if (!logging_enabled || !buffer || log_is_full) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mutexlock();
|
mutexlock();
|
||||||
buffer->Flight = flightnum;
|
|
||||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
|
||||||
buffer->FlightTime = xTaskGetTickCount() * portTICK_RATE_MS;
|
|
||||||
#else
|
|
||||||
buffer->FlightTime = 0;
|
|
||||||
#endif
|
|
||||||
buffer->Entry = lognum;
|
|
||||||
buffer->Type = DEBUGLOGENTRY_TYPE_UAVOBJECT;
|
|
||||||
buffer->ObjectID = objid;
|
|
||||||
buffer->InstanceID = instid;
|
|
||||||
if (size > sizeof(buffer->Data)) {
|
|
||||||
size = sizeof(buffer->Data);
|
|
||||||
}
|
|
||||||
buffer->Size = size;
|
|
||||||
memset(buffer->Data, 0xff, sizeof(buffer->Data));
|
|
||||||
memcpy(buffer->Data, data, size);
|
|
||||||
|
|
||||||
if (PIOS_FLASHFS_ObjSave(pios_user_fs_id, flightnum * 256, lognum, (uint8_t *)buffer, sizeof(DebugLogEntryData)) == 0) {
|
enqueue_data(objid, instid, size, data);
|
||||||
lognum++;
|
|
||||||
}
|
|
||||||
mutexunlock();
|
mutexunlock();
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@ -137,27 +134,30 @@ void PIOS_DEBUGLOG_UAVObject(uint32_t objid, uint16_t instid, size_t size, uint8
|
|||||||
*/
|
*/
|
||||||
void PIOS_DEBUGLOG_Printf(char *format, ...)
|
void PIOS_DEBUGLOG_Printf(char *format, ...)
|
||||||
{
|
{
|
||||||
if (!logging_enabled || !buffer) {
|
if (!logging_enabled || !buffer || log_is_full) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
mutexlock();
|
mutexlock();
|
||||||
|
// flush any pending buffer before writing debug text
|
||||||
|
if (used_buffer_space) {
|
||||||
|
write_current_buffer();
|
||||||
|
}
|
||||||
memset(buffer->Data, 0xff, sizeof(buffer->Data));
|
memset(buffer->Data, 0xff, sizeof(buffer->Data));
|
||||||
vsnprintf((char *)buffer->Data, sizeof(buffer->Data), (char *)format, args);
|
vsnprintf((char *)buffer->Data, sizeof(buffer->Data), (char *)format, args);
|
||||||
buffer->Flight = flightnum;
|
buffer->Flight = flightnum;
|
||||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
|
||||||
buffer->FlightTime = xTaskGetTickCount() * portTICK_RATE_MS;
|
buffer->FlightTime = PIOS_DELAY_GetuS();
|
||||||
#else
|
|
||||||
buffer->FlightTime = 0;
|
|
||||||
#endif
|
|
||||||
buffer->Entry = lognum;
|
buffer->Entry = lognum;
|
||||||
buffer->Type = DEBUGLOGENTRY_TYPE_TEXT;
|
buffer->Type = DEBUGLOGENTRY_TYPE_TEXT;
|
||||||
buffer->ObjectID = 0;
|
buffer->ObjectID = 0;
|
||||||
buffer->InstanceID = 0;
|
buffer->InstanceID = 0;
|
||||||
buffer->Size = strlen((const char *)buffer->Data);
|
buffer->Size = strlen((const char *)buffer->Data);
|
||||||
|
|
||||||
if (PIOS_FLASHFS_ObjSave(pios_user_fs_id, flightnum * 256, lognum, (uint8_t *)buffer, sizeof(DebugLogEntryData)) == 0) {
|
if (PIOS_FLASHFS_ObjSave(pios_user_fs_id, LOG_GET_FLIGHT_OBJID(flightnum), lognum, (uint8_t *)buffer, sizeof(DebugLogEntryData)) == 0) {
|
||||||
lognum++;
|
lognum++;
|
||||||
}
|
}
|
||||||
mutexunlock();
|
mutexunlock();
|
||||||
@ -179,7 +179,7 @@ void PIOS_DEBUGLOG_Printf(char *format, ...)
|
|||||||
int32_t PIOS_DEBUGLOG_Read(void *mybuffer, uint16_t flight, uint16_t inst)
|
int32_t PIOS_DEBUGLOG_Read(void *mybuffer, uint16_t flight, uint16_t inst)
|
||||||
{
|
{
|
||||||
PIOS_Assert(mybuffer);
|
PIOS_Assert(mybuffer);
|
||||||
return PIOS_FLASHFS_ObjLoad(pios_user_fs_id, flight * 256, inst, (uint8_t *)mybuffer, sizeof(DebugLogEntryData));
|
return PIOS_FLASHFS_ObjLoad(pios_user_fs_id, LOG_GET_FLIGHT_OBJID(flight), inst, (uint8_t *)mybuffer, sizeof(DebugLogEntryData));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -214,11 +214,68 @@ void PIOS_DEBUGLOG_Format(void)
|
|||||||
{
|
{
|
||||||
mutexlock();
|
mutexlock();
|
||||||
PIOS_FLASHFS_Format(pios_user_fs_id);
|
PIOS_FLASHFS_Format(pios_user_fs_id);
|
||||||
lognum = 0;
|
lognum = 0;
|
||||||
flightnum = 0;
|
flightnum = 0;
|
||||||
|
log_is_full = false;
|
||||||
|
fails_count = 0;
|
||||||
|
used_buffer_space = 0;
|
||||||
mutexunlock();
|
mutexunlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void enqueue_data(uint32_t objid, uint16_t instid, size_t size, uint8_t *data)
|
||||||
|
{
|
||||||
|
DebugLogEntryData *entry;
|
||||||
|
|
||||||
|
// start a new block
|
||||||
|
if (!used_buffer_space) {
|
||||||
|
entry = buffer;
|
||||||
|
memset(buffer->Data, 0xff, sizeof(buffer->Data));
|
||||||
|
used_buffer_space += size;
|
||||||
|
} else {
|
||||||
|
// if an instance is being filled and there is enough space, does enqueues new data.
|
||||||
|
if (used_buffer_space + size + LOG_ENTRY_HEADER_SIZE > LOG_ENTRY_MAX_DATA_SIZE) {
|
||||||
|
buffer->Type = DEBUGLOGENTRY_TYPE_MULTIPLEUAVOBJECTS;
|
||||||
|
if (!write_current_buffer()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
entry = buffer;
|
||||||
|
memset(buffer->Data, 0xff, sizeof(buffer->Data));
|
||||||
|
used_buffer_space += size;
|
||||||
|
} else {
|
||||||
|
entry = (DebugLogEntryData *)&buffer->Data[used_buffer_space];
|
||||||
|
used_buffer_space += size + LOG_ENTRY_HEADER_SIZE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
entry->Flight = flightnum;
|
||||||
|
entry->FlightTime = PIOS_DELAY_GetuS();
|
||||||
|
entry->Entry = lognum;
|
||||||
|
entry->Type = DEBUGLOGENTRY_TYPE_UAVOBJECT;
|
||||||
|
entry->ObjectID = objid;
|
||||||
|
entry->InstanceID = instid;
|
||||||
|
if (size > sizeof(buffer->Data)) {
|
||||||
|
size = sizeof(buffer->Data);
|
||||||
|
}
|
||||||
|
entry->Size = size;
|
||||||
|
|
||||||
|
memcpy(entry->Data, data, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool write_current_buffer()
|
||||||
|
{
|
||||||
|
// not enough space, write the block and start a new one
|
||||||
|
if (PIOS_FLASHFS_ObjSave(pios_user_fs_id, LOG_GET_FLIGHT_OBJID(flightnum), lognum, (uint8_t *)buffer, sizeof(DebugLogEntryData)) == 0) {
|
||||||
|
lognum++;
|
||||||
|
fails_count = 0;
|
||||||
|
used_buffer_space = 0;
|
||||||
|
} else {
|
||||||
|
if (fails_count++ > MAX_CONSECUTIVE_FAILS_COUNT) {
|
||||||
|
log_is_full = true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
* @}
|
* @}
|
||||||
|
@ -2,9 +2,9 @@
|
|||||||
<object name="DebugLogEntry" singleinstance="true" settings="false" category="System">
|
<object name="DebugLogEntry" singleinstance="true" settings="false" category="System">
|
||||||
<description>Log Entry in Flash</description>
|
<description>Log Entry in Flash</description>
|
||||||
<field name="Flight" units="" type="uint16" elements="1" />
|
<field name="Flight" units="" type="uint16" elements="1" />
|
||||||
<field name="FlightTime" units="ms" type="uint32" elements="1" />
|
<field name="FlightTime" units="us" type="uint32" elements="1" />
|
||||||
<field name="Entry" units="" type="uint16" elements="1" />
|
<field name="Entry" units="" type="uint16" elements="1" />
|
||||||
<field name="Type" units="" type="enum" elements="1" options="Empty, Text, UAVObject" />
|
<field name="Type" units="" type="enum" elements="1" options="Empty, Text, UAVObject, MultipleUAVObjects" />
|
||||||
<field name="ObjectID" units="" type="uint32" elements="1"/>
|
<field name="ObjectID" units="" type="uint32" elements="1"/>
|
||||||
<field name="InstanceID" units="" type="uint16" elements="1"/>
|
<field name="InstanceID" units="" type="uint16" elements="1"/>
|
||||||
<field name="Size" units="" type="uint16" elements="1" />
|
<field name="Size" units="" type="uint16" elements="1" />
|
||||||
|
Loading…
x
Reference in New Issue
Block a user