2010-09-27 09:28:34 +02:00
|
|
|
/**
|
|
|
|
******************************************************************************
|
2015-08-18 15:25:33 +02:00
|
|
|
* @addtogroup LibrePilotModules LibrePilot Modules
|
|
|
|
* @brief The LibrePilot Modules do the majority of the control in LibrePilot. The
|
2010-09-27 09:28:34 +02:00
|
|
|
* @ref SystemModule "System Module" starts all the other modules that then take care
|
2013-05-19 16:37:30 +02:00
|
|
|
* of all the telemetry and control algorithms and such. This is done through the @ref PIOS
|
2010-09-27 09:28:34 +02:00
|
|
|
* "PIOS Hardware abstraction layer" which then contains hardware specific implementations
|
|
|
|
* (currently only STM32 supported)
|
|
|
|
*
|
2013-05-19 16:37:30 +02:00
|
|
|
* @{
|
2010-09-27 09:28:34 +02:00
|
|
|
* @addtogroup SystemModule System Module
|
|
|
|
* @brief Initializes PIOS and other modules runs monitoring
|
|
|
|
* After initializing all the modules (currently selected by Makefile but in
|
|
|
|
* future controlled by configuration on SD card) runs basic monitoring and
|
|
|
|
* alarms.
|
2013-05-19 16:37:30 +02:00
|
|
|
* @{
|
2010-09-27 09:28:34 +02:00
|
|
|
*
|
|
|
|
* @file systemmod.c
|
2016-12-16 20:27:07 +01:00
|
|
|
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015-2016.
|
2015-08-18 15:25:33 +02:00
|
|
|
* The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2015.
|
2010-09-27 09:28:34 +02:00
|
|
|
* @brief System module
|
|
|
|
*
|
|
|
|
* @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
|
|
|
|
*/
|
|
|
|
|
2013-04-01 16:41:12 +02:00
|
|
|
#include <openpilot.h>
|
|
|
|
// private includes
|
|
|
|
#include "inc/systemmod.h"
|
2014-08-13 15:14:55 +02:00
|
|
|
|
|
|
|
#include <notification.h>
|
|
|
|
#ifdef PIOS_INCLUDE_WS2811
|
|
|
|
#include <lednotification.h>
|
|
|
|
#endif
|
2013-09-01 12:10:55 +02:00
|
|
|
|
2013-04-01 16:41:12 +02:00
|
|
|
// UAVOs
|
|
|
|
#include <objectpersistence.h>
|
|
|
|
#include <flightstatus.h>
|
|
|
|
#include <systemstats.h>
|
|
|
|
#include <systemsettings.h>
|
|
|
|
#include <i2cstats.h>
|
|
|
|
#include <taskinfo.h>
|
|
|
|
#include <watchdogstatus.h>
|
2014-02-02 19:54:17 +01:00
|
|
|
#include <callbackinfo.h>
|
2013-04-01 16:41:12 +02:00
|
|
|
#include <hwsettings.h>
|
2013-06-09 19:20:00 +02:00
|
|
|
#include <pios_flashfs.h>
|
2014-08-13 15:14:55 +02:00
|
|
|
#include <pios_notify.h>
|
2015-08-17 16:29:44 +02:00
|
|
|
#include <pios_task_monitor.h>
|
2015-11-08 18:44:10 +01:00
|
|
|
#include <pios_board_init.h>
|
2017-02-21 18:48:00 +01:00
|
|
|
#include <pios_board_io.h>
|
2014-06-07 17:43:36 +02:00
|
|
|
|
|
|
|
#ifdef PIOS_INCLUDE_INSTRUMENTATION
|
|
|
|
#include <instrumentation.h>
|
|
|
|
#include <pios_instrumentation.h>
|
|
|
|
#endif
|
|
|
|
|
2013-06-15 22:50:13 +02:00
|
|
|
#if defined(PIOS_INCLUDE_RFM22B)
|
|
|
|
#include <oplinkstatus.h>
|
|
|
|
#endif
|
2013-04-19 23:56:45 +02:00
|
|
|
|
2013-04-01 16:41:12 +02:00
|
|
|
// Flight Libraries
|
2013-03-30 19:57:16 +01:00
|
|
|
#include <sanitycheck.h>
|
|
|
|
|
2010-09-27 09:28:34 +02:00
|
|
|
|
2013-05-19 16:37:30 +02:00
|
|
|
// #define DEBUG_THIS_FILE
|
2012-10-11 06:07:12 +02:00
|
|
|
|
|
|
|
#if defined(PIOS_INCLUDE_DEBUG_CONSOLE) && defined(DEBUG_THIS_FILE)
|
2013-05-19 16:37:30 +02:00
|
|
|
#define DEBUG_MSG(format, ...) PIOS_COM_SendFormattedString(PIOS_COM_DEBUG, format,##__VA_ARGS__)
|
2012-10-11 06:07:12 +02:00
|
|
|
#else
|
|
|
|
#define DEBUG_MSG(format, ...)
|
|
|
|
#endif
|
|
|
|
|
2010-09-27 09:28:34 +02:00
|
|
|
// Private constants
|
2014-04-13 17:42:57 +02:00
|
|
|
#define SYSTEM_UPDATE_PERIOD_MS 250
|
2011-05-07 22:07:14 +02:00
|
|
|
|
2014-04-12 22:00:02 +02:00
|
|
|
#if defined(PIOS_SYSTEM_STACK_SIZE)
|
|
|
|
#define STACK_SIZE_BYTES PIOS_SYSTEM_STACK_SIZE
|
|
|
|
#else
|
|
|
|
#define STACK_SIZE_BYTES 1024
|
2011-05-07 22:07:14 +02:00
|
|
|
#endif
|
2011-04-30 10:56:52 +02:00
|
|
|
|
2014-04-13 17:42:57 +02:00
|
|
|
#define TASK_PRIORITY (tskIDLE_PRIORITY + 1)
|
2010-09-27 09:28:34 +02:00
|
|
|
|
|
|
|
// Private types
|
|
|
|
|
|
|
|
// Private variables
|
|
|
|
static xTaskHandle systemTaskHandle;
|
2012-07-23 06:03:27 +02:00
|
|
|
static xQueueHandle objectPersistenceQueue;
|
2014-02-16 12:50:40 +01:00
|
|
|
static enum { STACKOVERFLOW_NONE = 0, STACKOVERFLOW_WARNING = 1, STACKOVERFLOW_CRITICAL = 3 } stackOverflow;
|
2011-08-22 05:14:32 +02:00
|
|
|
static bool mallocFailed;
|
2013-03-30 19:57:16 +01:00
|
|
|
static HwSettingsData bootHwSettings;
|
2014-06-29 17:23:15 +02:00
|
|
|
static FrameType_t bootFrameType;
|
2014-04-12 22:00:02 +02:00
|
|
|
|
2014-12-04 01:23:35 +01:00
|
|
|
volatile int initTaskDone = 0;
|
|
|
|
|
2010-09-27 09:28:34 +02:00
|
|
|
// Private functions
|
2013-05-19 16:37:30 +02:00
|
|
|
static void objectUpdatedCb(UAVObjEvent *ev);
|
2014-06-29 17:23:15 +02:00
|
|
|
static void checkSettingsUpdatedCb(UAVObjEvent *ev);
|
2013-05-02 23:31:14 +02:00
|
|
|
#ifdef DIAG_TASKS
|
|
|
|
static void taskMonitorForEachCallback(uint16_t task_id, const struct pios_task_info *task_info, void *context);
|
2014-02-07 22:34:27 +01:00
|
|
|
static void callbackSchedulerForEachCallback(int16_t callback_id, const struct pios_callback_info *callback_info, void *context);
|
2013-05-02 23:31:14 +02:00
|
|
|
#endif
|
2010-09-27 09:28:34 +02:00
|
|
|
static void updateStats();
|
|
|
|
static void updateSystemAlarms();
|
|
|
|
static void systemTask(void *parameters);
|
2011-06-18 18:59:02 +02:00
|
|
|
static void updateI2Cstats();
|
2016-12-05 13:02:36 +01:00
|
|
|
#ifdef DIAG_I2C_WDG_STATS
|
2011-06-18 18:59:02 +02:00
|
|
|
static void updateWDGstats();
|
|
|
|
#endif
|
2013-06-09 19:20:00 +02:00
|
|
|
|
2016-12-05 13:02:36 +01:00
|
|
|
#ifdef PIOS_INCLUDE_I2C
|
|
|
|
#define I2C_ERROR_ACTIVITY_TIMEOUT_SECONDS 2
|
|
|
|
#define I2C_ERROR_ACTIVITY_TIMEOUT (I2C_ERROR_ACTIVITY_TIMEOUT_SECONDS * 1000 / SYSTEM_UPDATE_PERIOD_MS)
|
|
|
|
static uint8_t i2c_error_activity[PIOS_I2C_ERROR_COUNT_NUMELEM];
|
|
|
|
#endif
|
|
|
|
|
2016-10-04 00:41:40 +02:00
|
|
|
#ifdef PIOS_INCLUDE_RFM22B
|
2016-12-22 18:49:19 +01:00
|
|
|
static uint8_t previousRFXtalCap;
|
2016-12-16 20:27:07 +01:00
|
|
|
static void oplinkSettingsUpdatedCb(UAVObjEvent *ev);
|
2016-10-04 00:41:40 +02:00
|
|
|
#endif
|
|
|
|
|
2013-06-09 19:20:00 +02:00
|
|
|
extern uintptr_t pios_uavo_settings_fs_id;
|
|
|
|
extern uintptr_t pios_user_fs_id;
|
|
|
|
|
2010-09-27 09:28:34 +02:00
|
|
|
/**
|
2011-06-20 07:35:40 +02:00
|
|
|
* Create the module task.
|
|
|
|
* \returns 0 on success or -1 if initialization failed
|
2010-09-27 09:28:34 +02:00
|
|
|
*/
|
2011-06-20 07:35:40 +02:00
|
|
|
int32_t SystemModStart(void)
|
2010-09-27 09:28:34 +02:00
|
|
|
{
|
2013-04-17 20:23:49 +02:00
|
|
|
// Initialize vars
|
2014-02-07 22:34:27 +01:00
|
|
|
stackOverflow = STACKOVERFLOW_NONE;
|
2013-05-19 16:37:30 +02:00
|
|
|
mallocFailed = false;
|
2013-04-17 20:23:49 +02:00
|
|
|
// Create system task
|
2014-06-18 01:47:43 +02:00
|
|
|
xTaskCreate(systemTask, "System", STACK_SIZE_BYTES / 4, NULL, TASK_PRIORITY, &systemTaskHandle);
|
2013-04-17 20:23:49 +02:00
|
|
|
|
|
|
|
return 0;
|
2010-09-27 09:28:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2011-06-20 07:35:40 +02:00
|
|
|
* Initialize the module, called on startup.
|
|
|
|
* \returns 0 on success or -1 if initialization failed
|
2010-09-27 09:28:34 +02:00
|
|
|
*/
|
2011-06-20 07:35:40 +02:00
|
|
|
int32_t SystemModInitialize(void)
|
2010-09-27 09:28:34 +02:00
|
|
|
{
|
2013-04-17 20:23:49 +02:00
|
|
|
// Must registers objects here for system thread because ObjectManager started in OpenPilotInit
|
|
|
|
SystemSettingsInitialize();
|
|
|
|
SystemStatsInitialize();
|
|
|
|
FlightStatusInitialize();
|
|
|
|
ObjectPersistenceInitialize();
|
Final step: lot of small fixes, last commit in this commit series
This is the first cleanup pass through makefiles and pios.
Probably it is difficult to track changes due to the nature of them.
I would recommend to look at resulting files and compiled code instead.
NOTE: original branch was rebased and lot of conflicts were fixed on
the way. So do not expect that every commit in this series will be
buildable (unlike original branch). Only final result was tested.
The main goal was to remove as much duplication of code (and copy/paste
errors) as possible, moving common parts out of Makefiles. It still is
not perfect, and mostly no code changes made - Makefiles and #ifdefs only.
But please while testing make sure that all code works as before, and no
modules/options are missed by accident.
Brief list of changes:
- Moved common parts of Makefiles into the set of *.mk files.
- Changed method of passing common vars from top Makefile to lower ones.
- Some pios cleanup, mostly #ifdefs, and all pios_config.h files.
- Many obsolete files removed (for instance, AHRS files, op_config.h).
- Many obsolete or unused macros removed or fixed/renamed (ALL_DIGNOSTICS).
- Unified pios_config.h template. Please don't remove lines for board
configs, only comment/uncomment them. Adding new PIOS options, please
propagate them to all board files keeping the same order.
- Some formatting, spacing, indentation (no line endings change yet).
- Some cosmetic fixes (no more C:\X\Y\filename.c printings on Windows).
- Added some library.mk files to move libs into AR achives later.
- EntireFlash target now uses cross-platform python script to generate bin
files. So it works on all supported platforms: Linux, OSX, Windows.
- Top level packaging is completely rewritten. Now it is a part of top
Makefile. As such, all dependencies are checked and accounted, no
more 'make -j' problems should occur.
- Default GCS_BUILD_CONF is release now, may be changed if necessary
using 'make GCS_BUILD_CONF=debug gcs'.
- GCS build paths are separated into debug and release, so no more obj
file clashes. Packaging system supports only release builds.
- New target is introduced: 'clean_package'. Now 'make package' does not
clean build directory. Use clean_package instead for distributable builds.
- Targets like 'all', 'opfw_resource', etc now will print extra contex
in parallel builds too.
- If any of 'package', 'clean_package', 'opfw_resource' targets are given
on command line, GCS build will depend on the resource, so all fw_*.opfw
targets will be built and embedded into GCS. By default GCS does not
depend on resource, and will be built w/o firmware (unless the resource
files already exist and the Qt resource file is generated).
- fw_simposix (ELF executable) is now packaged for linux. Run'n'play!
- Make help is refined and is now up to date.
Still broken:
- UnitTests, should be fixed
- SimPosix: buildable, but should be reworked.
Next planned passes to do:
- toolchain bootstrapping and packaging (including windows - WIP)
- CMSIS/StdPeriph lib cleanup
- more PIOS cleanup
- move libs into AR archives to save build time
- sim targets refactir and cleanup
- move android-related directories under <top>/android
- unit test targets fix
- source code line ending changes (there are many different, were not changed)
- coding style
Merging this, please use --no-ff git option to make it the real commit point
Conflicts:
A lot of... :-)
2013-03-24 12:02:08 +01:00
|
|
|
#ifdef DIAG_TASKS
|
2013-04-17 20:23:49 +02:00
|
|
|
TaskInfoInitialize();
|
2014-02-02 19:54:17 +01:00
|
|
|
CallbackInfoInitialize();
|
2011-12-30 18:49:27 +01:00
|
|
|
#endif
|
Final step: lot of small fixes, last commit in this commit series
This is the first cleanup pass through makefiles and pios.
Probably it is difficult to track changes due to the nature of them.
I would recommend to look at resulting files and compiled code instead.
NOTE: original branch was rebased and lot of conflicts were fixed on
the way. So do not expect that every commit in this series will be
buildable (unlike original branch). Only final result was tested.
The main goal was to remove as much duplication of code (and copy/paste
errors) as possible, moving common parts out of Makefiles. It still is
not perfect, and mostly no code changes made - Makefiles and #ifdefs only.
But please while testing make sure that all code works as before, and no
modules/options are missed by accident.
Brief list of changes:
- Moved common parts of Makefiles into the set of *.mk files.
- Changed method of passing common vars from top Makefile to lower ones.
- Some pios cleanup, mostly #ifdefs, and all pios_config.h files.
- Many obsolete files removed (for instance, AHRS files, op_config.h).
- Many obsolete or unused macros removed or fixed/renamed (ALL_DIGNOSTICS).
- Unified pios_config.h template. Please don't remove lines for board
configs, only comment/uncomment them. Adding new PIOS options, please
propagate them to all board files keeping the same order.
- Some formatting, spacing, indentation (no line endings change yet).
- Some cosmetic fixes (no more C:\X\Y\filename.c printings on Windows).
- Added some library.mk files to move libs into AR achives later.
- EntireFlash target now uses cross-platform python script to generate bin
files. So it works on all supported platforms: Linux, OSX, Windows.
- Top level packaging is completely rewritten. Now it is a part of top
Makefile. As such, all dependencies are checked and accounted, no
more 'make -j' problems should occur.
- Default GCS_BUILD_CONF is release now, may be changed if necessary
using 'make GCS_BUILD_CONF=debug gcs'.
- GCS build paths are separated into debug and release, so no more obj
file clashes. Packaging system supports only release builds.
- New target is introduced: 'clean_package'. Now 'make package' does not
clean build directory. Use clean_package instead for distributable builds.
- Targets like 'all', 'opfw_resource', etc now will print extra contex
in parallel builds too.
- If any of 'package', 'clean_package', 'opfw_resource' targets are given
on command line, GCS build will depend on the resource, so all fw_*.opfw
targets will be built and embedded into GCS. By default GCS does not
depend on resource, and will be built w/o firmware (unless the resource
files already exist and the Qt resource file is generated).
- fw_simposix (ELF executable) is now packaged for linux. Run'n'play!
- Make help is refined and is now up to date.
Still broken:
- UnitTests, should be fixed
- SimPosix: buildable, but should be reworked.
Next planned passes to do:
- toolchain bootstrapping and packaging (including windows - WIP)
- CMSIS/StdPeriph lib cleanup
- more PIOS cleanup
- move libs into AR archives to save build time
- sim targets refactir and cleanup
- move android-related directories under <top>/android
- unit test targets fix
- source code line ending changes (there are many different, were not changed)
- coding style
Merging this, please use --no-ff git option to make it the real commit point
Conflicts:
A lot of... :-)
2013-03-24 12:02:08 +01:00
|
|
|
#ifdef DIAG_I2C_WDG_STATS
|
2013-04-17 20:23:49 +02:00
|
|
|
I2CStatsInitialize();
|
|
|
|
WatchdogStatusInitialize();
|
2011-06-18 18:59:02 +02:00
|
|
|
#endif
|
|
|
|
|
2014-06-07 17:43:36 +02:00
|
|
|
#ifdef PIOS_INCLUDE_INSTRUMENTATION
|
|
|
|
InstrumentationInit();
|
|
|
|
#endif
|
|
|
|
|
2013-04-17 20:23:49 +02:00
|
|
|
objectPersistenceQueue = xQueueCreate(1, sizeof(UAVObjEvent));
|
2013-05-19 16:37:30 +02:00
|
|
|
if (objectPersistenceQueue == NULL) {
|
2013-04-17 20:23:49 +02:00
|
|
|
return -1;
|
2013-05-19 16:37:30 +02:00
|
|
|
}
|
2012-07-23 06:03:27 +02:00
|
|
|
|
2013-04-17 20:23:49 +02:00
|
|
|
return 0;
|
2011-06-20 07:35:40 +02:00
|
|
|
}
|
|
|
|
|
2013-06-04 05:37:40 +02:00
|
|
|
MODULE_INITCALL(SystemModInitialize, 0);
|
2010-09-27 09:28:34 +02:00
|
|
|
/**
|
|
|
|
* System task, periodically executes every SYSTEM_UPDATE_PERIOD_MS
|
|
|
|
*/
|
2013-05-19 16:37:30 +02:00
|
|
|
static void systemTask(__attribute__((unused)) void *parameters)
|
2010-09-27 09:28:34 +02:00
|
|
|
{
|
2015-08-18 15:27:01 +02:00
|
|
|
/* calibrate the cpu usage monitor */
|
|
|
|
PIOS_TASK_MONITOR_CalibrateIdleCounter();
|
2015-08-18 15:25:33 +02:00
|
|
|
/* board driver init */
|
|
|
|
PIOS_Board_Init();
|
|
|
|
|
|
|
|
/* Initialize all modules */
|
|
|
|
MODULE_INITIALISE_ALL;
|
|
|
|
|
2014-12-04 01:06:00 +01:00
|
|
|
while (!initTaskDone) {
|
|
|
|
vTaskDelay(10);
|
|
|
|
}
|
|
|
|
|
2015-09-14 07:56:52 +02:00
|
|
|
#ifndef PIOS_INCLUDE_WDG
|
|
|
|
// if no watchdog is enabled, don't reset watchdog in MODULE_TASKCREATE_ALL loop
|
|
|
|
#define PIOS_WDG_Clear()
|
|
|
|
#endif
|
2013-05-19 16:37:30 +02:00
|
|
|
/* create all modules thread */
|
|
|
|
MODULE_TASKCREATE_ALL;
|
2011-12-30 19:26:54 +01:00
|
|
|
|
2013-07-28 20:31:31 +02:00
|
|
|
/* start the delayed callback scheduler */
|
2014-02-02 22:08:16 +01:00
|
|
|
PIOS_CALLBACKSCHEDULER_Start();
|
2013-07-30 22:14:36 +02:00
|
|
|
|
2015-08-18 15:25:33 +02:00
|
|
|
// Register task
|
|
|
|
PIOS_TASK_MONITOR_RegisterTask(TASKINFO_RUNNING_SYSTEM, systemTaskHandle);
|
|
|
|
|
2013-04-17 20:23:49 +02:00
|
|
|
if (mallocFailed) {
|
|
|
|
/* We failed to malloc during task creation,
|
|
|
|
* system behaviour is undefined. Reset and let
|
|
|
|
* the BootFault code recover for us.
|
|
|
|
*/
|
|
|
|
PIOS_SYS_Reset();
|
|
|
|
}
|
2012-01-15 23:56:42 +01:00
|
|
|
#if defined(PIOS_INCLUDE_IAP)
|
2013-04-17 20:23:49 +02:00
|
|
|
/* Record a successful boot */
|
|
|
|
PIOS_IAP_WriteBootCount(0);
|
2012-01-15 23:56:42 +01:00
|
|
|
#endif
|
2013-04-17 20:23:49 +02:00
|
|
|
// Listen for SettingPersistance object updates, connect a callback function
|
|
|
|
ObjectPersistenceConnectQueue(objectPersistenceQueue);
|
2010-09-27 09:28:34 +02:00
|
|
|
|
2013-05-19 16:37:30 +02:00
|
|
|
// Load a copy of HwSetting active at boot time
|
|
|
|
HwSettingsGet(&bootHwSettings);
|
2014-06-29 17:23:15 +02:00
|
|
|
bootFrameType = GetCurrentFrameType();
|
2013-04-17 20:23:49 +02:00
|
|
|
// Whenever the configuration changes, make sure it is safe to fly
|
2014-06-29 17:23:15 +02:00
|
|
|
HwSettingsConnectCallback(checkSettingsUpdatedCb);
|
|
|
|
SystemSettingsConnectCallback(checkSettingsUpdatedCb);
|
2012-10-26 04:49:53 +02:00
|
|
|
|
2016-10-04 00:41:40 +02:00
|
|
|
#ifdef PIOS_INCLUDE_RFM22B
|
2016-12-22 18:49:19 +01:00
|
|
|
// Initialize previousRFXtalCap used by callback
|
|
|
|
OPLinkSettingsRFXtalCapGet(&previousRFXtalCap);
|
2016-12-16 20:27:07 +01:00
|
|
|
OPLinkSettingsConnectCallback(oplinkSettingsUpdatedCb);
|
2016-10-04 00:41:40 +02:00
|
|
|
#endif
|
|
|
|
|
2013-05-02 23:31:14 +02:00
|
|
|
#ifdef DIAG_TASKS
|
2013-05-19 16:37:30 +02:00
|
|
|
TaskInfoData taskInfoData;
|
2017-01-15 22:34:39 +01:00
|
|
|
memset(&taskInfoData, 0, sizeof(TaskInfoData));
|
2014-02-06 23:54:30 +01:00
|
|
|
CallbackInfoData callbackInfoData;
|
2017-01-15 22:34:39 +01:00
|
|
|
memset(&callbackInfoData, 0, sizeof(CallbackInfoData));
|
2013-05-02 23:31:14 +02:00
|
|
|
#endif
|
2013-05-19 16:37:30 +02:00
|
|
|
// Main system loop
|
|
|
|
while (1) {
|
2014-04-13 11:54:25 +02:00
|
|
|
NotificationUpdateStatus();
|
2013-05-19 16:37:30 +02:00
|
|
|
// Update the system statistics
|
2014-02-22 00:30:03 +01:00
|
|
|
updateStats();
|
2016-12-05 13:02:36 +01:00
|
|
|
|
|
|
|
// Update I2C stats
|
|
|
|
updateI2Cstats();
|
|
|
|
|
2013-04-17 20:23:49 +02:00
|
|
|
// Update the system alarms
|
|
|
|
updateSystemAlarms();
|
Final step: lot of small fixes, last commit in this commit series
This is the first cleanup pass through makefiles and pios.
Probably it is difficult to track changes due to the nature of them.
I would recommend to look at resulting files and compiled code instead.
NOTE: original branch was rebased and lot of conflicts were fixed on
the way. So do not expect that every commit in this series will be
buildable (unlike original branch). Only final result was tested.
The main goal was to remove as much duplication of code (and copy/paste
errors) as possible, moving common parts out of Makefiles. It still is
not perfect, and mostly no code changes made - Makefiles and #ifdefs only.
But please while testing make sure that all code works as before, and no
modules/options are missed by accident.
Brief list of changes:
- Moved common parts of Makefiles into the set of *.mk files.
- Changed method of passing common vars from top Makefile to lower ones.
- Some pios cleanup, mostly #ifdefs, and all pios_config.h files.
- Many obsolete files removed (for instance, AHRS files, op_config.h).
- Many obsolete or unused macros removed or fixed/renamed (ALL_DIGNOSTICS).
- Unified pios_config.h template. Please don't remove lines for board
configs, only comment/uncomment them. Adding new PIOS options, please
propagate them to all board files keeping the same order.
- Some formatting, spacing, indentation (no line endings change yet).
- Some cosmetic fixes (no more C:\X\Y\filename.c printings on Windows).
- Added some library.mk files to move libs into AR achives later.
- EntireFlash target now uses cross-platform python script to generate bin
files. So it works on all supported platforms: Linux, OSX, Windows.
- Top level packaging is completely rewritten. Now it is a part of top
Makefile. As such, all dependencies are checked and accounted, no
more 'make -j' problems should occur.
- Default GCS_BUILD_CONF is release now, may be changed if necessary
using 'make GCS_BUILD_CONF=debug gcs'.
- GCS build paths are separated into debug and release, so no more obj
file clashes. Packaging system supports only release builds.
- New target is introduced: 'clean_package'. Now 'make package' does not
clean build directory. Use clean_package instead for distributable builds.
- Targets like 'all', 'opfw_resource', etc now will print extra contex
in parallel builds too.
- If any of 'package', 'clean_package', 'opfw_resource' targets are given
on command line, GCS build will depend on the resource, so all fw_*.opfw
targets will be built and embedded into GCS. By default GCS does not
depend on resource, and will be built w/o firmware (unless the resource
files already exist and the Qt resource file is generated).
- fw_simposix (ELF executable) is now packaged for linux. Run'n'play!
- Make help is refined and is now up to date.
Still broken:
- UnitTests, should be fixed
- SimPosix: buildable, but should be reworked.
Next planned passes to do:
- toolchain bootstrapping and packaging (including windows - WIP)
- CMSIS/StdPeriph lib cleanup
- more PIOS cleanup
- move libs into AR archives to save build time
- sim targets refactir and cleanup
- move android-related directories under <top>/android
- unit test targets fix
- source code line ending changes (there are many different, were not changed)
- coding style
Merging this, please use --no-ff git option to make it the real commit point
Conflicts:
A lot of... :-)
2013-03-24 12:02:08 +01:00
|
|
|
#ifdef DIAG_I2C_WDG_STATS
|
2013-04-17 20:23:49 +02:00
|
|
|
updateWDGstats();
|
2011-06-18 18:59:02 +02:00
|
|
|
#endif
|
2012-01-16 00:02:38 +01:00
|
|
|
|
2014-06-07 17:43:36 +02:00
|
|
|
#ifdef PIOS_INCLUDE_INSTRUMENTATION
|
|
|
|
InstrumentationPublishAllCounters();
|
|
|
|
#endif
|
|
|
|
|
Final step: lot of small fixes, last commit in this commit series
This is the first cleanup pass through makefiles and pios.
Probably it is difficult to track changes due to the nature of them.
I would recommend to look at resulting files and compiled code instead.
NOTE: original branch was rebased and lot of conflicts were fixed on
the way. So do not expect that every commit in this series will be
buildable (unlike original branch). Only final result was tested.
The main goal was to remove as much duplication of code (and copy/paste
errors) as possible, moving common parts out of Makefiles. It still is
not perfect, and mostly no code changes made - Makefiles and #ifdefs only.
But please while testing make sure that all code works as before, and no
modules/options are missed by accident.
Brief list of changes:
- Moved common parts of Makefiles into the set of *.mk files.
- Changed method of passing common vars from top Makefile to lower ones.
- Some pios cleanup, mostly #ifdefs, and all pios_config.h files.
- Many obsolete files removed (for instance, AHRS files, op_config.h).
- Many obsolete or unused macros removed or fixed/renamed (ALL_DIGNOSTICS).
- Unified pios_config.h template. Please don't remove lines for board
configs, only comment/uncomment them. Adding new PIOS options, please
propagate them to all board files keeping the same order.
- Some formatting, spacing, indentation (no line endings change yet).
- Some cosmetic fixes (no more C:\X\Y\filename.c printings on Windows).
- Added some library.mk files to move libs into AR achives later.
- EntireFlash target now uses cross-platform python script to generate bin
files. So it works on all supported platforms: Linux, OSX, Windows.
- Top level packaging is completely rewritten. Now it is a part of top
Makefile. As such, all dependencies are checked and accounted, no
more 'make -j' problems should occur.
- Default GCS_BUILD_CONF is release now, may be changed if necessary
using 'make GCS_BUILD_CONF=debug gcs'.
- GCS build paths are separated into debug and release, so no more obj
file clashes. Packaging system supports only release builds.
- New target is introduced: 'clean_package'. Now 'make package' does not
clean build directory. Use clean_package instead for distributable builds.
- Targets like 'all', 'opfw_resource', etc now will print extra contex
in parallel builds too.
- If any of 'package', 'clean_package', 'opfw_resource' targets are given
on command line, GCS build will depend on the resource, so all fw_*.opfw
targets will be built and embedded into GCS. By default GCS does not
depend on resource, and will be built w/o firmware (unless the resource
files already exist and the Qt resource file is generated).
- fw_simposix (ELF executable) is now packaged for linux. Run'n'play!
- Make help is refined and is now up to date.
Still broken:
- UnitTests, should be fixed
- SimPosix: buildable, but should be reworked.
Next planned passes to do:
- toolchain bootstrapping and packaging (including windows - WIP)
- CMSIS/StdPeriph lib cleanup
- more PIOS cleanup
- move libs into AR archives to save build time
- sim targets refactir and cleanup
- move android-related directories under <top>/android
- unit test targets fix
- source code line ending changes (there are many different, were not changed)
- coding style
Merging this, please use --no-ff git option to make it the real commit point
Conflicts:
A lot of... :-)
2013-03-24 12:02:08 +01:00
|
|
|
#ifdef DIAG_TASKS
|
2013-05-19 16:37:30 +02:00
|
|
|
// Update the task status object
|
|
|
|
PIOS_TASK_MONITOR_ForEachTask(taskMonitorForEachCallback, &taskInfoData);
|
|
|
|
TaskInfoSet(&taskInfoData);
|
2014-02-06 23:54:30 +01:00
|
|
|
// Update the callback status object
|
2014-02-07 22:34:27 +01:00
|
|
|
PIOS_CALLBACKSCHEDULER_ForEachCallback(callbackSchedulerForEachCallback, &callbackInfoData);
|
2014-02-06 23:54:30 +01:00
|
|
|
CallbackInfoSet(&callbackInfoData);
|
2012-01-16 00:02:38 +01:00
|
|
|
#endif
|
2010-10-20 07:31:24 +02:00
|
|
|
|
2013-04-17 20:23:49 +02:00
|
|
|
UAVObjEvent ev;
|
2014-04-12 22:00:02 +02:00
|
|
|
int delayTime = SYSTEM_UPDATE_PERIOD_MS;
|
2012-07-23 06:03:27 +02:00
|
|
|
|
2013-06-15 22:50:13 +02:00
|
|
|
#if defined(PIOS_INCLUDE_RFM22B)
|
2013-08-10 05:14:13 +02:00
|
|
|
|
2013-06-15 22:50:13 +02:00
|
|
|
// Update the OPLinkStatus UAVO
|
|
|
|
OPLinkStatusData oplinkStatus;
|
|
|
|
OPLinkStatusGet(&oplinkStatus);
|
2016-07-01 04:07:13 +02:00
|
|
|
oplinkStatus.HeapRemaining = xPortGetFreeHeapSize();
|
2013-06-15 22:50:13 +02:00
|
|
|
|
2013-08-10 05:14:13 +02:00
|
|
|
if (pios_rfm22b_id) {
|
|
|
|
// Get the stats from the radio device
|
|
|
|
struct rfm22b_stats radio_stats;
|
|
|
|
PIOS_RFM22B_GetStats(pios_rfm22b_id, &radio_stats);
|
|
|
|
|
|
|
|
// Update the OPLInk status
|
|
|
|
static bool first_time = true;
|
|
|
|
static uint16_t prev_tx_count = 0;
|
|
|
|
static uint16_t prev_rx_count = 0;
|
2016-03-25 11:23:06 +01:00
|
|
|
static uint16_t prev_tx_seq = 0;
|
|
|
|
static uint16_t prev_rx_seq = 0;
|
2016-03-25 11:17:48 +01:00
|
|
|
|
2016-10-03 14:56:40 +02:00
|
|
|
oplinkStatus.DeviceID = PIOS_RFM22B_DeviceID(pios_rfm22b_id);
|
|
|
|
oplinkStatus.RxGood = radio_stats.rx_good;
|
|
|
|
oplinkStatus.RxCorrected = radio_stats.rx_corrected;
|
|
|
|
oplinkStatus.RxErrors = radio_stats.rx_error;
|
|
|
|
oplinkStatus.RxMissed = radio_stats.rx_missed;
|
|
|
|
oplinkStatus.RxFailure = radio_stats.rx_failure;
|
|
|
|
oplinkStatus.TxDropped = radio_stats.tx_dropped;
|
|
|
|
oplinkStatus.TxFailure = radio_stats.tx_failure;
|
|
|
|
oplinkStatus.Resets = radio_stats.resets;
|
|
|
|
oplinkStatus.Timeouts = radio_stats.timeouts;
|
2016-07-09 23:57:22 +02:00
|
|
|
oplinkStatus.RSSI = radio_stats.rssi;
|
2016-10-03 14:56:40 +02:00
|
|
|
oplinkStatus.LinkQuality = radio_stats.link_quality;
|
|
|
|
oplinkStatus.AFCCorrection = radio_stats.afc_correction;
|
2013-08-10 05:14:13 +02:00
|
|
|
if (first_time) {
|
|
|
|
first_time = false;
|
|
|
|
} else {
|
2016-03-25 11:23:06 +01:00
|
|
|
uint16_t tx_count = radio_stats.tx_byte_count;
|
|
|
|
uint16_t rx_count = radio_stats.rx_byte_count;
|
2016-03-25 11:17:48 +01:00
|
|
|
uint16_t tx_packets = radio_stats.tx_seq - prev_tx_seq;
|
|
|
|
uint16_t rx_packets = radio_stats.rx_seq - prev_rx_seq;
|
2016-03-25 11:23:06 +01:00
|
|
|
uint16_t tx_bytes = (tx_count < prev_tx_count) ? (0xffff - prev_tx_count + tx_count) : (tx_count - prev_tx_count);
|
|
|
|
uint16_t rx_bytes = (rx_count < prev_rx_count) ? (0xffff - prev_rx_count + rx_count) : (rx_count - prev_rx_count);
|
2013-08-10 05:14:13 +02:00
|
|
|
oplinkStatus.TXRate = (uint16_t)((float)(tx_bytes * 1000) / SYSTEM_UPDATE_PERIOD_MS);
|
|
|
|
oplinkStatus.RXRate = (uint16_t)((float)(rx_bytes * 1000) / SYSTEM_UPDATE_PERIOD_MS);
|
2016-03-25 11:17:48 +01:00
|
|
|
oplinkStatus.TXPacketRate = (uint16_t)((float)(tx_packets * 1000) / SYSTEM_UPDATE_PERIOD_MS);
|
|
|
|
oplinkStatus.RXPacketRate = (uint16_t)((float)(rx_packets * 1000) / SYSTEM_UPDATE_PERIOD_MS);
|
2013-08-10 05:14:13 +02:00
|
|
|
prev_tx_count = tx_count;
|
|
|
|
prev_rx_count = rx_count;
|
2016-03-25 11:23:06 +01:00
|
|
|
prev_tx_seq = radio_stats.tx_seq;
|
|
|
|
prev_rx_seq = radio_stats.rx_seq;
|
2013-08-10 05:14:13 +02:00
|
|
|
}
|
|
|
|
oplinkStatus.TXSeq = radio_stats.tx_seq;
|
|
|
|
oplinkStatus.RXSeq = radio_stats.rx_seq;
|
|
|
|
|
|
|
|
oplinkStatus.LinkState = radio_stats.link_state;
|
2013-06-15 22:50:13 +02:00
|
|
|
} else {
|
2013-08-10 05:14:13 +02:00
|
|
|
oplinkStatus.LinkState = OPLINKSTATUS_LINKSTATE_DISABLED;
|
2013-06-15 22:50:13 +02:00
|
|
|
}
|
|
|
|
OPLinkStatusSet(&oplinkStatus);
|
2013-08-10 05:14:13 +02:00
|
|
|
|
2013-06-15 22:50:13 +02:00
|
|
|
#endif /* if defined(PIOS_INCLUDE_RFM22B) */
|
|
|
|
|
2013-05-19 16:37:30 +02:00
|
|
|
if (xQueueReceive(objectPersistenceQueue, &ev, delayTime) == pdTRUE) {
|
2013-04-17 20:23:49 +02:00
|
|
|
// If object persistence is updated call the callback
|
|
|
|
objectUpdatedCb(&ev);
|
|
|
|
}
|
|
|
|
}
|
2010-09-27 09:28:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Function called in response to object updates
|
|
|
|
*/
|
2013-05-19 16:37:30 +02:00
|
|
|
static void objectUpdatedCb(UAVObjEvent *ev)
|
2010-09-27 09:28:34 +02:00
|
|
|
{
|
2013-04-17 20:23:49 +02:00
|
|
|
ObjectPersistenceData objper;
|
|
|
|
UAVObjHandle obj;
|
|
|
|
|
|
|
|
// If the object updated was the ObjectPersistence execute requested action
|
|
|
|
if (ev->obj == ObjectPersistenceHandle()) {
|
|
|
|
// Get object data
|
|
|
|
ObjectPersistenceGet(&objper);
|
|
|
|
|
|
|
|
int retval = 1;
|
|
|
|
FlightStatusData flightStatus;
|
|
|
|
FlightStatusGet(&flightStatus);
|
|
|
|
|
|
|
|
// When this is called because of this method don't do anything
|
|
|
|
if (objper.Operation == OBJECTPERSISTENCE_OPERATION_ERROR || objper.Operation == OBJECTPERSISTENCE_OPERATION_COMPLETED) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Execute action if disarmed
|
|
|
|
if (flightStatus.Armed != FLIGHTSTATUS_ARMED_DISARMED) {
|
|
|
|
retval = -1;
|
|
|
|
} else if (objper.Operation == OBJECTPERSISTENCE_OPERATION_LOAD) {
|
|
|
|
if (objper.Selection == OBJECTPERSISTENCE_SELECTION_SINGLEOBJECT) {
|
|
|
|
// Get selected object
|
|
|
|
obj = UAVObjGetByID(objper.ObjectID);
|
|
|
|
if (obj == 0) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// Load selected instance
|
|
|
|
retval = UAVObjLoad(obj, objper.InstanceID);
|
|
|
|
} else if (objper.Selection == OBJECTPERSISTENCE_SELECTION_ALLSETTINGS || objper.Selection == OBJECTPERSISTENCE_SELECTION_ALLOBJECTS) {
|
|
|
|
retval = UAVObjLoadSettings();
|
|
|
|
} else if (objper.Selection == OBJECTPERSISTENCE_SELECTION_ALLMETAOBJECTS || objper.Selection == OBJECTPERSISTENCE_SELECTION_ALLOBJECTS) {
|
|
|
|
retval = UAVObjLoadMetaobjects();
|
|
|
|
}
|
|
|
|
} else if (objper.Operation == OBJECTPERSISTENCE_OPERATION_SAVE) {
|
|
|
|
if (objper.Selection == OBJECTPERSISTENCE_SELECTION_SINGLEOBJECT) {
|
|
|
|
// Get selected object
|
|
|
|
obj = UAVObjGetByID(objper.ObjectID);
|
|
|
|
if (obj == 0) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// Save selected instance
|
|
|
|
retval = UAVObjSave(obj, objper.InstanceID);
|
|
|
|
|
|
|
|
// Not sure why this is needed
|
|
|
|
vTaskDelay(10);
|
|
|
|
|
|
|
|
// Verify saving worked
|
2013-05-19 16:37:30 +02:00
|
|
|
if (retval == 0) {
|
2013-04-17 20:23:49 +02:00
|
|
|
retval = UAVObjLoad(obj, objper.InstanceID);
|
2013-05-19 16:37:30 +02:00
|
|
|
}
|
2013-04-17 20:23:49 +02:00
|
|
|
} else if (objper.Selection == OBJECTPERSISTENCE_SELECTION_ALLSETTINGS || objper.Selection == OBJECTPERSISTENCE_SELECTION_ALLOBJECTS) {
|
|
|
|
retval = UAVObjSaveSettings();
|
|
|
|
} else if (objper.Selection == OBJECTPERSISTENCE_SELECTION_ALLMETAOBJECTS || objper.Selection == OBJECTPERSISTENCE_SELECTION_ALLOBJECTS) {
|
|
|
|
retval = UAVObjSaveMetaobjects();
|
|
|
|
}
|
|
|
|
} else if (objper.Operation == OBJECTPERSISTENCE_OPERATION_DELETE) {
|
|
|
|
if (objper.Selection == OBJECTPERSISTENCE_SELECTION_SINGLEOBJECT) {
|
|
|
|
// Get selected object
|
|
|
|
obj = UAVObjGetByID(objper.ObjectID);
|
|
|
|
if (obj == 0) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// Delete selected instance
|
|
|
|
retval = UAVObjDelete(obj, objper.InstanceID);
|
|
|
|
} else if (objper.Selection == OBJECTPERSISTENCE_SELECTION_ALLSETTINGS || objper.Selection == OBJECTPERSISTENCE_SELECTION_ALLOBJECTS) {
|
|
|
|
retval = UAVObjDeleteSettings();
|
|
|
|
} else if (objper.Selection == OBJECTPERSISTENCE_SELECTION_ALLMETAOBJECTS || objper.Selection == OBJECTPERSISTENCE_SELECTION_ALLOBJECTS) {
|
|
|
|
retval = UAVObjDeleteMetaobjects();
|
|
|
|
}
|
|
|
|
} else if (objper.Operation == OBJECTPERSISTENCE_OPERATION_FULLERASE) {
|
2013-05-15 23:16:34 +02:00
|
|
|
#if defined(PIOS_INCLUDE_FLASH_LOGFS_SETTINGS)
|
2013-04-17 20:23:49 +02:00
|
|
|
retval = PIOS_FLASHFS_Format(0);
|
2013-03-30 19:57:16 +01:00
|
|
|
#else
|
2013-05-19 16:37:30 +02:00
|
|
|
retval = -1;
|
2011-08-15 17:24:37 +02:00
|
|
|
#endif
|
2013-04-17 20:23:49 +02:00
|
|
|
}
|
|
|
|
switch (retval) {
|
2013-05-19 16:37:30 +02:00
|
|
|
case 0:
|
|
|
|
objper.Operation = OBJECTPERSISTENCE_OPERATION_COMPLETED;
|
|
|
|
ObjectPersistenceSet(&objper);
|
|
|
|
break;
|
|
|
|
case -1:
|
|
|
|
objper.Operation = OBJECTPERSISTENCE_OPERATION_ERROR;
|
|
|
|
ObjectPersistenceSet(&objper);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
2013-04-17 20:23:49 +02:00
|
|
|
}
|
|
|
|
}
|
2010-09-27 09:28:34 +02:00
|
|
|
}
|
|
|
|
|
2012-11-11 17:23:07 +01:00
|
|
|
/**
|
|
|
|
* Called whenever hardware settings changed
|
|
|
|
*/
|
2014-06-29 17:23:15 +02:00
|
|
|
static void checkSettingsUpdatedCb(__attribute__((unused)) UAVObjEvent *ev)
|
2012-11-11 17:23:07 +01:00
|
|
|
{
|
2013-03-30 19:57:16 +01:00
|
|
|
HwSettingsData currentHwSettings;
|
2013-05-19 16:37:30 +02:00
|
|
|
|
2013-03-30 19:57:16 +01:00
|
|
|
HwSettingsGet(¤tHwSettings);
|
2014-06-29 17:23:15 +02:00
|
|
|
FrameType_t currentFrameType = GetCurrentFrameType();
|
2013-03-30 19:57:16 +01:00
|
|
|
// check whether the Hw Configuration has changed from the one used at boot time
|
2014-06-29 17:23:15 +02:00
|
|
|
if ((memcmp(&bootHwSettings, ¤tHwSettings, sizeof(HwSettingsData)) != 0) ||
|
|
|
|
(currentFrameType != bootFrameType)) {
|
2014-04-29 22:25:49 +02:00
|
|
|
ExtendedAlarmsSet(SYSTEMALARMS_ALARM_BOOTFAULT, SYSTEMALARMS_ALARM_CRITICAL, SYSTEMALARMS_EXTENDEDALARMSTATUS_REBOOTREQUIRED, 0);
|
2013-03-30 19:57:16 +01:00
|
|
|
}
|
2012-11-11 17:23:07 +01:00
|
|
|
}
|
|
|
|
|
2016-10-04 00:41:40 +02:00
|
|
|
#ifdef PIOS_INCLUDE_RFM22B
|
|
|
|
/**
|
|
|
|
* Called whenever OPLink settings changed
|
|
|
|
*/
|
2016-12-16 20:27:07 +01:00
|
|
|
static void oplinkSettingsUpdatedCb(__attribute__((unused)) UAVObjEvent *ev)
|
2016-10-04 00:41:40 +02:00
|
|
|
{
|
2016-12-22 18:49:19 +01:00
|
|
|
uint8_t currentRFXtalCap;
|
|
|
|
|
|
|
|
OPLinkSettingsRFXtalCapGet(¤tRFXtalCap);
|
2016-10-04 00:41:40 +02:00
|
|
|
|
|
|
|
// Check if RFXtalCap value changed
|
2016-12-22 18:49:19 +01:00
|
|
|
if (currentRFXtalCap != previousRFXtalCap) {
|
|
|
|
PIOS_RFM22B_SetXtalCap(pios_rfm22b_id, currentRFXtalCap);
|
2016-10-04 00:41:40 +02:00
|
|
|
PIOS_RFM22B_Reinit(pios_rfm22b_id);
|
2016-12-22 18:49:19 +01:00
|
|
|
previousRFXtalCap = currentRFXtalCap;
|
2016-10-04 00:41:40 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif /* ifdef PIOS_INCLUDE_RFM22B */
|
|
|
|
|
2013-05-02 23:31:14 +02:00
|
|
|
#ifdef DIAG_TASKS
|
|
|
|
static void taskMonitorForEachCallback(uint16_t task_id, const struct pios_task_info *task_info, void *context)
|
|
|
|
{
|
2013-05-19 16:37:30 +02:00
|
|
|
TaskInfoData *taskData = (TaskInfoData *)context;
|
|
|
|
|
|
|
|
// By convention, there is a direct mapping between task monitor task_id's and members
|
|
|
|
// of the TaskInfoXXXXElem enums
|
|
|
|
PIOS_DEBUG_Assert(task_id < TASKINFO_RUNNING_NUMELEM);
|
2014-08-24 00:16:34 +02:00
|
|
|
TaskInfoRunningToArray(taskData->Running)[task_id] = task_info->is_running ? TASKINFO_RUNNING_TRUE : TASKINFO_RUNNING_FALSE;
|
|
|
|
((uint16_t *)&taskData->StackRemaining)[task_id] = task_info->stack_remaining;
|
|
|
|
((uint8_t *)&taskData->RunningTime)[task_id] = task_info->running_time_percentage;
|
2013-05-02 23:31:14 +02:00
|
|
|
}
|
2014-02-07 22:34:27 +01:00
|
|
|
|
|
|
|
static void callbackSchedulerForEachCallback(int16_t callback_id, const struct pios_callback_info *callback_info, void *context)
|
|
|
|
{
|
|
|
|
CallbackInfoData *callbackData = (CallbackInfoData *)context;
|
|
|
|
|
|
|
|
if (callback_id < 0) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// delayed callback scheduler reports callback stack overflows as remaininng: -1
|
2015-05-23 15:19:09 +02:00
|
|
|
#if !defined(ARCH_POSIX) && !defined(ARCH_WIN32)
|
2014-02-07 22:34:27 +01:00
|
|
|
if (callback_info->stack_remaining < 0 && stackOverflow == STACKOVERFLOW_NONE) {
|
2014-02-16 12:50:40 +01:00
|
|
|
stackOverflow = STACKOVERFLOW_WARNING;
|
2014-02-07 22:34:27 +01:00
|
|
|
}
|
2015-05-23 15:19:09 +02:00
|
|
|
#endif
|
2014-02-07 22:34:27 +01:00
|
|
|
// By convention, there is a direct mapping between (not negative) callback scheduler callback_id's and members
|
|
|
|
// of the CallbackInfoXXXXElem enums
|
|
|
|
PIOS_DEBUG_Assert(callback_id < CALLBACKINFO_RUNNING_NUMELEM);
|
|
|
|
((uint8_t *)&callbackData->Running)[callback_id] = callback_info->is_running;
|
|
|
|
((uint32_t *)&callbackData->RunningTime)[callback_id] = callback_info->running_time_count;
|
|
|
|
((int16_t *)&callbackData->StackRemaining)[callback_id] = callback_info->stack_remaining;
|
|
|
|
}
|
|
|
|
#endif /* ifdef DIAG_TASKS */
|
2013-05-02 23:31:14 +02:00
|
|
|
|
2010-12-17 08:01:58 +01:00
|
|
|
/**
|
2016-12-05 13:02:36 +01:00
|
|
|
* Called periodically (every SYSTEM_UPDATE_PERIOD_MS milliseconds) to update the I2C statistics
|
2010-12-17 08:01:58 +01:00
|
|
|
*/
|
2013-04-17 20:23:49 +02:00
|
|
|
static void updateI2Cstats()
|
2010-12-17 08:01:58 +01:00
|
|
|
{
|
2011-02-20 08:14:02 +01:00
|
|
|
#if defined(PIOS_INCLUDE_I2C)
|
2016-12-05 13:02:36 +01:00
|
|
|
static uint8_t previous_error_counts[PIOS_I2C_ERROR_COUNT_NUMELEM];
|
|
|
|
|
|
|
|
struct pios_i2c_fault_history history;
|
|
|
|
uint8_t error_counts[PIOS_I2C_ERROR_COUNT_NUMELEM];
|
|
|
|
|
|
|
|
PIOS_I2C_GetDiagnostics(&history, error_counts);
|
|
|
|
|
|
|
|
// every time a counter changes, set activity timeout counter to ( I2C_ERROR_ACTIVITY_TIMEOUT ).
|
|
|
|
// every time a counter does not change, decrease activity counter.
|
|
|
|
|
|
|
|
for (uint8_t i = 0; i < PIOS_I2C_ERROR_COUNT_NUMELEM; i++) {
|
|
|
|
if (error_counts[i] != previous_error_counts[i]) {
|
|
|
|
i2c_error_activity[i] = I2C_ERROR_ACTIVITY_TIMEOUT;
|
|
|
|
} else if (i2c_error_activity[i] > 0) {
|
|
|
|
i2c_error_activity[i]--;
|
|
|
|
}
|
|
|
|
|
|
|
|
previous_error_counts[i] = error_counts[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef DIAG_I2C_WDG_STATS
|
2013-04-17 20:23:49 +02:00
|
|
|
I2CStatsData i2cStats;
|
|
|
|
I2CStatsGet(&i2cStats);
|
|
|
|
|
2016-12-05 13:02:36 +01:00
|
|
|
memcpy(&i2cStats.event_errors, &error_counts, sizeof(error_counts));
|
2013-04-17 20:23:49 +02:00
|
|
|
|
2013-05-19 16:37:30 +02:00
|
|
|
for (uint8_t i = 0; (i < I2C_LOG_DEPTH) && (i < I2CSTATS_EVENT_LOG_NUMELEM); i++) {
|
2013-04-17 20:23:49 +02:00
|
|
|
i2cStats.evirq_log[i] = history.evirq[i];
|
|
|
|
i2cStats.erirq_log[i] = history.erirq[i];
|
|
|
|
i2cStats.event_log[i] = history.event[i];
|
|
|
|
i2cStats.state_log[i] = history.state[i];
|
|
|
|
}
|
|
|
|
i2cStats.last_error_type = history.type;
|
|
|
|
I2CStatsSet(&i2cStats);
|
2016-12-05 13:02:36 +01:00
|
|
|
#endif /* DIAG_I2C_WDG_STATS */
|
|
|
|
#endif /* PIOS_INCLUDE_I2C */
|
2010-12-17 08:01:58 +01:00
|
|
|
}
|
|
|
|
|
2016-12-05 13:02:36 +01:00
|
|
|
#ifdef DIAG_I2C_WDG_STATS
|
2013-04-17 20:23:49 +02:00
|
|
|
static void updateWDGstats()
|
2011-01-10 01:16:30 +01:00
|
|
|
{
|
2013-04-17 20:23:49 +02:00
|
|
|
WatchdogStatusData watchdogStatus;
|
2013-05-19 16:37:30 +02:00
|
|
|
|
2013-04-17 20:23:49 +02:00
|
|
|
watchdogStatus.BootupFlags = PIOS_WDG_GetBootupFlags();
|
|
|
|
watchdogStatus.ActiveFlags = PIOS_WDG_GetActiveFlags();
|
|
|
|
WatchdogStatusSet(&watchdogStatus);
|
2011-01-10 01:16:30 +01:00
|
|
|
}
|
2013-05-19 16:37:30 +02:00
|
|
|
#endif /* ifdef DIAG_I2C_WDG_STATS */
|
2011-06-18 18:59:02 +02:00
|
|
|
|
2011-06-13 05:23:00 +02:00
|
|
|
/**
|
|
|
|
* Called periodically to update the system stats
|
|
|
|
*/
|
|
|
|
static uint16_t GetFreeIrqStackSize(void)
|
|
|
|
{
|
2013-04-17 20:23:49 +02:00
|
|
|
uint32_t i = 0x200;
|
2011-06-13 05:23:00 +02:00
|
|
|
|
|
|
|
#if !defined(ARCH_POSIX) && !defined(ARCH_WIN32) && defined(CHECK_IRQ_STACK)
|
2013-04-17 20:23:49 +02:00
|
|
|
extern uint32_t _irq_stack_top;
|
|
|
|
extern uint32_t _irq_stack_end;
|
2013-05-19 16:37:30 +02:00
|
|
|
uint32_t pattern = 0x0000A5A5;
|
|
|
|
uint32_t *ptr = &_irq_stack_end;
|
2011-06-13 05:23:00 +02:00
|
|
|
|
|
|
|
#if 1 /* the ugly way accurate but takes more time, useful for debugging */
|
2013-05-19 16:37:30 +02:00
|
|
|
uint32_t stack_size = (((uint32_t)&_irq_stack_top - (uint32_t)&_irq_stack_end) & ~3) / 4;
|
2013-04-17 20:23:49 +02:00
|
|
|
|
2013-05-19 16:37:30 +02:00
|
|
|
for (i = 0; i < stack_size; i++) {
|
|
|
|
if (ptr[i] != pattern) {
|
|
|
|
i = i * 4;
|
2013-04-17 20:23:49 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2011-06-13 05:23:00 +02:00
|
|
|
#else /* faster way but not accurate */
|
2013-05-19 16:37:30 +02:00
|
|
|
if (*(volatile uint32_t *)((uint32_t)ptr + IRQSTACK_LIMIT_CRITICAL) != pattern) {
|
2013-04-17 20:23:49 +02:00
|
|
|
i = IRQSTACK_LIMIT_CRITICAL - 1;
|
2013-05-19 16:37:30 +02:00
|
|
|
} else if (*(volatile uint32_t *)((uint32_t)ptr + IRQSTACK_LIMIT_WARNING) != pattern) {
|
2013-04-17 20:23:49 +02:00
|
|
|
i = IRQSTACK_LIMIT_WARNING - 1;
|
2013-05-19 16:37:30 +02:00
|
|
|
} else {
|
2013-04-17 20:23:49 +02:00
|
|
|
i = IRQSTACK_LIMIT_WARNING;
|
|
|
|
}
|
2011-06-13 05:23:00 +02:00
|
|
|
#endif
|
2013-05-19 16:37:30 +02:00
|
|
|
#endif /* if !defined(ARCH_POSIX) && !defined(ARCH_WIN32) && defined(CHECK_IRQ_STACK) */
|
2013-04-17 20:23:49 +02:00
|
|
|
return i;
|
2011-06-13 05:23:00 +02:00
|
|
|
}
|
|
|
|
|
2010-09-27 09:28:34 +02:00
|
|
|
/**
|
|
|
|
* Called periodically to update the system stats
|
|
|
|
*/
|
|
|
|
static void updateStats()
|
|
|
|
{
|
2013-04-17 20:23:49 +02:00
|
|
|
SystemStatsData stats;
|
2010-09-27 09:28:34 +02:00
|
|
|
|
2013-04-17 20:23:49 +02:00
|
|
|
// Get stats and update
|
|
|
|
SystemStatsGet(&stats);
|
2014-01-19 12:37:25 +01:00
|
|
|
stats.FlightTime = xTaskGetTickCount() * portTICK_RATE_MS;
|
2010-09-27 09:28:34 +02:00
|
|
|
#if defined(ARCH_POSIX) || defined(ARCH_WIN32)
|
2013-04-17 20:23:49 +02:00
|
|
|
// POSIX port of FreeRTOS doesn't have xPortGetFreeHeapSize()
|
2014-01-05 23:32:20 +01:00
|
|
|
stats.SystemModStackRemaining = 128;
|
2013-04-17 20:23:49 +02:00
|
|
|
stats.HeapRemaining = 10240;
|
2010-09-27 09:28:34 +02:00
|
|
|
#else
|
2013-04-17 20:23:49 +02:00
|
|
|
stats.HeapRemaining = xPortGetFreeHeapSize();
|
2014-01-19 12:37:25 +01:00
|
|
|
stats.SystemModStackRemaining = uxTaskGetStackHighWaterMark(NULL) * 4;
|
2010-09-27 09:28:34 +02:00
|
|
|
#endif
|
2011-02-21 22:50:10 +01:00
|
|
|
|
2013-04-17 20:23:49 +02:00
|
|
|
// Get Irq stack status
|
|
|
|
stats.IRQStackRemaining = GetFreeIrqStackSize();
|
2011-06-13 05:23:00 +02:00
|
|
|
|
2014-10-24 01:55:28 +02:00
|
|
|
#if !defined(ARCH_POSIX) && !defined(ARCH_WIN32) && defined(PIOS_INCLUDE_FLASH_LOGFS_SETTINGS)
|
|
|
|
static struct PIOS_FLASHFS_Stats fsStats;
|
|
|
|
|
2013-06-15 16:38:53 +02:00
|
|
|
if (pios_uavo_settings_fs_id) {
|
2013-06-09 19:20:00 +02:00
|
|
|
PIOS_FLASHFS_GetStats(pios_uavo_settings_fs_id, &fsStats);
|
2013-06-15 16:38:53 +02:00
|
|
|
stats.SysSlotsFree = fsStats.num_free_slots;
|
2013-06-09 19:20:00 +02:00
|
|
|
stats.SysSlotsActive = fsStats.num_active_slots;
|
|
|
|
}
|
2013-06-15 16:38:53 +02:00
|
|
|
if (pios_user_fs_id) {
|
2013-06-09 19:20:00 +02:00
|
|
|
PIOS_FLASHFS_GetStats(pios_user_fs_id, &fsStats);
|
2013-06-15 16:38:53 +02:00
|
|
|
stats.UsrSlotsFree = fsStats.num_free_slots;
|
2013-06-09 19:20:00 +02:00
|
|
|
stats.UsrSlotsActive = fsStats.num_active_slots;
|
|
|
|
}
|
|
|
|
#endif
|
2015-08-17 16:29:44 +02:00
|
|
|
stats.CPUIdleTicks = PIOS_TASK_MONITOR_GetIdleTicksCount();
|
|
|
|
stats.CPUZeroLoadTicks = PIOS_TASK_MONITOR_GetZeroLoadTicksCount();
|
|
|
|
stats.CPULoad = 100 - (uint8_t)((100 * stats.CPUIdleTicks) / stats.CPUZeroLoadTicks);
|
2014-02-22 00:30:03 +01:00
|
|
|
|
2011-01-21 18:18:24 +01:00
|
|
|
#if defined(PIOS_INCLUDE_ADC) && defined(PIOS_ADC_USE_TEMP_SENSOR)
|
2013-05-27 01:34:55 +02:00
|
|
|
float temp_voltage = PIOS_ADC_PinGetVolt(PIOS_ADC_TEMPERATURE_PIN);
|
2014-02-22 00:30:03 +01:00
|
|
|
stats.CPUTemp = PIOS_CONVERT_VOLT_TO_CPU_TEMP(temp_voltage);;
|
2011-01-21 18:18:24 +01:00
|
|
|
#endif
|
2013-04-17 20:23:49 +02:00
|
|
|
SystemStatsSet(&stats);
|
2010-09-27 09:28:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Update system alarms
|
|
|
|
*/
|
|
|
|
static void updateSystemAlarms()
|
|
|
|
{
|
2013-04-17 20:23:49 +02:00
|
|
|
SystemStatsData stats;
|
|
|
|
UAVObjStats objStats;
|
|
|
|
EventStats evStats;
|
2013-05-19 16:37:30 +02:00
|
|
|
|
2013-04-17 20:23:49 +02:00
|
|
|
SystemStatsGet(&stats);
|
|
|
|
|
|
|
|
// Check heap, IRQ stack and malloc failures
|
|
|
|
if (mallocFailed || (stats.HeapRemaining < HEAP_LIMIT_CRITICAL)
|
2011-06-13 05:23:00 +02:00
|
|
|
#if !defined(ARCH_POSIX) && !defined(ARCH_WIN32) && defined(CHECK_IRQ_STACK)
|
2013-05-19 16:37:30 +02:00
|
|
|
|| (stats.IRQStackRemaining < IRQSTACK_LIMIT_CRITICAL)
|
2011-11-07 16:42:04 +01:00
|
|
|
#endif
|
2013-05-19 16:37:30 +02:00
|
|
|
) {
|
2013-04-17 20:23:49 +02:00
|
|
|
AlarmsSet(SYSTEMALARMS_ALARM_OUTOFMEMORY, SYSTEMALARMS_ALARM_CRITICAL);
|
|
|
|
} else if ((stats.HeapRemaining < HEAP_LIMIT_WARNING)
|
2011-11-07 16:42:04 +01:00
|
|
|
#if !defined(ARCH_POSIX) && !defined(ARCH_WIN32) && defined(CHECK_IRQ_STACK)
|
2013-05-19 16:37:30 +02:00
|
|
|
|| (stats.IRQStackRemaining < IRQSTACK_LIMIT_WARNING)
|
2011-11-07 16:42:04 +01:00
|
|
|
#endif
|
2013-05-19 16:37:30 +02:00
|
|
|
) {
|
2013-04-17 20:23:49 +02:00
|
|
|
AlarmsSet(SYSTEMALARMS_ALARM_OUTOFMEMORY, SYSTEMALARMS_ALARM_WARNING);
|
|
|
|
} else {
|
|
|
|
AlarmsClear(SYSTEMALARMS_ALARM_OUTOFMEMORY);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check CPU load
|
|
|
|
if (stats.CPULoad > CPULOAD_LIMIT_CRITICAL) {
|
|
|
|
AlarmsSet(SYSTEMALARMS_ALARM_CPUOVERLOAD, SYSTEMALARMS_ALARM_CRITICAL);
|
|
|
|
} else if (stats.CPULoad > CPULOAD_LIMIT_WARNING) {
|
|
|
|
AlarmsSet(SYSTEMALARMS_ALARM_CPUOVERLOAD, SYSTEMALARMS_ALARM_WARNING);
|
|
|
|
} else {
|
|
|
|
AlarmsClear(SYSTEMALARMS_ALARM_CPUOVERLOAD);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check for stack overflow
|
2014-02-07 22:34:27 +01:00
|
|
|
switch (stackOverflow) {
|
|
|
|
case STACKOVERFLOW_NONE:
|
2013-04-17 20:23:49 +02:00
|
|
|
AlarmsClear(SYSTEMALARMS_ALARM_STACKOVERFLOW);
|
2014-02-07 22:34:27 +01:00
|
|
|
break;
|
2014-02-16 12:50:40 +01:00
|
|
|
case STACKOVERFLOW_WARNING:
|
2014-02-07 22:34:27 +01:00
|
|
|
AlarmsSet(SYSTEMALARMS_ALARM_STACKOVERFLOW, SYSTEMALARMS_ALARM_WARNING);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
AlarmsSet(SYSTEMALARMS_ALARM_STACKOVERFLOW, SYSTEMALARMS_ALARM_CRITICAL);
|
2013-04-17 20:23:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Check for event errors
|
|
|
|
UAVObjGetStats(&objStats);
|
|
|
|
EventGetStats(&evStats);
|
|
|
|
UAVObjClearStats();
|
|
|
|
EventClearStats();
|
|
|
|
if (objStats.eventCallbackErrors > 0 || objStats.eventQueueErrors > 0 || evStats.eventErrors > 0) {
|
|
|
|
AlarmsSet(SYSTEMALARMS_ALARM_EVENTSYSTEM, SYSTEMALARMS_ALARM_WARNING);
|
|
|
|
} else {
|
|
|
|
AlarmsClear(SYSTEMALARMS_ALARM_EVENTSYSTEM);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (objStats.lastCallbackErrorID || objStats.lastQueueErrorID || evStats.lastErrorID) {
|
|
|
|
SystemStatsData sysStats;
|
|
|
|
SystemStatsGet(&sysStats);
|
2013-05-19 16:37:30 +02:00
|
|
|
sysStats.EventSystemWarningID = evStats.lastErrorID;
|
2013-04-17 20:23:49 +02:00
|
|
|
sysStats.ObjectManagerCallbackID = objStats.lastCallbackErrorID;
|
2013-05-19 16:37:30 +02:00
|
|
|
sysStats.ObjectManagerQueueID = objStats.lastQueueErrorID;
|
2013-04-17 20:23:49 +02:00
|
|
|
SystemStatsSet(&sysStats);
|
|
|
|
}
|
2016-12-05 13:02:36 +01:00
|
|
|
|
|
|
|
#ifdef PIOS_INCLUDE_I2C
|
2016-12-05 13:47:17 +01:00
|
|
|
if (AlarmsGet(SYSTEMALARMS_ALARM_I2C) != SYSTEMALARMS_ALARM_UNINITIALISED) {
|
|
|
|
static const SystemAlarmsAlarmOptions i2c_alarm_by_error[] = {
|
|
|
|
[PIOS_I2C_BAD_EVENT_COUNTER] = SYSTEMALARMS_ALARM_ERROR,
|
|
|
|
[PIOS_I2C_FSM_FAULT_COUNT] = SYSTEMALARMS_ALARM_ERROR,
|
|
|
|
[PIOS_I2C_ERROR_INTERRUPT_COUNTER] = SYSTEMALARMS_ALARM_ERROR,
|
|
|
|
[PIOS_I2C_NACK_COUNTER] = SYSTEMALARMS_ALARM_CRITICAL,
|
|
|
|
[PIOS_I2C_TIMEOUT_COUNTER] = SYSTEMALARMS_ALARM_ERROR,
|
|
|
|
};
|
|
|
|
|
|
|
|
SystemAlarmsAlarmOptions i2c_alarm = SYSTEMALARMS_ALARM_OK;
|
|
|
|
|
|
|
|
for (uint8_t i = 0; i < PIOS_I2C_ERROR_COUNT_NUMELEM; i++) {
|
|
|
|
if ((i2c_error_activity[i] > 0) && (i2c_alarm < i2c_alarm_by_error[i])) {
|
|
|
|
i2c_alarm = i2c_alarm_by_error[i];
|
|
|
|
}
|
2016-12-05 13:02:36 +01:00
|
|
|
}
|
|
|
|
|
2016-12-05 13:47:17 +01:00
|
|
|
AlarmsSet(SYSTEMALARMS_ALARM_I2C, i2c_alarm);
|
|
|
|
}
|
2016-12-05 13:02:36 +01:00
|
|
|
#endif /* PIOS_INCLUDE_I2C */
|
2010-09-27 09:28:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2014-04-12 22:00:02 +02:00
|
|
|
* Called by the RTOS when the CPU is idle,
|
2010-09-27 09:28:34 +02:00
|
|
|
*/
|
|
|
|
void vApplicationIdleHook(void)
|
2014-04-12 22:00:02 +02:00
|
|
|
{
|
2015-08-17 16:29:44 +02:00
|
|
|
PIOS_TASK_MONITOR_IdleHook();
|
2014-04-13 11:54:25 +02:00
|
|
|
NotificationOnboardLedsRun();
|
2014-08-13 15:14:55 +02:00
|
|
|
#ifdef PIOS_INCLUDE_WS2811
|
|
|
|
LedNotificationExtLedsRun();
|
|
|
|
#endif
|
2014-04-13 11:54:25 +02:00
|
|
|
}
|
2010-09-27 09:28:34 +02:00
|
|
|
/**
|
|
|
|
* Called by the RTOS when a stack overflow is detected.
|
|
|
|
*/
|
2011-08-22 05:14:32 +02:00
|
|
|
#define DEBUG_STACK_OVERFLOW 0
|
2014-04-13 17:42:57 +02:00
|
|
|
void vApplicationStackOverflowHook(__attribute__((unused)) xTaskHandle *pxTask,
|
|
|
|
__attribute__((unused)) signed portCHAR *pcTaskName)
|
|
|
|
{
|
2015-05-23 15:19:09 +02:00
|
|
|
#if !defined(ARCH_POSIX) && !defined(ARCH_WIN32)
|
2014-04-13 17:42:57 +02:00
|
|
|
stackOverflow = STACKOVERFLOW_CRITICAL;
|
2011-08-22 05:14:32 +02:00
|
|
|
#if DEBUG_STACK_OVERFLOW
|
2014-04-13 17:42:57 +02:00
|
|
|
static volatile bool wait_here = true;
|
|
|
|
while (wait_here) {
|
|
|
|
;
|
2014-04-12 22:00:02 +02:00
|
|
|
}
|
2014-04-13 17:42:57 +02:00
|
|
|
wait_here = true;
|
|
|
|
#endif
|
2015-05-23 15:19:09 +02:00
|
|
|
#endif
|
2014-04-13 17:42:57 +02:00
|
|
|
}
|
2011-08-22 05:14:32 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Called by the RTOS when a malloc call fails.
|
|
|
|
*/
|
|
|
|
#define DEBUG_MALLOC_FAILURES 0
|
2014-04-13 17:42:57 +02:00
|
|
|
void vApplicationMallocFailedHook(void)
|
|
|
|
{
|
|
|
|
mallocFailed = true;
|
2011-08-22 05:14:32 +02:00
|
|
|
#if DEBUG_MALLOC_FAILURES
|
2014-04-13 17:42:57 +02:00
|
|
|
static volatile bool wait_here = true;
|
|
|
|
while (wait_here) {
|
|
|
|
;
|
2014-04-12 22:00:02 +02:00
|
|
|
}
|
2014-04-13 17:42:57 +02:00
|
|
|
wait_here = true;
|
|
|
|
#endif
|
|
|
|
}
|
2010-09-27 09:28:34 +02:00
|
|
|
|
|
|
|
/**
|
2013-04-17 20:23:49 +02:00
|
|
|
* @}
|
|
|
|
* @}
|
|
|
|
*/
|