Merged in paulpatience/nuttx-apps (pull request #11)

UAVCAN: Add platform-specific code
diff --git a/Application.mk b/Application.mk
index ef0a3d6..cd9d247 100644
--- a/Application.mk
+++ b/Application.mk
@@ -35,8 +35,6 @@
 #
 ############################################################################
 
--include $(TOPDIR)/.config
--include $(TOPDIR)/Make.defs
 include $(APPDIR)/Make.defs
 
 CXXEXT ?= .cxx
@@ -44,9 +42,14 @@
 AOBJS = $(ASRCS:.S=$(OBJEXT))
 COBJS = $(CSRCS:.c=$(OBJEXT))
 CXXOBJS = $(CXXSRCS:$(CXXEXT)=$(OBJEXT))
-MAINOBJ = $(MAINSRC:.c=$(OBJEXT))
 
-SRCS = $(ASRCS) $(CSRCS) $(MAINSRC)
+ifeq ($(suffix $(MAINSRC)),$(CXXEXT))
+  MAINOBJ = $(MAINSRC:$(CXXEXT)=$(OBJEXT))
+else
+  MAINOBJ = $(MAINSRC:.c=$(OBJEXT))
+endif
+
+SRCS = $(ASRCS) $(CSRCS) $(CXXSRCS) $(MAINSRC)
 OBJS = $(AOBJS) $(COBJS) $(CXXOBJS)
 
 ifneq ($(CONFIG_BUILD_KERNEL),y)
@@ -71,12 +74,20 @@
 $(AOBJS): %$(OBJEXT): %.S
 	$(call ASSEMBLE, $<, $@)
 
-$(COBJS) $(MAINOBJ): %$(OBJEXT): %.c
+$(COBJS): %$(OBJEXT): %.c
 	$(call COMPILE, $<, $@)
 
 $(CXXOBJS): %$(OBJEXT): %$(CXXEXT)
 	$(call COMPILEXX, $<, $@)
 
+ifeq ($(suffix $(MAINSRC)),$(CXXEXT))
+$(MAINOBJ): %$(OBJEXT): %$(CXXEXT)
+	$(call COMPILEXX, $<, $@)
+else
+$(MAINOBJ): %$(OBJEXT): %.c
+	$(call COMPILE, $<, $@)
+endif
+
 .built: $(OBJS)
 	$(call ARCHIVE, $(BIN), $(OBJS))
 	$(Q) touch .built
@@ -113,9 +124,12 @@
 context:
 endif
 
-.depend: Makefile $(SRCS) $(CXXSRCS)
+.depend: Makefile $(SRCS)
+ifeq ($(filter %$(CXXEXT),$(SRCS)),)
 	$(Q) $(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep
-	$(Q) $(MKDEP) $(ROOTDEPPATH) "$(CXX)" -- $(CXXFLAGS) -- $(CXXSRCS) >Make.dep
+else
+	$(Q) $(MKDEP) $(ROOTDEPPATH) "$(CXX)" -- $(CXXFLAGS) -- $(SRCS) >Make.dep
+endif
 	$(Q) touch $@
 
 depend: .depend
diff --git a/canutils/uavcan/Kconfig b/canutils/uavcan/Kconfig
index 4a66485..8b9c4cc 100644
--- a/canutils/uavcan/Kconfig
+++ b/canutils/uavcan/Kconfig
@@ -147,7 +147,30 @@
 	int "Memory Pool Block Size"
 	default 0
 	---help---
-		Specifies the memory pool block size.  A value of 0 will
-		use the library default.
+		Specifies the memory pool block size.  If the value is 0, the
+		library will use a default value.
+
+config UAVCAN_RX_QUEUE_CAPACITY
+	int "Rx Queue Capacity"
+	default 0
+	---help---
+		Specifies the rx queue capacity.  If the value is 0, the
+		library will use a default value.
+
+config UAVCAN_BIT_RATE
+	int "Bit Rate"
+	default 0
+	range 0 1000000
+	---help---
+		Specifies the CAN bit rate.  If the value is 0, the library
+		will automatically detect the bit rate.
+
+config UAVCAN_INIT_RETRIES
+	int "Initialization Retries"
+	default 0
+	---help---
+		Specifies the number of times to try initializing the CAN
+		peripherals before panicking.  A value of 0 means to try
+		forever.
 
 endif
diff --git a/canutils/uavcan/Makefile b/canutils/uavcan/Makefile
index 7cd4303..590cef4 100644
--- a/canutils/uavcan/Makefile
+++ b/canutils/uavcan/Makefile
@@ -61,7 +61,7 @@
 -include libuavcan/libuavcan/include.mk
 -include libuavcan/libuavcan_drivers/stm32/driver/include.mk
 
-CXXSRCS = $(LIBUAVCAN_SRC) $(LIBUAVCAN_STM32_SRC)
+CXXSRCS = platform_stm32.cpp $(LIBUAVCAN_SRC) $(LIBUAVCAN_STM32_SRC)
 
 CXXFLAGS += -I$(LIBUAVCAN_INC) -I$(LIBUAVCAN_STM32_INC) -Idsdlc_generated
 CXXFLAGS += -I$(TOPDIR)/arch/arm/src/common -I$(TOPDIR)/arch/arm/src/stm32
diff --git a/canutils/uavcan/platform_stm32.cpp b/canutils/uavcan/platform_stm32.cpp
new file mode 100644
index 0000000..27cd721
--- /dev/null
+++ b/canutils/uavcan/platform_stm32.cpp
@@ -0,0 +1,106 @@
+/****************************************************************************
+ * canutils/uavcan/uavcan_platform.cpp
+ *
+ *   Copyright (C) 2015 Omni Hoverboards Inc. All rights reserved.
+ *   Author: Paul Alexander Patience <paul-a.patience@polymtl.ca>
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <cunistd>
+
+#include <uavcan_stm32/uavcan_stm32.hpp>
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+#if CONFIG_UAVCAN_RX_QUEUE_CAPACITY > 0
+static uavcan_stm32::CanInitHelper<CONFIG_UAVCAN_RX_QUEUE_CAPACITY> can;
+#else
+static uavcan_stm32::CanInitHelper<> can;
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static void delay_callable()
+{
+  std::usleep(can.getRecommendedListeningDelay().toUSec());
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+uavcan::ISystemClock& getSystemClock()
+{
+  return uavcan_stm32::SystemClock::instance();
+}
+
+uavcan::ICanDriver& getCanDriver()
+{
+  static bool initialized = false;
+
+  if (!initialized)
+    {
+      uavcan::uint32_t bitrate = CONFIG_UAVCAN_BIT_RATE;
+
+#if CONFIG_UAVCAN_INIT_RETRIES > 0
+      int retries = 0;
+#endif
+
+      for (;;)
+        {
+          if (can.init(delay_callable, bitrate) >= 0)
+            {
+              break;
+            }
+
+#if CONFIG_UAVCAN_INIT_RETRIES > 0
+          retries++;
+          if (retries >= CONFIG_UAVCAN_INIT_RETRIES)
+            {
+              PANIC();
+            }
+#endif
+        }
+
+      initialized = true;
+    }
+
+  return can.driver;
+}
diff --git a/examples/cxxtest/Kconfig b/examples/cxxtest/Kconfig
index 55d2cf7..6c9c4c5 100644
--- a/examples/cxxtest/Kconfig
+++ b/examples/cxxtest/Kconfig
@@ -20,6 +20,6 @@
 		By default, if CONFIG_HAVE_CXX and CONFIG_HAVE_CXXINITIALIZE are
 		defined, then this example will call the NuttX function to
 		initialize static C++ constructors.  This option may be disabled,
-		however, if that static initialization was preformed elsewhere.
+		however, if that static initialization was performed elsewhere.
 
 endif
diff --git a/examples/cxxtest/Makefile b/examples/cxxtest/Makefile
index 2e75f5b..0f5638e 100644
--- a/examples/cxxtest/Makefile
+++ b/examples/cxxtest/Makefile
@@ -33,117 +33,22 @@
 #
 ############################################################################
 
--include $(TOPDIR)/.config
 -include $(TOPDIR)/Make.defs
-include $(APPDIR)/Make.defs
 
 # CXX test program
 
 ASRCS =
 CSRCS =
-CXXSRCS = 
+CXXSRCS =
 MAINSRC = cxxtest_main.cxx
 
-AOBJS = $(ASRCS:.S=$(OBJEXT))
-COBJS = $(CSRCS:.c=$(OBJEXT))
-CXXOBJS = $(CXXSRCS:.cxx=$(OBJEXT))
-MAINOBJ = $(MAINSRC:.cxx=$(OBJEXT))
-
-SRCS = $(ASRCS) $(CSRCS) $(CXXSRCS)
-OBJS = $(AOBJS) $(COBJS) $(CXXOBJS)
-
-ifneq ($(CONFIG_BUILD_KERNEL),y)
-  OBJS += $(MAINOBJ)
-endif
-
-ifeq ($(CONFIG_WINDOWS_NATIVE),y)
-  BIN = ..\..\libapps$(LIBEXT)
-else
-ifeq ($(WINTOOL),y)
-  BIN = ..\\..\\libapps$(LIBEXT)
-else
-  BIN = ../../libapps$(LIBEXT)
-endif
-endif
-
 CONFIG_XYZ_PROGNAME ?= cxxtest$(EXEEXT)
 PROGNAME = $(CONFIG_XYZ_PROGNAME)
 
-ROOTDEPPATH = --dep-path .
-
-ROOTDEPPATH = --dep-path .
-
 # cxxtest built-in application info
 
 APPNAME = cxxtest
 PRIORITY = SCHED_PRIORITY_DEFAULT
 STACKSIZE = 4096
 
-# Common build
-
-VPATH =
-
-all: .built
-.PHONY: clean depend distclean chkcxx
-
-chkcxx:
-ifneq ($(CONFIG_HAVE_CXX),y)
-	@echo ""
-	@echo "In order to use this example, you toolchain must support must"
-	@echo ""
-	@echo "  (1) Explicitly select CONFIG_HAVE_CXX to build in C++ support"
-	@echo "  (2) Define CXX, CXXFLAGS, and COMPILEXX in the Make.defs file"
-	@echo "      of the configuration that you are using."
-	@echo ""
-	@exit 1
-endif
-
-$(AOBJS): %$(OBJEXT): %.S
-	$(call ASSEMBLE, $<, $@)
-
-$(COBJS): %$(OBJEXT): %.c
-	$(call COMPILE, $<, $@)
-
-$(CXXOBJS) $(MAINOBJ): %$(OBJEXT): %.cxx
-	$(call COMPILEXX, $<, $@)
-
-.built: chkcxx $(OBJS)
-	$(call ARCHIVE, $(BIN), $(OBJS))
-	@touch .built
-
-ifeq ($(CONFIG_BUILD_KERNEL),y)
-$(BIN_DIR)$(DELIM)$(PROGNAME): $(OBJS) $(MAINOBJ)
-	@echo "LD: $(PROGNAME)"
-	$(Q) $(LD) $(LDELFFLAGS) $(LDLIBPATH) -o $(INSTALL_DIR)$(DELIM)$(PROGNAME) $(ARCHCRT0OBJ) $(MAINOBJ) $(LDLIBS)
-	$(Q) $(NM) -u  $(INSTALL_DIR)$(DELIM)$(PROGNAME)
-
-install: $(BIN_DIR)$(DELIM)$(PROGNAME)
-
-else
-install:
-
-endif
-ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
-$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat: $(DEPCONFIG) Makefile
-	$(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
-
-context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat
-else
-context:
-endif
-
-.depend: Makefile $(SRCS)
-	@$(MKDEP) $(ROOTDEPPATH) "$(CXX)" -- $(CXXFLAGS) -- $(SRCS) >Make.dep
-	@touch $@
-
-depend: .depend
-
-clean:
-	$(call DELFILE, .built)
-	$(call CLEAN)
-
-distclean: clean
-	$(call DELFILE, Make.dep)
-	$(call DELFILE, .depend)
-
--include Make.dep
+include $(APPDIR)/Application.mk
diff --git a/examples/helloxx/Kconfig b/examples/helloxx/Kconfig
index f585578..1a8bcd7 100644
--- a/examples/helloxx/Kconfig
+++ b/examples/helloxx/Kconfig
@@ -6,6 +6,7 @@
 config EXAMPLES_HELLOXX
 	bool "\"Hello, World!\" C++ example"
 	default n
+	depends on HAVE_CXX
 	---help---
 		Enable the \"Hello, World!\" C++ example
 
@@ -19,6 +20,6 @@
 		By default, if CONFIG_HAVE_CXX and CONFIG_HAVE_CXXINITIALIZE are
 		defined, then this example will call the NuttX function to
 		initialize static C++ constructors.  This option may be disabled,
-		however, if that static initialization was preformed elsewhere.
+		however, if that static initialization was performed elsewhere.
 
 endif
diff --git a/examples/helloxx/Makefile b/examples/helloxx/Makefile
index 285dd1d..64b9b32 100644
--- a/examples/helloxx/Makefile
+++ b/examples/helloxx/Makefile
@@ -33,116 +33,22 @@
 #
 ############################################################################
 
--include $(TOPDIR)/.config
 -include $(TOPDIR)/Make.defs
-include $(APPDIR)/Make.defs
 
 # Hello, World! C++ Example
 
-ASRCS		=
-CSRCS		=
-CXXSRCS		=
-MAINSRC		= helloxx_main.cxx
-
-AOBJS		= $(ASRCS:.S=$(OBJEXT))
-COBJS		= $(CSRCS:.c=$(OBJEXT))
-CXXOBJS		= $(CXXSRCS:.cxx=$(OBJEXT))
-MAINOBJ		= $(MAINSRC:.cxx=$(OBJEXT))
-
-SRCS		= $(ASRCS) $(CSRCS) $(CXXSRCS) $(MAINSRC)
-OBJS		= $(AOBJS) $(COBJS) $(CXXOBJS)
-
-ifneq ($(CONFIG_BUILD_KERNEL),y)
-  OBJS		+= $(MAINOBJ)
-endif
-
-ifeq ($(CONFIG_WINDOWS_NATIVE),y)
-  BIN		= ..\..\libapps$(LIBEXT)
-else
-ifeq ($(WINTOOL),y)
-  BIN		= ..\\..\\libapps$(LIBEXT)
-else
-  BIN		= ../../libapps$(LIBEXT)
-endif
-endif
+ASRCS =
+CSRCS =
+CXXSRCS =
+MAINSRC = helloxx_main.cxx
 
 CONFIG_EXAMPLES_HELLOXX_PROGNAME ?= helloxx$(EXEEXT)
-PROGNAME	= $(CONFIG_EXAMPLES_HELLOXX_PROGNAME)
-
-ROOTDEPPATH	= --dep-path .
+PROGNAME = $(CONFIG_EXAMPLES_HELLOXX_PROGNAME)
 
 # helloxx built-in application info
 
-APPNAME		= helloxx
-PRIORITY	= SCHED_PRIORITY_DEFAULT
-STACKSIZE	= 2048
+APPNAME = helloxx
+PRIORITY = SCHED_PRIORITY_DEFAULT
+STACKSIZE = 2048
 
-# Common build
-
-VPATH		=
-
-all: .built
-.PHONY:	clean depend distclean chkcxx
-
-chkcxx:
-ifneq ($(CONFIG_HAVE_CXX),y)
-	@echo ""
-	@echo "In order to use this example, you toolchain must support must"
-	@echo ""
-	@echo "  (1) Explicitly select CONFIG_HAVE_CXX to build in C++ support"
-	@echo "  (2) Define CXX, CXXFLAGS, and COMPILEXX in the Make.defs file"
-	@echo "      of the configuration that you are using."
-	@echo ""
-	@exit 1
-endif
-
-$(AOBJS): %$(OBJEXT): %.S
-	$(call ASSEMBLE, $<, $@)
-
-$(COBJS): %$(OBJEXT): %.c
-	$(call COMPILE, $<, $@)
-
-$(CXXOBJS) $(MAINOBJ): %$(OBJEXT): %.cxx
-	$(call COMPILEXX, $<, $@)
-
-.built: chkcxx $(OBJS)
-	$(call ARCHIVE, $(BIN), $(OBJS))
-	@touch .built
-
-ifeq ($(CONFIG_BUILD_KERNEL),y)
-$(BIN_DIR)$(DELIM)$(PROGNAME): $(OBJS) $(MAINOBJ)
-	@echo "LD: $(PROGNAME)"
-	$(Q) $(LD) $(LDELFFLAGS) $(LDLIBPATH) -o $(INSTALL_DIR)$(DELIM)$(PROGNAME) $(ARCHCRT0OBJ) $(MAINOBJ) $(LDLIBS)
-	$(Q) $(NM) -u  $(INSTALL_DIR)$(DELIM)$(PROGNAME)
-
-install: $(BIN_DIR)$(DELIM)$(PROGNAME)
-
-else
-install:
-
-endif
-
-ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
-$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat: $(DEPCONFIG) Makefile
-	$(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
-
-context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat
-else
-context:
-endif
-
-.depend: Makefile $(SRCS)
-	@$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep
-	@touch $@
-
-depend: .depend
-
-clean:
-	$(call DELFILE, .built)
-	$(call CLEAN)
-
-distclean: clean
-	$(call DELFILE, Make.dep)
-	$(call DELFILE, .depend)
-
--include Make.dep
+include $(APPDIR)/Application.mk