'Real Time OS'에 해당되는 글 2건

  1. 2017.12.19 Cortex-M4 환경에서 ChibiOS 사용한 기초 예제
  2. 2017.12.16 Firmware와 RTOS의 차이점
Embedded Programming/ChibiOS2017. 12. 19. 19:29


http://www.playembedded.org/blog/en/2017/08/24/demos-chibios-stm32/

http://www.playembedded.org/blog/en/2016/10/29/explanation-multithreading-chibios/


Cortex-M4 MCU(ST32F4)를 환경에서 Real Time OS(RTOS)인 ChibiOS를 이용한 임베디드(embedded) 시스템의 코딩의 예제입니다. 참고하시기 바랍니다.

 

주요 헤더 파일입니다.

chconf.h

Kernel에 관련된 세팅이 포함되며 예를 들어 시스템 Timer와 Kernel 파라미터, 디버깅에 연관된 스위치 등입니다.

/*===========================================================================*/
/**
* @name Debug options
* @{
*/
/*===========================================================================*/
 
/**
* @brief   Debug option, kernel statistics.
*
* @note    The default is @p FALSE.
*/
#define CH_DBG_STATISTICS                   FALSE
 
/**
* @brief   Debug option, system state check.
* @details If enabled the correct call protocol for system APIs is checked
*          at runtime.
*
* @note    The default is @p FALSE.
*/
#define CH_DBG_SYSTEM_STATE_CHECK           FALSE
 
/**
* @brief   Debug option, parameters checks.
* @details If enabled then the checks on the API functions input
*          parameters are activated.
*
* @note    The default is @p FALSE.
*/
#define CH_DBG_ENABLE_CHECKS                FALSE
 
/**
* @brief   Debug option, consistency checks.
* @details If enabled then all the assertions in the kernel code are
*          activated. This includes consistency checks inside the kernel,
*          runtime anomalies and port-defined checks.
*
* @note    The default is @p FALSE.
*/
#define CH_DBG_ENABLE_ASSERTS               FALSE
 
/**
* @brief   Debug option, trace buffer.
* @details If enabled then the trace buffer is activated.
*
* @note    The default is @p CH_DBG_TRACE_MASK_DISABLED.
*/
#define CH_DBG_TRACE_MASK                   CH_DBG_TRACE_MASK_DISABLED
 
/**
* @brief   Trace buffer entries.
* @note    The trace buffer is only allocated if @p CH_DBG_TRACE_MASK is
*          different from @p CH_DBG_TRACE_MASK_DISABLED.
*/
#define CH_DBG_TRACE_BUFFER_SIZE            128
 
/**
* @brief   Debug option, stack checks.
* @details If enabled then a runtime stack check is performed.
*
* @note    The default is @p FALSE.
* @note    The stack check is performed in a architecture/port dependent way.
*          It may not be implemented or some ports.
* @note    The default failure mode is to halt the system with the global
*          @p panic_msg variable set to @p NULL.
*/
#define CH_DBG_ENABLE_STACK_CHECK           FALSE
 
/**
* @brief   Debug option, stacks initialization.
* @details If enabled then the threads working area is filled with a byte
*          value when a thread is created. This can be useful for the
*          runtime measurement of the used stack.
*
* @note    The default is @p FALSE.
*/
#define CH_DBG_FILL_THREADS                 FALSE
 
/**
* @brief   Debug option, threads profiling.
* @details If enabled then a field is added to the @p thread_t structure that
*          counts the system ticks occurred while executing the thread.
*
* @note    The default is @p FALSE.
* @note    This debug option is not currently compatible with the
*          tickless mode.
*/
#define CH_DBG_THREADS_PROFILING            FALSE
 

/** @} */


halconf.h

ChibiOS/HAL 드라이버에 관련된 특성을 포함합니다. 예를 들어, PAL, CAN, ADC, DAC, PWM, Serial 드라이버 등이 해당됩니다. 참고로 사용하지 않는 드라이버는 disable 시켜야 합니다.


/**
* @brief   Enables the PAL subsystem.
*/
#if !defined(HAL_USE_PAL) || defined(__DOXYGEN__)
#define HAL_USE_PAL                 TRUE
#endif
 
/**
* @brief   Enables the ADC subsystem.
*/
#if !defined(HAL_USE_ADC) || defined(__DOXYGEN__)
#define HAL_USE_ADC                 FALSE
#endif
 
/**
* @brief   Enables the CAN subsystem.
*/
#if !defined(HAL_USE_CAN) || defined(__DOXYGEN__)
#define HAL_USE_CAN                 TRUE
#endif
 
/**
* @brief   Enables the DAC subsystem.
*/
#if !defined(HAL_USE_DAC) || defined(__DOXYGEN__)
#define HAL_USE_DAC                 FALSE

#endif


mcuconf.h

