Program runs, calls function but I get no "output" on STM32L1 - c

I encounter a problem currently with a custom STM32L151 board that I will try to explain here.
The program I am testing runs properly for some time, I get debug messages on puTTY as intended but at a time, the program seems to be "blocked".
It is pretty weird behaviour because the function which prints over UART is called (I put a breakpoint here to see if I reach this point) but I get no output on a terminal.
So I was wondering what could be the issue, if someone as an idea because I kinda run out of ideas to be honest, I tried to understand. I will assume there is no hardware issue, it is still possible but I do not think it could be that reason.
Also, the programs is aimed at receiving a FSK message and answering it and it seems that I have the same behaviour with the radio chip: I receive the message and send a response (I get the TxDone callback called which indicates that the FSK message has normally been sent but the device which waits for this response does not receive it).
So to sum up a bit: the program runs properly for a moment then "blocks" & I do not get any output anymore (debug or radio communication) but still runs (functions effectively called) and after a moment again, the program "unblocks" itself and runs properly again (debug messages work).
The device I work on is STM32L151 based, I work with Keil, UART config is: 19200 baudrate, 8 data bits, 1 stop bit, no parity, XON/XOFF flow control & the radio chip I use is SX1272.
If someone has any idea or any trail I can investigate on. If you need any further details, I am not sure I am accurate enough on the description of the problem but any help is appreciated.

Related

Glitchy audio output, no underruns

