본문 바로가기

Enginius/RT/OS issues

e-puck에 FreeRTOS를 포팅하기.


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