I aim to measure latency between an interruption from the interruption getting caught to the waking up of the waiting task.
I am able to send a signal from a Kernel module to the task.
However, on my target, I haven't got any driver developped for GPIO that were my first try, so I can't pilot any gpio from the kernel module (gpio_export gives error 38).
So I wanted to generate an interrupt through software directly and not from an external signal on GPIOs.
I've found this embetronicx tutorial that shows how to do it with x86 CPUs however, I can't find any similar solution with an A72 (Armv8) target. Do you have any tips ?
Related
We have an embedded board that has an iMX8M-Plus Processor and Linux v5.4.161. This board has one PCIe bus and that one is connected to an FPGA. When we power up the board, the FPGA is not yet configured, so it acts as if it was not on the PCIe bus.
Once the Linux is fully booted, we configure the FPGA and only after that it starts acting as a PCIe endpoint (device).
At this point, when I run lspci -> it returns nothing.
When I first execute echo "1" > /sys/bus/pci/rescan as suggested here and here and then lspci, I still get nothing.
But if I reboot the linux without reseting the FPGA, it starts being visible in the lspci list. Rebooting the linux is not an option for us. Somehow I need to tell the linux that whatever it's doing at the boot time, please do it again at runtime. But I couldn't find a solution for this so far.
According to the Texas Instrument support forum, they said if the PCIe link is not trained at the boot time, rescan command never works.
At the boot time, while linux loads a pci driver, it tries to establish a PCIe link, I can see that with an oscilloscope, PERST pin is asserted and PCIE_CLK generated for a while and then stops if it can not detect any device. But the rescan command never does that.
Also in the system there is no pcie device to executeecho 1 > $pcidevice/remove in order to make rescan functional. Or there is no device or bus to set power off and on back like echo 0 > /sys/bus/pci/slots/.../power
I also learned that there was a method in old linux times (v2.6) called adding a Fake PCIe Device which physically doesn't exist to solve this problem. For that I took the fakephp.c driver from an old linux repo and ported it to ours. After solving a couple of deprecated function problems, it is compiled for Linux Kernel v5.4. modprobe fakephp worked and driver loaded but somehow I didn't get this fake device in my device list. Here it is mentioned that the fakephp driver was removed from mainstream linux since PCI core has similar functionality, but he never mentioned how.
Short of the story is that, I am stuck here, I need my FPGA to be visible in the lspci list without restarting the linux.
I recommend configuring the FPGA in u-boot to get away from these kinds of problems. Connect up SPI pins to FPGA's config pins & run it in Slave configuration mode.
Is there an inbuilt or pre-existing feature I can use to accomplish Flashing a Cyclone IV's(EP4CE6E22C8) SROM(W25Q16BV) chip via its JTAG connection? Maybe some setting when compiling in Quartus to tell the FPGA "Hey flash this". Or a specific command for OpenOCD.
I saw that there are IP cores to manually flash the device, but I really do not want to go down that rabbit hole. Programming my own flasher sounds like an unnessisary hell at my experience level.
I hope this is good enough of a question, Ive been suffering with this for months, if you need any more information
INFO:
I have a W25Q16BV SROM chip connected directlyto a EP4CE6E22C8 in AS config mode. (Data input on SROM has single direct connection to FPGA's ASDO)
And to that FPGA I have a JTAG connection that connects to my computer via a J-Link adapter.
Controlling the J-Link adapter is OpenOCD that uploades compiled data(SVF file) provided by Quartus Prime.
The board is from an obscure seller, but it did come pre-flashed with an example program that starts upon every reset, so there must be some way they uploaded this.
We programmed a STM32L072, using, for the lower layers, the HAL lib generated from cubeMX.
Note that the "programming style" in my enterprise does not involve to include a watchdog in their embedded devices. No comment.
During one particular field test (out of many), the device stopped working (i.e.: screen freeze, and no response on the communication bus, but the PWM driver was working).
The device has been restarted and after a few minutes of work, the freeze happened again. This happened a few times before we arrived.
We plugged a JTAG/ST-LinkV2, and nothing changed on bus or screen.
As soon as we unplugged the flasher, the device restarted working without a reset (we could have recognized a initialization pattern if it had happened).
I don't understand how JTAG specification could explain this behavior (i.e. the unfreezing)?
By the way, what can cause a freeze that can be unfrozen by a JTAG unplugging? Oscillator stopped? Auto sleeping modes? hardware breakpoint? software breakpoint? Interrupts disabled?
EDIT - Answer to comments and recap :
Not an oscillator cause because PWM is still working.
Software breakpoint? unlikely as none has been set before flashing the
program.
Concerning interrupts, I think this is an interesting lead, but how can the JTAG change anything by unplugging it?
Hard to determine without knowing more about your software. If the PWM is running, clearly the oscillator has not stopped. It sounds like the code may have an embedded software breakpoint instruction. The on-chip debug does not by default stop peripheral clocks when it hits a break-point.
Such instructions should be guarded to only block when the host debugger is attached (i.e. the debugger software, not just the physical JTAG hardware), e.g:
if (CoreDebug->DHCSR & 1) __BKPT(0);
If the breakpoint is not conditional on the debugger, the processor will halt with nothing to restart it (other than a watchdog, preferably the independent watchdog, because the windowed watchdog can be configured to have its clock stopped when a breakpoint is hit).
When a debugger is detached the break-point will be released, which may be what is happening here.
I'm having trouble with an industrial Linux computer I'm working with to achieve communication over an RS485 bus with multiple connected devices. What I've encountered is that the IO pins used by the RS485 USART driver are set to different levels at startup instead of going to the RS485 idle/tri-state. As a result, the other devices on the bus are blocked for more than 30 seconds while the device boots up, triggering all sorts of external problems. The course of events can be viewed in the attached image, where I've measured the output voltages with an oscilloscope during startup.
My guess is that the actual driver is not started until the voltage levels reach their tri-state levels (e.g. ~2.2V for this device). After that everything works as expected.
I've tried to find any config-files to set the default IO level of the pins at boot (thinking this may be set by the bootloader) to no avail.
Also, I've tried to apply a startup-script to run "early enough" to set DATA- high, but the device in question does not provide any interface to control these pins as regular GPIOs as far as I can tell.
Any help, tips or insights would be much appreciated!
EDIT: I am not an experienced Linux developer, so please highlight if I've left out any important details.
Some specs:
ARM920T rev 0 (v41) CPU
Proprietary distribution of Linux 2.6
Uses Busybox
Atmel USART drivers
Extract from boot log:
Linux version 2.6.28.10 (root#) (gcc version 4.1.2) #94 PREEMPT Tue Oct 29 10:22:19 CET 2013
CPU: ARM920T [41129200] revision 0 (ARMv4T), cr=c0003177
/...
.../
RS485 mode for port /dev/ttyS3 enabled
/...
... (I'm guessing the ~30 secs elapse here)
.../
atmel_usart.3: ttyS3 at MMIO 0xfffcc000 (irq = 9) is a ATMEL_SERIAL
atmel_serial.3: Putting the RS485 RTS pin down
/...
...
.../
Full boot log: https://drive.google.com/file/d/0B2XYl1mNCa8jNUZ5V0Nic1hkU0U/view
Similar issue:
Possibly a similar issue is discussed here: UART initialisation: Prevent UART to pull RTS high
But I'm not sure how to proceed with the suggested solution.
This is little more than wild speculation, but it might be worth adding a start-up script that echoes a NULL character to the device (e.g. /dev/ttyS1 or whatever) as early as possible during start-up. This might be enough to kick the driver into initialising the hardware.
You could also try to locate the driver in the Linux source to look at how it starts up.
Probably you have access to the source code, so you can investigate who and when mess with the that GPIO. Just grep the kernel source for the atmel gpio controller port addresses to figure out what happen. If you are lucky may be there will be kernel command line option that you can pass from the bootloader to set the line to what you need in advance.
this answer may work if you can find required things mentioned below
of your board!
Once I also had a same issue on PWM. There I found that my bootloader was responsible for the same, I changed in bootloader configuration and it started working fine.
Check your BSP provided by board vendor or third party (If you have the source), If your bootloader is U-boot you can find it inside U-boot-(source)/include/configs/(your-board).h there you can find configuration for RS484. As per your datasheet for the board you can check for other things which are muxed on the same pin and disable those if not required for boot time and enable RS485.
enabling/disabling can be done by changing the values 0, 1 or 2 as per your configuration and also you can simply disable anything just by commenting // out the line.
I'm running embedded Linux (Angstrom) on an Atmel board (at91 sam9g25) mounting an ARM MCU.
I'd like to set the CPU in idle mode, ideally from userspace by using a function (then the system would be waken up by an hardware gpio interrupt). How can I do that? Alternatively, how can it be done in kernelspace?
I cannot find much, maybe somebody has some example to start from?
Try checking this page . Try also reading Optimizing Power Consumption for AT91SAM9261-based Systems to have an idea about what you can do with power management.
What you can basically do is setting the state you want in /sys/power/state but before entering the low-power state you need to set how your system can be awakened.
Be advised that, in my experience, I have seen a lot of different behaviors by changing the kernel, so by patient and try different versions.