1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-01-18 03:52:11 +01:00

Merge branch 'OP-423_Mathieu_Change_Init_To_Reduce_Memory_Footprint'

This commit is contained in:
James Cotton 2011-07-12 12:44:59 -05:00
commit 2fe7ee40b1
38 changed files with 675 additions and 196 deletions

View File

@ -113,12 +113,9 @@ OPUAVSYNTHDIR = $(OUTDIR)/../uavobject-synthetics/flight
# List C source files here. (C dependencies are automatically generated.)
# use file-extension c for "c-only"-files
MODNAMES = $(notdir ${MODULES})
ifndef TESTAPP
## MODULES
SRC += ${foreach MOD, ${MODULES}, ${wildcard ${OPMODULEDIR}/${MOD}/*.c}}
SRC += ${OUTDIR}/InitMods.c
## OPENPILOT CORE:
SRC += ${OPMODULEDIR}/System/systemmod.c
SRC += $(OPSYSTEM)/coptercontrol.c
@ -490,7 +487,7 @@ LSTFILES = $(addprefix $(OUTDIR)/, $(addsuffix .lst, $(ALLSRCBASE)))
DEPFILES = $(addprefix $(OUTDIR)/dep/, $(addsuffix .o.d, $(ALLSRCBASE)))
# Default target.
all: gencode build
all: build
ifeq ($(LOADFORMAT),ihex)
build: elf hex lss sym
@ -506,18 +503,6 @@ endif
endif
endif
# Generate intermediate code for objects
gencode: ${OUTDIR}/InitMods.c
# Generate code for module initialization
${OUTDIR}/InitMods.c: Makefile
@echo $(MSG_MODINIT) $(call toprel, $@)
@echo ${quote}// Autogenerated file${quote} > ${OUTDIR}/InitMods.c
@echo ${quote}${foreach MOD, ${MODNAMES}, extern unsigned int ${MOD}Initialize(void);}${quote} >> ${OUTDIR}/InitMods.c
@echo ${quote}void InitModules() {${quote} >> ${OUTDIR}/InitMods.c
@echo ${quote}${foreach MOD, ${MODNAMES}, ${MOD}Initialize();}${quote} >> ${OUTDIR}/InitMods.c
@echo ${quote}}${quote} >> ${OUTDIR}/InitMods.c
# Generate code for PyMite
#$(OUTDIR)/pmlib_img.c $(OUTDIR)/pmlib_nat.c $(OUTDIR)/pmlibusr_img.c $(OUTDIR)/pmlibusr_nat.c $(OUTDIR)/pmfeatures.h: $(wildcard $(PYMITELIB)/*.py) $(wildcard $(PYMITEPLAT)/*.py) $(wildcard $(FLIGHTPLANLIB)/*.py) $(wildcard $(FLIGHTPLANS)/*.py)
# @echo $(MSG_PYMITEINIT) $(call toprel, $@)
@ -624,4 +609,4 @@ else
endif
# Listing of phony targets.
.PHONY : all build clean clean_list gencode install
.PHONY : all build clean clean_list install

View File

@ -42,18 +42,16 @@
/* Global Variables */
/* Prototype of generated InitModules() function */
extern void InitModules(void);
/* Prototype of PIOS_Board_Init() function */
extern void PIOS_Board_Init(void);
extern void Stack_Change(void);
/**
* OpenPilot Main function:
*
* Initialize PiOS<BR>
* Create the "System" task (SystemModInitializein Modules/System/systemmod.c) <BR>
* Start FreeRTOS Scheduler (vTaskStartScheduler)<BR>
* Start FreeRTOS Scheduler (vTaskStartScheduler) (Now handled by caller)
* If something goes wrong, blink LED1 and LED2 every 100ms
*
*/
@ -65,40 +63,32 @@ int main()
/* Brings up System using CMSIS functions, enables the LEDs. */
PIOS_SYS_Init();
/* Initialize the system thread */
SystemModInitialize();
/* Start the FreeRTOS scheduler */
vTaskStartScheduler();
/* If all is well we will never reach here as the scheduler will now be running. */
/* If we do get here, it will most likely be because we ran out of heap space. */
return 0;
}
/**
* Initialize the hardware, libraries and modules (called by the System thread in systemmod.c)
*/
void OpenPilotInit()
{
/* Architecture dependant Hardware and
* core subsystem initialisation
* (see pios_board.c for your arch)
* */
PIOS_Board_Init();
#ifdef ERASE_FLASH
PIOS_Flash_W25X_EraseChip();
while(TRUE){};
#endif
/* Initialize modules */
InitModules();
}
MODULE_INITIALISE_ALL
/* swap the stack to use the IRQ stack */
Stack_Change();
/* Start the FreeRTOS scheduler which should never returns.*/
vTaskStartScheduler();
/* If all is well we will never reach here as the scheduler will now be running. */
/* Do some indication to user that something bad just happened */
PIOS_LED_Off(LED1); \
for(;;) { \
PIOS_LED_Toggle(LED1); \
PIOS_DELAY_WaitmS(100); \
};
return 0;
}
/**
* @}

View File

@ -30,7 +30,7 @@
#define configTICK_RATE_HZ ( ( portTickType ) 1000 )
#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 5 )
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 48 )
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 14 * 1024 ) )
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 55 * 256) )
#define configMAX_TASK_NAME_LEN ( 16 )
#define configUSE_TRACE_FACILITY 0
#define configUSE_16_BIT_TICKS 0
@ -71,6 +71,10 @@ configKERNEL_INTERRUPT_PRIORITY setting. Here 15 corresponds to the lowest
NVIC value of 255. */
#define configLIBRARY_KERNEL_INTERRUPT_PRIORITY 15
#if !defined(ARCH_POSIX) && !defined(ARCH_WIN32)
#define CHECK_IRQ_STACK
#endif
/* Enable run time stats collection */
//#if defined(DEBUG)
#define configGENERATE_RUN_TIME_STATS 1
@ -83,6 +87,7 @@ do {\
#define portGET_RUN_TIME_COUNTER_VALUE() (*(unsigned long *)0xe0001004)/* DWT_CYCCNT */
//#endif
/**
* @}
*/

View File

@ -88,13 +88,15 @@
/* Alarm Thresholds */
#define HEAP_LIMIT_WARNING 220
#define HEAP_LIMIT_CRITICAL 40
#define IRQSTACK_LIMIT_WARNING 100
#define IRQSTACK_LIMIT_CRITICAL 60
#define CPULOAD_LIMIT_WARNING 85
#define CPULOAD_LIMIT_CRITICAL 95
/* Task stack sizes */
#define PIOS_ACTUATOR_STACK_SIZE 1020
#define PIOS_MANUAL_STACK_SIZE 724
#define PIOS_SYSTEM_STACK_SIZE 560
#define PIOS_SYSTEM_STACK_SIZE 460
#define PIOS_STABILIZATION_STACK_SIZE 524
#define PIOS_TELEM_STACK_SIZE 500
#define PIOS_EVENTDISPATCHER_STACK_SIZE 96

View File

@ -69,7 +69,7 @@ static void ahrscommsTask(void *parameters);
* Initialise the module, called on startup
* \returns 0 on success or -1 if initialisation failed
*/
int32_t AHRSCommsInitialize(void)
int32_t AHRSCommsStart(void)
{
// Start main task
xTaskCreate(ahrscommsTask, (signed char *)"AHRSComms", STACK_SIZE, NULL, TASK_PRIORITY, &taskHandle);
@ -79,6 +79,17 @@ int32_t AHRSCommsInitialize(void)
return 0;
}
/**
* Initialise the module, called on startup
* \returns 0 on success or -1 if initialisation failed
*/
int32_t AHRSCommsInitialize(void)
{
return 0;
}
MODULE_INITCALL(AHRSCommsInitialize, 0, AHRSCommsStart, 0, MODULE_EXEC_NOORDER_FLAG)
/**
* Module thread, should not return.
*/

View File

@ -85,6 +85,19 @@ typedef struct {
int8_t matrix[5];
} __attribute__((packed)) Mixer_t;
/**
* @brief Module initialization
* @return 0
*/
int32_t ActuatorStart()
{
// Start main task
xTaskCreate(actuatorTask, (signed char*)"Actuator", STACK_SIZE_BYTES/4, NULL, TASK_PRIORITY, &taskHandle);
TaskMonitorAdd(TASKINFO_RUNNING_ACTUATOR, taskHandle);
PIOS_WDG_RegisterFlag(PIOS_WDG_ACTUATOR);
return 0;
}
/**
* @brief Module initialization
@ -100,14 +113,10 @@ int32_t ActuatorInitialize()
// If settings change, update the output rate
ActuatorSettingsConnectCallback(actuator_update_rate);
// Start main task
xTaskCreate(actuatorTask, (signed char*)"Actuator", STACK_SIZE_BYTES/4, NULL, TASK_PRIORITY, &taskHandle);
TaskMonitorAdd(TASKINFO_RUNNING_ACTUATOR, taskHandle);
PIOS_WDG_RegisterFlag(PIOS_WDG_ACTUATOR);
return 0;
}
MODULE_INITCALL(ActuatorInitialize, 0, ActuatorStart, 0, MODULE_EXEC_NOORDER_FLAG)
/**
* @brief Main Actuator module task

View File

@ -37,6 +37,7 @@
*/
#include "openpilot.h"
#include "altitude.h"
#include "baroaltitude.h" // object that will be updated by the module
#if defined(PIOS_INCLUDE_HCSR04)
#include "sonaraltitude.h" // object that will be updated by the module
@ -66,12 +67,22 @@ static void altitudeTask(void *parameters);
* Initialise the module, called on startup
* \returns 0 on success or -1 if initialisation failed
*/
int32_t AltitudeInitialize()
int32_t AltitudeStart()
{
// Start main task
xTaskCreate(altitudeTask, (signed char *)"Altitude", STACK_SIZE_BYTES/4, NULL, TASK_PRIORITY, &taskHandle);
TaskMonitorAdd(TASKINFO_RUNNING_ALTITUDE, taskHandle);
return 0;
}
/**
* Initialise the module, called on startup
* \returns 0 on success or -1 if initialisation failed
*/
int32_t AltitudeInitialize()
{
// init down-sampling data
alt_ds_temp = 0;
alt_ds_pres = 0;
@ -79,7 +90,7 @@ int32_t AltitudeInitialize()
return 0;
}
MODULE_INITCALL(AltitudeInitialize, 0, AltitudeStart, 0, MODULE_EXEC_NOORDER_FLAG)
/**
* Module thread, should not return.
*/

View File

@ -90,6 +90,21 @@ static float R[3][3];
static int8_t rotate = 0;
static bool zero_during_arming = false;
/**
* Initialise the module, called on startup
* \returns 0 on success or -1 if initialisation failed
*/
int32_t AttitudeStart(void)
{
// Start main task
xTaskCreate(AttitudeTask, (signed char *)"Attitude", STACK_SIZE_BYTES/4, NULL, TASK_PRIORITY, &taskHandle);
TaskMonitorAdd(TASKINFO_RUNNING_ATTITUDE, taskHandle);
PIOS_WDG_RegisterFlag(PIOS_WDG_ATTITUDE);
return 0;
}
/**
* Initialise the module, called on startup
* \returns 0 on success or -1 if initialisation failed
@ -104,22 +119,20 @@ int32_t AttitudeInitialize(void)
attitude.q3 = 0;
attitude.q4 = 0;
AttitudeActualSet(&attitude);
AttitudeSettingsConnectCallback(&settingsUpdatedCb);
// Create queue for passing gyro data, allow 2 back samples in case
gyro_queue = xQueueCreate(1, sizeof(float) * 4);
if(gyro_queue == NULL)
if(gyro_queue == NULL)
return -1;
PIOS_ADC_SetQueue(gyro_queue);
AttitudeSettingsConnectCallback(&settingsUpdatedCb);
// Start main task
xTaskCreate(AttitudeTask, (signed char *)"Attitude", STACK_SIZE_BYTES/4, NULL, TASK_PRIORITY, &taskHandle);
TaskMonitorAdd(TASKINFO_RUNNING_ATTITUDE, taskHandle);
PIOS_WDG_RegisterFlag(PIOS_WDG_ATTITUDE);
return 0;
}
MODULE_INITCALL(AttitudeInitialize, 0, AttitudeStart, 0, MODULE_EXEC_NOORDER_FLAG)
/**
* Module thread, should not return.
*/

View File

@ -75,6 +75,7 @@ static void onTimer(UAVObjEvent* ev);
* Initialise the module, called on startup
* \returns 0 on success or -1 if initialisation failed
*/
MODULE_INITCALL(BatteryInitialize, 0, 0, 0, MODULE_EXEC_NOORDER_FLAG)
int32_t BatteryInitialize(void)
{
static UAVObjEvent ev;

View File

@ -49,9 +49,14 @@
#include "examplemodperiodic.h"
#include "examplemodthread.h"
void ExampleInitialize(void)
void ExampleStart(void)
{
ExampleModEventInitialize();
ExampleModPeriodicInitialize();
ExampleModThreadInitialize();
}
void ExampleInitialize(void)
{
ExampleModEventInitialize();
}
MODULE_INITCALL(ExampleInitialize, 0, ExampleStart, 0, MODULE_EXEC_NOORDER_FLAG)

View File

@ -88,7 +88,7 @@ static void resetTask(UAVObjEvent *);
* \note
*
*/
MODULE_INITCALL(FirmwareIAPInitialize, 0, 0, 0, MODULE_EXEC_NOORDER_FLAG)
int32_t FirmwareIAPInitialize()
{
const struct pios_board_info * bdinfo = &pios_board_info_blob;

View File

@ -31,6 +31,7 @@
#include "openpilot.h"
#include "pm.h"
#include "flightplan.h"
#include "flightplanstatus.h"
#include "flightplancontrol.h"
#include "flightplansettings.h"
@ -53,6 +54,20 @@ static void objectUpdatedCb(UAVObjEvent * ev);
// External variables (temporary, TODO: this will be loaded from the SD card)
extern unsigned char usrlib_img[];
/**
* Module initialization
*/
int32_t FlightPlanStart()
{
taskHandle = NULL;
// Start VM thread
xTaskCreate(flightPlanTask, (signed char *)"FlightPlan", STACK_SIZE_BYTES/4, NULL, TASK_PRIORITY, &taskHandle);
TaskMonitorAdd(TASKINFO_RUNNING_FLIGHTPLAN, taskHandle);
return 0;
}
/**
* Module initialization
*/
@ -69,13 +84,9 @@ int32_t FlightPlanInitialize()
// Listen for FlightPlanControl updates
FlightPlanControlConnectQueue(queue);
// Start VM thread
xTaskCreate(flightPlanTask, (signed char *)"FlightPlan", STACK_SIZE_BYTES/4, NULL, TASK_PRIORITY, &taskHandle);
TaskMonitorAdd(TASKINFO_RUNNING_FLIGHTPLAN, taskHandle);
return 0;
}
MODULE_INITCALL(FlightPlanInitialize, 0, FlightPlanStart, 0, MODULE_EXEC_NOORDER_FLAG)
/**
* Module task
*/

View File

@ -109,19 +109,27 @@ static uint32_t numParsingErrors;
* \return 0 on success
*/
int32_t GPSInitialize(void)
int32_t GPSStart(void)
{
signed portBASE_TYPE xReturn;
// TODO: Get gps settings object
gpsPort = PIOS_COM_GPS;
// Start gps task
xReturn = xTaskCreate(gpsTask, (signed char *)"GPS", STACK_SIZE_BYTES/4, NULL, TASK_PRIORITY, &gpsTaskHandle);
xTaskCreate(gpsTask, (signed char *)"GPS", STACK_SIZE_BYTES/4, NULL, TASK_PRIORITY, &gpsTaskHandle);
TaskMonitorAdd(TASKINFO_RUNNING_GPS, gpsTaskHandle);
return 0;
}
/**
* Initialise the gps module
* \return -1 if initialisation failed
* \return 0 on success
*/
int32_t GPSInitialize(void)
{
// TODO: Get gps settings object
gpsPort = PIOS_COM_GPS;
return 0;
}
MODULE_INITCALL(GPSInitialize, 0, GPSStart, 0, MODULE_EXEC_NOORDER_FLAG)
// ****************
/**

View File

@ -78,6 +78,19 @@ static void updateVtolDesiredVelocity();
static void manualSetDesiredVelocity();
static void updateVtolDesiredAttitude();
/**
* Initialise the module, called on startup
* \returns 0 on success or -1 if initialisation failed
*/
int32_t GuidanceStart()
{
// Start main task
xTaskCreate(guidanceTask, (signed char *)"Guidance", STACK_SIZE_BYTES/4, NULL, TASK_PRIORITY, &guidanceTaskHandle);
TaskMonitorAdd(TASKINFO_RUNNING_GUIDANCE, guidanceTaskHandle);
return 0;
}
/**
* Initialise the module, called on startup
* \returns 0 on success or -1 if initialisation failed
@ -90,12 +103,9 @@ int32_t GuidanceInitialize()
// Listen for updates.
AttitudeRawConnectQueue(queue);
// Start main task
xTaskCreate(guidanceTask, (signed char *)"Guidance", STACK_SIZE_BYTES/4, NULL, TASK_PRIORITY, &guidanceTaskHandle);
TaskMonitorAdd(TASKINFO_RUNNING_GUIDANCE, guidanceTaskHandle);
return 0;
}
MODULE_INITCALL(GuidanceInitialize, 0, GuidanceStart, 0, MODULE_EXEC_NOORDER_FLAG)
static float northVelIntegral = 0;
static float eastVelIntegral = 0;

View File

@ -27,5 +27,5 @@
#define EXAMPLEMODPERIODIC_H
int32_t ExampleModPeriodicInitialize();
int32_t GuidanceInitialize(void);
#endif // EXAMPLEMODPERIODIC_H

View File

@ -144,19 +144,27 @@ static bool validInputRange(int16_t min, int16_t max, uint16_t value);
/**
* Module initialization
*/
int32_t ManualControlInitialize()
int32_t ManualControlStart()
{
/* Check the assumptions about uavobject enum's are correct */
if(!assumptions)
if(!assumptions)
return -1;
// Start main task
xTaskCreate(manualControlTask, (signed char *)"ManualControl", STACK_SIZE_BYTES/4, NULL, TASK_PRIORITY, &taskHandle);
TaskMonitorAdd(TASKINFO_RUNNING_MANUALCONTROL, taskHandle);
PIOS_WDG_RegisterFlag(PIOS_WDG_MANUAL);
return 0;
}
/**
* Module initialization
*/
int32_t ManualControlInitialize()
{
return 0;
}
MODULE_INITCALL(ManualControlInitialize, 0, ManualControlStart, 0, MODULE_EXEC_NOORDER_FLAG)
/**
* Module task
@ -621,3 +629,4 @@ bool validInputRange(int16_t min, int16_t max, uint16_t value)
* @}
* @}
*/

View File

@ -89,27 +89,40 @@ static void SettingsUpdatedCb(UAVObjEvent * ev);
/**
* Module initialization
*/
int32_t StabilizationInitialize()
int32_t StabilizationStart()
{
// Initialize variables
// Create object queue
queue = xQueueCreate(MAX_QUEUE_SIZE, sizeof(UAVObjEvent));
// Listen for updates.
// AttitudeActualConnectQueue(queue);
AttitudeRawConnectQueue(queue);
StabilizationSettingsConnectCallback(SettingsUpdatedCb);
SettingsUpdatedCb(StabilizationSettingsHandle());
// Start main task
xTaskCreate(stabilizationTask, (signed char*)"Stabilization", STACK_SIZE_BYTES/4, NULL, TASK_PRIORITY, &taskHandle);
TaskMonitorAdd(TASKINFO_RUNNING_STABILIZATION, taskHandle);
PIOS_WDG_RegisterFlag(PIOS_WDG_STABILIZATION);
return 0;
}
/**
* Module initialization
*/
int32_t StabilizationInitialize()
{
// Initialize variables
// Create object queue
queue = xQueueCreate(MAX_QUEUE_SIZE, sizeof(UAVObjEvent));
// Listen for updates.
// AttitudeActualConnectQueue(queue);
AttitudeRawConnectQueue(queue);
StabilizationSettingsConnectCallback(SettingsUpdatedCb);
SettingsUpdatedCb(StabilizationSettingsHandle());
// Start main task
return 0;
}
MODULE_INITCALL(StabilizationInitialize, 0, StabilizationStart, 0, MODULE_EXEC_NOORDER_FLAG)
/**
* Module task
*/

View File

@ -84,18 +84,34 @@ static void updateSystemAlarms();
static void systemTask(void *parameters);
/**
* Initialise the module, called on startup.
* \returns 0 on success or -1 if initialisation failed
* Create the module task.
* \returns 0 on success or -1 if initialization failed
*/
int32_t SystemModInitialize(void)
int32_t SystemModStart(void)
{
// Initialize vars
stackOverflow = 0;
// Create system task
xTaskCreate(systemTask, (signed char *)"System", STACK_SIZE_BYTES/4, NULL, TASK_PRIORITY, &systemTaskHandle);
// Register task
TaskMonitorAdd(TASKINFO_RUNNING_SYSTEM, systemTaskHandle);
return 0;
}
/**
* Initialize the module, called on startup.
* \returns 0 on success or -1 if initialization failed
*/
int32_t SystemModInitialize(void)
{
SystemModStart();
return 0;
}
MODULE_INITCALL(SystemModInitialize, 0, 0, 0, MODULE_EXEC_FIRST_FLAG)
/**
* System task, periodically executes every SYSTEM_UPDATE_PERIOD_MS
*/
@ -103,11 +119,8 @@ static void systemTask(void *parameters)
{
portTickType lastSysTime;
// System initialization
OpenPilotInit();
// Register task
TaskMonitorAdd(TASKINFO_RUNNING_SYSTEM, systemTaskHandle);
/* create all modules thread */
MODULE_TASKCREATE_ALL
// Initialize vars
idleCounter = 0;
@ -118,7 +131,7 @@ static void systemTask(void *parameters)
ObjectPersistenceConnectCallback(&objectUpdatedCb);
// Main system loop
while (1) {
while (1) {
// Update the system statistics
updateStats();
@ -260,6 +273,48 @@ static void updateWDGstats()
WatchdogStatusSet(&watchdogStatus);
}
/**
* Called periodically to update the system stats
*/
static uint16_t GetFreeIrqStackSize(void)
{
uint32_t i = 0x200;
#if !defined(ARCH_POSIX) && !defined(ARCH_WIN32) && defined(CHECK_IRQ_STACK)
extern uint32_t _irq_stack_top;
extern uint32_t _irq_stack_end;
uint32_t pattern = 0x0000A5A5;
uint32_t *ptr = &_irq_stack_end;
#if 1 /* the ugly way accurate but takes more time, useful for debugging */
uint32_t stack_size = (((uint32_t)&_irq_stack_top - (uint32_t)&_irq_stack_end) & ~3 ) / 4;
for (i=0; i< stack_size; i++)
{
if (ptr[i] != pattern)
{
i=i*4;
break;
}
}
#else /* faster way but not accurate */
if (*(volatile uint32_t *)((uint32_t)ptr + IRQSTACK_LIMIT_CRITICAL) != pattern)
{
i = IRQSTACK_LIMIT_CRITICAL - 1;
}
else if (*(volatile uint32_t *)((uint32_t)ptr + IRQSTACK_LIMIT_WARNING) != pattern)
{
i = IRQSTACK_LIMIT_WARNING - 1;
}
else
{
i = IRQSTACK_LIMIT_WARNING;
}
#endif
#endif
return i;
}
/**
* Called periodically to update the system stats
*/
@ -278,6 +333,9 @@ static void updateStats()
stats.HeapRemaining = xPortGetFreeHeapSize();
#endif
// Get Irq stack status
stats.IRQStackRemaining = GetFreeIrqStackSize();
// When idleCounterClear was not reset by the idle-task, it means the idle-task did not run
if (idleCounterClear) {
idleCounter = 0;
@ -320,6 +378,17 @@ static void updateSystemAlarms()
AlarmsClear(SYSTEMALARMS_ALARM_OUTOFMEMORY);
}
#if !defined(ARCH_POSIX) && !defined(ARCH_WIN32) && defined(CHECK_IRQ_STACK)
// Check IRQ stack
if (stats.IRQStackRemaining < IRQSTACK_LIMIT_CRITICAL) {
AlarmsSet(SYSTEMALARMS_ALARM_OUTOFMEMORY, SYSTEMALARMS_ALARM_CRITICAL);
} else if (stats.IRQStackRemaining < IRQSTACK_LIMIT_WARNING) {
AlarmsSet(SYSTEMALARMS_ALARM_OUTOFMEMORY, SYSTEMALARMS_ALARM_WARNING);
} else {
AlarmsClear(SYSTEMALARMS_ALARM_OUTOFMEMORY);
}
#endif
// Check CPU load
if (stats.CPULoad > CPULOAD_LIMIT_CRITICAL) {
AlarmsSet(SYSTEMALARMS_ALARM_CPUOVERLOAD, SYSTEMALARMS_ALARM_CRITICAL);

View File

@ -31,6 +31,7 @@
*/
#include "openpilot.h"
#include "telemetry.h"
#include "flighttelemetrystats.h"
#include "gcstelemetrystats.h"
#include "telemetrysettings.h"
@ -80,6 +81,28 @@ static void updateTelemetryStats();
static void gcsTelemetryStatsUpdated();
static void updateSettings();
/**
* Initialise the telemetry module
* \return -1 if initialisation failed
* \return 0 on success
*/
int32_t TelemetryStart(void)
{
// Start telemetry tasks
xTaskCreate(telemetryTxTask, (signed char *)"TelTx", STACK_SIZE_BYTES/4, NULL, TASK_PRIORITY_TX, &telemetryTxTaskHandle);
xTaskCreate(telemetryRxTask, (signed char *)"TelRx", STACK_SIZE_BYTES/4, NULL, TASK_PRIORITY_RX, &telemetryRxTaskHandle);
TaskMonitorAdd(TASKINFO_RUNNING_TELEMETRYTX, telemetryTxTaskHandle);
TaskMonitorAdd(TASKINFO_RUNNING_TELEMETRYRX, telemetryRxTaskHandle);
#if defined(PIOS_TELEM_PRIORITY_QUEUE)
xTaskCreate(telemetryTxPriTask, (signed char *)"TelPriTx", STACK_SIZE_BYTES/4, NULL, TASK_PRIORITY_TXPRI, &telemetryTxPriTaskHandle);
TaskMonitorAdd(TASKINFO_RUNNING_TELEMETRYTXPRI, telemetryTxPriTaskHandle);
#endif
return 0;
}
/**
* Initialise the telemetry module
* \return -1 if initialisation failed
@ -117,20 +140,11 @@ int32_t TelemetryInitialize(void)
GCSTelemetryStatsConnectQueue(priorityQueue);
TelemetrySettingsConnectQueue(priorityQueue);
// Start telemetry tasks
xTaskCreate(telemetryTxTask, (signed char *)"TelTx", STACK_SIZE_BYTES/4, NULL, TASK_PRIORITY_TX, &telemetryTxTaskHandle);
xTaskCreate(telemetryRxTask, (signed char *)"TelRx", STACK_SIZE_BYTES/4, NULL, TASK_PRIORITY_RX, &telemetryRxTaskHandle);
TaskMonitorAdd(TASKINFO_RUNNING_TELEMETRYTX, telemetryTxTaskHandle);
TaskMonitorAdd(TASKINFO_RUNNING_TELEMETRYRX, telemetryRxTaskHandle);
#if defined(PIOS_TELEM_PRIORITY_QUEUE)
xTaskCreate(telemetryTxPriTask, (signed char *)"TelPriTx", STACK_SIZE_BYTES/4, NULL, TASK_PRIORITY_TXPRI, &telemetryTxPriTaskHandle);
TaskMonitorAdd(TASKINFO_RUNNING_TELEMETRYTXPRI, telemetryTxPriTaskHandle);
#endif
return 0;
}
MODULE_INITCALL(TelemetryInitialize, 0, TelemetryStart, 0, MODULE_EXEC_LAST_FLAG)
/**
* Register a new object, adds object to local list and connects the queue depending on the object's
* telemetry settings.

View File

@ -112,8 +112,6 @@ UAVOBJSYNTHDIR = $(OUTDIR)/../uavobject-synthetics/flight
# List C source files here. (C dependencies are automatically generated.)
# use file-extension c for "c-only"-files
MODNAMES = $(notdir ${MODULES} ${PYMODULES})
ifndef TESTAPP
## PyMite files and modules
@ -128,7 +126,6 @@ SRC += $(PYSRC)
## MODULES
SRC += ${foreach MOD, ${MODULES}, ${wildcard ${OPMODULEDIR}/${MOD}/*.c}}
SRC += ${OUTDIR}/InitMods.c
## OPENPILOT CORE:
SRC += ${OPMODULEDIR}/System/systemmod.c
SRC += $(OPSYSTEM)/openpilot.c
@ -472,19 +469,10 @@ endif
endif
# Generate intermediate code
gencode: ${OUTDIR}/InitMods.c ${OUTDIR}/pmlib_img.c ${OUTDIR}/pmlib_nat.c ${OUTDIR}/pmlibusr_img.c ${OUTDIR}/pmlibusr_nat.c ${OUTDIR}/pmfeatures.h
gencode: ${OUTDIR}/pmlib_img.c ${OUTDIR}/pmlib_nat.c ${OUTDIR}/pmlibusr_img.c ${OUTDIR}/pmlibusr_nat.c ${OUTDIR}/pmfeatures.h
$(PYSRC): gencode
# Generate code for module initialization
${OUTDIR}/InitMods.c: Makefile
@echo $(MSG_MODINIT) $(call toprel, $@)
@echo ${quote}// Autogenerated file${quote} > ${OUTDIR}/InitMods.c
@echo ${quote}${foreach MOD, ${MODNAMES}, extern unsigned int ${MOD}Initialize(void);}${quote} >> ${OUTDIR}/InitMods.c
@echo ${quote}void InitModules() {${quote} >> ${OUTDIR}/InitMods.c
@echo ${quote}${foreach MOD, ${MODNAMES}, ${MOD}Initialize();}${quote} >> ${OUTDIR}/InitMods.c
@echo ${quote}}${quote} >> ${OUTDIR}/InitMods.c
# Generate code for PyMite
${OUTDIR}/pmlib_img.c ${OUTDIR}/pmlib_nat.c ${OUTDIR}/pmlibusr_img.c ${OUTDIR}/pmlibusr_nat.c ${OUTDIR}/pmfeatures.h: $(wildcard ${PYMITELIB}/*.py) $(wildcard ${PYMITEPLAT}/*.py) $(wildcard ${FLIGHTPLANLIB}/*.py) $(wildcard ${FLIGHTPLANS}/*.py)
@echo $(MSG_PYMITEINIT) $(call toprel, $@)

View File

@ -441,9 +441,13 @@ ${OUTDIR}/InitMods.c: Makefile.posix
@echo ${MSG_MODINIT}
@echo ${quote}// Autogenerated file${quote} > ${OUTDIR}/InitMods.c
@echo ${quote}${foreach MOD, ${MODNAMES}, extern unsigned int ${MOD}Initialize(void);}${quote} >> ${OUTDIR}/InitMods.c
@echo ${quote}${foreach MOD, ${MODNAMES}, extern unsigned int ${MOD}Start(void);}${quote} >> ${OUTDIR}/InitMods.c
@echo ${quote}void InitModules() {${quote} >> ${OUTDIR}/InitMods.c
@echo ${quote}${foreach MOD, ${MODNAMES}, ${MOD}Initialize();}${quote} >> ${OUTDIR}/InitMods.c
@echo ${quote}}${quote} >> ${OUTDIR}/InitMods.c
@echo ${quote}void StartModules() {${quote} >> ${OUTDIR}/InitMods.c
@echo ${quote}${foreach MOD, ${MODNAMES}, ${MOD}Start();}${quote} >> ${OUTDIR}/InitMods.c
@echo ${quote}}${quote} >> ${OUTDIR}/InitMods.c
# Generate code for PyMite
${OUTDIR}/pmlib_img.c ${OUTDIR}/pmlib_nat.c ${OUTDIR}/pmlibusr_img.c ${OUTDIR}/pmlibusr_nat.c ${OUTDIR}/pmfeatures.h: $(wildcard ${PYMITELIB}/*.py) $(wildcard ${PYMITEPLAT}/*.py) $(wildcard ${FLIGHTPLANLIB}/*.py) $(wildcard ${FLIGHTPLANS}/*.py) $(wildcard $(UAVOBJPYTHONSYNTHDIR)/*.py)

View File

@ -83,6 +83,9 @@ do {\
#define portGET_RUN_TIME_COUNTER_VALUE() (*(unsigned long *)0xe0001004)/* DWT_CYCCNT */
#endif
#if !defined(ARCH_POSIX) && !defined(ARCH_WIN32)
#define CHECK_IRQ_STACK
#endif
/**
* @}

View File

@ -84,6 +84,8 @@
/* Alarm Thresholds */
#define HEAP_LIMIT_WARNING 4000
#define HEAP_LIMIT_CRITICAL 1000
#define IRQSTACK_LIMIT_WARNING 150
#define IRQSTACK_LIMIT_CRITICAL 80
#define CPULOAD_LIMIT_WARNING 80
#define CPULOAD_LIMIT_CRITICAL 95

View File

@ -62,11 +62,10 @@ static void TaskSDCard(void *pvParameters);
int32_t CONSOLE_Parse(uint8_t port, char c);
void OP_ADC_NotifyChange(uint32_t pin, uint32_t pin_value);
/* Prototype of generated InitModules() function */
extern void InitModules(void);
/* Prototype of PIOS_Board_Init() function */
extern void PIOS_Board_Init(void);
extern void Stack_Change(void);
static void Stack_Change_Weak () __attribute__ ((weakref ("Stack_Change")));
/**
* OpenPilot Main function:
@ -85,48 +84,42 @@ int main()
/* Brings up System using CMSIS functions, enables the LEDs. */
PIOS_SYS_Init();
/* Initialize the system thread */
SystemModInitialize();
/* Start the FreeRTOS scheduler */
vTaskStartScheduler();
/* If all is well we will never reach here as the scheduler will now be running. */
/* If we do get here, it will most likely be because we ran out of heap space. */
PIOS_LED_Off(LED1);
PIOS_LED_Off(LED2);
for(;;) {
PIOS_LED_Toggle(LED1);
PIOS_LED_Toggle(LED2);
PIOS_DELAY_WaitmS(100);
}
return 0;
}
/**
* Initialize the hardware, libraries and modules (called by the System thread in systemmod.c)
*/
void OpenPilotInit()
{
/* Architecture dependant Hardware and
* core subsystem initialisation
* (see pios_board.c for your arch)
* */
PIOS_Board_Init();
/* Initialize modules */
InitModules();
MODULE_INITIALISE_ALL
#if INCLUDE_TEST_TASKS
/* Create test tasks */
//xTaskCreate(TaskTesting, (signed portCHAR *)"Testing", configMINIMAL_STACK_SIZE , NULL, 4, NULL);
//xTaskCreate(TaskHIDTest, (signed portCHAR *)"HIDTest", configMINIMAL_STACK_SIZE , NULL, 3, NULL);
//xTaskCreate(TaskServos, (signed portCHAR *)"Servos", configMINIMAL_STACK_SIZE , NULL, 3, NULL);
//xTaskCreate(TaskSDCard, (signed portCHAR *)"SDCard", configMINIMAL_STACK_SIZE, NULL, (tskIDLE_PRIORITY + 2), NULL);
xTaskCreate(TaskTesting, (signed portCHAR *)"Testing", configMINIMAL_STACK_SIZE , NULL, 4, NULL);
xTaskCreate(TaskHIDTest, (signed portCHAR *)"HIDTest", configMINIMAL_STACK_SIZE , NULL, 3, NULL);
xTaskCreate(TaskServos, (signed portCHAR *)"Servos", configMINIMAL_STACK_SIZE , NULL, 3, NULL);
xTaskCreate(TaskSDCard, (signed portCHAR *)"SDCard", configMINIMAL_STACK_SIZE, NULL, (tskIDLE_PRIORITY + 2), NULL);
#endif
/* swap the stack to use the IRQ stack (does nothing in sim mode) */
Stack_Change_Weak();
/* Start the FreeRTOS scheduler which should never returns.*/
vTaskStartScheduler();
/* If all is well we will never reach here as the scheduler will now be running. */
/* Do some indication to user that something bad just happened */
PIOS_LED_Off(LED1); \
for(;;) { \
PIOS_LED_Toggle(LED1); \
PIOS_DELAY_WaitmS(100); \
};
return 0;
}
#if INCLUDE_TEST_TASKS
static void TaskTesting(void *pvParameters)
{
@ -342,5 +335,5 @@ static void TaskSDCard(void *pvParameters)
/**
* @}
* @}
*/
*/

View File

@ -38,7 +38,22 @@
* and we cannot define a linker script for each of them atm
*/
#define uavobj_initcall(fn)
extern void InitModules();
extern void StartModules();
#define UAVOBJ_INITCALL(fn)
#define MODULE_INITCALL(ifn, iparam, sfn, sparam, flags)
#define MODULE_TASKCREATE_ALL { \
/* Start all module threads */ \
StartModules(); \
}
#define MODULE_INITIALISE_ALL { \
/* Initialize modules */ \
InitModules(); \
/* Initialize the system thread */ \
SystemModInitialize();}
#endif /* PIOS_INITCALL_H */

View File

@ -38,7 +38,18 @@
* and we cannot define a linker script for each of them atm
*/
#define uavobj_initcall(fn)
#define UAVOBJ_INITCALL(fn)
#define MODULE_INITCALL(ifn, iparam, sfn, sparam, flags)
#define MODULE_TASKCREATE_ALL
#define MODULE_INITIALISE_ALL { \
/* Initialize modules */ \
InitModules(); \
/* Start the FreeRTOS scheduler which never returns.*/ \
/* Initialize the system thread */ \
SystemModInitialize();}
#endif /* PIOS_INITCALL_H */

View File

@ -81,9 +81,11 @@ static union xRTOS_HEAP
volatile unsigned long ulDummy;
#endif
unsigned char ucHeap[ configTOTAL_HEAP_SIZE ];
} xHeap;
} xHeap __attribute__ ((section (".heap")));
static size_t xNextFreeByte = ( size_t ) 0;
static size_t currentTOTAL_HEAP_SISE = configTOTAL_HEAP_SIZE;
/*-----------------------------------------------------------*/
void *pvPortMalloc( size_t xWantedSize )
@ -102,7 +104,7 @@ void *pvReturn = NULL;
vTaskSuspendAll();
{
/* Check there is enough room left for the allocation. */
if( ( ( xNextFreeByte + xWantedSize ) < configTOTAL_HEAP_SIZE ) &&
if( ( ( xNextFreeByte + xWantedSize ) < currentTOTAL_HEAP_SISE ) &&
( ( xNextFreeByte + xWantedSize ) > xNextFreeByte ) )/* Check for overflow. */
{
/* Return the next free byte then increment the index past this
@ -145,8 +147,14 @@ void vPortInitialiseBlocks( void )
size_t xPortGetFreeHeapSize( void )
{
return ( configTOTAL_HEAP_SIZE - xNextFreeByte );
return ( currentTOTAL_HEAP_SISE - xNextFreeByte );
}
/*-----------------------------------------------------------*/
void xPortIncreaseHeapSize( size_t bytes )
{
vTaskSuspendAll();
currentTOTAL_HEAP_SISE = configTOTAL_HEAP_SIZE + bytes;
xTaskResumeAll();
}
/*-----------------------------------------------------------*/

View File

@ -81,7 +81,7 @@ static union xRTOS_HEAP
volatile unsigned long ulDummy;
#endif
unsigned char ucHeap[ configTOTAL_HEAP_SIZE ];
} xHeap;
} xHeap __attribute__ ((section (".heap")));
/* Define the linked list structure. This is used to link free blocks in order
of their size. */
@ -101,6 +101,7 @@ static xBlockLink xStart, xEnd;
/* Keeps track of the number of free bytes remaining, but says nothing about
fragmentation. */
static size_t xFreeBytesRemaining = configTOTAL_HEAP_SIZE;
static size_t currentTOTAL_HEAP_SISE = configTOTAL_HEAP_SIZE;
/* STATIC FUNCTIONS ARE DEFINED AS MACROS TO MINIMIZE THE FUNCTION CALL DEPTH. */
@ -140,13 +141,13 @@ xBlockLink *pxFirstFreeBlock; \
xStart.xBlockSize = ( size_t ) 0; \
\
/* xEnd is used to mark the end of the list of free blocks. */ \
xEnd.xBlockSize = configTOTAL_HEAP_SIZE; \
xEnd.xBlockSize = currentTOTAL_HEAP_SISE; \
xEnd.pxNextFreeBlock = NULL; \
\
/* To start with there is a single free block that is sized to take up the \
entire heap space. */ \
pxFirstFreeBlock = ( void * ) xHeap.ucHeap; \
pxFirstFreeBlock->xBlockSize = configTOTAL_HEAP_SIZE; \
pxFirstFreeBlock->xBlockSize = currentTOTAL_HEAP_SISE; \
pxFirstFreeBlock->pxNextFreeBlock = &xEnd; \
}
/*-----------------------------------------------------------*/
@ -181,7 +182,7 @@ void *pvReturn = NULL;
}
}
if( ( xWantedSize > 0 ) && ( xWantedSize < configTOTAL_HEAP_SIZE ) )
if( ( xWantedSize > 0 ) && ( xWantedSize < currentTOTAL_HEAP_SISE ) )
{
/* Blocks are stored in byte order - traverse the list from the start
(smallest) block until one of adequate size is found. */
@ -276,3 +277,18 @@ void vPortInitialiseBlocks( void )
{
/* This just exists to keep the linker quiet. */
}
void xPortIncreaseHeapSize( size_t bytes )
{
xBlockLink *pxNewBlockLink;
vTaskSuspendAll();
currentTOTAL_HEAP_SISE = configTOTAL_HEAP_SIZE + bytes;
xEnd.xBlockSize = currentTOTAL_HEAP_SISE;
xFreeBytesRemaining += bytes;
/* Insert the new block into the list of free blocks. */
pxNewBlockLink = ( void * ) &xHeap.ucHeap[ configTOTAL_HEAP_SIZE ];
pxNewBlockLink->xBlockSize = bytes;
prvInsertBlockIntoFreeList( ( pxNewBlockLink ) );
xTaskResumeAll();
}
/*-----------------------------------------------------------*/

View File

@ -3,7 +3,8 @@ PROVIDE ( vPortSVCHandler = 0 ) ;
PROVIDE ( xPortPendSVHandler = 0 ) ;
PROVIDE ( xPortSysTickHandler = 0 ) ;
_estack = 0x20004FF0;
/* This is the size of the stack for early init and for all FreeRTOS IRQs */
_irq_stack_size = 0x400;
/* Section Definitions */
SECTIONS
@ -59,6 +60,24 @@ SECTIONS
_ebss = . ;
} > SRAM
/*
* This stack is used both as the initial sp during early init as well as ultimately
* being used as the STM32's MSP (Main Stack Pointer) which is the same stack that
* is used for _all_ interrupt handlers. The end of this stack should be placed
* against the lowest address in RAM so that a stack overrun results in a hard fault
* at the first access beyond the end of the stack.
*/
.irq_stack :
{
. = ALIGN(4);
_irq_stack_end = . ;
. = . + _irq_stack_size ;
. = ALIGN(4);
_irq_stack_top = . - 4 ;
_init_stack_top = _irq_stack_top;
. = ALIGN(4);
} > SRAM
. = ALIGN(4);
_end = . ;

