Hard fault in STM32F101RF due to MRC2 Disassembly? - arm

I am having a bootloader code wherein I will sending/receiving data via USART . I have configured USART to operate in interrupt mode.
USART functionality works perfectly fine independently. Verified this with multiple read/write instances.
When I integrate USART code with my bootloader code, bootloader will keep on checking if there is any pending data to read from USART.
If there is any pending data, bootloader will read the Data Register (DR) for the data received already through interrupt. (kind of polling + interrupt)
My problem :
Whenever there is an USART receive interrupt is triggered , inside receive interrupt service routine hard fault error occurs.
PC says its inside hard fault routine where I read data from DR.
But a strange thing I saw is, from the location where hard fault hits, in the disassembly I see only MRC2 commands
Is the issue occuring because of this ?? 0x8004802 is the location where my hardfault hits.
Kindly enlighten me on this

Look at the raw hex values: 0xFF all the way starting with a suspicious address 0x8004800 which is for sure a page boundary.
In other words: The flash memory is bad or was erased and not completely written. Verifying the flashed program (bootloader) should fail.
If that was in your bootloader code, it might have tried to overwrite itself - or simply erased the wrong memory page.

Related

STM32: UART DMA does not start correctly

I am using two STM32H743 connected via RS232. These two modules connected to same power.
They use UART with DMA. When I turn on modules at the same time, UART and DMA starts correctly.
But when i restart one of the modules while other is awake, the reset module's UART and DMA does not start therefore they cannot communicate with each other.
This problem is also happened before with STM32F4 series. MCU is connected to FPGA and they communicate via UART. When FPGA starts before MCU, DMA and UART does not start properly. What could cause this problem?
Do i need to have a high-z or floating pin states before starting UART?
After lots of debugging hours, I finally found the cause and solution.
When first bytes reach to UART peripheral, due to clock mismatch, it triggers frame error then stops the DMA. This happens more than usual when UART datarate is very high. But I had added the ErrorCallback function to handle the interrupt. Unfortunately, I misused the function.
My use :
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{
HAL_UART_MspDeInit();
HAL_UART_Receive_DMA(...);
}
HAL_UART_MspDeInit does not clear structs and initializations therefore Receive_DMA function cannot start it again. So, my communication stops.
Correct use :
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{
HAL_UART_DeInit();
HAL_UART_Receive_DMA(...);
}
Thanks to three typos in my code, it caused to me a lot of time. But finally, it resolved.
The UART and DMA peripherals usually have an error detector, thus has it's flags into the status register. When an error happen, the STM32 HAL will stop any transfer ongoing and wait until you treat this fail. You can check, with the debug module, the HAL status registers to troubleshoot the problem, and add the treatment to it in you code. At first you could reset the peripheral by run DeInit() and right after run Init() routine of the peripheral with error, and reset any other piece of code e.g. state machines and stuff that uses the data from this peripheral.

Debugging STM32 Cortex-M4, running debugger causes hard fault

I'm trying to debug some firmware I'm developing on an STM32 Nucleo-64 dev board which has an STM32L412RBT6 Cortex-M4 MCU, and I've been running into a very weird error. Basically, when I try to debug, I end up getting a hard fault on one specific instruction (details below). The odd thing is that this only happens when I'm debugging. If I reset the MCU and let it run without the debugger, it executes the line fine and moves on with the rest of the code.
My setup:
- Using the onboard ST-Link debugger on the Nucleo board
- STM32CubeIDE environment
- GDB debugger
The debugging process seems to be working fine other than this hard fault. I can start the debugger, step through some commands, see changes in variables in my watch list, turn on/off LEDs, etc.
The line that causes the hard fault when debugging is a SPI read-write command:
ret = HAL_SPI_TransmitReceive(&hspi1, (uint8_t *) txBuffer, (uint8_t *) rxBuffer, 4, 1000);
And the line within the HAL_SPI_TransmitReceive() function that causes the fault is the if statement:
if ((((HAL_GetTick() - tickstart) >= Timeout) && ((Timeout != HAL_MAX_DELAY)))
|| (Timeout == 0U))
{
errorcode = HAL_TIMEOUT;
goto error;
}
I've just started working on this project and was just trying to run a quick SPI loopback test to make sure the driver was working properly. There is very little else in the project at the moment, just some initialization for the clock, GPIO, and SPI. I'm confident the code is sound, and again it is working fine when I'm not actively debugging.
I don't have any experience debugging these types of errors. After some searching, I arrived at the Cortex status registers. The Configurable Fault Status Register has a value of 0x0008 0000, which corresponds to the NOCP bit being set, indicating that a coprocessor instruction was issued but the coprocessor was disabled or not present. I'm not sure how this could be relevant, is there something I'm missing? The Hard Fault Status Register has a value of 0x0400 0000, with the FORCED bit set (meaning a configurable fault was escalated to a hard fault).
When I reset the MCU within the debug environment, it immediately goes to the hard fault handler. In that case, the Configurable Fault Status Register has a value of 0x8200, with the BFARVALID and PRECISERR bits set. With BFARVALID set, the Bus Fault Address Register holds the address that triggered the fault, and it has a value of 0x2000 a008. Here's where I get really confused, as the memory ranges for this chip are flash program memory from 0x0800 0000 to 0x0802 0000, and SRAM from 0x2000 0000 to 0x2000 a000, so the address of 0x2000 a008 is outside of either of those. I'm really stumped by this and not sure where to go from here. Any suggestions are much appreciated.

STM32F4 FSMC/FMC SRAM as Heap/Stack results in random hardfaults

we are currently evaluating to use an external SRAM for C/C++ heap storage on our platform using a STM32F439BI microcontroller.
The problem
Using the SRAM as storage for heap results in random hardfaults which are raised from buserrors/imprecice buserrors.
Without placing the heap on the SRAM, memory tests run successfully on the whole SRAM (8 bit/16 bit and 32 bit accesses).
Connecting a debugger I can observe these errors sometimes before a hardfault occurs. Most often a word is read from the SRAM and the CPU register fills with addresses of the following format: 0x-1F3-1F3 (- is most often '0', sometimes 'A' or '6'). The pattern '1F3' persists. If the same address is read again some lines further down the correct value is read (some other address in 0x60000000 space).
If I stop the program on a breakpoint at some point early in the program and step a few lines, I get these errors more frequently.
Further details
The SRAM is connected using the FMC/FSMC peripheral on FMC bank 1 and SRAM bank 1 and is therefore memory-mapped to address 0x60000000.
All settings for GPIO pins and FMC configuration are set from the startup file before main() executes or static objects are created.
The SRAM is the following: CY7C1041GN30
We connect all 16 data pins, all 18 address pins, BHE, BLE, OE, WE and CE to our controller. All pins are configured as push-pull-alternate-function, pull-up, AF_12 (FMC), very high speed. We enable clocks for all necessary pins and the clock for FMC. Note: Initially we started out without pull-up/down showing the same symptoms.
The controller runs with a clock speed of 168 MHz
As stated above, a memory test runs successfully
We use DMA for SPI, I2C and ADC data transfers
We frequently use interrupts, including external (pin) interrupts
We use the following timing settings:
AddressSetupTime: 2
AddressHoldTime: 4
DataSetupTime: 4
BusTurnAroundDuration: 1
CLKDivision: 2
DataLatency: 2
We configure the FMC as follows:
NSBank FMC_NORSRAM_BANK1,
DataAddressMux FMC_DATA_ADDRESS_MUX_DISABLE,
MemoryType FMC_MEMORY_TYPE_SRAM,
MemoryDataWidth FMC_NORSRAM_MEM_BUS_WIDTH_16,
BurstAccessMode FMC_BURST_ACCESS_MODE_DISABLE,
WaitSignalPolarity FMC_WAIT_SIGNAL_POLARITY_LOW,
WrapMode FMC_WRAP_MODE_DISABLE,
WaitSignalActive FMC_WAIT_TIMING_BEFORE_WS,
WriteOperation FMC_WRITE_OPERATION_ENABLE,
WaitSignal FMC_WAIT_SIGNAL_DISABLE,
ExtendedMode FMC_EXTENDED_MODE_DISABLE,
AsynchronousWait FMC_ASYNCHRONOUS_WAIT_DISABLE,
WriteBurst FMC_WRITE_BURST_DISABLE,
ContinuousClock FMC_CONTINUOUS_CLOCK_SYNC_ASYNC,
WriteFifo 0,
PageSize 0
We spend a lot of time of experimenting with longer timings and compared all the settings to examples including this one: Using STM32L476/486 FSMC peripheral
to drive external memories (although this one is for the STM32L4, I am fairly certain it applies to this controller as well)
Findings on similar problems
The problem sounds very similar to this errata sheet entry: "2.3.4 Corruption of data read from the FMC" but it also says the error is fixed in our revision of the controller (3)
I hope someone out there has seen this strange behaviour before and can help us. After over one week of debugging we expect some kind of error in the controller when interrupts/DMA accesses occur while the CPU accesses the SRAM (when we use it as heap, it is accessed very frequently). Hopefully you can shed some light on this topic.
Sorry for not getting back to you, internet.
Yes, we found out what the issue was (at least in our case). Problem was that the J-Link debugger we use is causing problems if it hangs above the power electronics on our pcb (it is mounted vertically). If we guide the ribbon cable out at the top (only digital electronics) the error disappears. So our guess is, that some noise from the electronics was caught up by the cable and directly injected into the JTAG port, which caused failures inside the MCU.
Just got a confirmation from ST, that there is a bug in the STM32F469 FMC that might cause incorrect values if the write fifo is disabled. The workaround is to have the fifo enabled. It is the same issue as in this F7 processor https://www.st.com/resource/en/errata_sheet/dm00145382.pdf

Spi interrupt handler works when a printf() is used

I am trying to initiate a spi communication between an omap processor an sam4l one. I have configured spi protocol and omap is the master. Now what I see is the test data I am sending is correctly reaching on sam4l and I can see the isr is printing that data. Using more printf here and there in isr makes the operation happen and the respective operation happens, but if I remove all printfs I can't see any operation happening. What can be the cause of this anomaly? Is it a usual case of wrong frequency settings or something?
If code is needed I will post that too but its big.
Thanks
I think you are trying to print message in driver.
As printing message on console with slow down your driver, it may behave slowly and your driver work well.
Use pr_info() for debug and change setting to not come message on console by editing /proc/sys/kernel/printk to 4 4 1 7
-> It will store debug message in buffer.
-> Driver not slow down because of printing message on screen.
-> And you can see it by typing dmesg command later.
Then find orignal problem which may cause error.
If a routine works with printf "here and there" and not otherwise, almostcertainly the problem is that there are timing issues. As a trivial example, let's say you write to an SPI flash and then check its content. The flash memory write will take some times, so if you check immediately, the data would not be valid, but if you insert a printf call in between, it may have taken enough time that the read back is now valid.

Interfacing a slow device to a MCF5270 Microcontroller

I'm looking for ways to interface a slow device (an ADC - ~1.2MHz) to my mcf5270 microcontroller, which is a rather fast device (~150MHz). I am using ADC0817, and have tried the following: GPIO read off the data lines, memory mapped access (since the adc is uP compatible).
When mapped as a location in memory, I am using the maximum wait states (15ws, which is about 107ns). The mcf5270 does not support any further waiting without using their bus model (which the ADCs do not support).
Using GPIO, only junk values are read.
Note: The ADC is actually working, and other than reading data the interface to it is functional. I am using C/C++ and assembly.
In short, I am looking for suggestions for ways in which to try to read the data off the ADC0817.
Comments and responses are greatly appreciated.
You could trigger the ADC through some GPIO, do an appropriate number of NOPs and then read the value. Also, you'd need to disable interrupts while doing this.
I think memory mapped should work - normally I would wait for the interrupt from the ADC, then read the byte at the specified address. Since you get an interrupt, there is no wait state needed. Am I missing something? GPIO should also work. How do you know the ADC is working? Can you put a logic analyzer on the data & interrupt to prove the ADC is producing the correct output?
I think from what he's saying MMIO wont' work because he would need more than the maximum number of wait states on the bus to get the glue logic to respond - ie, the A/D won't set its bus pins soon enough for the uC to be happy. That's a problem sometimes.
But the GPIO approach should work. If junk values are being read I assume that you aren't following the timing diagram provided. You'll have to be able to wait certain amounts of time after you signal a read before the data is valid. Check out the datasheet for specifics.

Resources