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()루틴을 수행함
- 서로 동일한 내용을 담고 있는 상충되는 두 vector 테이블인 .isr_vector섹션에 있는 g_pfnVectors과 CMSIS라이브러리의 __cs3_interrupt_vector_cortex_m 벡터를 차이점을 파악하고 조정하고 대체할 수 있는 방법을 모색하자. Linker 스크립트의 수정이 반듯이 필요하다.
- 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/
- 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)
- 인터럽트 핸들러
- 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값을 감소 시킴
댓글 없음:
댓글 쓰기