원래는 몇 개월 전에 정리가 끝났어야 하는 것들인데, 내가 게을러서 이제서야 다시 시작한다. 마음 잡고 잘 해보자.


중요한건 어느 정도 깊이까지 공부를 하느냐가 문제인데... 우선 목표는 다른 사람이 이해할 수 있도록 설명해주는 수준으로 아는 것이다. 솔직히 원리까지 알자면 시간도 오래 걸리고 금방 질릴 것 같다. 지금 당장은 개념과 특징 정도만 알아두어도 괜찮을 것 같다.



마지막 업데이트

오전 10:33
수요일, 2018년 1월 31일 (GMT+9)


'임베디드 > 개념' 카테고리의 다른 글

단자와 반도체 소자  (0) 2018.01.03
JTAG  (0) 2018.01.02
PWM이란  (0) 2017.11.24
레귤레이터(Regulator)  (0) 2017.10.25
수동소자, 능동소자  (0) 2017.10.25
블로그 이미지

NCookie

,

지금 다니고 있는 회사는 분야가 임베디드에 가깝기 때문에 소프트웨어 쪽만 알고서는 일하기 힘들다. 그렇기 때문에 진입장벽이 낮다는 PIC를 통해 임베디드 분야에 입문을 하게 되었다.


차장님께 추천받은 IDE는 MPLAB X IDE로 마이크로 컨트롤러와 아날로그 반도체 분야에서 유명한 회사라고 한다. 이 회사에서 개발자를 위해 MPLAB 이라는 개발환경을 제공한다. 기존에 자체적으로 만들었던 MPLAB과 NetBeans 기반의 MPLAB X가 있는데, 후자가 더 최신이고 평가도 좋다. 회사에서도 무료로 쓸 수 있는 프리웨어이다.


컴파일러는 회사에서 구매했다고 하는 CCS를 사용하기로 하였다. CCS는 마이크로 칩을 위한 C 컴파일러라고 한다. 자세한 내용은 홈페이지 참고.


처음 차장님이 개발환경을 구축하는데 시간이 꽤 걸릴 것이라고 말씀하셔서 걱정을 했었는데 다행히 자료가 많아서 생각보다 일찍 끝났다. 내가 MPLAB X IDE에서 CCS 컴파일러를 사용하기 위해 참고했던 자료가 있다.(PDF)



자세한건 첨부 링크 참조하고, 간단하게 설명하자면 그냥 플러그인 설치하고 프로젝트 생성할 때 설정만 해주면 된다. 그리고 내가 헤매서 쓸데없이 시간을 낭비한 부분이 있었다. 프로젝트를 생성하면 기본적으로 헤더와 소스 파일이 없는데, 소스 파일같은 경우에는 기존에 있던 파일을 불러와 사용할 수 있다.



그리고 저 예제 파일은 컴파일러가 설치되는 폴더(기본적으로 C 드라이브의 Program Files에 설치됨)에 함께 들어있는데, 만약 저 다이얼로그 박스의 우측 하단에 있는 Copy 부분을 체크하지 않으면 해당 파일 경로를 참조하게 된다. 즉, 시스템 폴더 안에 있는 파일을 접근하려고 하기 때문에 빌드 과정에서 오류가 발생할 수 밖에 없는 것이다.


저 Copy 부분을 보지 못해서 몇 시간동안 문제를 찾기 위해서 뻘짓을 했었다. 공식 메뉴얼에서도 이 부분을 언급했었는데 나는 이것이 문제라고는 생각지도 못하고 넘어갔었다. 앞으로는 문서를 꼼꼼하게 살피고 넘어가자...

블로그 이미지

NCookie

,

현재 회사에서 진행하고 있는 프로젝트에서 안드로이드 어플리케이션은 특정 디바이스와 계속해서 블루투스 연결을 유지해야 한다. 그러다보니 Service와 Broadcast 같은 것들에 대해 알아보게 되었는데, Service 부분이 헷갈리는게 있어서 정리하려고 한다.



안드로이드의 서비스는 life cycle에 따라 종류가 두 가지로 나누어진다.




1. Started Service


startService 메소드를 사용하면 서비스가 생성되며, stopService 또는 stopSelf를 호출하지 않는 이상 서비스는 종료되지 않고 계속 작동한다.


이러한 형태는 백그라운드에서 계속 돌아가야 하는 음악 재생 어플리케이션 등에서 사용된다.


그리고 서비스의 life cycle에 따라 콜백 메소드들이 존재한다.


하나의 서비스가 생성될 때 onCreate가 단 한번만 호출된다.


예전에는 onStart를 사용하였지만 요즘은 onStartCommand 사용을 권장하고 있다. 서비스가 시작될 때 호출되는데, 만약 이미 startService를 했는데 추가로 startService를 하려고 하면 이 onStartCommand가 호출된다. bindService를 사용할 때는 호출되지 않는다.


그리고 이 메소드는 int형의 반환값을 가지는데, 리소스 부족 등의 이유로 시스템이 서비스를 강제종료 했을 떄, 어떻게 처리할지를 정하는 플래그이다. 


