2009. 12. 22. 14:17


'[B-01] Quad-rotor' 카테고리의 다른 글

Headholding  (0) 2009.12.22
Tilt-camera  (0) 2009.12.22
Indoor flying  (0) 2009.12.22
GPS용 지도 만들기 입문  (0) 2009.12.04
XBee-Pro의 RSSI 측정  (0) 2009.12.03
Posted by eoseontaek
2009. 12. 22. 14:07


'[B-01] Quad-rotor' 카테고리의 다른 글

Tilt-camera  (0) 2009.12.22
Outdoor flying  (0) 2009.12.22
GPS용 지도 만들기 입문  (0) 2009.12.04
XBee-Pro의 RSSI 측정  (0) 2009.12.03
256-MBIT SYNCHRONOUS DRAM - IS42S16160B  (0) 2009.11.12
Posted by eoseontaek
2009. 12. 21. 20:49

무료 FTP 프로그램







'[Z-01] 참고 ' 카테고리의 다른 글

今臣戰船尙有十二  (0) 2009.12.28
__attribute__((packed))  (0) 2009.12.28
[UTIL] EASEUS Partition  (0) 2009.12.21
SAMPLE 전자에서 판매되는 각종 센서 모음 사이트  (0) 2009.12.08
Kernel을 Porting 한다는 것  (0) 2009.12.04
Posted by eoseontaek

무료 파티션 툴







'[Z-01] 참고 ' 카테고리의 다른 글

__attribute__((packed))  (0) 2009.12.28
[UTIL] FileZilla  (0) 2009.12.21
SAMPLE 전자에서 판매되는 각종 센서 모음 사이트  (0) 2009.12.08
Kernel을 Porting 한다는 것  (0) 2009.12.04
DPC(Deferred Procedure Call)  (0) 2009.12.04
Posted by eoseontaek
Posted by eoseontaek

ST 라이브러리의 도움말 파일에는 다음과 같이 정의하고 있다.


High Speed APB(APB2) peripheral clock을 Enable 또는  Disable 한다.

RCC_APB2Periph는 RCC_APB2Periph clock를 gate로 하는 APB2 peripheral을 나타낸다. 이 parameters는 아래의 값들로 조합될 수 있다.
RCC_APB2Periph_AFIO,
RCC_APB2Periph_GPIOA,
RCC_APB2Periph_GPIOB,
RCC_APB2Periph_GPIOC,
RCC_APB2Periph_GPIOD,
RCC_APB2Periph_GPIOE,
RCC_APB2Periph_GPIOF,
RCC_APB2Periph_GPIOG,
RCC_APB2Periph_ADC1,
RCC_APB2Periph_ADC2,
RCC_APB2Periph_TIM1,
RCC_APB2Periph_SPI1,
RCC_APB2Periph_TIM8,
RCC_APB2Periph_USART1,
RCC_APB2Periph_ADC3

NewState는 specified peripheral clock의 새로운 state를 나타낸다. 이 parameter는 ENABLE 또는 DISABLE이 될 수 있다.

stm32f10x_rxx.c 파일의 1059 라인에 정의되어 있고, FSMC_NAND_Init(), FSMC_NOR_Init(), FSMC_SRAM_Init(), I2C_EE_Init(), IOE_EXTI_Config(), IOE_GPIO_Config(), LCD_CtrlLinesConfig(), LCD_SPIConfig(), main(), RCC_Configuration(), SPI_FLASH_Init(), STM_EVAL_COMInit(), STM_EVAL_LEDInit(), and STM_EVAL_PBInit() 에 의해 참조된다.




Posted by eoseontaek

ST 라이브러리 도움말 파일에는 다음과 같이 정의하고 있다.


다른 시스템 clock을 configure 한다.



Posted by eoseontaek

system_stm32f10x.c파일에서 Frequency를 다음가 같이 설정하였다.

#define SYSCLK_FREQ_72MHz  72000000

따라서 SetSysClockTo72() 함수가 호출된다.

ST 라이브러리의 도움말 파일에는 다음과 같이 정의되어 있다.

System clock frequensy를 72MHz로 설정하고 HCLK, PCLK2, PCLK1 prescalers를 configure 한다.

