■포팅_2■
RTOS는 타이머 인터럽트가 꼭있어야하기 때문에 미리 만들어 놓으면 좋다.
$ pwd
03.ucos2-timer
$ cp timer.c /home/mds/FreeRTOSv10.1.1/FreeRTOS/Source/portable/GCC/ARM7_AT91FR40008/
1.
makefile 수정
THUMB_SRC =
../../Source/portable/GCC/ARM7_AT91FR40008/timer.c 추가
2. ucon 예제3번 timer.c 참고하여
port.c에 수정
#include "2450addr.h"
#include "option.h"
#include "my_lib.h"
extern unsigned int HandleTIMER0;
#else
//MDS2450's TIMER
/*
* Timer0 Init
* Prescaler value : 255, dead zone length = 0
* Divider value : 1/16, no DMA mode
* New frequency : (PCLK/(Prescaler value+1))*Divider value = (66Mhz/(256))*(1/16)
* = 16.113Khz(16113Hz)
*/
rTCFG0 = (0<<8)|(0xff);
rTCFG1 = (0<<20)|(3);
/* TCON¼³Á¤ :Dead zone disable, auto reload on, output inverter off
* manual update no operation, timer0 stop, TCNTB0=0, TCMPB0 =0
*/
rTCON = (0<<4)|(1<<3)|(0<<2)|(0<<1)|(0);
rTCNTB0 = 0;
rTCMPB0 = 0;
#if configUSE_PREEMPTION == 1
{
extern void ( vPreemptiveTick )( void );
HandleTIMER0 = (unsigned int)vPreemptiveTick; //register a interrupt vector for timer0
/* Interrupt Unmasking */
rINTMSK1 &= ~(1<<10);
}
#else // else use cooperative scheduler
{
extern void ( vNonPreemptiveTick )( void );
HandleTIMER0 = (unsigned int)vNonPreemptiveTick; //register a interrupt vector for timer0
/* Interrupt Unmasking */
rINTMSK1 &= ~(1<<10);
}
#endif
rTCNTB0 = 16113/configTICK_RATE_HZ; //MCU의 16.113*msec를 RTOS에서 비슷하게
rTCON |= (1<<1)|(0);
rTCON &= ~(1<<1);
rTCON |= 1;
#endif
3.
../../Source/portable/GCC/ARM7_AT91FR40008/timer.c 제거
4.
/* flash.c-Minimal */
#define ledNUMBER_OF_LEDS ( 1 ) -> 수정
void vStartLEDFlashTasks( UBaseType_t uxPriority )
{
BaseType_t xLEDTask;
/* Create the three tasks. */
for( xLEDTask = 0; xLEDTask < ledNUMBER_OF_LEDS; ++xLEDTask )
{
printf("vStartLEDFlashTasks\n");
/* Spawn the task. */
xTaskCreate( vLEDFlashTask, "LEDx", ledSTACK_SIZE, NULL, uxPriority, ( TaskHandle_t * ) NULL );
}
}
/* flash.c-Minimal */
static void vLEDFlashTask( void *pvParameters )
{
xLEDParameters *pxParameters;
/* Queue a message for printing to say the task has started. */
vPrintDisplayMessage( &pcTaskStartMsg );
pxParameters = ( xLEDParameters * ) pvParameters;
for(;;)
{
printf("togle@\n");
/* Delay for half the flash period then turn the LED on. */
vTaskDelay( pxParameters->xFlashRate / ( TickType_t ) 2 );
vParTestToggleLED( pxParameters->uxLED );
/* Delay for half the flash period then turn the LED off. */
vTaskDelay( pxParameters->xFlashRate / ( TickType_t ) 2 );
vParTestToggleLED( pxParameters->uxLED );
}
}
5.
필요없는 소스 삭제
$ pwd
/home/mds/FreeRTOSv10.1.1/FreeRTOS/Source/portable
rm -rf !(Common|GCC|MemMang|ThirdParty|Tasking)
$ pwd
/home/mds/FreeRTOSv10.1.1/FreeRTOS/Source/portable/GCC
HandleSWI = (unsigned)vPortYieldProcessor;
로 수정
7.
/* portISR */
#if configUSE_PREEMPTION == 0
/* The cooperative scheduler requires a normal IRQ service routine to
simply increment the system tick. */
void vNonPreemptiveTick( void ) __attribute__ ((interrupt ("IRQ")));
void vNonPreemptiveTick( void )
{
static volatile uint32_t ulDummy;
/* Clear tick timer interrupt indication. */
//ulDummy = portTIMER_REG_BASE_PTR->TC_SR;
xTaskIncrementTick();
/* TODO : Pending Register Clear */
rSRCPND1 = (1<<10);
rINTPND1 = (1<<10);
// tick++;
/* Acknowledge the interrupt at AIC level... */
//AT91C_BASE_AIC->AIC_EOICR = portCLEAR_AIC_INTERRUPT;
}
#else /* else preemption is turned on */
/* The preemptive scheduler is defined as "naked" as the full context is
saved on entry as part of the context switch. */
void vPreemptiveTick( void ) __attribute__((naked));
void vPreemptiveTick( void )
{
/* Save the context of the interrupted task. */
portSAVE_CONTEXT();
/* WARNING - Do not use local (stack) variables here. Use globals
if you must! */
static volatile uint32_t ulDummy;
/* Clear tick timer interrupt indication. */
// ulDummy = portTIMER_REG_BASE_PTR->TC_SR;
/* Increment the RTOS tick count, then look for the highest priority
task that is ready to run. */
if( xTaskIncrementTick() != pdFALSE )
{
vTaskSwitchContext();
}
/* Acknowledge the interrupt at AIC level... */
//AT91C_BASE_AIC->AIC_EOICR = portCLEAR_AIC_INTERRUPT;
/* TODO : Pending Register Clear */
rSRCPND1 = (1<<10);
rINTPND1 = (1<<10);
// tick++;
/* Restore the context of the new task. */
portRESTORE_CONTEXT();
}
로 수정해서 컴파일하면 LED 깜빡이는 것을 볼 수 있습니다.
< 포팅의 유형 >
1. CS8900 이더넷 컨트롤러를 DM9000 칩으로 변경
2. 블루투스 지원을 하기 위한 소프트웨어를 찾고 이를 이식
3. 커널을 업그레이드
4. 오픈소스(VLC)을 포팅
5. 커널을 커스텀 보드에 이식
'RTOS' 카테고리의 다른 글
[RTOS_Day5]예제 실습(세마포어, 뮤텍스, 이벤트 플래그, 메시지큐) (0) | 2018.12.27 |
---|---|
[RTOS_Day4]RTOS 포팅 진행 기록 (0) | 2018.12.26 |
[RTOS_Day3]통계 테스크 (0) | 2018.12.19 |
[RTOS_Day2]임계영역 보호 (0) | 2018.12.18 |
[RTOS_Day2]시간관리 함수 (2) | 2018.12.18 |