MCU에 관련된 모든 설정을 포함합니다. 따라서 MCU에 따라 다릅니다. Clock 트리, DMA, IRQ 우선순위 등이 예입니다.


ChibiOS의 가장 중요한 특성 중의 하나는 멀티스레딩(multi-threading)입니다. 이는 Kernel이 한가지 이상의 스레드를 독립적으로 나란히 동시에 실행하는 것입니다. 스레드는 실제의 함수이고 시작되었을 때 우선순위 레벨(priority level)과 working area에 연관됩니다. Working area는 스레드에 할당된 메모리의 부분이고 우선 순위는 상대적인 숫자로 나타냅니다.


모든 스레드는 그 루프 내에 sleep과 suspending 함수를 가져야 합니다. 이런 방식으로 CPU의 소유권은 여러 스레드 사이에서 스위치 되고 스케쥴은 진행될 수 있습니다. ChibiOS는 다른 sleep 함수를 제공합니다. 다음 함수는 XXX [ms] 시간 동안 스레드를 suspending 합니다. 이 함수는 ChibiOS 이하의 os\rt\include\chthreads.h에 선언되어 있습니다.


chThdSleepMilliseconds(<xxx>);


Makefile

Embitz와 같은 IDE 환경을 사용시 일일이 지정해야 하고 IDE 툴마다 다를 수 있지만, 전통적인 Unix 환경에서 Makefile을 이용한 방법이 일목요연하고 유지관리가 용이하기 때문에 Makefile을 이용한 빌드 기준으로 설명합니다.


ChibiOS를 사용하기 위해서는 ChibiOS가 설치된 상대 경로의 지정이 필요합니다. 

# Imported source files and paths
PROJECT = build
CHIBIOS = ../../..
MCU = cortex-m4
TRGT = arm-none-eabi-


참고로 'build'는 프로젝트 이름이며 MCU는 cortex-m4이고 TRGT는 GNU Toolchain을 사용함을 의미합니다.

main.c

static THD_WORKING_AREA(waThread1, 128);
static THD_FUNCTION(Thread1, arg) {
 
  (void)arg;
  chRegSetThreadName("Thread1");
  while (true) {
    palTogglePad(GPIOA, GPIOA_LED_GREEN);
    chThdSleepMilliseconds(200);
  }
}
 
int main(void) {
  halInit();
  chSysInit();
 
  chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO + 1, Thread1, NULL);
  while (true) {
    palTogglePad(GPIOA, GPIOA_LED_RED);
    chThdSleepMilliseconds(375);
  }

}


위의 예제에서 128byte의 크기를 갖는 waThread1라는 이름의 working area를 선언하고 Thread1이라는 함수를 선언합니다. 위의 두 라인은 단지 메모리와 함수를 선언한 것이며 main() 함수에서 thread 생성을 시켜야 사용할 수 있습니다. THE_FUNCTION의 arg는 함수 내부 코드로 전달되는 인자입니다.


chRegSetThreadName("blinker");


위 함수는 루프 이전에 단 한번 실행됩니다. 이 함수는 ChibiOS 이하의 os\rt\include\chregistry.h에 선언되어 있습니다.



main()함수 내의 2가지 함수가 실행되는데 이는 시스템 초기화를 실행하는 것으로, hallnit()는 ChibiOS/HAL과 HAL 서브 시스템을 초기화 하는 것이며 chSysInit()는 ChibiOS/RT의 API와 Kernel을 초기화합니다. 이후에는 main() 함수의 스레드와 다른 모든 스레드가 실행될 준비가 되지 않았을 때 실행되는 idle 스레드가 생성됩니다. 또한 이들 초기화 이전에 어떤 API의 실행은 하지 말아야 합니다. ChibiOS/RT 그리고 ChibiOS/HAL에 근거한 모든 프로그램은 위와 동일한 방식으로 시작합니다. 여기서 halInit() 함수는 ChibiOS 이하의 os\hal\include\hal.h에 그리고 chSysInit() 함수는 ChibiOS 이하의 os\rt\include\chsys.h에 선언되어 있습니다.


palTogglePad() 함수는 ChibiOS 이하의 os\hal\include\hal_pal.h에 선언되어 있으며, 첫번째 인자는 포트이고 두번째 인자는 그 포트 내에서의 패드 숫자입니다. 따라서 이 함수는 해당 포트의 해당 패드에 그 논리적인 상태 즉, LED를 토글(toggle)합니다.



chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO + 1, Thread1, NULL);


위의 스레드의 생성 함수는 5개의 인자가 필요하며 첫번째는 working area의 포인트이며 마지막 인자는 Thread1 함수로 전달될 파라미터로 이 경우에는 아무것도 보내지 않습니다. 이 함수는 ChibiOS 이하의 os\rt\include\chthreads.h에 선언되어 있습니다.


이 경우에 3개의 스레드인, Thead1, main, idle가 있으며 즉, Kernel은 3가지 스레드를 관리게 되는데 개념적인 timing 플로우는 다음과 같습니다.



