Reputation: 627
I'm working on Raspberry PI (Linux rpi 3.12.28+) and I have the following C code that I can use to manipulate GPIO ports:
// IO Acces
struct bcm2835_peripheral {
unsigned long addr_p;
int mem_fd; // memory file descriptor
void *map;
volatile unsigned int *addr;
};
struct bcm2835_peripheral gpio = {0x40000000};
// Exposes the physical address defined in the passed structure using mmap on /dev/mem
int map_peripheral(struct bcm2835_peripheral *p)
{
// Open /dev/mem
if ((p->mem_fd = open("/dev/mem", O_RDWR | O_SYNC) ) < 0) {
return -1;
}
p->map = mmap(
NULL,
BLOCK_SIZE,
PROT_READ | PROT_WRITE,
MAP_SHARED,
p->mem_fd, // File descriptor to physical memory virtual file '/dev/mem'
p->addr_p // Address in physical map that we want this memory block to expose
);
if (p->map == MAP_FAILED) {
return -1;
}
p->addr = (volatile unsigned int *)p->map;
return 0;
}
Above code works fine for normal programs (user space). But I need to create a Linux kernel module that will do the same. The problem is that compiler doesn't recognize methods like open() or mmap(). What is an appropriate approach to convert this code to the kernel module (driver)? Are these functions available for kernel programming or should I do that in a different way? I've seen methods like syscall_open(), filp_open(), sys_mmap2() but I'm confused. I will appreciate any help.
Upvotes: 0
Views: 5187
Reputation: 627
It is true that there is no need to access /dev/mem
in kernel modules. Accessing memory directly using phys_to_virt
is a solution to manipulate memory, but it will not work on Raspberry PI if the goal is to manipulate GPIO ports.
The solution is to access hardware registers. I have found excellent tutorial here:
Creating a Basic LED Driver for Raspberry Pi
Upvotes: 0
Reputation: 2967
You don't have system calls (open, close, read, write, etc..) in kernel space, instead, you'd have to use the internal interfaces provided by the modules, but seems that is not your case.
Considering you are accessing /dev/mem
I suppose you are trying to read the physical memory of the RaspberyPi. From kernel space you can access it directly since there's no memory protection, but, you'd have to use phys_to_virt
function to translate the addresses.
Upvotes: 2