이 블로그 검색

2011년 12월 16일 금요일

서비스와 디바이스 드라이버



블랙핀을 이용한 소프트웨어에서는 시스템 서비스와 디바이스 드라이버, 커널, 응용 계층으로 나눌 수 있다. 아래 그림은 이를 보여준다.
응용계층이나 커널, 디바이스 드라이버 계층에서 모두 시스템 서비스를 제어할수 있다.

그러면 시스템 서비스는 무엇을 말하는가?
임베디드 시스템에서는 기본적으로 있어야 하는 기능들이 있다.
PLL, DMA, interrupt controllers, timers, flags, port etc등은 대부분의 임베디드 프로세서에서 다루는 부분이다.  여기서 flags는 GPIO를 말하며 port 제어는 Multiple functional port control를 의미한다.

우리는 이런 기능을 시스템 서비스(자원)라고 명칭한다.  디바이스는  우리가 익히 알고 있는 Interface들과 주변장치등들이다.   디바이스 드라이버는 시스템 서비스를 이용하여 디바이스가 커널이나 응용계층에서 사용되어 질수 있도록 한다.

 간단한 예로 UART를 들수 있다.

UART는 인터럽트, DMA, Flag, PLL등 거의 모든 시스템 서비스(자원)가 사용된다.
우리의 논의는 이러한 디바이스 드라이버를 구현시 다른 디바이스에서도 선택적으로 사용되는 시스템서비스를 독립된 계층으로 분리하여 함수의 재사용을 추구하며 소프트웨어 계층을 둠으로서 디바이스 드라이버구현시 시스템 서비스만을 이용하여 구현할수 있게 할수 있다.
물론 응용계층과 커널계층에서 직접 시스템서비스를 사용하는 것도 가능해 진다.

하지만 블랙핀 DSP의 적용범위가 인버터나 산업용 제어에서 많이 쓰이는 관계로 이러한 계층화에 따라 Resource의 낭비를 고려 해야 한다고 본다. 또한 간단히 레지스터의 세팅으로 끝날 부분을 시스템서비스와 디바이스 드라이버를 이해하며 사용해야 하는 부담도 있다. 이러한 계층구조는 커널과 복잡한 응용계층이 존재할때 의미가 있어 보인다. 이때는 사용하는 것이 여러가지 이유로 유리한다. 시스템 서비스와 디바이스 드라이버가 에러없이 안정하게 Standalone과 VDK 모드로 ADI에서 직접 제공하고 있다.

기본적으로 VisualDSP를 설치하면
 C:\Program Files\Analog Devices\VisualDSP 5.0\Blackfin\lib\src 폴더에 서비스, 디바이스 드라이버, C Runtime & DSP등의 라이브러리가 포함되어 있다. 
















위의 그림이 시스템 서비스들을 나타낸다.

- Dynamic Power Management : 동작모드 설정, CCLK, SCLK설정 등
- External Bus Interface Unit (EBIU): SDRAM 설정및 SCLK 변경
- Interrupt Manager
- Deferred Callback Service: 인터럽트 서비스 루틴 관리
- DMA Manager
- Flag Control : GPIO
- Timer Control : 타이머
- Port Control: 다중 기능 포트제어 및 각 기능별 포트제어


 위의 그림은 디바이스 드라이버의 구조이다.


adi_dev_xxx() 은 각각의 디바이스의 adi_pdd_xxx()를 호출한다. adi_pdd_xxx()는 static으로 선언되어 각각의 디바이스 별로 존재하게 되고 adi_dev_xxx()는 해당 디바이스를 찾아 adi_pdd_xxx()를 호출해 주는 구조이다.
각각의 디바이스 드라이버 문서는 C:\Program Files\Analog Devices\VisualDSP 5.0\Blackfin\docs\drivers 폴더내에 있다. 참조 하기 바란다.

디바이스 드라이버에서 인터럽트 처리는 중요한 문제이다. 이 부분만 이해해도 디바이스 드라이버 이해가 쉬워진다.  응용이나 커널계층에서 Callback 함수를 만들고 이함수를 통해 인터럽트 처리를 하길 원하다면 디바이스 드라이버는 다양한 인터럽트를 이 함수를 호출해야 한다. 인터럽트 ID와 Callback 함수 관리를 해야 하며 다른 디바이스드라이버와도 잘 조화를 이루어야 한다.  같은 IVG에서는 소프트웨어적으로 인터럽트를 분리해야 하며 adi_dev에서 처리하여 해당 디바이스이 adi_pdd호출해 주어야 한다.


 