Project/STM32F10x_StdPeriph_Examples/RCC/main.c 파일의 561라인에 정의되어 있고 ENABLE, FLASH_Latency_2, FLASH_PrefetchBuffer_Enable, FLASH_PrefetchBufferCmd(), FLASH_SetLatency(), HSEStartUpStatus, RCC_DeInit(), RCC_FLAG_PLLRDY, RCC_GetFlagStatus(), RCC_GetSYSCLKSource(), RCC_HCLK_Div1, RCC_HCLK_Div2, RCC_HCLKConfig(), RCC_HSE_ON, RCC_HSEConfig(), RCC_PCLK1Config(), RCC_PCLK2Config(), RCC_PLLCmd(), RCC_PLLConfig(), RCC_PLLMul_9, RCC_PLLSource_HSE_Div1, RCC_SYSCLK_Div1, RCC_SYSCLKConfig(), RCC_SYSCLKSource_PLLCLK, RCC_WaitForHSEStartUp(), RESET, and SUCCESS.를 참조한다.

Posted by eoseontaek

ST에서 제공하는 라이브러리 도움말 파일에 다음과 같이 정의되어 있다.

System clock frequency, HCLK, PCLK2, PCLK1 prescalers를 configures 한다.

 Project/STM32F10x_StdPeriph_Examples/RCC/main.c의 130 라인에 정의되어 있고, SetSysClockTo24(), SetSysClockTo36(), SetSysClockTo48(), SetSysClockTo56(), SetSysClockTo72(),  SetSysClockToHSE() 를 참조한다.


Posted by eoseontaek


SystemInit() 함수에 대해서 분석해 보고자 한다.
우선 ST에서 제공하는 라이브러리에 포함된 도움말 파일에는 다음과 같이 정의하고 있다.


microcontroller system을 setup 한다.
    - Embedded Flash Interface와 PLL을 초기화
    - SystemFrequency variable을 update

system_stm32f10x.c 파일의 185 라인에 정의되어 있고, RCC와 SetSysClock() 를 참조하고, main()에서 참조된다고 나와 있다.

Posted by eoseontaek


STM 라이브러리에서 제공하는 Clock 초기화 관련 함수들을 이용해서 72MHz의 시스템 클럭을 설정하는 방법에 대하여 알아보았다.

먼저 STMicroelectronics 홈페이지에 가서 라이브러리를 다운 받는다. 
Link : http://www.st.com/mcu/devicedocs-STM32F103RB-110.html


위의 링크에 가서 STM32F10x_StdPeriph_Lib 를 다운받으면 된다.

다운로드 후에는 아래와 같이 프로젝트를 생성하고 다음 절차에 따라 진행하면 된다.


첫번째,
system_stm32f10x.c 와 startup_stm32f10x_md.s 을 컴파일러에 포함한다.



두번째,
stm32f10x.h 파일에서 아래 부분을 활성화한다.

/* Uncomment the line below according to the target STM32 device used in your application  */

#if !defined (STM32F10X_LD) && !defined (STM32F10X_MD) && !defined (STM32F10X_HD) && !defined (STM32F10X_CL)
  /* #define STM32F10X_LD */   /*!< STM32F10X_LD: STM32 Low density devices */
#define STM32F10X_MD         /*!< STM32F10X_MD: STM32 Medium density devices */
  /* #define STM32F10X_HD */   /*!< STM32F10X_HD: STM32 High density devices */
  /* #define STM32F10X_CL */   /*!< STM32F10X_CL: STM32 Connectivity line devices */
#endif

STM32F103RB는 medium density devices이므로 STM32F10X_MD를 활성화 해주어야 한다.


세번째,
stm32f10x.h 파일에 아래와 같이 추가한다.

/**
 * @brief In the following line adjust the value of External High Speed oscillator (HSE)
   used in your application
  
   Tip: To avoid modifying this file each time you need to use different HSE, you
        can define the HSE value in your toolchain compiler preprocessor.
  */    
#define EXT_CLOCK_SOURCE_12M
  
#if !defined  HSE_Value
 #ifdef STM32F10X_CL  
  #define HSE_Value    ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */
 #else
  #ifdef EXT_CLOCK_SOURCE_12M  
    #define HSE_Value   ((uint32_t)12000000) /*!< Value of the External oscillator in Hz */
  #else
    #define HSE_Value    ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */     
  #endif 
 #endif /* STM32F10X_CL */
#endif /* HSE_Value */

현재 사용중인 보드는 외부에 12MHz의 crystal을 사용하므로 HSE_Value를 12000000으로 설정하고 나중에 사용하게 된다.


