LinuxQuestions.org
Visit the LQ Articles and Editorials section
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Hardware > Linux - Embedded & Single-board computer
User Name
Password
Linux - Embedded & Single-board computer This forum is for the discussion of Linux on both embedded devices and single-board computers (such as the Raspberry Pi, BeagleBoard and PandaBoard). Discussions involving Arduino, plug computers and other micro-controller like devices are also welcome.

Notices

Reply
 
Search this Thread
Old 06-13-2013, 03:48 PM   #1
tseiman
LQ Newbie
 
Registered: Jun 2013
Posts: 2

Rep: Reputation: Disabled
Framebuffer driver for SPI driven display, memory allocation and handling


Hello,

I'm not sure whether this or the kernel forum is right...

My actual problem occurs in a framebuffer driver i write to drive a SPI controlled 2BPP greyscale LCD.
From the bunch of challenges i face this one is the most problematic:

From several examples and drivers come with linux kernel i copied the driver skeleton as well as of how to allocate the Video Memory:

In the framebuffer probe function i allocate RAM as frame buffer:
Here some extraction of it:

Code:
static int __devinit dogxl160fb_probe (struct spi_device *spi)
{
u8 *vmem; ... vmem = vzalloc(vmem_size_in); /* vmem_size_in= WIDTH*HEIGHT*BPP_INPUT/8, WIDTH=160, HEIGHT=104, BPP_INPUT=16 */ if (!vmem) return retval; info = framebuffer_alloc(sizeof(struct dogxl160fb_par), &spi->dev); if (!info) goto fballoc_fail; info->screen_base = (u8 __force __iomem *)vmem; ...
}
when the frame buffer is updated by some user space process i have a update function which writes the vmem to SPI:


Code:
static void dogxl160fb_update_display(struct dogxl160fb_par *par)
{
... u8 *vmem = par->info->screen_base; ... /*WIDTH=160, HEIGHT=104, BPP_OUPUT=2 */ dogxl160fb_write_data(par, vmem, WIDTH*HEIGHT*BPP_OUTPUT/8);
Code:
static void dogxl160fb_write_data(struct dogxl160fb_par *par, void *txbuf, size_t size)
{
... /* Set data mode */ gpio_set_value(par->dc, 1); spi_write(par->spi, txbuf, size);
}
Sure the input (vmem) buffer matches not exactly the byte stream i need on the display (wrong pixel format, wrong order etc.) but i expected to see at least some noise on the display.
Instead of that the kernel crashes always when i try to send vmem (or a copy from it) via spi_write function.

Analyzing the stack trace with GDB shows me that it crashes with the call of write_data function, or if i try to access vmem in the update function but only when I call spi_write

I thought also about the possibility that it could be a user space / kernel space memory problem and tried to copy_from_user() int another buffer. but that does not really help either (sometimes the module does not crash then but i don't have valid data).

The Platform is a ARM processor (ARM926EJ) on a NXP EA313X with 32MB RAM and a linux 3.3.0 kernel (from vendor of the board with the CPU and RAM already for IOs patched).

If there is any help or helpful idea out - would be great - i have spent already several weeks trying to understand where it fails ...

Thanks
Best Regards
Thomas S.

Last edited by tseiman; 06-13-2013 at 05:15 PM.
 
Old 06-23-2013, 03:32 PM   #2
Mara
Moderator
 
Registered: Feb 2002
Location: Grenoble
Distribution: Debian
Posts: 9,533

Rep: Reputation: 148Reputation: 148
Please re-check or post your spi initialization code (in the probe function, probably). Also, I'd try with a constant buffer with zeros. If it fails, it is rather the SPI configuration, not the memory you pass it. That part looks OK for me.

To transfer from user space, check get_user_pages(), this way it is usually faster than copy_from_user(). However, you have some more things to do to make it work.
 
Old 06-23-2013, 06:51 PM   #3
tseiman
LQ Newbie
 
Registered: Jun 2013
Posts: 2

Original Poster
Rep: Reputation: Disabled
Hello,
many thanks for your reply !

after tons of retries changes and testing I got it to work now. But it is fully unclear why it is working now and why it was not working before. Apparently I have not changed too much...

The problem was (IS !) definitively the memory allocation and handling. I figured later out that I could send over SPI by sending from a hardcoded buffer e.g.:

Code:
char buffer[] = { 0x1, 0x2,... };
I know that this is not a good coding style, but it worked for small tests. As well I got it working recently to send out directly from the vmem buffer which is allocated with vzalloc in dogxl160fb_probe. However since I need a very special pixel format i need to copy the bytes from the video memory "vmem" to another buffer. An again I was in trouble:
I could not use a second buffer allocated with vzalloc - I'm using kmalloc(vmem_size_out,GFP_KERNEL); now. With vzalloc the kernel crashes in the same way as before.

Main reason why it works now in my opinion could be:
  • using schedule_delayed_work to update the display on the deferred way
  • copy the memory from a vzalloc allocated memory to a memory which is allocated by kmalloc with GPF_KERNEL

I'm very sure that the main problem is that I'm not clear how memory is handled in kernel and how I have in which situation access to it. Unfortunately I cannot find documentation which is realy clear to me ...

I have uploaded the driver sources which is working now (somehow). There are still some things to do (for example I have hardcoded the struct dogxl160fb_data or dogxl160fb_configuration) which is, as far I know, bad coding style and I should alloc and initialize them - however I tried to vzalloc or kmalloc it with the correct struct size and than initialize it - but than again it crashes when accessing the allocated memory.

Documentation is a big problem I think - many examples do things in complete different manner (and in a way which is marked as a definitively bad way in kernel code skeletons) - and this does not necessarily help to find the "right" way.

Again thanks for your post - and sorry that i have not updated to the last state - but there was so long silence - that I thought that i'm just for my self ;-)

BR
Thomas

Last edited by tseiman; 06-23-2013 at 06:56 PM.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Can i register a ssc driver (a serial interface device) to be a spi driver ? 5883 Programming 0 03-04-2012 06:14 PM
Application Virtual address space memory allocation - memory does not get free chamara82 Linux - General 4 01-01-2011 08:19 PM
Invalid memory allocation display corrupted Andknig Linux - Newbie 2 04-27-2005 03:32 PM
memory allocation docGonzo2000 Linux - General 1 05-16-2003 09:24 PM
memory allocation, application<-->driver charlies Programming 2 03-03-2001 11:26 PM


All times are GMT -5. The time now is 04:37 AM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration