RTOS에는 여러 종류가 있지만 그 중 공짜로 사용할 수 있는 것은 tinyOS와 FreeRTOS정도가 있다.
이 중에서 FreeRTOS를 e-puck에 포팅해보자.
e-puck에 들어가는 mcu는 dsPIC로 FreeRTOS에서 제공해주긴 하지만, 두 가지 문제가 있다.
1. e-puck에는 dsPIC30F가 들어가지만 FreeRTOS에서 제공하는 것은 dsPIC33F이다.
PIC33FJ256GP710.gld => p30f6014A.gld
이를 변환하기 위해서 다음의 파일을 참고할 수 있다.
2. FreeRTOS는 explorer보드를 reference로 하고 있다. 즉 mcu주변 페리페럴이 많이 다르다.
e-puck.org에서 기본으로 제공하는 port 초기화 함수는 다음과 같다.
void e_init_port(void) { /********************** OUTPUTS ***************************/ /*LEDS*/ LED0 = 0; LED1 = 0; LED2 = 0; LED3 = 0; LED4 = 0; LED5 = 0; LED6 = 0; LED7 = 0; LED0_DIR = OUTPUT_PIN; LED1_DIR = OUTPUT_PIN; LED2_DIR = OUTPUT_PIN; LED3_DIR = OUTPUT_PIN; LED4_DIR = OUTPUT_PIN; LED5_DIR = OUTPUT_PIN; LED6_DIR = OUTPUT_PIN; LED7_DIR = OUTPUT_PIN; FRONT_LED = 0; FRONT_LED_DIR = OUTPUT_PIN; BODY_LED = 0; BODY_LED_DIR = OUTPUT_PIN; /*IR*/ PULSE_IR0 = 0; PULSE_IR1 = 0; PULSE_IR2 = 0; PULSE_IR3 = 0; PULSE_IR0_DIR = OUTPUT_PIN; PULSE_IR1_DIR = OUTPUT_PIN; PULSE_IR2_DIR = OUTPUT_PIN; PULSE_IR3_DIR = OUTPUT_PIN; /*basic audio*/ AUDIO_ON = 0; /*turn of speaker and codec*/ AUDIO_ON_DIR = OUTPUT_PIN; /*motors*/ MOTOR1_PHA = 0; MOTOR1_PHB = 0; MOTOR1_PHC = 0; MOTOR1_PHD = 0; MOTOR2_PHA = 0; MOTOR2_PHB = 0; MOTOR2_PHC = 0; MOTOR2_PHD = 0; MOTOR1_PHA_DIR = OUTPUT_PIN; MOTOR1_PHB_DIR = OUTPUT_PIN; MOTOR1_PHC_DIR = OUTPUT_PIN; MOTOR1_PHD_DIR = OUTPUT_PIN; MOTOR2_PHA_DIR = OUTPUT_PIN; MOTOR2_PHB_DIR = OUTPUT_PIN; MOTOR2_PHC_DIR = OUTPUT_PIN; MOTOR2_PHD_DIR = OUTPUT_PIN; /*camera*/ CAM_RESET=0; CAM_RESET_DIR = OUTPUT_PIN; /*I2C*/ SIO_C=0; SIO_D=0; SIO_C_DIR= OUTPUT_PIN; SIO_D_DIR= OUTPUT_PIN; /********************** INPUTS **************************/ /*low battery signal active low when Vbatt<3.4V*/ BATT_LOW_DIR = INPUT_PIN; /*IR TV receiver on normal extension*/ REMOTE_DIR = INPUT_PIN; /* selector*/ SELECTOR0_DIR = INPUT_PIN; SELECTOR1_DIR = INPUT_PIN; SELECTOR2_DIR = INPUT_PIN; SELECTOR3_DIR = INPUT_PIN; /*camera*/ CAM_y0_DIR = INPUT_PIN; CAM_y1_DIR = INPUT_PIN; CAM_y2_DIR = INPUT_PIN; CAM_y3_DIR = INPUT_PIN; CAM_y4_DIR = INPUT_PIN; CAM_y5_DIR = INPUT_PIN; CAM_y6_DIR = INPUT_PIN; CAM_y7_DIR = INPUT_PIN; }
그리고 각 포트에 해당하는 실제 레지스터와 H/W setup은 다음과 같이 정의된다.
#include "p30f6014A.h" /*********************GENERAL SETUP************************/ #define FOSC 7.3728e6 // 7.3728Mhz crystal in XTL mode #define PLL 8.0 // 8x PLL #define FCY ((FOSC*PLL)/(4.0)) // Instruction cycle frequency #define MILLISEC (FCY/1.0e3) // 1mSec delay constant #define MICROSEC (FCY/1.0e6) // 1uSec delay constant #define NANOSEC (FCY/1.0e9) // 1nSec delay constant #define TCY_PIC (1e9/FCY) //time instruction cycle in [ns] #define INTERRUPT_DELAY (10*TCY_PIC) //delay to start an interrupt in [ns] (observe with p30f6014) #define TRUE 1 #define FALSE 0 /********************** OUTPUTS ***************************/ #define OUTPUT_PIN 0 /*LEDS*/ /*First in front of robot than turning clokwise*/ #define LED0 _LATA6 #define LED1 _LATA7 #define LED2 _LATA9 #define LED3 _LATA12 #define LED4 _LATA10 #define LED5 _LATA13 #define LED6 _LATA14 #define LED7 _LATA15 #define LED0_DIR _TRISA6 #define LED1_DIR _TRISA7 #define LED2_DIR _TRISA9 #define LED3_DIR _TRISA12 #define LED4_DIR _TRISA10 #define LED5_DIR _TRISA13 #define LED6_DIR _TRISA14 #define LED7_DIR _TRISA15 #define FRONT_LED _LATC1 #define FRONT_LED_DIR _TRISC1 #define BODY_LED _LATC2 #define BODY_LED_DIR _TRISC2 /*IR*/ #define PULSE_IR0 _LATF7 // pulse IR 0 and 4 #define PULSE_IR1 _LATF8 // pulse IR 1 and 5 #define PULSE_IR2 _LATG0 // pulse IR 2 and 6 #define PULSE_IR3 _LATG1 // pulse IR 3 and 7 #define PULSE_IR0_DIR _TRISF7 #define PULSE_IR1_DIR _TRISF8 #define PULSE_IR2_DIR _TRISG0 #define PULSE_IR3_DIR _TRISG1 /*First in front right of robot than turning clokwise*/ #define IR0 8 // ir proximity sensor 0 on AD channel 8 #define IR1 9 // ir proximity sensor 1 on AD channel 9 #define IR2 10 // ir proximity sensor 2 on AD channel 10 #define IR3 11 // ir proximity sensor 3 on AD channel 11 #define IR4 12 // ir proximity sensor 4 on AD channel 12 #define IR5 13 // ir proximity sensor 5 on AD channel 13 #define IR6 14 // ir proximity sensor 6 on AD channel 14 #define IR7 15 // ir proximity sensor 7 on AD channel 15 /*analog*/ #define MIC1 2 // microphone 1 on AD channel 2 #define MIC2 3 // microphone 2 on AD channel 3 #define MIC3 4 // microphone 3 on AD channel 4 #define ACCX 5 // X Axis of accelerometer on AD channel 5 #define ACCY 6 // Y Axis of accelerometer on AD channel 6 #define ACCZ 7 // Z Axis of accelerometer on AD channel 7 /*basic audio*/ #define AUDIO_ON _LATF0 #define AUDIO_ON_DIR _TRISF0 /*motors*/ #define MOTOR1_PHA _LATD0 #define MOTOR1_PHB _LATD1 #define MOTOR1_PHC _LATD2 #define MOTOR1_PHD _LATD3 #define MOTOR2_PHA _LATD4 #define MOTOR2_PHB _LATD5 #define MOTOR2_PHC _LATD6 #define MOTOR2_PHD _LATD7 #define MOTOR1_PHA_DIR _TRISD0 #define MOTOR1_PHB_DIR _TRISD1 #define MOTOR1_PHC_DIR _TRISD2 #define MOTOR1_PHD_DIR _TRISD3 #define MOTOR2_PHA_DIR _TRISD4 #define MOTOR2_PHB_DIR _TRISD5 #define MOTOR2_PHC_DIR _TRISD6 #define MOTOR2_PHD_DIR _TRISD7 /*camera*/ #define CAM_RESET _LATC13 #define CAM_RESET_DIR _TRISC13 /* I2C */ #define SIO_D _LATG3 #define SIO_D_DIR _TRISG3 #define SIO_C _LATG2 #define SIO_C_DIR _TRISG2 /********************** INPUTS **************************/ #define INPUT_PIN 1 /*low battery signal active low when Vbatt<3.4V*/ #define BATT_LOW _RF1 #define BATT_LOW_DIR _TRISF1 /* selector on normal extension*/ #define SELECTOR0 _RG6 #define SELECTOR1 _RG7 #define SELECTOR2 _RG8 #define SELECTOR3 _RG9 #define SELECTOR0_DIR _TRISG6 #define SELECTOR1_DIR _TRISG7 #define SELECTOR2_DIR _TRISG8 #define SELECTOR3_DIR _TRISG9 /*IR TV receiver on normal extension*/ #define REMOTE _RF6 #define REMOTE_DIR _TRISF6 /*CAMERA*/ /*data higher 8 bits of port D*/ #define CAM_DATA PORTD; #define CAM_y0 _RD8 #define CAM_y1 _RD9 #define CAM_y2 _RD10 #define CAM_y3 _RD11 #define CAM_y4 _RD12 #define CAM_y5 _RD13 #define CAM_y6 _RD14 #define CAM_y7 _RD15 #define CAM_y0_DIR _TRISD8 #define CAM_y1_DIR _TRISD9 #define CAM_y2_DIR _TRISD10 #define CAM_y3_DIR _TRISD11 #define CAM_y4_DIR _TRISD12 #define CAM_y5_DIR _TRISD13 #define CAM_y6_DIR _TRISD14 #define CAM_y7_DIR _TRISD15 /*clock interupt*/ #define CAM_PWDN _RC2 #define CAM_VSYNC _RC4 #define CAM_HREF _RC3 #define CAM_PCLK _RC14 #define CAM_PWDN_DIR _TRISC2 #define CAM_VSYNC_DIR _TRISC4 #define CAM_HREF_DIR _TRISC3 #define CAM_PCLK_DIR _TRISC14 /*********************** ASEMBLER SMALL FUNCTCION********************** */ #define NOP() {__asm__ volatile ("nop");} #define CLRWDT() {__asm__ volatile ("clrwdt");} #define SLEEP() {__asm__ volatile ("pwrsav #0");} #define IDLE() {__asm__ volatile ("pwrsav #1");} #define INTERRUPT_OFF() {__asm__ volatile ("disi #10000");} #define INTERRUPT_ON() {__asm__ volatile ("disi #2");} #define RESET() {__asm__ volatile ("reset");} #define STOP_TMR1 IEC0bits.T1IE = 0 #define STOP_TMR2 IEC0bits.T2IE = 0 #define STOP_TMR3 IEC0bits.T3IE = 0 #define STOP_TMR4 IEC1bits.T4IE = 0 #define STOP_TMR5 IEC1bits.T5IE = 0 #endif
위의 값들을 이용해서 H/W 초기화를 할 수 있다.
FreeRTOS 소스로 와서, 여기서 H/W dependent한 부분은 FreeRTOSConfig.h 부분이다. 이곳에서
#include <p33FJ256GP710.h를 한다.
'Enginius > RT/OS issues' 카테고리의 다른 글
Priority Inversion (0) | 2011.10.24 |
---|---|
Self-optimizing Scheduler (0) | 2011.10.24 |