2015.05.13 20:01


Table of Content
  1. Intro
  2. 쉬운 API
  3. 어려운  API
  4. 어려운 API 와 쉬운 API?
  5. CPU 소모성 API
  6. CPU 소모가 없는 API
  7. msleep()
  8. msleep_interruptible()
  9. ssleep()
  10. schedule_timeout_interrupt()
  11. schedule_timeout_uninterrupt() 
  12. schedule_timeout() 
  13. ndelay(), udelay(), mdelay()  


1. Intro
 커널에서 시간 지연 함수는 여러가지가 있습니다. 
 굳이 분류를 하자면 쉬운 API, 어려운 API, CPU 소모성 API, CPU 소모가 없는 API 정도로 나눌 수 있습니다. 

2. 쉬운 API
 쉬운 API는 크게 보면 아래와 같습니다. 
  #include <linux/delay.h>
  #include <linux/timer.h>

  msleep()
  ssleep()

 이 API들은 함수명대로 micro  second, milli second, 1 second 을 뜻합니다. 
 그냥 사용하시면 됩니다. 

3. 어려운 API
 어려운 API 는 크게 보면 아래와 같습니다. 

 
  #include <linux/delay.h>
   #include <linux/timer.h>
   
   msleep_interruptible()
   schedule_timeout_interruptible();
   schedule_timerout_uninterruptible();
   schedule_timeout();

 이것도 그냥 사용하면 됩니다.

4. 어려운 API 와 쉬운 API ?
  어려운 API 와 쉬운 API 의 차이점은 무엇일까요? 

  가장 기본이 되는 지연 함수는 schedule_timeout() 입니다. 
  관계를 살펴보면

      ssleep()
    -----------------------------------------
      msleep()

    -----------------------------------------
      schedule_timeout_interruptible(), schedule_timeout_uninterruptible
 
    -----------------------------------------
      schedule_timeout()

 입니다. 위에 그림만으로는 잘 설명이 안될 수도 있는데, 커널 소스를 살펴보면 관계를 확실히 확인 할 수 있습니다. 

  ssleep() 는 msleep() 를 호출합니다. 
  msleep() 는 schedule_timeout_uninterrupt() 를 호출합니다. 
  schedule_timeout_uninterrupt() 는 schedule_timeout() 을 호출합니다. 

 결국 최종으로 호출되는 것은 schedule_timeout() 인데 시간 지연이라는게 인터럽트를 허용할 수도, 아닐수도 있고 또한 사용상의 편의상 ssleep() 나 msleep() 같은 front-end 를 만들어 쓴다고 생각하면 됩니다. 

8. CPU 소모성 API
 지정한 지연시간까지 loop 를 돌면서 cpu 시간을 소모하는 형태의 API 입니다. 
 
 ndelay();
 udelay();
 mdelay();

 위와 같이 delay 라는 이름이 붙은 API 들이 CPU 소모성 API 이며 아래와 같이 구현할 경우에도 CPU 소모성 API 입니다. 
 
 while(time_before(jiffies, j1))
 {
   cpu_relax();
 }

9. CPU 소모가 없는 API
 CPU 점유가 없이 시간 지연을 구현하려면 현재 자기자신한테 할당된 프로세스 시간을 반납하고 대기하는 방식을 사용하면 됩니다. 

 schedule_timeout_interruptible()
 schedule_timeout_uninterruptible()

 등이 그런 계통입니다. 

7. msleep()
  header : 
asm/delay.h
  void msleep(unsigned int msecs);
  unsigned long msleep_interruptible(unsigned int msecs);

 => 밀리세컨드 동안 지연해 줍니다. 지연시간동안에는 인터럽트를 받을 수 없습니다. 

example

 #include <asm/delay.h>

static void example_msleep(void)
{
  msleep(1000);


 
8. msleep_interruptible()
  header : 
asm/delay.h
  unsigned long msleep_interruptible(unsigned int msecs);

 => 밀리세컨드 동안 지연해 줍니다. 지연시간동안에는 인터럽트를 받을 수 있습니다. 

example)

 #include <asm/delay.h>

static void example_msleep(void)
{
  msleep_interruptible(1000);


 
9. ssleep()
  
  header : asm/delay.h
    void ssleep(unsigned int seconds);

 => 초단위로 지연해 줍니다. 지연시간동안에는 인터럽트를 받을 수 없습니다. 

example)

 #include <linux/sched.h>

static void example_ssleep(void)
{
  ssleep(2);



10. schedule_timeout_interruptible()

  
  header : linux/sched.h
    void schedule_timeout_interruptible(unsigned long timeout);

 => timeout 시간만큼 지연해 줍니다.  

example)

 #include <linux/sched.h>

