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... ;-)
User contributions licensed under CC BY-SA 3.0