View File

@ -1,3 +1,10 @@
/* This is the size of the stack for all FreeRTOS IRQs */
_irq_stack_size = 0x180;
/* This is the size of the stack for early init: life span is until scheduler starts */
_init_stack_size = 0x80;
/* there is probably a way to get that from the MEMORY section */
_eram = ORIGIN(SRAM) + LENGTH(SRAM);
/* Stub out these functions since we don't use them anyway */
PROVIDE ( vPortSVCHandler = 0 ) ;
PROVIDE ( xPortPendSVHandler = 0 ) ;
@ -5,8 +12,6 @@ PROVIDE ( xPortSysTickHandler = 0 ) ;
PROVIDE(pios_board_info_blob = ORIGIN(BD_INFO));
_estack = 0x20004FF0;
/* Section Definitions */
SECTIONS
{
@ -29,6 +34,16 @@ SECTIONS
__uavobj_initcall_end = .;
} >FLASH
/* module sections */
.initcallmodule.init :
{
. = ALIGN(4);
__module_initcall_start = .;
KEEP(*(.initcallmodule.init))
. = ALIGN(4);
__module_initcall_end = .;
} >FLASH
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
@ -43,6 +58,23 @@ SECTIONS
_etext = .;
_sidata = .;
/*
* This stack is used both as the initial sp during early init as well as ultimately
* being used as the STM32's MSP (Main Stack Pointer) which is the same stack that
* is used for _all_ interrupt handlers. The end of this stack should be placed
* against the lowest address in RAM so that a stack overrun results in a hard fault
* at the first access beyond the end of the stack.
*/
.irq_stack :
{
. = ALIGN(4);
_irq_stack_end = . ;
. = . + _irq_stack_size ;
. = ALIGN(4);
_irq_stack_top = . - 4 ;
. = ALIGN(4);
} > SRAM
.data : AT (_etext)
{
_sdata = .;
@ -51,6 +83,8 @@ SECTIONS
_edata = . ;
} > SRAM
/* .bss section which is used for uninitialized data */
.bss (NOLOAD) :
{
@ -60,6 +94,27 @@ SECTIONS
. = ALIGN(4);
_ebss = . ;
} > SRAM
.heap (NOLOAD) :
{
_sheap = . ;
_sheap_pre_rtos = . ;
*(.heap)
. = ALIGN(4);
_eheap = . ;
_eheap_pre_rtos = . ;
_init_stack_end = . ;
_sheap_post_rtos = . ;
. = . + _init_stack_size ;
. = ALIGN(4);
_eheap_post_rtos = . ;
_init_stack_top = . - 4 ;
} > SRAM
/* keep the heap section at the end of the SRAM */
/* this will allow to claim the remaining bytes not used
/* at run time! (done by the reset vector).
. = ALIGN(4);
_end = . ;

View File

@ -250,6 +250,7 @@ SECTIONS
. = . + _irq_stack_size ;
. = ALIGN(4);
_irq_stack_top = . - 4 ;
_init_stack_top = _irq_stack_top;
. = ALIGN(4);
} >RAM

View File

@ -223,6 +223,7 @@ SECTIONS
. = . + _irq_stack_size ;
. = ALIGN(4);
_irq_stack_top = . - 4 ;
_init_stack_top = _irq_stack_top;
. = ALIGN(4);
} >RAM
@ -364,5 +365,3 @@ SECTIONS
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
}

View File

@ -1,5 +1,9 @@
/* This is the size of the stack for early init and for all FreeRTOS IRQs */
_irq_stack_size = 0x400;
/* This is the size of the stack for early init: life span is until scheduler starts */
_init_stack_size = 0x400;
/* there is probably a way to get that from the MEMORY section */
_eram = ORIGIN(RAM) + LENGTH(RAM);
/* Check valid alignment for VTOR */
ASSERT(ORIGIN(FLASH) == ALIGN(ORIGIN(FLASH), 0x80), "Start of memory region flash not aligned for startup vector table");
@ -191,6 +195,16 @@ SECTIONS
__uavobj_initcall_end = .;
} >FLASH
/* module sections */
.initcallmodule.init :
{
. = ALIGN(4);
__module_initcall_start = .;
KEEP(*(.initcallmodule.init))
. = ALIGN(4);
__module_initcall_end = .;
} >FLASH
/* the program code is stored in the .text section, which goes to Flash */
.text :
{
@ -261,6 +275,26 @@ SECTIONS
_ebss = . ;
} >RAM
.heap (NOLOAD) :
{
_sheap = . ;
_sheap_pre_rtos = . ;
*(.heap)
. = ALIGN(4);
_eheap = . ;
_eheap_pre_rtos = . ;
_init_stack_end = . ;
_sheap_post_rtos = . ;
. = . + _init_stack_size ;
. = ALIGN(4);
_eheap_post_rtos = . ;
_init_stack_top = . - 4 ;
} > RAM
/* keep the heap section at the end of the SRAM */
/* this will allow to claim the remaining bytes not used
/* at run time! (done by the reset vector).
PROVIDE ( end = _ebss );
PROVIDE ( _end = _ebss );

View File

@ -36,6 +36,8 @@
.global g_pfnVectors
.global SystemInit_ExtMemCtl_Dummy
.global Default_Handler
.global xPortIncreaseHeapSize
.global Stack_Change
/* start address for the initialization values of the .data section.
defined in linker script */
@ -71,6 +73,35 @@ Reset_Handler:
/* restore original stack pointer */
LDR r0, =_irq_stack_top
MSR msp, r0
LDR r2, =_init_stack_top
MSR psp, r2
/* check if irq and init stack are the same */
/* if they are, we don't do stack swap */
/* and lets bypass the monitoring as well for now */
cmp r0, r2
beq SectionBssInit
/* DO
* - stay in thread process mode
* - stay in privilege level
* - use process stack
*/
movs r0, #2
MSR control, r0
ISB
/* Fill IRQ stack for watermark monitoring */
ldr r2, =_irq_stack_end
b LoopFillIRQStack
FillIRQStack:
movw r3, #0xA5A5
str r3, [r2], #4
LoopFillIRQStack:
ldr r3, = _irq_stack_top
cmp r2, r3
bcc FillIRQStack
SectionBssInit:
/* Copy the data segment initializers from flash to SRAM */
movs r1, #0
b LoopCopyDataInit
@ -100,9 +131,37 @@ LoopFillZerobss:
bcc FillZerobss
/* Call the application's entry point.*/
bl main
bx lr
/* will never return here */
bx lr
.size Reset_Handler, .-Reset_Handler
/**
* @brief This is the code that swaps stack (from end of heap to irq_stack).
* Also reclaim the heap that was used as a stack.
* @param None
* @retval : None
*/
.section .text.Stack_Change
.weak Stack_Change
.type Stack_Change, %function
Stack_Change:
mov r4, lr
/* Switches stack back momentarily to MSP */
movs r0, #0
msr control, r0
Heap_Reclaim:
/* add heap_post_rtos to the heap (if the capability/function exist) */
/* Also claim the unused memory (between end of heap to end of memory */
/* CAREFULL: the heap section must be the last section in RAM in order this to work */
ldr r0, = _init_stack_size
ldr r1, = _eheap_post_rtos
ldr r2, = _eram
subs r2, r2, r1
adds r0, r0, r2
bl xPortIncreaseHeapSize
bx r4
.size Stack_Change, .-Stack_Change
/**
* @brief Dummy SystemInit_ExtMemCtl function
* @param None
@ -114,12 +173,12 @@ SystemInit_ExtMemCtl_Dummy:
.size SystemInit_ExtMemCtl_Dummy, .-SystemInit_ExtMemCtl_Dummy
/**
* @brief This is the code that gets called when the processor receives an
* @brief This is the code that gets called when the processor receives an
* unexpected interrupt. This simply enters an infinite loop, preserving
* the system state for examination by a debugger.
*
* @param None
* @retval : None
* @param None
* @retval : None
*/
.section .text.Default_Handler,"ax",%progbits
Default_Handler:
@ -272,13 +331,13 @@ g_pfnVectors:
.weak NMI_Handler
.thumb_set NMI_Handler,Default_Handler
.weak HardFault_Handler
.thumb_set HardFault_Handler,Default_Handler
.weak MemManage_Handler
.thumb_set MemManage_Handler,Default_Handler
.weak BusFault_Handler
.thumb_set BusFault_Handler,Default_Handler

