add fancy hardfault handler, increase heater stack size
This commit is contained in:
@@ -121,6 +121,7 @@ void app_task_gui(void *argument) {
|
|||||||
/** Switch to a different screen handler.
|
/** Switch to a different screen handler.
|
||||||
* If "init" is true, immediately call it with the init event. */
|
* If "init" is true, immediately call it with the init event. */
|
||||||
void switch_screen(screen_t pScreen, bool init) {
|
void switch_screen(screen_t pScreen, bool init) {
|
||||||
|
PRINTF("Screen = %p, init=%d\r\n", pScreen, init);
|
||||||
s_app.initial_pushed = s_app.pushed;
|
s_app.initial_pushed = s_app.pushed;
|
||||||
s_app.screen = pScreen;
|
s_app.screen = pScreen;
|
||||||
// clear the union field
|
// clear the union field
|
||||||
|
|||||||
+1
-1
@@ -313,7 +313,7 @@ void app_temp_sample()
|
|||||||
|
|
||||||
float y = s_analog.cal_a * sum + s_analog.cal_b;
|
float y = s_analog.cal_a * sum + s_analog.cal_b;
|
||||||
float actual_temp = val_to_c(y);
|
float actual_temp = val_to_c(y);
|
||||||
PRINTF("T raw %f %f -> comp %f, temp %f°C\r\n", sum, y, actual_temp);
|
PRINTF("T raw %f -> comp %f, temp %f°C\r\n", sum, y, actual_temp);
|
||||||
|
|
||||||
s_analog.oven_temp = actual_temp;
|
s_analog.oven_temp = actual_temp;
|
||||||
s_analog.oven_temp_raw = sum;
|
s_analog.oven_temp_raw = sum;
|
||||||
|
|||||||
+1
-1
@@ -66,7 +66,7 @@ const osThreadAttr_t mainTsk_attributes = {
|
|||||||
};
|
};
|
||||||
/* Definitions for heaterTsk */
|
/* Definitions for heaterTsk */
|
||||||
osThreadId_t heaterTskHandle;
|
osThreadId_t heaterTskHandle;
|
||||||
uint32_t heaterTskBuffer[ 128 ];
|
uint32_t heaterTskBuffer[ 256 ];
|
||||||
osStaticThreadDef_t heaterTskControlBlock;
|
osStaticThreadDef_t heaterTskControlBlock;
|
||||||
const osThreadAttr_t heaterTsk_attributes = {
|
const osThreadAttr_t heaterTsk_attributes = {
|
||||||
.name = "heaterTsk",
|
.name = "heaterTsk",
|
||||||
|
|||||||
+169
-13
@@ -26,6 +26,8 @@
|
|||||||
/* USER CODE BEGIN Includes */
|
/* USER CODE BEGIN Includes */
|
||||||
#include "app_temp.h"
|
#include "app_temp.h"
|
||||||
#include "app_knob.h"
|
#include "app_knob.h"
|
||||||
|
#include "app_heater.h"
|
||||||
|
#include <inttypes.h>
|
||||||
/* USER CODE END Includes */
|
/* USER CODE END Includes */
|
||||||
|
|
||||||
/* Private typedef -----------------------------------------------------------*/
|
/* Private typedef -----------------------------------------------------------*/
|
||||||
@@ -89,20 +91,174 @@ void NMI_Handler(void)
|
|||||||
/* USER CODE END NonMaskableInt_IRQn 1 */
|
/* USER CODE END NonMaskableInt_IRQn 1 */
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief This function handles Hard fault interrupt.
|
|
||||||
*/
|
|
||||||
void HardFault_Handler(void)
|
|
||||||
{
|
|
||||||
/* USER CODE BEGIN HardFault_IRQn 0 */
|
|
||||||
PUTS("HardFault_Handler\r\n");
|
|
||||||
app_emergency_stop();
|
|
||||||
|
|
||||||
/* USER CODE END HardFault_IRQn 0 */
|
#define VERBOSE_HARDFAULT 1
|
||||||
while (1) {
|
|
||||||
/* USER CODE BEGIN W1_HardFault_IRQn 0 */
|
|
||||||
/* USER CODE END W1_HardFault_IRQn 0 */
|
#if VERBOSE_HARDFAULT
|
||||||
}
|
void __attribute__((used)) HardFault_DumpRegisters(const uint32_t *origStack, uint32_t lr_value)
|
||||||
|
{
|
||||||
|
/* These are volatile to try and prevent the compiler/linker optimising them
|
||||||
|
away as the variables never actually get used. If the debugger won't show the
|
||||||
|
values of the variables, make them global my moving their declaration outside
|
||||||
|
of this function. */
|
||||||
|
volatile uint32_t stacked_r0;
|
||||||
|
volatile uint32_t stacked_r1;
|
||||||
|
volatile uint32_t stacked_r2;
|
||||||
|
volatile uint32_t stacked_r3;
|
||||||
|
volatile uint32_t stacked_r12;
|
||||||
|
volatile uint32_t stacked_lr; /* Link register. */
|
||||||
|
volatile uint32_t stacked_pc; /* Program counter. */
|
||||||
|
volatile uint32_t stacked_psr;/* Program status register. */
|
||||||
|
|
||||||
|
#if (__CORTEX_M >= 3)
|
||||||
|
uint32_t cfsr, hfsr, dfsr;
|
||||||
|
|
||||||
|
uint32_t bus_fault_address;
|
||||||
|
uint32_t memmanage_fault_address;
|
||||||
|
|
||||||
|
bus_fault_address = SCB->BFAR;
|
||||||
|
memmanage_fault_address = SCB->MMFAR;
|
||||||
|
cfsr = SCB->CFSR;
|
||||||
|
hfsr = SCB->HFSR;
|
||||||
|
dfsr = SCB->DFSR;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
stacked_r0 = origStack[0];
|
||||||
|
stacked_r1 = origStack[1];
|
||||||
|
stacked_r2 = origStack[2];
|
||||||
|
stacked_r3 = origStack[3];
|
||||||
|
stacked_r12 = origStack[4];
|
||||||
|
stacked_lr = origStack[5];
|
||||||
|
stacked_pc = origStack[6];
|
||||||
|
stacked_psr = origStack[7];
|
||||||
|
|
||||||
|
app_heater_emergency_shutdown();
|
||||||
|
|
||||||
|
#define BS(reg, pos, str) (((reg)&(1<<(pos)))?(str" "):"")
|
||||||
|
#define REDPTR(val) (((val)&0xFF000000) != 0x08000000?"\033[31m":"\033[32m")
|
||||||
|
|
||||||
|
PRINTF("\r\n*** HARD FAULT ***\r\n\r\n");
|
||||||
|
PRINTF("- Stack frame:\r\n");
|
||||||
|
PRINTF(" R0 = \033[35m0x%"PRIX32"\033[m\r\n", stacked_r0);
|
||||||
|
PRINTF(" R1 = \033[35m0x%"PRIX32"\033[m\r\n", stacked_r1);
|
||||||
|
PRINTF(" R2 = \033[35m0x%"PRIX32"\033[m\r\n", stacked_r2);
|
||||||
|
PRINTF(" R3 = \033[35m0x%"PRIX32"\033[m\r\n", stacked_r3);
|
||||||
|
PRINTF(" R12 = \033[35m0x%"PRIX32"\033[m\r\n", stacked_r12);
|
||||||
|
PRINTF(" LR = %s0x%08"PRIX32"\033[m\r\n", REDPTR(stacked_lr), stacked_lr);
|
||||||
|
PRINTF(" PC = %s0x%08"PRIX32"\033[m\r\n", REDPTR(stacked_pc), stacked_pc);
|
||||||
|
PRINTF(" PSR = \033[36m0x%08"PRIX32"\033[m", stacked_psr);
|
||||||
|
uint32_t exc = stacked_psr & 0x3F;
|
||||||
|
PRINTF(" [ %s%s%s%s%s ]\r\n",
|
||||||
|
BS(stacked_psr, 31, "N"),
|
||||||
|
BS(stacked_psr, 30, "Z"),
|
||||||
|
BS(stacked_psr, 29, "C"),
|
||||||
|
BS(stacked_psr, 28, "V"),
|
||||||
|
//BS(stacked_psr, 24, "T"), - thumb, always ON
|
||||||
|
|
||||||
|
(exc==0)?"Thread":
|
||||||
|
(exc==2)?"NMI":
|
||||||
|
(exc==3)?"HardFault":
|
||||||
|
(exc==11)?"SVCall":
|
||||||
|
(exc==14)?"PendSV":
|
||||||
|
(exc==15)?"SysTick":
|
||||||
|
(exc>=16)?"IRQ":"Unknown"
|
||||||
|
);
|
||||||
|
|
||||||
|
#if (__CORTEX_M >= 3)
|
||||||
|
PRINTF("\r\n- FSR/FAR:\r\n");
|
||||||
|
PRINTF(" CFSR = \033[36m0x%08"PRIX32"\033[m\r\n", cfsr);
|
||||||
|
PRINTF(" UsageFault: \033[31;1m%s%s%s%s%s%s%s\033[m\r\n"
|
||||||
|
" BusFault: \033[31;1m%s%s%s%s%s%s%s%s\033[m\r\n"
|
||||||
|
" MemFault: \033[31;1m%s%s%s%s%s%s%s\033[m\r\n",
|
||||||
|
BS(cfsr, 0, "IAccViol"),
|
||||||
|
BS(cfsr, 1, "DAccViol"),
|
||||||
|
BS(cfsr, 3, "MUnstkErr"),
|
||||||
|
BS(cfsr, 4, "MStkErr"),
|
||||||
|
BS(cfsr, 5, "MLSPErr(FPU)"),
|
||||||
|
BS(cfsr, 7, "MMArValid"),
|
||||||
|
((cfsr&0xFF)?"":"\033[m- "),
|
||||||
|
|
||||||
|
BS(cfsr, 8, "IBusErr"),
|
||||||
|
BS(cfsr, 9, "PreciseErr"),
|
||||||
|
BS(cfsr, 10, "ImpreciseErr"),
|
||||||
|
BS(cfsr, 11, "UnstkErr"),
|
||||||
|
BS(cfsr, 12, "StkErr"),
|
||||||
|
BS(cfsr, 13, "LSPErr"),
|
||||||
|
BS(cfsr, 15, "BFArValid"),
|
||||||
|
((cfsr&0xFF00)?"":"\033[m- "),
|
||||||
|
|
||||||
|
BS(cfsr, 16, "UndefInstr"),
|
||||||
|
BS(cfsr, 17, "InvState"),
|
||||||
|
BS(cfsr, 18, "InvPC"),
|
||||||
|
BS(cfsr, 19, "NoCP"),
|
||||||
|
BS(cfsr, 24, "Unaligned"),
|
||||||
|
BS(cfsr, 25, "Div0"),
|
||||||
|
((cfsr&0xFFFF0000)?"":"\033[m- ")
|
||||||
|
);
|
||||||
|
|
||||||
|
PRINTF(" HFSR = \033[36m0x%08"PRIX32"\033[m", hfsr);
|
||||||
|
PRINTF(" [ %s%s%s]\r\n",
|
||||||
|
BS(hfsr, 31, "DebugEvt"),
|
||||||
|
BS(hfsr, 30, "Forced"),
|
||||||
|
BS(hfsr, 1, "VectTbl")
|
||||||
|
);
|
||||||
|
|
||||||
|
PRINTF(" DFSR = \033[36m0x%08"PRIX32"\033[m", dfsr);
|
||||||
|
PRINTF(" [ %s%s%s%s%s]\r\n",
|
||||||
|
BS(dfsr, 0, "Halted"),
|
||||||
|
BS(dfsr, 1, "Bkpt"),
|
||||||
|
BS(dfsr, 2, "DWtTrap"),
|
||||||
|
BS(dfsr, 3, "VCatch"),
|
||||||
|
BS(dfsr, 4, "External")
|
||||||
|
);
|
||||||
|
|
||||||
|
if (cfsr & 0x0080) PRINTF(" MMFAR = \033[33m0x%08"PRIX32"\033[m\r\n", memmanage_fault_address);
|
||||||
|
if (cfsr & 0x8000) PRINTF(" BFAR = \033[33m0x%08"PRIX32"\033[m\r\n", bus_fault_address);
|
||||||
|
PRINTF("\r\n- Misc\r\n");
|
||||||
|
PRINTF(" LR/EXC_RETURN= %s0x%08"PRIX32"\033[m\n", REDPTR(lr_value), lr_value);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
while (1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This function handles Hard fault interrupt.
|
||||||
|
*/
|
||||||
|
void __attribute__((naked)) HardFault_Handler(void)
|
||||||
|
{
|
||||||
|
#if VERBOSE_HARDFAULT
|
||||||
|
// __asm volatile
|
||||||
|
// (
|
||||||
|
// " tst lr, #4 \n"
|
||||||
|
// " ite eq \n"
|
||||||
|
// " mrseq r0, msp \n"
|
||||||
|
// " mrsne r0, psp \n"
|
||||||
|
// " ldr r1, [r0, #24] \n"
|
||||||
|
// " mov r2, lr \n"
|
||||||
|
// " ldr r3, handler2_address_const \n"
|
||||||
|
// " bx r3 \n"
|
||||||
|
// " handler2_address_const: .word HardFault_DumpRegisters \n"
|
||||||
|
// );
|
||||||
|
//
|
||||||
|
__asm volatile( ".syntax unified\n"
|
||||||
|
"MOVS R0, #4 \n"
|
||||||
|
"MOV R1, LR \n"
|
||||||
|
"TST R0, R1 \n"
|
||||||
|
"BEQ _MSP \n"
|
||||||
|
"MRS R0, PSP \n"
|
||||||
|
"B HardFault_DumpRegisters \n"
|
||||||
|
"_MSP: \n"
|
||||||
|
"MRS R0, MSP \n"
|
||||||
|
"B HardFault_DumpRegisters \n"
|
||||||
|
".syntax divided\n") ;
|
||||||
|
|
||||||
|
#else
|
||||||
|
app_emergency_stop();
|
||||||
|
PRINTF("*** HARD FAULT ***\r\n\r\n");
|
||||||
|
while (1);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+21
-1
@@ -29,6 +29,10 @@
|
|||||||
#define my_malloc(len) pvPortMalloc((len))
|
#define my_malloc(len) pvPortMalloc((len))
|
||||||
#define my_free(p) vPortFree((p))
|
#define my_free(p) vPortFree((p))
|
||||||
|
|
||||||
|
// Use a static buffer to avoid allocating for every printf!
|
||||||
|
#define S_PRINTF_BUF_LEN 200
|
||||||
|
static char s_printf_buf[S_PRINTF_BUF_LEN];
|
||||||
|
|
||||||
// Toggle features
|
// Toggle features
|
||||||
#define size_t size_t /* normally: int, unsigned */
|
#define size_t size_t /* normally: int, unsigned */
|
||||||
#undef HAVE_LONG_DOUBLE
|
#undef HAVE_LONG_DOUBLE
|
||||||
@@ -733,10 +737,12 @@ static void fmtfp(char *buffer, size_t *currlen, size_t maxlen,
|
|||||||
// leading zeros in the fractional part
|
// leading zeros in the fractional part
|
||||||
fzeropad = 0;
|
fzeropad = 0;
|
||||||
fzerocnt = max - 1;
|
fzerocnt = max - 1;
|
||||||
|
if (fzerocnt > 0) {
|
||||||
while (fracpart < POW10(fzerocnt)) {
|
while (fracpart < POW10(fzerocnt)) {
|
||||||
fzeropad++;
|
fzeropad++;
|
||||||
fzerocnt--;
|
fzerocnt--;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
do {
|
do {
|
||||||
temp = fracpart;
|
temp = fracpart;
|
||||||
my_modf(fracpart * 0.1, &fracpart);
|
my_modf(fracpart * 0.1, &fracpart);
|
||||||
@@ -800,8 +806,9 @@ static void fmtfp(char *buffer, size_t *currlen, size_t maxlen,
|
|||||||
zpadlen = 0;
|
zpadlen = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (fzeropad-- > 0) {
|
while (fzeropad > 0) {
|
||||||
dopr_outch(buffer, currlen, maxlen, '0');
|
dopr_outch(buffer, currlen, maxlen, '0');
|
||||||
|
fzeropad--;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (fplace > 0) {
|
while (fplace > 0) {
|
||||||
@@ -892,6 +899,18 @@ int printf(const char *format, ...)
|
|||||||
va_list ap;
|
va_list ap;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
va_start(ap, format);
|
||||||
|
ret = vsnprintf(s_printf_buf, S_PRINTF_BUF_LEN, format, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
PUTS(s_printf_buf);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
va_list ap;
|
||||||
|
int ret;
|
||||||
|
|
||||||
char *ptr = NULL;
|
char *ptr = NULL;
|
||||||
|
|
||||||
va_start(ap, format);
|
va_start(ap, format);
|
||||||
@@ -906,6 +925,7 @@ int printf(const char *format, ...)
|
|||||||
my_free(ptr);
|
my_free(ptr);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int vprintf(const char *format, va_list ap)
|
int vprintf(const char *format, va_list ap)
|
||||||
|
|||||||
Reference in New Issue
Block a user