stm32 cdc
František Burian
BuFran na seznam.cz
Úterý Prosinec 10 17:29:31 CET 2019
Na ladění HardFault mám pomůcku, nejčastěji se hardfault volá kvůli bad ARM
state (přístup na
nezarovnanou pozici. U USB je spousta registrů s pouze 16bitovým přístupem,
kde 8/32bitový
přístup generuje tento HardFault. Kdysi jsem ještě míval s pomocí externích
knihoven stack
overflowy ale ten už se to nestává, knihovny si píšu sám):
void HardFault_HandlerC(unsigned long *hardfault_args);
void hard_fault_handler(void)
{
// ".syntax unified\n"
__asm(
"MOVS R0, #4 \n"
"MOV R1, LR \n"
"TST R0, R1 \n"
"BEQ _MSP \n"
"MRS R0, PSP \n"
"B HardFault_HandlerC \n"
"_MSP: \n"
"MRS R0, MSP \n"
"B HardFault_HandlerC \n"
);
// ".syntax divided\n"
}
void HardFault_HandlerC(unsigned long *hardfault_args)
{
if (((uint32_t)hardfault_args & 0xF0000000) != 0x20000000)
{
printf("HardFault - Invalid xSP \r\n");
__asm("BKPT #0\n");
// * Check if you have allocated enough stack space.
// * Add a few function calls in various places in your program to
check for stack leaks. CMSIS-Core provides some functions to help accessing
SP value
// (e.g. __get_MSP()), and you can use those functions to add stack
checking code (e.g. the value of MSP should be the same everything when a
function is called).
// RTOS?
// No - You can use the banked stack pointer feature to separate the
stack used by threads and handlers. In this way you can also add stack
checking in
// the ISR with lowest priority level. Higher priority level
ISRs cannot use this trick because the SP value can be different if there
was a lower
// priority ISR running.
// Yes - some of them (including Keil RTX) has optional stack
checking feature.
}
volatile unsigned long stacked_r0 = ((unsigned long)hardfault_args[0]);
volatile unsigned long stacked_r1 = ((unsigned long)hardfault_args[1]);
volatile unsigned long stacked_r2 = ((unsigned long)hardfault_args[2]);
volatile unsigned long stacked_r3 = ((unsigned long)hardfault_args[3]);
volatile unsigned long stacked_r12 = ((unsigned long)hardfault_args[4]);
volatile unsigned long stacked_lr = ((unsigned long)hardfault_args[5]);
volatile unsigned long stacked_pc = ((unsigned long)hardfault_args[6]);
volatile unsigned long stacked_psr = ((unsigned long)hardfault_args[7]);
volatile unsigned long _CFSR = (*((volatile unsigned long *)(0xE000ED
28)));
volatile unsigned long _HFSR = (*((volatile unsigned long *)(0xE000ED2
C)));
volatile unsigned long _DFSR = (*((volatile unsigned long *)(0xE000ED
30)));
volatile unsigned long _AFSR = (*((volatile unsigned long *)(0xE000ED3
C))) ;
volatile unsigned long _BFAR = (*((volatile unsigned long *)(0xE000ED
34)));
volatile unsigned long _MMAR = (*((volatile unsigned long *)(0xE000ED
38)));
volatile unsigned long T = stacked_psr & (1 << 24) ? 1 : 0;
volatile unsigned long IPSR = stacked_psr & 0x3F;
printf("HardFault\r\n");
printf("xSP: %.8x (valid)\r\n", (uint32_t)hardfault_args );
printf("PSR: %.8x IPSR=%.2x T=%.1x\r\n", stacked_psr, IPSR, T);
printf(" PC: %.8x\r\n", stacked_pc);
printf(" LR: %.8x\r\n", stacked_lr);
if (!T) {
printf(" ARM state not allowed!\r\n", stacked_lr);
// * T=0 something is trying to switch the processor into Arm state.
// * T=0 and the stacked PC is pointing to the beginning of an ISR,
check the vector table (all LSB of exception vectors should be set to 1).
}
if (IPSR) {
printf(" ISR %d \r\n",IPSR);
// * IPSR is indicating an ISR is running, and the stacked PC is not
inside the address range of the ISR code, then you likely to have a stack
corruption
// in that ISR. Look out for data array accesses with unbounded index.
}
// * If the stacked PC is pointing to a memory access instruction,
usually you can debug the load/store issue based on the register contents
(see below):
// * Invalid address - check the address value
// * Data alignment issue (the processor has attempted to carried an
unaligned data accesses)
// * For Cortex-M0+ processor, please check for memory access permission
(e.g. unprivileged access to the NVIC register), or MPU permission
violations.
// * Bus components or peripheral returned an error response for other
reason.
__asm("BKPT #0\n") ; // Break into the debugger
}
---------- Původní e-mail ----------
Od: ToMaS <tomas.hum na worldonline.cz>
Komu: HW-news <hw-list na list.hw.cz>
Datum: 10. 12. 2019 16:59:52
Předmět: stm32 cdc
"Resim problem s STM32 VCP, at delam co delam tak to nic nedela.
Postupuji podle tohoto:
http://shawnhymel.com/1795/getting-started-with-stm32-nucleo-usb-virtual-com
-port/
Ale behem MX_USB_DEVICE_Init(); mi to skoci do void
HardFault_Handler(void) a koncim.
Jsem zacatecnik, je nejaka rada proc se tak deje? Respektive jak zjistit
proc se tak deje.
Diky za nasmerovani
ToMaS
P.S. Mam STM32L412, ale to asi neni problem.
_______________________________________________
HW-list mailing list - sponsored by www.HW.cz
Hw-list na list.hw.cz
http://list.hw.cz/mailman/listinfo/hw-list
"
------------- další část ---------------
HTML příloha byla odstraněna...
URL: <http://list.hw.cz/pipermail/hw-list/attachments/20191210/000c94c6/attachment.html>
Další informace o konferenci Hw-list