There are two ways I know about working with Gpio under Linux:
1. Writing the driver, of course, familiar with the Linux driver writing methods and techniques, in the driver can use the IOREMAP function to obtain the GPIO physical base address pointer, and then use this pointer to the IOCTL command to read and write the Gpio register, and send the results back to the application layer. Here is a little piece of the program for everyone to refer to:
int Init_module (void) {
PRINTK (kern_alert "IOCTL load.\r\n");
Register_chrdev (254, "Ioreg", &fops);
Stb_gpio = (Stbx25xx_gpio_reg *) Ioremap (Gpio_base,gpio_len);
if (Stb_gpio = = NULL) {
PRINTK (Kern_alert "can" t get io base.\r\n ");
return-1;
}
return 0;
}
int Io_ioctl (struct inode *inode, struct file *filp,unsigned int cmd, unsigned long arg) {
unsigned long ugpio;
PRINTK (kern_alert "Io_ioctl cmd=%04x,arg=%04x.\r\n", cmd, (int) arg);
Switch (CMD) {
Case set_io_dir:{
PRINTK (Kern_alert "set_io_dir\r\n");
Break
}
Case set_io_value:{
PRINTK (Kern_alert "set_io_value\r\n");
Break
}
Case get_io_value:{
PRINTK (Kern_alert "get_io_value\r\n");
Ugpio = stb_gpio->gpi;
PRINTK (kern_alert "GPIO =%08x", (int) ugpio);
Copy_to_user (void *) arg, (const void *) &ugpio,sizeof (Ugpio));
Break
}
Case get_io_dir:{
PRINTK (Kern_alert "get_io_dir\r\n");
Break
}
}
return 0;
}
2. At the application layer use the MMAP function at the application layer to obtain the virtual address pointer of the GPIO physical base site, and then use this pointer to read and write the Gpio register, here is a bit of program snippet for everyone to refer to:
Char dev_name[] = "/dev/mem";
Gpio_register *gpio_base;
FD = open (DEV_NAME,O_RDWR);
if (fd<0) {
printf ("Open%s is error\n", dev_name);
return-1;
}
Gpio_base = (Gpio_register *) mmap (0, 0x32, Prot_read | Prot_write, MAP_SHARED,FD, 0x40060000);
if (gpio_base = = NULL) {
printf ("Gpio base mmap is error\n");
Close (FD);
return-1;
}
Gpio_base->or = (Gpio_base->or & 0x7fffffff);
Mmap
Function Description:
Mmap maps a file or other object into memory. Files are mapped to multiple pages, and if the size of the file is not the sum of the size of all pages, the space that is not used by the last page will be zeroed out. Munmap performs the opposite operation by deleting the object mappings for a specific address area.
File-based mappings, st_atime of mapped files may be updated at any point during mmap and Munmap execution. If the St_atime field is not updated in the preceding scenario, the value of the field is updated the first time the first page of the map area is indexed. A file map built with the Prot_write and map_shared flags, its st_ctime and st_mtime
After the mapping area is written, but before Msync () is called through Ms_sync and Ms_async two flags are updated.
Usage:
#include <sys/mman.h>
void *mmap (void *start, size_t length, int prot, int flags,
int FD, off_t offset);
int Munmap (void *start, size_t length);
Parameters:
Start: The starting address of the map area.
Length: The size of the map area.
Prot: Expected memory protection flag, cannot conflict with open mode of file. is one of the following values that can be reasonably grouped together by an OR operation
Prot_exec//page content can be executed
Prot_read//page content can be read
Prot_write//page can be written
Prot_none//Page not accessible
Flags: Specifies the type of the mapped object, and whether the mapping options and mapping pages can be shared. Its value can be a combination of one or more of the following bits
Map_fixed//Using the specified mapping start address, if the memory area specified by the start and Len parameters overlap the existing mapping space, the overlapping portions will be discarded. If the specified start address is not available, the operation will fail. And the start address must fall on the boundary of the page.
Map_shared//share the mapping space with all other processes that map this object. Writes to the shared area are equivalent to outputting to a file. The file is not actually updated until Msync () or Munmap () is called.
Map_private//Create a private mapping of a write-time copy. The write to the memory area does not affect the original file. This flag is mutually exclusive to the above logo and can only be used with one.
Map_denywrite//This flag is ignored.
Map_executable//Ibid.
Map_noreserve//Do not reserve swap space for this mapping. When the swap space is preserved, modifications to the map area may be guaranteed. When the swap space is not preserved and the memory is low, modifications to the mapping area can cause a segment violation signal.
map_locked//Locks the page of the map area, thus preventing the page from being swapped out of memory.
Map_growsdown//For the stack, telling the kernel VM system that the mapping area can be scaled down.
Map_anonymous//Anonymous mapping, the map area is not associated with any files.
Map_anon//map_anonymous's nickname, no longer used.
Map_file//compatible flag, ignored.
Map_32bit//The mapping area is ignored when the low 2gb,map_fixed of the process address space is specified. Currently this flag is only supported on the X86-64 platform.
Map_populate//Prepare the page table for file mapping by pre-reading. Subsequent access to the map area is not blocked by page violations.
Map_nonblock//is only meaningful when used with map_populate. Does not perform a read-ahead, only creates a page table entry for a page that already exists in memory.
FD: A valid file description word. If Map_anonymous is set, the value should be-1 for compatibility issues.
Offset: The starting point for the content of the mapped object.
Return Description:
When executed successfully, MMAP () returns a pointer to the mapped area, and Munmap () returns 0. On Failure, mmap () returns map_failed[whose value is (void *) -1],munmap returns-1. Errno is set to one of the following values
Eacces: Access Error
Eagain: The file is locked, or too much memory is locked
EBADF:FD is not a valid file description word
EINVAL: One or more parameters are invalid
Enfile: The system has reached the limit of open files
Enodev: The file system where the specified file resides does not support memory mapping
ENOMEM: Insufficient memory, or the process has exceeded the maximum number of memory mappings
Eperm: Insufficient power, operation not allowed
Etxtbsy: Open file in written mode, specifying Map_denywrite flag
SIGSEGV: Try writing to the read-only area
Sigbus: Try to access memory areas that are not part of the process
Linux under Operation Gpio (two methods, drive and Mmap) (reprint)