mirror of
https://github.com/iNavFlight/inav.git
synced 2025-07-24 00:35:34 +03:00
Merge pull request #642 from iNavFlight/martinbudden-inav_stack_check
Stack watermarking
This commit is contained in:
commit
b32e9e7b99
16 changed files with 685 additions and 478 deletions
1
Makefile
1
Makefile
|
@ -396,6 +396,7 @@ COMMON_SRC = \
|
||||||
drivers/serial.c \
|
drivers/serial.c \
|
||||||
drivers/serial_uart.c \
|
drivers/serial_uart.c \
|
||||||
drivers/sound_beeper.c \
|
drivers/sound_beeper.c \
|
||||||
|
drivers/stack_check.c \
|
||||||
drivers/system.c \
|
drivers/system.c \
|
||||||
drivers/timer.c \
|
drivers/timer.c \
|
||||||
drivers/io_pca9685.c \
|
drivers/io_pca9685.c \
|
||||||
|
|
79
src/main/drivers/stack_check.c
Normal file
79
src/main/drivers/stack_check.c
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
/*
|
||||||
|
* stack_check.c
|
||||||
|
*
|
||||||
|
* Created on: 23 Aug 2016
|
||||||
|
* Author: martinbudden
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "platform.h"
|
||||||
|
|
||||||
|
#ifdef STACK_CHECK
|
||||||
|
|
||||||
|
#include "build/debug.h"
|
||||||
|
|
||||||
|
#define STACK_FILL_CHAR 0xa5
|
||||||
|
|
||||||
|
extern char _estack; // end of stack, declared in .LD file
|
||||||
|
extern char _Min_Stack_Size; // declared in .LD file
|
||||||
|
static uint32_t _Used_Stack_Size;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The ARM processor uses a full descending stack. This means the stack pointer holds the address
|
||||||
|
* of the last stacked item in memory. When the processor pushes a new item onto the stack,
|
||||||
|
* it decrements the stack pointer and then writes the item to the new memory location.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* RAM layout is generally as below, although some targets vary
|
||||||
|
*
|
||||||
|
* F1 Boards
|
||||||
|
* RAM is origin 0x20000000 length 20K that is:
|
||||||
|
* 0x20000000 to 0x20005000
|
||||||
|
*
|
||||||
|
* F3 Boards
|
||||||
|
* RAM is origin 0x20000000 length 40K that is:
|
||||||
|
* 0x20000000 to 0x2000a000
|
||||||
|
*
|
||||||
|
* F4 Boards
|
||||||
|
* RAM is origin 0x20000000 length 128K that is:
|
||||||
|
* 0x20000000 to 0x20020000
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void taskStackCheck(void)
|
||||||
|
{
|
||||||
|
char * const stackHighMem = &_estack;
|
||||||
|
const uint32_t stackSize = (uint32_t)&_Min_Stack_Size;
|
||||||
|
char * const stackLowMem = stackHighMem - stackSize;
|
||||||
|
const char * const stackCurrent = (char *)&stackLowMem;
|
||||||
|
|
||||||
|
char *p;
|
||||||
|
for (p = stackLowMem; p < stackCurrent; ++p) {
|
||||||
|
if (*p != STACK_FILL_CHAR) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_Used_Stack_Size = (uint32_t)stackHighMem - (uint32_t)p;
|
||||||
|
|
||||||
|
#ifdef DEBUG_STACK
|
||||||
|
debug[0] = (uint32_t)stackHighMem & 0xffff;
|
||||||
|
debug[1] = (uint32_t)stackLowMem & 0xffff;
|
||||||
|
debug[2] = (uint32_t)stackCurrent & 0xffff;
|
||||||
|
debug[3] = (uint32_t)p & 0xffff;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t getTotalStackSize(void)
|
||||||
|
{
|
||||||
|
return (uint32_t)&_Min_Stack_Size;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t getUsedStackSize(void)
|
||||||
|
{
|
||||||
|
return _Used_Stack_Size;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
23
src/main/drivers/stack_check.h
Executable file
23
src/main/drivers/stack_check.h
Executable file
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Cleanflight.
|
||||||
|
*
|
||||||
|
* Cleanflight 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.
|
||||||
|
*
|
||||||
|
* Cleanflight 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 Cleanflight. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef STACK_CHECK
|
||||||
|
uint32_t getTotalStackSize(void);
|
||||||
|
uint32_t getUsedStackSize(void);
|
||||||
|
#endif
|
|
@ -52,6 +52,7 @@
|
||||||
#include "drivers/timer.h"
|
#include "drivers/timer.h"
|
||||||
#include "drivers/pwm_rx.h"
|
#include "drivers/pwm_rx.h"
|
||||||
#include "drivers/sdcard.h"
|
#include "drivers/sdcard.h"
|
||||||
|
#include "drivers/stack_check.h"
|
||||||
|
|
||||||
#include "drivers/buf_writer.h"
|
#include "drivers/buf_writer.h"
|
||||||
|
|
||||||
|
@ -2818,6 +2819,10 @@ static void cliStatus(char *cmdline)
|
||||||
const uint16_t i2cErrorCounter = 0;
|
const uint16_t i2cErrorCounter = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef STACK_CHECK
|
||||||
|
cliPrintf("Used stack: %d, Total stack: %d\r\n", getUsedStackSize(), getTotalStackSize());
|
||||||
|
#endif
|
||||||
|
|
||||||
cliPrintf("Cycle Time: %d, I2C Errors: %d, config size: %d\r\n", cycleTime, i2cErrorCounter, sizeof(master_t));
|
cliPrintf("Cycle Time: %d, I2C Errors: %d, config size: %d\r\n", cycleTime, i2cErrorCounter, sizeof(master_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -652,6 +652,9 @@ int main(void)
|
||||||
#ifdef LED_STRIP
|
#ifdef LED_STRIP
|
||||||
setTaskEnabled(TASK_LEDSTRIP, feature(FEATURE_LED_STRIP));
|
setTaskEnabled(TASK_LEDSTRIP, feature(FEATURE_LED_STRIP));
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef STACK_CHECK
|
||||||
|
setTaskEnabled(TASK_STACK_CHECK, true);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef USE_PMW_SERVO_DRIVER
|
#ifdef USE_PMW_SERVO_DRIVER
|
||||||
setTaskEnabled(TASK_PWMDRIVER, feature(FEATURE_PWM_SERVO_DRIVER));
|
setTaskEnabled(TASK_PWMDRIVER, feature(FEATURE_PWM_SERVO_DRIVER));
|
||||||
|
|
|
@ -71,6 +71,9 @@ typedef enum {
|
||||||
#ifdef USE_PMW_SERVO_DRIVER
|
#ifdef USE_PMW_SERVO_DRIVER
|
||||||
TASK_PWMDRIVER,
|
TASK_PWMDRIVER,
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef STACK_CHECK
|
||||||
|
TASK_STACK_CHECK,
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Count of real tasks */
|
/* Count of real tasks */
|
||||||
TASK_COUNT,
|
TASK_COUNT,
|
||||||
|
|
|
@ -139,4 +139,12 @@ cfTask_t cfTasks[TASK_COUNT] = {
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef STACK_CHECK
|
||||||
|
[TASK_STACK_CHECK] = {
|
||||||
|
.taskName = "STACKCHECK",
|
||||||
|
.taskFunc = taskStackCheck,
|
||||||
|
.desiredPeriod = 1000000 / 10, // 10 Hz
|
||||||
|
.staticPriority = TASK_PRIORITY_IDLE,
|
||||||
|
},
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
|
@ -36,3 +36,4 @@ void taskSystem(void);
|
||||||
#ifdef USE_PMW_SERVO_DRIVER
|
#ifdef USE_PMW_SERVO_DRIVER
|
||||||
void taskSyncPwmDriver(void);
|
void taskSyncPwmDriver(void);
|
||||||
#endif
|
#endif
|
||||||
|
void taskStackCheck(void);
|
||||||
|
|
|
@ -98,6 +98,19 @@ LoopFillZerobss:
|
||||||
cmp r2, r3
|
cmp r2, r3
|
||||||
bcc FillZerobss
|
bcc FillZerobss
|
||||||
|
|
||||||
|
/* Mark the heap and stack */
|
||||||
|
ldr r2, =_heap_stack_begin
|
||||||
|
b LoopMarkHeapStack
|
||||||
|
|
||||||
|
MarkHeapStack:
|
||||||
|
movs r3, 0xa5a5a5a5
|
||||||
|
str r3, [r2], #4
|
||||||
|
|
||||||
|
LoopMarkHeapStack:
|
||||||
|
ldr r3, = _heap_stack_end
|
||||||
|
cmp r2, r3
|
||||||
|
bcc MarkHeapStack
|
||||||
|
|
||||||
/* Call the clock system intitialization function.*/
|
/* Call the clock system intitialization function.*/
|
||||||
bl SystemInit
|
bl SystemInit
|
||||||
/* Call the application's entry point.*/
|
/* Call the application's entry point.*/
|
||||||
|
|
|
@ -97,6 +97,19 @@ LoopFillZerobss:
|
||||||
cmp r2, r3
|
cmp r2, r3
|
||||||
bcc FillZerobss
|
bcc FillZerobss
|
||||||
|
|
||||||
|
/* Mark the heap and stack */
|
||||||
|
ldr r2, =_heap_stack_begin
|
||||||
|
b LoopMarkHeapStack
|
||||||
|
|
||||||
|
MarkHeapStack:
|
||||||
|
movs r3, 0xa5a5a5a5
|
||||||
|
str r3, [r2], #4
|
||||||
|
|
||||||
|
LoopMarkHeapStack:
|
||||||
|
ldr r3, = _heap_stack_end
|
||||||
|
cmp r2, r3
|
||||||
|
bcc MarkHeapStack
|
||||||
|
|
||||||
/* Call the clock system intitialization function.*/
|
/* Call the clock system intitialization function.*/
|
||||||
bl SystemInit
|
bl SystemInit
|
||||||
/* Call the application's entry point.*/
|
/* Call the application's entry point.*/
|
||||||
|
|
|
@ -105,6 +105,19 @@ LoopFillZerobss:
|
||||||
cmp r2, r3
|
cmp r2, r3
|
||||||
bcc FillZerobss
|
bcc FillZerobss
|
||||||
|
|
||||||
|
/* Mark the heap and stack */
|
||||||
|
ldr r2, =_heap_stack_begin
|
||||||
|
b LoopMarkHeapStack
|
||||||
|
|
||||||
|
MarkHeapStack:
|
||||||
|
movs r3, 0xa5a5a5a5
|
||||||
|
str r3, [r2], #4
|
||||||
|
|
||||||
|
LoopMarkHeapStack:
|
||||||
|
ldr r3, = _heap_stack_end
|
||||||
|
cmp r2, r3
|
||||||
|
bcc MarkHeapStack
|
||||||
|
|
||||||
/* Call the clock system intitialization function.*/
|
/* Call the clock system intitialization function.*/
|
||||||
bl SystemInit
|
bl SystemInit
|
||||||
/* Call the application's entry point.*/
|
/* Call the application's entry point.*/
|
||||||
|
|
|
@ -108,6 +108,19 @@ LoopFillZerobss:
|
||||||
cmp r2, r3
|
cmp r2, r3
|
||||||
bcc FillZerobss
|
bcc FillZerobss
|
||||||
|
|
||||||
|
/* Mark the heap and stack */
|
||||||
|
ldr r2, =_heap_stack_begin
|
||||||
|
b LoopMarkHeapStack
|
||||||
|
|
||||||
|
MarkHeapStack:
|
||||||
|
movs r3, 0xa5a5a5a5
|
||||||
|
str r3, [r2], #4
|
||||||
|
|
||||||
|
LoopMarkHeapStack:
|
||||||
|
ldr r3, = _heap_stack_end
|
||||||
|
cmp r2, r3
|
||||||
|
bcc MarkHeapStack
|
||||||
|
|
||||||
/* Call the clock system intitialization function.*/
|
/* Call the clock system intitialization function.*/
|
||||||
bl SystemInit
|
bl SystemInit
|
||||||
/* Call the application's entry point.*/
|
/* Call the application's entry point.*/
|
||||||
|
|
|
@ -107,6 +107,19 @@ LoopFillZerobss:
|
||||||
cmp r2, r3
|
cmp r2, r3
|
||||||
bcc FillZerobss
|
bcc FillZerobss
|
||||||
|
|
||||||
|
/* Mark the heap and stack */
|
||||||
|
ldr r2, =_heap_stack_begin
|
||||||
|
b LoopMarkHeapStack
|
||||||
|
|
||||||
|
MarkHeapStack:
|
||||||
|
movs r3, 0xa5a5a5a5
|
||||||
|
str r3, [r2], #4
|
||||||
|
|
||||||
|
LoopMarkHeapStack:
|
||||||
|
ldr r3, = _heap_stack_end
|
||||||
|
cmp r2, r3
|
||||||
|
bcc MarkHeapStack
|
||||||
|
|
||||||
/*FPU settings*/
|
/*FPU settings*/
|
||||||
ldr r0, =0xE000ED88 /* Enable CP10,CP11 */
|
ldr r0, =0xE000ED88 /* Enable CP10,CP11 */
|
||||||
ldr r1,[r0]
|
ldr r1,[r0]
|
||||||
|
|
|
@ -107,6 +107,19 @@ LoopFillZerobss:
|
||||||
cmp r2, r3
|
cmp r2, r3
|
||||||
bcc FillZerobss
|
bcc FillZerobss
|
||||||
|
|
||||||
|
/* Mark the heap and stack */
|
||||||
|
ldr r2, =_heap_stack_begin
|
||||||
|
b LoopMarkHeapStack
|
||||||
|
|
||||||
|
MarkHeapStack:
|
||||||
|
movs r3, 0xa5a5a5a5
|
||||||
|
str r3, [r2], #4
|
||||||
|
|
||||||
|
LoopMarkHeapStack:
|
||||||
|
ldr r3, = _heap_stack_end
|
||||||
|
cmp r2, r3
|
||||||
|
bcc MarkHeapStack
|
||||||
|
|
||||||
/*FPU settings*/
|
/*FPU settings*/
|
||||||
ldr r0, =0xE000ED88 /* Enable CP10,CP11 */
|
ldr r0, =0xE000ED88 /* Enable CP10,CP11 */
|
||||||
ldr r1,[r0]
|
ldr r1,[r0]
|
||||||
|
|
|
@ -109,6 +109,9 @@
|
||||||
#undef BLACKBOX
|
#undef BLACKBOX
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define STACK_CHECK
|
||||||
|
#define DEBUG_STACK
|
||||||
|
|
||||||
// Number of available PWM outputs
|
// Number of available PWM outputs
|
||||||
#define MAX_PWM_OUTPUT_PORTS 4
|
#define MAX_PWM_OUTPUT_PORTS 4
|
||||||
|
|
||||||
|
|
|
@ -110,6 +110,9 @@ SECTIONS
|
||||||
} >RAM
|
} >RAM
|
||||||
|
|
||||||
/* User_heap_stack section, used to check that there is enough RAM left */
|
/* User_heap_stack section, used to check that there is enough RAM left */
|
||||||
|
_heap_stack_end = ORIGIN(RAM)+LENGTH(RAM) - 8; /* 8 bytes to allow for alignment */
|
||||||
|
_heap_stack_begin = _heap_stack_end - _Min_Stack_Size - _Min_Heap_Size;
|
||||||
|
. = _heap_stack_begin;
|
||||||
._user_heap_stack :
|
._user_heap_stack :
|
||||||
{
|
{
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
|
@ -118,7 +121,7 @@ SECTIONS
|
||||||
. = . + _Min_Heap_Size;
|
. = . + _Min_Heap_Size;
|
||||||
. = . + _Min_Stack_Size;
|
. = . + _Min_Stack_Size;
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
} >RAM
|
} >RAM = 0xa5
|
||||||
|
|
||||||
/* MEMORY_bank1 section, code must be located here explicitly */
|
/* MEMORY_bank1 section, code must be located here explicitly */
|
||||||
/* Example: extern int foo(void) __attribute__ ((section (".mb1text"))); */
|
/* Example: extern int foo(void) __attribute__ ((section (".mb1text"))); */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue