How to set register value to enable interrupt? - c

I am handling interrupt for a device in Android. (Android 4.2.2 Kernel 2.6.29, running on Mach-Goldfish virtual device).
So far I have registered my device with the interrupt #17. It hasn't been enabled yet so signals sent to this interrupt are ignored and my interrupt handler is not notified.
The register that enables my device is at offset 0x00, and the memory address, as returned by
(char __iomem *)IO_ADDRESS(resource->start - IO_START)
starts at 0xFE016000.
I tried: (in mydevice_probe())
writel(0x07, 0xFE016000);
//0x07 is a mask to enable three sub-devices at bit 0, bit 1 and bit 2.
But the kernel crashed right away. The following writels also did not work:
writel(0x00, 0xFE016000);
writel(0x01, 0xFE016000);
What did I miss? Could any one show me how to get this done? In case I got the start address wrong, could you point out the way to get it correctly?
Thanks.
P/S: The kernel panic:
qemu: fatal: mydevice_write: Bad offset fea000
R00=c02ef00b R01=00000000 R02=00000007 R03=e0808000
R04=c0340864 R05=c031e3b0 R06=c0173b6c R07=c031e3cc
R08=00000000 R09=00100100 R10=00000000 R11=df827e34
R12=ff016000 R13=df827e18 R14=c002e96c R15=c0030aac
PSR=20000013 --C- A svc32
Aborted (core dumped)

This is to close my question.
it turns out that the emulator is faulty.
Normally writel(MASK, IO_ADDRESS(resource->start - IO_START)); should work.

Related

Hard fault in STM32F101RF due to MRC2 Disassembly?

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.

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.

x86 hardware Interrupt is not working on qemu

I'm writing a kernel (using qemu to simulate) for x86 as a school project and I ran into weird problem.
Even though I have set the interrupt flag in the eflags register, I'm sill not getting any clock interrupts (I checked with qemu info register command and I see eflag=0x292 which means it is set).
To be precise when I run a spin test (while(1); program) in user mode, I get one clock interrupt, but after that one, it stops, qemu does not seems to simulate more! did it happen to anyone else? Is there another mechanism that can affect interrupts?
Anyone have a clue?
Shai.
Apparently in x86, you have to acknowledge clock interrupts after each one.
I.e one must sent an acknowledgment to the lapic after every clock interrupt.
If you are expecting interrupts from the RTC, you must acknowledge the previous interrupt first by reading from REG_C (CMOS register 0x0C).

uart tx buf not changed

I am using EWARM IDE from IAR with an Olimex development board for the ARM STR712FR2, and a J-link JTAG debugger provided by IAR. For some reason, I can't seem to write to the UART TxBUFR register. I believe I have configured all the clocks and baud rate correctly. The datasheet says that when I write to the TxBUFR register, the UART is supposed to immediately start transmitting. I am running this in debug mode, and when I place a breakpoint right after I set the TxBUFR to a value, the register still shows 0x0000, unchanged.
The register value may not change or it may be write-only, have you checked to see if it is actually transmitting or not?
The UART_CR register resets to 0 which has some fields set to reserved values. Have you configured all the fields in here? ALso, as was mentioned, UART_TxBUFR is a write-only register, so you will not be able to read the value back.

Resources