mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2024-12-01 09:24:10 +01:00
Merge remote-tracking branch 'origin/corvuscorax/onboardlogging' into thread/OP-1119_Flight_Side_Logs_Plugin
This commit is contained in:
commit
3ec280b74f
@ -54,9 +54,9 @@ static void printchar(char * *str, int c)
|
||||
#define PAD_RIGHT 1
|
||||
#define PAD_ZERO 2
|
||||
|
||||
static int prints(char * *out, const char *string, int width, int pad)
|
||||
static int prints(char * *out, const char *string, int width, int pad, int limit)
|
||||
{
|
||||
register int pc = 0, padchar = ' ';
|
||||
register int pc = limit, padchar = ' ';
|
||||
|
||||
if (width > 0) {
|
||||
register int len = 0;
|
||||
@ -74,37 +74,37 @@ static int prints(char * *out, const char *string, int width, int pad)
|
||||
}
|
||||
}
|
||||
if (!(pad & PAD_RIGHT)) {
|
||||
for (; width > 0; --width) {
|
||||
for (; width > 0 && pc; --width) {
|
||||
printchar(out, padchar);
|
||||
++pc;
|
||||
--pc;
|
||||
}
|
||||
}
|
||||
for (; *string; ++string) {
|
||||
for (; *string && pc; ++string) {
|
||||
printchar(out, *string);
|
||||
++pc;
|
||||
--pc;
|
||||
}
|
||||
for (; width > 0; --width) {
|
||||
for (; width > 0 && pc; --width) {
|
||||
printchar(out, padchar);
|
||||
++pc;
|
||||
--pc;
|
||||
}
|
||||
|
||||
return pc;
|
||||
return limit - pc;
|
||||
}
|
||||
|
||||
/* the following should be enough for 32 bit int */
|
||||
#define PRINT_BUF_LEN 12
|
||||
|
||||
static int printi(char * *out, int i, int b, int sg, int width, int pad, int letbase)
|
||||
static int printi(char * *out, int i, int b, int sg, int width, int pad, int letbase, int limit)
|
||||
{
|
||||
char print_buf[PRINT_BUF_LEN];
|
||||
register char *s;
|
||||
register int t, neg = 0, pc = 0;
|
||||
register int t, neg = 0, pc = limit;
|
||||
register unsigned int u = i;
|
||||
|
||||
if (i == 0) {
|
||||
print_buf[0] = '0';
|
||||
print_buf[1] = '\0';
|
||||
return prints(out, print_buf, width, pad);
|
||||
return prints(out, print_buf, width, pad, limit);
|
||||
}
|
||||
|
||||
if (sg && b == 10 && i < 0) {
|
||||
@ -124,26 +124,26 @@ static int printi(char * *out, int i, int b, int sg, int width, int pad, int let
|
||||
u /= b;
|
||||
}
|
||||
|
||||
if (neg) {
|
||||
if (neg && pc) {
|
||||
if (width && (pad & PAD_ZERO)) {
|
||||
printchar(out, '-');
|
||||
++pc;
|
||||
--pc;
|
||||
--width;
|
||||
} else {
|
||||
*--s = '-';
|
||||
}
|
||||
}
|
||||
|
||||
return pc + prints(out, s, width, pad);
|
||||
return (limit - pc) + prints(out, s, width, pad, pc);
|
||||
}
|
||||
|
||||
static int print(char * *out, const char *format, va_list args)
|
||||
static int print(int limit, char * *out, const char *format, va_list args)
|
||||
{
|
||||
register int width, pad;
|
||||
register int pc = 0;
|
||||
register int pc = limit;
|
||||
char scr[2];
|
||||
|
||||
for (; *format != 0; ++format) {
|
||||
for (; *format != 0 && pc; ++format) {
|
||||
if (*format == '%') {
|
||||
++format;
|
||||
width = pad = 0;
|
||||
@ -167,43 +167,43 @@ static int print(char * *out, const char *format, va_list args)
|
||||
}
|
||||
if (*format == 's') {
|
||||
register char *s = (char *)va_arg(args, int);
|
||||
pc += prints(out, s ? s : "(null)", width, pad);
|
||||
pc -= prints(out, s ? s : "(null)", width, pad, pc);
|
||||
continue;
|
||||
}
|
||||
if (*format == 'd') {
|
||||
pc += printi(out, va_arg(args, int), 10, 1, width, pad, 'a');
|
||||
pc -= printi(out, va_arg(args, int), 10, 1, width, pad, 'a', pc);
|
||||
continue;
|
||||
}
|
||||
if (*format == 'x') {
|
||||
pc += printi(out, va_arg(args, int), 16, 0, width, pad, 'a');
|
||||
pc -= printi(out, va_arg(args, int), 16, 0, width, pad, 'a', pc);
|
||||
continue;
|
||||
}
|
||||
if (*format == 'X') {
|
||||
pc += printi(out, va_arg(args, int), 16, 0, width, pad, 'A');
|
||||
pc -= printi(out, va_arg(args, int), 16, 0, width, pad, 'A', pc);
|
||||
continue;
|
||||
}
|
||||
if (*format == 'u') {
|
||||
pc += printi(out, va_arg(args, int), 10, 0, width, pad, 'a');
|
||||
pc -= printi(out, va_arg(args, int), 10, 0, width, pad, 'a', pc);
|
||||
continue;
|
||||
}
|
||||
if (*format == 'c') {
|
||||
/* char are converted to int then pushed on the stack */
|
||||
scr[0] = (char)va_arg(args, int);
|
||||
scr[1] = '\0';
|
||||
pc += prints(out, scr, width, pad);
|
||||
pc -= prints(out, scr, width, pad, pc);
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
out:
|
||||
printchar(out, *format);
|
||||
++pc;
|
||||
--pc;
|
||||
}
|
||||
}
|
||||
if (out) {
|
||||
**out = '\0';
|
||||
}
|
||||
va_end(args);
|
||||
return pc;
|
||||
return limit - pc;
|
||||
}
|
||||
|
||||
int printf(const char *format, ...)
|
||||
@ -211,13 +211,13 @@ int printf(const char *format, ...)
|
||||
va_list args;
|
||||
|
||||
va_start(args, format);
|
||||
return print(0, format, args);
|
||||
return print(-1, 0, format, args);
|
||||
}
|
||||
|
||||
// TK: added for alternative parameter passing
|
||||
int vprintf(const char *format, va_list args)
|
||||
{
|
||||
return print(0, format, args);
|
||||
return print(-1, 0, format, args);
|
||||
}
|
||||
|
||||
int sprintf(char *out, const char *format, ...)
|
||||
@ -225,7 +225,7 @@ int sprintf(char *out, const char *format, ...)
|
||||
va_list args;
|
||||
|
||||
va_start(args, format);
|
||||
return print(&out, format, args);
|
||||
return print(-1, &out, format, args);
|
||||
}
|
||||
|
||||
// TK: added for alternative parameter passing
|
||||
@ -234,17 +234,22 @@ int vsprintf(char *out, const char *format, va_list args)
|
||||
char *_out;
|
||||
|
||||
_out = out;
|
||||
return print(&_out, format, args);
|
||||
return print(-1, &_out, format, args);
|
||||
}
|
||||
|
||||
int snprintf(char *buf, size_t count, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
(void)count;
|
||||
|
||||
va_start(args, format);
|
||||
return print(&buf, format, args);
|
||||
return print(count, &buf, format, args);
|
||||
}
|
||||
|
||||
// TK: added for alternative parameter passing
|
||||
int vsnprintf(char *buf, size_t count, const char *format, va_list args)
|
||||
{
|
||||
return print(count, &buf, format, args);
|
||||
}
|
||||
|
||||
/**
|
||||
|
121
flight/modules/Logging/Logging.c
Normal file
121
flight/modules/Logging/Logging.c
Normal file
@ -0,0 +1,121 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @addtogroup OpenPilotModules OpenPilot Modules
|
||||
* @{
|
||||
* @addtogroup LoggingModule Logging Module
|
||||
* @brief Features for on board logging
|
||||
* @{
|
||||
*
|
||||
* @file Logging.c
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2013.
|
||||
* @brief Logging module, provides features for on board logging
|
||||
* @see The GNU Public License (GPL) Version 3
|
||||
*
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
// ****************
|
||||
|
||||
#include "openpilot.h"
|
||||
#include "debuglogsettings.h"
|
||||
#include "debuglogcontrol.h"
|
||||
#include "debuglogstatus.h"
|
||||
#include "debuglogentry.h"
|
||||
#include "flightstatus.h"
|
||||
|
||||
// private variables
|
||||
static DebugLogSettingsData settings;
|
||||
static DebugLogControlData control;
|
||||
static DebugLogStatusData status;
|
||||
static DebugLogEntryData *entry; // would be better on stack but event dispatcher stack might be insufficient
|
||||
|
||||
// private functions
|
||||
static void SettingsUpdatedCb(UAVObjEvent *ev);
|
||||
static void ControlUpdatedCb(UAVObjEvent *ev);
|
||||
static void StatusUpdatedCb(UAVObjEvent *ev);
|
||||
|
||||
int32_t LoggingInitialize(void)
|
||||
{
|
||||
DebugLogSettingsInitialize();
|
||||
DebugLogControlInitialize();
|
||||
DebugLogStatusInitialize();
|
||||
DebugLogEntryInitialize();
|
||||
FlightStatusInitialize();
|
||||
PIOS_DEBUGLOG_Initialize();
|
||||
entry = pvPortMalloc(sizeof(DebugLogEntryData));
|
||||
if (!entry) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t LoggingStart(void)
|
||||
{
|
||||
DebugLogSettingsConnectCallback(SettingsUpdatedCb);
|
||||
DebugLogControlConnectCallback(ControlUpdatedCb);
|
||||
SettingsUpdatedCb(DebugLogSettingsHandle());
|
||||
|
||||
UAVObjEvent ev = { .obj = DebugLogSettingsHandle(), .instId = 0, .event = EV_UPDATED_PERIODIC };
|
||||
EventPeriodicCallbackCreate(&ev, StatusUpdatedCb, 1000);
|
||||
// invoke a periodic dispatcher callback - the event struct is a dummy, it could be filled with anything!
|
||||
StatusUpdatedCb(&ev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
MODULE_INITCALL(LoggingInitialize, LoggingStart);
|
||||
|
||||
static void StatusUpdatedCb(__attribute__((unused)) UAVObjEvent *ev)
|
||||
{
|
||||
PIOS_DEBUGLOG_Info(&status.Flight, &status.Entry, &status.FreeSlots, &status.UsedSlots);
|
||||
DebugLogStatusSet(&status);
|
||||
}
|
||||
|
||||
static void SettingsUpdatedCb(__attribute__((unused)) UAVObjEvent *ev)
|
||||
{
|
||||
DebugLogSettingsGet(&settings);
|
||||
PIOS_DEBUGLOG_Enable(settings.LoggingEnabled);
|
||||
PIOS_DEBUGLOG_Printf("Logging enabled");
|
||||
}
|
||||
|
||||
static void ControlUpdatedCb(__attribute__((unused)) UAVObjEvent *ev)
|
||||
{
|
||||
DebugLogControlGet(&control);
|
||||
if (control.Operation == DEBUGLOGCONTROL_OPERATION_RETRIEVE) {
|
||||
memset(entry, 0, sizeof(DebugLogEntryData));
|
||||
if (PIOS_DEBUGLOG_Read(entry, control.Flight, control.Entry) != 0) {
|
||||
// reading from log failed, mark as non existent in output
|
||||
entry->Flight = control.Flight;
|
||||
entry->Entry = control.Entry;
|
||||
entry->Type = DEBUGLOGENTRY_TYPE_EMPTY;
|
||||
}
|
||||
DebugLogEntrySet(entry);
|
||||
} else if (control.Operation == DEBUGLOGCONTROL_OPERATION_FORMATFLASH) {
|
||||
uint8_t armed;
|
||||
FlightStatusArmedGet(&armed);
|
||||
if (armed == FLIGHTSTATUS_ARMED_DISARMED) {
|
||||
PIOS_DEBUGLOG_Format();
|
||||
}
|
||||
}
|
||||
StatusUpdatedCb(ev);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
@ -88,6 +88,7 @@ static int32_t transmitData(uint8_t *data, int32_t length);
|
||||
static void registerObject(UAVObjHandle obj);
|
||||
static void updateObject(UAVObjHandle obj, int32_t eventType);
|
||||
static int32_t setUpdatePeriod(UAVObjHandle obj, int32_t updatePeriodMs);
|
||||
static int32_t setLoggingPeriod(UAVObjHandle obj, int32_t updatePeriodMs);
|
||||
static void processObjEvent(UAVObjEvent *ev);
|
||||
static void updateTelemetryStats();
|
||||
static void gcsTelemetryStatsUpdated();
|
||||
@ -180,22 +181,16 @@ static void registerObject(UAVObjHandle obj)
|
||||
UAVObjConnectQueue(obj, priorityQueue, EV_MASK_ALL_UPDATES);
|
||||
return;
|
||||
} else {
|
||||
UAVObjMetadata metadata;
|
||||
UAVObjUpdateMode updateMode;
|
||||
UAVObjGetMetadata(obj, &metadata);
|
||||
updateMode = UAVObjGetTelemetryUpdateMode(&metadata);
|
||||
// Setup object for periodic updates
|
||||
UAVObjEvent ev = {
|
||||
.obj = obj,
|
||||
.instId = UAVOBJ_ALL_INSTANCES,
|
||||
.event = EV_UPDATED_PERIODIC,
|
||||
};
|
||||
EventPeriodicQueueCreate(&ev, queue, 0);
|
||||
ev.event = EV_LOGGING_PERIODIC;
|
||||
EventPeriodicQueueCreate(&ev, queue, 0);
|
||||
|
||||
/* Only create a periodic event for objects that are periodic */
|
||||
if ((updateMode == UPDATEMODE_PERIODIC) ||
|
||||
(updateMode == UPDATEMODE_THROTTLED)) {
|
||||
// Setup object for periodic updates
|
||||
UAVObjEvent ev = {
|
||||
.obj = obj,
|
||||
.instId = UAVOBJ_ALL_INSTANCES,
|
||||
.event = EV_UPDATED_PERIODIC,
|
||||
};
|
||||
EventPeriodicQueueCreate(&ev, queue, 0);
|
||||
}
|
||||
|
||||
// Setup object for telemetry updates
|
||||
updateObject(obj, EV_NONE);
|
||||
@ -209,7 +204,7 @@ static void registerObject(UAVObjHandle obj)
|
||||
static void updateObject(UAVObjHandle obj, int32_t eventType)
|
||||
{
|
||||
UAVObjMetadata metadata;
|
||||
UAVObjUpdateMode updateMode;
|
||||
UAVObjUpdateMode updateMode, loggingMode;
|
||||
int32_t eventMask;
|
||||
|
||||
if (UAVObjIsMetaobject(obj)) {
|
||||
@ -222,46 +217,78 @@ static void updateObject(UAVObjHandle obj, int32_t eventType)
|
||||
|
||||
// Get metadata
|
||||
UAVObjGetMetadata(obj, &metadata);
|
||||
updateMode = UAVObjGetTelemetryUpdateMode(&metadata);
|
||||
updateMode = UAVObjGetTelemetryUpdateMode(&metadata);
|
||||
loggingMode = UAVObjGetLoggingUpdateMode(&metadata);
|
||||
|
||||
// Setup object depending on update mode
|
||||
eventMask = 0;
|
||||
switch (updateMode) {
|
||||
case UPDATEMODE_PERIODIC:
|
||||
// Set update period
|
||||
setUpdatePeriod(obj, metadata.telemetryUpdatePeriod);
|
||||
// Connect queue
|
||||
eventMask = EV_UPDATED_PERIODIC | EV_UPDATED_MANUAL | EV_UPDATE_REQ;
|
||||
UAVObjConnectQueue(obj, priorityQueue, eventMask);
|
||||
eventMask |= EV_UPDATED_PERIODIC | EV_UPDATED_MANUAL | EV_UPDATE_REQ;
|
||||
break;
|
||||
case UPDATEMODE_ONCHANGE:
|
||||
// Set update period
|
||||
setUpdatePeriod(obj, 0);
|
||||
// Connect queue
|
||||
eventMask = EV_UPDATED | EV_UPDATED_MANUAL | EV_UPDATE_REQ;
|
||||
UAVObjConnectQueue(obj, priorityQueue, eventMask);
|
||||
eventMask |= EV_UPDATED | EV_UPDATED_MANUAL | EV_UPDATE_REQ;
|
||||
break;
|
||||
case UPDATEMODE_THROTTLED:
|
||||
if ((eventType == EV_UPDATED_PERIODIC) || (eventType == EV_NONE)) {
|
||||
// If we received a periodic update, we can change back to update on change
|
||||
eventMask = EV_UPDATED | EV_UPDATED_MANUAL | EV_UPDATE_REQ;
|
||||
eventMask |= EV_UPDATED | EV_UPDATED_MANUAL | EV_UPDATE_REQ;
|
||||
// Set update period on initialization and metadata change
|
||||
if (eventType == EV_NONE) {
|
||||
setUpdatePeriod(obj, metadata.telemetryUpdatePeriod);
|
||||
}
|
||||
} else {
|
||||
// Otherwise, we just received an object update, so switch to periodic for the timeout period to prevent more updates
|
||||
eventMask = EV_UPDATED_PERIODIC | EV_UPDATED_MANUAL | EV_UPDATE_REQ;
|
||||
eventMask |= EV_UPDATED_PERIODIC | EV_UPDATED_MANUAL | EV_UPDATE_REQ;
|
||||
}
|
||||
UAVObjConnectQueue(obj, priorityQueue, eventMask);
|
||||
break;
|
||||
case UPDATEMODE_MANUAL:
|
||||
// Set update period
|
||||
setUpdatePeriod(obj, 0);
|
||||
// Connect queue
|
||||
eventMask = EV_UPDATED_MANUAL | EV_UPDATE_REQ;
|
||||
UAVObjConnectQueue(obj, priorityQueue, eventMask);
|
||||
eventMask |= EV_UPDATED_MANUAL | EV_UPDATE_REQ;
|
||||
break;
|
||||
}
|
||||
switch (loggingMode) {
|
||||
case UPDATEMODE_PERIODIC:
|
||||
// Set update period
|
||||
setLoggingPeriod(obj, metadata.loggingUpdatePeriod);
|
||||
// Connect queue
|
||||
eventMask |= EV_LOGGING_PERIODIC | EV_LOGGING_MANUAL;
|
||||
break;
|
||||
case UPDATEMODE_ONCHANGE:
|
||||
// Set update period
|
||||
setLoggingPeriod(obj, 0);
|
||||
// Connect queue
|
||||
eventMask |= EV_UPDATED | EV_LOGGING_MANUAL;
|
||||
break;
|
||||
case UPDATEMODE_THROTTLED:
|
||||
if ((eventType == EV_LOGGING_PERIODIC) || (eventType == EV_NONE)) {
|
||||
// If we received a periodic update, we can change back to update on change
|
||||
eventMask |= EV_UPDATED | EV_LOGGING_MANUAL;
|
||||
// Set update period on initialization and metadata change
|
||||
if (eventType == EV_NONE) {
|
||||
setLoggingPeriod(obj, metadata.loggingUpdatePeriod);
|
||||
}
|
||||
} else {
|
||||
// Otherwise, we just received an object update, so switch to periodic for the timeout period to prevent more updates
|
||||
eventMask |= EV_LOGGING_PERIODIC | EV_LOGGING_MANUAL;
|
||||
}
|
||||
break;
|
||||
case UPDATEMODE_MANUAL:
|
||||
// Set update period
|
||||
setLoggingPeriod(obj, 0);
|
||||
// Connect queue
|
||||
eventMask |= EV_LOGGING_MANUAL;
|
||||
break;
|
||||
}
|
||||
UAVObjConnectQueue(obj, priorityQueue, eventMask);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -288,7 +315,7 @@ static void processObjEvent(UAVObjEvent *ev)
|
||||
// Act on event
|
||||
retries = 0;
|
||||
success = -1;
|
||||
if (ev->event == EV_UPDATED || ev->event == EV_UPDATED_MANUAL || ((ev->event == EV_UPDATED_PERIODIC) && (updateMode != UPDATEMODE_THROTTLED))) {
|
||||
if ((ev->event == EV_UPDATED && (updateMode == UPDATEMODE_ONCHANGE || updateMode == UPDATEMODE_THROTTLED)) || ev->event == EV_UPDATED_MANUAL || ((ev->event == EV_UPDATED_PERIODIC) && (updateMode != UPDATEMODE_THROTTLED))) {
|
||||
// Send update to GCS (with retries)
|
||||
while (retries < MAX_RETRIES && success == -1) {
|
||||
success = UAVTalkSendObject(uavTalkCon, ev->obj, ev->instId, UAVObjGetTelemetryAcked(&metadata), REQ_TIMEOUT_MS); // call blocks until ack is received or timeout
|
||||
@ -321,6 +348,24 @@ static void processObjEvent(UAVObjEvent *ev)
|
||||
}
|
||||
}
|
||||
}
|
||||
// Log UAVObject if necessary
|
||||
if (ev->obj) {
|
||||
updateMode = UAVObjGetLoggingUpdateMode(&metadata);
|
||||
if ((ev->event == EV_UPDATED && (updateMode == UPDATEMODE_ONCHANGE || updateMode == UPDATEMODE_THROTTLED)) || ev->event == EV_LOGGING_MANUAL || ((ev->event == EV_LOGGING_PERIODIC) && (updateMode != UPDATEMODE_THROTTLED))) {
|
||||
if (ev->instId == UAVOBJ_ALL_INSTANCES) {
|
||||
success = UAVObjGetNumInstances(ev->obj);
|
||||
for (retries = 0; retries < success; retries++) {
|
||||
UAVObjInstanceWriteToLog(ev->obj, retries);
|
||||
}
|
||||
} else {
|
||||
UAVObjInstanceWriteToLog(ev->obj, ev->instId);
|
||||
}
|
||||
}
|
||||
if (updateMode == UPDATEMODE_THROTTLED) {
|
||||
// If this is UPDATEMODE_THROTTLED, the event mask changes on every event.
|
||||
updateObject(ev->obj, ev->event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -447,6 +492,24 @@ static int32_t setUpdatePeriod(UAVObjHandle obj, int32_t updatePeriodMs)
|
||||
return EventPeriodicQueueUpdate(&ev, queue, updatePeriodMs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set logging update period of object (it must be already setup for periodic updates)
|
||||
* \param[in] obj The object to update
|
||||
* \param[in] updatePeriodMs The update period in ms, if zero then periodic updates are disabled
|
||||
* \return 0 Success
|
||||
* \return -1 Failure
|
||||
*/
|
||||
static int32_t setLoggingPeriod(UAVObjHandle obj, int32_t updatePeriodMs)
|
||||
{
|
||||
UAVObjEvent ev;
|
||||
|
||||
// Add object for periodic updates
|
||||
ev.obj = obj;
|
||||
ev.instId = UAVOBJ_ALL_INSTANCES;
|
||||
ev.event = EV_LOGGING_PERIODIC;
|
||||
return EventPeriodicQueueUpdate(&ev, queue, updatePeriodMs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called each time the GCS telemetry stats object is updated.
|
||||
* Trigger a flight telemetry stats update if a connection is not
|
||||
|
224
flight/pios/common/pios_debuglog.c
Normal file
224
flight/pios/common/pios_debuglog.c
Normal file
@ -0,0 +1,224 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @addtogroup PIOS PIOS Core hardware abstraction layer
|
||||
* @{
|
||||
* @defgroup PIOS_DEBUGLOG Flash log debugging Functions
|
||||
* @brief Debugging functionality
|
||||
* @{
|
||||
*
|
||||
* @file pios_debuglog.c
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2013.
|
||||
* @brief Debugging Functions
|
||||
* @see The GNU Public License (GPL) Version 3
|
||||
*
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* Project Includes */
|
||||
#include "pios.h"
|
||||
#include "uavobjectmanager.h"
|
||||
#include "debuglogentry.h"
|
||||
|
||||
// global definitions
|
||||
|
||||
|
||||
// Global variables
|
||||
extern uintptr_t pios_user_fs_id; // flash filesystem for logging
|
||||
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
static xSemaphoreHandle mutex = 0;
|
||||
#define mutexlock() xSemaphoreTakeRecursive(mutex, portMAX_DELAY)
|
||||
#define mutexunlock() xSemaphoreGiveRecursive(mutex)
|
||||
#else
|
||||
#define mutexlock()
|
||||
#define mutexunlock()
|
||||
#endif
|
||||
|
||||
static bool logging_enabled = false;
|
||||
static uint16_t flightnum = 0;
|
||||
static uint16_t lognum = 0;
|
||||
static DebugLogEntryData *buffer = 0;
|
||||
#if !defined(PIOS_INCLUDE_FREERTOS)
|
||||
static DebugLogEntryData staticbuffer;
|
||||
#endif
|
||||
|
||||
/* Private Function Prototypes */
|
||||
|
||||
/**
|
||||
* @brief Initialize the log facility
|
||||
*/
|
||||
void PIOS_DEBUGLOG_Initialize()
|
||||
{
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
if (!mutex) {
|
||||
mutex = xSemaphoreCreateRecursiveMutex();
|
||||
buffer = pvPortMalloc(sizeof(DebugLogEntryData));
|
||||
}
|
||||
#else
|
||||
buffer = &staticbuffer;
|
||||
#endif
|
||||
if (!buffer) {
|
||||
return;
|
||||
}
|
||||
mutexlock();
|
||||
lognum = 0;
|
||||
flightnum = 0;
|
||||
while (PIOS_FLASHFS_ObjLoad(pios_user_fs_id, flightnum * 256, lognum, (uint8_t *)buffer, sizeof(DebugLogEntryData)) == 0) {
|
||||
flightnum++;
|
||||
}
|
||||
mutexunlock();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Enables or Disables logging globally
|
||||
* @param[in] enable or disable logging
|
||||
*/
|
||||
void PIOS_DEBUGLOG_Enable(uint8_t enabled)
|
||||
{
|
||||
logging_enabled = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write a debug log entry with a uavobject
|
||||
* @param[in] objectid
|
||||
* @param[in] instanceid
|
||||
* @param[in] instanceid
|
||||
* @param[in] size of object
|
||||
* @param[in] data buffer
|
||||
*/
|
||||
void PIOS_DEBUGLOG_UAVObject(uint32_t objid, uint16_t instid, size_t size, uint8_t *data)
|
||||
{
|
||||
if (!logging_enabled || !buffer) {
|
||||
return;
|
||||
}
|
||||
mutexlock();
|
||||
buffer->Flight = flightnum;
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
buffer->FlightTime = xTaskGetTickCount() * portTICK_RATE_MS;
|
||||
#else
|
||||
buffer->FlightTime = 0;
|
||||
#endif
|
||||
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, 0, 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) {
|
||||
lognum++;
|
||||
}
|
||||
mutexunlock();
|
||||
}
|
||||
/**
|
||||
* @brief Write a debug log entry with text
|
||||
* @param[in] format - as in printf
|
||||
* @param[in] variable arguments for printf
|
||||
* @param...
|
||||
*/
|
||||
void PIOS_DEBUGLOG_Printf(char *format, ...)
|
||||
{
|
||||
if (!logging_enabled || !buffer) {
|
||||
return;
|
||||
}
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
mutexlock();
|
||||
memset(buffer->Data, 0, sizeof(buffer->Data));
|
||||
vsnprintf((char *)buffer->Data, sizeof(buffer->Data), (char *)format, args);
|
||||
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_TEXT;
|
||||
buffer->ObjectID = 0;
|
||||
buffer->InstanceID = 0;
|
||||
buffer->Size = strlen((const char *)buffer->Data);
|
||||
|
||||
if (PIOS_FLASHFS_ObjSave(pios_user_fs_id, flightnum * 256, lognum, (uint8_t *)buffer, sizeof(DebugLogEntryData)) == 0) {
|
||||
lognum++;
|
||||
}
|
||||
mutexunlock();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Load one object instance from the filesystem
|
||||
* @param[out] buffer where to store the uavobject
|
||||
* @param[in] log entry from which flight
|
||||
* @param[in] log entry sequence number
|
||||
* @return 0 if success or error code
|
||||
* @retval -1 if fs_id is not a valid filesystem instance
|
||||
* @retval -2 if failed to start transaction
|
||||
* @retval -3 if object not found in filesystem
|
||||
* @retval -4 if object size in filesystem does not exactly match buffer size
|
||||
* @retval -5 if reading the object data from flash fails
|
||||
*/
|
||||
int32_t PIOS_DEBUGLOG_Read(void *mybuffer, uint16_t flight, uint16_t inst)
|
||||
{
|
||||
PIOS_Assert(mybuffer);
|
||||
return PIOS_FLASHFS_ObjLoad(pios_user_fs_id, flight * 256, inst, (uint8_t *)mybuffer, sizeof(DebugLogEntryData));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Retrieve run time info of logging system
|
||||
* @param[out] current flight number
|
||||
* @param[out] next entry number
|
||||
* @param[out] free slots in filesystem
|
||||
* @param[out] used slots in filesystem
|
||||
*/
|
||||
void PIOS_DEBUGLOG_Info(uint16_t *flight, uint16_t *entry, uint16_t *free, uint16_t *used)
|
||||
{
|
||||
if (flight) {
|
||||
*flight = flightnum;
|
||||
}
|
||||
if (entry) {
|
||||
*entry = lognum;
|
||||
}
|
||||
struct PIOS_FLASHFS_Stats stats = { 0, 0 };
|
||||
PIOS_FLASHFS_GetStats(pios_user_fs_id, &stats);
|
||||
if (free) {
|
||||
*free = stats.num_free_slots;
|
||||
}
|
||||
if (used) {
|
||||
*used = stats.num_active_slots;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Format entire flash memory!!!
|
||||
*/
|
||||
void PIOS_DEBUGLOG_Format(void)
|
||||
{
|
||||
mutexlock();
|
||||
PIOS_FLASHFS_Format(pios_user_fs_id);
|
||||
lognum = 0;
|
||||
flightnum = 0;
|
||||
mutexunlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
261
flight/pios/common/pios_dosfs_logfs.c
Normal file
261
flight/pios/common/pios_dosfs_logfs.c
Normal file
@ -0,0 +1,261 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file pios_dosfs_logfs.c
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2013.
|
||||
* @addtogroup PIOS PIOS Core hardware abstraction layer
|
||||
* @{
|
||||
* @brief Log Structured Filesystem wrapper implemented using dosfs
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
|
||||
#include "pios.h"
|
||||
|
||||
#ifdef PIOS_USE_SETTINGS_ON_SDCARD
|
||||
|
||||
#include <openpilot.h>
|
||||
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
static xSemaphoreHandle mutex = 0;
|
||||
#endif
|
||||
|
||||
struct flashfs_logfs_cfg;
|
||||
|
||||
|
||||
/**
|
||||
* Get an 8 character (plus extension) filename for the object.
|
||||
* @param[in] obj The object handle.
|
||||
* @param[in] instId The instance ID
|
||||
* @param[in] file Filename string pointer -- must be 14 bytes long and allocated
|
||||
*/
|
||||
static void objectFilename(uint32_t obj_id, uint16_t obj_inst_id, uint8_t *filename)
|
||||
{
|
||||
uint32_t prefix = obj_id + (obj_inst_id / 256) * 16; // put upper 8 bit of instance id into object id modification,
|
||||
// skip least sig nibble since that is used for meta object id
|
||||
uint8_t suffix = obj_inst_id & 0xff;
|
||||
|
||||
snprintf((char *)filename, 13, "%08X.o%02X", prefix, suffix);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Initialize the flash object setting FS
|
||||
* @return 0 if success, -1 if failure
|
||||
*/
|
||||
int32_t PIOS_FLASHFS_Logfs_Init(__attribute__((unused)) uintptr_t *fs_id, __attribute__((unused)) const struct flashfs_logfs_cfg *cfg, __attribute__((unused)) const struct pios_flash_driver *driver, __attribute__((unused)) uintptr_t flash_id)
|
||||
{
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
if (!mutex) {
|
||||
mutex = xSemaphoreCreateRecursiveMutex();
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t PIOS_FLASHFS_Logfs_Destroy(__attribute__((unused)) uintptr_t fs_id)
|
||||
{
|
||||
// stub, only wrapper for dosfs, does not need destroying
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**********************************
|
||||
*
|
||||
* Provide a PIOS_FLASHFS_* driver
|
||||
*
|
||||
*********************************/
|
||||
#include "pios_flashfs.h" /* API for flash filesystem */
|
||||
|
||||
/**
|
||||
* @brief Saves one object instance to the filesystem
|
||||
* @param[in] fs_id The filesystem to use for this action
|
||||
* @param[in] obj UAVObject ID of the object to save
|
||||
* @param[in] obj_inst_id The instance number of the object being saved
|
||||
* @param[in] obj_data Contents of the object being saved
|
||||
* @param[in] obj_size Size of the object being saved
|
||||
* @return 0 if success or error code
|
||||
* @retval -1 if fs_id is not a valid filesystem instance
|
||||
* @retval -2 if failed to start transaction
|
||||
* @retval -3 if failure to delete any previous versions of the object
|
||||
* @retval -4 if filesystem is entirely full and garbage collection won't help
|
||||
* @retval -5 if garbage collection failed
|
||||
* @retval -6 if filesystem is full even after garbage collection should have freed space
|
||||
* @retval -7 if writing the new object to the filesystem failed
|
||||
*/
|
||||
int32_t PIOS_FLASHFS_ObjSave(__attribute__((unused)) uintptr_t fs_id, uint32_t obj_id, uint16_t obj_inst_id, uint8_t *obj_data, uint16_t obj_size)
|
||||
{
|
||||
FILEINFO file;
|
||||
uint8_t filename[14];
|
||||
|
||||
if (PIOS_SDCARD_IsMounted() == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Lock
|
||||
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
#endif
|
||||
|
||||
// Get filename
|
||||
objectFilename(obj_id, obj_inst_id, filename);
|
||||
|
||||
// Open file
|
||||
if (PIOS_FOPEN_WRITE(filename, file)) {
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
#endif
|
||||
return -2;
|
||||
}
|
||||
// Append object
|
||||
uint32_t bytes_written = 0;
|
||||
PIOS_FWRITE(&file, obj_data, obj_size, &bytes_written);
|
||||
|
||||
// Done, close file and unlock
|
||||
PIOS_FCLOSE(file);
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
#endif
|
||||
|
||||
if (bytes_written != obj_size) {
|
||||
return -7;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Load one object instance from the filesystem
|
||||
* @param[in] fs_id The filesystem to use for this action
|
||||
* @param[in] obj UAVObject ID of the object to load
|
||||
* @param[in] obj_inst_id The instance of the object to load
|
||||
* @param[in] obj_data Buffer to hold the contents of the loaded object
|
||||
* @param[in] obj_size Size of the object to be loaded
|
||||
* @return 0 if success or error code
|
||||
* @retval -1 if fs_id is not a valid filesystem instance
|
||||
* @retval -2 if failed to start transaction
|
||||
* @retval -3 if object not found in filesystem
|
||||
* @retval -4 if object size in filesystem does not exactly match buffer size
|
||||
* @retval -5 if reading the object data from flash fails
|
||||
*/
|
||||
int32_t PIOS_FLASHFS_ObjLoad(__attribute__((unused)) uintptr_t fs_id, uint32_t obj_id, uint16_t obj_inst_id, uint8_t *obj_data, uint16_t obj_size)
|
||||
{
|
||||
FILEINFO file;
|
||||
uint8_t filename[14];
|
||||
|
||||
// Check for file system availability
|
||||
if (PIOS_SDCARD_IsMounted() == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
// Lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
#endif
|
||||
// Get filename
|
||||
objectFilename(obj_id, obj_inst_id, filename);
|
||||
|
||||
// Open file
|
||||
if (PIOS_FOPEN_READ(filename, file)) {
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
// Load object
|
||||
uint32_t bytes_read = 0;
|
||||
uint32_t result = PIOS_FREAD(&file, obj_data, obj_size, &bytes_read);
|
||||
|
||||
// Done, close file and unlock
|
||||
PIOS_FCLOSE(file);
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
#endif
|
||||
if (result != 0) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Delete one instance of an object from the filesystem
|
||||
* @param[in] fs_id The filesystem to use for this action
|
||||
* @param[in] obj UAVObject ID of the object to delete
|
||||
* @param[in] obj_inst_id The instance of the object to delete
|
||||
* @return 0 if success or error code
|
||||
* @retval -1 if fs_id is not a valid filesystem instance
|
||||
* @retval -2 if failed to start transaction
|
||||
* @retval -3 if failed to delete the object from the filesystem
|
||||
*/
|
||||
int32_t PIOS_FLASHFS_ObjDelete(__attribute__((unused)) uintptr_t fs_id, uint32_t obj_id, uint16_t obj_inst_id)
|
||||
{
|
||||
uint8_t filename[14];
|
||||
|
||||
// Check for file system availability
|
||||
if (PIOS_SDCARD_IsMounted() == 0) {
|
||||
return -1;
|
||||
}
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
// Lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
#endif
|
||||
// Get filename
|
||||
objectFilename(obj_id, obj_inst_id, filename);
|
||||
|
||||
// Delete file
|
||||
PIOS_FUNLINK(filename);
|
||||
|
||||
// Done
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Erases all filesystem arenas and activate the first arena
|
||||
* @param[in] fs_id The filesystem to use for this action
|
||||
* @return 0 if success or error code
|
||||
* @retval -1 if fs_id is not a valid filesystem instance
|
||||
* @retval -2 if failed to start transaction
|
||||
* @retval -3 if failed to erase all arenas
|
||||
* @retval -4 if failed to activate arena 0
|
||||
* @retval -5 if failed to mount arena 0
|
||||
*/
|
||||
int32_t PIOS_FLASHFS_Format(__attribute__((unused)) uintptr_t fs_id)
|
||||
{
|
||||
/* stub - not implemented */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returs stats for the filesystems
|
||||
* @param[in] fs_id The filesystem to use for this action
|
||||
* @return 0 if success or error code
|
||||
* @retval -1 if fs_id is not a valid filesystem instance
|
||||
*/
|
||||
int32_t PIOS_FLASHFS_GetStats(__attribute__((unused)) uintptr_t fs_id, __attribute__((unused)) struct PIOS_FLASHFS_Stats *stats)
|
||||
{
|
||||
/* stub - not implemented */
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* PIOS_USE_SETTINGS_ON_SDCARD */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
97
flight/pios/inc/pios_debuglog.h
Normal file
97
flight/pios/inc/pios_debuglog.h
Normal file
@ -0,0 +1,97 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @addtogroup PIOS PIOS Core hardware abstraction layer
|
||||
* @{
|
||||
* @defgroup PIOS_DEBUGLOG Flash log debugging Functions
|
||||
* @brief Debugging functionality
|
||||
* @{
|
||||
*
|
||||
* @file pios_debuglog.c
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2013.
|
||||
* @brief Debugging Functions
|
||||
* @see The GNU Public License (GPL) Version 3
|
||||
*
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef PIOS_DEBUGLOG_H
|
||||
#define PIOS_DEBUGLOG_H
|
||||
|
||||
|
||||
/**
|
||||
* @brief Initialize the log facility
|
||||
*/
|
||||
void PIOS_DEBUGLOG_Initialize();
|
||||
|
||||
/**
|
||||
* @brief Enables or Disables logging globally
|
||||
* @param[in] enable or disable logging
|
||||
*/
|
||||
void PIOS_DEBUGLOG_Enable(uint8_t enabled);
|
||||
|
||||
/**
|
||||
* @brief Write a debug log entry with a uavobject
|
||||
* @param[in] objectid
|
||||
* @param[in] instanceid
|
||||
* @param[in] instanceid
|
||||
* @param[in] size of object
|
||||
* @param[in] data buffer
|
||||
*/
|
||||
void PIOS_DEBUGLOG_UAVObject(uint32_t objid, uint16_t instid, size_t size, uint8_t *data);
|
||||
|
||||
/**
|
||||
* @brief Write a debug log entry with text
|
||||
* @param[in] format - as in printf
|
||||
* @param[in] variable arguments for printf
|
||||
* @param...
|
||||
*/
|
||||
void PIOS_DEBUGLOG_Printf(char *format, ...);
|
||||
|
||||
/**
|
||||
* @brief Load one object instance from the filesystem
|
||||
* @param[out] buffer where to store the uavobject
|
||||
* @param[in] log entry from which flight
|
||||
* @param[in] log entry sequence number
|
||||
* @return 0 if success or error code
|
||||
* @retval -1 if fs_id is not a valid filesystem instance
|
||||
* @retval -2 if failed to start transaction
|
||||
* @retval -3 if object not found in filesystem
|
||||
* @retval -4 if object size in filesystem does not exactly match buffer size
|
||||
* @retval -5 if reading the object data from flash fails
|
||||
*/
|
||||
int32_t PIOS_DEBUGLOG_Read(void *buffer, uint16_t flight, uint16_t inst);
|
||||
|
||||
/**
|
||||
* @brief Retrieve run time info of logging system
|
||||
* @param[out] current flight number
|
||||
* @param[out] next entry number
|
||||
* @param[out] free slots in filesystem
|
||||
* @param[out] used slots in filesystem
|
||||
*/
|
||||
void PIOS_DEBUGLOG_Info(uint16_t *flight, uint16_t *entry, uint16_t *free, uint16_t *used);
|
||||
|
||||
/**
|
||||
* @brief Format entire flash memory!!!
|
||||
*/
|
||||
void PIOS_DEBUGLOG_Format(void);
|
||||
|
||||
#endif // ifndef PIOS_DEBUGLOG_H
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
@ -69,6 +69,7 @@
|
||||
/* #define DEBUG_LEVEL 0 */
|
||||
/* #define PIOS_ENABLE_DEBUG_PINS */
|
||||
#include <pios_debug.h>
|
||||
#include <pios_debuglog.h>
|
||||
|
||||
/* PIOS common functions */
|
||||
#include <pios_crc.h>
|
||||
|
@ -78,8 +78,11 @@ extern void PIOS_LED_Init(void);
|
||||
#include <pios_servo.h>
|
||||
#include <pios_wdg.h>
|
||||
#include <pios_debug.h>
|
||||
#include <pios_debuglog.h>
|
||||
#include <pios_crc.h>
|
||||
#include <pios_rcvr.h>
|
||||
#include <pios_flash.h>
|
||||
#include <pios_flashfs.h>
|
||||
|
||||
#if defined(PIOS_INCLUDE_IAP)
|
||||
#include <pios_iap.h>
|
||||
|
224
flight/pios/posix/pios_debuglog.c
Normal file
224
flight/pios/posix/pios_debuglog.c
Normal file
@ -0,0 +1,224 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @addtogroup PIOS PIOS Core hardware abstraction layer
|
||||
* @{
|
||||
* @defgroup PIOS_DEBUGLOG Flash log debugging Functions
|
||||
* @brief Debugging functionality
|
||||
* @{
|
||||
*
|
||||
* @file pios_debuglog.c
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2013.
|
||||
* @brief Debugging Functions
|
||||
* @see The GNU Public License (GPL) Version 3
|
||||
*
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* Project Includes */
|
||||
#include "pios.h"
|
||||
#include "uavobjectmanager.h"
|
||||
#include "debuglogentry.h"
|
||||
|
||||
// global definitions
|
||||
|
||||
|
||||
// Global variables
|
||||
extern uintptr_t pios_user_fs_id; // flash filesystem for logging
|
||||
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
static xSemaphoreHandle mutex = 0;
|
||||
#define mutexlock() xSemaphoreTakeRecursive(mutex, portMAX_DELAY)
|
||||
#define mutexunlock() xSemaphoreGiveRecursive(mutex)
|
||||
#else
|
||||
#define mutexlock()
|
||||
#define mutexunlock()
|
||||
#endif
|
||||
|
||||
static bool logging_enabled = false;
|
||||
static uint16_t flightnum = 0;
|
||||
static uint16_t lognum = 0;
|
||||
static DebugLogEntryData *buffer = 0;
|
||||
#if !defined(PIOS_INCLUDE_FREERTOS)
|
||||
static DebugLogEntryData staticbuffer;
|
||||
#endif
|
||||
|
||||
/* Private Function Prototypes */
|
||||
|
||||
/**
|
||||
* @brief Initialize the log facility
|
||||
*/
|
||||
void PIOS_DEBUGLOG_Initialize()
|
||||
{
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
if (!mutex) {
|
||||
mutex = xSemaphoreCreateRecursiveMutex();
|
||||
buffer = pvPortMalloc(sizeof(DebugLogEntryData));
|
||||
}
|
||||
#else
|
||||
buffer = &staticbuffer;
|
||||
#endif
|
||||
if (!buffer) {
|
||||
return;
|
||||
}
|
||||
mutexlock();
|
||||
lognum = 0;
|
||||
flightnum = 0;
|
||||
while (PIOS_FLASHFS_ObjLoad(pios_user_fs_id, flightnum * 256, lognum, (uint8_t *)buffer, sizeof(DebugLogEntryData)) == 0) {
|
||||
flightnum++;
|
||||
}
|
||||
mutexunlock();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Enables or Disables logging globally
|
||||
* @param[in] enable or disable logging
|
||||
*/
|
||||
void PIOS_DEBUGLOG_Enable(uint8_t enabled)
|
||||
{
|
||||
logging_enabled = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write a debug log entry with a uavobject
|
||||
* @param[in] objectid
|
||||
* @param[in] instanceid
|
||||
* @param[in] instanceid
|
||||
* @param[in] size of object
|
||||
* @param[in] data buffer
|
||||
*/
|
||||
void PIOS_DEBUGLOG_UAVObject(uint32_t objid, uint16_t instid, size_t size, uint8_t *data)
|
||||
{
|
||||
if (!logging_enabled || !buffer) {
|
||||
return;
|
||||
}
|
||||
mutexlock();
|
||||
buffer->Flight = flightnum;
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
buffer->FlightTime = xTaskGetTickCount() * portTICK_RATE_MS;
|
||||
#else
|
||||
buffer->FlightTime = 0;
|
||||
#endif
|
||||
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, 0, 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) {
|
||||
lognum++;
|
||||
}
|
||||
mutexunlock();
|
||||
}
|
||||
/**
|
||||
* @brief Write a debug log entry with text
|
||||
* @param[in] format - as in printf
|
||||
* @param[in] variable arguments for printf
|
||||
* @param...
|
||||
*/
|
||||
void PIOS_DEBUGLOG_Printf(char *format, ...)
|
||||
{
|
||||
if (!logging_enabled || !buffer) {
|
||||
return;
|
||||
}
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
mutexlock();
|
||||
memset(buffer->Data, 0, sizeof(buffer->Data));
|
||||
vsnprintf((char *)buffer->Data, sizeof(buffer->Data), (char *)format, args);
|
||||
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_TEXT;
|
||||
buffer->ObjectID = 0;
|
||||
buffer->InstanceID = 0;
|
||||
buffer->Size = strlen((const char *)buffer->Data);
|
||||
|
||||
if (PIOS_FLASHFS_ObjSave(pios_user_fs_id, flightnum * 256, lognum, (uint8_t *)buffer, sizeof(DebugLogEntryData)) == 0) {
|
||||
lognum++;
|
||||
}
|
||||
mutexunlock();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Load one object instance from the filesystem
|
||||
* @param[out] buffer where to store the uavobject
|
||||
* @param[in] log entry from which flight
|
||||
* @param[in] log entry sequence number
|
||||
* @return 0 if success or error code
|
||||
* @retval -1 if fs_id is not a valid filesystem instance
|
||||
* @retval -2 if failed to start transaction
|
||||
* @retval -3 if object not found in filesystem
|
||||
* @retval -4 if object size in filesystem does not exactly match buffer size
|
||||
* @retval -5 if reading the object data from flash fails
|
||||
*/
|
||||
int32_t PIOS_DEBUGLOG_Read(void *mybuffer, uint16_t flight, uint16_t inst)
|
||||
{
|
||||
PIOS_Assert(mybuffer);
|
||||
return PIOS_FLASHFS_ObjLoad(pios_user_fs_id, flight * 256, inst, (uint8_t *)mybuffer, sizeof(DebugLogEntryData));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Retrieve run time info of logging system
|
||||
* @param[out] current flight number
|
||||
* @param[out] next entry number
|
||||
* @param[out] free slots in filesystem
|
||||
* @param[out] used slots in filesystem
|
||||
*/
|
||||
void PIOS_DEBUGLOG_Info(uint16_t *flight, uint16_t *entry, uint16_t *free, uint16_t *used)
|
||||
{
|
||||
if (flight) {
|
||||
*flight = flightnum;
|
||||
}
|
||||
if (entry) {
|
||||
*entry = lognum;
|
||||
}
|
||||
struct PIOS_FLASHFS_Stats stats = { 0, 0 };
|
||||
PIOS_FLASHFS_GetStats(pios_user_fs_id, &stats);
|
||||
if (free) {
|
||||
*free = stats.num_free_slots;
|
||||
}
|
||||
if (used) {
|
||||
*used = stats.num_active_slots;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Format entire flash memory!!!
|
||||
*/
|
||||
void PIOS_DEBUGLOG_Format(void)
|
||||
{
|
||||
mutexlock();
|
||||
PIOS_FLASHFS_Format(pios_user_fs_id);
|
||||
lognum = 0;
|
||||
flightnum = 0;
|
||||
mutexunlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
261
flight/pios/posix/pios_dosfs_logfs.c
Normal file
261
flight/pios/posix/pios_dosfs_logfs.c
Normal file
@ -0,0 +1,261 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file pios_dosfs_logfs.c
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2013.
|
||||
* @addtogroup PIOS PIOS Core hardware abstraction layer
|
||||
* @{
|
||||
* @brief Log Structured Filesystem wrapper implemented using dosfs
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
|
||||
#include "pios.h"
|
||||
|
||||
#ifdef PIOS_USE_SETTINGS_ON_SDCARD
|
||||
|
||||
#include <openpilot.h>
|
||||
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
static xSemaphoreHandle mutex = 0;
|
||||
#endif
|
||||
|
||||
struct flashfs_logfs_cfg;
|
||||
|
||||
|
||||
/**
|
||||
* Get an 8 character (plus extension) filename for the object.
|
||||
* @param[in] obj The object handle.
|
||||
* @param[in] instId The instance ID
|
||||
* @param[in] file Filename string pointer -- must be 14 bytes long and allocated
|
||||
*/
|
||||
static void objectFilename(uint32_t obj_id, uint16_t obj_inst_id, uint8_t *filename)
|
||||
{
|
||||
uint32_t prefix = obj_id + (obj_inst_id / 256) * 16; // put upper 8 bit of instance id into object id modification,
|
||||
// skip least sig nibble since that is used for meta object id
|
||||
uint8_t suffix = obj_inst_id & 0xff;
|
||||
|
||||
snprintf((char *)filename, 13, "%08X.o%02X", prefix, suffix);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Initialize the flash object setting FS
|
||||
* @return 0 if success, -1 if failure
|
||||
*/
|
||||
int32_t PIOS_FLASHFS_Logfs_Init(__attribute__((unused)) uintptr_t *fs_id, __attribute__((unused)) const struct flashfs_logfs_cfg *cfg, __attribute__((unused)) const struct pios_flash_driver *driver, __attribute__((unused)) uintptr_t flash_id)
|
||||
{
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
if (!mutex) {
|
||||
mutex = xSemaphoreCreateRecursiveMutex();
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t PIOS_FLASHFS_Logfs_Destroy(__attribute__((unused)) uintptr_t fs_id)
|
||||
{
|
||||
// stub, only wrapper for dosfs, does not need destroying
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**********************************
|
||||
*
|
||||
* Provide a PIOS_FLASHFS_* driver
|
||||
*
|
||||
*********************************/
|
||||
#include "pios_flashfs.h" /* API for flash filesystem */
|
||||
|
||||
/**
|
||||
* @brief Saves one object instance to the filesystem
|
||||
* @param[in] fs_id The filesystem to use for this action
|
||||
* @param[in] obj UAVObject ID of the object to save
|
||||
* @param[in] obj_inst_id The instance number of the object being saved
|
||||
* @param[in] obj_data Contents of the object being saved
|
||||
* @param[in] obj_size Size of the object being saved
|
||||
* @return 0 if success or error code
|
||||
* @retval -1 if fs_id is not a valid filesystem instance
|
||||
* @retval -2 if failed to start transaction
|
||||
* @retval -3 if failure to delete any previous versions of the object
|
||||
* @retval -4 if filesystem is entirely full and garbage collection won't help
|
||||
* @retval -5 if garbage collection failed
|
||||
* @retval -6 if filesystem is full even after garbage collection should have freed space
|
||||
* @retval -7 if writing the new object to the filesystem failed
|
||||
*/
|
||||
int32_t PIOS_FLASHFS_ObjSave(__attribute__((unused)) uintptr_t fs_id, uint32_t obj_id, uint16_t obj_inst_id, uint8_t *obj_data, uint16_t obj_size)
|
||||
{
|
||||
FILEINFO file;
|
||||
uint8_t filename[14];
|
||||
|
||||
if (PIOS_SDCARD_IsMounted() == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Lock
|
||||
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
#endif
|
||||
|
||||
// Get filename
|
||||
objectFilename(obj_id, obj_inst_id, filename);
|
||||
|
||||
// Open file
|
||||
if (PIOS_FOPEN_WRITE(filename, file)) {
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
#endif
|
||||
return -2;
|
||||
}
|
||||
// Append object
|
||||
uint32_t bytes_written = 0;
|
||||
PIOS_FWRITE(&file, obj_data, obj_size, &bytes_written);
|
||||
|
||||
// Done, close file and unlock
|
||||
PIOS_FCLOSE(file);
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
#endif
|
||||
|
||||
if (bytes_written != obj_size) {
|
||||
return -7;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Load one object instance from the filesystem
|
||||
* @param[in] fs_id The filesystem to use for this action
|
||||
* @param[in] obj UAVObject ID of the object to load
|
||||
* @param[in] obj_inst_id The instance of the object to load
|
||||
* @param[in] obj_data Buffer to hold the contents of the loaded object
|
||||
* @param[in] obj_size Size of the object to be loaded
|
||||
* @return 0 if success or error code
|
||||
* @retval -1 if fs_id is not a valid filesystem instance
|
||||
* @retval -2 if failed to start transaction
|
||||
* @retval -3 if object not found in filesystem
|
||||
* @retval -4 if object size in filesystem does not exactly match buffer size
|
||||
* @retval -5 if reading the object data from flash fails
|
||||
*/
|
||||
int32_t PIOS_FLASHFS_ObjLoad(__attribute__((unused)) uintptr_t fs_id, uint32_t obj_id, uint16_t obj_inst_id, uint8_t *obj_data, uint16_t obj_size)
|
||||
{
|
||||
FILEINFO file;
|
||||
uint8_t filename[14];
|
||||
|
||||
// Check for file system availability
|
||||
if (PIOS_SDCARD_IsMounted() == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
// Lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
#endif
|
||||
// Get filename
|
||||
objectFilename(obj_id, obj_inst_id, filename);
|
||||
|
||||
// Open file
|
||||
if (PIOS_FOPEN_READ(filename, file)) {
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
// Load object
|
||||
uint32_t bytes_read = 0;
|
||||
uint32_t result = PIOS_FREAD(&file, obj_data, obj_size, &bytes_read);
|
||||
|
||||
// Done, close file and unlock
|
||||
PIOS_FCLOSE(file);
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
#endif
|
||||
if (result != 0) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Delete one instance of an object from the filesystem
|
||||
* @param[in] fs_id The filesystem to use for this action
|
||||
* @param[in] obj UAVObject ID of the object to delete
|
||||
* @param[in] obj_inst_id The instance of the object to delete
|
||||
* @return 0 if success or error code
|
||||
* @retval -1 if fs_id is not a valid filesystem instance
|
||||
* @retval -2 if failed to start transaction
|
||||
* @retval -3 if failed to delete the object from the filesystem
|
||||
*/
|
||||
int32_t PIOS_FLASHFS_ObjDelete(__attribute__((unused)) uintptr_t fs_id, uint32_t obj_id, uint16_t obj_inst_id)
|
||||
{
|
||||
uint8_t filename[14];
|
||||
|
||||
// Check for file system availability
|
||||
if (PIOS_SDCARD_IsMounted() == 0) {
|
||||
return -1;
|
||||
}
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
// Lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
#endif
|
||||
// Get filename
|
||||
objectFilename(obj_id, obj_inst_id, filename);
|
||||
|
||||
// Delete file
|
||||
PIOS_FUNLINK(filename);
|
||||
|
||||
// Done
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Erases all filesystem arenas and activate the first arena
|
||||
* @param[in] fs_id The filesystem to use for this action
|
||||
* @return 0 if success or error code
|
||||
* @retval -1 if fs_id is not a valid filesystem instance
|
||||
* @retval -2 if failed to start transaction
|
||||
* @retval -3 if failed to erase all arenas
|
||||
* @retval -4 if failed to activate arena 0
|
||||
* @retval -5 if failed to mount arena 0
|
||||
*/
|
||||
int32_t PIOS_FLASHFS_Format(__attribute__((unused)) uintptr_t fs_id)
|
||||
{
|
||||
/* stub - not implemented */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returs stats for the filesystems
|
||||
* @param[in] fs_id The filesystem to use for this action
|
||||
* @return 0 if success or error code
|
||||
* @retval -1 if fs_id is not a valid filesystem instance
|
||||
*/
|
||||
int32_t PIOS_FLASHFS_GetStats(__attribute__((unused)) uintptr_t fs_id, __attribute__((unused)) struct PIOS_FLASHFS_Stats *stats)
|
||||
{
|
||||
/* stub - not implemented */
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* PIOS_USE_SETTINGS_ON_SDCARD */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
@ -157,7 +157,7 @@
|
||||
#define PIOS_MANUAL_STACK_SIZE 800
|
||||
#define PIOS_SYSTEM_STACK_SIZE 660
|
||||
#define PIOS_STABILIZATION_STACK_SIZE 524
|
||||
#define PIOS_TELEM_STACK_SIZE 500
|
||||
#define PIOS_TELEM_STACK_SIZE 800
|
||||
#define PIOS_EVENTDISPATCHER_STACK_SIZE 130
|
||||
|
||||
/* This can't be too high to stop eventdispatcher thread overflowing */
|
||||
|
@ -157,7 +157,7 @@
|
||||
#define PIOS_MANUAL_STACK_SIZE 724
|
||||
#define PIOS_SYSTEM_STACK_SIZE 460
|
||||
#define PIOS_STABILIZATION_STACK_SIZE 524
|
||||
#define PIOS_TELEM_STACK_SIZE 500
|
||||
#define PIOS_TELEM_STACK_SIZE 800
|
||||
#define PIOS_EVENTDISPATCHER_STACK_SIZE 130
|
||||
|
||||
/* This can't be too high to stop eventdispatcher thread overflowing */
|
||||
|
@ -68,7 +68,7 @@ ifndef TESTAPP
|
||||
#endif
|
||||
|
||||
## Misc library functions
|
||||
SRC += $(FLIGHTLIB)/printf2.c
|
||||
#SRC += $(FLIGHTLIB)/printf2.c
|
||||
SRC += $(FLIGHTLIB)/WorldMagModel.c
|
||||
|
||||
## UAVObjects
|
||||
|
@ -102,7 +102,7 @@
|
||||
// TELEMETRY
|
||||
// ------------------------
|
||||
#define TELEM_QUEUE_SIZE 20
|
||||
#define PIOS_TELEM_STACK_SIZE 624
|
||||
#define PIOS_TELEM_STACK_SIZE 800
|
||||
|
||||
// *****************************************************************
|
||||
// Interrupt Priorities
|
||||
|
@ -682,12 +682,12 @@ const struct pios_rfm22b_cfg *PIOS_BOARD_HW_DEFS_GetRfm22Cfg(uint32_t board_revi
|
||||
#include "pios_flash_internal_priv.h"
|
||||
|
||||
static const struct flashfs_logfs_cfg flashfs_external_user_cfg = {
|
||||
.fs_magic = 0x99abcdef,
|
||||
.fs_magic = 0x99abceff,
|
||||
.total_fs_size = 0x001C0000, /* 2M bytes (32 sectors = entire chip) */
|
||||
.arena_size = 0x00010000, /* 256 * slot size */
|
||||
.arena_size = 0x000E0000, /* biggest possible arena size fssize/2 */
|
||||
.slot_size = 0x00000100, /* 256 bytes */
|
||||
|
||||
.start_offset = 0x40000, /* start offset */
|
||||
.start_offset = 0x00040000, /* start offset */
|
||||
.sector_size = 0x00010000, /* 64K bytes */
|
||||
.page_size = 0x00000100, /* 256 bytes */
|
||||
};
|
||||
|
@ -47,6 +47,7 @@ MODULES += Radio
|
||||
MODULES += PathPlanner
|
||||
MODULES += FixedWingPathFollower
|
||||
MODULES += Osd/osdoutout
|
||||
MODULES += Logging
|
||||
MODULES += Telemetry
|
||||
|
||||
OPTMODULES += ComUsbBridge
|
||||
|
@ -36,6 +36,10 @@ UAVOBJSRCFILENAMES += barosensor
|
||||
UAVOBJSRCFILENAMES += airspeedsensor
|
||||
UAVOBJSRCFILENAMES += airspeedsettings
|
||||
UAVOBJSRCFILENAMES += airspeedstate
|
||||
UAVOBJSRCFILENAMES += debuglogsettings
|
||||
UAVOBJSRCFILENAMES += debuglogcontrol
|
||||
UAVOBJSRCFILENAMES += debuglogstatus
|
||||
UAVOBJSRCFILENAMES += debuglogentry
|
||||
UAVOBJSRCFILENAMES += flightbatterysettings
|
||||
UAVOBJSRCFILENAMES += firmwareiapobj
|
||||
UAVOBJSRCFILENAMES += flightbatterystate
|
||||
|
@ -177,7 +177,7 @@ extern uint32_t pios_packet_handler;
|
||||
// TELEMETRY
|
||||
// ------------------------
|
||||
#define TELEM_QUEUE_SIZE 80
|
||||
#define PIOS_TELEM_STACK_SIZE 624
|
||||
#define PIOS_TELEM_STACK_SIZE 800
|
||||
|
||||
// -------------------------
|
||||
// System Settings
|
||||
|
@ -139,7 +139,7 @@ extern uint32_t pios_com_hkosd_id;
|
||||
// TELEMETRY
|
||||
// ------------------------
|
||||
#define TELEM_QUEUE_SIZE 80
|
||||
#define PIOS_TELEM_STACK_SIZE 624
|
||||
#define PIOS_TELEM_STACK_SIZE 800
|
||||
|
||||
// -------------------------
|
||||
// System Settings
|
||||
|
@ -69,3 +69,7 @@ const struct pios_udp_cfg pios_udp_aux_cfg = {
|
||||
#include <pios_com_priv.h>
|
||||
|
||||
#endif /* PIOS_INCLUDE_COM */
|
||||
|
||||
#if defined(PIOS_INCLUDE_FLASH)
|
||||
#include "pios_flashfs_logfs_priv.h"
|
||||
#endif
|
||||
|
@ -37,6 +37,7 @@ MODULES += FixedWingPathFollower
|
||||
MODULES += VtolPathFollower
|
||||
MODULES += CameraStab
|
||||
MODULES += Telemetry
|
||||
MODULES += Logging
|
||||
MODULES += FirmwareIAP
|
||||
MODULES += StateEstimation
|
||||
#MODULES += Sensors/simulated/Sensors
|
||||
|
@ -42,6 +42,10 @@ UAVOBJSRCFILENAMES += barosensor
|
||||
UAVOBJSRCFILENAMES += airspeedsensor
|
||||
UAVOBJSRCFILENAMES += airspeedsettings
|
||||
UAVOBJSRCFILENAMES += airspeedstate
|
||||
UAVOBJSRCFILENAMES += debuglogsettings
|
||||
UAVOBJSRCFILENAMES += debuglogcontrol
|
||||
UAVOBJSRCFILENAMES += debuglogstatus
|
||||
UAVOBJSRCFILENAMES += debuglogentry
|
||||
UAVOBJSRCFILENAMES += flightbatterysettings
|
||||
UAVOBJSRCFILENAMES += firmwareiapobj
|
||||
UAVOBJSRCFILENAMES += flightbatterystate
|
||||
|
@ -75,6 +75,7 @@ uint32_t pios_com_telem_rf_id = 0;
|
||||
uint32_t pios_com_bridge_id = 0;
|
||||
|
||||
uintptr_t pios_uavo_settings_fs_id;
|
||||
uintptr_t pios_user_fs_id;
|
||||
|
||||
/*
|
||||
* Setup a com port based on the passed cfg, driver and buffer sizes. tx size of -1 make the port rx only
|
||||
@ -118,6 +119,13 @@ void PIOS_Board_Init(void)
|
||||
/* Delay system */
|
||||
PIOS_DELAY_Init();
|
||||
|
||||
// Initialize dosfs fake flash logfs
|
||||
if (PIOS_FLASHFS_Logfs_Init(&pios_uavo_settings_fs_id, NULL, NULL, 0)) {
|
||||
PIOS_DEBUG_Assert(0);
|
||||
}
|
||||
pios_user_fs_id = pios_uavo_settings_fs_id;
|
||||
|
||||
|
||||
/* Initialize the task monitor */
|
||||
if (PIOS_TASK_MONITOR_Initialize(TASKINFO_RUNNING_NUMELEM)) {
|
||||
PIOS_Assert(0);
|
||||
|
@ -79,6 +79,8 @@ static inline void $(NAME)RequestUpdate() { UAVObjRequestUpdate($(NAME)Handle())
|
||||
static inline void $(NAME)RequestInstUpdate(uint16_t instId) { UAVObjRequestInstanceUpdate($(NAME)Handle(), instId); }
|
||||
static inline void $(NAME)Updated() { UAVObjUpdated($(NAME)Handle()); }
|
||||
static inline void $(NAME)InstUpdated(uint16_t instId) { UAVObjInstanceUpdated($(NAME)Handle(), instId); }
|
||||
static inline void $(NAME)Logging() { UAVObjLogging($(NAME)Handle()); }
|
||||
static inline void $(NAME)InstLogging(uint16_t instId) { UAVObjInstanceLogging($(NAME)Handle(), instId); }
|
||||
static inline int32_t $(NAME)GetMetadata(UAVObjMetadata *dataOut) { return UAVObjGetMetadata($(NAME)Handle(), dataOut); }
|
||||
static inline int32_t $(NAME)SetMetadata(const UAVObjMetadata *dataIn) { return UAVObjSetMetadata($(NAME)Handle(), dataIn); }
|
||||
static inline int8_t $(NAME)ReadOnly() { return UAVObjReadOnly($(NAME)Handle()); }
|
||||
|
@ -44,6 +44,7 @@
|
||||
#define UAVOBJ_GCS_TELEMETRY_ACKED_SHIFT 3
|
||||
#define UAVOBJ_TELEMETRY_UPDATE_MODE_SHIFT 4
|
||||
#define UAVOBJ_GCS_TELEMETRY_UPDATE_MODE_SHIFT 6
|
||||
#define UAVOBJ_LOGGING_UPDATE_MODE_SHIFT 8
|
||||
#define UAVOBJ_UPDATE_MODE_MASK 0x3
|
||||
|
||||
typedef void *UAVObjHandle;
|
||||
@ -73,9 +74,10 @@ typedef enum {
|
||||
* 3 gcsTelemetryAcked Defines if an ack is required for the transactions of this object (1:acked, 0:not acked)
|
||||
* 4-5 telemetryUpdateMode Update mode used by the telemetry module (UAVObjUpdateMode)
|
||||
* 6-7 gcsTelemetryUpdateMode Update mode used by the GCS (UAVObjUpdateMode)
|
||||
* 8-9 loggingUpdateMode Update mode used by the logging module (UAVObjUpdateMode)
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t flags; /** Defines flags for update and logging modes and whether an update should be ACK'd (bits defined above) */
|
||||
uint16_t flags; /** Defines flags for update and logging modes and whether an update should be ACK'd (bits defined above) */
|
||||
uint16_t telemetryUpdatePeriod; /** Update period used by the telemetry module (only if telemetry mode is PERIODIC) */
|
||||
uint16_t gcsTelemetryUpdatePeriod; /** Update period used by the GCS (only if telemetry mode is PERIODIC) */
|
||||
uint16_t loggingUpdatePeriod; /** Update period used by the logging module (only if logging mode is PERIODIC) */
|
||||
@ -85,19 +87,21 @@ typedef struct {
|
||||
* Event types generated by the objects.
|
||||
*/
|
||||
typedef enum {
|
||||
EV_NONE = 0x00, /** No event */
|
||||
EV_UNPACKED = 0x01, /** Object data updated by unpacking */
|
||||
EV_UPDATED = 0x02, /** Object data updated by changing the data structure */
|
||||
EV_NONE = 0x00, /** No event */
|
||||
EV_UNPACKED = 0x01, /** Object data updated by unpacking */
|
||||
EV_UPDATED = 0x02, /** Object data updated by changing the data structure */
|
||||
EV_UPDATED_MANUAL = 0x04, /** Object update event manually generated */
|
||||
EV_UPDATED_PERIODIC = 0x08, /** Object update from periodic event */
|
||||
EV_UPDATE_REQ = 0x10 /** Request to update object data */
|
||||
EV_LOGGING_MANUAL = 0x10, /** Object update event manually generated */
|
||||
EV_LOGGING_PERIODIC = 0x20, /** Object update from periodic event */
|
||||
EV_UPDATE_REQ = 0x40 /** Request to update object data */
|
||||
} UAVObjEventType;
|
||||
|
||||
/**
|
||||
* Helper macros for event masks
|
||||
*/
|
||||
#define EV_MASK_ALL 0
|
||||
#define EV_MASK_ALL_UPDATES (EV_UNPACKED | EV_UPDATED | EV_UPDATED_MANUAL | EV_UPDATED_PERIODIC)
|
||||
#define EV_MASK_ALL_UPDATES (EV_UNPACKED | EV_UPDATED | EV_UPDATED_MANUAL | EV_UPDATED_PERIODIC | EV_LOGGING_MANUAL | EV_LOGGING_PERIODIC)
|
||||
|
||||
/**
|
||||
* Access types
|
||||
@ -190,6 +194,8 @@ UAVObjUpdateMode UAVObjGetTelemetryUpdateMode(const UAVObjMetadata *dataOut);
|
||||
void UAVObjSetTelemetryUpdateMode(UAVObjMetadata *dataOut, UAVObjUpdateMode val);
|
||||
UAVObjUpdateMode UAVObjGetGcsTelemetryUpdateMode(const UAVObjMetadata *dataOut);
|
||||
void UAVObjSetTelemetryGcsUpdateMode(UAVObjMetadata *dataOut, UAVObjUpdateMode val);
|
||||
UAVObjUpdateMode UAVObjGetLoggingUpdateMode(const UAVObjMetadata *dataOut);
|
||||
void UAVObjSetLoggingUpdateMode(UAVObjMetadata *dataOut, UAVObjUpdateMode val);
|
||||
int8_t UAVObjReadOnly(UAVObjHandle obj);
|
||||
int32_t UAVObjConnectQueue(UAVObjHandle obj_handle, xQueueHandle queue, uint8_t eventMask);
|
||||
int32_t UAVObjDisconnectQueue(UAVObjHandle obj_handle, xQueueHandle queue);
|
||||
@ -199,7 +205,10 @@ void UAVObjRequestUpdate(UAVObjHandle obj);
|
||||
void UAVObjRequestInstanceUpdate(UAVObjHandle obj_handle, uint16_t instId);
|
||||
void UAVObjUpdated(UAVObjHandle obj);
|
||||
void UAVObjInstanceUpdated(UAVObjHandle obj_handle, uint16_t instId);
|
||||
void UAVObjLogging(UAVObjHandle obj);
|
||||
void UAVObjInstanceLogging(UAVObjHandle obj_handle, uint16_t instId);
|
||||
void UAVObjIterate(void (*iterator)(UAVObjHandle obj));
|
||||
void UAVObjInstanceWriteToLog(UAVObjHandle obj_handle, uint16_t instId);
|
||||
|
||||
#endif // UAVOBJECTMANAGER_H
|
||||
|
||||
|
@ -94,7 +94,8 @@ $(INITFIELDS)
|
||||
$(FLIGHTTELEM_ACKED) << UAVOBJ_TELEMETRY_ACKED_SHIFT |
|
||||
$(GCSTELEM_ACKED) << UAVOBJ_GCS_TELEMETRY_ACKED_SHIFT |
|
||||
$(FLIGHTTELEM_UPDATEMODE) << UAVOBJ_TELEMETRY_UPDATE_MODE_SHIFT |
|
||||
$(GCSTELEM_UPDATEMODE) << UAVOBJ_GCS_TELEMETRY_UPDATE_MODE_SHIFT;
|
||||
$(GCSTELEM_UPDATEMODE) << UAVOBJ_GCS_TELEMETRY_UPDATE_MODE_SHIFT |
|
||||
$(LOGGING_UPDATEMODE) << UAVOBJ_LOGGING_UPDATE_MODE_SHIFT;
|
||||
metadata.telemetryUpdatePeriod = $(FLIGHTTELEM_UPDATEPERIOD);
|
||||
metadata.gcsTelemetryUpdatePeriod = $(GCSTELEM_UPDATEPERIOD);
|
||||
metadata.loggingUpdatePeriod = $(LOGGING_UPDATEPERIOD);
|
||||
|
@ -184,15 +184,6 @@ static int32_t connectObj(UAVObjHandle obj_handle, xQueueHandle queue,
|
||||
static int32_t disconnectObj(UAVObjHandle obj_handle, xQueueHandle queue,
|
||||
UAVObjEventCallback cb);
|
||||
|
||||
#if defined(PIOS_USE_SETTINGS_ON_SDCARD) && defined(PIOS_INCLUDE_FLASH_LOGFS_SETTINGS)
|
||||
#error Both PIOS_USE_SETTINGS_ON_SDCARD and PIOS_INCLUDE_FLASH_LOGFS_SETTINGS. Only one settings storage allowed.
|
||||
#endif
|
||||
|
||||
#if defined(PIOS_USE_SETTINGS_ON_SDCARD)
|
||||
static void objectFilename(UAVObjHandle obj_handle, uint8_t *filename);
|
||||
static void customSPrintf(uint8_t *buffer, uint8_t *format, ...);
|
||||
#endif
|
||||
|
||||
// Private variables
|
||||
static xSemaphoreHandle mutex;
|
||||
static const UAVObjMetadata defMetadata = {
|
||||
@ -713,82 +704,43 @@ unlock_exit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
#if defined(PIOS_USE_SETTINGS_ON_SDCARD)
|
||||
|
||||
/**
|
||||
* Save the data of the specified object instance to the file system (SD card).
|
||||
* The object will be appended and the file will not be closed.
|
||||
* The object data can be restored using the UAVObjLoad function.
|
||||
* @param[in] obj The object handle.
|
||||
* @param[in] instId The instance ID
|
||||
* @param[in] file File to append to
|
||||
* @return 0 if success or -1 if failure
|
||||
* Actually write the object's data to the logfile
|
||||
* \param[in] obj The object handle
|
||||
* \param[in] instId The object instance ID
|
||||
*/
|
||||
int32_t UAVObjSaveToFile(UAVObjHandle obj_handle, uint16_t instId,
|
||||
FILEINFO *file)
|
||||
void UAVObjInstanceWriteToLog(UAVObjHandle obj_handle, uint16_t instId)
|
||||
{
|
||||
PIOS_Assert(obj_handle);
|
||||
|
||||
uint32_t bytesWritten;
|
||||
// Check for file system availability
|
||||
if (PIOS_SDCARD_IsMounted() == 0) {
|
||||
return -1;
|
||||
}
|
||||
// Lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
|
||||
if (UAVObjIsMetaobject(obj_handle)) {
|
||||
// Get the instance information
|
||||
if (instId != 0) {
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return -1;
|
||||
}
|
||||
// Write the object ID
|
||||
uint32_t objId = UAVObjGetID(obj_handle);
|
||||
PIOS_FWRITE(file, &objId, sizeof(objId),
|
||||
&bytesWritten);
|
||||
|
||||
// Write the data and check that the write was successful
|
||||
PIOS_FWRITE(file, MetaDataPtr((struct UAVOMeta *)obj_handle), MetaNumBytes,
|
||||
&bytesWritten);
|
||||
if (bytesWritten != MetaNumBytes) {
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return -1;
|
||||
goto unlock_exit;
|
||||
}
|
||||
PIOS_DEBUGLOG_UAVObject(UAVObjGetID(obj_handle), instId, MetaNumBytes, (uint8_t *)MetaDataPtr((struct UAVOMeta *)obj_handle));
|
||||
} else {
|
||||
struct UAVOData *uavo;
|
||||
struct UAVOData *obj;
|
||||
InstanceHandle instEntry;
|
||||
|
||||
// Cast to object
|
||||
uavo = (struct UAVOData *)obj_handle;
|
||||
// Cast handle to object
|
||||
obj = (struct UAVOData *)obj_handle;
|
||||
|
||||
// Get the instance information
|
||||
instEntry = getInstance(uavo, instId);
|
||||
// Get the instance
|
||||
instEntry = getInstance(obj, instId);
|
||||
if (instEntry == NULL) {
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return -1;
|
||||
}
|
||||
// Write the object ID
|
||||
PIOS_FWRITE(file, &uavo->id, sizeof(uavo->id),
|
||||
&bytesWritten);
|
||||
|
||||
// Write the instance ID
|
||||
if (!UAVObjIsSingleInstance(obj_handle)) {
|
||||
PIOS_FWRITE(file, &instId,
|
||||
sizeof(instId), &bytesWritten);
|
||||
}
|
||||
// Write the data and check that the write was successful
|
||||
PIOS_FWRITE(file, InstanceData(instEntry), uavo->instance_size,
|
||||
&bytesWritten);
|
||||
if (bytesWritten != uavo->instance_size) {
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return -1;
|
||||
goto unlock_exit;
|
||||
}
|
||||
// Pack data
|
||||
PIOS_DEBUGLOG_UAVObject(UAVObjGetID(obj_handle), instId, obj->instance_size, (uint8_t *)InstanceData(instEntry));
|
||||
}
|
||||
// Done
|
||||
|
||||
unlock_exit:
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return 0;
|
||||
}
|
||||
#endif /* PIOS_USE_SETTINGS_ON_SDCARD */
|
||||
|
||||
/**
|
||||
* Save the data of the specified object to the file system (SD card).
|
||||
@ -797,14 +749,12 @@ int32_t UAVObjSaveToFile(UAVObjHandle obj_handle, uint16_t instId,
|
||||
* The object data can be restored using the UAVObjLoad function.
|
||||
* @param[in] obj The object handle.
|
||||
* @param[in] instId The instance ID
|
||||
* @param[in] file File to append to
|
||||
* @return 0 if success or -1 if failure
|
||||
*/
|
||||
int32_t UAVObjSave(UAVObjHandle obj_handle, __attribute__((unused)) uint16_t instId)
|
||||
int32_t UAVObjSave(UAVObjHandle obj_handle, uint16_t instId)
|
||||
{
|
||||
PIOS_Assert(obj_handle);
|
||||
|
||||
#if defined(PIOS_INCLUDE_FLASH_LOGFS_SETTINGS)
|
||||
if (UAVObjIsMetaobject(obj_handle)) {
|
||||
if (instId != 0) {
|
||||
return -1;
|
||||
@ -828,131 +778,9 @@ int32_t UAVObjSave(UAVObjHandle obj_handle, __attribute__((unused)) uint16_t ins
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif /* if defined(PIOS_INCLUDE_FLASH_LOGFS_SETTINGS) */
|
||||
#if defined(PIOS_USE_SETTINGS_ON_SDCARD)
|
||||
FILEINFO file;
|
||||
uint8_t filename[14];
|
||||
|
||||
// Check for file system availability
|
||||
if (PIOS_SDCARD_IsMounted() == 0) {
|
||||
return -1;
|
||||
}
|
||||
// Lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
|
||||
// Get filename
|
||||
objectFilename(obj_handle, filename);
|
||||
|
||||
// Open file
|
||||
if (PIOS_FOPEN_WRITE(filename, file)) {
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return -1;
|
||||
}
|
||||
// Append object
|
||||
if (UAVObjSaveToFile(obj_handle, instId, &file) == -1) {
|
||||
PIOS_FCLOSE(file);
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return -1;
|
||||
}
|
||||
// Done, close file and unlock
|
||||
PIOS_FCLOSE(file);
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
#endif /* PIOS_USE_SETTINGS_ON_SDCARD */
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(PIOS_USE_SETTINGS_ON_SDCARD)
|
||||
/**
|
||||
* Load an object from the file system (SD card).
|
||||
* @param[in] obj The object handle.
|
||||
* @param[in] file File to read from
|
||||
* @return 0 if success or -1 if failure
|
||||
*/
|
||||
int32_t UAVObjLoadFromFile(UAVObjHandle obj_handle, FILEINFO *file)
|
||||
{
|
||||
uint32_t bytesRead;
|
||||
struct UAVOBase *objEntry;
|
||||
InstanceHandle instEntry;
|
||||
uint32_t objId;
|
||||
uint16_t instId;
|
||||
|
||||
// Check for file system availability
|
||||
if (PIOS_SDCARD_IsMounted() == 0) {
|
||||
return -1;
|
||||
}
|
||||
// Get the object
|
||||
if (obj_handle == 0) {
|
||||
return -1;
|
||||
}
|
||||
objEntry = (struct UAVOBase *)obj_handle;
|
||||
|
||||
// Lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
|
||||
// Read the object ID
|
||||
if (PIOS_FREAD(file, &objId, sizeof(objId), &bytesRead)) {
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Check that the IDs match
|
||||
if (objId != UAVObjGetID(obj_handle)) {
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Get the instance ID
|
||||
instId = 0;
|
||||
if (!UAVObjIsSingleInstance(obj_handle)) {
|
||||
if (PIOS_FREAD
|
||||
(file, &instId, sizeof(instId), &bytesRead)) {
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (UAVObjIsMetaobject(obj_handle)) {
|
||||
// If the instance does not exist create it and any other instances before it
|
||||
if (instId != 0) {
|
||||
// Error, unlock and return
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return -1;
|
||||
}
|
||||
// Read the instance data
|
||||
if (PIOS_FREAD
|
||||
(file, MetaDataPtr((struct UAVOMeta *)obj_handle), MetaNumBytes, &bytesRead)) {
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
// Get the instance information
|
||||
instEntry = getInstance((struct UAVOData *)objEntry, instId);
|
||||
|
||||
// If the instance does not exist create it and any other instances before it
|
||||
if (instEntry == NULL) {
|
||||
instEntry = createInstance((struct UAVOData *)objEntry, instId);
|
||||
if (instEntry == NULL) {
|
||||
// Error, unlock and return
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
// Read the instance data
|
||||
if (PIOS_FREAD
|
||||
(file, InstanceData(instEntry), ((struct UAVOData *)objEntry)->instance_size, &bytesRead)) {
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// Fire event
|
||||
sendEvent(objEntry, instId, EV_UNPACKED);
|
||||
|
||||
// Unlock
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return 0;
|
||||
}
|
||||
#endif /* PIOS_USE_SETTINGS_ON_SDCARD */
|
||||
|
||||
/**
|
||||
* Load an object from the file system (SD card).
|
||||
@ -962,11 +790,10 @@ int32_t UAVObjLoadFromFile(UAVObjHandle obj_handle, FILEINFO *file)
|
||||
* @param[in] instId The object instance
|
||||
* @return 0 if success or -1 if failure
|
||||
*/
|
||||
int32_t UAVObjLoad(UAVObjHandle obj_handle, __attribute__((unused)) uint16_t instId)
|
||||
int32_t UAVObjLoad(UAVObjHandle obj_handle, uint16_t instId)
|
||||
{
|
||||
PIOS_Assert(obj_handle);
|
||||
|
||||
#if defined(PIOS_INCLUDE_FLASH_LOGFS_SETTINGS)
|
||||
if (UAVObjIsMetaobject(obj_handle)) {
|
||||
if (instId != 0) {
|
||||
return -1;
|
||||
@ -993,37 +820,7 @@ int32_t UAVObjLoad(UAVObjHandle obj_handle, __attribute__((unused)) uint16_t ins
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* if defined(PIOS_INCLUDE_FLASH_LOGFS_SETTINGS) */
|
||||
|
||||
#if defined(PIOS_USE_SETTINGS_ON_SDCARD)
|
||||
FILEINFO file;
|
||||
uint8_t filename[14];
|
||||
|
||||
// Check for file system availability
|
||||
if (PIOS_SDCARD_IsMounted() == 0) {
|
||||
return -1;
|
||||
}
|
||||
// Lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
|
||||
// Get filename
|
||||
objectFilename(obj_handle, filename);
|
||||
|
||||
// Open file
|
||||
if (PIOS_FOPEN_READ(filename, file)) {
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return -1;
|
||||
}
|
||||
// Load object
|
||||
if (UAVObjLoadFromFile(obj_handle, &file) != 0) {
|
||||
PIOS_FCLOSE(file);
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return -1;
|
||||
}
|
||||
// Done, close file and unlock
|
||||
PIOS_FCLOSE(file);
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
#endif /* PIOS_USE_SETTINGS_ON_SDCARD */
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1033,31 +830,10 @@ int32_t UAVObjLoad(UAVObjHandle obj_handle, __attribute__((unused)) uint16_t ins
|
||||
* @param[in] instId The object instance
|
||||
* @return 0 if success or -1 if failure
|
||||
*/
|
||||
int32_t UAVObjDelete(UAVObjHandle obj_handle, __attribute__((unused)) uint16_t instId)
|
||||
int32_t UAVObjDelete(UAVObjHandle obj_handle, uint16_t instId)
|
||||
{
|
||||
PIOS_Assert(obj_handle);
|
||||
#if defined(PIOS_INCLUDE_FLASH_LOGFS_SETTINGS)
|
||||
PIOS_FLASHFS_ObjDelete(pios_uavo_settings_fs_id, UAVObjGetID(obj_handle), instId);
|
||||
#endif
|
||||
#if defined(PIOS_USE_SETTINGS_ON_SDCARD)
|
||||
uint8_t filename[14];
|
||||
|
||||
// Check for file system availability
|
||||
if (PIOS_SDCARD_IsMounted() == 0) {
|
||||
return -1;
|
||||
}
|
||||
// Lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
|
||||
// Get filename
|
||||
objectFilename(obj_handle, filename);
|
||||
|
||||
// Delete file
|
||||
PIOS_FUNLINK(filename);
|
||||
|
||||
// Done
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
#endif /* PIOS_USE_SETTINGS_ON_SDCARD */
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1683,6 +1459,28 @@ void UAVObjSetGcsTelemetryUpdateMode(UAVObjMetadata *metadata, UAVObjUpdateMode
|
||||
SET_BITS(metadata->flags, UAVOBJ_GCS_TELEMETRY_UPDATE_MODE_SHIFT, val, UAVOBJ_UPDATE_MODE_MASK);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the UAVObject metadata logging update mode
|
||||
* \param[in] metadata The metadata object
|
||||
* \return the GCS telemetry update mode
|
||||
*/
|
||||
UAVObjUpdateMode UAVObjGetLoggingUpdateMode(const UAVObjMetadata *metadata)
|
||||
{
|
||||
PIOS_Assert(metadata);
|
||||
return (metadata->flags >> UAVOBJ_LOGGING_UPDATE_MODE_SHIFT) & UAVOBJ_UPDATE_MODE_MASK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the UAVObject metadata logging update mode member
|
||||
* \param[in] metadata The metadata object
|
||||
* \param[in] val The GCS telemetry update mode
|
||||
*/
|
||||
void UAVObjSetLoggingUpdateMode(UAVObjMetadata *metadata, UAVObjUpdateMode val)
|
||||
{
|
||||
PIOS_Assert(metadata);
|
||||
SET_BITS(metadata->flags, UAVOBJ_LOGGING_UPDATE_MODE_SHIFT, val, UAVOBJ_UPDATE_MODE_MASK);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if an object is read only
|
||||
@ -1819,6 +1617,28 @@ void UAVObjInstanceUpdated(UAVObjHandle obj_handle, uint16_t instId)
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log the object's data (triggers a EV_LOGGING_MANUAL event on this object).
|
||||
* \param[in] obj The object handle
|
||||
*/
|
||||
void UAVObjLogging(UAVObjHandle obj_handle)
|
||||
{
|
||||
UAVObjInstanceLogging(obj_handle, UAVOBJ_ALL_INSTANCES);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log the object's data (triggers a EV_LOGGING_MANUAL event on this object).
|
||||
* \param[in] obj The object handle
|
||||
* \param[in] instId The object instance ID
|
||||
*/
|
||||
void UAVObjInstanceLogging(UAVObjHandle obj_handle, uint16_t instId)
|
||||
{
|
||||
PIOS_Assert(obj_handle);
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
sendEvent((struct UAVOBase *)obj_handle, instId, EV_LOGGING_MANUAL);
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterate through all objects in the list.
|
||||
* \param iterator This function will be called once for each object,
|
||||
@ -2043,24 +1863,3 @@ static int32_t disconnectObj(UAVObjHandle obj_handle, xQueueHandle queue,
|
||||
// If this point is reached the queue was not found
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if defined(PIOS_USE_SETTINGS_ON_SDCARD)
|
||||
/**
|
||||
* Wrapper for the sprintf function
|
||||
*/
|
||||
static void customSPrintf(uint8_t *buffer, uint8_t *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, format);
|
||||
vsprintf((char *)buffer, (char *)format, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an 8 character (plus extension) filename for the object.
|
||||
*/
|
||||
static void objectFilename(UAVObjHandle obj_handle, uint8_t *filename)
|
||||
{
|
||||
customSPrintf(filename, (uint8_t *)"%X.obj", UAVObjGetID(obj_handle));
|
||||
}
|
||||
#endif /* PIOS_USE_SETTINGS_ON_SDCARD */
|
||||
|
@ -81,6 +81,7 @@ $(FIELDSINIT)
|
||||
$(GCSTELEM_ACKED) << UAVOBJ_GCS_TELEMETRY_ACKED_SHIFT |
|
||||
UAVObject.Metadata.UpdateModeNum(UAVObject.UpdateMode.$(FLIGHTTELEM_UPDATEMODE)) << UAVOBJ_TELEMETRY_UPDATE_MODE_SHIFT |
|
||||
UAVObject.Metadata.UpdateModeNum(UAVObject.UpdateMode.$(GCSTELEM_UPDATEMODE)) << UAVOBJ_GCS_TELEMETRY_UPDATE_MODE_SHIFT;
|
||||
UAVObject.Metadata.UpdateModeNum(UAVObject.UpdateMode.$(LOGGING_UPDATEMODE)) << UAVOBJ_LOGGING_UPDATE_MODE_SHIFT;
|
||||
metadata.flightTelemetryUpdatePeriod = $(FLIGHTTELEM_UPDATEPERIOD);
|
||||
metadata.gcsTelemetryUpdatePeriod = $(GCSTELEM_UPDATEPERIOD);
|
||||
metadata.loggingUpdatePeriod = $(LOGGING_UPDATEPERIOD);
|
||||
|
@ -39,7 +39,7 @@ UAVMetaObject::UAVMetaObject(quint32 objID, const QString & name, UAVObject *par
|
||||
UAVObject::MetadataInitialize(ownMetadata);
|
||||
// Setup fields
|
||||
QStringList modesBitField;
|
||||
modesBitField << tr("FlightReadOnly") << tr("GCSReadOnly") << tr("FlightTelemetryAcked") << tr("GCSTelemetryAcked") << tr("FlightUpdatePeriodic") << tr("FlightUpdateOnChange") << tr("GCSUpdatePeriodic") << tr("GCSUpdateOnChange");
|
||||
modesBitField << tr("FlightReadOnly") << tr("GCSReadOnly") << tr("FlightTelemetryAcked") << tr("GCSTelemetryAcked") << tr("FlightUpdatePeriodic") << tr("FlightUpdateOnChange") << tr("GCSUpdatePeriodic") << tr("GCSUpdateOnChange") << tr("LoggingUpdatePeriodic") << tr("LoggingUpdateOnChange");
|
||||
QList<UAVObjectField *> fields;
|
||||
fields.append(new UAVObjectField(tr("Modes"), tr("boolean"), UAVObjectField::BITFIELD, modesBitField, QStringList()));
|
||||
fields.append(new UAVObjectField(tr("Flight Telemetry Update Period"), tr("ms"), UAVObjectField::UINT16, 1, QStringList()));
|
||||
|
@ -36,6 +36,7 @@
|
||||
#define UAVOBJ_GCS_TELEMETRY_ACKED_SHIFT 3
|
||||
#define UAVOBJ_TELEMETRY_UPDATE_MODE_SHIFT 4
|
||||
#define UAVOBJ_GCS_TELEMETRY_UPDATE_MODE_SHIFT 6
|
||||
#define UAVOBJ_LOGGING_UPDATE_MODE_SHIFT 8
|
||||
#define UAVOBJ_UPDATE_MODE_MASK 0x3
|
||||
|
||||
// Macros
|
||||
@ -498,7 +499,8 @@ void UAVObject::MetadataInitialize(UAVObject::Metadata & metadata)
|
||||
1 << UAVOBJ_TELEMETRY_ACKED_SHIFT |
|
||||
1 << UAVOBJ_GCS_TELEMETRY_ACKED_SHIFT |
|
||||
UPDATEMODE_ONCHANGE << UAVOBJ_TELEMETRY_UPDATE_MODE_SHIFT |
|
||||
UPDATEMODE_ONCHANGE << UAVOBJ_GCS_TELEMETRY_UPDATE_MODE_SHIFT;
|
||||
UPDATEMODE_ONCHANGE << UAVOBJ_GCS_TELEMETRY_UPDATE_MODE_SHIFT |
|
||||
UPDATEMODE_ONCHANGE << UAVOBJ_LOGGING_UPDATE_MODE_SHIFT;
|
||||
metadata.flightTelemetryUpdatePeriod = 0;
|
||||
metadata.gcsTelemetryUpdatePeriod = 0;
|
||||
metadata.loggingUpdatePeriod = 0;
|
||||
|
@ -71,7 +71,8 @@ UAVObject::Metadata $(NAME)::getDefaultMetadata()
|
||||
$(FLIGHTTELEM_ACKED) << UAVOBJ_TELEMETRY_ACKED_SHIFT |
|
||||
$(GCSTELEM_ACKED) << UAVOBJ_GCS_TELEMETRY_ACKED_SHIFT |
|
||||
$(FLIGHTTELEM_UPDATEMODE) << UAVOBJ_TELEMETRY_UPDATE_MODE_SHIFT |
|
||||
$(GCSTELEM_UPDATEMODE) << UAVOBJ_GCS_TELEMETRY_UPDATE_MODE_SHIFT;
|
||||
$(GCSTELEM_UPDATEMODE) << UAVOBJ_GCS_TELEMETRY_UPDATE_MODE_SHIFT |
|
||||
$(LOGGING_UPDATEMODE) << UAVOBJ_LOGGING_UPDATE_MODE_SHIFT;
|
||||
metadata.flightTelemetryUpdatePeriod = $(FLIGHTTELEM_UPDATEPERIOD);
|
||||
metadata.gcsTelemetryUpdatePeriod = $(GCSTELEM_UPDATEPERIOD);
|
||||
metadata.loggingUpdatePeriod = $(LOGGING_UPDATEPERIOD);
|
||||
|
@ -45,6 +45,7 @@
|
||||
#define UAVOBJ_GCS_TELEMETRY_ACKED_SHIFT 3
|
||||
#define UAVOBJ_TELEMETRY_UPDATE_MODE_SHIFT 4
|
||||
#define UAVOBJ_GCS_TELEMETRY_UPDATE_MODE_SHIFT 6
|
||||
#define UAVOBJ_LOGGING_UPDATE_MODE_SHIFT 8
|
||||
#define UAVOBJ_UPDATE_MODE_MASK 0x3
|
||||
|
||||
class UAVObjectField;
|
||||
@ -87,9 +88,10 @@ public:
|
||||
* 3 gcsTelemetryAcked Defines if an ack is required for the transactions of this object (1:acked, 0:not acked)
|
||||
* 4-5 telemetryUpdateMode Update mode used by the telemetry module (UAVObjUpdateMode)
|
||||
* 6-7 gcsTelemetryUpdateMode Update mode used by the GCS (UAVObjUpdateMode)
|
||||
* 8-9 loggingUpdateMode Update mode used by the logging module (UAVObjUpdateMode)
|
||||
*/
|
||||
typedef struct {
|
||||
quint8 flags; /** Defines flags for update and logging modes and whether an update should be ACK'd (bits defined above) */
|
||||
quint16 flags; /** Defines flags for update and logging modes and whether an update should be ACK'd (bits defined above) */
|
||||
quint16 flightTelemetryUpdatePeriod; /** Update period used by the telemetry module (only if telemetry mode is PERIODIC) */
|
||||
quint16 gcsTelemetryUpdatePeriod; /** Update period used by the GCS (only if telemetry mode is PERIODIC) */
|
||||
quint16 loggingUpdatePeriod; /** Update period used by the logging module (only if logging mode is PERIODIC) */
|
||||
|
@ -34,6 +34,10 @@ HEADERS += $$UAVOBJECT_SYNTHETICS/accessorydesired.h \
|
||||
$$UAVOBJECT_SYNTHETICS/altitudeholddesired.h \
|
||||
$$UAVOBJECT_SYNTHETICS/altitudeholdsettings.h \
|
||||
$$UAVOBJECT_SYNTHETICS/altitudefiltersettings.h \
|
||||
$$UAVOBJECT_SYNTHETICS/debuglogsettings.h \
|
||||
$$UAVOBJECT_SYNTHETICS/debuglogcontrol.h \
|
||||
$$UAVOBJECT_SYNTHETICS/debuglogstatus.h \
|
||||
$$UAVOBJECT_SYNTHETICS/debuglogentry.h \
|
||||
$$UAVOBJECT_SYNTHETICS/ekfconfiguration.h \
|
||||
$$UAVOBJECT_SYNTHETICS/ekfstatevariance.h \
|
||||
$$UAVOBJECT_SYNTHETICS/revocalibration.h \
|
||||
@ -120,6 +124,10 @@ SOURCES += $$UAVOBJECT_SYNTHETICS/accessorydesired.cpp \
|
||||
$$UAVOBJECT_SYNTHETICS/altholdsmoothed.cpp \
|
||||
$$UAVOBJECT_SYNTHETICS/altitudeholddesired.cpp \
|
||||
$$UAVOBJECT_SYNTHETICS/altitudeholdsettings.cpp \
|
||||
$$UAVOBJECT_SYNTHETICS/debuglogsettings.cpp \
|
||||
$$UAVOBJECT_SYNTHETICS/debuglogcontrol.cpp \
|
||||
$$UAVOBJECT_SYNTHETICS/debuglogstatus.cpp \
|
||||
$$UAVOBJECT_SYNTHETICS/debuglogentry.cpp \
|
||||
$$UAVOBJECT_SYNTHETICS/altitudefiltersettings.cpp \
|
||||
$$UAVOBJECT_SYNTHETICS/ekfconfiguration.cpp \
|
||||
$$UAVOBJECT_SYNTHETICS/ekfstatevariance.cpp \
|
||||
|
@ -81,6 +81,7 @@ SRC += $(PIOSCOMMON)/pios_com_msg.c
|
||||
SRC += $(PIOSCOMMON)/pios_crc.c
|
||||
SRC += $(PIOSCOMMON)/pios_flashfs_logfs.c
|
||||
SRC += $(PIOSCOMMON)/pios_flash_jedec.c
|
||||
SRC += $(PIOSCOMMON)/pios_debuglog.c
|
||||
SRC += $(PIOSCOMMON)/pios_rcvr.c
|
||||
SRC += $(PIOSCOMMON)/pios_rfm22b.c
|
||||
SRC += $(PIOSCOMMON)/pios_rfm22b_com.c
|
||||
@ -102,6 +103,7 @@ SRC += $(FLIGHTLIB)/sanitycheck.c
|
||||
SRC += $(FLIGHTLIB)/CoordinateConversions.c
|
||||
SRC += $(MATHLIB)/sin_lookup.c
|
||||
SRC += $(MATHLIB)/pid.c
|
||||
SRC += $(FLIGHTLIB)/printf-stdarg.c
|
||||
|
||||
## Modules
|
||||
SRC += $(foreach mod, $(MODULES), $(sort $(wildcard $(OPMODULEDIR)/$(mod)/*.c)))
|
||||
|
@ -6,6 +6,6 @@
|
||||
<access gcs="readwrite" flight="readwrite"/>
|
||||
<telemetrygcs acked="false" updatemode="manual" period="0"/>
|
||||
<telemetryflight acked="false" updatemode="periodic" period="1000"/>
|
||||
<logging updatemode="periodic" period="1000"/>
|
||||
<logging updatemode="manual" period="0"/>
|
||||
</object>
|
||||
</xml>
|
||||
|
@ -8,6 +8,6 @@
|
||||
<access gcs="readwrite" flight="readwrite"/>
|
||||
<telemetrygcs acked="false" updatemode="manual" period="0"/>
|
||||
<telemetryflight acked="false" updatemode="onchange" period="0"/>
|
||||
<logging updatemode="periodic" period="1000"/>
|
||||
<logging updatemode="manual" period="0"/>
|
||||
</object>
|
||||
</xml>
|
||||
|
12
shared/uavobjectdefinition/debuglogcontrol.xml
Normal file
12
shared/uavobjectdefinition/debuglogcontrol.xml
Normal file
@ -0,0 +1,12 @@
|
||||
<xml>
|
||||
<object name="DebugLogControl" singleinstance="true" settings="false" category="System">
|
||||
<description>Log Control Object</description>
|
||||
<field name="Operation" units="" type="enum" elements="1" options="None, Retrieve, FormatFlash" />
|
||||
<field name="Flight" units="" type="uint16" elements="1" />
|
||||
<field name="Entry" units="" type="uint16" elements="1" />
|
||||
<access gcs="readwrite" flight="readwrite"/>
|
||||
<telemetrygcs acked="true" updatemode="manual" period="0"/>
|
||||
<telemetryflight acked="true" updatemode="manual" period="0"/>
|
||||
<logging updatemode="manual" period="0"/>
|
||||
</object>
|
||||
</xml>
|
17
shared/uavobjectdefinition/debuglogentry.xml
Normal file
17
shared/uavobjectdefinition/debuglogentry.xml
Normal file
@ -0,0 +1,17 @@
|
||||
<xml>
|
||||
<object name="DebugLogEntry" singleinstance="true" settings="false" category="System">
|
||||
<description>Log Entry in Flash</description>
|
||||
<field name="Flight" units="" type="uint16" elements="1" />
|
||||
<field name="FlightTime" units="ms" type="uint32" elements="1" />
|
||||
<field name="Entry" units="" type="uint16" elements="1" />
|
||||
<field name="Type" units="" type="enum" elements="1" options="Empty, Text, UAVObject" />
|
||||
<field name="ObjectID" units="" type="uint32" elements="1"/>
|
||||
<field name="InstanceID" units="" type="uint16" elements="1"/>
|
||||
<field name="Size" units="" type="uint16" elements="1" />
|
||||
<field name="Data" units="" type="uint8" elements="200" />
|
||||
<access gcs="readwrite" flight="readwrite"/>
|
||||
<telemetrygcs acked="false" updatemode="manual" period="0"/>
|
||||
<telemetryflight acked="false" updatemode="manual" period="0"/>
|
||||
<logging updatemode="manual" period="0"/>
|
||||
</object>
|
||||
</xml>
|
11
shared/uavobjectdefinition/debuglogsettings.xml
Normal file
11
shared/uavobjectdefinition/debuglogsettings.xml
Normal file
@ -0,0 +1,11 @@
|
||||
<xml>
|
||||
<object name="DebugLogSettings" singleinstance="true" settings="true" category="System">
|
||||
<description>Configure On Board Logging Facilities</description>
|
||||
<field name="LoggingEnabled" units="bool" type="enum" elements="1" options="False,True" defaultvalue="False" />
|
||||
|
||||
<access gcs="readwrite" flight="readwrite"/>
|
||||
<telemetrygcs acked="true" updatemode="onchange" period="0"/>
|
||||
<telemetryflight acked="true" updatemode="onchange" period="0"/>
|
||||
<logging updatemode="manual" period="0"/>
|
||||
</object>
|
||||
</xml>
|
13
shared/uavobjectdefinition/debuglogstatus.xml
Normal file
13
shared/uavobjectdefinition/debuglogstatus.xml
Normal file
@ -0,0 +1,13 @@
|
||||
<xml>
|
||||
<object name="DebugLogStatus" singleinstance="true" settings="false" category="System">
|
||||
<description>Log Control Object</description>
|
||||
<field name="Flight" units="" type="uint16" elements="1" />
|
||||
<field name="Entry" units="" type="uint16" elements="1" />
|
||||
<field name="UsedSlots" units="" type="uint16" elements="1" />
|
||||
<field name="FreeSlots" units="" type="uint16" elements="1" />
|
||||
<access gcs="readwrite" flight="readwrite"/>
|
||||
<telemetrygcs acked="false" updatemode="manual" period="0"/>
|
||||
<telemetryflight acked="false" updatemode="periodic" period="1000"/>
|
||||
<logging updatemode="manual" period="0"/>
|
||||
</object>
|
||||
</xml>
|
@ -10,6 +10,6 @@
|
||||
<access gcs="readwrite" flight="readwrite"/>
|
||||
<telemetrygcs acked="false" updatemode="manual" period="0"/>
|
||||
<telemetryflight acked="false" updatemode="periodic" period="5000"/>
|
||||
<logging updatemode="periodic" period="5000"/>
|
||||
<logging updatemode="manual" period="0"/>
|
||||
</object>
|
||||
</xml>
|
||||
|
@ -15,6 +15,6 @@
|
||||
<access gcs="readwrite" flight="readwrite"/>
|
||||
<telemetrygcs acked="false" updatemode="manual" period="0"/>
|
||||
<telemetryflight acked="false" updatemode="periodic" period="1000"/>
|
||||
<logging updatemode="periodic" period="1000"/>
|
||||
<logging updatemode="manual" period="0"/>
|
||||
</object>
|
||||
</xml>
|
||||
|
@ -9,6 +9,6 @@
|
||||
<access gcs="readwrite" flight="readwrite"/>
|
||||
<telemetrygcs acked="false" updatemode="manual" period="0"/>
|
||||
<telemetryflight acked="false" updatemode="periodic" period="10000"/>
|
||||
<logging updatemode="periodic" period="30000"/>
|
||||
<logging updatemode="manual" period="0"/>
|
||||
</object>
|
||||
</xml>
|
||||
|
@ -10,6 +10,6 @@
|
||||
<access gcs="readwrite" flight="readwrite"/>
|
||||
<telemetrygcs acked="false" updatemode="manual" period="0"/>
|
||||
<telemetryflight acked="false" updatemode="periodic" period="10000"/>
|
||||
<logging updatemode="periodic" period="30000"/>
|
||||
<logging updatemode="manual" period="0"/>
|
||||
</object>
|
||||
</xml>
|
||||
|
@ -7,6 +7,6 @@
|
||||
<access gcs="readwrite" flight="readwrite"/>
|
||||
<telemetrygcs acked="false" updatemode="manual" period="0"/>
|
||||
<telemetryflight acked="false" updatemode="periodic" period="1000"/>
|
||||
<logging updatemode="periodic" period="1000"/>
|
||||
<logging updatemode="manual" period="0"/>
|
||||
</object>
|
||||
</xml>
|
||||
|
@ -14,6 +14,6 @@
|
||||
<access gcs="readwrite" flight="readwrite"/>
|
||||
<telemetrygcs acked="false" updatemode="manual" period="0"/>
|
||||
<telemetryflight acked="false" updatemode="periodic" period="10000"/>
|
||||
<logging updatemode="periodic" period="30000"/>
|
||||
<logging updatemode="manual" period="0"/>
|
||||
</object>
|
||||
</xml>
|
||||
|
@ -16,6 +16,6 @@
|
||||
<access gcs="readwrite" flight="readwrite"/>
|
||||
<telemetrygcs acked="false" updatemode="manual" period="0"/>
|
||||
<telemetryflight acked="false" updatemode="periodic" period="1000"/>
|
||||
<logging updatemode="periodic" period="1000"/>
|
||||
<logging updatemode="manual" period="0"/>
|
||||
</object>
|
||||
</xml>
|
||||
|
@ -31,6 +31,6 @@
|
||||
<access gcs="readonly" flight="readwrite"/>
|
||||
<telemetrygcs acked="false" updatemode="manual" period="0"/>
|
||||
<telemetryflight acked="false" updatemode="throttled" period="500"/>
|
||||
<logging updatemode="periodic" period="1000"/>
|
||||
<logging updatemode="manual" period="0"/>
|
||||
</object>
|
||||
</xml>
|
||||
|
@ -5,6 +5,6 @@
|
||||
<access gcs="readwrite" flight="readwrite"/>
|
||||
<telemetrygcs acked="false" updatemode="manual" period="0"/>
|
||||
<telemetryflight acked="false" updatemode="onchange" period="0"/>
|
||||
<logging updatemode="periodic" period="1000"/>
|
||||
<logging updatemode="manual" period="0"/>
|
||||
</object>
|
||||
</xml>
|
||||
|
@ -11,6 +11,6 @@
|
||||
<access gcs="readwrite" flight="readwrite"/>
|
||||
<telemetrygcs acked="false" updatemode="manual" period="0"/>
|
||||
<telemetryflight acked="false" updatemode="periodic" period="1000"/>
|
||||
<logging updatemode="periodic" period="1000"/>
|
||||
<logging updatemode="manual" period="0"/>
|
||||
</object>
|
||||
</xml>
|
||||
|
@ -25,6 +25,6 @@
|
||||
<access gcs="readwrite" flight="readwrite"/>
|
||||
<telemetrygcs acked="true" updatemode="manual" period="0"/>
|
||||
<telemetryflight acked="false" updatemode="periodic" period="4000"/>
|
||||
<logging updatemode="periodic" period="1000"/>
|
||||
<logging updatemode="manual" period="0"/>
|
||||
</object>
|
||||
</xml>
|
||||
|
@ -11,6 +11,6 @@
|
||||
<access gcs="readwrite" flight="readwrite"/>
|
||||
<telemetrygcs acked="false" updatemode="manual" period="0"/>
|
||||
<telemetryflight acked="false" updatemode="periodic" period="1000"/>
|
||||
<logging updatemode="periodic" period="1000"/>
|
||||
<logging updatemode="manual" period="0"/>
|
||||
</object>
|
||||
</xml>
|
||||
|
@ -7,6 +7,6 @@
|
||||
<access gcs="readwrite" flight="readwrite"/>
|
||||
<telemetrygcs acked="false" updatemode="manual" period="0"/>
|
||||
<telemetryflight acked="false" updatemode="periodic" period="1000"/>
|
||||
<logging updatemode="periodic" period="1000"/>
|
||||
<logging updatemode="manual" period="0"/>
|
||||
</object>
|
||||
</xml>
|
||||
|
@ -7,6 +7,6 @@
|
||||
<access gcs="readwrite" flight="readwrite"/>
|
||||
<telemetrygcs acked="false" updatemode="manual" period="0"/>
|
||||
<telemetryflight acked="false" updatemode="periodic" period="1000"/>
|
||||
<logging updatemode="periodic" period="1000"/>
|
||||
<logging updatemode="manual" period="0"/>
|
||||
</object>
|
||||
</xml>
|
||||
|
@ -7,6 +7,6 @@
|
||||
<access gcs="readwrite" flight="readwrite"/>
|
||||
<telemetrygcs acked="false" updatemode="manual" period="0"/>
|
||||
<telemetryflight acked="false" updatemode="periodic" period="1000"/>
|
||||
<logging updatemode="periodic" period="1000"/>
|
||||
<logging updatemode="manual" period="0"/>
|
||||
</object>
|
||||
</xml>
|
||||
|
@ -43,6 +43,6 @@
|
||||
<access gcs="readwrite" flight="readwrite"/>
|
||||
<telemetrygcs acked="true" updatemode="onchange" period="0"/>
|
||||
<telemetryflight acked="true" updatemode="onchange" period="0"/>
|
||||
<logging updatemode="periodic" period="1000"/>
|
||||
<logging updatemode="manual" period="0"/>
|
||||
</object>
|
||||
</xml>
|
||||
|
@ -16,6 +16,6 @@
|
||||
<access gcs="readwrite" flight="readwrite"/>
|
||||
<telemetrygcs acked="false" updatemode="manual" period="0"/>
|
||||
<telemetryflight acked="false" updatemode="periodic" period="1000"/>
|
||||
<logging updatemode="periodic" period="1000"/>
|
||||
<logging updatemode="manual" period="0"/>
|
||||
</object>
|
||||
</xml>
|
||||
|
@ -113,6 +113,6 @@
|
||||
<access gcs="readwrite" flight="readwrite"/>
|
||||
<telemetrygcs acked="true" updatemode="onchange" period="0"/>
|
||||
<telemetryflight acked="true" updatemode="periodic" period="10000"/>
|
||||
<logging updatemode="periodic" period="1000"/>
|
||||
<logging updatemode="manual" period="0"/>
|
||||
</object>
|
||||
</xml>
|
||||
|
@ -7,6 +7,6 @@
|
||||
<access gcs="readwrite" flight="readwrite"/>
|
||||
<telemetrygcs acked="false" updatemode="manual" period="0"/>
|
||||
<telemetryflight acked="false" updatemode="periodic" period="1000"/>
|
||||
<logging updatemode="periodic" period="1000"/>
|
||||
<logging updatemode="manual" period="0"/>
|
||||
</object>
|
||||
</xml>
|
||||
|
@ -7,6 +7,6 @@
|
||||
<access gcs="readwrite" flight="readwrite"/>
|
||||
<telemetrygcs acked="false" updatemode="manual" period="0"/>
|
||||
<telemetryflight acked="false" updatemode="periodic" period="1000"/>
|
||||
<logging updatemode="periodic" period="1000"/>
|
||||
<logging updatemode="manual" period="0"/>
|
||||
</object>
|
||||
</xml>
|
||||
|
@ -6,6 +6,6 @@
|
||||
<access gcs="readwrite" flight="readwrite"/>
|
||||
<telemetrygcs acked="false" updatemode="manual" period="0"/>
|
||||
<telemetryflight acked="false" updatemode="periodic" period="5000"/>
|
||||
<logging updatemode="periodic" period="5000"/>
|
||||
<logging updatemode="manual" period="0"/>
|
||||
</object>
|
||||
</xml>
|
||||
|
@ -7,6 +7,6 @@
|
||||
<access gcs="readwrite" flight="readwrite"/>
|
||||
<telemetrygcs acked="true" updatemode="manual" period="0"/>
|
||||
<telemetryflight acked="false" updatemode="periodic" period="4000"/>
|
||||
<logging updatemode="periodic" period="1000"/>
|
||||
<logging updatemode="manual" period="0"/>
|
||||
</object>
|
||||
</xml>
|
||||
|
@ -5,6 +5,6 @@
|
||||
<access gcs="readwrite" flight="readwrite"/>
|
||||
<telemetrygcs acked="false" updatemode="manual" period="0"/>
|
||||
<telemetryflight acked="false" updatemode="onchange" period="0"/>
|
||||
<logging updatemode="periodic" period="1000"/>
|
||||
<logging updatemode="manual" period="0"/>
|
||||
</object>
|
||||
</xml>
|
||||
|
Loading…
Reference in New Issue
Block a user