부트로더란?

2016. 8. 6. 10:15 from MCU/AVR

부트로더(부트스트랩 로더)란?


 


Microprocessor에서 부트로더의 의미는 시스템이 시작할 때 가장 먼저 시작하는 프로그램으로 랜덤 액세스가 가능한 ROM이나 플래시 메모리에 있던 프로그램을 SRAM으로 부팅하는 것입니다.


 


이는 ROM이나 플래시 메모리에서 액세스 시간이 길기 때문에 거기서 명령을 실행할 경우 매번 명령어를 가져오는데에도 기다려주어 하기에 실행속도가 떨어지기게 됩니다. 그러나 SRAM으로 옮겨 실행한다면 아주 액세스 속도가 빠르게 될 것입니다.


 


그러나 AVR의 경우에는 부트로더의 의미가 달라졌습니다. 즉, 제품의 사용자가 제품의 펌웨어를 업그레이드할 수 있는 내장 프로그램을 말합니다. AVR에 탑재된 플래시 메모리 같은 비휘발성 메모리는 부트로더 영역과 응용 프로그램 영역으로 나뉘어지고 부트로더 부분은 한번 써놓으면 그 자리에 항시 존재하고 따라서 적어도 한번 기록해야 하며 나머지 응용 프로그램은 개발 및 유지 단계에서 수시로 업그레이드가 필요할 것입니다.


 


결과적으로 부트로더는 AVR이 부트되면 시리얼 포트를 감시하며 프로그램의 다운로드를 기다립니다. 만약 시리얼 포트로 프로그램이 전송되면 이 프로그램을 플래시 메모리에에 기록합니다. 그리고 다음번 부팅 때부터는 시리얼 신호가 없어도 부트로드된 프로그램이 있으면 이 프로그램을 바로 실행시키며  플래시가 비어 있으면 시리얼 다운로드를 기다립니다. 


 


만일 덩치가 크지 않은 사용자 프로그램을 시리얼 통신으로 다운로드 받고 PC와 통신한다면 개발시 편리한 방법이기에 앞으로 부트로드 사용이 일반화되겠지요...


 


하지만 이러한 부트로더 프로그램은 응용 프로그램과 더불어 사용자가 함께 만들어야 하는데 아두이노(Arduino) 보드는 부트로더를 탑재하여 제공하니 편하고 보급이 빠른 이유 중의 하나일 듯 생각됩니다.


 


참고로 AVR에 프로그램을 다운로드 하는 방법을 다음과 같습니다.


 


1. AVR ISP의 소프트웨어 그리고 하드웨어를 이용한 방법으로 SPI 프로토콜을 이용하여 AVR 칩의 SCLK/MISO/MOSI/SS 핀을 이용합니다.


 


2. 부트로더를 이용한 방법으로 UART 다운로드 툴과 칩의 TXD/RXD 핀을 이용합니다. 처음 부트로더를 다운로드하기 위해서는 1의 방법을 적어도 한 번 사용해야 합니다.


출처 : http://sharehobby.tistory.com/entry/%EB%B6%80%ED%8A%B8%EB%A1%9C%EB%8D%94%EB%9E%80

'MCU > AVR' 카테고리의 다른 글

SPI 통신  (0) 2016.04.21
내부 풀업 저항 (I/O 포트)  (0) 2016.04.19
펌웨어와 임베디드  (0) 2015.05.29
인터럽트 한개로 다수의 RC 서보 제어  (0) 2013.12.17
[AVR] 데이터 손실  (0) 2013.12.12
Posted by 나무길 :

ESC에는 두가지 종류



가 있습니다. OPTO Type와 BEC Type 입니다. 솔직히 제가 전공한 분야가 아니라서 잘 모르다보니, 배터리 - 모터/ESC - Flight Controller 를 연결하는 게 이해가 힘들었습니다. 특히 ESC의 종류에 따라 연결방법이 달라진다고 하니 더 그랬죠. 


제가 조립했던 DJI F450에는 OPTO 형 ESC가 달려 있었습니다. 얼마전 조립한 3DR 의 DIY Quad Kit은 BEC 형 ESC가 달려있었구요. 이번에 새로 조립할 때는 이 두가지를 조합해서 조립할 예정으로 있습니다. 제가 왜 어려워하는지 이해하시겠죠. :)