View File

@ -33,6 +33,8 @@
.global g_pfnVectors
.global Default_Handler
.global xPortIncreaseHeapSize
.global Stack_Change
/* start address for the initialization values of the .data section.
defined in linker script */
@ -61,6 +63,47 @@ defined in linker script */
.type Reset_Handler, %function
Reset_Handler:
/*
* From COrtex-M3 reference manual:
* - Handler IRQ always use SP_main
* - Process use SP_main or SP_process
* Here, we will use beginning of SRAM for IRQ (SP_main)
* and end of heap for initialization (SP_process).
* Once the schedule starts, all threads will use their own stack
* from heap and NOBOBY should use SP_process again.
*/
/* Do set/reset the stack pointers */
LDR r0, =_irq_stack_top
MSR msp, r0
LDR r2, =_init_stack_top
MSR psp, r2
/* check if irq and init stack are the same */
/* if they are, we don't do stack swap */
/* and lets bypass the monitoring as well for now */
cmp r0, r2
beq SectionBssInit
/* DO
* - stay in thread process mode
* - stay in privilege level
* - use process stack
*/
movs r0, #2
MSR control, r0
ISB
/* Fill IRQ stack for watermark monitoring */
ldr r2, =_irq_stack_end
b LoopFillIRQStack
FillIRQStack:
movw r3, #0xA5A5
str r3, [r2], #4
LoopFillIRQStack:
ldr r3, = _irq_stack_top
cmp r2, r3
bcc FillIRQStack
SectionBssInit:
/* Copy the data segment initializers from flash to SRAM */
movs r1, #0
b LoopCopyDataInit
@ -90,16 +133,45 @@ LoopFillZerobss:
bcc FillZerobss
/* Call the application's entry point.*/
bl main
/* will never return here */
bx lr
.size Reset_Handler, .-Reset_Handler
/**
* @brief This is the code that gets called when the processor receives an
* @brief This is the code that swaps stack (from end of heap to irq_stack).
* Also reclaim the heap that was used as a stack.
* @param None
* @retval : None
*/
.section .text.Stack_Change
.weak Stack_Change
.type Stack_Change, %function
Stack_Change:
mov r4, lr
/* Switches stack back momentarily to MSP */
movs r0, #0
msr control, r0
Heap_Reclaim:
/* add heap_post_rtos to the heap (if the capability/function exist) */
/* Also claim the unused memory (between end of heap to end of memory */
/* CAREFULL: the heap section must be the last section in RAM in order this to work */
ldr r0, = _init_stack_size
ldr r1, = _eheap_post_rtos
ldr r2, = _eram
subs r2, r2, r1
adds r0, r0, r2
bl xPortIncreaseHeapSize
bx r4
.size Stack_Change, .-Stack_Change
/**
* @brief This is the code that gets called when the processor receives an
* unexpected interrupt. This simply enters an infinite loop, preserving
* the system state for examination by a debugger.
*
* @param None
* @retval : None
* @param None
* @retval : None
*/
.section .text.Default_Handler,"ax",%progbits
Default_Handler:
@ -119,7 +191,7 @@ Infinite_Loop:
g_pfnVectors:
.word _estack
.word _irq_stack_top
.word Reset_Handler
.word NMI_Handler
.word HardFault_Handler

