Android from hardware to application: Step by Step 1, step by step android
Hardware Platform: TI AM335X Starter Kit
Development Source: TI-Android-ICS-4.0.3-DevKit-EVM-SK-3.0.1.bin
Host system: Ubuntu 10.04
In this writing, "Android from hardware to application" is intended to start with the simplest GPIO hardware driver at the underlying layer, step by step, and go through the Hardware Abstraction Layer HAL and JNI methods, finally, write out the APP to achieve the purpose of hardware calling. During this period, some details about the Android C program testing the underlying driver will be added. Since the driver is written from scratch, it is necessary to remove some existing api functions from the source code package, starting from the hardware circuit. Find the GPIO schematic of the EVM board:
I want to control the status of LED D1, as shown in. D1 is connected to Q4, that is, BSS138, nchannels' MOS device, AM335X_GPIO_LED4 is high-power, and the gate drain of Q4 is switched on. D1 is bright, otherwise, destroy. First, set the GPIO clock:
1. cm_per_gpiow.clkctrl: The address 0x44E000AC is 0x00040002
Then set the GPIO1 output enabling:
2. GPIO_OE: The address 0x4804C134 is 0x0.
Then set the output of GPIO1:
3. GPIO_DATAOUT: The address 0x4804C13C should be loaded with a value of 0x00000010 or 0x00000000, so that the AM335X_GPIO_LED4 pin is high or low, so that D1 can be highlighted
Write the driver android_gpio.c: Move to the drivers/char directory
#include <linux/module.h> #include <linux/kernel.h> #include <linux/fs.h> #include <linux/uaccess.h> /* copy_to_user,copy_from_user */ #include <linux/miscdevice.h> #include <linux/device.h> #include <asm/io.h> static struct class *gpio_class; volatile unsigned long *DIR; volatile unsigned long *DAT; volatile unsigned long *CLK; int gpio_open (struct inode *inode,struct file *filp) { *CLK = 0x00040002; //Enable *DIR = (*DIR)&0xffffffef; //output return 0; } ssize_t gpio_read (struct file *filp, char __user *buf, size_t count,loff_t *f_pos) { return 0; } ssize_t gpio_write (struct file *filp, const char __user *buf, size_t count,loff_t *f_pos) { char val_buf[2]; int ret; ret = copy_from_user(val_buf,buf,count); switch(val_buf[0]) { case 0x31 : *DAT = (*DAT)|0x00000010; break; case 0x30 : *DAT = (*DAT)&0xffffffef; break; default : break; } return count; } struct file_operations gpio_fops = { .owner = THIS_MODULE, .open = gpio_open, .read = gpio_read, .write = gpio_write, } ; int major; int gpio_init (void) { major = register_chrdev(0,"Android_gpio",&gpio_fops); gpio_class = class_create(THIS_MODULE, "Android_gpio"); device_create(gpio_class,NULL,MKDEV(major,0),NULL,"AdrIO"); DIR = (volatile unsigned long *)ioremap(0x4804C134,4); DAT = (volatile unsigned long *)ioremap(0x4804C13C,4); CLK = (volatile unsigned long *)ioremap(0x44E000AC,4); printk ("gpio is ready\n"); return 0; } void gpio_exit (void) { unregister_chrdev(major,"Android_gpio"); device_destroy(gpio_class,MKDEV(major,0)); class_destroy(gpio_class); iounmap(DIR); iounmap(DAT); iounmap(CLK); printk ("module exit\n"); return ; } MODULE_LICENSE("GPL"); module_init(gpio_init); module_exit(gpio_exit);
Open the Makefile in the drivers/char directory and add:
obj-$(CONFIG_ANDROID_GPIO)+= android_gpio.o
Open Kconfig in the drivers/char directory and add:
config ANDROID_GPIO tristate "android gpio enable" default y
Run the following command in the source code directory:
Make ARCH = arm CROSS_COMPILE = arm-eabi-uImage
Generate a uImage and restart the new system. Run ls/dev to view the device:
# ls /dev AdrIO alarm android_adb ashmem binder block bus
The first step is to complete the discovery of the AdrIO device. Note that you must perform operations on the physical address. Otherwise
GPIO1 will affect the LCD display of AM335X Starter Kit. The next step is to run the C program to test the driver.