- START_STICKY : client에서 startService 사용 시 intent로 서비스를 전달하며, onStartCommand에서 intent를 인자로 받을 수 있다. 단, 기존의 전달되었던 intent 값은 넘어오지 않는다.


- START_NOT_STICKY : 시스템이 서비스를 죽여도 다시 살아나지 않는다.


- START_REDELIVER_INTENT : 기본적으로 START_STICKY 플래그와 비슷하며, 대신 기존에 전달했던 intent 값을 돌려준다.


서비스 생성 : startService(Intent service)

서비스 종료 : stopService() 또는 stopSelf()



2. Bound Service


bindService 메소드를 사용하면 서비스가 생성되며, unbindService를 사용하거나 기존에 bound 된 액티비티들이 모두 unbind 하면 종료된다.


명시적으로 메소드를 사용해야 종료되는 Started Service와는 달리, 생성한 서비스에 bound 된 액티비티가 존재하지 않는다면 서비스는 종료된다.


콜백 메소드로는 onBind, onRebind, onUnbind가 있다. onRebind 같은 경우, 이미 unbind 되었던 액티비티가 다시 서비스에 연결했을 때 호출된다. 내 프로젝트를 예로 들자면 사용자가 앱 화면을 벗어나 다른 작업을 할 때 unbind가 되는데, 현재 디바이스가 연결되어 있다는 것을 notification bar로 보여준다. 그리고 다시 화면으로 돌아와 rebind 되면 notification을 내린다.


Bound Service 또한 마찬가지로 서비스에 플래그를 전달할 수 있는데, bindService 메소드의 인자로 값을 설정한다. 흔히 사용하는 플래그로는 0과 BIND_AUTO_CREATE가 있다.


0을 플래그로 설정하면 startService로 서비스를 생성하기 이전까지는 서비스가 생성되지 않는다. 만약 기존에 서비스가 생성되어 있다면 정상적으로 bind 된다.


BIND_AUTO_CREATE는 시스템에 의해 강제로 종료되더라도 리소스가 충분해지면 리소스에서 다시 실행하도록 하며, onBind에서 이전에 전달받았던 Intent 값을 받을 수 있다. 즉 바인딩된 액티비티가 존재하는 한 서비스를 생성한다. 대신 onStartCommand는 startService를 사용할 때에만 호출된다.


서비스 생성 : bindService(Intent service, ServiceConnection conn, int flags)

서비스 종료 : unbindService() 또는 모든 액티비티 unbound



3. start와 bind 동시 사용


startService와 bindService를 동시에 사용하는 것 또한 가능하다. 


이 때 서비스의 life cycle은 Started Service를 따른다. 즉, 명시적으로 stopService 또는 stopSelf 메소드를 사용하지 않는 이상 서비스는 종료되지 않는다.(시스템이 종료하는 것은 제외하고...)


이에 대해서는 구글에 좋은 예제가 있다.



참고


[Android] 서비스(Service)의 기초


19. Service에 대해서 - Service의 생존(2)


[컴][안드로이드] service에 bind하기 - local service


android service startService() and bindService()


Use 0 or BIND_AUTO_CREATE for bindService's flag


Google Android developers Context#BIND_AUTO_CREATE

블로그 이미지

NCookie

,

Serializable 을 implements 해서 BluetoothDevice 객체를 Intent에 넣어서 전달하려고 했는데, 막상 받아보니 null 값이 들어있었다.


그래서 찾아보니, BluetoothDevice 클래스 선언 단계에서 Parcelable 을 implements 하였고, 필요한 함수들도 이미 구현되어 있다고 한다.


그래서 Parcelabe을 implements 하거나 그에 따라 필요한 함수들도 따로 구현할 필요가 없다.


그냥 값을 넘길 때


intent.putExtra(intent_key, mSelectedDevice);
startActivity(intent);

하고, 값을 받으려면


Intent intent = getIntent();
BluetoothDevice bluetoothDevice = intent.getExtras().getParcelable(intent_key);


이렇게 하면 된다. 엄청 편하다.



참고


Passing BluetoothDevice Object to Another Activity though Intent


Google Developers : BluetoothDevice

블로그 이미지

NCookie

,

png 이미지를 안드로이드에서 사용했는데, 위 아래의 여백이 있었다.


그러나 실제 이미지에는 그런 여백이 없었다.


이런 현상은 android:adjustViewBounds 속성을 이용하여 해결할 수 있다. 이 속성은 drawable의 원래 비율을 유지하기 위해 뷰의 영역을 조절할지 정한다.


그렇기 때문에 이 속성을 true로 하면 여백을 없앨 수 있다.


만약 안드로이드의 API 가 17 이하라면, 이미지가 이미지뷰보다 클 때에만 적용된다. 자세한 내용은 아래의 링크를 참고하자.




참고


Google Developers ImageView


[안드로이드] SDK 17 이하에서 ImageView의 adjustViewBounds 속성 문제

블로그 이미지

NCookie

,