diff --git a/flight/modules/Logging/Logging.c b/flight/modules/Logging/Logging.c new file mode 100644 index 000000000..12441ffa4 --- /dev/null +++ b/flight/modules/Logging/Logging.c @@ -0,0 +1,106 @@ +/** + ****************************************************************************** + * @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 "debuglogentry.h" + +// private variables +static DebugLogSettingsData settings; +static DebugLogControlData control; +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); + +int32_t LoggingInitialize(void) +{ + DebugLogSettingsInitialize(); + DebugLogControlInitialize(); + DebugLogEntryInitialize(); + PIOS_DEBUGLOG_Initialize(); + entry = pvPortMalloc(sizeof(DebugLogEntryData)); + if (!entry) { + return -1; + } + + return 0; +} + +int32_t LoggingStart(void) +{ + DebugLogSettingsConnectCallback(SettingsUpdatedCb); + DebugLogControlConnectCallback(ControlUpdatedCb); + SettingsUpdatedCb(DebugLogSettingsHandle()); + return 0; +} +MODULE_INITCALL(LoggingInitialize, LoggingStart); + + +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) +{ + static bool ignore = 0; // this little hack allows us to set our own uavobject in the callback + + if (ignore) { + ignore = 0; + return; + } + + DebugLogControlGet(&control); + if (PIOS_DEBUGLOG_Read(entry, control.Flight, control.Entry) != 0) { + // reading from log failed, mark as non existent in output + memset(entry, 0, sizeof(DebugLogEntryData)); + entry->Flight = control.Flight; + entry->Entry = control.Entry; + entry->Type = DEBUGLOGENTRY_TYPE_EMPTY; + } + PIOS_DEBUGLOG_Info(&control.Flight, &control.Entry); + + ignore = 1; // set ignore flag before setting object - creates loop otherwise!!! + DebugLogEntrySet(entry); + DebugLogControlSet(&control); +} + + +/** + * @} + * @} + */ diff --git a/flight/pios/inc/pios_debuglog.h b/flight/pios/inc/pios_debuglog.h new file mode 100644 index 000000000..ba32631ee --- /dev/null +++ b/flight/pios/inc/pios_debuglog.h @@ -0,0 +1,90 @@ +/** + ****************************************************************************** + * @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(bool 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] buffer where to store the uavobject + * @param[in] log entry from which flight + */ +void PIOS_DEBUGLOG_Info(uint16_t *flight, uint16_t *entry); + +#endif // ifndef PIOS_DEBUGLOG_H + +/** + * @} + * @} + */ diff --git a/flight/pios/pios_sim_posix.h b/flight/pios/pios_sim_posix.h index fbef644c0..84fd5440a 100644 --- a/flight/pios/pios_sim_posix.h +++ b/flight/pios/pios_sim_posix.h @@ -78,6 +78,7 @@ extern void PIOS_LED_Init(void); #include #include #include +#include #include #include #include diff --git a/flight/pios/posix/pios_debuglog.c b/flight/pios/posix/pios_debuglog.c new file mode 100644 index 000000000..369778137 --- /dev/null +++ b/flight/pios/posix/pios_debuglog.c @@ -0,0 +1,192 @@ +/** + ****************************************************************************** + * @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; + +/* Private Function Prototypes */ + +/** + * @brief Initialize the log facility + */ +void PIOS_DEBUGLOG_Initialize() +{ +#if defined(PIOS_INCLUDE_FREERTOS) + if (!mutex) { + mutex = xSemaphoreCreateRecursiveMutex(); + } +#endif + 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(bool 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) { + 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; + buffer.Size = size; + uint16_t t = 0; + for (; t < size && t < sizeof(buffer.Data); t++) { + buffer.Data[t] = data[t]; + } + + 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) { + return; + } + va_list args; + va_start(args, format); + mutexlock(); + 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 *buffer, uint16_t flight, uint16_t inst) +{ + PIOS_Assert(buffer); + return PIOS_FLASHFS_ObjLoad(pios_user_fs_id, flight * 256, inst, (uint8_t *)buffer, sizeof(DebugLogEntryData)); +} + +/** + * @brief Retrieve run time info of logging system + * @param[out] buffer where to store the uavobject + * @param[in] log entry from which flight + */ +void PIOS_DEBUGLOG_Info(uint16_t *flight, uint16_t *entry) +{ + if (flight) { + *flight = flightnum; + } + if (entry) { + *entry = lognum; + } +} + + +/** + * @} + * @} + */ diff --git a/flight/targets/boards/simposix/firmware/Makefile b/flight/targets/boards/simposix/firmware/Makefile index 76524166e..ed04e470f 100644 --- a/flight/targets/boards/simposix/firmware/Makefile +++ b/flight/targets/boards/simposix/firmware/Makefile @@ -37,6 +37,7 @@ MODULES += FixedWingPathFollower MODULES += VtolPathFollower MODULES += CameraStab MODULES += Telemetry +MODULES += Logging MODULES += FirmwareIAP MODULES += StateEstimation #MODULES += Sensors/simulated/Sensors diff --git a/flight/targets/boards/simposix/firmware/UAVObjects.inc b/flight/targets/boards/simposix/firmware/UAVObjects.inc index 4cdf923a3..c404b272a 100644 --- a/flight/targets/boards/simposix/firmware/UAVObjects.inc +++ b/flight/targets/boards/simposix/firmware/UAVObjects.inc @@ -42,6 +42,9 @@ UAVOBJSRCFILENAMES += barosensor UAVOBJSRCFILENAMES += airspeedsensor UAVOBJSRCFILENAMES += airspeedsettings UAVOBJSRCFILENAMES += airspeedstate +UAVOBJSRCFILENAMES += debuglogsettings +UAVOBJSRCFILENAMES += debuglogcontrol +UAVOBJSRCFILENAMES += debuglogentry UAVOBJSRCFILENAMES += flightbatterysettings UAVOBJSRCFILENAMES += firmwareiapobj UAVOBJSRCFILENAMES += flightbatterystate diff --git a/ground/openpilotgcs/src/plugins/uavobjects/uavobjects.pro b/ground/openpilotgcs/src/plugins/uavobjects/uavobjects.pro index 44b96a580..4051a027f 100644 --- a/ground/openpilotgcs/src/plugins/uavobjects/uavobjects.pro +++ b/ground/openpilotgcs/src/plugins/uavobjects/uavobjects.pro @@ -34,6 +34,9 @@ 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/debuglogentry.h \ $$UAVOBJECT_SYNTHETICS/ekfconfiguration.h \ $$UAVOBJECT_SYNTHETICS/ekfstatevariance.h \ $$UAVOBJECT_SYNTHETICS/revocalibration.h \ @@ -120,6 +123,9 @@ 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/debuglogentry.cpp \ $$UAVOBJECT_SYNTHETICS/altitudefiltersettings.cpp \ $$UAVOBJECT_SYNTHETICS/ekfconfiguration.cpp \ $$UAVOBJECT_SYNTHETICS/ekfstatevariance.cpp \ diff --git a/shared/uavobjectdefinition/debuglogcontrol.xml b/shared/uavobjectdefinition/debuglogcontrol.xml new file mode 100644 index 000000000..6af9106f9 --- /dev/null +++ b/shared/uavobjectdefinition/debuglogcontrol.xml @@ -0,0 +1,11 @@ + + + Log Control Object + + + + + + + + diff --git a/shared/uavobjectdefinition/debuglogentry.xml b/shared/uavobjectdefinition/debuglogentry.xml new file mode 100644 index 000000000..9a9acda83 --- /dev/null +++ b/shared/uavobjectdefinition/debuglogentry.xml @@ -0,0 +1,17 @@ + + + Log Entry in Flash + + + + + + + + + + + + + + diff --git a/shared/uavobjectdefinition/debuglogsettings.xml b/shared/uavobjectdefinition/debuglogsettings.xml new file mode 100644 index 000000000..05587dedc --- /dev/null +++ b/shared/uavobjectdefinition/debuglogsettings.xml @@ -0,0 +1,11 @@ + + + Configure On Board Logging Facilities + + + + + + + +