2011년 4월 12일 화요일

FreeRTOS on LPC17xx 분석

  • Runtime Library의 구성
    • CMSIS(Cortex Microcontroller Software Interface Standard)
    • Microcontroller Startup code for use with Red Suite
    • Main() 루틴

    • CMSIS의 구성
      • startup_LPC17xx.s
        • __cs3_heap_start, __cs3_heap_end : Heap_Size(0x00001000) 만큼 할당된 Heap 영역의 초기주소와 마지막 주소
        • __cs3_interrupt_vector_cortex_m : 스택영역의 최상위 주소, 리셋 및 인터럽트 핸들러가 정의된 vector
        • _cs3_stack_mem, __cs3_stack_size : Stack_Size(0x00000100) 만큼 할당된 Stack 영역의 초기주소와 크기
        • __cs3_reset_cortex_m : 리셋 핸들러 (rom모드일 경우 __bss_start__에서 __bss_end__까지의 영역을 0으로 초기화 한후 SystemInit() 처리와 main()으로 분기, ram모드일 경우 SystemInit() 처리와 _start로 분기)
        • Default_Handler : 지정되지 않은 (“B .”)재자리 분기의 IRQ 핸들러로써 LPC17xx내에 있는 모든 IRQ 핸들로의 초기상태가 되도록 한다.
      • system_LPC17xx.c
        • SystemInit() : Clock, PLL, Flash 설정 및 SCB(System Control Block)의 Vector table Offset설정
      • core_cm3.c
        • cortex에 관련된 정의와 cortex시스템 코어 제어루틴들 (가령 인터럽트 활성/비활성 기능과 Processor 상태 점검 기능) 이 정의되어 있으나 현재 RealView의 컴파일러만 지원한다. GCC는 cortex 관련 정의만 사용한다

    • Microcontroller Startup code for use with Red Suite
      • r_startup_lpc17.c 
        • __USE_CMSIS을 정의하여 CMSIS내에 포함된 system_LPC17xx의 기능을 사용함
        • g_pfnVectors을 .isr_vector 섹션에 생성한다. CMSIS에 존재하는 __cs3_interrupt_vector_cortex_m  벡터 테이블과 일대일 대응하는 항목으로 채워져 있다.
        • ResetISR()
          • g_pfnVectors의 리셋 핸들러 항목에 채워져 있음
          • _etext영역 이후의 데이터 영역에 해당하는 내용들을 SRAM(LPC17xx의 내부 메모리)의 _data부터 _edata까지의 영역에 복사
          • bss영역을 0으로 초기화
          • __USE_CMSIS가 정의되 있다면 CMSIS내에 포함된 SystemInit()루틴을 수행함
          • Main()루틴을 수행함

    • CMSIS와 FreeRTOS의 공생

      • 서로 동일한 내용을 담고 있는 상충되는 두 vector 테이블인 .isr_vector섹션에 있는 g_pfnVectors과 CMSIS라이브러리의 __cs3_interrupt_vector_cortex_m 벡터를 차이점을 파악하고 조정하고 대체할 수 있는 방법을 모색하자. Linker 스크립트의 수정이 반듯이 필요하다.

    • FreeRTOS와 newlib의 공생

      • FreeRTOS의 소스구조를 살펴보면 memory 할당자를 자체적으로 가지고 있다. 그레서 종종 malloc을 사용할 때 Bus-Fault를 발생시키거나 예기치 않은 동작을 할때가 있다. 이것은 컴파일러가 가지고 있는 자체 malloc이 동작하기 때문인데 FreeRTOS를 컴파일 할때는 Makefile에 CFLAGS += -DMALLOC_PROVIDED를 추가해서 newlib에 있는 malloc이 동작하지 않도록 할 수 있다. - 출처 : http://michaldemin.wordpress.com/2010/03/09/freertos-newlib-on-cortex-m3/

    • Port.c의 Macro 분석

      • portNVIC_SYSTICK_CTRL - STCTRL (System Timer Control and status register)
        • portNVIC_SYSTICK_CLK - System Tick clock source selection. (when 1, the CPU clock is selected. When 0, the external clock pin (STCLK) is selected.
        • portNVIC_SYSTICK_INT - System Tick interrupt enable
        • portNVIC_SYSTICK_ENABLE - System Tick counter enable
      • portNVIC_SYSTICK_LOAD  - STELOAD (System Timer Reload value register) 24bits register
      • portNVIC_INT_CTRL – ICSR (Interrupt Control and State Register)
        • portNVIC_PENDSVSET – PendSV set-pending bit (Write: 0 = no effect, 1 = changes PendSV exception state to pending), (Read: 0 = PendSV exception is not pending, 1 = PendSV exception is pending)
      • portNVIC_SYSPRI2 - SHPR3 (System Handler Priority Register)

    •  Port.c의 함수 분석

      • 인터럽트 핸들러
        • xPortPendSVHandler - context switching 을 위한 Task의 TCB(Tack Content Block)를 복구
        • xPortSysTickHandler - vTaskIncrementTick을 주기적으로 구동 시킴(실질적인 Task 전환이 이루어짐)
        • vPortSVCHandler
      •  인터럽트 설정 : prvSetupTimerInterrupt
        • *(portNVIC_SYSTICK_LOAD) = ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; :  SysTick의 주파수를 설정하기 위한 CPU클럭 카운트 값(configTICK_RATE_HZ 값은 1000으로 설정되어 있음. 즉 1Khz = 1ms당 한번씩 SysTick이 구동됨)
        • *(portNVIC_SYSTICK_CTRL) = portNVIC_SYSTICK_CLK | portNVIC_SYSTICK_INT | portNVIC_SYSTICK_ENABLE; : SysTick 의 활성화, 인터럽트 활성화, 그리고 구동 클럭 CPU의 클럭으로 설정
      •  스택 초기화 함수: pxPortInitialiseStack – 스택에서 Task가 사용할 위한 공간을 확보한 후 스택의 주소를 되돌려줌
      • xPortStartScheduler 
        • xPortPendSVHandler 와 xPortSysTickHandler 의 우선순위를 설정
        • prvSetupTimerInterrupt : xPortSysTickHandler 구동을 위한 설정
        • uxCriticalNesting : 스케쥴링의 활성 혹은 비활성화를 위한 nesting 변수 (초기값 0)
        • vPortStartFirstTask의 구동 (스택주소 로딩, 전역 인터럽트 활성화 등의 Pumping 작업을 함)
      • vPortEndScheduler - Schedule한 후 처리작업 (Cortex M3에서는 필요없는 작업)
      • vPortYieldFromISR - 강제적으로 context 전환을 이루도록 함
      • vPortEnterCritical - 인터럽트를 비 활성화 시키고, uxCriticalNesting값을 증가 시킴
      • vPortExitCritical - 인터럽트를 활성화 시키고 uxCriticalNesting값을 감소 시킴

      댓글 없음:

      댓글 쓰기