위 그림에서 스레드는 y축 상에 우선순위에 따라 실행되고 x축은 시간이 됩니다. chSysInit()이 실행될 때 main() 함수는 main이라는 스레드가 되고 Thread1의 생성될 때까지 실행됩니다. Thread1이 생성된 후에는 main와 Thread1이 준비된 상태가 됩니다. 


ChibiOS의 우선순위는 정수이고 LOWPRIO와 HIGHPRIO의 범위를 가지며 main 스레드는 NORMALPRIO의 우선 순위를 가지며 전체 범위의 중간 값을 가집니다. Thread1과 main() 함수 내에 chThdSleepMilliseconds() 함수는 시간을 지연시키지만 그 동안 CPU의 소유권을 다음의 우선순위 스레드에 넘기게 됩니다.



'Embedded Programming > ChibiOS' 카테고리의 다른 글

ChibiOS/RT 설치  (1) 2018.02.25
ChibiOS/RT의 특징  (0) 2018.02.25
Posted by Nature & Life


임베디드(Embedded)나 펌웨어 궁극적으로는 둘다 작은 시스템 내에 하드웨어 제어를 위해 EEPROM 등에 기록되는 일종의 프로그램입니다. 거의 같다라고 봐도 무방합니다. 하지만 근래 들어서 시스템의 복잡화로 인해 기존의 펌웨어를 제작할 때 사용되는 프로그래밍 방식 '슈퍼루프 방식'은 프로그래머의 체계적인 프로그램 설계와 짜임세 있는 구성이 프로그래머를 피곤하게 할 만큼 복잡하게 되었습니다.


이에 대한 대안으로서 나온 것이 RTOS(Real Time OS)라는 것인데 ROM에 기록되는 펌웨어 중에서도 특히 이런 RTOS를 이용한 것을 임베디드(내장형 시스템)라 칭하는 경우가 많습니다. RTOS를 사용하게 되면 ROM에 기록되어야 할 펌웨어의 크기가 커지고, 시스템 오버해드라 하여 불필요한 부하를 가져다 주게 됩니다. 하지만, 펌웨어 개발의 융통성과, 안정성, 정확성을 고려할 때 펌웨어의 크기나 시스템 오버해드는 충분이 무시할 수 있는 요소가 된다는 것입니다.


대표적인 RTOS인 ChibiOS


RTOS를 이용한 임베디드 시스템은 꼭 ARM같이 거대한 프로세서에만 사용되는 것은 아닙니다. 상당히 유명한 uCOS-II경우 구식 8051부터 Intel 32bit까지 다양한 플랫폼을 지원합니다. 8051계열에도 얼마든지 임베디드 시스템을 펌웨어로 올릴 수 있습니다.


펌웨어는 일반적으로 롬(ROM)에 저장된 하드웨어를 제어하는 마이크로 프로그램을 의미합니다. 프로그램이라는 관점에서는 소프트웨어와 동일하지만 하드웨어와 밀접한 관계를 가지고 있다는 점에서 일반 응용 소프트웨어와 구분되어 펌웨어는 소프트웨어와 하드웨어의 특성을 모두 가지고 있다고 할 수 있습니다.


예를 들어 어떤 기능을 발휘하는 하드웨어를 만든다고 할 때, 그것을 제어하는 모든 회로를 하드웨어로만 만들면, 그 구조도 대단히 복잡해지고 심지어는 논리적인 표현을 하기가 어려운 부분도 발생합니다. 이런 경우 상당부분을 소프트웨어로 대체하되 그 소프트웨어가 저장된 기억장치를 하드웨어의 제어회로 중의 중심부분으로 구성하면, 매우 간단하면서도 적은 비용으로 문제를 해결할 수 있게 됩니다. 이렇게 만든 하드웨어적인 소프트웨어를 펌웨어라 합니다.


이렇게 할 경우 하드웨어의 입장에서는 별도의 논리회로를 가진 것이 아니기 때문에 소프트웨어적인 특성을 가지고 있지만, 소프트웨어 입장에서는 마이크로 프로그램이 하드웨어를 제어하기 때문에 하드웨어적인 특성을 가진다고 설명할 수 있습니다.


소프트웨어의 기능을 펌웨어로 변경할 수 있으면 속도가 현저하게 증대되어 고속 처리가 필요한 프로그램은 펌웨어로 만들어 사용하기도 합니다. 또한 하드웨어의 기능을 펌웨어로 변경하면 속도는 느려지지만, 그 기능을 위한 논리회로를 설계하여 사용하는 것보다 저렴하고, 편리하게 구현하여 사용할 수 있는 장점을 가지기도 한다는 것입니다.




'Embedded Programming > Environment' 카테고리의 다른 글

왜 RTOS가 필요한가?  (0) 2018.01.31
Posted by Nature & Life