Fresh import of the PX4 firmware sources.

This commit is contained in:
px4dev
2012-08-04 15:12:36 -07:00
commit 8a365179ea
2425 changed files with 609220 additions and 0 deletions
+211
View File
@@ -0,0 +1,211 @@
#
# Generic GDB macros for working with NuttX
#
echo Loading NuttX GDB macros. Use 'help nuttx' for more information.\n
define nuttx
echo Use 'help nuttx' for more information.\n
end
document nuttx
. Various macros for working with NuttX.
.
. showheap
. Prints the contents of the malloc heap(s).
. showtasks
. Prints a list of all tasks.
. showtask <address>
. Prints information about the task at <address>
.
. Use 'help <macro>' for more specific help.
end
################################################################################
# Heap display
################################################################################
define _showheap
set $index = $arg0
if (sizeof(struct mm_allocnode_s) == 4)
set $MM_ALLOC_BIT = 0x8000
else
set $MM_ALLOC_BIT = 0x80000000
end
printf "HEAP %d %p - %p\n", $index, g_heapstart[$index], g_heapend[$index]
printf "ptr size\n"
set $node = (char *)g_heapstart[$index] + sizeof(struct mm_allocnode_s)
while $node < g_heapend[$index]
printf " %p", $node
set $nodestruct = (struct mm_allocnode_s *)$node
printf " %u", $nodestruct->size
if !($nodestruct->preceding & $MM_ALLOC_BIT)
printf " FREE"
end
if ($nodestruct->size > g_heapsize) || (($node + $nodestruct->size) > g_heapend[$index])
printf " (BAD SIZE)"
end
printf "\n"
set $node = $node + $nodestruct->size
end
end
define showheap
set $nheaps = sizeof(g_heapstart) / sizeof(g_heapstart[0])
printf "Printing %d heaps\n", $nheaps
set $heapindex = (int)0
while $heapindex < $nheaps
showheap $heapindex
set $heapindex = $heapindex + 1
end
end
document showheap
. showheap
. Prints the contents of the malloc heap(s).
end
################################################################################
# Task display
################################################################################
define _showtask_oneline
set $task = (struct _TCB *)$arg0
printf " %p %.2d %.3d %s\n", $task, $task->pid, $task->sched_priority, $task->name
end
define _showtasklist
set $queue = (dq_queue_t *)$arg0
set $cursor = (dq_entry_t *)$queue->head
if $cursor != 0
printf " TCB PID PRI\n"
else
printf " <none>\n"
end
while $cursor != 0
_showtask_oneline $cursor
if $cursor == $queue->tail
set $cursor = 0
else
set $next = $cursor->flink
if $next->blink != $cursor
printf "task linkage corrupt\n"
set $cursor = 0
else
set $cursor = $next
end
end
end
end
#
# Print task registers for a NuttX v7em target with FPU enabled.
#
define _showtaskregs_v7em
set $task = (struct _TCB *)$arg0
set $regs = (uint32_t *)&($task->xcp.regs[0])
printf " r0: 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n", $regs[27], $regs[28], $regs[29], $regs[30], $regs[2], $regs[3], $regs[4], $regs[5]
printf " r8: 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n", $regs[6], $regs[7], $regs[8], $regs[9], $regs[31], $regs[0], $regs[32], $regs[33]
printf " XPSR 0x%08x EXC_RETURN 0x%08x PRIMASK 0x%08x\n", $regs[34], $regs[10], $regs[1]
end
#
# Print current registers for a NuttX v7em target with FPU enabled.
#
define _showcurrentregs_v7em
printf " r0: 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n", $r0, $r1, $r2, $r3, $r4, $r5, $r6, $r7
printf " r8: 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n", $r8, $r9, $r10, $r11, $r12, $r13, $r14, $r15
printf " XPSR 0x%08x\n", $xpsr
end
#
# Print details of a semaphore
#
define _showsemaphore
printf "count %d ", $arg0->semcount
if $arg0->hlist.holder != 0
set $_task = (struct _TCB *)$arg0->hlist.holder
printf "held by %s", $_task->name
end
printf "\n"
end
define showtask
set $task = (struct _TCB *)$arg0
printf "%p %.2d ", $task, $task->pid
_showtaskstate $task
printf " %s\n", $task->name
set $stack_free = 0
while ($stack_free < $task->adj_stack_size) && *(uint8_t *)($task->stack_alloc_ptr + $stack_free)
set $stack_free = $stack_free + 1
end
printf" stack 0x%08x-0x%08x (%d) %d free\n", $task->stack_alloc_ptr, $task->adj_stack_ptr, $task->adj_stack_size, $stack_free
if $task->task_state == TSTATE_WAIT_SEM
printf " waiting on %p ", $task->waitsem
_showsemaphore $task->waitsem
end
if $task->task_state != TSTATE_TASK_RUNNING
_showtaskregs_v7em $task
else
_showcurrentregs_v7em
end
# XXX print registers here
end
document showtask
. showtask <TCB pointer>
. Print details of a task.
end
define _showtaskstate
if $arg0->task_state == TSTATE_TASK_INVALID
printf "INVALID"
end
if $arg0->task_state == TSTATE_TASK_PENDING
printf "PENDING"
end
if $arg0->task_state == TSTATE_TASK_READYTORUN
printf "READYTORUN"
end
if $arg0->task_state == TSTATE_TASK_RUNNING
printf "RUNNING"
end
if $arg0->task_state == TSTATE_TASK_INACTIVE
printf "INACTIVE"
end
if $arg0->task_state == TSTATE_WAIT_SEM
printf "WAIT_SEM"
end
if $arg0->task_state == TSTATE_WAIT_SIG
printf "WAIT_SIG"
end
if $arg0->task_state > TSTATE_WAIT_SIG
printf "%d", $arg0->task_state
end
end
define showtasks
printf "PENDING\n"
_showtasklist &g_pendingtasks
printf "RUNNABLE\n"
_showtasklist &g_readytorun
printf "WAITING\n"
_showtasklist &g_waitingforsemaphore
printf "INACTIVE\n"
_showtasklist &g_inactivetasks
end
document showtasks
. showtasks
. Print a list of all tasks in the system, separated into their respective queues.
end
+6
View File
@@ -0,0 +1,6 @@
#
# Setup macros for the BlackMagic debug probe and NuttX.
#
mon swdp_scan
attach 1
+11
View File
@@ -0,0 +1,11 @@
define f4_memdump
shell mkdir -p /tmp/dump
printf "Dumping CCSRAM to /tmp/dump/ccsram\n"
dump memory /tmp/dump/ccsram 0x10000000 0x10010000
printf "Dumping SRAM to /tmp/dump/sram\n"
dump memory /tmp/dump/sram 0x20000000 0x20020000
end
document f4_memdump
Dumps the STM32F4 memory to files in /tmp/dump.
end
+64
View File
@@ -0,0 +1,64 @@
# script for stm32f2xxx
if { [info exists CHIPNAME] } {
set _CHIPNAME $CHIPNAME
} else {
set _CHIPNAME stm32f4xxx
}
if { [info exists ENDIAN] } {
set _ENDIAN $ENDIAN
} else {
set _ENDIAN little
}
# Work-area is a space in RAM used for flash programming
# By default use 64kB
if { [info exists WORKAREASIZE] } {
set _WORKAREASIZE $WORKAREASIZE
} else {
set _WORKAREASIZE 0x10000
}
# JTAG speed should be <= F_CPU/6. F_CPU after reset is 8MHz, so use F_JTAG = 1MHz
#
# Since we may be running of an RC oscilator, we crank down the speed a
# bit more to be on the safe side. Perhaps superstition, but if are
# running off a crystal, we can run closer to the limit. Note
# that there can be a pretty wide band where things are more or less stable.
jtag_khz 1000
jtag_nsrst_delay 100
jtag_ntrst_delay 100
#jtag scan chain
if { [info exists CPUTAPID ] } {
set _CPUTAPID $CPUTAPID
} else {
# See STM Document RM0033
# Section 32.6.3 - corresponds to Cortex-M3 r2p0
set _CPUTAPID 0x4ba00477
}
jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID
if { [info exists BSTAPID ] } {
set _BSTAPID $BSTAPID
} else {
# See STM Document RM0033
# Section 32.6.2
#
set _BSTAPID 0x06413041
}
jtag newtap $_CHIPNAME bs -irlen 5 -expected-id $_BSTAPID
set _TARGETNAME $_CHIPNAME.cpu
target create $_TARGETNAME cortex_m3 -endian $_ENDIAN -chain-position $_TARGETNAME -rtos auto
$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0
set _FLASHNAME $_CHIPNAME.flash
flash bank $_FLASHNAME stm32f2x 0 0 0 0 $_TARGETNAME
# if srst is not fitted use SYSRESETREQ to
# perform a soft reset
cortex_m3 reset_config sysresetreq
File diff suppressed because it is too large Load Diff
+37
View File
@@ -0,0 +1,37 @@
Linux/Mac OS X
==============
To install doxygen:
$sudo apt-get install doxygen
If the above does not work go to:
http://www.stack.nl/~dimitri/doxygen/download.html for the correct download.
Then go to the following website for inforamtion on the install:
http://www.stack.nl/~dimitri/doxygen/install.html
Then to generate the html, run the following code while you are in the qgroundcontrol/doc directory:
$doxygen Doxyfile
The html file index.html should be in doc/html unless you changed the output directory.
The other option for generating the documentation is to use the wizard:
$doxywizard &
doxywizard information:
http://www.stack.nl/~dimitri/doxygen/doxywizard_usage.html
Or go to the Doxygen Manual for information at the website noted below.
Windows
=======
Go to the following website for the correct download and follow the wizard to install:
http://www.stack.nl/~dimitri/doxygen/download.html
Run the wizard to generate the documentation.
Go to the website below or the Doxygen Manual for information on running doxywizard.
http://www.stack.nl/~dimitri/doxygen/doxywizard_usage.html
Doxygen Manual
==============
http://www.stack.nl/~dimitri/doxygen/
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

+3
View File
@@ -0,0 +1,3 @@
#!/bin/sh
rm -rf html
doxygen
Binary file not shown.
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 KiB

