Difference between revisions of "Xenomai:Blinking LEDs"
(→Makefile) |
|||
Line 92: | Line 92: | ||
XENO=$(ARMADEUS_ROOTFS_DIR)/usr/xenomai | XENO=$(ARMADEUS_ROOTFS_DIR)/usr/xenomai | ||
− | CC= arm-linux-gcc | + | CC:=$(ARMADEUS_TOOLCHAIN_PATH)/arm-linux-gcc |
− | LD= arm-linux-ld | + | LD:=$(ARMADEUS_TOOLCHAIN_PATH)/arm-linux-ld |
− | CXX= arm-linux-g++ | + | CXX:=$(ARMADEUS_TOOLCHAIN_PATH)/arm-linux-g++ |
− | AS= arm-linux-as | + | AS:=$(ARMADEUS_TOOLCHAIN_PATH)/arm-linux-as |
− | NM= arm-linux-nm | + | NM:=$(ARMADEUS_TOOLCHAIN_PATH)/arm-linux-nm |
− | AR= arm-linux-ar | + | AR:=$(ARMADEUS_TOOLCHAIN_PATH)/arm-linux-ar |
− | SIZE= arm-linux-size | + | SIZE:=$(ARMADEUS_TOOLCHAIN_PATH)/arm-linux-size |
− | OBJCOPY= arm-linux-objcopy | + | OBJCOPY:=$(ARMADEUS_TOOLCHAIN_PATH)/arm-linux-objcopy |
EXEC=blink_led_xeno_userspace | EXEC=blink_led_xeno_userspace | ||
Line 105: | Line 105: | ||
SRC= $(wildcard *.c) | SRC= $(wildcard *.c) | ||
OBJ= $(SRC:.c=.o) | OBJ= $(SRC:.c=.o) | ||
− | |||
CFLAGS=-g -W -Wall -I$(XENO)/include -I$(XENO)/include/native -I$(XENO)/include/rtdm -D_GNU_SOURCE -D_REENTRANT | CFLAGS=-g -W -Wall -I$(XENO)/include -I$(XENO)/include/native -I$(XENO)/include/rtdm -D_GNU_SOURCE -D_REENTRANT | ||
− | LDFLAGS=-L$(XENO)/lib -Xlinker -rpath $(XENO)/lib -Xlinker $(XENO)/lib/libnative.a $(XENO)/lib/librtdm.a - | + | LDFLAGS=-L$(XENO)/lib -Xlinker -rpath $(XENO)/lib -Xlinker $(XENO)/lib/libnative.a $(XENO)/lib/librtdm.a -lpthread -lnative -lrtdm |
$(EXEC) : $(OBJ) | $(EXEC) : $(OBJ) | ||
$(CC) -o $@ $^ $(LDFLAGS) | $(CC) -o $@ $^ $(LDFLAGS) | ||
Line 115: | Line 114: | ||
.PHONY: all | .PHONY: all | ||
all: $(EXEC) | all: $(EXEC) | ||
+ | |||
.PHONY: clean | .PHONY: clean | ||
clean: | clean: | ||
Line 120: | Line 120: | ||
rm -rf $(EXEC) | rm -rf $(EXEC) | ||
rm -f *.c~ *.h~ Makefile~ | rm -f *.c~ *.h~ Makefile~ | ||
+ | |||
.PHONY: install | .PHONY: install | ||
install: $(EXEC) | install: $(EXEC) |
Revision as of 10:36, 15 February 2010
This tutorial explains how to create a simple Xenomai application. This application will blink the APF9328DevFull user LED (connected to pin 31 of i.MXL portD; on the APF27 you would use pin 14 of portF).
Application code
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <signal.h>
#include <sys/mman.h>
#include <native/task.h>
#include <native/timer.h>
#define TIMESLEEP 1000000000
#define LED "/dev/gpio/PD31"
RT_TASK blink_task;
int fd;
void blink(void *arg)
{
int iomask = 0x00;
rt_task_set_periodic(NULL, TM_NOW, TIMESLEEP);
while(1) {
rt_task_wait_period(NULL);
write(fd,&iomask,sizeof(iomask));
iomask ^= 1;
}
}
void catch_signal() {}
int main(int argc, char **argv)
{
signal(SIGTERM, catch_signal);
signal(SIGINT, catch_signal);
/* Avoids memory swapping for this program */
mlockall(MCL_CURRENT|MCL_FUTURE);
/* led device opening */
if ((fd = open(LED, O_WRONLY)) < 0) {
printf("Open error on %s\n",LED);
exit(0);
}
/* Task Creation */
rt_task_create(&blink_task, "blinkLed", 0, 99, 0);
rt_task_start(&blink_task, &blink, NULL);
getchar();
rt_task_delete(&blink_task);
close(fd);
return 0;
}
This source looks very like a classical Linux application with threads and nanosleep() function.
The only differences are on the task creation using Xenomai API:
- Create a new task with stksize stack size, prio level of priority and mode type of creation:
int rt_task_create(RT_TASK * task, const char * name, int stksize, int prio, int mode)
- Launch the new task with entry function and cookie parameters:
int rt_task_start (RT_TASK *task, void(*entry)(void *cookie), void *cookie)
- set for the task periodic, idate time for the first release (time in nanoseconds)
int rt_task_set_periodic (RT_TASK *task, RTIME idate, RTIME period)
- To block the task during the previously set period:
int rt_task_wait_period (unsigned long *overruns_r)
Makefile
The second step is to create a Makefile with specific Xenomai includes.
###### CONFIGURATION ######
DEST_DIR=/tftpboot/local/bin
ARMADEUS_BASE_DIR=../
include $(ARMADEUS_BASE_DIR)/Makefile.in
XENO=$(ARMADEUS_ROOTFS_DIR)/usr/xenomai
CC:=$(ARMADEUS_TOOLCHAIN_PATH)/arm-linux-gcc
LD:=$(ARMADEUS_TOOLCHAIN_PATH)/arm-linux-ld
CXX:=$(ARMADEUS_TOOLCHAIN_PATH)/arm-linux-g++
AS:=$(ARMADEUS_TOOLCHAIN_PATH)/arm-linux-as
NM:=$(ARMADEUS_TOOLCHAIN_PATH)/arm-linux-nm
AR:=$(ARMADEUS_TOOLCHAIN_PATH)/arm-linux-ar
SIZE:=$(ARMADEUS_TOOLCHAIN_PATH)/arm-linux-size
OBJCOPY:=$(ARMADEUS_TOOLCHAIN_PATH)/arm-linux-objcopy
EXEC=blink_led_xeno_userspace
SRC= $(wildcard *.c)
OBJ= $(SRC:.c=.o)
CFLAGS=-g -W -Wall -I$(XENO)/include -I$(XENO)/include/native -I$(XENO)/include/rtdm -D_GNU_SOURCE -D_REENTRANT
LDFLAGS=-L$(XENO)/lib -Xlinker -rpath $(XENO)/lib -Xlinker $(XENO)/lib/libnative.a $(XENO)/lib/librtdm.a -lpthread -lnative -lrtdm
$(EXEC) : $(OBJ)
$(CC) -o $@ $^ $(LDFLAGS)
$(OBJ): $(SRC)
$(CC) $(CFLAGS) -o $@ -c $<
.PHONY: all
all: $(EXEC)
.PHONY: clean
clean:
rm -rf $(OBJ)
rm -rf $(EXEC)
rm -f *.c~ *.h~ Makefile~
.PHONY: install
install: $(EXEC)
mkdir $(DEST_DIR)/$(EXEC)
echo "$(EXEC):native:!./$(EXEC);popall:control_c" > /$(DEST_DIR)/$(EXEC)/.runinfo
cp $(EXEC) $(DEST_DIR)/$(EXEC)
.PHONY: mrproper
mrproper: clean
rm -rf $(DEST_DIR)/$(EXEC)
ARMADEUS_BASE_DIR needs to be adapted to the correct path where the Armadeus buildroot is installed.
DEST_DIR assumes you used an NFS mount on /tftpboot/local as /usr/local on the board.
Compilation, installation and run
$ make
If you setup the NFS as indicated above, you can install the application on your board with :
$ make install
Otherwise you can manually copy blink_led_xeno_userspace exe to your board (/usr/local/bin/).
Running
On your APF, you must change directory to /usr/local/bin and type :
# xeno-load blink_led_xeno_userspace