diff --git a/Makefile b/Makefile index 63bb6cec92..4a0f13cd19 100644 --- a/Makefile +++ b/Makefile @@ -97,8 +97,132 @@ upload: endif endif +ifeq ($(PX4_TARGET_OS),nuttx) +# +# Built products +# +DESIRED_FIRMWARES = $(foreach config,$(CONFIGS),$(IMAGE_DIR)$(config).px4) +STAGED_FIRMWARES = $(foreach config,$(KNOWN_CONFIGS),$(IMAGE_DIR)$(config).px4) +FIRMWARES = $(foreach config,$(KNOWN_CONFIGS),$(BUILD_DIR)$(config).build/firmware.px4) + +all: $(DESIRED_FIRMWARES) + +# +# Copy FIRMWARES into the image directory. +# +# XXX copying the .bin files is a hack to work around the PX4IO uploader +# not supporting .px4 files, and it should be deprecated onced that +# is taken care of. +# +$(STAGED_FIRMWARES): $(IMAGE_DIR)%.px4: $(BUILD_DIR)%.build/firmware.px4 + @$(ECHO) %% Copying $@ + $(Q) $(COPY) $< $@ + $(Q) $(COPY) $(patsubst %.px4,%.bin,$<) $(patsubst %.px4,%.bin,$@) + +# +# Generate FIRMWARES. +# +.PHONY: $(FIRMWARES) +$(BUILD_DIR)%.build/firmware.px4: config = $(patsubst $(BUILD_DIR)%.build/firmware.px4,%,$@) +$(BUILD_DIR)%.build/firmware.px4: work_dir = $(BUILD_DIR)$(config).build/ +$(FIRMWARES): $(BUILD_DIR)%.build/firmware.px4: generateuorbtopicheaders checksubmodules + @$(ECHO) %%%% + @$(ECHO) %%%% Building $(config) in $(work_dir) + @$(ECHO) %%%% + $(Q) $(MKDIR) -p $(work_dir) + $(Q) $(MAKE) -r -C $(work_dir) \ + -f $(PX4_MK_DIR)firmware.mk \ + CONFIG=$(config) \ + WORK_DIR=$(work_dir) \ + $(FIRMWARE_GOAL) + +# +# Make FMU firmwares depend on the corresponding IO firmware. +# +# This is a pretty vile hack, since it hard-codes knowledge of the FMU->IO dependency +# and forces the _default config in all cases. There has to be a better way to do this... +# +FMU_VERSION = $(patsubst px4fmu-%,%,$(word 1, $(subst _, ,$(1)))) +define FMU_DEP +$(BUILD_DIR)$(1).build/firmware.px4: $(IMAGE_DIR)px4io-$(call FMU_VERSION,$(1))_default.px4 +endef +FMU_CONFIGS := $(filter px4fmu%,$(CONFIGS)) +$(foreach config,$(FMU_CONFIGS),$(eval $(call FMU_DEP,$(config)))) + +# +# Build the NuttX export archives. +# +# Note that there are no explicit dependencies extended from these +# archives. If NuttX is updated, the user is expected to rebuild the +# archives/build area manually. Likewise, when the 'archives' target is +# invoked, all archives are always rebuilt. +# +# XXX Should support fetching/unpacking from a separate directory to permit +# downloads of the prebuilt archives as well... +# +NUTTX_ARCHIVES = $(foreach board,$(BOARDS),$(ARCHIVE_DIR)$(board).export) +.PHONY: archives +archives: checksubmodules $(NUTTX_ARCHIVES) + +# We cannot build these parallel; note that we also force -j1 for the +# sub-make invocations. +ifneq ($(filter archives,$(MAKECMDGOALS)),) +.NOTPARALLEL: +endif + +J?=1 + +$(ARCHIVE_DIR)%.export: board = $(notdir $(basename $@)) +$(ARCHIVE_DIR)%.export: configuration = nsh +$(NUTTX_ARCHIVES): $(ARCHIVE_DIR)%.export: $(NUTTX_SRC) + @$(ECHO) %% Configuring NuttX for $(board) + $(Q) (cd $(NUTTX_SRC) && $(RMDIR) nuttx-export) + $(Q) $(MAKE) -r -j$(J) -C $(NUTTX_SRC) -r $(MQUIET) distclean + $(Q) (cd $(NUTTX_SRC)/configs && $(COPYDIR) $(PX4_BASE)nuttx-configs/$(board) .) + $(Q) (cd $(NUTTX_SRC)tools && ./configure.sh $(board)/$(configuration)) + @$(ECHO) %% Exporting NuttX for $(board) + $(Q) $(MAKE) -r -j$(J) -C $(NUTTX_SRC) -r $(MQUIET) CONFIG_ARCH_BOARD=$(board) export + $(Q) $(MKDIR) -p $(dir $@) + $(Q) $(COPY) $(NUTTX_SRC)nuttx-export.zip $@ + $(Q) (cd $(NUTTX_SRC)/configs && $(RMDIR) $(board)) + +# +# The user can run the NuttX 'menuconfig' tool for a single board configuration with +# make BOARDS= menuconfig +# +ifeq ($(MAKECMDGOALS),menuconfig) +ifneq ($(words $(BOARDS)),1) +$(error BOARDS must specify exactly one board for the menuconfig goal) +endif +BOARD = $(BOARDS) +menuconfig: $(NUTTX_SRC) + @$(ECHO) %% Configuring NuttX for $(BOARD) + $(Q) (cd $(NUTTX_SRC) && $(RMDIR) nuttx-export) + $(Q) $(MAKE) -r -j$(J) -C $(NUTTX_SRC) -r $(MQUIET) distclean + $(Q) (cd $(NUTTX_SRC)/configs && $(COPYDIR) $(PX4_BASE)nuttx-configs/$(BOARD) .) + $(Q) (cd $(NUTTX_SRC)tools && ./configure.sh $(BOARD)/nsh) + @$(ECHO) %% Running menuconfig for $(BOARD) + $(Q) $(MAKE) -r -j$(J) -C $(NUTTX_SRC) -r $(MQUIET) menuconfig + @$(ECHO) %% Saving configuration file + $(Q)$(COPY) $(NUTTX_SRC).config $(PX4_BASE)nuttx-configs/$(BOARD)/nsh/defconfig +else +menuconfig: + @$(ECHO) "" + @$(ECHO) "The menuconfig goal must be invoked without any other goal being specified" + @$(ECHO) "" + +endif + +$(NUTTX_SRC): checksubmodules + +$(UAVCAN_DIR): + $(Q) (./Tools/check_submodules.sh) + +endif + ifeq ($(PX4_TARGET_OS),nuttx) -include $(PX4_BASE)makefiles/firmware_nuttx.mk +# TODO +# Move the above nuttx specific rules into $(PX4_BASE)makefiles/firmware_nuttx.mk endif ifeq ($(PX4_TARGET_OS),posix) include $(PX4_BASE)makefiles/firmware_posix.mk @@ -107,6 +231,16 @@ ifeq ($(PX4_TARGET_OS),qurt) include $(PX4_BASE)makefiles/firmware_qurt.mk endif + +.PHONY: checksubmodules +checksubmodules: + $(Q) ($(PX4_BASE)/Tools/check_submodules.sh) + +.PHONY: updatesubmodules +updatesubmodules: + $(Q) (git submodule init) + $(Q) (git submodule update) + MSG_DIR = $(PX4_BASE)msg UORB_TEMPLATE_DIR = $(PX4_BASE)msg/templates/uorb MULTIPLATFORM_TEMPLATE_DIR = $(PX4_BASE)msg/templates/px4/uorb @@ -117,15 +251,6 @@ TOPICHEADER_TEMP_DIR = $(BUILD_DIR)topics_temporary GENMSG_PYTHONPATH = $(PX4_BASE)Tools/genmsg/src GENCPP_PYTHONPATH = $(PX4_BASE)Tools/gencpp/src -.PHONY: checksubmodules -checksubmodules: - $(Q) ($(PX4_BASE)/Tools/check_submodules.sh) - -.PHONY: updatesubmodules -updatesubmodules: - $(Q) (git submodule init) - $(Q) (git submodule update) - .PHONY: generateuorbtopicheaders generateuorbtopicheaders: checksubmodules @$(ECHO) "Generating uORB topic headers" diff --git a/makefiles/firmware.mk b/makefiles/firmware.mk index b58f23cbc2..f5f5d8188d 100644 --- a/makefiles/firmware.mk +++ b/makefiles/firmware.mk @@ -213,7 +213,7 @@ endef MODULE_MKFILES := $(foreach module,$(MODULES),$(call MODULE_SEARCH,$(module))) MISSING_MODULES := $(subst MISSING_,,$(filter MISSING_%,$(MODULE_MKFILES))) ifneq ($(MISSING_MODULES),) -$(error Can't find module(s): $(MISSING_MODULES)) +$(error Cant find module(s): $(MISSING_MODULES)) endif # Make a list of the object files we expect to build from modules @@ -273,7 +273,7 @@ endef LIBRARY_MKFILES := $(foreach library,$(LIBRARIES),$(call LIBRARY_SEARCH,$(library))) MISSING_LIBRARIES := $(subst MISSING_,,$(filter MISSING_%,$(LIBRARY_MKFILES))) ifneq ($(MISSING_LIBRARIES),) -$(error Can't find library(s): $(MISSING_LIBRARIES)) +$(error Cant find library(s): $(MISSING_LIBRARIES)) endif # Make a list of the archive files we expect to build from libraries @@ -311,6 +311,132 @@ $(LIBRARY_CLEANS): LIBRARY_MK=$(mkfile) \ clean +ifeq ($(PX4_TARGET_OS),nuttx) +################################################################################ +# ROMFS generation +################################################################################ + +ifneq ($(ROMFS_ROOT),) +ifeq ($(wildcard $(ROMFS_ROOT)),) +$(error ROMFS_ROOT specifies a directory that does not exist) +endif + +# +# Note that there is no support for more than one root directory or constructing +# a root from several templates. That would be a nice feature. +# + +# Add dependencies on anything in the ROMFS root directory +ROMFS_FILES += $(wildcard \ + $(ROMFS_ROOT)/* \ + $(ROMFS_ROOT)/*/* \ + $(ROMFS_ROOT)/*/*/* \ + $(ROMFS_ROOT)/*/*/*/* \ + $(ROMFS_ROOT)/*/*/*/*/* \ + $(ROMFS_ROOT)/*/*/*/*/*/*) +ifeq ($(ROMFS_FILES),) +$(error ROMFS_ROOT $(ROMFS_ROOT) specifies a directory containing no files) +endif +ROMFS_DEPS += $(ROMFS_FILES) + +# Extra files that may be copied into the ROMFS /extras directory +# ROMFS_EXTRA_FILES are required, ROMFS_OPTIONAL_FILES are optional +ROMFS_EXTRA_FILES += $(wildcard $(ROMFS_OPTIONAL_FILES)) +ROMFS_DEPS += $(ROMFS_EXTRA_FILES) + +ROMFS_IMG = romfs.img +ROMFS_SCRATCH = romfs_scratch +ROMFS_CSRC = $(ROMFS_IMG:.img=.c) +ROMFS_OBJ = $(ROMFS_CSRC:.c=.o) +LIBS += $(ROMFS_OBJ) +LINK_DEPS += $(ROMFS_OBJ) + +# Remove all comments from startup and mixer files +ROMFS_PRUNER = $(PX4_BASE)/Tools/px_romfs_pruner.py + +# Turn the ROMFS image into an object file +$(ROMFS_OBJ): $(ROMFS_IMG) $(GLOBAL_DEPS) + $(call BIN_TO_OBJ,$<,$@,romfs_img) + +# Generate the ROMFS image from the root +$(ROMFS_IMG): $(ROMFS_SCRATCH) $(ROMFS_DEPS) $(GLOBAL_DEPS) + @$(ECHO) "ROMFS: $@" + $(Q) $(GENROMFS) -f $@ -d $(ROMFS_SCRATCH) -V "NSHInitVol" + +# Construct the ROMFS scratch root from the canonical root +$(ROMFS_SCRATCH): $(ROMFS_DEPS) $(GLOBAL_DEPS) + $(Q) $(MKDIR) -p $(ROMFS_SCRATCH) + $(Q) $(COPYDIR) $(ROMFS_ROOT)/* $(ROMFS_SCRATCH) +# delete all files in ROMFS_SCRATCH which start with a . or end with a ~ + $(Q) $(RM) $(ROMFS_SCRATCH)/*/.[!.]* $(ROMFS_SCRATCH)/*/*~ +ifneq ($(ROMFS_EXTRA_FILES),) + $(Q) $(MKDIR) -p $(ROMFS_SCRATCH)/extras + $(Q) $(COPY) $(ROMFS_EXTRA_FILES) $(ROMFS_SCRATCH)/extras +endif + $(Q) $(PYTHON) -u $(ROMFS_PRUNER) --folder $(ROMFS_SCRATCH) + +EXTRA_CLEANS += $(ROMGS_OBJ) $(ROMFS_IMG) + +endif + +################################################################################ +# Builtin command list generation +################################################################################ + +# +# Builtin commands can be generated by the configuration, in which case they +# must refer to commands that already exist, or indirectly generated by modules +# when they are built. +# +# The configuration supplies builtin command information in the BUILTIN_COMMANDS +# variable. Applications make empty files in $(WORK_DIR)/builtin_commands whose +# filename contains the same information. +# +# In each case, the command information consists of four fields separated with a +# period. These fields are the command's name, its thread priority, its stack size +# and the name of the function to call when starting the thread. +# +BUILTIN_CSRC = $(WORK_DIR)builtin_commands.c + +# command definitions from modules (may be empty at Makefile parsing time...) +MODULE_COMMANDS = $(subst COMMAND.,,$(notdir $(wildcard $(WORK_DIR)builtin_commands/COMMAND.*))) + +# We must have at least one pre-defined builtin command in order to generate +# any of this. +# +ifneq ($(BUILTIN_COMMANDS),) + +# (BUILTIN_PROTO,,) +define BUILTIN_PROTO + $(ECHO) 'extern int $(word 4,$1)(int argc, char *argv[]);' >> $2; +endef + +# (BUILTIN_DEF,,) +define BUILTIN_DEF + $(ECHO) ' {"$(word 1,$1)", $(word 2,$1), $(word 3,$1), $(word 4,$1)},' >> $2; +endef + +# Don't generate until modules have updated their command files +$(BUILTIN_CSRC): $(GLOBAL_DEPS) $(MODULE_OBJS) $(MODULE_MKFILES) $(BUILTIN_COMMAND_FILES) + @$(ECHO) "CMDS: $@" + $(Q) $(ECHO) '/* builtin command list - automatically generated, do not edit */' > $@ + $(Q) $(ECHO) '#include ' >> $@ + $(Q) $(ECHO) '#include ' >> $@ + $(Q) $(foreach spec,$(BUILTIN_COMMANDS),$(call BUILTIN_PROTO,$(subst ., ,$(spec)),$@)) + $(Q) $(foreach spec,$(MODULE_COMMANDS),$(call BUILTIN_PROTO,$(subst ., ,$(spec)),$@)) + $(Q) $(ECHO) 'const struct builtin_s g_builtins[] = {' >> $@ + $(Q) $(foreach spec,$(BUILTIN_COMMANDS),$(call BUILTIN_DEF,$(subst ., ,$(spec)),$@)) + $(Q) $(foreach spec,$(MODULE_COMMANDS),$(call BUILTIN_DEF,$(subst ., ,$(spec)),$@)) + $(Q) $(ECHO) ' {NULL, 0, 0, NULL}' >> $@ + $(Q) $(ECHO) '};' >> $@ + $(Q) $(ECHO) 'const int g_builtin_count = $(words $(BUILTIN_COMMANDS) $(MODULE_COMMANDS));' >> $@ + +SRCS += $(BUILTIN_CSRC) + +EXTRA_CLEANS += $(BUILTIN_CSRC) + +endif +endif ################################################################################ # Default SRCS generation @@ -329,9 +455,22 @@ SRCS += $(EMPTY_SRC) endif ################################################################################ -# Generic Build rules +# Build rules ################################################################################ +ifeq ($(PX4_TARGET_OS),nuttx) +# +# What we're going to build. +# +PRODUCT_BUNDLE = $(WORK_DIR)firmware.px4 +PRODUCT_BIN = $(WORK_DIR)firmware.bin +PRODUCT_ELF = $(WORK_DIR)firmware.elf +PRODUCT_PARAMXML = $(WORK_DIR)/parameters.xml + +.PHONY: firmware +firmware: $(PRODUCT_BUNDLE) +endif + # # Object files we will generate from sources # @@ -352,13 +491,59 @@ $(filter %.cpp.o,$(OBJS)): $(WORK_DIR)%.cpp.o: %.cpp $(GLOBAL_DEPS) $(filter %.S.o,$(OBJS)): $(WORK_DIR)%.S.o: %.S $(GLOBAL_DEPS) $(call ASSEMBLE,$<,$@) +ifeq ($(PX4_TARGET_OS),nuttx) # +# Built product rules +# + +$(PRODUCT_BUNDLE): $(PRODUCT_BIN) + @$(ECHO) %% Generating $@ +ifdef GEN_PARAM_XML + $(Q) $(PYTHON) $(PX4_BASE)/Tools/px_process_params.py --src-path $(PX4_BASE)/src --board CONFIG_ARCH_BOARD_$(CONFIG_BOARD) --xml + $(Q) $(MKFW) --prototype $(IMAGE_DIR)/$(BOARD).prototype \ + --git_identity $(PX4_BASE) \ + --parameter_xml $(PRODUCT_PARAMXML) \ + --image $< > $@ +else + $(Q) $(MKFW) --prototype $(IMAGE_DIR)/$(BOARD).prototype \ + --git_identity $(PX4_BASE) \ + --image $< > $@ +endif + +$(PRODUCT_BIN): $(PRODUCT_ELF) + $(call SYM_TO_BIN,$<,$@) + +$(PRODUCT_ELF): $(OBJS) $(MODULE_OBJS) $(LIBRARY_LIBS) $(GLOBAL_DEPS) $(LINK_DEPS) $(MODULE_MKFILES) + $(call LINK,$@,$(OBJS) $(MODULE_OBJS) $(LIBRARY_LIBS)) + +# +# Utility rules +# + +.PHONY: upload +upload: $(PRODUCT_BUNDLE) $(PRODUCT_BIN) + $(Q) $(MAKE) -f $(PX4_MK_DIR)/upload.mk \ + METHOD=serial \ + CONFIG=$(CONFIG) \ + BOARD=$(BOARD) \ + BUNDLE=$(PRODUCT_BUNDLE) \ + BIN=$(PRODUCT_BIN) + +.PHONY: clean +clean: $(MODULE_CLEANS) + @$(ECHO) %% cleaning + $(Q) $(REMOVE) $(PRODUCT_BUNDLE) $(PRODUCT_BIN) $(PRODUCT_ELF) + $(Q) $(REMOVE) $(OBJS) $(DEP_INCLUDES) $(EXTRA_CLEANS) + $(Q) $(RMDIR) $(NUTTX_EXPORT_DIR) +endif + # Include the OS specific build rules # The rules must define the "firmware" make target # ifeq ($(PX4_TARGET_OS),nuttx) -include $(MK_DIR)/nuttx_romfs.mk +# TODO +# Move above nuttx specific rules to $(MK_DIR)/nuttx_romfs.mk endif ifeq ($(PX4_TARGET_OS),posix) include $(MK_DIR)/posix_elf.mk diff --git a/makefiles/nuttx.mk b/makefiles/nuttx.mk index a151e7d917..4ca1dc2ac6 100644 --- a/makefiles/nuttx.mk +++ b/makefiles/nuttx.mk @@ -34,7 +34,7 @@ # building firmware. # -#MODULES += platforms/nuttx/px4_layer +MODULES += platforms/nuttx/px4_layer platforms/common # # Check that the NuttX archive for the selected board is available. diff --git a/src/drivers/device/module.mk b/src/drivers/device/module.mk index c206a5037c..a9e964ef94 100644 --- a/src/drivers/device/module.mk +++ b/src/drivers/device/module.mk @@ -41,8 +41,7 @@ SRCS = \ cdev.cpp \ i2c_nuttx.cpp \ pio.cpp \ - spi.cpp \ - ringbuffer.cpp + spi.cpp else SRCS = \ device_posix.cpp \ @@ -51,5 +50,5 @@ SRCS = \ vdev_posix.cpp \ i2c_posix.cpp \ sim.cpp \ - ringbuffer.cpp + ringbuffer.cpp endif diff --git a/src/drivers/device/ringbuffer.cpp b/src/drivers/device/ringbuffer.cpp index 0da2467fd6..1790289338 100644 --- a/src/drivers/device/ringbuffer.cpp +++ b/src/drivers/device/ringbuffer.cpp @@ -237,7 +237,7 @@ RingBuffer::force(double val) // FIXME - clang crashes on this get() call #ifdef __PX4_QURT #define __PX4_SBCAP my_sync_bool_compare_and_swap -static bool my_sync_bool_compare_and_swap(volatile unsigned *a, unsigned b, unsigned c) +static inline bool my_sync_bool_compare_and_swap(volatile unsigned *a, unsigned b, unsigned c) { if (*a == b) { *a = c; diff --git a/src/drivers/device/ringbuffer.h b/src/drivers/device/ringbuffer.h index 876bb3a8f2..1c65c02135 100644 --- a/src/drivers/device/ringbuffer.h +++ b/src/drivers/device/ringbuffer.h @@ -172,3 +172,9 @@ private: RingBuffer operator=(const RingBuffer&); }; +#ifdef __PX4_NUTTX +// Not sure why NuttX requires these to be defined in the header file +// but on other targets it causes a problem with multiple definitions +// at link time +#include "ringbuffer.cpp" +#endif diff --git a/src/examples/publisher/publisher_example.cpp b/src/examples/publisher/publisher_example.cpp index 7ce1533125..d034d33d6e 100644 --- a/src/examples/publisher/publisher_example.cpp +++ b/src/examples/publisher/publisher_example.cpp @@ -51,6 +51,8 @@ PublisherExample::PublisherExample() : { } +px4::AppState PublisherExample::appState; + int PublisherExample::main() { px4::Rate loop_rate(10); diff --git a/src/modules/commander/state_machine_helper.cpp b/src/modules/commander/state_machine_helper.cpp index a2829be829..7d973abdcb 100644 --- a/src/modules/commander/state_machine_helper.cpp +++ b/src/modules/commander/state_machine_helper.cpp @@ -361,7 +361,7 @@ main_state_transition(struct vehicle_status_s *status, main_state_t new_main_sta return ret; } -#ifdef PX4_NUTTX +#ifdef __PX4_NUTTX static transition_result_t disable_publication(const int mavlink_fd) { transition_result_t ret; diff --git a/src/modules/uORB/module.mk b/src/modules/uORB/module.mk index 88f1d6807a..31a2b24e4a 100644 --- a/src/modules/uORB/module.mk +++ b/src/modules/uORB/module.mk @@ -41,6 +41,7 @@ MODULE_STACKSIZE = 2048 ifeq ($(PX4_TARGET_OS),nuttx) SRCS = uORBDevices_nuttx.cpp \ + uORBTest_UnitTest.cpp \ uORBManager_nuttx.cpp else diff --git a/src/modules/uORB/uORBTest_UnitTest.cpp b/src/modules/uORB/uORBTest_UnitTest.cpp index c1ea73959f..722f538976 100644 --- a/src/modules/uORB/uORBTest_UnitTest.cpp +++ b/src/modules/uORB/uORBTest_UnitTest.cpp @@ -35,6 +35,7 @@ #include "uORBCommon.hpp" #include #include +#include uORBTest::UnitTest &uORBTest::UnitTest::instance() { diff --git a/src/platforms/common/px4_getopt.c b/src/platforms/common/px4_getopt.c index 3078351727..5f76065bb0 100644 --- a/src/platforms/common/px4_getopt.c +++ b/src/platforms/common/px4_getopt.c @@ -121,7 +121,7 @@ static int reorder(int argc, char **argv, const char *options) // Argv is changed to put all options and option args at the beginning, // followed by non-options. // -int px4_getopt(int argc, char *argv[], const char *options, int *myoptind, const char **myoptarg) +__EXPORT int px4_getopt(int argc, char *argv[], const char *options, int *myoptind, const char **myoptarg) { char *p; char c; @@ -149,4 +149,3 @@ int px4_getopt(int argc, char *argv[], const char *options, int *myoptind, const } return -1; } - diff --git a/src/platforms/nuttx/px4_layer/px4_nuttx_tasks.c b/src/platforms/nuttx/px4_layer/px4_nuttx_tasks.c index 7aa96bb5c0..e9b722de4c 100644 --- a/src/platforms/nuttx/px4_layer/px4_nuttx_tasks.c +++ b/src/platforms/nuttx/px4_layer/px4_nuttx_tasks.c @@ -72,21 +72,6 @@ px4_systemreset(bool to_bootloader) while(true); } -static void kill_task(FAR struct tcb_s *tcb, FAR void *arg); - -void px4_killall() -{ -// printf("Sending SIGUSR1 to all processes now\n"); - - /* iterate through all tasks and send kill signal */ - sched_foreach(kill_task, NULL); -} - -static void kill_task(FAR struct tcb_s *tcb, FAR void *arg) -{ - kill(tcb->pid, SIGUSR1); -} - int px4_task_spawn_cmd(const char *name, int scheduler, int priority, int stack_size, main_t entry, char * const argv[]) { int pid;