Bus fault when accessing mcu internal peripheral
$begingroup$
I am struggling with a bus fault error on my samg55 µC based on arm cortex m4 architecture. The issue occurs sporadically and is not 100% reproductible. Let me give some details.
Application code writes periodically some datas into reserved internal flash memory. To do this I use the EFC (embedded flash controller) of the µC which is mapped at address 0x400E0A00 in system controller.
This writing leads in certain conditions to a hard fault. I dumped registers and got the following:
R4_20001368 R5_00000001 R6_00000338 R7_00000020
R8_00000020 R9_2001bcc8 R10_200128cc R11_0043d3a9
R0_402e0a00 R1_5a03380b R2_5a033800 R3_20000067
R12_200129cc LR_0043320b PC_2000006a PSR_010f0000
SHCSR: 0x00000000
CFSR: 0x00008600
HFSR: 0x40000000
DFSR: 0x00000000
MMFAR: 0x402e0a08
BFAR: 0x402e0a08
AFSR: 0x00000000
CFSR indicates a bus fault with BFARVALID flag set. Looking at BFAR register I can see the value 0x402e0a08 which base address 0x402e0a00 is just one bit different from the EFC address 0x400E0A00.
I digged into the code but could not find the bug. Here is suspected code:
Assembler code
004331d4 <efc_perform_command>:
4331d4: f1a1 030e sub.w r3, r1, #14
4331d8: 2b01 cmp r3, #1
4331da: b537 push {r0, r1, r2, r4, r5, lr}
4331dc: d91d bls.n 43321a <efc_perform_command+0x46>
4331de: f3ef 8310 mrs r3, PRIMASK
4331e2: fab3 f383 clz r3, r3
4331e6: 095b lsrs r3, r3, #5
4331e8: 9301 str r3, [sp, #4]
4331ea: b672 cpsid i
4331ec: f3bf 8f5f dmb sy
4331f0: 4c0b ldr r4, [pc, #44] ; (433220 <efc_perform_command+0x4c>)
4331f2: 2300 movs r3, #0
4331f4: 7023 strb r3, [r4, #0]
4331f6: 4b0b ldr r3, [pc, #44] ; (433224 <efc_perform_command+0x50>)
4331f8: 9d01 ldr r5, [sp, #4]
4331fa: ea03 2202 and.w r2, r3, r2, lsl #8
4331fe: f042 42b4 orr.w r2, r2, #1509949440 ; 0x5a000000
433202: b2c9 uxtb r1, r1
433204: 4311 orrs r1, r2
433206: 4b08 ldr r3, [pc, #32] ; (433228 <efc_perform_command+0x54>)
433208: 4798 blx r3
43320a: b125 cbz r5, 433216 <efc_perform_command+0x42>
43320c: 2301 movs r3, #1
43320e: 7023 strb r3, [r4, #0]
433210: f3bf 8f5f dmb sy
433214: b662 cpsie i
433216: b003 add sp, #12
433218: bd30 pop {r4, r5, pc}
43321a: f04f 30ff mov.w r0, #4294967295 ; 0xffffffff
43321e: e7fa b.n 433216 <efc_perform_command+0x42>
433220: 20001368 .word 0x20001368
433224: 00ffff00 .word 0x00ffff00
433228: 20000067 .word 0x20000067
20000066 <efc_perform_fcr>:
20000066: b082 sub sp, #8
20000068: 6041 str r1, [r0, #4]
2000006a: 6883 ldr r3, [r0, #8]
2000006c: 9301 str r3, [sp, #4]
2000006e: 9b01 ldr r3, [sp, #4]
20000070: 07db lsls r3, r3, #31
20000072: d5fa bpl.n 2000006a <efc_perform_fcr+0x4>
20000074: 9801 ldr r0, [sp, #4]
20000076: f000 000e and.w r0, r0, #14
2000007a: b002 add sp, #8
2000007c: 4770 bx lr
C code
/**
* brief Perform the given command and wait until its completion (or an error).
*
* note Unique ID commands are not supported, use efc_perform_read_sequence.
*
* param p_efc Pointer to an EFC instance.
* param ul_command Command to perform.
* param ul_argument Optional command argument.
*
* note This function will automatically choose to use IAP function.
*
* return 0 if successful, otherwise returns an error code.
*/
uint32_t efc_perform_command(Efc *p_efc, uint32_t ul_command,
uint32_t ul_argument)
{
uint32_t result;
irqflags_t flags;
/* Unique ID commands are not supported. */
if (ul_command == EFC_FCMD_STUI || ul_command == EFC_FCMD_SPUI) {
return EFC_RC_NOT_SUPPORT;
}
flags = cpu_irq_save();
/* Use RAM Function. */
result = efc_perform_fcr(p_efc,
EEFC_FCR_FKEY_PASSWD | EEFC_FCR_FARG(ul_argument) |
EEFC_FCR_FCMD(ul_command));
cpu_irq_restore(flags);
return result;
}
/**
* brief Perform command.
*
* param p_efc Pointer to an EFC instance.
* param ul_fcr Flash command.
*
* return The current status.
*/
__no_inline
RAMFUNC
uint32_t efc_perform_fcr(Efc *p_efc, uint32_t ul_fcr)
{
volatile uint32_t ul_status;
p_efc->EEFC_FCR = ul_fcr;
do {
ul_status = p_efc->EEFC_FSR;
} while ((ul_status & EEFC_FSR_FRDY) != EEFC_FSR_FRDY);
return (ul_status & EEFC_ERROR_FLAGS);
}
Code is compiled with arm-none-eabi-gcc (gcc-arm-none-eabi-7-2017-q4-major) with -Os optimization.
Note: issue seems to occurs more frequently in low temperature (0°C), so I don't exclude hardware related problem, even though operating range of µC is -40 to 85 °C...
Any idea what could go wrong ?
Thanks for your help !
PS: I am not ready to blame cosmic ray... ;-)
EDIT:
Adding some details after more investigation
First, system is clearly more stable with dynamic wait state setting according to core frequency. This is true for temperature nearby 0°C and a little less.
But it becomes totally unstable at -15°C.
I am suspecting that the internal oscillator that we are using has a significant drift due to low temperature (and/or voltage instability). This oscillator (16MHz) is used as source for core and also for peripherals like timer and usart.
I have two other possibilities for source oscillator:
- External fast oscillator at 12 MHz
- External slow oscillator at 32.768 KHz
Oscillator at 12 MHz is not very suitable to generate good clock for uart with a 115200 baudrate.
Slow oscillator can be used to generale a pll clock with frequency between 24 and 48 MHz, that can be used as source for peripherals. I tried this solution and have good results so far at very low temp, but I am not sure it is recommended, specifically for uart.
So my question is, is using a pll as source for uart a bad practice ?
The hardware solution would be to replace external fast oscillator, selecting suitable frequency for uart, but it is not possible for now.
c embedded flash cortex-m4 gcc
$endgroup$
migrated from superuser.com Jan 23 at 11:11
This question came from our site for computer enthusiasts and power users.
|
show 10 more comments
$begingroup$
I am struggling with a bus fault error on my samg55 µC based on arm cortex m4 architecture. The issue occurs sporadically and is not 100% reproductible. Let me give some details.
Application code writes periodically some datas into reserved internal flash memory. To do this I use the EFC (embedded flash controller) of the µC which is mapped at address 0x400E0A00 in system controller.
This writing leads in certain conditions to a hard fault. I dumped registers and got the following:
R4_20001368 R5_00000001 R6_00000338 R7_00000020
R8_00000020 R9_2001bcc8 R10_200128cc R11_0043d3a9
R0_402e0a00 R1_5a03380b R2_5a033800 R3_20000067
R12_200129cc LR_0043320b PC_2000006a PSR_010f0000
SHCSR: 0x00000000
CFSR: 0x00008600
HFSR: 0x40000000
DFSR: 0x00000000
MMFAR: 0x402e0a08
BFAR: 0x402e0a08
AFSR: 0x00000000
CFSR indicates a bus fault with BFARVALID flag set. Looking at BFAR register I can see the value 0x402e0a08 which base address 0x402e0a00 is just one bit different from the EFC address 0x400E0A00.
I digged into the code but could not find the bug. Here is suspected code:
Assembler code
004331d4 <efc_perform_command>:
4331d4: f1a1 030e sub.w r3, r1, #14
4331d8: 2b01 cmp r3, #1
4331da: b537 push {r0, r1, r2, r4, r5, lr}
4331dc: d91d bls.n 43321a <efc_perform_command+0x46>
4331de: f3ef 8310 mrs r3, PRIMASK
4331e2: fab3 f383 clz r3, r3
4331e6: 095b lsrs r3, r3, #5
4331e8: 9301 str r3, [sp, #4]
4331ea: b672 cpsid i
4331ec: f3bf 8f5f dmb sy
4331f0: 4c0b ldr r4, [pc, #44] ; (433220 <efc_perform_command+0x4c>)
4331f2: 2300 movs r3, #0
4331f4: 7023 strb r3, [r4, #0]
4331f6: 4b0b ldr r3, [pc, #44] ; (433224 <efc_perform_command+0x50>)
4331f8: 9d01 ldr r5, [sp, #4]
4331fa: ea03 2202 and.w r2, r3, r2, lsl #8
4331fe: f042 42b4 orr.w r2, r2, #1509949440 ; 0x5a000000
433202: b2c9 uxtb r1, r1
433204: 4311 orrs r1, r2
433206: 4b08 ldr r3, [pc, #32] ; (433228 <efc_perform_command+0x54>)
433208: 4798 blx r3
43320a: b125 cbz r5, 433216 <efc_perform_command+0x42>
43320c: 2301 movs r3, #1
43320e: 7023 strb r3, [r4, #0]
433210: f3bf 8f5f dmb sy
433214: b662 cpsie i
433216: b003 add sp, #12
433218: bd30 pop {r4, r5, pc}
43321a: f04f 30ff mov.w r0, #4294967295 ; 0xffffffff
43321e: e7fa b.n 433216 <efc_perform_command+0x42>
433220: 20001368 .word 0x20001368
433224: 00ffff00 .word 0x00ffff00
433228: 20000067 .word 0x20000067
20000066 <efc_perform_fcr>:
20000066: b082 sub sp, #8
20000068: 6041 str r1, [r0, #4]
2000006a: 6883 ldr r3, [r0, #8]
2000006c: 9301 str r3, [sp, #4]
2000006e: 9b01 ldr r3, [sp, #4]
20000070: 07db lsls r3, r3, #31
20000072: d5fa bpl.n 2000006a <efc_perform_fcr+0x4>
20000074: 9801 ldr r0, [sp, #4]
20000076: f000 000e and.w r0, r0, #14
2000007a: b002 add sp, #8
2000007c: 4770 bx lr
C code
/**
* brief Perform the given command and wait until its completion (or an error).
*
* note Unique ID commands are not supported, use efc_perform_read_sequence.
*
* param p_efc Pointer to an EFC instance.
* param ul_command Command to perform.
* param ul_argument Optional command argument.
*
* note This function will automatically choose to use IAP function.
*
* return 0 if successful, otherwise returns an error code.
*/
uint32_t efc_perform_command(Efc *p_efc, uint32_t ul_command,
uint32_t ul_argument)
{
uint32_t result;
irqflags_t flags;
/* Unique ID commands are not supported. */
if (ul_command == EFC_FCMD_STUI || ul_command == EFC_FCMD_SPUI) {
return EFC_RC_NOT_SUPPORT;
}
flags = cpu_irq_save();
/* Use RAM Function. */
result = efc_perform_fcr(p_efc,
EEFC_FCR_FKEY_PASSWD | EEFC_FCR_FARG(ul_argument) |
EEFC_FCR_FCMD(ul_command));
cpu_irq_restore(flags);
return result;
}
/**
* brief Perform command.
*
* param p_efc Pointer to an EFC instance.
* param ul_fcr Flash command.
*
* return The current status.
*/
__no_inline
RAMFUNC
uint32_t efc_perform_fcr(Efc *p_efc, uint32_t ul_fcr)
{
volatile uint32_t ul_status;
p_efc->EEFC_FCR = ul_fcr;
do {
ul_status = p_efc->EEFC_FSR;
} while ((ul_status & EEFC_FSR_FRDY) != EEFC_FSR_FRDY);
return (ul_status & EEFC_ERROR_FLAGS);
}
Code is compiled with arm-none-eabi-gcc (gcc-arm-none-eabi-7-2017-q4-major) with -Os optimization.
Note: issue seems to occurs more frequently in low temperature (0°C), so I don't exclude hardware related problem, even though operating range of µC is -40 to 85 °C...
Any idea what could go wrong ?
Thanks for your help !
PS: I am not ready to blame cosmic ray... ;-)
EDIT:
Adding some details after more investigation
First, system is clearly more stable with dynamic wait state setting according to core frequency. This is true for temperature nearby 0°C and a little less.
But it becomes totally unstable at -15°C.
I am suspecting that the internal oscillator that we are using has a significant drift due to low temperature (and/or voltage instability). This oscillator (16MHz) is used as source for core and also for peripherals like timer and usart.
I have two other possibilities for source oscillator:
- External fast oscillator at 12 MHz
- External slow oscillator at 32.768 KHz
Oscillator at 12 MHz is not very suitable to generate good clock for uart with a 115200 baudrate.
Slow oscillator can be used to generale a pll clock with frequency between 24 and 48 MHz, that can be used as source for peripherals. I tried this solution and have good results so far at very low temp, but I am not sure it is recommended, specifically for uart.
So my question is, is using a pll as source for uart a bad practice ?
The hardware solution would be to replace external fast oscillator, selecting suitable frequency for uart, but it is not possible for now.
c embedded flash cortex-m4 gcc
$endgroup$
migrated from superuser.com Jan 23 at 11:11
This question came from our site for computer enthusiasts and power users.
$begingroup$
Thanks Andrew for advice. I will try to move it to EE site.
$endgroup$
– Kev1
Jan 23 at 11:03
1
$begingroup$
These kind of bootloader firmware residing on-chip typically wants you to reserve RAM for them. Is this the case and if so, have you done it? And there's also likely some app note regarding this which is a must-read. Btw your debugging seems quite archaic, why are you working with register dumps? Just set a breakpoint at the exception handler then view the instruction trace, to find out exactly which C line that is the culprit, together with the state of all registers. You might need a tool chain free of Eclipse and other diseases though.
$endgroup$
– Lundin
Jan 23 at 11:36
1
$begingroup$
I've seen issues like this before which resulted from incorrectly configuring the micro's internal Flash timing registers, resulting in the Flash being 'overclocked' and occasionally returning invalid code.
$endgroup$
– brhans
Jan 23 at 12:12
1
$begingroup$
@Lundin - "free of Eclipse and other diseases" ;)
$endgroup$
– brhans
Jan 23 at 12:13
1
$begingroup$
Yeah - that's exactly the issue I'm referring to. If your Flash wait states are not set correctly it could appear to sort-kinda-work most of the time, but occasionally you'll find your flash toggles a bit somewhere as the core reads instructions or data and that'll manifest in some really weird symptoms.
$endgroup$
– brhans
Jan 23 at 15:29
|
show 10 more comments
$begingroup$
I am struggling with a bus fault error on my samg55 µC based on arm cortex m4 architecture. The issue occurs sporadically and is not 100% reproductible. Let me give some details.
Application code writes periodically some datas into reserved internal flash memory. To do this I use the EFC (embedded flash controller) of the µC which is mapped at address 0x400E0A00 in system controller.
This writing leads in certain conditions to a hard fault. I dumped registers and got the following:
R4_20001368 R5_00000001 R6_00000338 R7_00000020
R8_00000020 R9_2001bcc8 R10_200128cc R11_0043d3a9
R0_402e0a00 R1_5a03380b R2_5a033800 R3_20000067
R12_200129cc LR_0043320b PC_2000006a PSR_010f0000
SHCSR: 0x00000000
CFSR: 0x00008600
HFSR: 0x40000000
DFSR: 0x00000000
MMFAR: 0x402e0a08
BFAR: 0x402e0a08
AFSR: 0x00000000
CFSR indicates a bus fault with BFARVALID flag set. Looking at BFAR register I can see the value 0x402e0a08 which base address 0x402e0a00 is just one bit different from the EFC address 0x400E0A00.
I digged into the code but could not find the bug. Here is suspected code:
Assembler code
004331d4 <efc_perform_command>:
4331d4: f1a1 030e sub.w r3, r1, #14
4331d8: 2b01 cmp r3, #1
4331da: b537 push {r0, r1, r2, r4, r5, lr}
4331dc: d91d bls.n 43321a <efc_perform_command+0x46>
4331de: f3ef 8310 mrs r3, PRIMASK
4331e2: fab3 f383 clz r3, r3
4331e6: 095b lsrs r3, r3, #5
4331e8: 9301 str r3, [sp, #4]
4331ea: b672 cpsid i
4331ec: f3bf 8f5f dmb sy
4331f0: 4c0b ldr r4, [pc, #44] ; (433220 <efc_perform_command+0x4c>)
4331f2: 2300 movs r3, #0
4331f4: 7023 strb r3, [r4, #0]
4331f6: 4b0b ldr r3, [pc, #44] ; (433224 <efc_perform_command+0x50>)
4331f8: 9d01 ldr r5, [sp, #4]
4331fa: ea03 2202 and.w r2, r3, r2, lsl #8
4331fe: f042 42b4 orr.w r2, r2, #1509949440 ; 0x5a000000
433202: b2c9 uxtb r1, r1
433204: 4311 orrs r1, r2
433206: 4b08 ldr r3, [pc, #32] ; (433228 <efc_perform_command+0x54>)
433208: 4798 blx r3
43320a: b125 cbz r5, 433216 <efc_perform_command+0x42>
43320c: 2301 movs r3, #1
43320e: 7023 strb r3, [r4, #0]
433210: f3bf 8f5f dmb sy
433214: b662 cpsie i
433216: b003 add sp, #12
433218: bd30 pop {r4, r5, pc}
43321a: f04f 30ff mov.w r0, #4294967295 ; 0xffffffff
43321e: e7fa b.n 433216 <efc_perform_command+0x42>
433220: 20001368 .word 0x20001368
433224: 00ffff00 .word 0x00ffff00
433228: 20000067 .word 0x20000067
20000066 <efc_perform_fcr>:
20000066: b082 sub sp, #8
20000068: 6041 str r1, [r0, #4]
2000006a: 6883 ldr r3, [r0, #8]
2000006c: 9301 str r3, [sp, #4]
2000006e: 9b01 ldr r3, [sp, #4]
20000070: 07db lsls r3, r3, #31
20000072: d5fa bpl.n 2000006a <efc_perform_fcr+0x4>
20000074: 9801 ldr r0, [sp, #4]
20000076: f000 000e and.w r0, r0, #14
2000007a: b002 add sp, #8
2000007c: 4770 bx lr
C code
/**
* brief Perform the given command and wait until its completion (or an error).
*
* note Unique ID commands are not supported, use efc_perform_read_sequence.
*
* param p_efc Pointer to an EFC instance.
* param ul_command Command to perform.
* param ul_argument Optional command argument.
*
* note This function will automatically choose to use IAP function.
*
* return 0 if successful, otherwise returns an error code.
*/
uint32_t efc_perform_command(Efc *p_efc, uint32_t ul_command,
uint32_t ul_argument)
{
uint32_t result;
irqflags_t flags;
/* Unique ID commands are not supported. */
if (ul_command == EFC_FCMD_STUI || ul_command == EFC_FCMD_SPUI) {
return EFC_RC_NOT_SUPPORT;
}
flags = cpu_irq_save();
/* Use RAM Function. */
result = efc_perform_fcr(p_efc,
EEFC_FCR_FKEY_PASSWD | EEFC_FCR_FARG(ul_argument) |
EEFC_FCR_FCMD(ul_command));
cpu_irq_restore(flags);
return result;
}
/**
* brief Perform command.
*
* param p_efc Pointer to an EFC instance.
* param ul_fcr Flash command.
*
* return The current status.
*/
__no_inline
RAMFUNC
uint32_t efc_perform_fcr(Efc *p_efc, uint32_t ul_fcr)
{
volatile uint32_t ul_status;
p_efc->EEFC_FCR = ul_fcr;
do {
ul_status = p_efc->EEFC_FSR;
} while ((ul_status & EEFC_FSR_FRDY) != EEFC_FSR_FRDY);
return (ul_status & EEFC_ERROR_FLAGS);
}
Code is compiled with arm-none-eabi-gcc (gcc-arm-none-eabi-7-2017-q4-major) with -Os optimization.
Note: issue seems to occurs more frequently in low temperature (0°C), so I don't exclude hardware related problem, even though operating range of µC is -40 to 85 °C...
Any idea what could go wrong ?
Thanks for your help !
PS: I am not ready to blame cosmic ray... ;-)
EDIT:
Adding some details after more investigation
First, system is clearly more stable with dynamic wait state setting according to core frequency. This is true for temperature nearby 0°C and a little less.
But it becomes totally unstable at -15°C.
I am suspecting that the internal oscillator that we are using has a significant drift due to low temperature (and/or voltage instability). This oscillator (16MHz) is used as source for core and also for peripherals like timer and usart.
I have two other possibilities for source oscillator:
- External fast oscillator at 12 MHz
- External slow oscillator at 32.768 KHz
Oscillator at 12 MHz is not very suitable to generate good clock for uart with a 115200 baudrate.
Slow oscillator can be used to generale a pll clock with frequency between 24 and 48 MHz, that can be used as source for peripherals. I tried this solution and have good results so far at very low temp, but I am not sure it is recommended, specifically for uart.
So my question is, is using a pll as source for uart a bad practice ?
The hardware solution would be to replace external fast oscillator, selecting suitable frequency for uart, but it is not possible for now.
c embedded flash cortex-m4 gcc
$endgroup$
I am struggling with a bus fault error on my samg55 µC based on arm cortex m4 architecture. The issue occurs sporadically and is not 100% reproductible. Let me give some details.
Application code writes periodically some datas into reserved internal flash memory. To do this I use the EFC (embedded flash controller) of the µC which is mapped at address 0x400E0A00 in system controller.
This writing leads in certain conditions to a hard fault. I dumped registers and got the following:
R4_20001368 R5_00000001 R6_00000338 R7_00000020
R8_00000020 R9_2001bcc8 R10_200128cc R11_0043d3a9
R0_402e0a00 R1_5a03380b R2_5a033800 R3_20000067
R12_200129cc LR_0043320b PC_2000006a PSR_010f0000
SHCSR: 0x00000000
CFSR: 0x00008600
HFSR: 0x40000000
DFSR: 0x00000000
MMFAR: 0x402e0a08
BFAR: 0x402e0a08
AFSR: 0x00000000
CFSR indicates a bus fault with BFARVALID flag set. Looking at BFAR register I can see the value 0x402e0a08 which base address 0x402e0a00 is just one bit different from the EFC address 0x400E0A00.
I digged into the code but could not find the bug. Here is suspected code:
Assembler code
004331d4 <efc_perform_command>:
4331d4: f1a1 030e sub.w r3, r1, #14
4331d8: 2b01 cmp r3, #1
4331da: b537 push {r0, r1, r2, r4, r5, lr}
4331dc: d91d bls.n 43321a <efc_perform_command+0x46>
4331de: f3ef 8310 mrs r3, PRIMASK
4331e2: fab3 f383 clz r3, r3
4331e6: 095b lsrs r3, r3, #5
4331e8: 9301 str r3, [sp, #4]
4331ea: b672 cpsid i
4331ec: f3bf 8f5f dmb sy
4331f0: 4c0b ldr r4, [pc, #44] ; (433220 <efc_perform_command+0x4c>)
4331f2: 2300 movs r3, #0
4331f4: 7023 strb r3, [r4, #0]
4331f6: 4b0b ldr r3, [pc, #44] ; (433224 <efc_perform_command+0x50>)
4331f8: 9d01 ldr r5, [sp, #4]
4331fa: ea03 2202 and.w r2, r3, r2, lsl #8
4331fe: f042 42b4 orr.w r2, r2, #1509949440 ; 0x5a000000
433202: b2c9 uxtb r1, r1
433204: 4311 orrs r1, r2
433206: 4b08 ldr r3, [pc, #32] ; (433228 <efc_perform_command+0x54>)
433208: 4798 blx r3
43320a: b125 cbz r5, 433216 <efc_perform_command+0x42>
43320c: 2301 movs r3, #1
43320e: 7023 strb r3, [r4, #0]
433210: f3bf 8f5f dmb sy
433214: b662 cpsie i
433216: b003 add sp, #12
433218: bd30 pop {r4, r5, pc}
43321a: f04f 30ff mov.w r0, #4294967295 ; 0xffffffff
43321e: e7fa b.n 433216 <efc_perform_command+0x42>
433220: 20001368 .word 0x20001368
433224: 00ffff00 .word 0x00ffff00
433228: 20000067 .word 0x20000067
20000066 <efc_perform_fcr>:
20000066: b082 sub sp, #8
20000068: 6041 str r1, [r0, #4]
2000006a: 6883 ldr r3, [r0, #8]
2000006c: 9301 str r3, [sp, #4]
2000006e: 9b01 ldr r3, [sp, #4]
20000070: 07db lsls r3, r3, #31
20000072: d5fa bpl.n 2000006a <efc_perform_fcr+0x4>
20000074: 9801 ldr r0, [sp, #4]
20000076: f000 000e and.w r0, r0, #14
2000007a: b002 add sp, #8
2000007c: 4770 bx lr
C code
/**
* brief Perform the given command and wait until its completion (or an error).
*
* note Unique ID commands are not supported, use efc_perform_read_sequence.
*
* param p_efc Pointer to an EFC instance.
* param ul_command Command to perform.
* param ul_argument Optional command argument.
*
* note This function will automatically choose to use IAP function.
*
* return 0 if successful, otherwise returns an error code.
*/
uint32_t efc_perform_command(Efc *p_efc, uint32_t ul_command,
uint32_t ul_argument)
{
uint32_t result;
irqflags_t flags;
/* Unique ID commands are not supported. */
if (ul_command == EFC_FCMD_STUI || ul_command == EFC_FCMD_SPUI) {
return EFC_RC_NOT_SUPPORT;
}
flags = cpu_irq_save();
/* Use RAM Function. */
result = efc_perform_fcr(p_efc,
EEFC_FCR_FKEY_PASSWD | EEFC_FCR_FARG(ul_argument) |
EEFC_FCR_FCMD(ul_command));
cpu_irq_restore(flags);
return result;
}
/**
* brief Perform command.
*
* param p_efc Pointer to an EFC instance.
* param ul_fcr Flash command.
*
* return The current status.
*/
__no_inline
RAMFUNC
uint32_t efc_perform_fcr(Efc *p_efc, uint32_t ul_fcr)
{
volatile uint32_t ul_status;
p_efc->EEFC_FCR = ul_fcr;
do {
ul_status = p_efc->EEFC_FSR;
} while ((ul_status & EEFC_FSR_FRDY) != EEFC_FSR_FRDY);
return (ul_status & EEFC_ERROR_FLAGS);
}
Code is compiled with arm-none-eabi-gcc (gcc-arm-none-eabi-7-2017-q4-major) with -Os optimization.
Note: issue seems to occurs more frequently in low temperature (0°C), so I don't exclude hardware related problem, even though operating range of µC is -40 to 85 °C...
Any idea what could go wrong ?
Thanks for your help !
PS: I am not ready to blame cosmic ray... ;-)
EDIT:
Adding some details after more investigation
First, system is clearly more stable with dynamic wait state setting according to core frequency. This is true for temperature nearby 0°C and a little less.
But it becomes totally unstable at -15°C.
I am suspecting that the internal oscillator that we are using has a significant drift due to low temperature (and/or voltage instability). This oscillator (16MHz) is used as source for core and also for peripherals like timer and usart.
I have two other possibilities for source oscillator:
- External fast oscillator at 12 MHz
- External slow oscillator at 32.768 KHz
Oscillator at 12 MHz is not very suitable to generate good clock for uart with a 115200 baudrate.
Slow oscillator can be used to generale a pll clock with frequency between 24 and 48 MHz, that can be used as source for peripherals. I tried this solution and have good results so far at very low temp, but I am not sure it is recommended, specifically for uart.
So my question is, is using a pll as source for uart a bad practice ?
The hardware solution would be to replace external fast oscillator, selecting suitable frequency for uart, but it is not possible for now.
c embedded flash cortex-m4 gcc
c embedded flash cortex-m4 gcc
edited Feb 6 at 16:09
Kev1
asked Jan 23 at 10:37
Kev1Kev1
13
13
migrated from superuser.com Jan 23 at 11:11
This question came from our site for computer enthusiasts and power users.
migrated from superuser.com Jan 23 at 11:11
This question came from our site for computer enthusiasts and power users.
$begingroup$
Thanks Andrew for advice. I will try to move it to EE site.
$endgroup$
– Kev1
Jan 23 at 11:03
1
$begingroup$
These kind of bootloader firmware residing on-chip typically wants you to reserve RAM for them. Is this the case and if so, have you done it? And there's also likely some app note regarding this which is a must-read. Btw your debugging seems quite archaic, why are you working with register dumps? Just set a breakpoint at the exception handler then view the instruction trace, to find out exactly which C line that is the culprit, together with the state of all registers. You might need a tool chain free of Eclipse and other diseases though.
$endgroup$
– Lundin
Jan 23 at 11:36
1
$begingroup$
I've seen issues like this before which resulted from incorrectly configuring the micro's internal Flash timing registers, resulting in the Flash being 'overclocked' and occasionally returning invalid code.
$endgroup$
– brhans
Jan 23 at 12:12
1
$begingroup$
@Lundin - "free of Eclipse and other diseases" ;)
$endgroup$
– brhans
Jan 23 at 12:13
1
$begingroup$
Yeah - that's exactly the issue I'm referring to. If your Flash wait states are not set correctly it could appear to sort-kinda-work most of the time, but occasionally you'll find your flash toggles a bit somewhere as the core reads instructions or data and that'll manifest in some really weird symptoms.
$endgroup$
– brhans
Jan 23 at 15:29
|
show 10 more comments
$begingroup$
Thanks Andrew for advice. I will try to move it to EE site.
$endgroup$
– Kev1
Jan 23 at 11:03
1
$begingroup$
These kind of bootloader firmware residing on-chip typically wants you to reserve RAM for them. Is this the case and if so, have you done it? And there's also likely some app note regarding this which is a must-read. Btw your debugging seems quite archaic, why are you working with register dumps? Just set a breakpoint at the exception handler then view the instruction trace, to find out exactly which C line that is the culprit, together with the state of all registers. You might need a tool chain free of Eclipse and other diseases though.
$endgroup$
– Lundin
Jan 23 at 11:36
1
$begingroup$
I've seen issues like this before which resulted from incorrectly configuring the micro's internal Flash timing registers, resulting in the Flash being 'overclocked' and occasionally returning invalid code.
$endgroup$
– brhans
Jan 23 at 12:12
1
$begingroup$
@Lundin - "free of Eclipse and other diseases" ;)
$endgroup$
– brhans
Jan 23 at 12:13
1
$begingroup$
Yeah - that's exactly the issue I'm referring to. If your Flash wait states are not set correctly it could appear to sort-kinda-work most of the time, but occasionally you'll find your flash toggles a bit somewhere as the core reads instructions or data and that'll manifest in some really weird symptoms.
$endgroup$
– brhans
Jan 23 at 15:29
$begingroup$
Thanks Andrew for advice. I will try to move it to EE site.
$endgroup$
– Kev1
Jan 23 at 11:03
$begingroup$
Thanks Andrew for advice. I will try to move it to EE site.
$endgroup$
– Kev1
Jan 23 at 11:03
1
1
$begingroup$
These kind of bootloader firmware residing on-chip typically wants you to reserve RAM for them. Is this the case and if so, have you done it? And there's also likely some app note regarding this which is a must-read. Btw your debugging seems quite archaic, why are you working with register dumps? Just set a breakpoint at the exception handler then view the instruction trace, to find out exactly which C line that is the culprit, together with the state of all registers. You might need a tool chain free of Eclipse and other diseases though.
$endgroup$
– Lundin
Jan 23 at 11:36
$begingroup$
These kind of bootloader firmware residing on-chip typically wants you to reserve RAM for them. Is this the case and if so, have you done it? And there's also likely some app note regarding this which is a must-read. Btw your debugging seems quite archaic, why are you working with register dumps? Just set a breakpoint at the exception handler then view the instruction trace, to find out exactly which C line that is the culprit, together with the state of all registers. You might need a tool chain free of Eclipse and other diseases though.
$endgroup$
– Lundin
Jan 23 at 11:36
1
1
$begingroup$
I've seen issues like this before which resulted from incorrectly configuring the micro's internal Flash timing registers, resulting in the Flash being 'overclocked' and occasionally returning invalid code.
$endgroup$
– brhans
Jan 23 at 12:12
$begingroup$
I've seen issues like this before which resulted from incorrectly configuring the micro's internal Flash timing registers, resulting in the Flash being 'overclocked' and occasionally returning invalid code.
$endgroup$
– brhans
Jan 23 at 12:12
1
1
$begingroup$
@Lundin - "free of Eclipse and other diseases" ;)
$endgroup$
– brhans
Jan 23 at 12:13
$begingroup$
@Lundin - "free of Eclipse and other diseases" ;)
$endgroup$
– brhans
Jan 23 at 12:13
1
1
$begingroup$
Yeah - that's exactly the issue I'm referring to. If your Flash wait states are not set correctly it could appear to sort-kinda-work most of the time, but occasionally you'll find your flash toggles a bit somewhere as the core reads instructions or data and that'll manifest in some really weird symptoms.
$endgroup$
– brhans
Jan 23 at 15:29
$begingroup$
Yeah - that's exactly the issue I'm referring to. If your Flash wait states are not set correctly it could appear to sort-kinda-work most of the time, but occasionally you'll find your flash toggles a bit somewhere as the core reads instructions or data and that'll manifest in some really weird symptoms.
$endgroup$
– brhans
Jan 23 at 15:29
|
show 10 more comments
0
active
oldest
votes
Your Answer
StackExchange.ifUsing("editor", function () {
return StackExchange.using("mathjaxEditing", function () {
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
});
});
}, "mathjax-editing");
StackExchange.ifUsing("editor", function () {
return StackExchange.using("schematics", function () {
StackExchange.schematics.init();
});
}, "cicuitlab");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "135"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2felectronics.stackexchange.com%2fquestions%2f418480%2fbus-fault-when-accessing-mcu-internal-peripheral%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
0
active
oldest
votes
0
active
oldest
votes
active
oldest
votes
active
oldest
votes
Thanks for contributing an answer to Electrical Engineering Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2felectronics.stackexchange.com%2fquestions%2f418480%2fbus-fault-when-accessing-mcu-internal-peripheral%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
$begingroup$
Thanks Andrew for advice. I will try to move it to EE site.
$endgroup$
– Kev1
Jan 23 at 11:03
1
$begingroup$
These kind of bootloader firmware residing on-chip typically wants you to reserve RAM for them. Is this the case and if so, have you done it? And there's also likely some app note regarding this which is a must-read. Btw your debugging seems quite archaic, why are you working with register dumps? Just set a breakpoint at the exception handler then view the instruction trace, to find out exactly which C line that is the culprit, together with the state of all registers. You might need a tool chain free of Eclipse and other diseases though.
$endgroup$
– Lundin
Jan 23 at 11:36
1
$begingroup$
I've seen issues like this before which resulted from incorrectly configuring the micro's internal Flash timing registers, resulting in the Flash being 'overclocked' and occasionally returning invalid code.
$endgroup$
– brhans
Jan 23 at 12:12
1
$begingroup$
@Lundin - "free of Eclipse and other diseases" ;)
$endgroup$
– brhans
Jan 23 at 12:13
1
$begingroup$
Yeah - that's exactly the issue I'm referring to. If your Flash wait states are not set correctly it could appear to sort-kinda-work most of the time, but occasionally you'll find your flash toggles a bit somewhere as the core reads instructions or data and that'll manifest in some really weird symptoms.
$endgroup$
– brhans
Jan 23 at 15:29