Objective
Recently in Reading Luo Shenyang's "Android system source code scenario analysis," I believe that many people who engage in Android will go to see the book, then for the second chapter of the hardware abstraction layer, contact the actual work, it is necessary to learn something to do a summary analysis. Of course, this part will be based on Lao Luo's book of Ideas one by one to uncover the veil of hardware abstraction layer.
File System interface
The general kernel layer exposes the interface to the user layer for user space to use. Broadly, they can be divided into three categories.
- Proc File System interface
- Legacy Device File System interface
- DEVFS File System interface
Where the proc file system interface and the traditional device file system interface same strain, they can make a more complete file system interface.
Proc File system interface with legacy Device file system interface
It is composed of traditional device file operation method and traditional device file operation method table FoPs. Lao Luo in the book with freg.c this file to explain, but actually in the use of the process still need to understand the people themselves.
Here I will use the Charger interface I wrote as an example to analyze.
When you see the static int smbchg_probe (struct spmi_device *spmi) function, you have it call the CREATE function directly to create a file system interface.
create_batt_voltage_proc_file();
And look at the definition of the function.
static create_batt_voltage_proc_file(void){ 0644NULL, &batt_voltage_fops); if (batt_voltage_proc_file) { printk("[Proc]%s sucessed!\n"__FUNCTION__); else{ printk("[Proc]%s failed!\n"__FUNCTION__); }}
As you can see, the main task is to mount the FoPs. Retrace
#define batt_voltage_PROC_FILE "batt_voltage_now"staticconststruct file_operations batt_voltage_fops = { .owner = THIS_MODULE, .open = batt_voltage_proc_open, .read = seq_read, .release = single_release,};
FoPs has appeared, in fact he will hang on the load/porc/batt_voltage_now, which is attributed to the function proc_create (Batt_voltage_proc_file, 0644, NULL, &batt_voltage _fops); Of course not seen here
See open below.
staticint batt_voltage_proc_open(structstruct file *file){ returnNULL);}
Its main purpose is to callback Single_open (file, Batt_voltage_proc_read, NULL); Batt_voltage_proc_read in.
StaticintBatt_voltage_proc_read (struct seq_file*buf, void*v){intRET =-1; struct power_supply*psy; Union Power_supply_propval Val;intvoltage_now=0; Psy = Get_psy_battery (); ret = Psy->get_property (psy, Power_supply_prop_voltage_now, &val);if(!ret) {Voltage_now = Val.intval/ +; seq_printf (BUF,"%d\ n", Voltage_now); }Else{PRINTK ("%s: Can ' t get voltage_now, ret = %d!\n", __function__, ret); Voltage_now = ret; }return 0;}
This way you can see that the main function of this function is to divide the voltage value by 1000 and pass it back to the interface.
Summary: The core idea is to mount the FoPs.
DEVFS File System interface
Let's take hall_sensor as an example.
static0664, show_action_status, store_action_status);staticstruct attribute *hall_sensor_attrs[] = { &dev_attr_status.attr, NULL};staticstruct attribute_group hall_sensor_group = { .name"hall_sensor", .attrs = hall_sensor_attrs};
This code has clearly shown what needs to be erected. Build the Devfs file system through device_attr. and provide the relevant operation node Show_action_status, Store_action_status.
/*=========================== *| | Sysfs device_attr Part | | *=========================== * */Staticssize_t Show_action_status (structDevice *dev,structDevice_attribute *attr,Char*BUF) {if(!hall_sensor_dev)return sprintf(BUF,"Hall sensor does not exist!\n");return sprintf(BUF,"%d\n", hall_sensor_dev->status);}Staticssize_t Store_action_status (structDevice *dev,structDevice_attribute *attr,Const Char*buf, size_t count) {intRequestunsigned LongFlags//if (!hall_sensor_dev) //Return sprintf (buf, "Hall sensor does not exist!\n"); sscanf(BUF,"%du", &request); Spin_lock_irqsave (&hall_sensor_dev->mhallsensorlock, flags);if(!request) Hall_sensor_dev->status =0;ElseHall_sensor_dev->status =1; Spin_unlock_irqrestore (&hall_sensor_dev->mhallsensorlock, flags);Log("[ATTR] status Rewite value =%d\n",!hall_sensor_dev->status);returnCount;}
I cannot analyze its specific functions here. But the idea is to do the act of mounting.
Subsequent
Of course here I just will kernel part of the node way to do a brief introduction, the time to hardware,framwork layer how to work on the complement.
Reference Blog
How to use Proc_create
The difference between proc_create and Create_proc_entry
About Android (6) Hardware Abstraction Layer Kernel analysis