編輯:關於Android編程
最近在拜讀羅升陽的《Android系統源代碼情景分析》一書,相信有許多搞android系統的人會去看看本書,那麼針對於第二章的硬件抽象層,聯系一下實際的工作,有必要將自己學習的東西做一個總結分析。當然這部分將依據老羅的書的思路一一揭開硬件抽象層的面紗。
一般kernel層會給用戶層暴露相關的接口供用戶空間去使用。大致上可以被分為三類。
proc文件系統接口 傳統設備文件系統接口 devfs文件系統接口其中proc文件系統接口與傳統設備文件系統接口一脈相承,它們和起來才能做一個較為完善的文件系統接口。
它是由傳統設備文件操作方法與傳統設備文件操作方法表fops組成。老羅一書中用了freg.c這個文件來做解釋的,但實際真正在使用過程中還需大家自己去體悟。
在這裡將通過我自己寫的charger接口作為例子進行分析。
看到static int smbchg_probe(struct spmi_device *spmi)函數,會讓其直接調用create函數來創建一個文件系統接口。
create_batt_voltage_proc_file();
然後看這個函數的定義
void static create_batt_voltage_proc_file(void)
{
batt_voltage_proc_file = proc_create(batt_voltage_PROC_FILE, 0644, NULL, &batt_voltage_fops);
if (batt_voltage_proc_file) {
printk("[Proc]%s sucessed!\n", __FUNCTION__);
} else{
printk("[Proc]%s failed!\n", __FUNCTION__);
}
}
可以看到,其主要工作是將fops掛載上去。按圖索骥。
#define batt_voltage_PROC_FILE "batt_voltage_now"
static const struct file_operations batt_voltage_fops = {
.owner = THIS_MODULE,
.open = batt_voltage_proc_open,
.read = seq_read,
.release = single_release,
};
fops已經出現了,其實他會掛在載/porc/batt_voltage_now,這都得歸功於函數proc_create(batt_voltage_PROC_FILE, 0644, NULL, &batt_voltage_fops);當然在這裡沒有看到
下面看open。
static int batt_voltage_proc_open(struct inode *inode, struct file *file)
{
return single_open(file, batt_voltage_proc_read, NULL);
}
其主要就是為了回調single_open(file, batt_voltage_proc_read, NULL);中的batt_voltage_proc_read。
static int batt_voltage_proc_read(struct seq_file *buf, void *v)
{
int ret = -1;
struct power_supply *psy;
union power_supply_propval val;
int voltage_now=0;
psy = get_psy_battery();
ret = psy->get_property(psy, POWER_SUPPLY_PROP_VOLTAGE_NOW, &val);
if (!ret) {
voltage_now = val.intval / 1000;
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;
}
這樣就可以看到這個函數的主要功能就是將電壓值除以1000後回傳給接口。
小結一下:其核心思想就是為了將fops掛載上去。
我們以hall_sensor為例。
static DEVICE_ATTR(status, 0664, show_action_status, store_action_status);
static struct attribute *hall_sensor_attrs[] = {
&dev_attr_status.attr,
NULL
};
static struct attribute_group hall_sensor_group = {
.name = "hall_sensor",
.attrs = hall_sensor_attrs
};
這段code已經清晰顯示需要架設的東西了。通過DEVICE_ATTR去建立devfs文件系統。並提供相關的操作節點show_action_status, store_action_status。
/*===========================
*|| sysfs DEVICE_ATTR part ||
*===========================
*
*/
static ssize_t show_action_status(struct device *dev,struct device_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);
}
static ssize_t store_action_status(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
int request;
unsigned long flags;
//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;
else
hall_sensor_dev->status = 1;
spin_unlock_irqrestore(&hall_sensor_dev->mHallSensorLock, flags);
log("[ATTR] status rewite value = %d\n",!hall_sensor_dev->status);
return count;
}
在此我不便分析其具體功能。但其思想便是做掛載的動作。
當然在這裡我僅僅是將kernel部分的節點方式做了簡單介紹,抽空將hardware,framwork層如何工作的補上。
簡述:相信很多學安卓的都是從java入門之後開始進行安卓的學習,而當我們面臨安卓線程的書寫的時候,發現安卓線程並不是我們想象中使用java的線程寫法就可以。java線程的
關於Windows下Android開發環境搭建、配置方面文章,網上一搜一堆,為方便以後參考,權且做個記錄,主要關注安裝過程中的注意事項。對新手提醒的是,本文
一.兄弟Layout_height為fill_parent本來准備編寫一款簡單的計算器,來學習android,遇到了多個兄弟Layout區域按照一個比例大小來顯示的技術問
Android開發本質上就是手機和web服務器之間進行通信,從服務端需要獲取數據,但是當訪問的數據比較大,比較多,並且是重復數據時,會極大影響性能,甚至應用崩潰,手機卡死