그래서... 구글링을 해서 자료를 찾아 정리해봤습니다. 이글은 Black Tie Aerial의 글을 필요에 따라 정리한 것입니다.


- ESC : Electronic Speed Controller. 전자변속기. 그냥 변속기라고도 합니다.

- Opto : Optoisolator 의 약어. Aotpisolator라는 전자 신호를 전기로 연결하지 않고 전달할 수 있는 전자 회로 이다. (아주 간략하게 말해서) Optoisolator 안에는 약간의 간격이 있고, 한쪽엔 LED, 다른쪽엔 광검출기(photodetector)가 달려있다. 입력 전자신호(예를 들어 비행콘트롤로에서 들어오는 신호)는 일련의 빛(flash)으로 변환된다. 이 빛을 반대편에 있는 광검출기가 감지를 한다. 마치 어떤 사람이 후레시를 켰다 껏다하면서 모르스 부호를 통신하는 것이라고 생각할 수 있다. 따라서 신호가 전기가 아닌 빛으로 전송된다.

- BEC/UBEC : 배터리 제거회로(Battery Eliminator Circuit/Universal Battery Eliminator Circuit) BEC와 UBEC는 기본적으로 동일한 회로로서, 몸집이 큰 전압조정기(voltage regulator)라고 생각하면된다. 목적은 멀티로터 배터리(일반적으로 11.1V)의 고전압전기를 저전압(일반적으로 5V)로 변환하는 것으로서, 비행콘트롤러나 서보와 같는 저전압 장치를 구동시키는 데 사용된다. 만약 비행콘트롤러를 배터리와 직접 연결하면 비행콘트롤러가 타버리게 된다. 따라서 배터리와 비행콘트롤러 사이에 BEC/UBEC를 두어 적절한 수준으로 전압을 떨어뜨려야 한다.




전자변속기를 무엇인가?


Brush 모터와 Brushless 모터의 근본적인 차이로, Brushless 모터는 반드시 제어 회로가 필요하다. ESC가 바로 Brushless 모터의 제어기이다. ESC는 모터속에 있는 전자기 코일에 들어가는 전기 흐름을 제어하여 모터를 돌아가도록 한다. ESC는 Brushless 모터의 회전 속도를 제어하는데 사용된다.


ESC에는 두가지 종류가 있다. opto ESC와 BEC ESC이다. 멀티로터를 조립할 때 어떤 ESC를 사용하느냐하는 것은 매우 중요하다. 종류에 따라 전원체계가 완전히 다르기 때문이다. 불행히도 이 두가지 ESC는 라벨만 다를 뿐 형태는 거의 비슷하다.




BEC형 ESC는?


BEC 혹은 UBEC 형 ESC 에는 기본적으로 두개의 전자회로가 한꺼번에 들어있다. 첫번째는 ESC 회로로서, 비행콘트롤러로부터 신호를 받아서 그 강도에 따라 연결된 모터의 속도를 제어한다. 두번째 회로는 BEC 회로로서, 배터리로부터 고전압을 받아, 비행콘트롤러에 필요한 수준으로 전압을 떨어뜨린다.


ESC와 BEC를 결합하면 편리하다. ESC를 비행콘트롤러에 꽂아주기만 하면 되기 때문이다. 한편으로는 모터의 속도를 제어하면서 비행콘트롤러에 전원을 넣어줄 수 이싿. 따라서 BEC ESC를 사용하면 전원부 설정이 간단해진다. 배터리 - ESC - 비행콘트롤러 순으로 연결만 하면 된다.


BEC ESC의 단점은 배터리 전압을 떨어뜨리는 과정에서 잉여 에너지를 열로 바꾼다는 점이다. 이때문에 BEC ESC를 탑재한 멀티로터를 조금 날리다보면 뜨거워지는 것을 느낄 수 있다. 열이 너무 많이나면 ESC를 망가뜨리게 되고 멀티로터를 추락시킬 수 있다.




Opto형 ESC는?


