포팅_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    추가


컴파일 해보기




2ucon 예제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


rm -r !(ARM7_AT91FR40008)


6.
검색 shift + Ctrl + F 
[\t\s]+swi[\t\s]
boot.s 보기


/*    exception.c    */
void vPortYieldProcessor(void);

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. 커널을 커스텀 보드에 이식








+ Recent posts