OSに頼らず、startupとmain.cでBeagleBoneのUserLEDをチカチカさせてみた。
使ったツールは、TIのサイトでダウンロードできるCode Composer Studio(CCS)。
PC上でCCSを走らせてバイナリをつくり、以下の形式でJTAG接続してARMの内蔵RAM上でLEDチカチカプログラムを走らせた。
[PC(CCS)]----USB Cable--->[BeagleBone(FT2232+ARM)]
/*
* main.c
* LED blink test for BeagleBone
* function: blink LED (user0)
*/
#define CONTROL_MODULE 0x44E10000
#define CONF_GPMC_A5 0x854
#define CONF_GPMC_A6 0x858
#define CONF_GPMC_A7 0x85C
#define CONF_GPMC_A8 0x860
#define CM_PER 0x44E00000
#define GPIO1_CLKCTRL 0xac
#define GPIO1 0x4804c000
#define GPIO_OE 0x134
#define GPIO_DATAOUT 0x13c
void gpmc_init(void);
void led_init(void);
void led_blink(void);
void wait(int);
void main(void) {
gpmc_init();
led_init();
while(1){
led_blink();
wait(500);
}
}
void gpmc_init(void){
unsigned long val;
// set pad control
val = 0x1 << 6 | 0x0 << 5 | 0x1 << 4 | 0x1 << 3 | 0x7;
*((unsigned long *)(CONTROL_MODULE + CONF_GPMC_A5)) |= val;
*((unsigned long *)(CONTROL_MODULE + CONF_GPMC_A6)) |= val;
*((unsigned long *)(CONTROL_MODULE + CONF_GPMC_A7)) |= val;
*((unsigned long *)(CONTROL_MODULE + CONF_GPMC_A8)) |= val;
// GPIO1 clock enable
*((unsigned long *)(CM_PER + GPIO1_CLKCTRL)) |= 0x1 << 18 | 0x0 << 16 | 0x2;
}
void led_init(void){
unsigned long * port;
// set GPIO1_21,..,24 as output
port = (unsigned long *)(GPIO1 + GPIO_OE);
*port &= ~(1 << 24 | 1 << 23 | 1 << 22 | 1 << 21);
// set GPIO1_21,..,24 to L
port = (unsigned long *)(GPIO1 + GPIO_DATAOUT);
*port &= ~(1 << 24 | 1 << 23 | 1 << 22 | 1 << 21);
}
void led_blink(void){
static int led_status=0;
unsigned long * port;
port = (unsigned long *)(GPIO1 + GPIO_DATAOUT);
if(led_status==0){
// set GPIO1_21 to H
*port |= 1 << 21;
led_status=1;
}else{
// set GPIO1_21 to L
*port &= ~(1 << 21);
led_status=0;
}
}
void wait(int i){
int j;
volatile int dummy=0;
while(i--){
j=1000;
while(j--){
//nop
dummy++;
}
}
}再利用性の高いコードを書くには勝手にマクロを定義せず、CMSISに従ってincludeしてマクロを流用するべきですが、、まぁ短いコードだし。。