From 00321b09dcf7b869ed27dcce2e717938f2994806 Mon Sep 17 00:00:00 2001 From: Corvus Corax Date: Sat, 16 Nov 2013 17:30:40 +0100 Subject: [PATCH 01/26] Modified uavobjectmanager to only use logfs calls for UAVObject flash transactions, abstracted dosfs calls to use logfs wrapper class for simpiosix and SD-card access --- flight/pios/common/pios_dosfs_logfs.c | 273 +++++++++++++++++ flight/pios/pios_sim_posix.h | 2 + flight/pios/posix/pios_dosfs_logfs.c | 273 +++++++++++++++++ .../targets/boards/simposix/board_hw_defs.c | 4 + .../boards/simposix/firmware/pios_board.c | 8 + flight/uavobjects/uavobjectmanager.c | 281 ------------------ 6 files changed, 560 insertions(+), 281 deletions(-) create mode 100644 flight/pios/common/pios_dosfs_logfs.c create mode 100644 flight/pios/posix/pios_dosfs_logfs.c diff --git a/flight/pios/common/pios_dosfs_logfs.c b/flight/pios/common/pios_dosfs_logfs.c new file mode 100644 index 000000000..83a83bbd7 --- /dev/null +++ b/flight/pios/common/pios_dosfs_logfs.c @@ -0,0 +1,273 @@ +/** + ****************************************************************************** + * @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 + +#if defined(PIOS_INCLUDE_FREERTOS) +static xSemaphoreHandle mutex; +#endif + +struct flashfs_logfs_cfg; + + +/** + * Wrapper for the unimplemented sprintf function + * warning, no buffer length boundary checks, use with caution! + */ +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. + * @param[in] obj The object handle. + * @param[in] instId The instance ID + * @param[in] file Filename string pointer WARNING, must be 14 bytes long and allocated, no checks! + */ +static void objectFilename(uint32_t obj_id, uint16_t obj_inst_id, uint8_t *filename) +{ + uint32_t prefix = obj_id + (obj_inst_id / 256); + uint8_t suffix = obj_inst_id & 0xff; + + customSPrintf(filename, (uint8_t *)"%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 */ + +/** + * @} + * @} + */ diff --git a/flight/pios/pios_sim_posix.h b/flight/pios/pios_sim_posix.h index 642c0b6e9..fbef644c0 100644 --- a/flight/pios/pios_sim_posix.h +++ b/flight/pios/pios_sim_posix.h @@ -80,6 +80,8 @@ extern void PIOS_LED_Init(void); #include #include #include +#include +#include #if defined(PIOS_INCLUDE_IAP) #include diff --git a/flight/pios/posix/pios_dosfs_logfs.c b/flight/pios/posix/pios_dosfs_logfs.c new file mode 100644 index 000000000..83a83bbd7 --- /dev/null +++ b/flight/pios/posix/pios_dosfs_logfs.c @@ -0,0 +1,273 @@ +/** + ****************************************************************************** + * @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 + +#if defined(PIOS_INCLUDE_FREERTOS) +static xSemaphoreHandle mutex; +#endif + +struct flashfs_logfs_cfg; + + +/** + * Wrapper for the unimplemented sprintf function + * warning, no buffer length boundary checks, use with caution! + */ +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. + * @param[in] obj The object handle. + * @param[in] instId The instance ID + * @param[in] file Filename string pointer WARNING, must be 14 bytes long and allocated, no checks! + */ +static void objectFilename(uint32_t obj_id, uint16_t obj_inst_id, uint8_t *filename) +{ + uint32_t prefix = obj_id + (obj_inst_id / 256); + uint8_t suffix = obj_inst_id & 0xff; + + customSPrintf(filename, (uint8_t *)"%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 */ + +/** + * @} + * @} + */ diff --git a/flight/targets/boards/simposix/board_hw_defs.c b/flight/targets/boards/simposix/board_hw_defs.c index 9971a8d30..6c78422f9 100644 --- a/flight/targets/boards/simposix/board_hw_defs.c +++ b/flight/targets/boards/simposix/board_hw_defs.c @@ -69,3 +69,7 @@ const struct pios_udp_cfg pios_udp_aux_cfg = { #include #endif /* PIOS_INCLUDE_COM */ + +#if defined(PIOS_INCLUDE_FLASH) +#include "pios_flashfs_logfs_priv.h" +#endif diff --git a/flight/targets/boards/simposix/firmware/pios_board.c b/flight/targets/boards/simposix/firmware/pios_board.c index 51c800df6..07f93d80a 100644 --- a/flight/targets/boards/simposix/firmware/pios_board.c +++ b/flight/targets/boards/simposix/firmware/pios_board.c @@ -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); diff --git a/flight/uavobjects/uavobjectmanager.c b/flight/uavobjects/uavobjectmanager.c index 0ed0e1cfe..e62ecbb7e 100644 --- a/flight/uavobjects/uavobjectmanager.c +++ b/flight/uavobjects/uavobjectmanager.c @@ -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,6 @@ 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 - */ -int32_t UAVObjSaveToFile(UAVObjHandle obj_handle, uint16_t instId, - FILEINFO *file) -{ - 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; - } - } else { - struct UAVOData *uavo; - InstanceHandle instEntry; - - // Cast to object - uavo = (struct UAVOData *)obj_handle; - - // Get the instance information - instEntry = getInstance(uavo, 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; - } - } - // Done - xSemaphoreGiveRecursive(mutex); - return 0; -} -#endif /* PIOS_USE_SETTINGS_ON_SDCARD */ /** * Save the data of the specified object to the file system (SD card). @@ -804,7 +719,6 @@ int32_t UAVObjSave(UAVObjHandle obj_handle, __attribute__((unused)) uint16_t ins { PIOS_Assert(obj_handle); -#if defined(PIOS_INCLUDE_FLASH_LOGFS_SETTINGS) if (UAVObjIsMetaobject(obj_handle)) { if (instId != 0) { return -1; @@ -828,131 +742,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). @@ -966,7 +758,6 @@ int32_t UAVObjLoad(UAVObjHandle obj_handle, __attribute__((unused)) uint16_t ins { PIOS_Assert(obj_handle); -#if defined(PIOS_INCLUDE_FLASH_LOGFS_SETTINGS) if (UAVObjIsMetaobject(obj_handle)) { if (instId != 0) { return -1; @@ -993,37 +784,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; } @@ -1036,28 +797,7 @@ int32_t UAVObjLoad(UAVObjHandle obj_handle, __attribute__((unused)) uint16_t ins int32_t UAVObjDelete(UAVObjHandle obj_handle, __attribute__((unused)) 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; } @@ -2043,24 +1783,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 */ From 314d526e941b98222d483a6e510ca9922309cb99 Mon Sep 17 00:00:00 2001 From: Corvus Corax Date: Sat, 16 Nov 2013 18:55:54 +0100 Subject: [PATCH 02/26] corrected instance id encoding in filename to not conflict with metadata uavobject ids --- flight/pios/common/pios_dosfs_logfs.c | 3 ++- flight/pios/posix/pios_dosfs_logfs.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/flight/pios/common/pios_dosfs_logfs.c b/flight/pios/common/pios_dosfs_logfs.c index 83a83bbd7..2628646f8 100644 --- a/flight/pios/common/pios_dosfs_logfs.c +++ b/flight/pios/common/pios_dosfs_logfs.c @@ -57,7 +57,8 @@ static void customSPrintf(uint8_t *buffer, uint8_t *format, ...) */ static void objectFilename(uint32_t obj_id, uint16_t obj_inst_id, uint8_t *filename) { - uint32_t prefix = obj_id + (obj_inst_id / 256); + 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; customSPrintf(filename, (uint8_t *)"%08X.o%02X", prefix, suffix); diff --git a/flight/pios/posix/pios_dosfs_logfs.c b/flight/pios/posix/pios_dosfs_logfs.c index 83a83bbd7..2628646f8 100644 --- a/flight/pios/posix/pios_dosfs_logfs.c +++ b/flight/pios/posix/pios_dosfs_logfs.c @@ -57,7 +57,8 @@ static void customSPrintf(uint8_t *buffer, uint8_t *format, ...) */ static void objectFilename(uint32_t obj_id, uint16_t obj_inst_id, uint8_t *filename) { - uint32_t prefix = obj_id + (obj_inst_id / 256); + 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; customSPrintf(filename, (uint8_t *)"%08X.o%02X", prefix, suffix); From 320bbcf4347a346204c41f9788b1ae687dc261fc Mon Sep 17 00:00:00 2001 From: Corvus Corax Date: Sun, 17 Nov 2013 02:47:58 +0100 Subject: [PATCH 03/26] Made printf-stdarg check maximum string length limit (supports snprintf now) --- flight/libraries/printf-stdarg.c | 63 ++++++++++++++++---------------- 1 file changed, 31 insertions(+), 32 deletions(-) diff --git a/flight/libraries/printf-stdarg.c b/flight/libraries/printf-stdarg.c index e4c01552d..5f4f0c40b 100644 --- a/flight/libraries/printf-stdarg.c +++ b/flight/libraries/printf-stdarg.c @@ -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,16 @@ 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); } /** From adfbdfae38fb777651ec2e0c8c3e9f1c1063889c Mon Sep 17 00:00:00 2001 From: Corvus Corax Date: Sun, 17 Nov 2013 02:49:53 +0100 Subject: [PATCH 04/26] Make use of (now supported) standard snprintf in stdarg-printf when used in logfs --- flight/pios/common/pios_dosfs_logfs.c | 19 +++---------------- flight/pios/posix/pios_dosfs_logfs.c | 19 +++---------------- 2 files changed, 6 insertions(+), 32 deletions(-) diff --git a/flight/pios/common/pios_dosfs_logfs.c b/flight/pios/common/pios_dosfs_logfs.c index 2628646f8..0b627e542 100644 --- a/flight/pios/common/pios_dosfs_logfs.c +++ b/flight/pios/common/pios_dosfs_logfs.c @@ -30,30 +30,17 @@ #include #if defined(PIOS_INCLUDE_FREERTOS) -static xSemaphoreHandle mutex; +static xSemaphoreHandle mutex = 0; #endif struct flashfs_logfs_cfg; -/** - * Wrapper for the unimplemented sprintf function - * warning, no buffer length boundary checks, use with caution! - */ -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. * @param[in] obj The object handle. * @param[in] instId The instance ID - * @param[in] file Filename string pointer WARNING, must be 14 bytes long and allocated, no checks! + * @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) { @@ -61,7 +48,7 @@ static void objectFilename(uint32_t obj_id, uint16_t obj_inst_id, uint8_t *filen // skip least sig nibble since that is used for meta object id uint8_t suffix = obj_inst_id & 0xff; - customSPrintf(filename, (uint8_t *)"%08X.o%02X", prefix, suffix); + snprintf((char *)filename, 13, "%08X.o%02X", prefix, suffix); } diff --git a/flight/pios/posix/pios_dosfs_logfs.c b/flight/pios/posix/pios_dosfs_logfs.c index 2628646f8..0b627e542 100644 --- a/flight/pios/posix/pios_dosfs_logfs.c +++ b/flight/pios/posix/pios_dosfs_logfs.c @@ -30,30 +30,17 @@ #include #if defined(PIOS_INCLUDE_FREERTOS) -static xSemaphoreHandle mutex; +static xSemaphoreHandle mutex = 0; #endif struct flashfs_logfs_cfg; -/** - * Wrapper for the unimplemented sprintf function - * warning, no buffer length boundary checks, use with caution! - */ -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. * @param[in] obj The object handle. * @param[in] instId The instance ID - * @param[in] file Filename string pointer WARNING, must be 14 bytes long and allocated, no checks! + * @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) { @@ -61,7 +48,7 @@ static void objectFilename(uint32_t obj_id, uint16_t obj_inst_id, uint8_t *filen // skip least sig nibble since that is used for meta object id uint8_t suffix = obj_inst_id & 0xff; - customSPrintf(filename, (uint8_t *)"%08X.o%02X", prefix, suffix); + snprintf((char *)filename, 13, "%08X.o%02X", prefix, suffix); } From a0746d87fa6c07cac17944807e85937e446998b1 Mon Sep 17 00:00:00 2001 From: Corvus Corax Date: Sun, 17 Nov 2013 02:54:26 +0100 Subject: [PATCH 05/26] Logging facility: logs debug data to logfs and exports it through container UAVObject --- flight/modules/Logging/Logging.c | 106 ++++++++++ flight/pios/inc/pios_debuglog.h | 90 ++++++++ flight/pios/pios_sim_posix.h | 1 + flight/pios/posix/pios_debuglog.c | 192 ++++++++++++++++++ .../targets/boards/simposix/firmware/Makefile | 1 + .../boards/simposix/firmware/UAVObjects.inc | 3 + .../src/plugins/uavobjects/uavobjects.pro | 6 + .../uavobjectdefinition/debuglogcontrol.xml | 11 + shared/uavobjectdefinition/debuglogentry.xml | 17 ++ .../uavobjectdefinition/debuglogsettings.xml | 11 + 10 files changed, 438 insertions(+) create mode 100644 flight/modules/Logging/Logging.c create mode 100644 flight/pios/inc/pios_debuglog.h create mode 100644 flight/pios/posix/pios_debuglog.c create mode 100644 shared/uavobjectdefinition/debuglogcontrol.xml create mode 100644 shared/uavobjectdefinition/debuglogentry.xml create mode 100644 shared/uavobjectdefinition/debuglogsettings.xml 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 + + + + + + + + From 354ca88cd61d3c173faafc1055a6a951197946f3 Mon Sep 17 00:00:00 2001 From: Corvus Corax Date: Sun, 17 Nov 2013 14:00:42 +0100 Subject: [PATCH 06/26] Updated UAVObject metadata to include correct flags needed for on board logging --- flight/uavobjects/inc/uavobjectmanager.h | 16 ++++++++++------ flight/uavobjects/uavobject.c.template | 3 ++- .../templates/uavobject.java.template | 1 + .../src/plugins/uavobjects/uavmetaobject.cpp | 2 +- .../src/plugins/uavobjects/uavobject.cpp | 4 +++- .../plugins/uavobjects/uavobject.cpp.template | 3 ++- .../src/plugins/uavobjects/uavobject.h | 4 +++- 7 files changed, 22 insertions(+), 11 deletions(-) diff --git a/flight/uavobjects/inc/uavobjectmanager.h b/flight/uavobjects/inc/uavobjectmanager.h index 202c17f2e..9e681ea6b 100644 --- a/flight/uavobjects/inc/uavobjectmanager.h +++ b/flight/uavobjects/inc/uavobjectmanager.h @@ -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 diff --git a/flight/uavobjects/uavobject.c.template b/flight/uavobjects/uavobject.c.template index f7e37723f..b9f45b5ae 100644 --- a/flight/uavobjects/uavobject.c.template +++ b/flight/uavobjects/uavobject.c.template @@ -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); diff --git a/ground/openpilotgcs/src/libs/juavobjects/templates/uavobject.java.template b/ground/openpilotgcs/src/libs/juavobjects/templates/uavobject.java.template index 2944f1270..d720bf898 100644 --- a/ground/openpilotgcs/src/libs/juavobjects/templates/uavobject.java.template +++ b/ground/openpilotgcs/src/libs/juavobjects/templates/uavobject.java.template @@ -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); diff --git a/ground/openpilotgcs/src/plugins/uavobjects/uavmetaobject.cpp b/ground/openpilotgcs/src/plugins/uavobjects/uavmetaobject.cpp index 92c6d8c3b..80e4d5ed6 100644 --- a/ground/openpilotgcs/src/plugins/uavobjects/uavmetaobject.cpp +++ b/ground/openpilotgcs/src/plugins/uavobjects/uavmetaobject.cpp @@ -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 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())); diff --git a/ground/openpilotgcs/src/plugins/uavobjects/uavobject.cpp b/ground/openpilotgcs/src/plugins/uavobjects/uavobject.cpp index d795e8cb3..7f6c02a15 100644 --- a/ground/openpilotgcs/src/plugins/uavobjects/uavobject.cpp +++ b/ground/openpilotgcs/src/plugins/uavobjects/uavobject.cpp @@ -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; diff --git a/ground/openpilotgcs/src/plugins/uavobjects/uavobject.cpp.template b/ground/openpilotgcs/src/plugins/uavobjects/uavobject.cpp.template index df78735bb..a91754136 100644 --- a/ground/openpilotgcs/src/plugins/uavobjects/uavobject.cpp.template +++ b/ground/openpilotgcs/src/plugins/uavobjects/uavobject.cpp.template @@ -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); diff --git a/ground/openpilotgcs/src/plugins/uavobjects/uavobject.h b/ground/openpilotgcs/src/plugins/uavobjects/uavobject.h index 882378e7a..c7d9941d2 100644 --- a/ground/openpilotgcs/src/plugins/uavobjects/uavobject.h +++ b/ground/openpilotgcs/src/plugins/uavobjects/uavobject.h @@ -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) */ From d9a9536b61a5710b28120de1f7a5bc9a743861f8 Mon Sep 17 00:00:00 2001 From: Corvus Corax Date: Sun, 17 Nov 2013 14:53:08 +0100 Subject: [PATCH 07/26] modified uavobjectmanager to have accessor functions for the new flags --- flight/uavobjects/inc/uavobject.h.template | 2 + flight/uavobjects/inc/uavobjectmanager.h | 4 ++ flight/uavobjects/uavobjectmanager.c | 44 ++++++++++++++++++++++ 3 files changed, 50 insertions(+) diff --git a/flight/uavobjects/inc/uavobject.h.template b/flight/uavobjects/inc/uavobject.h.template index 572317f01..599ba4fb8 100644 --- a/flight/uavobjects/inc/uavobject.h.template +++ b/flight/uavobjects/inc/uavobject.h.template @@ -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()); } diff --git a/flight/uavobjects/inc/uavobjectmanager.h b/flight/uavobjects/inc/uavobjectmanager.h index 9e681ea6b..a7af203fb 100644 --- a/flight/uavobjects/inc/uavobjectmanager.h +++ b/flight/uavobjects/inc/uavobjectmanager.h @@ -194,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); @@ -203,6 +205,8 @@ 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)); #endif // UAVOBJECTMANAGER_H diff --git a/flight/uavobjects/uavobjectmanager.c b/flight/uavobjects/uavobjectmanager.c index e62ecbb7e..8b2120a4b 100644 --- a/flight/uavobjects/uavobjectmanager.c +++ b/flight/uavobjects/uavobjectmanager.c @@ -1423,6 +1423,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 @@ -1559,6 +1581,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, From 243e261411f7463b4bf04a9aee6c899aa87b7046 Mon Sep 17 00:00:00 2001 From: Corvus Corax Date: Sun, 17 Nov 2013 17:15:23 +0100 Subject: [PATCH 08/26] UAVObject logging through telemetry module and uavobjectmanager --- flight/modules/Telemetry/telemetry.c | 116 ++++++++++++++++++----- flight/uavobjects/inc/uavobjectmanager.h | 1 + flight/uavobjects/uavobjectmanager.c | 44 ++++++++- 3 files changed, 132 insertions(+), 29 deletions(-) diff --git a/flight/modules/Telemetry/telemetry.c b/flight/modules/Telemetry/telemetry.c index 2ddb3f5aa..2749121a2 100644 --- a/flight/modules/Telemetry/telemetry.c +++ b/flight/modules/Telemetry/telemetry.c @@ -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(); @@ -181,21 +182,18 @@ static void registerObject(UAVObjHandle obj) return; } else { UAVObjMetadata metadata; - UAVObjUpdateMode updateMode; + UAVObjUpdateMode updateMode, loggingMode; UAVObjGetMetadata(obj, &metadata); - updateMode = UAVObjGetTelemetryUpdateMode(&metadata); + updateMode = UAVObjGetTelemetryUpdateMode(&metadata); + loggingMode = UAVObjGetLoggingUpdateMode(&metadata); - /* 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 periodic updates + UAVObjEvent ev = { + .obj = obj, + .instId = UAVOBJ_ALL_INSTANCES, + .event = (updateMode == UPDATEMODE_PERIODIC || updateMode == UPDATEMODE_THROTTLED) ? EV_UPDATED_PERIODIC : 0 | (loggingMode == UPDATEMODE_PERIODIC || loggingMode == UPDATEMODE_THROTTLED) ? EV_LOGGING_PERIODIC : 0, + }; + EventPeriodicQueueCreate(&ev, queue, 0); // Setup object for telemetry updates updateObject(obj, EV_NONE); @@ -209,7 +207,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 +220,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 +318,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 +351,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 +495,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 diff --git a/flight/uavobjects/inc/uavobjectmanager.h b/flight/uavobjects/inc/uavobjectmanager.h index a7af203fb..349d7c3dd 100644 --- a/flight/uavobjects/inc/uavobjectmanager.h +++ b/flight/uavobjects/inc/uavobjectmanager.h @@ -208,6 +208,7 @@ 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 diff --git a/flight/uavobjects/uavobjectmanager.c b/flight/uavobjects/uavobjectmanager.c index 8b2120a4b..66117a1da 100644 --- a/flight/uavobjects/uavobjectmanager.c +++ b/flight/uavobjects/uavobjectmanager.c @@ -705,6 +705,43 @@ unlock_exit: } +/** + * Actually write the object's data to the logfile + * \param[in] obj The object handle + * \param[in] instId The object instance ID + */ +void UAVObjInstanceWriteToLog(UAVObjHandle obj_handle, uint16_t instId) +{ + PIOS_Assert(obj_handle); + + // Lock + xSemaphoreTakeRecursive(mutex, portMAX_DELAY); + + if (UAVObjIsMetaobject(obj_handle)) { + if (instId != 0) { + goto unlock_exit; + } + PIOS_DEBUGLOG_UAVObject(UAVObjGetID(obj_handle), instId, MetaNumBytes, (uint8_t *)MetaDataPtr((struct UAVOMeta *)obj_handle)); + } else { + struct UAVOData *obj; + InstanceHandle instEntry; + + // Cast handle to object + obj = (struct UAVOData *)obj_handle; + + // Get the instance + instEntry = getInstance(obj, instId); + if (instEntry == NULL) { + goto unlock_exit; + } + // Pack data + PIOS_DEBUGLOG_UAVObject(UAVObjGetID(obj_handle), instId, obj->instance_size, (uint8_t *)InstanceData(instEntry)); + } + +unlock_exit: + xSemaphoreGiveRecursive(mutex); +} + /** * Save the data of the specified object to the file system (SD card). * If the object contains multiple instances, all of them will be saved. @@ -712,10 +749,9 @@ unlock_exit: * 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); @@ -754,7 +790,7 @@ int32_t UAVObjSave(UAVObjHandle obj_handle, __attribute__((unused)) uint16_t ins * @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); @@ -794,7 +830,7 @@ 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); PIOS_FLASHFS_ObjDelete(pios_uavo_settings_fs_id, UAVObjGetID(obj_handle), instId); From 6031200aea5481e8d0c91410dc1ffb8089149798 Mon Sep 17 00:00:00 2001 From: Corvus Corax Date: Sun, 17 Nov 2013 18:04:47 +0100 Subject: [PATCH 09/26] Some fixes in debuglog to compile and run on all firmware platforms --- flight/pios/common/pios_debuglog.c | 201 +++++++++++++++++++++++++++++ flight/pios/inc/pios_debuglog.h | 2 +- flight/pios/pios.h | 1 + flight/pios/posix/pios_debuglog.c | 73 ++++++----- make/apps-defs.mk | 1 + 5 files changed, 245 insertions(+), 33 deletions(-) create mode 100644 flight/pios/common/pios_debuglog.c diff --git a/flight/pios/common/pios_debuglog.c b/flight/pios/common/pios_debuglog.c new file mode 100644 index 000000000..6ef2112fb --- /dev/null +++ b/flight/pios/common/pios_debuglog.c @@ -0,0 +1,201 @@ +/** + ****************************************************************************** + * @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; + 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(); + 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 + */ +void PIOS_DEBUGLOG_Info(uint16_t *flight, uint16_t *entry) +{ + if (flight) { + *flight = flightnum; + } + if (entry) { + *entry = lognum; + } +} + + +/** + * @} + * @} + */ diff --git a/flight/pios/inc/pios_debuglog.h b/flight/pios/inc/pios_debuglog.h index ba32631ee..e9d3e79a2 100644 --- a/flight/pios/inc/pios_debuglog.h +++ b/flight/pios/inc/pios_debuglog.h @@ -41,7 +41,7 @@ void PIOS_DEBUGLOG_Initialize(); * @brief Enables or Disables logging globally * @param[in] enable or disable logging */ -void PIOS_DEBUGLOG_Enable(bool enabled); +void PIOS_DEBUGLOG_Enable(uint8_t enabled); /** * @brief Write a debug log entry with a uavobject diff --git a/flight/pios/pios.h b/flight/pios/pios.h index 1a566627d..6ba15b104 100644 --- a/flight/pios/pios.h +++ b/flight/pios/pios.h @@ -69,6 +69,7 @@ /* #define DEBUG_LEVEL 0 */ /* #define PIOS_ENABLE_DEBUG_PINS */ #include +#include /* PIOS common functions */ #include diff --git a/flight/pios/posix/pios_debuglog.c b/flight/pios/posix/pios_debuglog.c index 369778137..6ef2112fb 100644 --- a/flight/pios/posix/pios_debuglog.c +++ b/flight/pios/posix/pios_debuglog.c @@ -51,7 +51,10 @@ static xSemaphoreHandle mutex = 0; static bool logging_enabled = false; static uint16_t flightnum = 0; static uint16_t lognum = 0; -static DebugLogEntryData buffer; +static DebugLogEntryData *buffer = 0; +#if !defined(PIOS_INCLUDE_FREERTOS) +static DebugLogEntryData staticbuffer; +#endif /* Private Function Prototypes */ @@ -62,13 +65,19 @@ void PIOS_DEBUGLOG_Initialize() { #if defined(PIOS_INCLUDE_FREERTOS) if (!mutex) { - mutex = xSemaphoreCreateRecursiveMutex(); + 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) { + while (PIOS_FLASHFS_ObjLoad(pios_user_fs_id, flightnum * 256, lognum, (uint8_t *)buffer, sizeof(DebugLogEntryData)) == 0) { flightnum++; } mutexunlock(); @@ -79,7 +88,7 @@ void PIOS_DEBUGLOG_Initialize() * @brief Enables or Disables logging globally * @param[in] enable or disable logging */ -void PIOS_DEBUGLOG_Enable(bool enabled) +void PIOS_DEBUGLOG_Enable(uint8_t enabled) { logging_enabled = enabled; } @@ -94,26 +103,26 @@ void PIOS_DEBUGLOG_Enable(bool enabled) */ void PIOS_DEBUGLOG_UAVObject(uint32_t objid, uint16_t instid, size_t size, uint8_t *data) { - if (!logging_enabled) { + if (!logging_enabled || !buffer) { return; } mutexlock(); - buffer.Flight = flightnum; + buffer->Flight = flightnum; #if defined(PIOS_INCLUDE_FREERTOS) - buffer.FlightTime = xTaskGetTickCount() * portTICK_RATE_MS; + buffer->FlightTime = xTaskGetTickCount() * portTICK_RATE_MS; #else - buffer.FlightTime = 0; + 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]; + buffer->Type = DEBUGLOGENTRY_TYPE_UAVOBJECT; + buffer->ObjectID = objid; + buffer->InstanceID = instid; + if (size > sizeof(buffer->Data)) { + size = sizeof(buffer->Data); } + buffer->Size = size; + memcpy(buffer->Data, data, size); - if (PIOS_FLASHFS_ObjSave(pios_user_fs_id, flightnum * 256, lognum, (uint8_t *)&buffer, sizeof(DebugLogEntryData)) == 0) { + if (PIOS_FLASHFS_ObjSave(pios_user_fs_id, flightnum * 256, lognum, (uint8_t *)buffer, sizeof(DebugLogEntryData)) == 0) { lognum++; } mutexunlock(); @@ -126,26 +135,26 @@ void PIOS_DEBUGLOG_UAVObject(uint32_t objid, uint16_t instid, size_t size, uint8 */ void PIOS_DEBUGLOG_Printf(char *format, ...) { - if (!logging_enabled) { + if (!logging_enabled || !buffer) { return; } va_list args; va_start(args, format); mutexlock(); - vsnprintf((char *)buffer.Data, sizeof(buffer.Data), (char *)format, args); - buffer.Flight = flightnum; + vsnprintf((char *)buffer->Data, sizeof(buffer->Data), (char *)format, args); + buffer->Flight = flightnum; #if defined(PIOS_INCLUDE_FREERTOS) - buffer.FlightTime = xTaskGetTickCount() * portTICK_RATE_MS; + buffer->FlightTime = xTaskGetTickCount() * portTICK_RATE_MS; #else - buffer.FlightTime = 0; + 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); + 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) { + if (PIOS_FLASHFS_ObjSave(pios_user_fs_id, flightnum * 256, lognum, (uint8_t *)buffer, sizeof(DebugLogEntryData)) == 0) { lognum++; } mutexunlock(); @@ -164,16 +173,16 @@ void PIOS_DEBUGLOG_Printf(char *format, ...) * @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) +int32_t PIOS_DEBUGLOG_Read(void *mybuffer, 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)); + 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] buffer where to store the uavobject - * @param[in] log entry from which flight + * @param[out] current flight number + * @param[out] next entry number */ void PIOS_DEBUGLOG_Info(uint16_t *flight, uint16_t *entry) { diff --git a/make/apps-defs.mk b/make/apps-defs.mk index 54e2e991e..801e75277 100644 --- a/make/apps-defs.mk +++ b/make/apps-defs.mk @@ -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 From 9dbac5d060f7a1f1e085f390c980ed0559cfcde7 Mon Sep 17 00:00:00 2001 From: Corvus Corax Date: Sun, 17 Nov 2013 18:49:50 +0100 Subject: [PATCH 10/26] Enabled printf-stdarg on all targets, implemented vsnprintf() (needed for logging) --- flight/libraries/printf-stdarg.c | 6 ++++++ flight/targets/boards/osd/firmware/Makefile | 2 +- make/apps-defs.mk | 1 + 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/flight/libraries/printf-stdarg.c b/flight/libraries/printf-stdarg.c index 5f4f0c40b..c0bbd31f6 100644 --- a/flight/libraries/printf-stdarg.c +++ b/flight/libraries/printf-stdarg.c @@ -246,6 +246,12 @@ int snprintf(char *buf, size_t count, const char *format, ...) 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); +} + /** * @} */ diff --git a/flight/targets/boards/osd/firmware/Makefile b/flight/targets/boards/osd/firmware/Makefile index 70ec0624f..22f4f2928 100644 --- a/flight/targets/boards/osd/firmware/Makefile +++ b/flight/targets/boards/osd/firmware/Makefile @@ -68,7 +68,7 @@ ifndef TESTAPP #endif ## Misc library functions - SRC += $(FLIGHTLIB)/printf2.c + #SRC += $(FLIGHTLIB)/printf2.c SRC += $(FLIGHTLIB)/WorldMagModel.c ## UAVObjects diff --git a/make/apps-defs.mk b/make/apps-defs.mk index 801e75277..b326b218d 100644 --- a/make/apps-defs.mk +++ b/make/apps-defs.mk @@ -103,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))) From 3d8625abaf56ec861defc0681e8e75d16ed0ad85 Mon Sep 17 00:00:00 2001 From: Corvus Corax Date: Sun, 17 Nov 2013 18:50:51 +0100 Subject: [PATCH 11/26] Enabled logging on revolution (added module and uavobjects) --- flight/targets/boards/revolution/firmware/Makefile | 1 + flight/targets/boards/revolution/firmware/UAVObjects.inc | 3 +++ 2 files changed, 4 insertions(+) diff --git a/flight/targets/boards/revolution/firmware/Makefile b/flight/targets/boards/revolution/firmware/Makefile index 07aed3b52..3202b2e1e 100644 --- a/flight/targets/boards/revolution/firmware/Makefile +++ b/flight/targets/boards/revolution/firmware/Makefile @@ -47,6 +47,7 @@ MODULES += Radio MODULES += PathPlanner MODULES += FixedWingPathFollower MODULES += Osd/osdoutout +MODULES += Logging MODULES += Telemetry OPTMODULES += ComUsbBridge diff --git a/flight/targets/boards/revolution/firmware/UAVObjects.inc b/flight/targets/boards/revolution/firmware/UAVObjects.inc index 27563043b..ff08a773e 100644 --- a/flight/targets/boards/revolution/firmware/UAVObjects.inc +++ b/flight/targets/boards/revolution/firmware/UAVObjects.inc @@ -36,6 +36,9 @@ UAVOBJSRCFILENAMES += barosensor UAVOBJSRCFILENAMES += airspeedsensor UAVOBJSRCFILENAMES += airspeedsettings UAVOBJSRCFILENAMES += airspeedstate +UAVOBJSRCFILENAMES += debuglogsettings +UAVOBJSRCFILENAMES += debuglogcontrol +UAVOBJSRCFILENAMES += debuglogentry UAVOBJSRCFILENAMES += flightbatterysettings UAVOBJSRCFILENAMES += firmwareiapobj UAVOBJSRCFILENAMES += flightbatterystate From fcc479f5cb2f1b0c58f0fbb3b08a9ec8a709eebc Mon Sep 17 00:00:00 2001 From: Corvus Corax Date: Sun, 17 Nov 2013 20:14:50 +0100 Subject: [PATCH 12/26] more intelligent log interfacing, including flash formatting option --- flight/modules/Logging/Logging.c | 49 ++++++++++++------- flight/pios/common/pios_debuglog.c | 25 +++++++++- flight/pios/inc/pios_debuglog.h | 13 +++-- flight/pios/posix/pios_debuglog.c | 25 +++++++++- .../boards/revolution/firmware/UAVObjects.inc | 1 + .../boards/simposix/firmware/UAVObjects.inc | 1 + .../src/plugins/uavobjects/uavobjects.pro | 2 + .../uavobjectdefinition/debuglogcontrol.xml | 1 + shared/uavobjectdefinition/debuglogstatus.xml | 13 +++++ 9 files changed, 108 insertions(+), 22 deletions(-) create mode 100644 shared/uavobjectdefinition/debuglogstatus.xml diff --git a/flight/modules/Logging/Logging.c b/flight/modules/Logging/Logging.c index 12441ffa4..3abb76477 100644 --- a/flight/modules/Logging/Logging.c +++ b/flight/modules/Logging/Logging.c @@ -33,22 +33,28 @@ #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) { @@ -63,10 +69,21 @@ 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) { @@ -77,26 +94,24 @@ static void SettingsUpdatedCb(__attribute__((unused)) UAVObjEvent *ev) 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 + if (control.Operation == DEBUGLOGCONTROL_OPERATION_RETRIEVE) { memset(entry, 0, sizeof(DebugLogEntryData)); - entry->Flight = control.Flight; - entry->Entry = control.Entry; - entry->Type = DEBUGLOGENTRY_TYPE_EMPTY; + 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(); + } } - PIOS_DEBUGLOG_Info(&control.Flight, &control.Entry); - - ignore = 1; // set ignore flag before setting object - creates loop otherwise!!! - DebugLogEntrySet(entry); - DebugLogControlSet(&control); + StatusUpdatedCb(ev); } diff --git a/flight/pios/common/pios_debuglog.c b/flight/pios/common/pios_debuglog.c index 6ef2112fb..79782e868 100644 --- a/flight/pios/common/pios_debuglog.c +++ b/flight/pios/common/pios_debuglog.c @@ -120,6 +120,7 @@ void PIOS_DEBUGLOG_UAVObject(uint32_t objid, uint16_t instid, size_t size, uint8 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) { @@ -141,6 +142,7 @@ void PIOS_DEBUGLOG_Printf(char *format, ...) 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) @@ -183,8 +185,10 @@ int32_t PIOS_DEBUGLOG_Read(void *mybuffer, 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) +void PIOS_DEBUGLOG_Info(uint16_t *flight, uint16_t *entry, uint16_t *free, uint16_t *used) { if (flight) { *flight = flightnum; @@ -192,8 +196,27 @@ void PIOS_DEBUGLOG_Info(uint16_t *flight, uint16_t *entry) 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(); +} /** * @} diff --git a/flight/pios/inc/pios_debuglog.h b/flight/pios/inc/pios_debuglog.h index e9d3e79a2..62023dc4d 100644 --- a/flight/pios/inc/pios_debuglog.h +++ b/flight/pios/inc/pios_debuglog.h @@ -77,10 +77,17 @@ 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 + * @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); +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 diff --git a/flight/pios/posix/pios_debuglog.c b/flight/pios/posix/pios_debuglog.c index 6ef2112fb..79782e868 100644 --- a/flight/pios/posix/pios_debuglog.c +++ b/flight/pios/posix/pios_debuglog.c @@ -120,6 +120,7 @@ void PIOS_DEBUGLOG_UAVObject(uint32_t objid, uint16_t instid, size_t size, uint8 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) { @@ -141,6 +142,7 @@ void PIOS_DEBUGLOG_Printf(char *format, ...) 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) @@ -183,8 +185,10 @@ int32_t PIOS_DEBUGLOG_Read(void *mybuffer, 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) +void PIOS_DEBUGLOG_Info(uint16_t *flight, uint16_t *entry, uint16_t *free, uint16_t *used) { if (flight) { *flight = flightnum; @@ -192,8 +196,27 @@ void PIOS_DEBUGLOG_Info(uint16_t *flight, uint16_t *entry) 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(); +} /** * @} diff --git a/flight/targets/boards/revolution/firmware/UAVObjects.inc b/flight/targets/boards/revolution/firmware/UAVObjects.inc index ff08a773e..7a63dc9f2 100644 --- a/flight/targets/boards/revolution/firmware/UAVObjects.inc +++ b/flight/targets/boards/revolution/firmware/UAVObjects.inc @@ -38,6 +38,7 @@ UAVOBJSRCFILENAMES += airspeedsettings UAVOBJSRCFILENAMES += airspeedstate UAVOBJSRCFILENAMES += debuglogsettings UAVOBJSRCFILENAMES += debuglogcontrol +UAVOBJSRCFILENAMES += debuglogstatus UAVOBJSRCFILENAMES += debuglogentry UAVOBJSRCFILENAMES += flightbatterysettings UAVOBJSRCFILENAMES += firmwareiapobj diff --git a/flight/targets/boards/simposix/firmware/UAVObjects.inc b/flight/targets/boards/simposix/firmware/UAVObjects.inc index c404b272a..be99363d3 100644 --- a/flight/targets/boards/simposix/firmware/UAVObjects.inc +++ b/flight/targets/boards/simposix/firmware/UAVObjects.inc @@ -44,6 +44,7 @@ UAVOBJSRCFILENAMES += airspeedsettings UAVOBJSRCFILENAMES += airspeedstate UAVOBJSRCFILENAMES += debuglogsettings UAVOBJSRCFILENAMES += debuglogcontrol +UAVOBJSRCFILENAMES += debuglogstatus UAVOBJSRCFILENAMES += debuglogentry UAVOBJSRCFILENAMES += flightbatterysettings UAVOBJSRCFILENAMES += firmwareiapobj diff --git a/ground/openpilotgcs/src/plugins/uavobjects/uavobjects.pro b/ground/openpilotgcs/src/plugins/uavobjects/uavobjects.pro index 4051a027f..00cd3c29d 100644 --- a/ground/openpilotgcs/src/plugins/uavobjects/uavobjects.pro +++ b/ground/openpilotgcs/src/plugins/uavobjects/uavobjects.pro @@ -36,6 +36,7 @@ HEADERS += $$UAVOBJECT_SYNTHETICS/accessorydesired.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 \ @@ -125,6 +126,7 @@ SOURCES += $$UAVOBJECT_SYNTHETICS/accessorydesired.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 \ diff --git a/shared/uavobjectdefinition/debuglogcontrol.xml b/shared/uavobjectdefinition/debuglogcontrol.xml index 6af9106f9..1599fe6da 100644 --- a/shared/uavobjectdefinition/debuglogcontrol.xml +++ b/shared/uavobjectdefinition/debuglogcontrol.xml @@ -1,6 +1,7 @@ Log Control Object + diff --git a/shared/uavobjectdefinition/debuglogstatus.xml b/shared/uavobjectdefinition/debuglogstatus.xml new file mode 100644 index 000000000..a89c12562 --- /dev/null +++ b/shared/uavobjectdefinition/debuglogstatus.xml @@ -0,0 +1,13 @@ + + + Log Control Object + + + + + + + + + + From c7431623afe2918ad4db8c55554d4688048c6b31 Mon Sep 17 00:00:00 2001 From: Corvus Corax Date: Sun, 17 Nov 2013 20:43:53 +0100 Subject: [PATCH 13/26] changed hardware definition for revolution to have usr space in just one arena (no flash garbage collection since used primarily for logging where there are no deletes) --- flight/targets/boards/revolution/board_hw_defs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flight/targets/boards/revolution/board_hw_defs.c b/flight/targets/boards/revolution/board_hw_defs.c index 6ecec9522..02b8126e2 100644 --- a/flight/targets/boards/revolution/board_hw_defs.c +++ b/flight/targets/boards/revolution/board_hw_defs.c @@ -684,7 +684,7 @@ const struct pios_rfm22b_cfg *PIOS_BOARD_HW_DEFS_GetRfm22Cfg(uint32_t board_revi static const struct flashfs_logfs_cfg flashfs_external_user_cfg = { .fs_magic = 0x99abcdef, .total_fs_size = 0x001C0000, /* 2M bytes (32 sectors = entire chip) */ - .arena_size = 0x00010000, /* 256 * slot size */ + .arena_size = 0x001C0000, /* full size, no garbage collection in usr */ .slot_size = 0x00000100, /* 256 bytes */ .start_offset = 0x40000, /* start offset */ From 3f1ea5ed09ddced6efbbe42fb1cf809303b041b5 Mon Sep 17 00:00:00 2001 From: Corvus Corax Date: Sun, 17 Nov 2013 20:45:04 +0100 Subject: [PATCH 14/26] set all uavobjects logging mode to manual enable only at users discretion as needed to preserve log space --- shared/uavobjectdefinition/airspeedstate.xml | 2 +- shared/uavobjectdefinition/altitudeholddesired.xml | 2 +- shared/uavobjectdefinition/flighttelemetrystats.xml | 2 +- shared/uavobjectdefinition/gpspositionsensor.xml | 2 +- shared/uavobjectdefinition/gpssatellites.xml | 2 +- shared/uavobjectdefinition/gpstime.xml | 2 +- shared/uavobjectdefinition/gpsvelocitysensor.xml | 2 +- shared/uavobjectdefinition/i2cstats.xml | 2 +- shared/uavobjectdefinition/mixerstatus.xml | 2 +- shared/uavobjectdefinition/oplinkstatus.xml | 2 +- shared/uavobjectdefinition/overosyncsettings.xml | 2 +- shared/uavobjectdefinition/overosyncstats.xml | 2 +- shared/uavobjectdefinition/pathaction.xml | 2 +- shared/uavobjectdefinition/pathstatus.xml | 2 +- shared/uavobjectdefinition/poilocation.xml | 2 +- shared/uavobjectdefinition/positionstate.xml | 2 +- shared/uavobjectdefinition/ratedesired.xml | 2 +- shared/uavobjectdefinition/systemalarms.xml | 2 +- shared/uavobjectdefinition/systemstats.xml | 2 +- shared/uavobjectdefinition/taskinfo.xml | 2 +- shared/uavobjectdefinition/velocitydesired.xml | 2 +- shared/uavobjectdefinition/velocitystate.xml | 2 +- shared/uavobjectdefinition/watchdogstatus.xml | 2 +- shared/uavobjectdefinition/waypoint.xml | 2 +- shared/uavobjectdefinition/waypointactive.xml | 2 +- 25 files changed, 25 insertions(+), 25 deletions(-) diff --git a/shared/uavobjectdefinition/airspeedstate.xml b/shared/uavobjectdefinition/airspeedstate.xml index 3a7db51d9..f38473bae 100644 --- a/shared/uavobjectdefinition/airspeedstate.xml +++ b/shared/uavobjectdefinition/airspeedstate.xml @@ -6,6 +6,6 @@ - + diff --git a/shared/uavobjectdefinition/altitudeholddesired.xml b/shared/uavobjectdefinition/altitudeholddesired.xml index cf056cfa0..af2dafe94 100644 --- a/shared/uavobjectdefinition/altitudeholddesired.xml +++ b/shared/uavobjectdefinition/altitudeholddesired.xml @@ -8,6 +8,6 @@ - + diff --git a/shared/uavobjectdefinition/flighttelemetrystats.xml b/shared/uavobjectdefinition/flighttelemetrystats.xml index 352bb7de0..2e371b7de 100644 --- a/shared/uavobjectdefinition/flighttelemetrystats.xml +++ b/shared/uavobjectdefinition/flighttelemetrystats.xml @@ -10,6 +10,6 @@ - + diff --git a/shared/uavobjectdefinition/gpspositionsensor.xml b/shared/uavobjectdefinition/gpspositionsensor.xml index 8686a76ef..cfaba9db0 100644 --- a/shared/uavobjectdefinition/gpspositionsensor.xml +++ b/shared/uavobjectdefinition/gpspositionsensor.xml @@ -15,6 +15,6 @@ - + diff --git a/shared/uavobjectdefinition/gpssatellites.xml b/shared/uavobjectdefinition/gpssatellites.xml index 47c4c0f56..8d3ecb8e3 100644 --- a/shared/uavobjectdefinition/gpssatellites.xml +++ b/shared/uavobjectdefinition/gpssatellites.xml @@ -9,6 +9,6 @@ - + diff --git a/shared/uavobjectdefinition/gpstime.xml b/shared/uavobjectdefinition/gpstime.xml index ab93d4e9c..1408ba2d8 100644 --- a/shared/uavobjectdefinition/gpstime.xml +++ b/shared/uavobjectdefinition/gpstime.xml @@ -10,6 +10,6 @@ - + diff --git a/shared/uavobjectdefinition/gpsvelocitysensor.xml b/shared/uavobjectdefinition/gpsvelocitysensor.xml index c94474ca2..a9fa3ce2b 100644 --- a/shared/uavobjectdefinition/gpsvelocitysensor.xml +++ b/shared/uavobjectdefinition/gpsvelocitysensor.xml @@ -7,6 +7,6 @@ - + diff --git a/shared/uavobjectdefinition/i2cstats.xml b/shared/uavobjectdefinition/i2cstats.xml index 3e79d79ea..f5cc5318a 100644 --- a/shared/uavobjectdefinition/i2cstats.xml +++ b/shared/uavobjectdefinition/i2cstats.xml @@ -14,6 +14,6 @@ - + diff --git a/shared/uavobjectdefinition/mixerstatus.xml b/shared/uavobjectdefinition/mixerstatus.xml index c7491a92e..0c33d7f24 100644 --- a/shared/uavobjectdefinition/mixerstatus.xml +++ b/shared/uavobjectdefinition/mixerstatus.xml @@ -16,6 +16,6 @@ - + diff --git a/shared/uavobjectdefinition/oplinkstatus.xml b/shared/uavobjectdefinition/oplinkstatus.xml index a0d2fded5..bcceb3751 100644 --- a/shared/uavobjectdefinition/oplinkstatus.xml +++ b/shared/uavobjectdefinition/oplinkstatus.xml @@ -31,6 +31,6 @@ - + diff --git a/shared/uavobjectdefinition/overosyncsettings.xml b/shared/uavobjectdefinition/overosyncsettings.xml index 2d884bc1a..9c70d47bb 100644 --- a/shared/uavobjectdefinition/overosyncsettings.xml +++ b/shared/uavobjectdefinition/overosyncsettings.xml @@ -5,6 +5,6 @@ - + diff --git a/shared/uavobjectdefinition/overosyncstats.xml b/shared/uavobjectdefinition/overosyncstats.xml index de069e38c..ce87c306d 100644 --- a/shared/uavobjectdefinition/overosyncstats.xml +++ b/shared/uavobjectdefinition/overosyncstats.xml @@ -11,6 +11,6 @@ - + diff --git a/shared/uavobjectdefinition/pathaction.xml b/shared/uavobjectdefinition/pathaction.xml index 983863650..16ed7a569 100644 --- a/shared/uavobjectdefinition/pathaction.xml +++ b/shared/uavobjectdefinition/pathaction.xml @@ -25,6 +25,6 @@ - + diff --git a/shared/uavobjectdefinition/pathstatus.xml b/shared/uavobjectdefinition/pathstatus.xml index 746d15c47..52352dc4a 100644 --- a/shared/uavobjectdefinition/pathstatus.xml +++ b/shared/uavobjectdefinition/pathstatus.xml @@ -11,6 +11,6 @@ - + diff --git a/shared/uavobjectdefinition/poilocation.xml b/shared/uavobjectdefinition/poilocation.xml index 6ab6f0273..52298f017 100644 --- a/shared/uavobjectdefinition/poilocation.xml +++ b/shared/uavobjectdefinition/poilocation.xml @@ -7,6 +7,6 @@ - + diff --git a/shared/uavobjectdefinition/positionstate.xml b/shared/uavobjectdefinition/positionstate.xml index f6d689741..2a054a648 100644 --- a/shared/uavobjectdefinition/positionstate.xml +++ b/shared/uavobjectdefinition/positionstate.xml @@ -7,6 +7,6 @@ - + diff --git a/shared/uavobjectdefinition/ratedesired.xml b/shared/uavobjectdefinition/ratedesired.xml index 5d68597ee..6c297c3e5 100644 --- a/shared/uavobjectdefinition/ratedesired.xml +++ b/shared/uavobjectdefinition/ratedesired.xml @@ -7,6 +7,6 @@ - + diff --git a/shared/uavobjectdefinition/systemalarms.xml b/shared/uavobjectdefinition/systemalarms.xml index faa1cc9b1..34c353d64 100644 --- a/shared/uavobjectdefinition/systemalarms.xml +++ b/shared/uavobjectdefinition/systemalarms.xml @@ -43,6 +43,6 @@ - + diff --git a/shared/uavobjectdefinition/systemstats.xml b/shared/uavobjectdefinition/systemstats.xml index e09c817a4..4d305a471 100644 --- a/shared/uavobjectdefinition/systemstats.xml +++ b/shared/uavobjectdefinition/systemstats.xml @@ -16,6 +16,6 @@ - + diff --git a/shared/uavobjectdefinition/taskinfo.xml b/shared/uavobjectdefinition/taskinfo.xml index 1886967fc..7dc843c0a 100644 --- a/shared/uavobjectdefinition/taskinfo.xml +++ b/shared/uavobjectdefinition/taskinfo.xml @@ -113,6 +113,6 @@ - + diff --git a/shared/uavobjectdefinition/velocitydesired.xml b/shared/uavobjectdefinition/velocitydesired.xml index d20f43cb6..957c09b1a 100644 --- a/shared/uavobjectdefinition/velocitydesired.xml +++ b/shared/uavobjectdefinition/velocitydesired.xml @@ -7,6 +7,6 @@ - + diff --git a/shared/uavobjectdefinition/velocitystate.xml b/shared/uavobjectdefinition/velocitystate.xml index 90a89a4dd..9b922f6a9 100644 --- a/shared/uavobjectdefinition/velocitystate.xml +++ b/shared/uavobjectdefinition/velocitystate.xml @@ -7,6 +7,6 @@ - + diff --git a/shared/uavobjectdefinition/watchdogstatus.xml b/shared/uavobjectdefinition/watchdogstatus.xml index 2adef2c87..8bbc275e5 100644 --- a/shared/uavobjectdefinition/watchdogstatus.xml +++ b/shared/uavobjectdefinition/watchdogstatus.xml @@ -6,6 +6,6 @@ - + diff --git a/shared/uavobjectdefinition/waypoint.xml b/shared/uavobjectdefinition/waypoint.xml index 2a27f7fd5..e2c5b944a 100644 --- a/shared/uavobjectdefinition/waypoint.xml +++ b/shared/uavobjectdefinition/waypoint.xml @@ -7,6 +7,6 @@ - + diff --git a/shared/uavobjectdefinition/waypointactive.xml b/shared/uavobjectdefinition/waypointactive.xml index 3343715b5..d38b82713 100644 --- a/shared/uavobjectdefinition/waypointactive.xml +++ b/shared/uavobjectdefinition/waypointactive.xml @@ -5,6 +5,6 @@ - + From c6031ed9632f422b269eb40e648a787e61dd11da Mon Sep 17 00:00:00 2001 From: Corvus Corax Date: Sun, 17 Nov 2013 21:03:08 +0100 Subject: [PATCH 15/26] fixed usr flash system definition --- flight/targets/boards/revolution/board_hw_defs.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/flight/targets/boards/revolution/board_hw_defs.c b/flight/targets/boards/revolution/board_hw_defs.c index 02b8126e2..78d106cbc 100644 --- a/flight/targets/boards/revolution/board_hw_defs.c +++ b/flight/targets/boards/revolution/board_hw_defs.c @@ -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 = 0x001C0000, /* full size, no garbage collection in usr */ + .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 */ }; From 0e502d373487463b8cfefbd892de34f861da316e Mon Sep 17 00:00:00 2001 From: Corvus Corax Date: Sun, 17 Nov 2013 22:10:03 +0100 Subject: [PATCH 16/26] Modified queue creation for telemetry and logging event queues are now created for all uavobjects for both telemetry and logging, so later modifications from manual to periodic are possible --- flight/modules/Telemetry/telemetry.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/flight/modules/Telemetry/telemetry.c b/flight/modules/Telemetry/telemetry.c index 2749121a2..239aa33e1 100644 --- a/flight/modules/Telemetry/telemetry.c +++ b/flight/modules/Telemetry/telemetry.c @@ -191,9 +191,12 @@ static void registerObject(UAVObjHandle obj) UAVObjEvent ev = { .obj = obj, .instId = UAVOBJ_ALL_INSTANCES, - .event = (updateMode == UPDATEMODE_PERIODIC || updateMode == UPDATEMODE_THROTTLED) ? EV_UPDATED_PERIODIC : 0 | (loggingMode == UPDATEMODE_PERIODIC || loggingMode == UPDATEMODE_THROTTLED) ? EV_LOGGING_PERIODIC : 0, + .event = EV_UPDATED_PERIODIC, }; EventPeriodicQueueCreate(&ev, queue, 0); + ev.event = EV_LOGGING_PERIODIC; + EventPeriodicQueueCreate(&ev, queue, 0); + // Setup object for telemetry updates updateObject(obj, EV_NONE); From 951c7bfea042377ac189560540b8207021276db7 Mon Sep 17 00:00:00 2001 From: Corvus Corax Date: Sun, 17 Nov 2013 22:20:19 +0100 Subject: [PATCH 17/26] removed redundant code from Telemetry --- flight/modules/Telemetry/telemetry.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/flight/modules/Telemetry/telemetry.c b/flight/modules/Telemetry/telemetry.c index 239aa33e1..c43cddff7 100644 --- a/flight/modules/Telemetry/telemetry.c +++ b/flight/modules/Telemetry/telemetry.c @@ -181,12 +181,6 @@ static void registerObject(UAVObjHandle obj) UAVObjConnectQueue(obj, priorityQueue, EV_MASK_ALL_UPDATES); return; } else { - UAVObjMetadata metadata; - UAVObjUpdateMode updateMode, loggingMode; - UAVObjGetMetadata(obj, &metadata); - updateMode = UAVObjGetTelemetryUpdateMode(&metadata); - loggingMode = UAVObjGetLoggingUpdateMode(&metadata); - // Setup object for periodic updates UAVObjEvent ev = { .obj = obj, From 9414f3513f93b8c25266fd2b8e48e89a2ce4dc77 Mon Sep 17 00:00:00 2001 From: Corvus Corax Date: Sun, 17 Nov 2013 22:39:39 +0100 Subject: [PATCH 18/26] adapted telemetry stack sizes for flight firmware to include more space needed for logging feature --- flight/targets/boards/coptercontrol/firmware/inc/pios_config.h | 2 +- flight/targets/boards/oplinkmini/firmware/inc/pios_config.h | 2 +- flight/targets/boards/osd/pios_board.h | 2 +- flight/targets/boards/revolution/pios_board.h | 2 +- flight/targets/boards/revoproto/pios_board.h | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/flight/targets/boards/coptercontrol/firmware/inc/pios_config.h b/flight/targets/boards/coptercontrol/firmware/inc/pios_config.h index 09f9b0b51..a8970239b 100644 --- a/flight/targets/boards/coptercontrol/firmware/inc/pios_config.h +++ b/flight/targets/boards/coptercontrol/firmware/inc/pios_config.h @@ -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 */ diff --git a/flight/targets/boards/oplinkmini/firmware/inc/pios_config.h b/flight/targets/boards/oplinkmini/firmware/inc/pios_config.h index 97f307cb5..ef965b0af 100644 --- a/flight/targets/boards/oplinkmini/firmware/inc/pios_config.h +++ b/flight/targets/boards/oplinkmini/firmware/inc/pios_config.h @@ -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 */ diff --git a/flight/targets/boards/osd/pios_board.h b/flight/targets/boards/osd/pios_board.h index 16dafb34f..9b88a5e3b 100644 --- a/flight/targets/boards/osd/pios_board.h +++ b/flight/targets/boards/osd/pios_board.h @@ -102,7 +102,7 @@ // TELEMETRY // ------------------------ #define TELEM_QUEUE_SIZE 20 -#define PIOS_TELEM_STACK_SIZE 624 +#define PIOS_TELEM_STACK_SIZE 800 // ***************************************************************** // Interrupt Priorities diff --git a/flight/targets/boards/revolution/pios_board.h b/flight/targets/boards/revolution/pios_board.h index d6843c7e6..de47db80a 100644 --- a/flight/targets/boards/revolution/pios_board.h +++ b/flight/targets/boards/revolution/pios_board.h @@ -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 diff --git a/flight/targets/boards/revoproto/pios_board.h b/flight/targets/boards/revoproto/pios_board.h index 2c3dd65cb..6da2bbd9c 100644 --- a/flight/targets/boards/revoproto/pios_board.h +++ b/flight/targets/boards/revoproto/pios_board.h @@ -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 From 3bfe74e73cfa7371dab4738a9d698dfb035d7923 Mon Sep 17 00:00:00 2001 From: Corvus Corax Date: Tue, 19 Nov 2013 18:55:38 +0100 Subject: [PATCH 19/26] added some in uavobject definition comments --- shared/uavobjectdefinition/debuglogcontrol.xml | 10 +++++++++- shared/uavobjectdefinition/debuglogstatus.xml | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/shared/uavobjectdefinition/debuglogcontrol.xml b/shared/uavobjectdefinition/debuglogcontrol.xml index 1599fe6da..2a4b5a84a 100644 --- a/shared/uavobjectdefinition/debuglogcontrol.xml +++ b/shared/uavobjectdefinition/debuglogcontrol.xml @@ -1,6 +1,14 @@ - Log Control Object + Log Control Object - Used to issue commands to the on board logging system + diff --git a/shared/uavobjectdefinition/debuglogstatus.xml b/shared/uavobjectdefinition/debuglogstatus.xml index a89c12562..0d510a332 100644 --- a/shared/uavobjectdefinition/debuglogstatus.xml +++ b/shared/uavobjectdefinition/debuglogstatus.xml @@ -1,6 +1,6 @@ - Log Control Object + Log Status Object, contains log partition status information From 77b7ba3089bce90f0ac92ac3d3dab339c3722ee0 Mon Sep 17 00:00:00 2001 From: Corvus Corax Date: Tue, 19 Nov 2013 19:29:24 +0100 Subject: [PATCH 20/26] Added new setting 'OnlyWhenArmed' to debuglogsettings --- flight/modules/Logging/Logging.c | 22 +++++++++++++++++-- .../uavobjectdefinition/debuglogsettings.xml | 2 +- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/flight/modules/Logging/Logging.c b/flight/modules/Logging/Logging.c index 3abb76477..3cf7d2a78 100644 --- a/flight/modules/Logging/Logging.c +++ b/flight/modules/Logging/Logging.c @@ -41,12 +41,14 @@ static DebugLogSettingsData settings; static DebugLogControlData control; static DebugLogStatusData status; +static FlightStatusData flightstatus; 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); +static void FlightStatusUpdatedCb(UAVObjEvent *ev); int32_t LoggingInitialize(void) { @@ -68,6 +70,7 @@ int32_t LoggingStart(void) { DebugLogSettingsConnectCallback(SettingsUpdatedCb); DebugLogControlConnectCallback(ControlUpdatedCb); + FlightStatusConnectCallback(FlightStatusUpdatedCb); SettingsUpdatedCb(DebugLogSettingsHandle()); UAVObjEvent ev = { .obj = DebugLogSettingsHandle(), .instId = 0, .event = EV_UPDATED_PERIODIC }; @@ -85,11 +88,26 @@ static void StatusUpdatedCb(__attribute__((unused)) UAVObjEvent *ev) DebugLogStatusSet(&status); } +static void FlightStatusUpdatedCb(__attribute__((unused)) UAVObjEvent *ev) +{ + FlightStatusGet(&flightstatus); + switch (settings.LoggingEnabled) { + case DEBUGLOGSETTINGS_LOGGINGENABLED_ALWAYS: + PIOS_DEBUGLOG_Enable(1); + break; + case DEBUGLOGSETTINGS_LOGGINGENABLED_ONLYWHENARMED: + PIOS_DEBUGLOG_Enable(flightstatus.Armed == FLIGHTSTATUS_ARMED_ARMED); + break; + default: + PIOS_DEBUGLOG_Enable(0); + } +} + static void SettingsUpdatedCb(__attribute__((unused)) UAVObjEvent *ev) { DebugLogSettingsGet(&settings); - PIOS_DEBUGLOG_Enable(settings.LoggingEnabled); - PIOS_DEBUGLOG_Printf("Logging enabled"); + FlightStatusUpdatedCb(NULL); + PIOS_DEBUGLOG_Printf("On board logging enabled."); } static void ControlUpdatedCb(__attribute__((unused)) UAVObjEvent *ev) diff --git a/shared/uavobjectdefinition/debuglogsettings.xml b/shared/uavobjectdefinition/debuglogsettings.xml index 05587dedc..cb5fef6ed 100644 --- a/shared/uavobjectdefinition/debuglogsettings.xml +++ b/shared/uavobjectdefinition/debuglogsettings.xml @@ -1,7 +1,7 @@ Configure On Board Logging Facilities - + From 32b5ff22cf7e188f1ff1b33a8b39410fe78b6742 Mon Sep 17 00:00:00 2001 From: Corvus Corax Date: Sun, 24 Nov 2013 15:27:33 +0100 Subject: [PATCH 21/26] cleanup defect in OP-Review-586 --- flight/targets/boards/osd/firmware/Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/flight/targets/boards/osd/firmware/Makefile b/flight/targets/boards/osd/firmware/Makefile index 22f4f2928..90bc9618e 100644 --- a/flight/targets/boards/osd/firmware/Makefile +++ b/flight/targets/boards/osd/firmware/Makefile @@ -68,7 +68,6 @@ ifndef TESTAPP #endif ## Misc library functions - #SRC += $(FLIGHTLIB)/printf2.c SRC += $(FLIGHTLIB)/WorldMagModel.c ## UAVObjects From 89afbde58ad169624485e416aa7c3d19d8d8614c Mon Sep 17 00:00:00 2001 From: Corvus Corax Date: Sun, 24 Nov 2013 15:36:26 +0100 Subject: [PATCH 22/26] initialized log packages with 0xff instead of 0x0 to reduce flash wear --- flight/pios/common/pios_debuglog.c | 4 ++-- flight/pios/posix/pios_debuglog.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/flight/pios/common/pios_debuglog.c b/flight/pios/common/pios_debuglog.c index 79782e868..d87b655af 100644 --- a/flight/pios/common/pios_debuglog.c +++ b/flight/pios/common/pios_debuglog.c @@ -120,7 +120,7 @@ void PIOS_DEBUGLOG_UAVObject(uint32_t objid, uint16_t instid, size_t size, uint8 size = sizeof(buffer->Data); } buffer->Size = size; - memset(buffer->Data, 0, sizeof(buffer->Data)); + memset(buffer->Data, 0xff, sizeof(buffer->Data)); memcpy(buffer->Data, data, size); if (PIOS_FLASHFS_ObjSave(pios_user_fs_id, flightnum * 256, lognum, (uint8_t *)buffer, sizeof(DebugLogEntryData)) == 0) { @@ -142,7 +142,7 @@ void PIOS_DEBUGLOG_Printf(char *format, ...) va_list args; va_start(args, format); mutexlock(); - memset(buffer->Data, 0, sizeof(buffer->Data)); + memset(buffer->Data, 0xff, sizeof(buffer->Data)); vsnprintf((char *)buffer->Data, sizeof(buffer->Data), (char *)format, args); buffer->Flight = flightnum; #if defined(PIOS_INCLUDE_FREERTOS) diff --git a/flight/pios/posix/pios_debuglog.c b/flight/pios/posix/pios_debuglog.c index 79782e868..d87b655af 100644 --- a/flight/pios/posix/pios_debuglog.c +++ b/flight/pios/posix/pios_debuglog.c @@ -120,7 +120,7 @@ void PIOS_DEBUGLOG_UAVObject(uint32_t objid, uint16_t instid, size_t size, uint8 size = sizeof(buffer->Data); } buffer->Size = size; - memset(buffer->Data, 0, sizeof(buffer->Data)); + memset(buffer->Data, 0xff, sizeof(buffer->Data)); memcpy(buffer->Data, data, size); if (PIOS_FLASHFS_ObjSave(pios_user_fs_id, flightnum * 256, lognum, (uint8_t *)buffer, sizeof(DebugLogEntryData)) == 0) { @@ -142,7 +142,7 @@ void PIOS_DEBUGLOG_Printf(char *format, ...) va_list args; va_start(args, format); mutexlock(); - memset(buffer->Data, 0, sizeof(buffer->Data)); + memset(buffer->Data, 0xff, sizeof(buffer->Data)); vsnprintf((char *)buffer->Data, sizeof(buffer->Data), (char *)format, args); buffer->Flight = flightnum; #if defined(PIOS_INCLUDE_FREERTOS) From 18ad56d4ed5d80be1e02b39e46d9772e2f1edd82 Mon Sep 17 00:00:00 2001 From: Corvus Corax Date: Sun, 24 Nov 2013 15:40:32 +0100 Subject: [PATCH 23/26] removed identical files from pios/posix (use files from common instead) --- flight/pios/posix/pios_debuglog.c | 224 --------------- flight/pios/posix/pios_dosfs_logfs.c | 261 ------------------ .../targets/boards/simposix/firmware/Makefile | 2 + 3 files changed, 2 insertions(+), 485 deletions(-) delete mode 100644 flight/pios/posix/pios_debuglog.c delete mode 100644 flight/pios/posix/pios_dosfs_logfs.c diff --git a/flight/pios/posix/pios_debuglog.c b/flight/pios/posix/pios_debuglog.c deleted file mode 100644 index d87b655af..000000000 --- a/flight/pios/posix/pios_debuglog.c +++ /dev/null @@ -1,224 +0,0 @@ -/** - ****************************************************************************** - * @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, 0xff, sizeof(buffer->Data)); - memcpy(buffer->Data, data, size); - - if (PIOS_FLASHFS_ObjSave(pios_user_fs_id, flightnum * 256, lognum, (uint8_t *)buffer, sizeof(DebugLogEntryData)) == 0) { - 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, 0xff, 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(); -} - -/** - * @} - * @} - */ diff --git a/flight/pios/posix/pios_dosfs_logfs.c b/flight/pios/posix/pios_dosfs_logfs.c deleted file mode 100644 index 0b627e542..000000000 --- a/flight/pios/posix/pios_dosfs_logfs.c +++ /dev/null @@ -1,261 +0,0 @@ -/** - ****************************************************************************** - * @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 - -#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 */ - -/** - * @} - * @} - */ diff --git a/flight/targets/boards/simposix/firmware/Makefile b/flight/targets/boards/simposix/firmware/Makefile index ed04e470f..c9d719334 100644 --- a/flight/targets/boards/simposix/firmware/Makefile +++ b/flight/targets/boards/simposix/firmware/Makefile @@ -98,6 +98,8 @@ SRC += $(MATHLIB)/sin_lookup.c SRC += $(MATHLIB)/pid.c SRC += $(PIOSCORECOMMON)/pios_task_monitor.c +SRC += $(PIOSCORECOMMON)/pios_dosfs_logfs.c +SRC += $(PIOSCORECOMMON)/pios_debuglog.c ## PIOS Hardware include $(PIOS)/posix/library.mk From 2fc34910e0ad599f9492e965d4c82501266ff1f9 Mon Sep 17 00:00:00 2001 From: Fredrik Arvidsson Date: Sat, 23 Nov 2013 23:36:23 +0100 Subject: [PATCH 24/26] OP-1119 Fix in pios function for debuglogging uavo. --- flight/pios/common/pios_debuglog.c | 1 + 1 file changed, 1 insertion(+) diff --git a/flight/pios/common/pios_debuglog.c b/flight/pios/common/pios_debuglog.c index d87b655af..1c7a4e191 100644 --- a/flight/pios/common/pios_debuglog.c +++ b/flight/pios/common/pios_debuglog.c @@ -113,6 +113,7 @@ void PIOS_DEBUGLOG_UAVObject(uint32_t objid, uint16_t instid, size_t size, uint8 #else buffer->FlightTime = 0; #endif + buffer->Entry = lognum; buffer->Type = DEBUGLOGENTRY_TYPE_UAVOBJECT; buffer->ObjectID = objid; buffer->InstanceID = instid; From 25fd3d5740f2e564133599c93a469db3391f4778 Mon Sep 17 00:00:00 2001 From: Corvus Corax Date: Tue, 26 Nov 2013 00:43:02 +0100 Subject: [PATCH 25/26] Just uncrustification --- flight/pios/common/pios_debuglog.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/flight/pios/common/pios_debuglog.c b/flight/pios/common/pios_debuglog.c index 1c7a4e191..167e33329 100644 --- a/flight/pios/common/pios_debuglog.c +++ b/flight/pios/common/pios_debuglog.c @@ -113,8 +113,8 @@ void PIOS_DEBUGLOG_UAVObject(uint32_t objid, uint16_t instid, size_t size, uint8 #else buffer->FlightTime = 0; #endif - buffer->Entry = lognum; - buffer->Type = DEBUGLOGENTRY_TYPE_UAVOBJECT; + buffer->Entry = lognum; + buffer->Type = DEBUGLOGENTRY_TYPE_UAVOBJECT; buffer->ObjectID = objid; buffer->InstanceID = instid; if (size > sizeof(buffer->Data)) { From 9c6abef89ba88ae7bea22cbaade4669451b7c2bb Mon Sep 17 00:00:00 2001 From: Corvus Corax Date: Sun, 1 Dec 2013 00:03:24 +0100 Subject: [PATCH 26/26] fixed enabled and disabled messages for logging in all cases --- flight/modules/Logging/Logging.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/flight/modules/Logging/Logging.c b/flight/modules/Logging/Logging.c index 3cf7d2a78..504b58abf 100644 --- a/flight/modules/Logging/Logging.c +++ b/flight/modules/Logging/Logging.c @@ -91,23 +91,29 @@ static void StatusUpdatedCb(__attribute__((unused)) UAVObjEvent *ev) static void FlightStatusUpdatedCb(__attribute__((unused)) UAVObjEvent *ev) { FlightStatusGet(&flightstatus); - switch (settings.LoggingEnabled) { - case DEBUGLOGSETTINGS_LOGGINGENABLED_ALWAYS: - PIOS_DEBUGLOG_Enable(1); - break; - case DEBUGLOGSETTINGS_LOGGINGENABLED_ONLYWHENARMED: - PIOS_DEBUGLOG_Enable(flightstatus.Armed == FLIGHTSTATUS_ARMED_ARMED); - break; - default: - PIOS_DEBUGLOG_Enable(0); + if (settings.LoggingEnabled == DEBUGLOGSETTINGS_LOGGINGENABLED_ONLYWHENARMED) { + if (flightstatus.Armed != FLIGHTSTATUS_ARMED_ARMED) { + PIOS_DEBUGLOG_Printf("FlightStatus Disarmed: On board Logging disabled."); + PIOS_DEBUGLOG_Enable(0); + } else { + PIOS_DEBUGLOG_Enable(1); + PIOS_DEBUGLOG_Printf("FlightStatus Armed: On board logging enabled."); + } } } static void SettingsUpdatedCb(__attribute__((unused)) UAVObjEvent *ev) { DebugLogSettingsGet(&settings); - FlightStatusUpdatedCb(NULL); - PIOS_DEBUGLOG_Printf("On board logging enabled."); + if (settings.LoggingEnabled == DEBUGLOGSETTINGS_LOGGINGENABLED_ALWAYS) { + PIOS_DEBUGLOG_Enable(1); + PIOS_DEBUGLOG_Printf("On board logging enabled."); + } else if (settings.LoggingEnabled == DEBUGLOGSETTINGS_LOGGINGENABLED_DISABLED) { + PIOS_DEBUGLOG_Printf("On board logging disabled."); + PIOS_DEBUGLOG_Enable(0); + } else { + FlightStatusUpdatedCb(NULL); + } } static void ControlUpdatedCb(__attribute__((unused)) UAVObjEvent *ev)