네번째,
system_stm32f10x.c 파일을 아래와 같이 수정한다.

/* #define SYSCLK_FREQ_HSE    HSE_Value */
/* #define SYSCLK_FREQ_24MHz  24000000 */
/* #define SYSCLK_FREQ_36MHz  36000000 */
/* #define SYSCLK_FREQ_48MHz  48000000 */
/* #define SYSCLK_FREQ_56MHz  56000000 */
#define SYSCLK_FREQ_72MHz  72000000

SYSCLK_FREQ_72MHz를 72000000으로 설정해 놓았으므로,
SetSysClockTo72()함수가 호출된다.


다섯번째,
system_stm32f10x.c 파일의 SetSysClockTo72() 함수를 아래와 같이 수정한다.

#elif defined SYSCLK_FREQ_72MHz
/**
  * @brief  Sets System clock frequency to 72MHz and configure HCLK, PCLK2
  *          and PCLK1 prescalers.
  * @note   This function should be used only after reset.
  * @param  None
  * @retval None
  */
static void SetSysClockTo72(void)
{
  __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
 
  /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/   
  /* Enable HSE */   
  RCC->CR |= ((uint32_t)RCC_CR_HSEON);
 
  /* Wait till HSE is ready and if Time out is reached exit */
  do
  {
    HSEStatus = RCC->CR & RCC_CR_HSERDY;
    StartUpCounter++; 
  } while((HSEStatus == 0) && (StartUpCounter != HSEStartUp_TimeOut));

  if ((RCC->CR & RCC_CR_HSERDY) != RESET)
  {
    HSEStatus = (uint32_t)0x01;
  }
  else
  {
    HSEStatus = (uint32_t)0x00;
  } 

  if (HSEStatus == (uint32_t)0x01)
  {
    /* Enable Prefetch Buffer */
    FLASH->ACR |= FLASH_ACR_PRFTBE;

    /* Flash 2 wait state */
    FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
    FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;   

 
    /* HCLK = SYSCLK */
    RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
     
    /* PCLK2 = HCLK */
    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
   
    /* PCLK1 = HCLK/2 */
    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;

#ifdef STM32F10X_CL
    /* Configure PLLs ------------------------------------------------------*/
    /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */
    /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */
       
    RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL |
                              RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC);
    RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 |
                             RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5);
 
    /* Enable PLL2 */
    RCC->CR |= RCC_CR_PLL2ON;
    /* Wait till PLL2 is ready */
    while((RCC->CR & RCC_CR_PLL2RDY) == 0)
    {
    }
   
  
    /* PLL configuration: PLLCLK = PREDIV1 * 9 = 72 MHz */
    RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL);
    RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 |
                            RCC_CFGR_PLLMULL9);
#else  
   
    /*  PLL configuration: PLLCLK = HSE * 9 = 72 MHz */
    /*  if EXT_CLOCK_SOURCE_12M, PLL configuration: PLLCLK = HSE * 6 = 72 MHz */
    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE |
                                        RCC_CFGR_PLLMULL));


  #ifdef  EXT_CLOCK_SOURCE_12M
    RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL6);
  #else    
    RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9);
  #endif 
   
#endif /* STM32F10X_CL */

    /* Enable PLL */
    RCC->CR |= RCC_CR_PLLON;

    /* Wait till PLL is ready */
    while((RCC->CR & RCC_CR_PLLRDY) == 0)
    {
    }
   
    /* Select PLL as system clock source */
    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
    RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;   

    /* Wait till PLL is used as system clock source */
    while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)
    {
    }
  }
  else
  { /* If HSE fails to start-up, the application will have wrong clock
         configuration. User can add here some code to deal with this error */   

    /* Go to infinite loop */
    while (1)
    {
    }
  }
}
#endif

외부에 12MHz의 crystal을 사용하므로 PLLMUL6으로 하여 12000000MHz * 6 = 72000000MHz를 사용할 수 있게 된다.



모든 설정이 끝나면 다시 빌드하여 프로그램을 실행해 본다.






Posted by eoseontaek

Link :  http://cafe.naver.com/carroty.cafe


kmz51_example1을 기준으로 avr 소스 수정

C#에서 가끔 에러 나는거 잡기 : 도대체 이유를 모르것음

 

구동 방법

뭐 AVR에 프로그램 넣고, C# 프로그램 구동하면 된다.





