Forums » Software Development »
Video output blinks frequently
Added by Helmut Forren over 11 years ago
My custom system is based on the MityOMAP-L138F.
At random times, but fairly frequently, my video output corrupts for a frame. The nature of the corruption is that a single line (perhaps the top line) is shifted part way across the screen, and then reproduced for every line of the screen. Since I have 40-pixel-wide black bands on the left and right sides of my image, I end up seeing this black band in the center, and the rest of the screen looks like vertical stripes due to the repetition of a single original line of video. The actual nature of the corruption might be a clue, but otherwise how this looks is not the real issue. The issue is that the corruption happens at all.
At the lowest level, my program is using "ioctl(*display_fd, VIDIOC_DQBUF, &buf)" to get a buffer from VPIF, doing a memcpy of my working image into the buffer, and then using "ioctl(*display_fd, VIDIOC_QBUF, &buf)" to give the buffer back to VPIF.
I've analyzed far enough to figure out the following. I let my program run for a few seconds, then automatically STOP using those ioctl's. The result should be that the 15 buffers I've had VPIF create and use, are now never touched again. The video output should remain "frozen" on the last video image that I sent (which was the same for all 15 buffers). I did this in order to eliminate the possibility that the corruption is of my own buffer. So, while "frozen", the video output indeed looks frozen. However, the frequent corruptions STILL OCCUR. This means that the corruption simply must be happening down inside VPIF, below the conceptual level of my ioctl calls.
I believe I've subsequently gotten to the point of proving that it's an ARM processor busy problem. The corruption frequency increases dramatically during a periodic process that my application does in the foreground. Otherwise, the corruption seems synchronized with another particular process I'm doing once per second. When I comment out that process, the corruption goes away. The process shouldn't be touching the buffers used by VPIF, so I'm assuming the process is failing to yield and let VPIF do it's job in a timely manner.
Now, I don't see how the particular corruption imagery could happen. But nevertheless, it seems that I need to play with task or process priorities. And here I get lost. I don't know enough about linux to do this. Also, I'm not sure how to get at the process beneath the ioctl's, either. And I don't know if I'm on the right track for sure.
Please advise! Thanks.
Replies (6)
RE: Video output blinks frequently - Added by Jonathan Cormier over 11 years ago
Helmut,
First thing is which version of the kernel are you running?
uname -a
Also the command nice can be used to start applications in a lower priority.
http://www.manpagez.com/man/1/nice/
There is also a system call if you want to change the priority level inside code.
http://www.manpagez.com/man/2/setpriority/
RE: Video output blinks frequently - Added by Michael Williamson over 11 years ago
I suspect that you need to increase the bus master DMA priority of the VPIF or LCDC peripherals (it's not clear to me which output you are using, VPIF or LCDC, sounds like maybe VPIF).
You can read up about the priorities in the OMAP-L138 Technical Reference Manual section 11.3 (Master Priorities).
The VPIF and LCDC priorities are both fairly low by default, and if their FIFOs are starved then the output timing will stall and the result will be much like as you describe. If the ARM is doing intensive memory I/O, it will get priority over the other peripherals with the default priorities.
If you look in the baseboard-industrialio.c, there are some lines the modify the LCDC peripheral DMA output priority to the highest priority in the kernel configuration.
#define MSTPRI2_LCD_MASK 0x70000000 #define MSTPRI2_LCD_SHIFT 28 #define LCD_PRIORITY 0 /* make video output highest priority */ /* set peripheral master priority up to 1 */ prio = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_MSTPRI2_REG)); prio &= ~MSTPRI2_LCD_MASK; prio |= LCD_PRIORITY<<MSTPRI2_LCD_SHIFT; __raw_writel(prio, DA8XX_SYSCFG0_VIRT(DA8XX_MSTPRI2_REG));
You may need to do the same with the outbound VPIF module.
-Mike
RE: Video output blinks frequently - Added by Helmut Forren over 11 years ago
Mike:
Thanks for the advice. FYI, this is same project as Wade Calcutt is working on, regarding FPGA loading properly.
Bumping up bus master DMA priority sounds like that for which I'm looking. I looked at the TRM, and please confirm for me. We're discussing two different types of priorities here. The DMA priority is some kind of hardware priority. The priority I had been investigating before is a linux multitasking priority. Please confirm if it's indeed your suspicion, Mike, that this may be substantially a hardware priority issue, and that playing with linux process priorities is a wild goose chase. (This statement is within the constraints of the application still feeding fast enough. But remember, I made the application intentionally STOP feeding, leaving the 15 VPIF buffers with leftover content. The video continued to get played, with corruption occurring only once per sec or less. So it seems that the VPIF will happily reuse old buffers in this loop. I don't know if these buffers are the same as the FIFO you're talking about. I suspect they're different, and perhaps the DMA is actually transferring from the 15 buffers I mention to the FIFO you mention. Dunno yet. Still studying...)
-----------------
Jonathan:
Thanks for the advice. uname returns "Linux mityomapl138 2.6.34-rc1 #74 PREEMPT Fri Feb 1 09:02:10 EST 2013 armv5tejl unknown". I've tried playing with setpriority, but it didn't help. Also there seem to be 7 threads and I vaguely recall not knowing which was which or how to confirm I set priority on the correct one.
-Helmut
RE: Video output blinks frequently - Added by Helmut Forren over 11 years ago
Mike,
I'm using VPIF. It might also be the case that my interfering tasks are interfering because they're transferring 153600 byte buffers between the DSP and ARM, via proc_READ() and proc_WRITE(). These transfers are intended to be a "background" process, separate from our use of RingIO to transfer video data from the DSP to ARM.
So, perhaps you can hint me forward a bit. TRM table 11-1 tells me default priority 4 for VPIF DMA0 and VPIF DMA1. I gather that 0 is highest priority. What Master item corresponds to proc_READ() and proc_WRITE()? Also, do you have a guess as to whether I'll be able to set the RIngIO transfers to a middle level priority, higher than my proc_READ() and proc_WRITE(), but either the same or lower than VPIF DMA0/1? After all, I need RingIO and VPIF both to run smoothly at higher priorities, to get my video throughput cleanly. Then I need my "backgrouind" proc_READ() and proc_WRITE() to go as slow as need be to not interfere with clean video.
((I'll ask Wade for assistance on this SYSCFG programming that the TRM mentions. Unless, of course, you add some advice here...))
Thanks again,
Helmut
RE: Video output blinks frequently - Added by Helmut Forren over 11 years ago
FIXED! I changed VPIF DMA0/1 priority from 4 to 1 and the blinks went away. Thanks you, Mike.
-Helmut