mirror of
https://github.com/ArduPilot/ardupilot
synced 2025-02-04 06:58:39 -04:00
HAL_ChibiOS: improved stack checking and stack display
display both ISR stack and thread stacks. Show total stack sizes as well as amount of stack remaining
This commit is contained in:
parent
84eac7642b
commit
ba69cd72c9
@ -500,7 +500,7 @@ void Scheduler::_io_thread(void* arg)
|
|||||||
#if CH_DBG_ENABLE_STACK_CHECK == TRUE
|
#if CH_DBG_ENABLE_STACK_CHECK == TRUE
|
||||||
if (now - last_stack_check_ms > 1000) {
|
if (now - last_stack_check_ms > 1000) {
|
||||||
last_stack_check_ms = now;
|
last_stack_check_ms = now;
|
||||||
check_stack_free();
|
sched->check_stack_free();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -711,20 +711,29 @@ void Scheduler::watchdog_pat(void)
|
|||||||
*/
|
*/
|
||||||
void Scheduler::check_stack_free(void)
|
void Scheduler::check_stack_free(void)
|
||||||
{
|
{
|
||||||
|
// we raise an internal error stack_overflow when the available
|
||||||
|
// stack on any thread or the ISR stack drops below this
|
||||||
|
// threshold. This means we get an overflow error when we haven't
|
||||||
|
// yet completely run out of stack. This gives us a good
|
||||||
|
// pre-warning when we are getting too close
|
||||||
|
#if defined(STM32F1)
|
||||||
const uint32_t min_stack = 32;
|
const uint32_t min_stack = 32;
|
||||||
bool ok = false;
|
#else
|
||||||
|
const uint32_t min_stack = 64;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (stack_free(__main_stack_base__) < min_stack) {
|
if (stack_free(&__main_stack_base__) < min_stack) {
|
||||||
AP::internalerror().error(error_number, 0xFFFF);
|
// use "line number" of 0xFFFF for ISR stack low
|
||||||
|
AP::internalerror().error(AP_InternalError::error_t::stack_overflow, 0xFFFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
thread_t *tp = chRegFirstThread();
|
for (thread_t *tp = chRegFirstThread(); tp; tp = chRegNextThread(tp)) {
|
||||||
do {
|
|
||||||
if (stack_free(tp->wabase) < min_stack) {
|
if (stack_free(tp->wabase) < min_stack) {
|
||||||
AP::internalerror().error(error_number, tp->prio);
|
// use task priority for line number. This allows us to
|
||||||
|
// identify the task fairly reliably
|
||||||
|
AP::internalerror().error(AP_InternalError::error_t::stack_overflow, tp->prio);
|
||||||
}
|
}
|
||||||
tp = chRegNextThread(tp);
|
}
|
||||||
} while (tp != NULL);
|
|
||||||
}
|
}
|
||||||
#endif // CH_DBG_ENABLE_STACK_CHECK == TRUE
|
#endif // CH_DBG_ENABLE_STACK_CHECK == TRUE
|
||||||
|
|
||||||
|
@ -300,12 +300,12 @@ bool Util::was_watchdog_reset() const
|
|||||||
*/
|
*/
|
||||||
size_t Util::thread_info(char *buf, size_t bufsize)
|
size_t Util::thread_info(char *buf, size_t bufsize)
|
||||||
{
|
{
|
||||||
thread_t *tp;
|
|
||||||
size_t total = 0;
|
size_t total = 0;
|
||||||
|
|
||||||
// a header to allow for machine parsers to determine format
|
// a header to allow for machine parsers to determine format
|
||||||
int n = snprintf(buf, bufsize, "ThreadsV2\nISR PRI=255 sp=%p STACK_FREE=%u/%u\n",
|
const uint32_t isr_stack_size = uint32_t((const uint8_t *)&__main_stack_end__ - (const uint8_t *)&__main_stack_base__);
|
||||||
__main_stack_base__, stack_free(__main_stack_base__), __main_stack_size__);
|
int n = snprintf(buf, bufsize, "ThreadsV2\nISR PRI=255 sp=%p STACK=%u/%u\n",
|
||||||
|
&__main_stack_base__, stack_free(&__main_stack_base__), isr_stack_size);
|
||||||
if (n <= 0) {
|
if (n <= 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -313,21 +313,28 @@ size_t Util::thread_info(char *buf, size_t bufsize)
|
|||||||
bufsize -= n;
|
bufsize -= n;
|
||||||
total += n;
|
total += n;
|
||||||
|
|
||||||
tp = chRegFirstThread();
|
for (thread_t *tp = chRegFirstThread(); tp; tp = chRegNextThread(tp)) {
|
||||||
|
uint32_t total_stack;
|
||||||
do {
|
if (tp->wabase == (void*)&__main_thread_stack_base__) {
|
||||||
const uint32_t total_stack = uint32_t(tp) - uint32_t(tp->wabase);
|
// main thread has its stack separated from the thread context
|
||||||
n = snprintf(buf, bufsize, "%-13.13s PRI=%3u sp=%p STACK_LEFT=%u/%u\n",
|
total_stack = uint32_t((const uint8_t *)&__main_thread_stack_end__ - (const uint8_t *)&__main_thread_stack_base__);
|
||||||
tp->name, unsigned(tp->prio), tp->wabase,
|
} else {
|
||||||
stack_free(tp->wabase), total_stack);
|
// all other threads have their thread context pointer
|
||||||
if (n <= 0) {
|
// above the stack top
|
||||||
break;
|
total_stack = uint32_t(tp) - uint32_t(tp->wabase);
|
||||||
}
|
}
|
||||||
buf += n;
|
if (bufsize > 0) {
|
||||||
bufsize -= n;
|
n = snprintf(buf, bufsize, "%-13.13s PRI=%3u sp=%p STACK=%u/%u\n",
|
||||||
total += n;
|
tp->name, unsigned(tp->prio), tp->wabase,
|
||||||
tp = chRegNextThread(tp);
|
stack_free(tp->wabase), total_stack);
|
||||||
} while (tp != NULL);
|
if (n > bufsize) {
|
||||||
|
n = bufsize;
|
||||||
|
}
|
||||||
|
buf += n;
|
||||||
|
bufsize -= n;
|
||||||
|
total += n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
@ -462,6 +462,6 @@ uint32_t stack_free(void *stack_base)
|
|||||||
while (*p == canary_word) {
|
while (*p == canary_word) {
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
return uint32_t(p) - uint32_t(stack_base);
|
return ((uint32_t)p) - (uint32_t)stack_base;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -117,8 +117,10 @@ void stack_overflow(thread_t *tp);
|
|||||||
uint32_t stack_free(void *stack_base);
|
uint32_t stack_free(void *stack_base);
|
||||||
|
|
||||||
// allow stack view code to show free ISR stack
|
// allow stack view code to show free ISR stack
|
||||||
extern void *__main_stack_base__;
|
extern uint32_t __main_stack_base__;
|
||||||
extern uint32_t __main_stack_size__;
|
extern uint32_t __main_stack_end__;
|
||||||
|
extern uint32_t __main_thread_stack_base__;
|
||||||
|
extern uint32_t __main_thread_stack_end__;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user