Analog Devices(ADSP-BF592소개)

1. ADSP-BF592주요특징
 - . 가격 대비 최상의DSP성능으로 개발업체들은 보다 시스템 수준의 장점들로 더욱 복잡한알고리즘을 구동할 수 있다.
 -. 200 MHz 전력소비가 51mW에 불과하고, 대기전력이 1mW 미만이라 경쟁사 제품 대비 전력소비를 80% 줄였으며 배터리 수명을 연장시킨다.
 -. 400-MMAC/200-MHz 장치의 크기가 업계 최소 패키지인 9mm x 9mm로, 디자이너들은 제한된 공간 내에서 매우 높은 성능을 구현해낼 수 있다.
 -. 외장 메모리나 실행플래쉬 없이도 다양한 애플리케이션 구동에 최적화되어 있다. 주변장치 세트에는 SPORT 2개, PPI 1개, SPI 2개, 범용 카운터 4개가 포함되어 있으며 자체 프로그램된 인스트럭션 ROM 블록에는 VDK RTOS와 C 런타임 라이브러리가 포함된다.
 -. 상업·산업 온도등급으로 출시되며 자동차용으로도 검증되었다.
 -.휴대용 헬스케어 제품, 오디오 기기, CMOS 센서 기반 2-D 바코드 스캐너와 같은 이미지 생성 제품
 -.가격 및 출시블랙핀 ADSP-BF592는 1000개 구매시, 200-MHz 속도 등급을 기준으로 단가가 1.99달러이다(모델 번호 ADSP-BF592KCPZ-2). 프로세서는 샘플 공급 가능

2. 개발 플랫폼

 - 블랙핀 ADSP-BF592
이지키트 라이트(EZ-KIT Lite(R)) 평가보드는 ADI 공식판매처를 통해 정상가 199달러
 - EZ-KIT 에는 C/C++ 컴파일러, 어셈블러, 링커 등과 같은 ADI 비주얼 DSP++(VisualDSP++) 개발환경 평가보드가 포함
 - 150달러에 공급되는 블랙핀 에뮬레이터(emulator, ADZS-ICE-100B)는 디자이너들에게 종합적 개발 플랫폼을 제공함으로써 블랙핀 BF592 구매 비용을 줄였다.
 - 프로세서 최적화와 전반적인 시그널 체인 성능을 위해 전원 IC, 데이터 컨버터, 센서, 디지털 컨디셔닝 IC 등도 공급

3. 참고자료
- 데이터 시트는 아날로그닷컴
블랙핀 ADSP-BF592 제품 페이지 참조(www.analog.com/ADSP-BF592)
- 400-MHz 속도등급의
블랙핀 ADSP-BF592 안내동영상은 www.analog.com/ADSP-BF592_video 참조.
- DSP 지원과 관련해서는 ADI 온라인 기술지원 커뮤니티인
엔지니어존(EngineerZone™) http://ez.analog.com/community/dsp 참조.

4. 추천글


혁신 디자인에는 블랙핀 수준의 프로세싱이 필수적아나로그 디바이스의16/32비트 블랙핀 프로세서를 통해 엔지니어들은 디지털 시그널 프로세싱 전환의 이점을 취하고 통합된 아키텍처 상에서 프로세성을 제어하는 모든 애플리케이션의 인텔리전스, 성능, 연결성을 향상시킬 수 있다. 성능 대비 가격과 에너지 효율성이 매우 뛰어나며, 개발툴·애플리케이션·3자 지원 등을 통해 풍부한 통합 시스템을 구축한 만큼, 블랙핀은 산업·의학·자동차·보안·디지털홈엔터테인먼트·휴대용 기기 등 각종 혁신 애플리케이션 프로세서에 있어 최고의 선택이 될 것이다.

5. 아나로그 디바이스(Analog Devices)


