- 在config裡勾選
CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y CONFIG_LEDS_GPIO=y CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGER_TIMER=y
- 在board-*.c 裡面建立platform_device
static struct gpio_led gpio_leds[] = { { .name = "WHITE_LED",//should change to your own .gpio = _GPIO_1, //should change to your own .active_low = 1, .default_trigger = "timer", }, }; static struct gpio_led_platform_data gpio_led_info = { .leds = gpio_leds, .num_leds = ARRAY_SIZE(gpio_leds), }; static struct platform_device leds_gpio = { .name = "leds-gpio", .id = -1, .dev = { .platform_data = &gpio_led_info, }, }; //記得要在類似init加入--> platform_device_register(&leds_gpio); - 實做platform_driver
基本上依我的板子為例,platform_driver的實做已經在driver/leds/leds-gpio.c裡面做好了 不需要更改
- 修改LED HAL
以我的版為例,修改的是libleds.c 在 static int open_lights(const struct hw_module_t *module, char const *name, struct hw_device_t **device) 裡面新增了 }else if(0 == strcmp(LIGHT_ID_BATTERY, name)){ set_light = set_light_battery; } 然後因為我的led是gpio led, 只支援on/off ,沒有brightness level, Android定義了不同的level會有不同的顏色或閃爍 因此我的實做為 static int set_light_battery(struct light_device_t *dev, struct light_state_t const *state) { int err = 0; int flashmode=state->flashMode; pthread_mutex_lock(&g_lock); //set flash if(flashmode==1){ err = write_str("/sys/class/leds/PMU_LED/trigger","timer"); err = write_int("/sys/class/leds/PMU_LED/delay_on",250); err = write_int("/sys/class/leds/PMU_LED/delay_off",150); }else if(state->color ==0xffffff00||state->color ==0xffff0000||state->color ==-256){ err = write_str("/sys/class/leds/PMU_LED/trigger","none"); err = write_int("/sys/class/leds/PMU_LED/brightness",0); }else if(state->color ==0xff00ff00||state->color ==0x0){ err = write_str("/sys/class/leds/PMU_LED/trigger","none"); err = write_int("/sys/class/leds/PMU_LED/brightness",255); } pthread_mutex_unlock(&g_lock); return err; }
2012年3月23日 星期五
Android LED Implementation
2012年3月22日 星期四
Android Conditional Compilation( JAVA)
我們都知道JAVA其實是不支援條件式編譯的 例如在C/C++
所以我的方法是,在JAVA的地方產生一個JAVA檔,內容為
在其他的程式碼裡就可以:
這樣應該可以達到類似的目的了
#ifdef CONFIG_XXX_YYY
...
#ENDIF
$ gcc xxx.c -DCONFIG_XXX_YYY
所以我的方法是,在JAVA的地方產生一個JAVA檔,內容為
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
public class ConditionFlag {
public static final Set ConditionConfig;
static {
HashSet config =new HashSet();
config.put("CONFIG_XXX_YYY");
ConditionConfig = Collections.unmodifiableSet(config);
}
}
在其他的程式碼裡就可以:
if(ConditionFlag.ConditionConfig.Contains("CONFIG_XXX_YYY")){
...
}
這樣應該可以達到類似的目的了
repo 常用指令
- 取得source
$ repo init -u [address] -b [branch]
- 更換remote branch
$ repo init -b [branch]
- 建立/跳轉local branch
$ repo start [branch] [dir] or $ repo start --all [branch]
- 清除未進track的檔案
$ repo forall -c git clean -fdD
- 清除未commit 檔案
$ repo forall -c git reset --hard HEAD
- 取得 repository status
$ repo status
- 清除未commit 檔案
$ repo forall -c git reset --hard HEAD
completion
在Linux kernel 中我們可以使用completion來等待某樣事情完成
ex.
ex.
#include linux/completion.h
struct completion comp;
void module_init{
//初始化my_completion, set comp.done=0
init_completion(&comp);
}
ssize_t complete_read (struct file *filp, char __user *buf, size_t count, loff_t *pos)
{
//等待所有的comp 都被complete.
wait_for_completion(&comp);
printk(KERN_DEBUG "awoken %i (%s)\n", current->pid, current->comm);
return 0; /* EOF */
}
ssize_t complete_write (struct file *filp, const char __user *buf, size_t count, loff_t *pos)
{
complete(&comp);
return count; /* succeed, to avoid retrial */
}
kmalloc()
- void * kmalloc (size_t size, int flags) : 在kernel配置記憶體位置
- INCLUDE :include/linux/slab.h
- FLAG:
flags:
Action Modifiers( 通常使用後面提到的type modifier)
__GFP_WAIT
|
The allocator can sleep.
|
__GFP_HIGH
|
The allocator can access emergency pools.
|
__GFP_IO
|
The allocator can start physical I/O.
|
__GFP_FS
|
The allocator can start filesystem I/O.
|
__GFP_COLD
|
The allocator should use cache cold pages.
|
__GFP_NOWARN
|
The allocator will not print failure warnings.
|
__GFP_REPEAT
|
The allocator will repeat the allocation if it fails, but the allocation can potentially fail. This depends upon the particular VM implementation.
|
__GFP_NOFAIL
|
The allocator will indefinitely repeat the allocation. The allocation cannot fail.
|
__GFP_NORETRY
|
The allocator will never retry if the allocation fails.
|
__GFP_COMP
|
Add compound page metadata. Used internally by thehugetlb code.
|
__GFP_ZERO
|
Add compound page metadata. Used internally by thehugetlb code.
|
__GFP_NOMEMALLOC
|
Don't use emergency reserves.
|
__GFP_HARDWALL
|
Enforce hardwall cpuset memory allocs.
|
__GFP_THISNODE
|
No fallback, no policies.
|
__GFP_RECLAIMABLE
|
Page is reclaimable.
|
__GFP_NOTRACK
|
Don't track with kmemcheck.
|
__GFP_NO_KSWAPD
| |
__GFP_OTHER_NODE
|
On behalf of other node.
|
Example:
ptr = kmalloc(size, __GFP_WAIT | __GFP_IO | __GFP_FS);
Zone Modifiers ( 選擇要從哪分配空間 預設是從ZONE_NORMAL)
__GFP_DMA
|
Allocate only from ZONE_DMA
|
__GFP_HIGHMEM
|
Allocate from ZONE_HIGHMEM or ZONE_NORMAL
|
__GFP_DMA32
| |
__GFP_MOVABLE
|
Type Flags( 定義了action 及 zone modifier)
GFP_ATOMIC
| |
GFP_NOIO
| |
GFP_NOFS
| |
GFP_KERNEL
| |
GFP_USER
| |
GFP_HIGHUSER
| |
GFP_DMA
|
This is an allocation from ZONE_DMA. Device drivers that need DMA-able memory use this flag, usually in combination with one of the above.
|
以下列出各Type modifier的組合:
GFP_ATOMIC
|
__GFP_HIGH
|
GFP_NOIO
|
__GFP_WAIT
|
GFP_NOFS
|
(__GFP_WAIT | __GFP_IO)
|
GFP_KERNEL
|
(__GFP_WAIT | __GFP_IO | __GFP_FS)
|
GFP_USER
|
(__GFP_WAIT | __GFP_IO | __GFP_FS)
|
GFP_HIGHUSER
|
(__GFP_WAIT | __GFP_IO | __GFP_FS | __GFP_HIGHMEM)
|
GFP_DMA
|
__GFP_DMA
|
建議的用法:
Situation
|
Solution
|
|---|---|
Process context, can sleep
|
Use GFP_KERNEL
|
Process context, cannot sleep
|
Use GFP_ATOMIC, or perform your allocations with GFP_KERNEL at an earlier or later point when you can sleep
|
Interrupt handler
|
Use GFP_ATOMIC
|
Softirq
|
Use GFP_ATOMIC
|
Tasklet
|
Use GFP_ATOMIC
|
Need DMA-able memory, can sleep
|
Use (GFP_DMA | GFP_KERNEL)
|
Need DMA-able memory, cannot sleep
|
Use (GFP_DMA | GFP_ATOMIC), or perform your allocation at an earlier point when you can sleep
|
Example:
char *reloc_lp0;
reloc_lp0 = kmalloc(size,GFP_KERNEL);
WARN_ON(!reloc_lp0);
if (!reloc_lp0) {
pr_err("%s: Failed to allocate reloc_lp0\n",__func__);
goto out;
}
...
kfree(reloc_lp0);
Reference:
include/linux/gfp.h
http://www.makelinux.net/books/lkd2/ch11lev1sec4
http://www.google.com.tw/url?sa=t&rct=j&q=&esrc=s&source=web&cd=5&ved=0CF8QFjAE&url=http%3A%2F%2Fant.comm.ccu.edu.tw%2Fcourse%2F96_Driver%2F0_Lectures%2FChap7-Getting%2520Hold%2520of%2520Memory_milk.ppt&ei=TMFqT_ysHqWfmQW5obyWBg&usg=AFQjCNGvVEk9-Io481khM_SqoFd-WsvwqQ&sig2=qvOIAsidZzvw15vpq0JlrQ
2011年2月25日 星期五
ObjectOutputStream送出的物件指向舊的物件?
假設我在Server端有以下的Code
HashMap<String,String> map=new HashMap<String,String> ();
ObjectOutputStream oos=new ObjectOutputStream(clientsocket.getOutputStream);
while(true){
map.put(Long.toString(System.currentTimeMillis()),Long.toString(System.currentTimeMillis()));
oos.writeObject(map);
}
另外一端收到的會發現後面收到的物件都跟第一次收到的物件一樣,Why?因為在送出的時候都是指向同一個位址,因此必須要加上oos.reset();結果才會正確。
HashMap<String,String> map=new HashMap<String,String> ();
ObjectOutputStream oos=new ObjectOutputStream(clientsocket.getOutputStream);
while(true){
map.put(Long.toString(System.currentTimeMillis()),Long.toString(System.currentTimeMillis()));
oos.writeObject(map);
}
另外一端收到的會發現後面收到的物件都跟第一次收到的物件一樣,Why?因為在送出的時候都是指向同一個位址,因此必須要加上oos.reset();結果才會正確。
訂閱:
意見 (Atom)