+2
View File
@@ -0,0 +1,2 @@
#!/bin/sh
git log --pretty=format:"Last change: commit %h - %aN, %ar : %s" -1 $1 || echo no git
+22
View File
@@ -0,0 +1,22 @@
{
"folders":
[
{
"path": "."
}
],
"settings":
{
"tab_size": 8,
"translate_tabs_to_spaces": false
},
"build_systems":
[
{
"name": "PX4",
"working_dir": "${project_path}",
"file_regex": "^(..[^:]*):([0-9]+):?([0-9]+)?:? (.*)$",
"cmd": ["make"]
}
]
}
+12
View File
@@ -0,0 +1,12 @@
{
"board_id": 5,
"magic": "PX4FWv1",
"description": "Firmware for the PX4FMU board",
"image": "",
"build_time": 0,
"summary": "PX4FMU",
"version": "0.1",
"image_size": 0,
"git_identity": "",
"board_revision": 0
}
+12
View File
@@ -0,0 +1,12 @@
{
"board_id": 7,
"magic": "PX4FWv1",
"description": "Firmware for the PX4IO board",
"image": "",
"build_time": 0,
"summary": "PX4IO",
"version": "0.1",
"image_size": 0,
"git_identity": "",
"board_revision": 0
}
+142
View File
@@ -0,0 +1,142 @@
#
# Top-level Makefile for building PX4 firmware images.
#
#
# Note that this is a transitional process; the eventual goal is for this
# project to slim down and simply generate PX4 link kits via the NuttX
# 'make export' mechanism.
#
#
#
# Some useful paths.
#
export PX4BASE = $(realpath $(dir $(lastword $(MAKEFILE_LIST))))
export NUTTX_SRC = $(PX4BASE)/nuttx
export NUTTX_APPS = $(PX4BASE)/apps
export MAVLINK_SRC = $(PX4BASE)/mavlink
export ROMFS_SRC = $(PX4BASE)/ROMFS
export IMAGE_DIR = $(PX4BASE)/Images
#
# Tools
#
MKFW = $(PX4BASE)/Tools/px_mkfw.py
UPLOADER = $(PX4BASE)/Tools/px_uploader.py
#
# What are we currently configured for?
#
CONFIGURED = $(PX4BASE)/.configured
ifeq ($(wildcard $(CONFIGURED)),)
# the $(CONFIGURED) target will make this a reality before building
export TARGET = px4fmu
$(shell echo $(TARGET) > $(CONFIGURED))
else
export TARGET = $(shell cat $(CONFIGURED))
endif
#
# What we will build
#
FIRMWARE_BUNDLE = $(IMAGE_DIR)/$(TARGET).px4
FIRMWARE_BINARY = $(IMAGE_DIR)/$(TARGET).bin
FIRMWARE_PROTOTYPE = $(IMAGE_DIR)/$(TARGET).prototype
#
# Debugging
#
MQUIET = --no-print-directory
#MQUIET = --print-directory
all: $(FIRMWARE_BUNDLE)
#
# Generate a wrapped .px4 file from the built binary
#
$(FIRMWARE_BUNDLE): $(FIRMWARE_BINARY) $(MKFW) $(FIRMWARE_PROTOTYPE)
@echo Generating $@
@$(MKFW) --prototype $(FIRMWARE_PROTOTYPE) \
--git_identity $(PX4BASE) \
--image $(FIRMWARE_BINARY) > $@
#
# Build the firmware binary.
#
.PHONY: $(FIRMWARE_BINARY)
$(FIRMWARE_BINARY): configure_$(TARGET) setup_$(TARGET)
@echo Building $@
@make -C $(NUTTX_SRC) -r $(MQUIET) all
@cp $(NUTTX_SRC)/nuttx.bin $@
#
# The 'configure' targets select one particular firmware configuration
# and makes it current.
#
configure_px4fmu:
ifneq ($(TARGET),px4fmu)
@make -C $(PX4BASE) distclean
endif
@cd $(NUTTX_SRC)/tools && /bin/sh configure.sh px4fmu/nsh
@echo px4fmu > $(CONFIGURED)
configure_px4io:
ifneq ($(TARGET),px4io)
@make -C $(PX4BASE) distclean
endif
@cd $(NUTTX_SRC)/tools && /bin/sh configure.sh px4io/io
@echo px4io > $(CONFIGURED)
#
# Per-configuration additional targets
#
.PHONY: px4fmu_setup
setup_px4fmu:
@echo Generating ROMFS
@make -C $(ROMFS_SRC) all
setup_px4io:
#
# Firmware uploading.
#
# serial port defaults by operating system.
SYSTYPE = $(shell uname)
ifeq ($(SYSTYPE),Darwin)
SERIAL_PORTS ?= "/dev/tty.usbmodemPX1,/dev/tty.usbmodemPX2,/dev/tty.usbmodemPX3,/dev/tty.usbmodemPX4"
endif
ifeq ($(SYSTYPE),Linux)
SERIAL_PORTS ?= "/dev/ttyACM5,/dev/ttyACM4,/dev/ttyACM3,/dev/ttyACM2,/dev/ttyACM1,/dev/ttyACM0"
endif
ifeq ($(SERIAL_PORTS),)
SERIAL_PORTS = "\\\\.\\COM18,\\\\.\\COM17,\\\\.\\COM16,\\\\.\\COM15,\\\\.\\COM14,\\\\.\\COM13,\\\\.\\COM12,\\\\.\\COM11,\\\\.\\COM10,\\\\.\\COM9,\\\\.\\COM8,\\\\.\\COM7,\\\\.\\COM6,\\\\.\\COM5,\\\\.\\COM4,\\\\.\\COM3,\\\\.\\COM2,\\\\.\\COM1,\\\\.\\COM0"
endif
upload: $(FIRMWARE_BUNDLE) $(UPLOADER)
@python -u $(UPLOADER) --port $(SERIAL_PORTS) $(FIRMWARE_BUNDLE)
#
# Hacks and fixups
#
ifeq ($(SYSTYPE),Darwin)
# PATH inherited by Eclipse may not include toolchain install location
export PATH := $(PATH):/usr/local/bin
endif
#
# Cleanup targets. 'clean' should remove all built products and force
# a complete re-compilation, 'distclean' should remove everything
# that's generated leaving only files that are in source control.
#
.PHONY: clean
clean:
@make -C $(NUTTX_SRC) -r $(MQUIET) clean
@make -C $(ROMFS_SRC) -r $(MQUIET) clean
.PHONY: distclean
distclean:
@rm -f $(CONFIGURED)
@make -C $(NUTTX_SRC) -r $(MQUIET) distclean
@make -C $(ROMFS_SRC) -r $(MQUIET) distclean
+1
View File
@@ -0,0 +1 @@
/img
+102
View File
@@ -0,0 +1,102 @@
#
# Makefile to generate a PX4FMU ROMFS image.
#
# In normal use, 'make install' will generate a new ROMFS header and place it
# into the px4fmu configuration in the appropriate location.
#
#
# Directories of interest
#
SRCROOT ?= $(dir $(lastword $(MAKEFILE_LIST)))
BUILDROOT ?= $(SRCROOT)/img
ROMFS_HEADER ?= $(SRCROOT)/../nuttx/configs/px4fmu/include/nsh_romfsimg.h
#
# List of files to install in the ROMFS, specified as <source>~<destination>
#
ROMFS_FSSPEC := $(SRCROOT)/scripts/rcS~init.d/rcS \
$(SRCROOT)/scripts/rc.sensors~init.d/rc.sensors \
$(SRCROOT)/scripts/rc.logging~init.d/rc.logging \
$(SRCROOT)/scripts/rc.standalone~init.d/rc.standalone \
$(SRCROOT)/scripts/rc.PX4IO~init.d/rc.PX4IO \
$(SRCROOT)/scripts/rc.PX4IOAR~init.d/rc.PX4IOAR
#
# Add the PX4IO firmware to the spec if someone has dropped it into the
# source directory, or otherwise specified its location.
#
# Normally this is only something you'd do when working on PX4IO; most
# users will upgrade with firmware off the microSD card.
#
PX4IO_FIRMWARE ?= $(SRCROOT)/px4io.bin
ifneq ($(wildcard $(PX4IO_FIRMWARE)),)
ROMFS_FSSPEC += $(PX4IO_FIRMWARE)~px4io.bin
endif
################################################################################
# No user-serviceable parts below
################################################################################
#
# Just the source files from the ROMFS spec, so that we can fail cleanly if they don't
# exist
#
ROMFS_SRCFILES = $(foreach spec,$(ROMFS_FSSPEC),$(firstword $(subst ~, ,$(spec))))
#
# Just the destination directories from the ROMFS spec
#
ROMFS_DIRS = $(sort $(dir $(foreach spec,$(ROMFS_FSSPEC),$(lastword $(subst ~, ,$(spec))))))
#
# Intermediate products
#
ROMFS_IMG = $(BUILDROOT)/romfs.img
ROMFS_WORKDIR = $(BUILDROOT)/romfs
#
# Convenience target for rebuilding the ROMFS header
#
all: $(ROMFS_HEADER)
$(ROMFS_HEADER): $(ROMFS_IMG) $(dir $(ROMFS_HEADER))
@echo Generating the ROMFS header...
@(cd $(dir $(ROMFS_IMG)) && xxd -i $(notdir $(ROMFS_IMG))) > $@
$(ROMFS_IMG): $(ROMFS_WORKDIR)
@echo Generating the ROMFS image...
@genromfs -f $@ -d $(ROMFS_WORKDIR) -V "NSHInitVol"
$(ROMFS_WORKDIR): $(ROMFS_SRCFILES)
@echo Rebuilding the ROMFS work area...
@rm -rf $(ROMFS_WORKDIR)
@mkdir -p $(ROMFS_WORKDIR)
@for dir in $(ROMFS_DIRS) ; do mkdir -p $(ROMFS_WORKDIR)/$$dir; done
@for spec in $(ROMFS_FSSPEC) ; do \
echo $$spec | sed -e 's%^.*~% %' ;\
`echo "cp $$spec" | sed -e 's%~% $(ROMFS_WORKDIR)/%'` ;\
done
$(BUILDROOT):
@mkdir -p $(BUILDROOT)
clean:
@rm -rf $(BUILDROOT)
distclean: clean
@rm -f $(PX4IO_FIRMWARE) $(ROMFS_HEADER)
.PHONY: all install clean distclean
#
# Hacks and fixups
#
SYSTYPE = $(shell uname)
ifeq ($(SYSTYPE),Darwin)
# PATH inherited by Eclipse may not include toolchain install location
export PATH := $(PATH):/usr/local/bin
endif
+74
View File
@@ -0,0 +1,74 @@
#!nsh
#
# Flight startup script for PX4FMU with PX4IO carrier board.
#
echo "[init] doing PX4IO startup..."
#
# Start the ORB
#
uorb start
#
# Start the sensors.
#
sh /etc/init.d/rc.sensors
#
# Start MAVLink
#
mavlink -d /dev/ttyS0 -b 57600 &
#
# Start the commander.
#
# XXX this should be '<command> start'.
#
commander &
#
# Start the attitude estimator
#
# XXX this should be '<command> start'.
#
attitude_estimator_bm &
#position_estimator &
#
# Configure PX4FMU for operation with PX4IO
#
# XXX arguments?
#
px4fmu start
#
# Start the fixed-wing controller
#
# XXX this should be '<command> start'.
#
fixedwing_control &
#
# Fire up the PX4IO interface.
#
px4io start
#
# Start looking for a GPS.
#
# XXX this should not need to be backgrounded
#
gps -d /dev/ttyS3 -m all &
#
# Start logging to microSD if we can
#
sh /etc/init.d/rc.logging
#
# startup is done; we don't want the shell because we
# use the same UART for telemetry (dumb).
#
echo "[init] startup done, exiting."
exit
+69
View File
@@ -0,0 +1,69 @@
#!nsh
#
# Flight startup script for PX4FMU on PX4IOAR carrier board.
#
echo "[init] doing PX4IOAR startup..."
#
# Start the ORB
#
uorb start
#
# Start the sensors.
#
sh /etc/init.d/rc.sensors
#
# Start MAVLink
#
mavlink -d /dev/ttyS0 -b 57600 &
#
# Start the commander.
#
# XXX this should be '<command> start'.
#
commander &
#
# Start the attitude estimator
#
# XXX this should be '<command> start'.
#
attitude_estimator_bm &
#position_estimator &
#
# Configure PX4FMU for operation with PX4IOAR
#
# XXX arguments?
#
px4fmu start
#
# Fire up the AR.Drone controller.
#
# XXX this should be '<command> start'.
#
ardrone_control -d /dev/ttyS1 -m attitude &
#
# Start looking for a GPS.
#
# XXX this should not need to be backgrounded
#
gps -d /dev/ttyS3 -m all &
#
# Start logging to microSD if we can
#
sh /etc/init.d/rc.logging
#
# startup is done; we don't want the shell because we
# use the same UART for telemetry (dumb).
#
echo "[init] startup done, exiting."
exit
+10
View File
@@ -0,0 +1,10 @@
#!nsh
#
# Test jig startup script
#
echo "[testing] doing production test.."
tests jig
echo "[testing] testing done"
+10
View File
@@ -0,0 +1,10 @@
#!nsh
#
# Initialise logging services.
#
if [ -d /fs/microsd ]
then
# XXX this should be '<command> start'.
# sdlog &
fi
+28
View File
@@ -0,0 +1,28 @@
#!nsh
#
# Standard startup script for PX4FMU onboard sensor drivers.
#
#
# Start sensor drivers here.
#
#ms5611 start
#
# Start the sensor collection task.
#
# XXX should be 'sensors start'
#
sensors &
#
# Test sensor functionality
#
# XXX integrate with 'sensors start' ?
#
#if sensors quicktest
#then
# echo "[init] sensor initialisation FAILED."
# reboot
#fi
+67
View File
@@ -0,0 +1,67 @@
#!nsh
#
# Flight startup script for PX4FMU standalone configuration.
#
echo "[init] doing standalone PX4FMU startup..."
#
# Start the ORB
#
#uorb start
#
# Start the sensors.
#
#sh /etc/init.d/rc.sensors
#
# Start MAVLink
#
# mavlink -d /dev/ttyS0 -b 57600 &
#
# Start the commander.
#
# XXX this should be 'commander start'.
#
#commander &
#
# Start the attitude estimator
#
# XXX this should be '<command> start'.
#
#attitude_estimator_bm &
#position_estimator &
#
# Start the fixed-wing controller.
#
# XXX should this be looking for configuration to decide
# whether the board is configured for fixed-wing use?
#
# XXX this should be 'fixedwing_control start'.
#
#fixedwing_control &
#
# Configure FMU for standalone mode
#
# XXX arguments?
#
#px4fmu start
#
# Start looking for a GPS.
#
# XXX this should not need to be backgrounded
#
#gps -d /dev/ttyS3 -m all &
#
# Start logging to microSD if we can
#
sh /etc/init.d/rc.logging
echo "[init] startup done"
+120
View File
@@ -0,0 +1,120 @@
#!nsh
#
# PX4FMU startup script.
#
# This script is responsible for:
#
# - mounting the microSD card (if present)
# - running the user startup script from the microSD card (if present)
# - detecting the configuration of the system and picking a suitable
# startup script to continue with
#
# Note: DO NOT add configuration-specific commands to this script;
# add them to the per-configuration scripts instead.
#
#
# Default to auto-start mode. An init script on the microSD card
# can change this to prevent automatic startup of the flight script.
#
set MODE autostart
set USB_ALLOWED yes
set USB no
#
# Try to mount the microSD card.
#
echo "[init] looking for microSD..."
if mount -t vfat /dev/mmcsd0 /fs/microsd
then
echo "[init] card mounted at /fs/microsd"
else
echo "[init] no microSD card found"
fi
#
# Look for an init script on the microSD card.
#
# To prevent automatic startup in the current flight mode,
# the script should set MODE to some other value.
#
if [ -f /fs/microsd/etc/rc ]
then
echo "[init] reading /fs/microsd/etc/rc"
sh /fs/microsd/etc/rc
fi
#
# Check for USB host
#
if [ $USB_ALLOWED == yes ]
then
if sercon
then
echo "[init] USB interface connected"
fi
fi
#
# If we are still in flight mode, work out what airframe
# configuration we have and start up accordingly.
#
if [ $MODE != autostart ]
then
echo "[init] automatic startup cancelled by user script"
else
echo "[init] detecting attached hardware..."
#
# Assume that we are PX4FMU in standalone mode
#
set BOARD PX4FMU
#
# Are we attached to a PX4IOAR (AR.Drone carrier board)?
#
if boardinfo -t 7
then
set BOARD PX4IOAR
if [ -f /etc/init.d/rc.PX4IOAR ]
then
echo "[init] reading /etc/init.d/rc.PX4IOAR"
sh /etc/init.d/rc.PX4IOAR
fi
else
echo "[init] PX4IOAR not detected"
fi
#
# Are we attached to a PX4IO?
#
if boardinfo -t 6
then
set BOARD PX4IO
if [ -f /etc/init.d/rc.PX4IO ]
then
echo "[init] reading /etc/init.d/rc.PX4IO"
sh /etc/init.d/rc.PX4IO
fi
else
echo "[init] PX4IO not detected"
fi
#
# Looks like we are stand-alone
#
if [ $BOARD == PX4FMU ]
then
echo "[init] no expansion board detected"
if [ -f /etc/init.d/rc.standalone ]
then
echo "[init] reading /etc/init.d/rc.standalone"
sh /etc/init.d/rc.standalone
fi
fi
#
# We may not reach here if the airframe-specific script exits the shell.
#
echo "[init] startup done."
fi
+19
View File
@@ -0,0 +1,19 @@
#!/bin/sh
astyle \
--style=linux \
--indent=force-tab=8 \
--indent-cases \
--indent-preprocessor \
--break-blocks=all \
--pad-oper \
--pad-header \
--unpad-paren \
--keep-one-line-blocks \
--keep-one-line-statements \
--align-pointer=name \
--align-reference=name \
--suffix=none \
--ignore-exclude-errors-x \
--lineend=linux \
--exclude=EASTL \
$*
+110
View File
@@ -0,0 +1,110 @@
#!/usr/bin/env python
############################################################################
#
# Copyright (C) 2012 PX4 Development Team. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# 3. Neither the name PX4 nor the names of its contributors may be
# used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
############################################################################
#
# PX4 firmware image generator
#
# The PX4 firmware file is a JSON-encoded Python object, containing
# metadata fields and a zlib-compressed base64-encoded firmware image.
#
import sys
import argparse
import json
import base64
import zlib
import time
import subprocess
#
# Construct a basic firmware description
#
def mkdesc():
proto = {}
proto['magic'] = "PX4FWv1"
proto['board_id'] = 0
proto['board_revision'] = 0
proto['version'] = ""
proto['summary'] = ""
proto['description'] = ""
proto['git_identity'] = ""
proto['build_time'] = 0
proto['image'] = base64.b64encode(bytearray())
proto['image_size'] = 0
return proto
# Parse commandline
parser = argparse.ArgumentParser(description="Firmware generator for the PX autopilot system.")
parser.add_argument("--prototype", action="store", help="read a prototype description from a file")
parser.add_argument("--board_id", action="store", help="set the board ID required")
parser.add_argument("--board_revision", action="store", help="set the board revision required")
parser.add_argument("--version", action="store", help="set a version string")
parser.add_argument("--summary", action="store", help="set a brief description")
parser.add_argument("--description", action="store", help="set a longer description")
parser.add_argument("--git_identity", action="store", help="the working directory to check for git identity")
parser.add_argument("--image", action="store", help="the firmware image")
args = parser.parse_args()
# Fetch the firmware descriptor prototype if specified
if args.prototype != None:
f = open(args.prototype,"r")
desc = json.load(f)
f.close()
else:
desc = mkdesc()
desc['build_time'] = int(time.time())
if args.board_id != None:
desc['board_id'] = int(args.board_id)
if args.board_revision != None:
desc['board_revision'] = int(args.board_revision)
if args.version != None:
desc['version'] = str(args.version)
if args.summary != None:
desc['summary'] = str(args.summary)
if args.description != None:
desc['description'] = str(args.description)
if args.git_identity != None:
cmd = " ".join(["git", "--git-dir", args.git_identity + "/.git", "describe", "--always", "--dirty"])
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE).stdout
desc['git_identity'] = p.read().strip()
p.close()
if args.image != None:
f = open(args.image, "rb")
bytes = f.read()
desc['image_size'] = len(bytes)
desc['image'] = base64.b64encode(zlib.compress(bytes,9))
print json.dumps(desc, indent=4)
+318
View File
@@ -0,0 +1,318 @@
############################################################################
#
# Copyright (C) 2012 PX4 Development Team. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# 3. Neither the name PX4 nor the names of its contributors may be
# used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
############################################################################
#
# Serial firmware uploader for the PX4FMU bootloader
#
# The PX4 firmware file is a JSON-encoded Python object, containing
# metadata fields and a zlib-compressed base64-encoded firmware image.
#
# The uploader uses the following fields from the firmware file:
#
# image
# The firmware that will be uploaded.
# image_size
# The size of the firmware in bytes.
# board_id
# The board for which the firmware is intended.
# board_revision
# Currently only used for informational purposes.
#
import sys
import argparse
import binascii
import serial
import os
import struct
import json
import zlib
import base64
import time
from sys import platform as _platform
class firmware(object):
'''Loads a firmware file'''
desc = {}
image = bytearray()
def __init__(self, path):
# read the file
f = open(path, "r")
self.desc = json.load(f)
f.close()
self.image = zlib.decompress(base64.b64decode(self.desc['image']))
def property(self, propname):
return self.desc[propname]
class uploader(object):
'''Uploads a firmware file to the PX FMU bootloader'''
NOP = chr(0x00)
OK = chr(0x10)
FAILED = chr(0x11)
INSYNC = chr(0x12)
EOC = chr(0x20)
GET_SYNC = chr(0x21)
GET_DEVICE = chr(0x22)
CHIP_ERASE = chr(0x23)
CHIP_VERIFY = chr(0x24)
PROG_MULTI = chr(0x27)
READ_MULTI = chr(0x28)
REBOOT = chr(0x30)
INFO_BL_REV = chr(1) # bootloader protocol revision
BL_REV = 2 # supported bootloader protocol
INFO_BOARD_ID = chr(2) # board type
INFO_BOARD_REV = chr(3) # board revision
INFO_FLASH_SIZE = chr(4) # max firmware size in bytes
PROG_MULTI_MAX = 60 # protocol max is 255, must be multiple of 4
READ_MULTI_MAX = 60 # protocol max is 255, something overflows with >= 64
def __init__(self, portname, baudrate):
# open the port
self.port = serial.Serial(portname, baudrate, timeout=10)
def close(self):
if self.port is not None:
self.port.close()
def __send(self, c):
# print("send " + binascii.hexlify(c))
self.port.write(str(c))
def __recv(self, count = 1):
c = self.port.read(count)
if (len(c) < 1):
raise RuntimeError("timeout waiting for data")
# print("recv " + binascii.hexlify(c))
return c
def __getSync(self):
self.port.flush()
c = self.__recv()
if (c != self.INSYNC):
raise RuntimeError("unexpected 0x%x instead of INSYNC" % ord(c))
c = self.__recv()
if (c != self.OK):
raise RuntimeError("unexpected 0x%x instead of OK" % ord(c))
# attempt to get back into sync with the bootloader
def __sync(self):
# send a stream of ignored bytes longer than the longest possible conversation
# that we might still have in progress
# self.__send(uploader.NOP * (uploader.PROG_MULTI_MAX + 2))
self.port.flushInput()
self.__send(uploader.GET_SYNC
+ uploader.EOC)
self.__getSync()
def __trySync(self):
c = self.__recv()
if (c != self.INSYNC):
#print("unexpected 0x%x instead of INSYNC" % ord(c))
return False;
c = self.__recv()
if (c != self.OK):
#print("unexpected 0x%x instead of OK" % ord(c))
return False
return True
# send the GET_DEVICE command and wait for an info parameter
def __getInfo(self, param):
self.__send(uploader.GET_DEVICE + param + uploader.EOC)
raw = self.__recv(4)
self.__getSync()
value = struct.unpack_from('<I', raw)
return value[0]
# send the CHIP_ERASE command and wait for the bootloader to become ready
def __erase(self):
self.__send(uploader.CHIP_ERASE
+ uploader.EOC)
self.__getSync()
# send a PROG_MULTI command to write a collection of bytes
def __program_multi(self, data):
self.__send(uploader.PROG_MULTI
+ chr(len(data)))
self.__send(data)
self.__send(uploader.EOC)
self.__getSync()
# verify multiple bytes in flash
def __verify_multi(self, data):
self.__send(uploader.READ_MULTI
+ chr(len(data))
+ uploader.EOC)
programmed = self.__recv(len(data))
if (programmed != data):
print("got " + binascii.hexlify(programmed))
print("expect " + binascii.hexlify(data))
return False
self.__getSync()
return True
# send the reboot command
def __reboot(self):
self.__send(uploader.REBOOT)
self.port.flush()
# split a sequence into a list of size-constrained pieces
def __split_len(self, seq, length):
return [seq[i:i+length] for i in range(0, len(seq), length)]
# upload code
def __program(self, fw):
code = fw.image
groups = self.__split_len(code, uploader.PROG_MULTI_MAX)
for bytes in groups:
self.__program_multi(bytes)
# verify code
def __verify(self, fw):
self.__send(uploader.CHIP_VERIFY
+ uploader.EOC)
self.__getSync()
code = fw.image
groups = self.__split_len(code, uploader.READ_MULTI_MAX)
for bytes in groups:
if (not self.__verify_multi(bytes)):
raise RuntimeError("Verification failed")
# get basic data about the board
def identify(self):
# make sure we are in sync before starting
self.__sync()
# get the bootloader protocol ID first
bl_rev = self.__getInfo(uploader.INFO_BL_REV)
if bl_rev != uploader.BL_REV:
raise RuntimeError("Bootloader protocol mismatch")
self.board_type = self.__getInfo(uploader.INFO_BOARD_ID)
self.board_rev = self.__getInfo(uploader.INFO_BOARD_REV)
self.fw_maxsize = self.__getInfo(uploader.INFO_FLASH_SIZE)
# upload the firmware
def upload(self, fw):
# Make sure we are doing the right thing
if self.board_type != fw.property('board_id'):
raise RuntimeError("Firmware not suitable for this board")
if self.fw_maxsize < fw.property('image_size'):
raise RuntimeError("Firmware image is too large for this board")
print("erase...")
self.__erase()
print("program...")
self.__program(fw)
print("verify...")
self.__verify(fw)
print("done, rebooting.")
self.__reboot()
self.port.close()
# Parse commandline arguments
parser = argparse.ArgumentParser(description="Firmware uploader for the PX autopilot system.")
parser.add_argument('--port', action="store", required=True, help="Serial port(s) to which the FMU may be attached")
parser.add_argument('--baud', action="store", type=int, default=115200, help="Baud rate of the serial port (default is 115200), only required for true serial ports.")
parser.add_argument('firmware', action="store", help="Firmware file to be uploaded")
args = parser.parse_args()
# Load the firmware file
fw = firmware(args.firmware)
print("Loaded firmware for %x,%x, waiting for the bootloader..." % (fw.property('board_id'), fw.property('board_revision')))
# Spin waiting for a device to show up
while True:
for port in args.port.split(","):
#print("Trying %s" % port)
# create an uploader attached to the port
try:
if "linux" in _platform:
# Linux, don't open Mac OS and Win ports
if not "COM" in port and not "tty.usb" in port:
up = uploader(port, args.baud)
elif "darwin" in _platform:
# OS X, don't open Windows and Linux ports
if not "COM" in port and not "ACM" in port:
up = uploader(port, args.baud)
elif "win" in _platform:
# Windows, don't open POSIX ports
if not "/" in port:
up = uploader(port, args.baud)
except:
# open failed, rate-limit our attempts
time.sleep(0.05)
# and loop to the next port
continue
# port is open, try talking to it
try:
# identify the bootloader
up.identify()
print("Found board %x,%x on %s" % (up.board_type, up.board_rev, port))
except:
# most probably a timeout talking to the port, no bootloader
continue
try:
# ok, we have a bootloader, try flashing it
up.upload(fw)
except RuntimeError as ex:
# print the error
print("ERROR: %s" % ex.args)
finally:
# always close the port
up.close()
# we could loop here if we wanted to wait for more boards...
sys.exit(0)
+272
View File
@@ -0,0 +1,272 @@
5.19 2011-03-12 Gregory Nutt <gnutt@nuttx.org>
* Initial version of the apps/ directory was released as contributed by
Uros Platise.
6.0 2011-03-21 Gregory Nutt <gnutt@nuttx.org>
* README.txt -- README cosmetics
* hello/ -- hello world minor changes
* Makefile -- Makefile cosmetics (I am slowly adding the Darjeeling JVM)
* Make.defs -- New file adds common make definitions for applications.
* hello/Makefile -- Now uses new Make.defs definitions. Added README.txt.
* apps/poweroff -- New application to turn off board power.
* Moved NSH library, netutils, and examples from the nuttx/ directory to
the apps/ directory
* Moved exec_nuttapp machinery into the nuttapp/ directory.
6.1 2011-04-10 Gregory Nutt <gnutt@nuttx.org>
* Creation of auto-generated header files now occurs during the context
build phase.
* Added sdcard insert and eject, nsh command '?' and some code remarks
* Renamed nuttapp to namedapp
* namedapp/binfs.c -- Create a tiny filesystem that can be used
to show the internal named apps under /bin.
* Numerous fixes to build system required to support building with native
Windows toolchain.
6.2 2011-05-06 Gregory Nutt <gnutt@nuttx.org>
* apps/examples/nxffs: Add a test a a configuration that will be used to
verify NXFFS.
6.3 2011-05-15 Gregory Nutt <gnutt@nuttx.org>
* apps/interpreter: Add a directory to hold interpreters. The Pascal add-
on module now installs and builds under this directory.
* apps/interpreter/ficl: Added logic to build Ficl (the "Forth Inspired
Command Language"). See http://ficl.sourceforge.net/.
* apps/netutils/dhcpc, dhcpcd, and tftp. If these directories are included
in the configuration but CONFIG_NET_UDP is disable (which is not very wise),
then a make error occurs because tools/mkdep.sh is called with no files.
* system/free: Move Uros' custom free command from vsn/free
* system/install: Add a new install command submitted by Uros Platise.
* examples/rgmp. Add a placeholder for an RGMP build example.
RGMP is a project for running GPOS and RTOS simultaneously on
multi-processor platforms. See http://rgmp.sourceforge.net/wiki/index.php/Main_Page
for further information about RGMP. NOTE: This is an empty example
on initial check-in.
6.4 2011-06-06 Gregory Nutt <gnutt@nuttx.org>
* nshlib/nsh_netcmds.c: If a network device name and IP address are provided
with the ifconfig command, then this command will now set the network address.
(Contributed by Yu Qiang).
* netutils/ftpc: A library to support client-side FTP.
* examples/ftpc: A simple add-on to the NSH. From NSH, you can start
this simple FTP shell to transfer files to/from a remote FTP server.
6.5 2011-06-21 Gregory Nutt <gnutt@nuttx.org>
* netutils/ftpc: Simpflication and size reduction.
6.6 2011-07-11 Gregory Nutt <gnutt@nuttx.org>
* Make.defs, namedapp/namedapp.c: Several structural changes made to get a
clean compile under the ez80 ZDS-II toolchain (no design changes).
* apps/examples/buttons: Add a test for the new standardized button interfaces
* apps/examples/nxtext: Add another NX graphics test. This one focus on
placing text on the background while pop-up windows occur. Text should
continue to update normally with or without the popup windows present.
6.7 2011-08-02 Gregory Nutt <gnutt@nuttx.org>
* apps/examples/nx and nxtext: These examples can now be built as NSH
"built-in" commands.
* apps/examples/nxhello: The simplest graphics example: It just says
"Hello, World!" in the center of the display. This example can also be
built as an NSH "built-in" command.
* apps/examples/nx, ntext, and nxhello: All updated to use the new
NuttX font interfaces.
* apps/examples/nximage: Another super simple graphics example: It just puts
the NuttX logo in the center of the display. This example can also be
built as an NSH "built-in" command.
* apps/examples/usbstorage: Can now be built as two NSH "built-in" commands:
'msconn' will connect the USB mass storage device; 'msdis' will disconnect
the USB storage device.
* apps/examples/nx*: All NX header files moved from nuttx/include/nuttx to
nuttx/include/nuttx/nx.
* apps/examples/usbstorage: Added instrumentation to monitor memory usage
to check for memory leaks in the USB storage driver.
* apps/examples/nxhello/nxhello_bkgd.c: Fix handling of allocated glyph
memory.
6.8 2011-08-11 Gregory Nutt <gnutt@nuttx.org>
* apps/examples/nxlines: Added a test for NX line drawing capabilities.
6.9 2011-09-11 Gregory Nutt <gnutt@nuttx.org>
* apps/examples/nxlines: Extend the line drawing text to include drawing
of circles.
* apps/system/i2c: Add an I2C test tool that should help to bring up I2C
devices (when it is fully functional).
* apps/nshlib/nsh_timcmds.c: Add the date command that can be used to
show or set the time (only if CONFIG_RTC is set).
6.10 2011-10-06 Gregory Nutt <gnutt@nuttx.org>
* apps/system/i2c: Add repitition and address auto-incrementing so that
and command can be executed numerous times. Add a new verify command
that will write to a register, read from register, and verify that
returned value.
* apps/graphics/tiff: Add a library that can be used to create TIFF files.
* apps/examples/tiff: Add a unit test for the TIFF file creation logic
* apps/examples/lcdrw: Add a test to verify if you can or can or read
data from an LCD correctly.
* apps/examples/usbterm: A USB terminal example.. more of a USB chat or
serial bridge: Data received on local console echoed via USB serial;
data received on USB serial is echoed on the local console.
* apps/examples/touchscreen: Add a simple, generic test for any
touschscreen driver.
* Makefile: The apps/ Makefile now checks for an apps/external directory
or symbolic link. If such a directory/link exists (and has a Makefile),
it will be added to the apps/ build. This allows external directories
to be included into the apps/ build by simply creating a symbolic link.
6.11 2011-11-12 Gregory Nutt <gnutt@nuttx.org>
(No major changes from 6.10)
6.12 2011-12-06 Gregory Nutt <gnutt@nuttx.org>
* apps/examples/buttons: The button test can now be executed as an NSH
built in command.
6.13 2012-12-26 Gregory Nutt <gnutt@nuttx.org>
* apps/examples/dhcpd: May now be built as an NSH built-in application
by setting CONFIG_NSH_BUILTIN_APPS.
* apps/netutils/dhcpd/dhcpd.c: Fix several problems using host order address
where network addresses expected (and vice versa).
* apps/examples/nettest: May now be built as an NSH built-in application
by setting CONFIG_NSH_BUILTIN_APPS.
* apps/examples/nettest: Correct some build issues with the nettest is
built for performance evaluation.
* apps/examples/adc: Add a very simple test to drive and test an ADC
driver.
* apps/examples/pwm: Add an NSH PWM command to drive and test a PWM
driver.
* apps/examples/can: Add an NSH CAN command to drive and test a CAN
driver in loopback mode.
6.14 2012-01-15 Gregory Nutt <gnutt@nuttx.org>
* apps/examples/buttons/main.c: The test needs to call up_buttoninit() to
properly configure the button interrupt GPIOs.
* apps/examples/pwm: Add support to test the pulse count option recently
added to the PWM interface.
6.15 2012-02-12 Gregory Nutt <gnutt@nuttx.org>
* apps/nshlib/nsh_serial.c and nsh_usbdev.c: If NuttX is configured to use
a USB serial console, then NSH needs to wait until the USB console is
connected and available.
* apps/examples/composite: Add a test of the USB composite device.
* apps/examples/Telnetd: Move the tiny uIP shell example from
netutils/Telnetd to examples/Telnetd. Enhanced the Telnetd daemon so that
it supports Telnetd via a TTY device driver: A new TTY device driver is
created when each new Telnet connection is created. The shell thread
is started with stdin, stdout, and stderr mapped to the TTY device.
* netutils/Telnetd: The old uIP Telnet demo is gone. In its place is a new
Telnet infrastructure. The new Telnet daemon creates sessions that are
"wrapped" as character devices and mapped to stdin, stdout, and stderr.
Now the Telnet session can be inherited by spawned tasks.
* examples/Telnetd: Add a test for the new Telnet daemon.
* examples/Telnetd/telnetd_driver.c: Move the internal socket structure from
the daemon's socket array into the driver's state data so that it will be
independent from the the Telnetd daemon.
* apps/system/readline: Moved the old nuttx/lib/stdio/lib_fgets.c here
and renamed it as readline(). The old fgets was simplied and the overloaded
readline functionality was removed.
* apps/netutils/ftpd: Add an FTPD server (does not even compile on initial
checkin).
* apps/examples/ftpd: Add a test for the FTPD server (untest on initial
check-in).
* apps/nshlib/nsh_fscmds.c: Add support for a 'dmesg' command that will
dump the system log if CONFIG_SYSLOG is selected.
6.16 2012-03-10 Gregory Nutt <gnutt@nuttx.org>
* apps/examples/qencoder: Add a quadrature driver test.
* apps/examples/ostest/fpu.c: Add a test to verify that FPU registers
are properly saved and restored on context switches.
* apps/system/readline/readline.c: readline() will now treat either a
backspace or a DEL character as a backspace (i.e., deleting the character
to the left of the cursor). This makes NSH less dependent on particular
keyboard mappings of the Backspace key. Submitted by Mike Smith.
* apps/examples/cdcacm: An example that illustrates how the CDC/ACM driver
may to connected and disconnected through software control.
* apps/examples/nsh/nsh_main.c: If available, call up_cxxinitialize() to
initialize all statically defined C++ classes.
* apps/nshlib: Now supports a USB serial device for NSH console I/O. This
allows NSH to be used on boards that have USB but no serial connectors.
6.17 2012-04-14 Gregory Nutt <gnutt@nuttx.org>
* apps/examples/can: Add conditional compilation so that the test can be
configured to only send messages or to only receive messages. This will
let the test work in other modes than simple loopback testing.
* apps/examples/hello and apps/examples/ostest: Can now be built as NSH
built-int functions.
* vsn/hello: Removed. The modified apps/examples/hello is enough "Hello,
World!"
* apps/examples/nxconsole: Add a test of the NX console device.
* apps/examples/nxconsole: The NX console example now supports running
the NuttShell (NSH) within an NX window.
* apps/system/readline: Now uses standard definitions from
include/nuttx/ascii.h and vt100.h
* Kconfig, */Kconfig: Added skeleton Kconfig files to all directories that
may need them.
6.18 2012-05-19 Gregory Nutt <gnutt@nuttx.org>
* Kconfig: Continued Kconfig file updates (no longer tracking on a per-file
basis in the ChangeLog)
* apps/examples/watchdog: Add a watchdog timer example.
* apps/examples/tiff: Fix wrong path used for temporary file.
* apps/examples/touchscreen: Standardize the board-specific, touchscreen
initialization interfaces.
6.19 2012-06-15 Gregory Nutt <gnutt@nuttx.org>
* apps/nshlib/nsh_usbdev.c: Add the capability to use an arbitrary USB
device as the console (not necessarily /dev/console). This is a useful
option because then you can still use the serial console to debug with.
* apps/nshlib/nsh_usbdev.c: User now has to press ENTER 3 times before
USB console will start. Otherwise, the USB console starts before there
is anyone at the other end to listen.
* apps/nshlib/nsh_usbdev.c and nsh_consolemain.c: Add support for the USB
capability when a USB console is used.
* apps/nshlib/nsh_fscmds.c: Add the 'mv' command
6.20 2012-07-12 Gregory Nutt <gnutt@nuttx.org>
* namedapp/exec_namedapp.c - Correct an error when round robin scheduling
is enabled. The priority of the new, named application was erroneously
being set to the priority of the parent thread; losing its configured
priority. Reported by Mike Smith.
6.21 2012-xx-xx Gregory Nutt <gnutt@nuttx.org>
* apps/include/: Stylistic clean-up of all header files.
* apps/modbus and apps/include/modbus: A port of freemodbus-v1.5.0
has been added to the NuttX apps/ source tree.
* apps/examples/modbus: A port of the freemodbus-v1.5.0 "demo"
program that will be used to verify the FreeModBus port
* apps/modbus: Don't use strerror(). It is just too big.
* apps/modbus: Add CONFIG_MB_TERMIOS. If the driver doesn't support
termios ioctls, then don't bother trying to configure the baud, parity
etc.
* apps/nslib: If waitpid() is supported, then NSH not catches the
return value from spawned applications (provided by Mike Smith)
* apps/nslib: Lock the schedule while starting built-in applications
in order to eliminate race conditions (also from Mike Smith).
* apps/examples/adc, pwm, and qencoder: Add support for testing
devices with multiple ADC, PWM, and QE devices.
* apps/nshlib/nsh_mntcmds.c: Separated mount-related commands out of
nsh_fscmds.c. Extended to the mount command so that if no arguments
are provided, then the current mountpoints are enumerated.
* apps/nshlib/nsh_mntcmds.c: Add an NSH df command to list the
properties of mounted file systems.
+36
View File
@@ -0,0 +1,36 @@
#
# For a description of the syntax of this configuration file,
# see misc/tools/kconfig-language.txt.
#
menu "Named Applications"
source "$APPSDIR/namedapp/Kconfig"
endmenu
menu "Examples"
source "$APPSDIR/examples/Kconfig"
endmenu
menu "Interpreters"
source "$APPSDIR/interpreters/Kconfig"
endmenu
menu "Network Utilities"
source "$APPSDIR/netutils/Kconfig"
endmenu
menu "ModBus"
source "$APPSDIR/modbus/Kconfig"
endmenu
menu "NSH Library"
source "$APPSDIR/nshlib/Kconfig"
endmenu
menu "System NSH Add-Ons"
source "$APPSDIR/system/Kconfig"
endmenu
menu "VSN board Add-Ons"
source "$APPSDIR/vsn/Kconfig"
endmenu
+41
View File
@@ -0,0 +1,41 @@
############################################################################
# apps/Make.defs
# Common make definitions provided to all applications
#
# Copyright (C) 2011 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <spudmonkey@racsa.co.cr>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# 3. Neither the name NuttX nor the names of its contributors may be
# used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
############################################################################
define REGISTER
@echo "Register: $1"
@echo "{ \"$1\", $2, $3, $4 }," >> "$(APPDIR)/namedapp/namedapp_list.h"
@echo "EXTERN int $4(int argc, char *argv[]);" >> "$(APPDIR)/namedapp/namedapp_proto.h"
endef
+176
View File
@@ -0,0 +1,176 @@
############################################################################
# apps/Makefile
#
# Copyright (C) 2011-2012 Uros Platise. All rights reserved.
# Authors: Uros Platise <uros.platise@isotel.eu>
# Gregory Nutt <gnutt@nuttx.org>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# 3. Neither the name NuttX nor the names of its contributors may be
# used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
############################################################################
-include $(TOPDIR)/Make.defs
-include $(TOPDIR)/.config
APPDIR = ${shell pwd}
# Application Directories
# CONFIGURED_APPS is the list of all configured built-in directories/built
# action. It is created by the configured appconfig file (a copy of which
# appears in this directory as .config)
# SUBDIRS is the list of all directories containing Makefiles. It is used
# only for cleaning. namedapp must always be the first in the list. This
# list can be extended by the .config file as well
CONFIGURED_APPS =
#SUBDIRS = examples graphics interpreters modbus namedapp nshlib netutils system vsn
ALL_SUBDIRS = $(dir $(shell /usr/bin/find . -name Makefile))
SUBDIRS = namedapp/ $(filter-out ./ ./namedapp/ ./examples/,$(ALL_SUBDIRS))
# There are two different mechanisms for obtaining the list of configured
# directories:
#
# (1) In the legacy method, these paths are all provided in the appconfig
# file that is copied to the top-level apps/ directory as .config
# (2) With the development of the NuttX configuration tool, however, the
# selected applications are now enabled by the configuration tool.
# The apps/.config file is no longer used. Instead, the set of
# configured build directories can be found by including a Make.defs
# file contained in each of the apps/subdirectories.
#
# When the NuttX configuration tools executes, it will always define the
# configure CONFIG_NUTTX_NEWCONFIG to select between these two cases. Then
# legacy appconfig files will still work but newly configuration files will
# also work. Eventually the CONFIG_NUTTX_NEWCONFIG option will be phased
# out.
ifeq ($(CONFIG_NUTTX_NEWCONFIG),y)
-include examples/Make.defs
-include graphics/Make.defs
-include interpreters/Make.defs
-include modbus/Make.defs
-include namedapp/Make.defs
-include netutils/Make.defs
-include nshlib/Make.defs
-include system/Make.defs
-include vsn/Make.defs
# INSTALLED_APPS is the list of currently available application directories. It
# is the same as CONFIGURED_APPS, but filtered to exclude any non-existent
# application directory. namedapp is always in the list of applications to be
# built.
INSTALLED_APPS =
# The legacy case:
else
-include .config
# INSTALLED_APPS is the list of currently available application directories. It
# is the same as CONFIGURED_APPS, but filtered to exclude any non-existent
# application directory. namedapp is always in the list of applications to be
# built.
INSTALLED_APPS = namedapp
endif
# Create the list of available applications (INSTALLED_APPS)
define ADD_BUILTIN
INSTALLED_APPS += ${shell if [ -r $1/Makefile ]; then echo "$1"; fi}
endef
$(foreach BUILTIN, $(CONFIGURED_APPS), $(eval $(call ADD_BUILTIN,$(BUILTIN))))
# The external/ directory may also be added to the INSTALLED_APPS. But there
# is no external/ directory in the repository. Rather, this directory may be
# provided by the user (possibly as a symbolic link) to add libraries and
# applications to the standard build from the repository.
INSTALLED_APPS += ${shell if [ -r external/Makefile ]; then echo "external"; fi}
SUBDIRS += ${shell if [ -r external/Makefile ]; then echo "external"; fi}
# The final build target
BIN = libapps$(LIBEXT)
# Build targets
all: $(BIN)
.PHONY: $(INSTALLED_APPS) context depend clean distclean
$(INSTALLED_APPS):
@$(MAKE) -C $@ TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)";
$(BIN): $(INSTALLED_APPS)
@( for obj in $(OBJS) ; do \
$(call ARCHIVE, $@, $${obj}); \
done ; )
.context:
@for dir in $(INSTALLED_APPS) ; do \
rm -f $$dir/.context ; \
$(MAKE) -C $$dir TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" context ; \
done
@touch $@
context: .context
.depend: context Makefile $(SRCS)
@for dir in $(INSTALLED_APPS) ; do \
rm -f $$dir/.depend ; \
$(MAKE) -C $$dir TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" depend ; \
done
@touch $@
depend: .depend
clean:
@for dir in $(SUBDIRS) ; do \
$(MAKE) -C $$dir clean TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)"; \
done
@rm -f $(BIN) *~ .*.swp *.o
$(call CLEAN)
distclean: # clean
@for dir in $(SUBDIRS) ; do \
$(MAKE) -C $$dir distclean TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)"; \
done
@rm -f .config .context .depend
@( if [ -e external ]; then \
echo "********************************************************"; \
echo "* The external directory/link must be removed manually *"; \
echo "********************************************************"; \
fi; \
)
+211
View File
@@ -0,0 +1,211 @@
Application Folder
==================
Contents
--------
General
Directory Location
Named Applications
Named Startup main() function
NuttShell (NSH) Built-In Commands
Synchronous Built-In Commands
Application Configuration File
Example Named Application
Building NuttX with Board-Specific Pieces Outside the Source Tree
General
-------
This folder provides various applications found in sub-directories. These
applications are not inherently a part of NuttX but are provided you help
you develop your own applications. The apps/ directory is a "break away"
part of the configuration that you may chose to use or not.
Directory Location
------------------
The default application directory used by the NuttX build should be named
apps/ (or apps-x.y/ where x.y is the NuttX version number). This apps/
directory should appear in the directory tree at the same level as the
NuttX directory. Like:
.
|- nuttx
|
`- apps
If all of the above conditions are TRUE, then NuttX will be able to
find the application directory. If your application directory has a
different name or is location at a different position, then you will
have to inform the NuttX build system of that location. There are several
ways to do that:
1) You can define CONFIG_APPS_DIR to be the full path to your application
directory in the NuttX configuration file.
2) You can provide the path to the application directory on the command line
like: make APPDIR=<path> or make CONFIG_APPS_DIR=<path>
3) When you configure NuttX using tools/configure.sh, you can provide that
path to the application directory on the configuration command line
like: ./configure.sh -a <app-dir> <board-name>/<config-name>
Named Applications
------------------
NuttX also supports applications that can be started using a name string.
In this case, application entry points with their requirements are gathered
together in two files:
- namedapp/namedapp_proto.h Entry points, prototype function
- namedapp/namedapp_list.h Application specific information and requirements
The build occurs in several phases as different build targets are executed:
(1) context, (2) depend, and (3) default (all). Application information is
collected during the make context build phase.
To execute an application function:
exec_namedapp() is defined in the nuttx/include/apps/apps.h
NuttShell (NSH) Built-In Commands
---------------------------------
One use of named applications is to provide a way of invoking your custom
application through the NuttShell (NSH) command line. NSH will support
a seamless method invoking the applications, when the following option is
enabled in the NuttX configuration file:
CONFIG_NSH_BUILTIN_APPS=y
Applications registered in the apps/namedapp/namedapp_list.h file will then
be accessible from the NSH command line. If you type 'help' at the NSH
prompt, you will see a list of the registered commands.
Synchronous Built-In Commands
-----------------------------
By default, built-in commands started from the NSH command line will run
asynchronously with NSH. If you want to force NSH to execute commands
then wait for the command to execute, you can enable that feature by
adding the following to the NuttX configuration file:
CONFIG_SCHED_WAITPID=y
The configuration option enables support for the waitpid() RTOS interface.
When that interface is enabled, NSH will use it to wait, sleeping until
the built-in command executes to completion.
Of course, even with CONFIG_SCHED_WAITPID=y defined, specific commands
can still be forced to run asynchronously by adding the ampersand (&)
after the NSH command.
Application Configuration File
------------------------------
A special configuration file is used to configure which applications
are to be included in the build. The source for this file is
configs/<board>/<configuration>/appconfig. The existence of the appconfig
file in the board configuration directory is sufficient to enable building
of applications.
The appconfig file is copied into the apps/ directory as .config when
NuttX is configured. .config is included in the toplevel apps/Makefile.
As a minimum, this configuration file must define files to add to the
CONFIGURED_APPS list like:
CONFIGURED_APPS += examples/hello vsn/poweroff
Named Start-Up main() function
------------------------------
A named application can even be used as the main, start-up entry point
into your embedded software. When the user defines this option in
the NuttX configuration file:
CONFIG_BUILTIN_APP_START=<application name>
that application shall be invoked immediately after system starts
*instead* of the normal, default "user_start" entry point.
Note that <application name> must be provided as: "hello",
will call:
int hello_main(int argc, char *argv[])
Example Named Application
-------------------------
An example application skeleton can be found under the examples/hello
sub-directory. This example shows how a named application can be added
to the project. One must define:
1. create sub-directory as: appname
2. provide entry point: appname_main()
3. set the requirements in the file: Makefile, specially the lines:
APPNAME = appname
PRIORITY = SCHED_PRIORITY_DEFAULT
STACKSIZE = 768
ASRCS = asm source file list as a.asm b.asm ...
CSRCS = C source file list as foo1.c foo2.c ..
4. add application in the apps/.config
Building NuttX with Board-Specific Pieces Outside the Source Tree
-----------------------------------------------------------------
Q: Has anyone come up with a tidy way to build NuttX with board-
specific pieces outside the source tree?
A: Here are four:
1) There is a make target called 'make export'. It will build
NuttX, then bundle all of the header files, libaries, startup
objects, and other build components into a .zip file. You
can can move that .zip file into any build environment you
want. You even build NuttX under a DOS CMD window.
This make target is documented in the top level nuttx/README.txt.
2) You can replace the entire apps/ directory. If there is
nothing in the apps/ directory that you need, you can define
CONFIG_APPS_DIR in your .config file so that it points to a
different, custom application directory.
You can copy any pieces that you like from the old apps/directory
to your custom apps directory as necessary.
This is documented in NuttX/configs/README.txt and
nuttx/Documentation/NuttxPortingGuide.html (Online at
http://nuttx.sourceforge.net/NuttxPortingGuide.html#apndxconfigs
under Build options). And in the apps/README.txt file.
3) If you like the random collection of stuff in the apps/ directory
but just want to expand the existing components with your own,
external sub-directory then there is an easy way to that too:
You just create the sympolic link at apps/external that
redirects to your application sub-directory. The apps/Makefile
will always automatically check for the existence of an
apps/external directory and if it exists, it will automatically
incorporate it into the build.
This feature of the apps/Makefile is documented only here.
You can, for example, create a script called install.sh that
installs a custom application, configuration, and board specific
directory:
a) Copy 'MyBoard' directory to configs/MyBoard.
b) Add a symbolic link to MyApplication at apps/external
c) Configure NuttX (usually by:
tools/configure.sh MyBoard/MyConfiguration
or simply by copying defconfig->nutt/.config,
setenv.sh->nuttx/setenv.sh, Make.defs->nuttx/Make.defs,
appconfig->apps/.config
Using the 'external' link makes it especially easy to add a
'built-in' application an existing configuration.
4) Add any link to apps/
a) Add symbolic links apps/ to as many other directories as you
want.
b) Then just add the (relative) paths to the links in your
appconfig file (that becomes the apps/.config file).
That is basically the same as my option #3 but doesn't use the
magic 'external' link. The toplevel apps/Makefile will always
to build whatever in finds in the apps/.config file (plus the
external link if present).
View File
View File
+45
View File
@@ -0,0 +1,45 @@
############################################################################
#
# Copyright (C) 2012 PX4 Development Team. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# 3. Neither the name PX4 nor the names of its contributors may be
# used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
############################################################################
#
# Makefile to build uORB
#
APPNAME = ardrone_control
PRIORITY = SCHED_PRIORITY_MAX - 15
STACKSIZE = 2048
# explicit list of sources - not everything is built currently
CSRCS = ardrone_control.c ardrone_motor_control.c ardrone_control_helper.c rate_control.c attitude_control.c pid.c
include $(APPDIR)/mk/app.mk
+272
View File
@@ -0,0 +1,272 @@
/****************************************************************************
*
* Copyright (C) 2008-2012 PX4 Development Team. All rights reserved.
* Author: Lorenz Meier <lm@inf.ethz.ch>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name PX4 nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/*
* @file Implementation of AR.Drone 1.0 / 2.0 control interface
*/
#include <nuttx/config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <debug.h>
#include <termios.h>
#include <time.h>
#include <sys/prctl.h>
#include <arch/board/up_hrt.h>
#include "ardrone_control.h"
#include "attitude_control.h"
#include "rate_control.h"
#include "ardrone_motor_control.h"
#include "position_control.h"
#include <uORB/uORB.h>
#include <uORB/topics/vehicle_status.h>
#include <uORB/topics/vehicle_attitude.h>
#include <uORB/topics/ardrone_control.h>
#include <uORB/topics/rc_channels.h>
#include <uORB/topics/ardrone_motors_setpoint.h>
#include <uORB/topics/sensor_combined.h>
#include "ardrone_control_helper.h"
__EXPORT int ardrone_control_main(int argc, char *argv[]);
/****************************************************************************
* Internal Definitions
****************************************************************************/
enum {
CONTROL_MODE_RATES = 0,
CONTROL_MODE_ATTITUDE = 1,
} control_mode;
/****************************************************************************
* Private Data
****************************************************************************/
/*File descriptors */
int ardrone_write;
int gpios;
bool position_control_thread_started;
/****************************************************************************
* pthread loops
****************************************************************************/
static void *position_control_loop(void *arg)
{
struct vehicle_status_s *state = (struct vehicle_status_s *)arg;
// Set thread name
prctl(PR_SET_NAME, "ardrone pos ctrl", getpid());
while (1) {
if (state->state_machine == SYSTEM_STATE_AUTO) {
// control_position(); //FIXME TODO XXX
/* temporary 50 Hz execution */
usleep(20000);
} else {
position_control_thread_started = false;
break;
}
}
return NULL;
}
/****************************************************************************
* main
****************************************************************************/
int ardrone_control_main(int argc, char *argv[])
{
/* welcome user */
printf("[ardrone_control] Control started, taking over motors\n");
/* default values for arguments */
char *ardrone_uart_name = "/dev/ttyS1";
control_mode = CONTROL_MODE_RATES;
char *commandline_usage = "\tusage: ardrone_control -d ardrone-devicename -m mode\n\tmodes are:\n\t\trates\n\t\tattitude\n";
/* read commandline arguments */
int i;
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "-d") == 0 || strcmp(argv[i], "--device") == 0) { //ardrone set
if (argc > i + 1) {
ardrone_uart_name = argv[i + 1];
} else {
printf(commandline_usage);
return 0;
}
} else if (strcmp(argv[i], "-m") == 0 || strcmp(argv[i], "--mode") == 0) {
if (argc > i + 1) {
if (strcmp(argv[i + 1], "rates") == 0) {
control_mode = CONTROL_MODE_RATES;
} else if (strcmp(argv[i + 1], "attitude") == 0) {
control_mode = CONTROL_MODE_ATTITUDE;
} else {
printf(commandline_usage);
return 0;
}
} else {
printf(commandline_usage);
return 0;
}
}
}
/* open uarts */
printf("[ardrone_control] AR.Drone UART is %s\n", ardrone_uart_name);
ardrone_write = open(ardrone_uart_name, O_RDWR | O_NOCTTY | O_NDELAY);
/* initialize motors */
ar_init_motors(ardrone_write, &gpios);
int counter = 0;
/* pthread for position control */
pthread_t position_control_thread;
position_control_thread_started = false;
/* structures */
struct vehicle_status_s state;
struct vehicle_attitude_s att;
struct ardrone_control_s ar_control;
struct rc_channels_s rc;
struct sensor_combined_s raw;
struct ardrone_motors_setpoint_s setpoint;
/* subscribe to attitude, motor setpoints and system state */
int att_sub = orb_subscribe(ORB_ID(vehicle_attitude));
int state_sub = orb_subscribe(ORB_ID(vehicle_status));
int rc_sub = orb_subscribe(ORB_ID(rc_channels));
int sensor_sub = orb_subscribe(ORB_ID(sensor_combined));
int setpoint_sub = orb_subscribe(ORB_ID(ardrone_motors_setpoint));
/* publish AR.Drone motor control state */
int ardrone_pub = orb_advertise(ORB_ID(ardrone_control), &ar_control);
while (1) {
/* get a local copy of the vehicle state */
orb_copy(ORB_ID(vehicle_status), state_sub, &state);
/* get a local copy of rc */
orb_copy(ORB_ID(rc_channels), rc_sub, &rc);
/* get a local copy of attitude */
orb_copy(ORB_ID(vehicle_attitude), att_sub, &att);
if (state.state_machine == SYSTEM_STATE_AUTO) {
if (false == position_control_thread_started) {
pthread_attr_t position_control_thread_attr;
pthread_attr_init(&position_control_thread_attr);
pthread_attr_setstacksize(&position_control_thread_attr, 2048);
pthread_create(&position_control_thread, &position_control_thread_attr, position_control_loop, &state);
position_control_thread_started = true;
}
control_attitude(&rc, &att, &state, ardrone_pub, &ar_control);
//No check for remote sticks to disarm in auto mode, land/disarm with ground station
} else if (state.state_machine == SYSTEM_STATE_MANUAL) {
if (control_mode == CONTROL_MODE_RATES) {
orb_copy(ORB_ID(sensor_combined), sensor_sub, &raw);
orb_copy(ORB_ID(ardrone_motors_setpoint), setpoint_sub, &setpoint);
control_rates(&raw, &setpoint);
} else if (control_mode == CONTROL_MODE_ATTITUDE) {
control_attitude(&rc, &att, &state, ardrone_pub, &ar_control);
}
} else {
}
//fancy led animation...
static int blubb = 0;
if (counter % 20 == 0) {
if (blubb == 0) ar_set_leds(ardrone_write, 0, 1, 0, 0, 0, 0, 0 , 0);
if (blubb == 1) ar_set_leds(ardrone_write, 1, 1, 0, 0, 0, 0, 0 , 0);
if (blubb == 2) ar_set_leds(ardrone_write, 1, 0, 0, 0, 0, 0, 0 , 0);
if (blubb == 3) ar_set_leds(ardrone_write, 0, 0, 0, 1, 0, 0, 0 , 0);
if (blubb == 4) ar_set_leds(ardrone_write, 0, 0, 1, 1, 0, 0, 0 , 0);
if (blubb == 5) ar_set_leds(ardrone_write, 0, 0, 1, 0, 0, 0, 0 , 0);
if (blubb == 6) ar_set_leds(ardrone_write, 0, 0, 0, 0, 0, 1, 0 , 0);
if (blubb == 7) ar_set_leds(ardrone_write, 0, 0, 0, 0, 1, 1, 0 , 0);
if (blubb == 8) ar_set_leds(ardrone_write, 0, 0, 0, 0, 1, 0, 0 , 0);
if (blubb == 9) ar_set_leds(ardrone_write, 0, 0, 0, 0, 0, 0, 0 , 1);
if (blubb == 10) ar_set_leds(ardrone_write, 0, 0, 0, 0, 0, 0, 1 , 1);
if (blubb == 11) ar_set_leds(ardrone_write, 0, 0, 0, 0, 0, 0, 1 , 0);
blubb++;
if (blubb == 12) blubb = 0;
}
/* run at approximately 200 Hz */
usleep(5000);
counter++;
}
/* close uarts */
close(ardrone_write);
ar_multiplexing_deinit(gpios);
printf("[ardrone_control] ending now...\r\n");
fflush(stdout);
return 0;
}
+12
View File
@@ -0,0 +1,12 @@
/*
* ardrone_control.h
*
* Created on: Mar 23, 2012
* Author: thomasgubler
*/
#ifndef ARDRONE_CONTROL_H_
#define ARDRONE_CONTROL_H_
#endif /* ARDRONE_CONTROL_H_ */
@@ -0,0 +1,60 @@
#include "ardrone_control_helper.h"
#include <unistd.h>
#include <nuttx/config.h>
#include <stdio.h>
#include <stdlib.h>
// int read_sensors_raw(sensors_raw_t *sensors_raw)
// {
// static int ret;
// ret = global_data_wait(&global_data_sensors_raw->access_conf_rate_full);
// if (ret == 0) {
// memcpy(sensors_raw->gyro_raw, global_data_sensors_raw->gyro_raw, sizeof(sensors_raw->gyro_raw));
// // printf("Timestamp %d\n", &global_data_sensors_raw->timestamp);
// } else {
// printf("Controller timeout, no new sensor values available\n");
// }
// global_data_unlock(&global_data_sensors_raw->access_conf_rate_full);
// return ret;
// }
// int read_attitude(global_data_attitude_t *attitude)
// {
// static int ret;
// ret = global_data_wait(&global_data_attitude->access_conf);
// if (ret == 0) {
// memcpy(&attitude->roll, &global_data_attitude->roll, sizeof(global_data_attitude->roll));
// memcpy(&attitude->pitch, &global_data_attitude->pitch, sizeof(global_data_attitude->pitch));
// memcpy(&attitude->yaw, &global_data_attitude->yaw, sizeof(global_data_attitude->yaw));
// memcpy(&attitude->rollspeed, &global_data_attitude->rollspeed, sizeof(global_data_attitude->rollspeed));
// memcpy(&attitude->pitchspeed, &global_data_attitude->pitchspeed, sizeof(global_data_attitude->pitchspeed));
// memcpy(&attitude->yawspeed, &global_data_attitude->yawspeed, sizeof(global_data_attitude->yawspeed));
// } else {
// printf("Controller timeout, no new attitude values available\n");
// }
// global_data_unlock(&global_data_attitude->access_conf);
// return ret;
// }
// void read_quad_motors_setpoint(quad_motors_setpoint_t *rate_setpoint)
// {
// if (0 == global_data_trylock(&global_data_quad_motors_setpoint->access_conf)) { //TODO: check if trylock is the right choice, maybe only lock?
// rate_setpoint->motor_front_nw = global_data_quad_motors_setpoint->motor_front_nw;
// rate_setpoint->motor_right_ne = global_data_quad_motors_setpoint->motor_right_ne;
// rate_setpoint->motor_back_se = global_data_quad_motors_setpoint->motor_back_se;
// rate_setpoint->motor_left_sw = global_data_quad_motors_setpoint->motor_left_sw;
// global_data_unlock(&global_data_quad_motors_setpoint->access_conf);
// }
// }
@@ -0,0 +1,21 @@
/*
* ardrone_control_helper.h
*
* Created on: May 15, 2012
* Author: thomasgubler
*/
#ifndef ARDRONE_CONTROL_HELPER_H_
#define ARDRONE_CONTROL_HELPER_H_
#include <stdint.h>
// typedef struct {
// int16_t gyro_raw[3]; // l3gd20
// } sensors_raw_t;
// /* Copy quad_motors_setpoint values from global memory to private variables */ //TODO: change this once the new mavlink message for rates is available
// void read_quad_motors_setpoint(quad_motors_setpoint_t *rate_setpoint);
#endif /* ARDRONE_CONTROL_HELPER_H_ */
@@ -0,0 +1,277 @@
/****************************************************************************
*
* Copyright (C) 2008-2012 PX4 Development Team. All rights reserved.
* Author: Lorenz Meier <lm@inf.ethz.ch>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name PX4 nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/*
* @file Implementation of AR.Drone 1.0 / 2.0 motor control interface
*/
#include "ardrone_motor_control.h"
static const unsigned long motor_gpios = GPIO_EXT_1 | GPIO_EXT_2 | GPIO_MULTI_1 | GPIO_MULTI_2;
static const unsigned long motor_gpio[4] = { GPIO_EXT_1, GPIO_EXT_2, GPIO_MULTI_1, GPIO_MULTI_2 };
typedef union {
uint16_t motor_value;
uint8_t bytes[2];
} motor_union_t;
/**
* @brief Generate the 8-byte motor set packet
*
* @return the number of bytes (8)
*/
void ar_get_motor_packet(uint8_t *motor_buf, uint16_t motor1, uint16_t motor2, uint16_t motor3, uint16_t motor4)
{
motor_buf[0] = 0x20;
motor_buf[1] = 0x00;
motor_buf[2] = 0x00;
motor_buf[3] = 0x00;
motor_buf[4] = 0x00;
/*
* {0x20, 0x00, 0x00, 0x00, 0x00};
* 0x20 is start sign / motor command
*/
motor_union_t curr_motor;
uint16_t nineBitMask = 0x1FF;
/* Set motor 1 */
curr_motor.motor_value = (motor1 & nineBitMask) << 4;
motor_buf[0] |= curr_motor.bytes[1];
motor_buf[1] |= curr_motor.bytes[0];
/* Set motor 2 */
curr_motor.motor_value = (motor2 & nineBitMask) << 3;
motor_buf[1] |= curr_motor.bytes[1];
motor_buf[2] |= curr_motor.bytes[0];
/* Set motor 3 */
curr_motor.motor_value = (motor3 & nineBitMask) << 2;
motor_buf[2] |= curr_motor.bytes[1];
motor_buf[3] |= curr_motor.bytes[0];
/* Set motor 4 */
curr_motor.motor_value = (motor4 & nineBitMask) << 1;
motor_buf[3] |= curr_motor.bytes[1];
motor_buf[4] |= curr_motor.bytes[0];
}
void ar_enable_broadcast(int fd)
{
ar_select_motor(fd, 0);
}
int ar_multiplexing_init()
{
int fd;
fd = open("/dev/gpio", O_RDONLY | O_NONBLOCK);
if (fd < 0) {
printf("GPIO: open fail\n");
return fd;
}
if (ioctl(fd, GPIO_SET_OUTPUT, motor_gpios) != 0) {
printf("GPIO: output set fail\n");
close(fd);
return -1;
}
/* deactivate all outputs */
int ret = 0;
ret += ioctl(fd, GPIO_SET, motor_gpios);
if (ret < 0) {
printf("GPIO: clearing pins fail\n");
close(fd);
return -1;
}
return fd;
}
int ar_multiplexing_deinit(int fd)
{
if (fd < 0) {
printf("GPIO: no valid descriptor\n");
return fd;
}
int ret = 0;
/* deselect motor 1-4 */
ret += ioctl(fd, GPIO_SET, motor_gpios);
if (ret != 0) {
printf("GPIO: clear failed %d times\n", ret);
}
if (ioctl(fd, GPIO_SET_INPUT, motor_gpios) != 0) {
printf("GPIO: input set fail\n");
return -1;
}
close(fd);
return ret;
}
int ar_select_motor(int fd, uint8_t motor)
{
int ret = 0;
unsigned long gpioset;
/*
* Four GPIOS:
* GPIO_EXT1
* GPIO_EXT2
* GPIO_UART2_CTS
* GPIO_UART2_RTS
*/
/* select motor 0 to enable broadcast */
if (motor == 0) {
/* select motor 1-4 */
ret += ioctl(fd, GPIO_CLEAR, motor_gpios);
} else {
/* select reqested motor */
ret += ioctl(fd, GPIO_CLEAR, motor_gpio[motor - 1]);
/* deselect all others */
gpioset = motor_gpios ^ motor_gpio[motor - 1];
ret += ioctl(fd, GPIO_SET, gpioset);
}
return ret;
}
void ar_init_motors(int ardrone_uart, int *gpios_pin)
{
/* Initialize multiplexing */
*gpios_pin = ar_multiplexing_init();
/* Write ARDrone commands on UART2 */
uint8_t initbuf[] = {0xE0, 0x91, 0xA1, 0x00, 0x40};
uint8_t multicastbuf[] = {0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0};
/* initialize all motors
* - select one motor at a time
* - configure motor
*/
int i;
int errcounter = 0;
for (i = 1; i < 5; ++i) {
/* Initialize motors 1-4 */
initbuf[3] = i;
errcounter += ar_select_motor(*gpios_pin, i);
write(ardrone_uart, initbuf + 0, 1);
/* sleep 400 ms */
usleep(200000);
usleep(200000);
write(ardrone_uart, initbuf + 1, 1);
/* wait 50 ms */
usleep(50000);
write(ardrone_uart, initbuf + 2, 1);
/* wait 50 ms */
usleep(50000);
write(ardrone_uart, initbuf + 3, 1);
/* wait 50 ms */
usleep(50000);
write(ardrone_uart, initbuf + 4, 1);
/* wait 50 ms */
usleep(50000);
/* enable multicast */
write(ardrone_uart, multicastbuf + 0, 1);
/* wait 1 ms */
usleep(1000);
write(ardrone_uart, multicastbuf + 1, 1);
/* wait 1 ms */
usleep(1000);
write(ardrone_uart, multicastbuf + 2, 1);
/* wait 1 ms */
usleep(1000);
write(ardrone_uart, multicastbuf + 3, 1);
/* wait 1 ms */
usleep(1000);
write(ardrone_uart, multicastbuf + 4, 1);
/* wait 1 ms */
usleep(1000);
write(ardrone_uart, multicastbuf + 5, 1);
/* wait 5 ms */
usleep(50000);
}
/* start the multicast part */
errcounter += ar_select_motor(*gpios_pin, 0);
if (errcounter != 0) {
printf("AR: init sequence incomplete, failed %d times", -errcounter);
fflush(stdout);
}
}
/*
* Sets the leds on the motor controllers, 1 turns led on, 0 off.
*/
void ar_set_leds(int ardrone_uart, uint8_t led1_red, uint8_t led1_green, uint8_t led2_red, uint8_t led2_green, uint8_t led3_red, uint8_t led3_green, uint8_t led4_red, uint8_t led4_green)
{
/*
* 2 bytes are sent. The first 3 bits describe the command: 011 means led control
* the following 4 bits are the red leds for motor 4, 3, 2, 1
* then 4 bits with unknown function, then 4 bits for green leds for motor 4, 3, 2, 1
* the last bit is unknown.
*
* The packet is therefore:
* 011 rrrr 0000 gggg 0
*/
uint8_t leds[2];
leds[0] = 0x60 | ((led4_red & 0x01) << 4) | ((led3_red & 0x01) << 3) | ((led2_red & 0x01) << 2) | ((led1_red & 0x01) << 1);
leds[1] = ((led4_green & 0x01) << 4) | ((led3_green & 0x01) << 3) | ((led2_green & 0x01) << 2) | ((led1_green & 0x01) << 1);
write(ardrone_uart, leds, 2);
}

Some files were not shown because too many files have changed in this diff Show More