혁신, 성능, 우수성은 아나로그 디바이스(Analog Devices)가 기술부문에서 오랫동안 최고 성장을 구가할 수 있는 초석이 되어왔다. 데이터 전환과 신호조정 기술을 선도하는 세계적인 기업으로 인정받고 있는 아나로그 디바이스는 거의 모든 종류의 전자기기를 공급하는 60,000개 이상의 고객을 보유하고 있다. 미 매사추세츠주 노우드에 본사를 두고, 전세계에 걸쳐 설계, 제조 시설을 운영하고 있다. 아나로그 디바이스의 주식은 종목기호 ADI로 뉴욕증권거래소 에 상장되어 있으며, S&P500지수에 포함되어 있다 (http://www.analog.com 참조).

ADI 트위터: http://www.twitter.com/ADI_News
링크드인 그룹(Linkedin Group): 아날로그 디바이스 블랙핀(Analog Devices Blackfin)

ADI 월간 기술잡지 아나로그 다이얼로그(Analog Dialogue) 구독: http://www.analog.com/library/analogDialogue/subscribe.html.

Blackfin, EZ-KIT Lite, VisualDSP++는 Analog Devices, Inc.의 등록상표이다. 기사에서 언급된 그 외 모든 상표의 소유권은 개별 소유권자에게 있다.

사진 및 멀티미디어 자료는 http://www.businesswire.com/cgi-bin/mmg.cgi?eid=6842552&lang=en을 참고할 것.

11. 연락처
시리얼시스템-박지한(블랙핀 FAE)

인터럽트(BF506F)

블랙핀은 2 레벨의 인터럽트를 처리과정을 따른다.



Core event controller(CEC)와 System interrupt controller(SIC)이다.

CEC는 CCLK 클록영역에서 동작하며,프로그램 시퀀서와 밀접하게 상호동작하
고, 이벤트 벡터 테이블(EVT)을 관리한다. 또한, Core와 관련된 인터럽트들 즉, 예외, Core 에러 그리고 emulation events 뿐만아니라 소프트웨어 인터럽트들도 지원한다.

SIC는 SCLK 클록영역에서 동작하며, 칩내부 또는 외부의 주변장치에 의해서 알려지
는 인터럽트 요구들을 masking, grouping, 그리고 우선순위를 결정하고, CEC로 전송
한다.


프로세서의 CEC는 5가지 종류의 활동과 이벤트를 처리한다.

1) Emulation
2) Reset
3) NMI :
NMI event는 software watchdog timer에 의해서 발생될 수도 있고, _NMI pin, 또는
software에 의해서 발생될 수 있다. 일반적으로 NMI event는 system의 shutdown을 순
서대로 수행하기 위한 power-down indicator로 사용된다.
4) Exceptions :
software에 의해서 초기화된 event로서 program flow에 동기적으로 발생하는 events.
예) data alignment violations, undefined instructions, etc.
5) Interrupts :
program flow에 비동기적으로 발생하는 events. 이들은 timers 그리고 다른 주변장치들
의 입력 신호들에 의해서 발생하거나 명확한 software 명령에 의해서 발생한다.
각각의 event type은 return address를 유지하기 위한 관련된 register와 관련된
return-from-event instruction을 가지고 있다. Event가 발생하면, ISR은 supervisor
stack에 processor의 상태를 저장해야 한다.

여기에서 Event는 위의 5가지를 말하며 CEC는 좀더 엄밀히 말해서 15개의 확장된 이벤트들를 처리하는데 아래 테이블을 참조하라.




CEC는 전용 interrupt와 exception events외에 9개의 general-purpose
interrupts(IVG15-7)를 지원한다. 이들 general-purpose interrupts 중에서 2개의 가장
우선 순위가 낮은 interrupts(IVG15-14)는 software interrupt handlers로 사용되는 것
이 좋다.

위에서 SIC에 대해서 간략히 설명했지만 좀더 자세히 다루어 보자

SIC는 많은 주변장치 인터럽트들로 부터 우선권을 갖는 CEC의 general-purpose
interrupt inputs(IVG7-15)로 이벤트들의 연결을 라우팅할수 있는 기능을 제공한다. 비록 프로세서가 기본적으로 Mapping된 연결을 제공하지만 사용자는 interrupt assignment register(SIC_IARx)를 통해 인터럽트의 Mapping과 우선권을 변경할수 있다. 주변장치들에서 발생한 인터럽트들은 SIC로 들어가고, 이어서 직접 CEC의general-purpose interrupts로 들어간다.

SIC_IAR registers안에 interrupt 할당은 peripheral interrupts를 grouping할 뿐만 아니라,
개별적으로 IVG channel에 할당하여 우선권을 부여할 수 있다. 만일, 한 개의 interrupt
source 이상이 동일한 interrupt에 mapping된다면, 이들은 hardware 적인 우선권이 없이
단순히, 논리적으로 ORing되며, software가 interrupt 처리에 대한 우선권을 부여해 주어야
한다.
리셋을 하면, SIC_IMASK register의 내용은 모든 peripheral interrupts를 mask off 하기
위해서 “0”이 된다. 이제, 특정 interrupt를 enabling하는 것은 SIC_IMASK register 의 해당비트를 1로 세팅함으로 이루어 진다.