Opto ESC에는 배터리제거회로가 없다. 따라서 Opto ESC는 비행콘트롤러로부터 신호를 받아 모터의 속도를 제어하지만, 비행콘트롤러에 전원을 공급하는 기능은 없다. 이 사실을 모르고 Opto ESC를 주문했다가는 별도의 BEC 회로가 필요하게 된다. BEC/UBEC는 배터리와 비행콘트롤러 사이에 연결하여 비행콘트롤러에 적절한 전압을 공급한다.


Opto ESC는 별도로 UBEC를 구입해야 한다는 단점이 있다 아울러 전원설정이 약간 더 복잡해지고, 선도 더 많아진다.


하지만 Opto ESC는 BEC 회로가 없기 때문에 BEC ESC에 비해 약 20% 정도 저렴하다. 따라서 UBEC를 별도로 구입하더라도 비용을 절약할 수 있다. 


또한 BEC ESC를 사용하여 멀티로터를 만들경우, ESC가 잘못되면 (예를 들어 과열로 인해) 비행콘트롤러로 가는 전원까지 망가짐으로써 멀티콥터가 추락하게 된다. Opto ESC를 사용하면 ESC가 잘못되더라도 비행콘트롤러는 영향을 받지 않아, 나머지 모터들을 사용하여 안전하게 착륙시킬 기회가 생길 수 있다.




Opto ESC와 UBEC을 사용하여 결선하는 방법




- Opto ESC를 모터에 연결

- Opto ESC를 비행콘트롤러에 연결

- Opto ESC와 배터리를 연결

- 외부 UBEC를 배터리에 연결

- UBEC를 비행콘트롤러에 연결.

===




출처 : http://www.internetmap.kr/entry/ESC-OPTO-vs-BEC

'project > Coaxial copter' 카테고리의 다른 글

분해능 / 샘플링 이란?  (0) 2016.04.12
거리 측정 센서 선정  (0) 2016.04.12
ADC의 전압별 비트 분해능  (0) 2016.04.12
가변저항 원리  (0) 2016.04.11
모터, 프로펠러, 배터리 선정  (0) 2013.12.20
Posted by 나무길 :

SPI 통신

2016. 4. 21. 18:04 from MCU/AVR

SPI 통신을 통해서 2byte 송수신 하기


ATmega128 두개로 SPI 통신을 테스트 해보았다. 하는 도중에 하위 1byte와 상위 1byte가 뒤집혀서 출력되는 현상이 있었는데 slave MISO 핀에 내부 풀업을 하지 않아서 발생하는 오류였다.


내부 풀업을 사용하지 않을시 아래와 같은 파형이 나온다. 저렇게 exp 적인 파형으로 인해서 잘못된 데이트가 입력되게 된다.







SPI 작동 방식





SPI 통신은 위 모양 처럼 환형큐의 모습을 가지고 있다. SPCR의 DORB(Data Order) 비트를 어떻게 설정 하느냐에 따라서 MSB 또는 LSB 부터 데이터 전송이 이루어진다.


2byte를 전송할 때에는 master와 slave 각 데이터를 상위 바이트와 하위 바이트로 나눈다. 그리고 상위 바이트는 상위 바이트끼리 환형큐 모양으로 전송하고, 하위 바이트도 환형큐 모양으로 전송한다.



< example >




SPCR의 CPHA bit이다. Setup과 Sample 뜻이 궁금했는데 아래 그림을 보면 알 수 있다.



CPHA가 0이면, master와 slave장치는 클럭신호 주기의 첫번째 엣지인 상승엣지에서 비트값을 읽고, 하강엣지에서 비트값을 변경할 수 있. CPHA가 1이면, 이 장치들은 클럭신호 주기의 두번째 엣지인 하강엣지에서 비트값을 읽는다. 그리고 비트값은 상승엣지에서 바뀔 수 있다. 비트값을 읽는동시에 값을 바꾸는 것이 아니다!



소스 코드


----------------------------------------- spi.h -------------------------------------------


#ifndef __SPI_H__

#define __SPI_H__


#define SS 0

#define SCK 1

#define MOSI 2

#define MISO 3


#define SPI_DDR DDRB

#define SPI_PORT PORTB

                                                            

void SPI_init_master();

void SPI_init_slave();


unsigned int SPI_IO_master(unsigned int);

unsigned int SPI_IO_slave(unsigned int);


#endif __SPI_H__



---------------------------------------- SPI_function.c ----------------------------------


#include <delay.h>

#include <mega128.h>

#include "spi.h"



void Putch (unsigned char data);

void SPI_init_master()

{

    //SPI_PORT |= (1 << SS); // pull up pins

    SPI_PORT |= (1 << MOSI) | (1 << MISO) | (1 << SCK) | (1 << SS);     // pulled up

    SPI_DDR |= (1 << MOSI) | (0 << MISO) | (1 << SCK) | (1 << SS);    // MOSI, SCK, SS output mode

    

    // SPI enable, set Master, fosc / 4    

    SPCR |= (0 << SPIE) | (1 << SPE) | (0 << DORD) | (1 << MSTR) | (0 << CPOL) | (1 << CPHA) | (0 << SPR0);

}


void SPI_init_slave()

{

    SPI_PORT |= (1 << MOSI) | (1 << MISO) | (1 << SCK) | (1 << SS);     // pulled up

    SPI_DDR = (1 << MISO);  // MISO output mode

    

    // SPI enable, set Slave    

    SPCR |= (0 << SPIE) | (1 << SPE) | (0 << DORD) | (0 << MSTR) | (0 << CPOL) | (1 << CPHA) | (0 << SPR0); 

}




unsigned int SPI_IO_master(unsigned int byte)

{

    unsigned int ad_value;

    unsigned char Mbyte, Lbyte; 

      

    SPI_PORT &= ~(1 << SS); //slave select low (통신할 수 있는 상태를 만듬)

      

    SPDR = (byte >> 8);                     

    while(!(SPSR & 0x80)); 

    Mbyte = SPDR;


    SPDR = byte;

    while(!(SPSR & 0x80)); 

    Lbyte = SPDR;

    

    ad_value = ((Mbyte << 8) | Lbyte);

    

    SPI_PORT |= (1 << SS);


    return ad_value;

}


unsigned int SPI_IO_slave(unsigned int byte)

{

    unsigned int ad_value;

    unsigned char Mbyte, Lbyte;

    

    SPDR = (byte >> 8);

    while(!(SPSR & 0x80));

    Mbyte = SPDR;


    SPDR = byte;

    while(!(SPSR & 0x80));

    Lbyte = SPDR;

                 

    ad_value = ((Mbyte << 8) | Lbyte);

    

    return ad_value;

}


------------------------------------------- master.c --------------------------------------------


#include <stdio.h>

#include <delay.h>

#include <mega128.h>xx  

#include "spi.h"



void UARTInit();          


void main()

{  

    unsigned int test = 2010;

    unsigned int rtn, cnt = 0;

 

    PORTA = 0x01;   

    DDRA = 0x0f;

    

    SPI_init_master();

    UARTInit();

    

    while(1){

        rtn = SPI_IO_master(test);

        delay_us(50);

                             

        //if (rtn != 4050) PORTA ^= 0x01;        

        //printf("%u \r\n", rtn);                

    }

}

     

void UARTInit()

{

    UCSR0A = 0x0;

    UCSR0B = 0b00001000;

    UCSR0C = 0b00000110;

    UBRR0H = 0;

    UBRR0L = 8;

}


----------------------------------------------- slave.c -----------------------------------------------


#include <stdio.h>

#include <delay.h>

#include <meag128.h>

#include "spi.h"


void UARTInit();


void main()

{

unsigned int test2 = 4050;

unsigned int rtn;


DDRA = 0xff;

PORTA = 0x01;


SPI_init_slave();

UARTInit();


while(1){

rtn = SPI_IO_slave (test2);


if (rtn != 2010) PORTA ^= 0x01;

}

}



void UARTInit()

{

    UCSR0A = 0x0;

    UCSR0B = 0b00001000;

    UCSR0C = 0b00000110;

    UBRR0H = 0;

    UBRR0L = 8;

}

'MCU > AVR' 카테고리의 다른 글

부트로더란?  (0) 2016.08.06
내부 풀업 저항 (I/O 포트)  (0) 2016.04.19
펌웨어와 임베디드  (0) 2015.05.29
인터럽트 한개로 다수의 RC 서보 제어  (0) 2013.12.17
[AVR] 데이터 손실  (0) 2013.12.12
Posted by 나무길 :