When using snd_pcm_writei() in non-blocking mode everything works perfect for a while but eventually the audio gets choppy. It sounds like the ring buffer pointers are getting out of sync (ie. sometimes I can tell that the audio is playing out of order). How long it takes for the problem to start it's hardware dependent. On a Gentoo box on real hardware it seldom happens, but on a buildroot system running on QEMU it happens after about 5 minutes. On both cases draining the pcm stream fixes the problem. I have verified that I'm writing the samples correctly by also writting them to a file and playing them with aplay.
Currently I'm setting avail_min to the period size (1024 frames) and calling snd_pcm_wait() before writting chunks of the period size. But I tried a number of different variations (different chunk sizes, checking avail myself and use pthread_cond_timedwait() instead of snd_pcm_wait(), etc). But the only thing that works fine is using blocking mode but I can not do that.
You can see the current source code here: https://bitbucket.org/frodzdev/mediabox/src/5a6471316c7ae481b329e7e0d4af1bb68a32e71d/src/audio.c?at=staging&fileviewer=file-view-default (it needs a little cleanup since I'm trying all kinds of things). The code that does the actual IO starts at line 375.
Edit:
I think I got a solution but I don't understand why it seems to work. It seems that it does not matter if I'm using non-blocking mode, the problem is when I wait to make sure there's room on the buffer (either through snd_pcm_wait(), pthread_cond_timedwait(), or usleep()).
The version that seems to work is here: https://bitbucket.org/frodzdev/mediabox/src/c3eb290087d9bbe0d5f37653a33a1ba88ef0628b/src/audio.c?fileviewer=file-view-default. I switched to blocking mode while still waiting before calling snd_pcm_writei() and it didn't made a difference. Then I added the call to snd_pcm_avail() before calling snd_pcm_status() on avbox_audiostream_gettime(). This function is called constantly by another thread to get the stream clock and it only uses snd_pcm_status() to get the timestamps. Now it seems to work (at least it is a lot less probable to happen) but I don't understand exactly why. I understand that snd_pcm_avail() will synchronize the pointers with the kernel but I don't really understand when it needs to be called and the difference between snd_pcm_state() et al and snd_pcm_status(). Does snd_pcm_status() also synchronize anything? It seems not because sometimes snd_pcm_status_get_state() will return RUNNING when snd_pcm_avail() returns -EPIPE. The ALSA documentation is really vague. Perhaps understanding these things will help me understand my problem?
Now, when I said that it seems to be working I mean that I cannot reproduce it on real hardware. It still happens on QEMU though way less often. But considering that on the next commit I switched to blocking mode without waiting (which I've used in the past and never had a problem with on real hardware) and it still happens in QEMU and also the fact that this is a common issue with QEMU I'm starting to think that I may have fixed the issue on my end and now it's just a QEMU problem. Is there any way to determine if the problem is a bug on my end that is easier to trigger on the emulator or if it's just an emulator problem?
Edit: I realize that I should fill the buffer before waiting but at this point my concern is not to prevent underruns but to make sure that my code can handle them when they happen. Besides the buffer is filling up after a few iterations. I confirmed this by outputing avail, buffer_size, etc before writing each packet and the numbers I get don't make perfect sense, they show an error of 1 or 2 periods about every 8th period. Also (and this is the main problem) I'm not detecting any underruns, the audio get choppy but all writes succeed. In fact, if the problem start happening and I trigger an underrun by overloading the CPU it will correct itself when the pcm is reset.
In line 505: You're using time as argument to malloc.
In line 568: Weren't you playing audio? In this case you should do wait only after you wrote the frames. Let's think ...
Audio device generates an interrupt when it terminates to process a period.
| period A | period B |
^ ^
irq irq
Before you start the pcm, audio device doesn't generate any interrupt. Notice here that you're waiting and you haven't started the pcm yet. You only starts it when you call snd_pcm_writei().
When you wait for audio data you'll be awake only when the current period has been fully processed -- in your first wait the first period wasn't even written -- so in a comfortable situation you should write the whole buffer, wait for the first interrupt, and then write the just processed period, and on and on.
Initially, buffer is empty:
| | |
write():
|############|############|
wait():
..............
When we wake up:
| |############|
write():
|############|############|
I found the problem is you're writing audio just before it be played, then sometimes it may arrive delayed in the buffer.

Atmel SAM4S8B: Unable to enter Programming mode

So I was programming on my board with a ATSAM4S8Bu using an Atmel-ICE debugger happily when suddenly I was assaulted by this error message any time I tried to debug or deploy to my board:
Failed to launch program
Error: unexpected chip identifier 0x00000000
This error also sometimes gets shouted at me:
Could not activate interface, but found DAP with ID 0x2ba01477.
How rude of it! I tried reasoning with it but it is not having any of it.
but seriously, it was fine one moment and the next this error has stopped me from further development so what does it mean and how do I fix this?
EDIT:
This error only seems to occur on my machine. It works on my colleagues, I tried reinstalling atmel-usb and atmel studio 6.2 but no luck :(
EDIT:
Some screen shots of the screen im shown in Tools->Device Programming and then trying to read the devices signature:
EDIT:
I also seem to get this error sometimes instead:
I've had this problem too and I have found a couple of solutions that I would like to share.
My PCB was using an ATSAM4E processor (that had never been programmed) with a Cortex debug header. I got the error message when I tried either method (SWD or JTAG).
Note: I was able to read the Device ID for a very short window after powering the PCB on or after pressing the reset button (Credit to Yaro and Yarooo). Often I would have to try multiple times to try and hit that short window. This confirmed to me that my circuit of the Cortex Debug header was correct.
jrb114 quotes in his post that there is an errata on the SAM3S datasheet that requires:
an external crystal or ceramic resonator on XIN/XOUT, or use the Main oscillator in bypass mode (applying a clock on XIN).
...
So what I did to make these boards work was provide a 1 MHz clock to XIN using a signal generator. Apply power to the PCB, then connect using the ATMEL-Ice. This connects fine. After that I set the GPNVM Bit 1 so we boot from flash, not SAMBA, programmed the device and it works fine.
My PCBs had an external crystal so I was a bit confused why my boards didn't work. So I put an oscilloscope on the XIN line and found that the crystal was not generating a waveform.
It turns out that on most of my boards, there was a short between one of the capacitors (for the crystal) to ground. No wonder my clock wasn't going.
On the other boards, the inductor that goes between VDD_OUT and VDD_PLL was not soldered correctly to the PCB, causing it to be open circuit.
Overall, it appears that this error is a result of not having a clock signal on XIN, whether it be incorrect wiring or not using an external crystal/resonator.

32F429IDISCOVERY board hard fault/default handler

I'm trying to implement a GOCR algorithm to 32F429IDISCOVERY board. The GOCR itself works very well on PC but on the discovery board I'm still having some issues that makes it unstable and unusable. Sometimes the algorithm works fine, everything goes well and the result is great but sometimes the processor gets stuck in hard fault/default handler. I cannot tell what is the reason of the crash and what am I supposed to do but I believe that stack/heap got overflowed.
Below I attached an image that shows the state of the processor before and after the crash:

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.

Hijacking the realtime clock in linux

I want to write a LKM (Linux Kernel Module) that hijacks the realtime clock (interrupt 8). So I want the interrupt to be set to my function and at some point send it back to the old function.
I have tried to use the request_irq function without any success, probably because the kernel function that is there is not willing to share the interrupt (which is a good decision I guess).
I also tried to edit the IDT (Interrupt Descriptor Table), according to some pages I found. Non of them worked, most didn't even compile since they where written for kernel 2.6, and I'm working with 3.10.
This is a simplified code that I have just to give you the idea of what I'm doing.
kpage =__get_free_page( GFP_KERNEL);
asm("sidt %0": : "m"(*idtr) : );
memcpy(kpage, idtr, 256*sizeof(kpage));
newidt = (unsigned long long *)(*(unsigned long*)(idtr+1));
newidt[8] = &my_function;
asm("lidt %0": "=m"(newidt):);
All my attempts ended in good times with a segmentation fault, and in bad times with the kernel crashing forcing me to reboot (luckily I work with a virtual machine and snapshots).
So how can I hijack the realtime interrupt so it does my stuff? (And then send it back to the original function to get executed.)
Here is some nice code to change the pagefault function on the IDT. I couldn't make it work, since it's also written for kernel 2.6. This question is also worth looking into.
To get the bounty please publish working code, or at least sufficient info to make it run.
This can help you : http://cormander.com/2011/12/how-to-hook-into-hijack-linux-kernel-functions-via-lkm/
Why not you simply hook a function that is call every x steps like you want and execute what ever you need ?

Resources