SIC는 peripheral interrupt sources 중에서 어느 하나의 interrupt 상태에 대응하는 개별적
인 bits를 포함하는 하나 또는 그 이상의 read-only SIC_ISR registers를 가지고 있다. 즉,
SIC가 interrupt를 검출할 때, 그 bit는 asserting되고, deasserting된 것을 검출할 때는 대
응하는 bits가 clearing된다.
Peripheral DMA channels는 peripheral interrupt IDs에 고정된 방법으로 mapping된다. 그
러나, peripherals와 DMA channels 사이의 할당은 DMA_PERIPHERAL _MAP registers로
자유롭게 programming될 수 있다. 일단, 임의의 peripheral이 임의의 다른 DMA channel에
할당되면, 그것은 DMA가 enabling 된 것과 상관없이 새로운 DMA channel's interrupt를
이용한다. 그러므로, DMA가 사용되지 않는다고 하더라도, DMA_PERIPHERAL_MAP은
clearing 제대로 관리되어야 한다. 만일, non-DMA applications만 사용할 것이라면, default
setup을 사용하는 것이 제일 좋다.
만일, 동적으로 power를 관리하고 싶다면, 임의의 peripherals가 core를 idle 상태에서
interrupt를 처리하는 상태로 wake up하도록 수어될 수 있는데, 이것은 단순히 SIC_IWR
register안에 있는 적절한 bit를 enabling하면 된다. 즉, 임의의 peripheral interrupt source
가 SIC_IWR안에서 enabling되어 있고, core idle 상태에 있다면, core가 interrupt를 처리할
수 있도록 일련의 과정을 따르도록 한다. 그러나, 이 mode를 이용하는 경우에는 interrupt
processing에 약간의 latency가 추가되는 데 주의하자.
정리하면, SIC_IWR register는 core가 idle 상태에 있을 때만 효과를 가진다는 데 주의하자.
그리고, 모든 interrupt가 disabling 되어 있을 때에 이 register에 어떠한 writing operation
을 수행해야 한다.
wakeup 기능은 interrupt mask 기능과는 다른 것이다. 만일, 어떠한 interrupt source가
SIC_IWR안에서 enabling되어 있고, SIC_IMASK register에서 mask off되어 있다면, idle 상
태에서 께어나기는 하지만, interrupt는 발생하지 않는데 주의하자. 결국, core에 interrupt는
발생하지 않지만, core를 깨우는 동작만 하게 되는 셈이다.



임의의 interrupt(즉, interrupt A)가 interrupt-enabled peripheral에 의해서
생성된 경우이다. 각각의 register에 대해서 간단히, 정리하면 다음과 같다.

1) SIC_ISR :
SIC_ISR은 request를 반영하고, asserting된 system interrupts의 track을 유지하지만, 아
직, servicing되지는 않았다.
2) SIC_IWR :
SIC_IWR은 발생한 interrupt request에 근거하여 idle 상태에 있는 core를 깨워야 하는지
check한다.
3) SIC_IMASK :
SIC_IMASK는 system level에서 peripherals로부터 interrupts를 enabling하거나 mask
off한다.
4) SIC_IAR :
SIC_IAR은 그 peripheral interrupts를 general-purpose core interrupts(IVG7-IVG15)
에 mapping하여 interrupt A의 core priority를 결정한다. 즉, 각각의 peripheral
interrupt ID를 대응하는 IVG priority level에 mapping한다. 이것은 4-bit grouping이
IVG levels로 translation되는 것을 의미한다.
5) ILAT :
ILAT는 interrupt A를 core에 의해서 latch되는 interrupts에 등록하지만, 아직도
servicing은 되지 않고 있다.
6) IMASK :
서로 다른 core 우선권들을 가지는 events를 enabling하거나 mask off한다. 만일,
interrupt A에 해당하는 IVGx event가 mask되지 않았다면, 7)번 단계로 수행한다.
7) EVT(Event Vector Table) :
EVT는 interrupt A의 ISR을 위한 적절한 vector를 찾기 위해서 접근된다.
8) IPEND :
interrupt A를 위한 event vector가 core pipeline으로 진입할 때, 적절한 IPEND bit가
set되고, 그것은 각각의 ILAT bit를 clear 해 준다. 그러므로, IPEND는 ISR을 servicing
해 줄뿐만 아니라 모든 pending interrupts를 추적한다.
9) RTI(Return From Interrupt) :
interrupt A를 위한 ISR이 실행 될 때, RTI는 적절히 IPEND bit를 clearing해 주어서 또
다른 interrupt를 받아 들일 수 있도록 해 준다. 그러나, ISR이 interrupt A를 생성한
mechanism을 clearing해 주지 않는다면, 계속해서 해당 peripheral로부터 interrupt가 들
어오므로 SIC_ISR은 clearing되지 않는다.





