cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
abbascit
Contributor
Contributor
12,967 Views
Registered: ‎12-30-2015

Write and read to device memory from user space

Hello,

 

I have a simple hardware with some registers. I have kernel driver for it. I know from kernel space i can write to some memory of hardware using iowrite32() and read using ioread32(). But i don,t know how i can send some value to kernel space from user space that will be written to hardware. I have following questions.

 

1.How i can send some values, array or any data from user space to kernel space?

 

2. Where(in which function) i should put these iowrite32() and ioread32() functiona in kernel space?

At time being i am using these functions in proble method and when i insert the module it writes and read from memory.

 

3. How i can access or handle intrrupt from user space??

 

Waiting for kind reply.

 

Regards

 

0 Kudos
10 Replies
Anonymous
Not applicable
12,914 Views

This is covered in depth by the kernel driver literature. When doing a char driver (I assume that is what your driver is), you need to implement the read and write file-operations, or add support for mmap. Then User-space can open your device node and read/write or mmap. I suggest referring to "Linux Device Drivers" book (LDD) for further information. User-space interrupts can be handled as a blocking read (probably in a thread) on the device node.

 

Stepping back though, you may actually find that UIO (userspace IO) is better suited to your application as it sounds like you are really trying to control the whole device from user-space. UIO is designed for this. UIO lets you register your device as being a UIO device, which creates a generic device node that can be mmapped and the read system call can be used for interrupts. Then you shouldn't not need to write a device driver all.

abbascit
Contributor
Contributor
12,754 Views
Registered: ‎12-30-2015

Hello pete_128,

 

Thanks for your help.

 

first two problems i have solved. 

 

But about third how i can access intrrupt from user space??

 

About UIO i read on UIO .

But i did not come to know that whether UIO will create different file on path sys/class/... or user should specify to create some file??

 

its mentioned that  /sys/class/uio/uio0/device/config will have intrrupt. so for every UIO it will be in this file or its different for different driver?

 

it has automatically generated this file or we have to specify that create this file for intrrupts.

 

I hope you will help me.

 

waiting for your kind reply.

 

Regards

 

Tags (2)
0 Kudos
Anonymous
Not applicable
12,745 Views

Hi,

 

So I think the instructions you linked for UIO are overkill. I think you can do it with no kernel code at all, that one assumes you still setup the UIO driver in a KO. Generic UIO should allow you to register your hardware as being UIO controlled using a DTS compatible string. Backing up a sec, what is the device tree node you have added for your IP? It should have UIO in it somewhere, and connect your interrupts to the interrupt controller. Hopefully the device tree UIO capability is enabled in your Kernel by default so it just probes.

 

Once you have UIO you just do a read on the open file for /dev/uio to wait for an interrupt. You shouldn't need to be in /sys/class except if you are looking for read-only information.

0 Kudos
abbascit
Contributor
Contributor
12,742 Views
Registered: ‎12-30-2015

Hi pete_128,

 

Really thanks for your help.

 

I have a IP with reg = <0x43c00000 0x10000>; it is connect with axi DMA IP to write data to DDR. So i have to grep DMA interrupt in user space. So to get interrupt i have to read from 4th byte location of file  /dev/uio ? 

 

One thing more i have to include an axi timer IP to calculate the time takken by my custom IP to perform algorithm. So i will also need driver for axi timer IP? 

0 Kudos
Anonymous
Not applicable
12,739 Views

Hi,

 

Paste more - paste the whole node. It should have an interrupt string as well as a compatible string.

 

Not sure where the timer fits in. can't you just use the kernel's sense of time to time everything is software. If that is not accurate enough, than that means you have your timer connected up to hardware triggers and events. Its difficult for a generic kernel timer driver to make sense of this (they are generally written to providing timing services for the Kernel itself), so I would just UIO that as well, as the timer is a simple IP to manage.

0 Kudos
abbascit
Contributor
Contributor
12,678 Views
Registered: ‎12-30-2015

Hello pete_128,

 

I have attached file having complete PL part.

 

 

0 Kudos
Anonymous
Not applicable
12,594 Views

/*
 * CAUTION: This file is automatically generated by Xilinx.
 * Version:  
 * Today is: Sun Apr 17 23:23:38 2016
*/


/ {
	amba_pl: amba_pl {
		#address-cells = <1>;
		#size-cells = <1>;
		compatible = "simple-bus";
		ranges ;
		axi_dma_0: dma@40400000 {
			#dma-cells = <1>;
			compatible = "xlnx,axi-dma-1.00.a";
			interrupt-parent = <&intc>;
			interrupts = <0 29 4>;
			reg = <0x40400000 0x10000>;
			dma-channel@40400030 {
				compatible = "xlnx,axi-dma-s2mm-channel";
				dma-channels = <0x1>;
				interrupts = <0 29 4>;
				xlnx,datawidth = <0x20>;
				xlnx,device-id = <0x0>;
			};
		};
		testIP_0: testIP@43c00000 {
			compatible = "xlnx,testIP-1.0";
			reg = <0x43c00000 0x10000>;
			xlnx,s-axi-axilites-addr-width = <0x6>;
			xlnx,s-axi-axilites-data-width = <0x20>;
		};
	};
};

So your custom IP is not defining its own interrupt. Does it have an interrupt source that is connected? This is what I would expect. To get UIO working you set the compatible string to "generic-uio". You would then have an interrupts tuple for you IPs interrupt matching its connection to GIC.

0 Kudos
abbascit
Contributor
Contributor
12,578 Views
Registered: ‎12-30-2015

Hi pete_128,

 

Thanks for your reply.

 

I want to handle interrupt that is in generated by axi DMA. For time being my IP is not generating any interrupt.

 

So only i want interrupt handler for DMA interrupt.

 

 

0 Kudos
Anonymous
Not applicable
12,544 Views

Ah!

 

Do you want to just control the whole lot as registers from userspace?

 

In that case, change the compat string of both to "generic-uio", then you will get two UIO nodes for each IP. Open both in your program and read/write registers as normal.

 

Controlling a DMA from userspace is tricky though, as you need to program the DMA with physical addresses of memory for data buffers. Userspace does not have access to allocated memorys phy addresses so you would need to either pre-allocate physical memory (a common solution) or you will need some kernel-side help.

 

Its not clear to me how much you want to control from userspace and how much from kernel space. But it would be odd to try and have the kernel control the DMA yet have userspace intercept the interrupt. If you want the kernel to control the DMA (which will use the interrupt) you may find it easiest to just split the wire in hardware and make yourself a second read-only interrupt for your device that is really just the DMA interrupt.

 

HTH

0 Kudos
abbascit
Contributor
Contributor
9,223 Views
Registered: ‎12-30-2015

Hi,

 

I have attached the snapshot of my hardware. My testIp is connect to GPO. Output of testIp is a stream interface which is connected to dma s2MM.

So it is really simple. I just want to trasfer data from testIp to DMA that will write data to DDR.

 

For that i have to configure DMA and handle the interrupt that it generates . I should also write to register of testIp so it will sends data to DMA. 

 

So should i use "generic-uio" or how i can do this? I found a driver for dma at Driver_LINK. so it should use this driver?

ultimately my goal is to give input to my testIp and it will send data to DMA that will move finally data to DDR. DMA will generate interrupt so i have to handle access the interrupt from user space.

Waiting for your kind reply.

test_setup.JPG
0 Kudos