Posted by eoseontaek

Link : http://cafe.naver.com/carroty.cafe

* AVR Program

AVR측 프로그램입니다. I2C가 완성되지 않았기 때문에 별거 없어요.

스위치 입력 받을때마다 시리얼 포트로 @090!, @180!, @270!, @360!을 전송하게 되어있습니다.

I2C를 짠다음에 또 올려보도록 하죠.

 

* Future Works

1. 프로그램을 안전하게 종료시키기

  프로그램을 닫을때 시리얼 포트 및 모든 자원을 해제 해야 하는데, 대충 닫았습니다.

  종종 다시 시리얼 포트가 열릴때 문제가 생깁니다. ^^

  급하게 만들다 보니 이런실수가.. 크흑

 

2. 시리얼 클래스를 외부로 뽑기

  여기저기서 시리얼 클래스를 쓰는데, 매번 코드 복사하는것도 번거로와서, 뭔가 해결책을 찾아야 하는데 말이죠 ^^

  걍 클래스로만 만들어도 되나요? 뭐 DLL 이런걸로 만들어야 되나요?

 

3. C#에서 파싱하기

  AVR에서 쑥떡같이 보내도 C#에서 찰떡같이 알아듣기

  현재는 이렇게 보냅니다. @XYZ! XYZ는 각각 100의 자릿수, 10의 자릿수, 1의 자리수..

  고로, 45를 보내려고 해도, @45! 하믄 안되고, @045!와 같이 보내야 합니다.

  왜냐하면, C#에서

  if(str.StartsWidt(@)||str.EndsWidth(!)) { ...

    str.SubString(1,3);

  이렇게 읽기 때문이죠.

 

4. AVR에서 문자열  입력 받기

  도대체 하이퍼 터미널에서 "200" 이라고 문자열을 입력하면 AVR에서 어떻게 200이라고 알수 있을까요?

  문제는 입력되는 숫자가 가변적임, 즉 "3"이 올수도 있고, "45910"이 올수도 있음. 물론 끝에 엔터는 들어감

  문자열 보내는 것도 짜증나고, 받는 것도 짜증나요.

  긍까 하이퍼 터미널에서 문자열로 30이 오면 AVR에서 숫자로 30을 받고 싶다는 거죠

 

5. 지자기 센서 읽기

  데이터 쉬트 보고 읽으면 되지 않을까요? ^^






Posted by eoseontaek

Link : http://cafe.naver.com/carroty.cafe


전체 구조는 위와 같습니다.

지자기 센서의 I2C 출력값을 ATmega32에서 받아서, PC로 시리얼 통식 방식으로 쏩니다.

이 값을 받아서 PC 어플리케이션이 처리합니다.

PC 어플리케이션은 C#, VB, C++ 원하시는 툴로 짜면 됩니다. 당근이는 C#으로 짰음.

아래 예제가 있음돠.

 

 

이거 예제 짤때 쪼까 고생했는데, 고생한 목록은 다음과 같습니다.

1. 시계 모양으로 땡구라미를 그리는게 좀 힘들었습니다. 위의 조그만 동그라미들은 이미지가 아니라 좌표 계산하여 그린겁니다.

  고로, 프레임을 확대 축소해도 깨지지 않아요. 동구라미 좌표 그릴때 등방성 좌표계를 이용한다는데.. 거 뭔말인지..

2. 트랙바로 움직이게 했는데, 트랙바보다는 vertical Slider가 더 이쁜거 같더군요. (뭐야 이건 어려운게 아니잖아!)

3. 설명드리기가 곤란한데, 가장 복잡했던점이..

  당근이가 만든 Compass 클래스에서 OnPaint 메소드를 호출했더니, 자꾸 에러가 나더군요.

  UsrControl을 상속받아야 했구요.

  처음에는 패널의 Graphics 객체를 Compass에서 받아와서 처리했는데, 보통 그렇게 하지 않더군요.

  걍 Compass의 Graphics에서 createGraphics를 한 이후에 Compass를 생성할때 Graphics를 넘겨주는 방식..

  조금 버벅 댔음

4. 더블 버퍼링.. 그래도 조금 어려울줄 알았는데, 한줄이면 되더군요. ㅜㅠ

 

아래는 소스 짜는 중 이것 저것 캡쳐해본검돠.

초기 버젼 : 아직 시리얼을 못 붙였음

 

개선중 : 패널 제거작업 (크하하.. 패널 뒤에 있어서 안그려지는 알고 거의 30분 삽질 ㅜㅠ)

 

최종 버젼

 

예제 소스 설명

1. 초기 프로토 타입 : 클래스 설계 개판

2. 어쨌든 움직이게 했다.

3. 더블 버퍼링

4. 시리얼 입력 받음 : 옆의 슬라이더와 동시에 받음

 

현재 작업 내역

컴 마스터로 당근보드의 스위치를 누르면 이 값이 PC의 C# 프로그램으로 갑니다.

그라무네, 나침반이 90, 180, 270, 360도 이렇게 움직입니다. 버튼이 뭐 4개밖에 없어서 걍 편하게 짰음

서서히 정회전 역회전 할수도 있지만, 나중에 하기로 하고 오늘은 여기까지 !



Posted by eoseontaek

Link : http://cafe.naver.com/carroty.cafe


CMPS03 지자기 센서를 이용한 방위각 측정을 해보려고 합니다.

2008.06.28 현재 센서값을 읽지는 못했습니다. 좀 시간내서 더 짜봐야 할듯요. I2C 하기 싫어서.. ㅜㅠ

환경은 알아서 구성해 주세요.

당근이는 XP, Visual Studio 2005 C#, AvrStudio ?.?.14, 당근보드, 뭐 이렇게 사용합니다.

 

일단 CMPS03 라는 놈이 모냐? 쉽게 설명하면 "Compass(나침반)"이라고 생각하면 됩니다.

http://www.touchsensor.co.kr/robotelec/se-cmps.htm

조기서 판매하고 있고요. 각종 자료나 소스도 제공해 줍니다. 물론 BASCOM이나 VB를 안쓰기 때문에, 당근이는 그닥 필요가.. ㅜㅠ

 

데이터 포맷은 아직 데이터 쉬트를 못봐서 모르겠지만, 북쪽이면 0, 남쪽이면 180 뭐 이렇게 나오지 않을까 싶네요. 사진 함 구경해 보죠.

 

 

 

요로코롬 생긴놈입니다. PIC를 제거하면 엄지 손톱만 해지지도 않을까 생각해 봅니다.

누가 PCB 비용이라도 주믄 함 만들어 보겠다. ㅋㅋㅋ

흠. 지자기 센서가 I2C를 지원안하니까, PIC는 꼭 있어야 하나? 어쩌나? 흠 모르것다.

 

핀 디스크립션은 위와 같구요.

NC는 도대체 왜 뽑아놓은건지..

얘는 I2C로 출력하므로, I2C 포맷을 알아야 합니다.

제어에 대한 자세한 내용은 데이터쉬트를 참조.. ^^

 

다음에는 프로그램 함 보도록 하죠.

Visual Studio가 없으신 분들은 첨부파일을 다운로드 하여 실행해 보면 됩니다.

옆의 슬라이더를 움직이면, 바늘이 움직입니다.

즉, 지자기 센서의 값을 읽어서 슬라이더를 움직이는 것과 동일한 이벤트를 발생시키겠다는 거죵. 대략 이해가 가시겠죠?

 



Posted by eoseontaek

'[Z-01] 참고 ' 카테고리의 다른 글

[UTIL] FileZilla  (0) 2009.12.21
[UTIL] EASEUS Partition  (0) 2009.12.21
Kernel을 Porting 한다는 것  (0) 2009.12.04
DPC(Deferred Procedure Call)  (0) 2009.12.04
Call Back Function  (0) 2009.12.04
Posted by eoseontaek

PM0056 Programming manual
STM32F10xxx Cortex-M3 programming manual



Link : http://www.st.com/stonline/products/literature/pm/15491.pdf


Posted by eoseontaek

Link : http://recipes.egloos.com/5100880


임베디드 시스템에 입문해서 kernel을 포팅한다는 말을 많이 사용했던 것 같다.
그런데 막상 생각해보니 그 의미를 정확히 알고 있지 못했다.
친절한 임베디드 시스템 개발자 되기 강좌에서 간단하게 그 의미가 정리되어 있었다.
아래는 스킵한 내용이다.



Porting을 한다는 것은 이미 만들어져 있는 Software를 우리가 만들려는 Target에 동작할 수 있도록 잘 수정을 한다던가, 특정 Routine을 만든다던가 해서 Target에서 잘 동작할 수 있도록 만드는 걸 Porting이라고 부르더군요. 그러니까, Kernel을 만들기에는 시간이 부족하고, 돈도 많이 들고 하니까, 이미 만들어져 있는 Kernel을 우리의 Target에 제대로 동작하도록 만들고 있다는 뭐 그런 의미였던 것이었었던 것이죠.
 
그러면 만들어져 있던 Kernel을 우리의 Target에 제대로 동작하게 한다는 건 또 어떤 의미냐 하면, Linux Kernel을 예를 든다면, Linux Kernel은 Software  그 자체로서 어느 CPU든지 Compile만 새로 한다면 동작할 수 있도록 구성되어 있는데 고로 범용성이 높은 C로 짜여져 있는 경우가 대부분이에요. C는 많은 CPU들에서 C compiler를 제공하니까, 그냥 가져다가 우리 Target에 맞는 Compiler로 다시 Compile만 하면 되는 거죠. 그러면 어느 부분을 작업을 해야 Porting한다고 제대로 말할 수 있는 걸까요.
 
뭐 크게 예만 든다면,
ⓐ Interrupt Lock/ Unlock을 하는 방법은 CPU마다 다르겠죠.
ⓑ Context Switching 할 때 Backup 해야 하는 Context는 CPU마다 다르겠죠. (Register들이 CPU마다 다 천차만별일 테니까요.)
ⓒ Stack이 자라는 방향은 CPU마다 Compiler option마다 다르겠죠.
ⓓ SWI를 호출하는 방법이 CPU마다 다르겠죠.
ⓔ Interrupt가 걸린 후 처리 되는 방법도 CPU마다 틀리겠죠.
ⓕ 특히나 ARM같은 경우에는 Mode마다 사용되는 Stack도 따로 있으니 이 부분도 수정되어야 하고요.
ⓖ Watch dog Timer도 MCU마다 다른 시간 설정일 테니 이 부분도 잘 봐줘야 할 것이고요
.
 
뭐 이런 부분들이 따로 새로 만들어 지거나, 우리 Target에 맞도록 수정되어야 기존에 만들어져 있던 Kernel을 우리가 Target으로 하는 CPU에서 동작할 수 있도록 할 수 있는 것이죠. Kernel을 Porting하는 작업은 쉬운 작업이 아니에요. Kernel이 어떻게 동작하고 있는 지와, 우리가 Target으로 생각하는 CPU가 어떻게 동작하는지를 잘 알아야 가능한 일인 게죠.
 
어떤 특정 Kernel을 잡아서 어떻게 Porting 한다는 걸 보여주는 건 의미가 있을지도 모르겠습니다만, 저 같은 경우에는 관심 없는 Kernel 잡아서 보여주는 건 별로 흥미도 재미도 없더라고요. 위의 ⓐ~ⓖ 같은 것들을 들여다 봐야 한다만 알아도 Porting을 할 수 있는 기본 자세가 되었다고 보시면 무리 없다고 봐야 하지 않을까 싶습니다요.
Posted by eoseontaek

'[Z-01] 참고 ' 카테고리의 다른 글

SAMPLE 전자에서 판매되는 각종 센서 모음 사이트  (0) 2009.12.08
Kernel을 Porting 한다는 것  (0) 2009.12.04
Call Back Function  (0) 2009.12.04
친절한 임베디드 시스템 개발자 되기 강좌  (0) 2009.12.03
MOSFET  (0) 2009.12.02
Posted by eoseontaek

콜백의 기본 개념

일반적인 의미에서 콜백이란 호출자(Caller)가 피호출자(Callee)를 호출하는 것이 아니라 피호출자가 호출자를 호출하는 것을 말한다(<그림 1> 참조). 콜백이 많이 사용되는 전형적인 예는 WIN32 API이다. 대개의 경우 응용 프로그램이 WIN32 API를 호출하는 거서이 일반적이지만 때때로 윈도우 시스템이 응용 프로그램을 호출해야 할 때가 있다. 이때 응용 프로그램은 콜백 함수를 윈도우 시스템에게 알려주고 어떤 조건이 만족되면 윈도우 시스템이 콜백 함수를 호출해 준다. WIN32 API의 EnumWindow, SetTimer 함수 등이 콜백을 사용하며 윈도우 프로시저(window procedure) 역시 콜백 개념을 사용한다.

 

 

<그림 2>는 전형적인 콜백 메커니즘을 보여주고 있다. 콜백 메커니즘의 순서로써

(1) 호출자는 콜백 메서드의 참조(함수 포인터)를 매개 변수로 하여 피호출 메서드를 호출한다.

(2) 피호출 메서드는 매개 변수로 전달된 콜백 메서드에 대한 참조를 필드와 같은 곳에 기록해 둔다.

(3) 이제 콜백을 수행할 어떤 조건(이 조건은 다양할 수 있다)이 만족되면 ...

(4) 기록해 둔 콜백 메서드 참조를 이용하여 콜백 메서드를 호출하게 된다.

물론 모든 콜백이 <그림 2>와 같은 순서를 따르는 것은 아니지만 많은 경우 이와 같은 시나리오를 따르는 것이 일반적이다. 콜백을 수행할 조건을 만족하는지 지속적으로 검사하는 과정이 필요하기 때문에 별도의 스레드를 이용하는 경우가 대부분이며, 콜백 메서드를 호출하는 스레드 역시 조건을 검사하는 스레드이기 때문에

 콜백 메서드는 서로 다른 스레드에서 호출되는 것이 일반적이다. 이렇게 다중 스레드를 사용하기 때문에 비동기(asynchronous) 작업을 수행할 때 비동기 작업이 완료되었음을 알리기 위한 방법으로 콜백 메커니즘이 많이 사용되곤 한다.

 

참조: http://imaso.co.kr/?doc=bbs/gnuboard.php&bo_table=article&wr_id=29268

 

 

OS에 의해 직접 불려지는 함수를 CALLBACK 함수라고 한다. 예를 들면 WndProc 콜백 함수는 EVENT 발생시 OS에 의해 직접 호출되며, 이때 Message 종류와 내용을 Parameter로 전달 받는다.

 

Callback routines are defined by the user program, instructing the graphic system to call a specific function when a specific event occurs. Normally they are used to automatically redraw a window when its content has changed.

 

CALLBACK 함수는 메시지를 처리한다. 윈도우즈 자체가 메시지 기반으로 작동하기 때문에 우리가 아무것도 안하면 혼자  놀고 있다가 버튼이라도 하나 누르면 그 버튼 ID에 따른 처리를 해준다. 이런 처리를 해주는 부분이 CALLBACK 함수이다.

 

CALLBACK으로 선언된 함수는 윈도우 운영체제에서 특정한 사건이 발생될 때 운영체제로부터 호출돼는 함수이다. 예로 Timer가 있다. Timer는 사용자가 프로그램에서 얼마 간격으로 SetTimer를 설정하면 운영체제가 그 시간이 돼면 OnTimer 함수를 호출한다.

 

 

CALLBACK 함수는 불려지는 쪽에서 부르는 쪽의 데이터를 참조하거나 핸들링 하는 함수이다. 윈도우는 data segment와 code segment가 분리되어 있다. code는 공유를 하나 data는 공유 하지 않는다. 공유하게 되면 심각한 문제가 발생할 것이다. 그래서 나온 것이 CALLBACK 함수이다.

 

예를 들어 설명하면,
'A'라는 DLL이 'B'라는 DLL을 불러 쓰고 'A'라는 DLL에는 동적으로 메모리를 할당 받을 변수와 메모리를 할당하고 해제하는 함수가 있다고 가정하고 'B'라는 DLL에서 이 변수에 동적으로 메모리를 할당하고 처리하려 한다고 할 때 'B'에서 'A'의 변수를 인자로 받아 메모리를 할당하고 처리하는 것은 무의미 하거나 위험하다. 앞에서 말했듯이 'A'와 'B'는 서로 독립된 DATA SEGMENT를 갖기 때문이다. 그렇다면 B는 A의 메모리 할당 함수를 이용해서 A의 변수에 메모리를 할당하고 해제 해야한다. 여기에서 A에서 B로 넘겨주는 메모리 할당 함수를 CALLBACK 함수라고한다. 다시말해서 불려지는 쪽에서 부르는 쪽의 DATA를 참조하기 위한 교량 역할을 하는 것이 CALLBACK 함수인 것이다. WNDPROC가 CALLBACK 함수인 이유도 여기에 있다. 애플리케이션에 의해 불려지는 운영체제에서 디폴트 윈도우 프로시져의 위치에 부르는 함수이기 때문이다.

 


Posted by eoseontaek