View File

@ -41,7 +41,21 @@
/*
* Used for initialization calls..
*/
#define MODULE_EXEC_NOORDER_FLAG 0xFA000000
#define MODULE_EXEC_FIRST_FLAG 0xFA000001
#define MODULE_EXEC_LAST_FLAG 0xFA000002
typedef int32_t (*initcall_t)(void);
typedef struct {
uint32_t flag;
uint32_t param_minit;
initcall_t fn_minit;
uint32_t param_tinit;
initcall_t fn_tinit;
} initmodule_t;
/* Init module section */
extern initmodule_t __module_initcall_start[], __module_initcall_end[];
/* initcalls are now grouped by functionality into separate
* subsections. Ordering inside the subsections is determined
@ -55,7 +69,26 @@ typedef int32_t (*initcall_t)(void);
static initcall_t __initcall_##fn##id __attribute__((__used__)) \
__attribute__((__section__(".initcall" level ".init"))) = fn
#define uavobj_initcall(fn) __define_initcall("uavobj",fn,1)
#define __define_module_initcall(level,ifn,iparam,sfn,sparam, param) \
static initmodule_t __initcall_##fn __attribute__((__used__)) \
__attribute__((__section__(".initcall" level ".init"))) = { .flag = param, .param_minit = iparam, .fn_minit = ifn, .param_tinit = sparam, .fn_tinit = sfn };
#define UAVOBJ_INITCALL(fn) __define_initcall("uavobj",fn,1)
#define MODULE_INITCALL(ifn, iparam, sfn, sparam, flags) __define_module_initcall("module", ifn, iparam, sfn, sparam, flags)
#define MODULE_INITIALISE_ALL { for (initmodule_t *fn = __module_initcall_start; fn < __module_initcall_end; fn++) \
if (fn->fn_minit && ( (fn->flag & MODULE_EXEC_FIRST_FLAG) == MODULE_EXEC_FIRST_FLAG) ) \
(fn->fn_minit)(); \
for (initmodule_t *fn = __module_initcall_start; fn < __module_initcall_end; fn++) \
if (fn->fn_minit && ( (fn->flag & (MODULE_EXEC_LAST_FLAG | MODULE_EXEC_FIRST_FLAG)) == MODULE_EXEC_NOORDER_FLAG) ) \
(fn->fn_minit)(); \
for (initmodule_t *fn = __module_initcall_start; fn < __module_initcall_end; fn++) \
if (fn->fn_minit && ( (fn->flag & MODULE_EXEC_LAST_FLAG) == MODULE_EXEC_LAST_FLAG) ) \
(fn->fn_minit)(); }
#define MODULE_TASKCREATE_ALL { for (initmodule_t *fn = __module_initcall_start; fn < __module_initcall_end; fn++) \
if (fn->fn_tinit) \
(fn->fn_tinit)(); }
#endif /* PIOS_INITCALL_H */

View File

@ -64,7 +64,7 @@ int32_t $(NAME)Initialize(void)
}
}
uavobj_initcall($(NAME)Initialize);
UAVOBJ_INITCALL($(NAME)Initialize);
/**
* Initialize object fields and metadata with the default values.

View File

@ -3,6 +3,7 @@
<description>CPU and memory usage from OpenPilot computer. </description>
<field name="FlightTime" units="ms" type="uint32" elements="1"/>
<field name="HeapRemaining" units="bytes" type="uint16" elements="1"/>
<field name="IRQStackRemaining" units="bytes" type="uint16" elements="1"/>
<field name="CPULoad" units="%" type="uint8" elements="1"/>
<field name="CPUTemp" units="C" type="int8" elements="1"/>
<access gcs="readwrite" flight="readwrite"/>