위의 그림은 어떻게 7개의 SIC_IAR registers가 9개의 사용할 수 있는 CEC의
peripheral request inputs에 할당하는 것을 제어하는 지 보여주고 있다.
여기서 주의할 것은 어떠한 interrupt를 받아들인 것에 대한 인정(acknowledge)
mechanism이 없다는 것이다.

EVT레지스터는 인터럽트 벡터그룹에 대응하는 서비스루틴 어드레스를 가진다.
우리는 이 레지스터에 인터럽트 서비스 루틴의 함수 어드레스를 포인팅함으로서 인터럽트를 처리할수 있다.

아래는 general purposed timer의 인터럽트 설정 이다.
이 세팅을 보면 Timer 6이 사용됨을 알수 있다.

register_handler(ik_ivg11,GPTimer_ISR);
    - 이 부분이 IVG11 그룹에 EVT[11]에 GPTimer_ISR함수 어드레스를 설정하는 함수 이다.
 *pSIC_IAR4   &= 0xF0FFFFFF;
 *pSIC_IAR4   |= 0x04000000;   // 


    - 해당 SIC-IARx을 찾아 4를 세팅하여 IVG11을 사용을 설정한다.
/*
  IVG7------0  IVG11------4
  IVG8------1  IVG12------5
  IVG9------2  IVG13------6
  IVG10-----3  IVG14------7
      IVG15------8
 */

 *pSIC_IMASK1|= 0x00000040; 
   - 해당 SIC-IMASKx 을 찾아 4를 세팅하여 SIC인터럽트를 CEC로 넘겨준다.


typedef void (*ex_handler_fn)();
#define EX_HANDLER(KIND,NAME) \
_Pragma(#KIND) \
void NAME (void)

#define EX_HANDLER_PROTO(KIND, NAME) EX_HANDLER(KIND, NAME)
#define EX_INTERRUPT_HANDLER(NAME) EX_HANDLER(interrupt,NAME)
#define EX_EXCEPTION_HANDLER(NAME) EX_HANDLER(exception,NAME)
#define EX_NMI_HANDLER(NAME)  EX_HANDLER(nmi,NAME)

#define EX_REENTRANT_HANDLER(NAME) \
_Pragma("interrupt_reentrant") \
EX_HANDLER(interrupt,NAME)

ex_handler_fn register_handler(interrupt_kind int_kind, ex_handler_fn handler);

register_handler :
- 기능 설명 :
이 함수는 event handler를 등록해 준다.
이 함수는 어떻게 hardware event kind가 처리될지를 결정한다. 이것은 그 event를 위한
handler로서 fn 에 의해서 지적된 함수를 등록함에 의해서 그리고, interrupt가 실행수 있
도록 IMASK register를 갱신한다.
register_handler_ex 함수는 register_handler보다 확장되고, 더 기능이 많은 interface를
제공한다.

EX_INTERRUPT_HANDLER(GPTimer_ISR)
{
 *pTIMER_STATUS= TIMIL6;//w1c , Timer6 Interrupt, indicates an interrupt request when   IRQ_ENA is set.
}

위의 함수가 인터럽트 서비스 루틴이다. 위의 매크로들을 참조하기 바란다.

ADSP-BF506F Overview

ADSP-BF506F
Feature
Up/Down/Rotary Counters   2
Timer/Counters with PWM   8
3-Phase PWM Units    2
SPORTs   2
SPIs   2
UARTs   2
Parallel Peripheral Interface   1
Removable Storage Interface   1
CAN   1
TWI   1
Internal 32M Bit Flash –   1
ADC Control Module (ACM)   1
Internal ADC   1
GPIOs  35
L1 Instruction SRAM  16K
L1 Instruction SRAM/Cache  16K
L1 Data SRAM  16K
L1 Data SRAM/Cache  16K
L1 Scratchpad  4K
L3 Boot ROM  4K


그림 1 ADSP-BF506F 내부구조

그림2 ADSP-BF506F 메모리구조