static void example_ssleep(void)
{
  schedule_timeout_interruptible(1 * HZ); /* 1 초간 지연 */


11. schedule_timeout_uninterruptible()

  
  header : linux/sched.h
    void schedule_timeout_uninterruptible(unsigned long timeout);

 => timeout 시간만큼 지연해 줍니다. 지연시간도중에는 인터럽트를 받을 수 없습니다. 
  
  
example)

 #include <linux/sched.h>

static void example_ssleep(void)
{
  schedule_timeout_uninterruptible(1 * HZ); /* 1 초간 지연 */


 
12. schedule_timeout()

  
  header : linux/sched.h
    void schedule_timeout(unsigned long timeout);

 => timeout 시간만큼 지연해 줍니다. 가장 기본이 되는 함수입니다. 그렇기 때문에 직접 호출하여 사용하지는 않습니다. 

example)

 #include <linux/sched.h>

static void __sched schedule_timeout_interruptible(void long timeout)
{
  __set_current_state(TASK_INTERRUPTIBLE);
 
 return schedule_timeout(timeout); 



13. ndelay, udelay, mdelay
   header : linux/delay.h
   #define ndelay(n);
   #define udelay(n); 
   #define mdelay(n);

  busy wait 방식이어서 cpu 로드가 많은 편입니다. 하지만 간단하게 쓸 수 있는 장점이 있습니다. 

example)


#include <linux/delay.h>

void delay_test(void long timeout)
{
  ndelay(1000);
  udelay(1000);
  mdelay(1000); 
 


신고


Posted by injunech
2015.04.12 16:19


[Android] onTouchEvent 에서의 MotionEvent 터치 구분



@Override

public boolean onTouchEvent(MotionEvent event) {

int action = event.getAction();

int touch_id = ((action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> 8 );

int actionEvent = action & MotionEvent.ACTION_MASK; // MotionEvent.ACTION_MASK = 0xff

pointerCount = event.getPointerCount();


switch (actionEvent) {

case MotionEvent.ACTION_DOWN: {

...

}


위와 같이 action 값을 받게 되면 해당 action 값에는 Touch 동작 관련 HEX 값이 들어가게 된다

Integer.toHexString(action) 를 통해 int 값을 HEX 로 출력하면 16진수로 다음과같은 값으로 터치를 구분할 수 있다

0x___

세번째 두번째 첫번째


첫번째 값은 터치의 Up, Down, Move 를 판별 가능하며, 첫번째 터치인경우와 두번째 터치 이후의 터치의 경우 Up 과 Down 구분 값이 다음과 같이 달라진다.

     Primary Finger DOWN = 0        Primary Finger UP     = 1

non-Primary Finger DOWN 5   non-Primary Finger UP     = 6

All Finger MOVE             = 2


두번째 값은 0 이 입력되고 0 이외의 값은 본적이 없다. (나중에 추가로 조사를 해봐야 할듯)


세번째 값은 touch ID 값으로 첫번째 터치인경우 0의 값 두번째 터치인 경우 1의값 세번째 터치인 경우 2의 값이 들어가며 멀티 터치를 지원하는 최대 값까지 입력된다. 한개의 터치가 Release 되는 경우에는 아직 터치상태인 나머지 터치의 action 의 세번째 Hex 값은 첫번째 터치 값인 0부터 다시 차례대로 터치한 상태로 매겨지게 된다. 자세한 사항은 아래 참고의 예를 확인

- 참고 : 첫번째 터치시에 값은 0 두번째 터치시에 값은 1, 세번째 터치시에 값은 2 이다.

이상태에서 터치를 Release 하는 경우에는 해당 터치 ID 의 값이 입력된다.

예를 들면 3번째까지 터치한 상태에서 두번째 터치한 손가락을 Release 하는 경우에는 action의 세번째 Hex 값은 1이된다.

또한 이상태에서 현재 터치한 Count 값은 총 2개이다. 그리고 나머지 첫번째 터치한 action의 세번째 Hex 값은 그대로 0이고 세번째 터치한 action 의 세번째 Hex 값은 기존의 2에서 1로 변경되게 된다.





나같은 경우에는 위 코드와 같이 action 값을 세번째 Hex 값, 첫번째 두번째 Hex 값으로 아래와 같이 저장하여 이용한다.

int action = event.getAction();

int touch_id = ((action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> 8 );

int actionEvent = action & MotionEvent.ACTION_MASK; // MotionEvent.ACTION_MASK = 0xff






신고


Posted by injunech
2015.04.11 11:01


Android에서 'Android library projects cannot be launched' 에러가 발생 할 수 있다. 이 문제는 project를 application이 아닌 Library로 인식하기 때문에 발생할 수 있다. 다음을 체크해 보자


Project Properties > Android > Is Library 가 체크되어 있는지를 확인한다.

만약 체크되어 있다면 체크해제 후 재 실행하면 해결 할 수 있다.

신고


Posted by injunech