KL25Z Freedom, PortC, and HardFault

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 
已解决

KL25Z Freedom, PortC, and HardFault

跳至解决方案
3,432 次查看
alexdean
Contributor III

I'm trying to configure Port C on the KL25Z on the Freedom board for GPIO and I get a hard fault/exception when I access PORTC->PCR[0]. Ports A, B, and D don't (seem to) give any problems. I'm using Keil MicroVision 4. Would anyone have any information on what's going on?

Thanks!

标签 (1)
1 解答
1,697 次查看
JimDon
Senior Contributor III

Try this:

    // Need to do this or setting PCR registers will generate a hard fault.

    // 12.2.9 This enables the clock so you can pin route.

    SIM_SCGC5 |= (SIM_SCGC5_PORTD_MASK | SIM_SCGC5_PORTA_MASK | SIM_SCGC5_PORTC_MASK |   SIM_SCGC5_PORTB_MASK | SIM_SCGC5_PORTE_MASK );

在原帖中查看解决方案

0 项奖励
回复
6 回复数
1,697 次查看
alexdean
Contributor III

Thanks for the suggestions. It sounds like a job for ... MicroTraceBuffer-Man! I'll let you know who the villain turns out to be.

1,698 次查看
JimDon
Senior Contributor III

Try this:

    // Need to do this or setting PCR registers will generate a hard fault.

    // 12.2.9 This enables the clock so you can pin route.

    SIM_SCGC5 |= (SIM_SCGC5_PORTD_MASK | SIM_SCGC5_PORTA_MASK | SIM_SCGC5_PORTC_MASK |   SIM_SCGC5_PORTB_MASK | SIM_SCGC5_PORTE_MASK );

0 项奖励
回复
1,697 次查看
alexdean
Contributor III

Thanks, Jim. That did it!

0 项奖励
回复
1,697 次查看
JimDon
Senior Contributor III

Alex,

Please mark this as the answer so others will see this as solved and hopefully avoid the pain we went through to figure this out....

thanks.

0 项奖励
回复
1,697 次查看
BlackNight
NXP Employee
NXP Employee

I have seen cases where a dangling pointer was writing to the stack, and when the pcr register was restored, it had the T bit cleared, causing a hard fault at the next branch instruction.

It was helpful for me to write a small interrupt handler as described in Debugging Hard Faults on ARM Cortex-M | MCU on Eclipse

Erich

0 项奖励
回复
1,697 次查看
Derrick
NXP Employee
NXP Employee

It's a little hard to tell what's going on based upon your description.  The ARM Cortex-M0+ Devices Generic User Guide (document DUI0662A) may shed some light, specifically section 2.4 "Fault handling":

"Faults are a subset of exceptions, see Exception model on page 2-16. All faults result in the HardFault exception being taken or cause Lockup if they occur in the NMI or HardFault handler.

The faults are:

  • execution of an SVC instruction at a priority equal or higher than SVCall

  • execution of a BKPT instruction without a debugger attached

  • a system-generated bus error on a load or store

  • execution of an instruction from an XN memory address

  • execution of an instruction from a location for which the system generates a bus fault

  • a system-generated bus error on a vector fetch

  • execution of an Undefined instruction

  • execution of an instruction when not in Thumb-State as a result of the T-bit being previously cleared to 0

  • an attempted load or store to an unaligned address

  • if the device implements the MPU, an MPU fault because of a privilege violation or an attempt to access an unmanaged region.

I recently encountered a HardFault caused by a BLX instruction that was clearing the T-bit.  I didn't see anything wrong with my C source code.  I found the problem as I single-stepped through the resultant assembly language.  I found the cause in section 3.3.2 "Restrictions when using PC or SP" of the same manual:

"When you update the PC with a BX, BLX, or POP instruction, bit[0] of any address must be 1 for correct execution. This is because this bit indicates the destination instruction set, and the Cortex-M0+ processor only supports Thumb instructions. When a BL or BLX instruction writes the value of bit[0] into the LR it is automatically assigned the value 1."

In my case, the destination address for the BLX instruction had its least significant bit cleared, i.e., bit[0] = 0.  Sure enough, when the BLX instruction executed I saw the T-bit clear in the Execution Program Status Register (EPSR).  As indicated above, this needs to change to bit[0] = 1 to stay in the the Thumb code state.  I fixed this by simply incrementing the destination address (which was a pointer variable) prior to the execution of the BLX instruction.

I'm not sure if this applies to your particular scenario but I hope that it gives you an idea as to where to look.

Best Regards,

Derrick

0 项奖励
回复