1
0
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:
Fredrik Arvidsson 2013-11-18 23:48:03 +01:00
commit 3ec280b74f
63 changed files with 1531 additions and 369 deletions

View File

@ -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);
}
/**

View 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);
}
/**
* @}
* @}
*/

View File

@ -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

View 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();
}
/**
* @}
* @}
*/

View 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 */
/**
* @}
* @}
*/

View 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
/**
* @}
* @}
*/

View File

@ -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>

View File

@ -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>

View 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();
}
/**
* @}
* @}
*/

View 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 */
/**
* @}
* @}
*/

View File

@ -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 */

View File

@ -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 */

View File

@ -68,7 +68,7 @@ ifndef TESTAPP
#endif
## Misc library functions
SRC += $(FLIGHTLIB)/printf2.c
#SRC += $(FLIGHTLIB)/printf2.c
SRC += $(FLIGHTLIB)/WorldMagModel.c
## UAVObjects

View File

@ -102,7 +102,7 @@
// TELEMETRY
// ------------------------
#define TELEM_QUEUE_SIZE 20
#define PIOS_TELEM_STACK_SIZE 624
#define PIOS_TELEM_STACK_SIZE 800
// *****************************************************************
// Interrupt Priorities

View File

@ -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 */
};

View File

@ -47,6 +47,7 @@ MODULES += Radio
MODULES += PathPlanner
MODULES += FixedWingPathFollower
MODULES += Osd/osdoutout
MODULES += Logging
MODULES += Telemetry
OPTMODULES += ComUsbBridge

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -37,6 +37,7 @@ MODULES += FixedWingPathFollower
MODULES += VtolPathFollower
MODULES += CameraStab
MODULES += Telemetry
MODULES += Logging
MODULES += FirmwareIAP
MODULES += StateEstimation
#MODULES += Sensors/simulated/Sensors

View File

@ -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

View File

@ -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);

View File

@ -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()); }

View File

@ -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

View File

@ -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);

View File

@ -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 */

View File

@ -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);

View File

@ -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()));

View File

@ -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;

View File

@ -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);

View File

@ -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) */

View File

@ -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 \

View File

@ -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)))

View File

@ -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>

View File

@ -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>

View 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>

View 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>

View 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>

View 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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>