mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2025-02-05 21:52:10 +01:00
Merge remote-tracking branch 'origin/next' into brian/rfm22_FHSS
This commit is contained in:
commit
1979e8b57f
512
Makefile
512
Makefile
@ -31,12 +31,44 @@ $(foreach var, $(SANITIZE_GCC_VARS), $(eval $(call SANITIZE_VAR,$(var),disallowe
|
|||||||
SANITIZE_DEPRECATED_VARS := USE_BOOTLOADER
|
SANITIZE_DEPRECATED_VARS := USE_BOOTLOADER
|
||||||
$(foreach var, $(SANITIZE_DEPRECATED_VARS), $(eval $(call SANITIZE_VAR,$(var),deprecated)))
|
$(foreach var, $(SANITIZE_DEPRECATED_VARS), $(eval $(call SANITIZE_VAR,$(var),deprecated)))
|
||||||
|
|
||||||
|
# Deal with unreasonable requests
|
||||||
|
# See: http://xkcd.com/149/
|
||||||
|
ifeq ($(MAKECMDGOALS),me a sandwich)
|
||||||
|
ifeq ($(shell whoami),root)
|
||||||
|
$(error Okay)
|
||||||
|
else
|
||||||
|
$(error What? Make it yourself)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Make sure this isn't being run as root
|
||||||
|
ifeq ($(shell whoami),root)
|
||||||
|
$(error You should not be running this as root)
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Decide on a verbosity level based on the V= parameter
|
||||||
|
export AT := @
|
||||||
|
|
||||||
|
ifndef V
|
||||||
|
export V0 :=
|
||||||
|
export V1 := $(AT)
|
||||||
|
else ifeq ($(V), 0)
|
||||||
|
export V0 := $(AT)
|
||||||
|
export V1 := $(AT)
|
||||||
|
else ifeq ($(V), 1)
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Make sure we know a few things about the architecture before including
|
||||||
|
# the tools.mk to ensure that we download/install the right tools.
|
||||||
|
UNAME := $(shell uname)
|
||||||
|
ARCH := $(shell uname -m)
|
||||||
|
|
||||||
|
include $(ROOT_DIR)/make/tools.mk
|
||||||
|
|
||||||
# We almost need to consider autoconf/automake instead of this
|
# We almost need to consider autoconf/automake instead of this
|
||||||
# I don't know if windows supports uname :-(
|
# I don't know if windows supports uname :-(
|
||||||
QT_SPEC=win32-g++
|
QT_SPEC=win32-g++
|
||||||
UAVOBJGENERATOR="$(BUILD_DIR)/ground/uavobjgenerator/debug/uavobjgenerator.exe"
|
UAVOBJGENERATOR="$(BUILD_DIR)/ground/uavobjgenerator/debug/uavobjgenerator.exe"
|
||||||
UNAME := $(shell uname)
|
|
||||||
ARCH := $(shell uname -m)
|
|
||||||
ifeq ($(UNAME), Linux)
|
ifeq ($(UNAME), Linux)
|
||||||
QT_SPEC=linux-g++
|
QT_SPEC=linux-g++
|
||||||
UAVOBJGENERATOR="$(BUILD_DIR)/ground/uavobjgenerator/uavobjgenerator"
|
UAVOBJGENERATOR="$(BUILD_DIR)/ground/uavobjgenerator/uavobjgenerator"
|
||||||
@ -52,18 +84,6 @@ GCS_BUILD_CONF ?= debug
|
|||||||
# Set up misc host tools
|
# Set up misc host tools
|
||||||
RM=rm
|
RM=rm
|
||||||
|
|
||||||
# Decide on a verbosity level based on the V= parameter
|
|
||||||
export AT := @
|
|
||||||
|
|
||||||
ifndef V
|
|
||||||
export V0 :=
|
|
||||||
export V1 := $(AT)
|
|
||||||
else ifeq ($(V), 0)
|
|
||||||
export V0 := $(AT)
|
|
||||||
export V1 := $(AT)
|
|
||||||
else ifeq ($(V), 1)
|
|
||||||
endif
|
|
||||||
|
|
||||||
.PHONY: help
|
.PHONY: help
|
||||||
help:
|
help:
|
||||||
@echo
|
@echo
|
||||||
@ -96,6 +116,10 @@ help:
|
|||||||
@echo " all_<board> - Build all available images for <board>"
|
@echo " all_<board> - Build all available images for <board>"
|
||||||
@echo " all_<board>_clean - Remove all available images for <board>"
|
@echo " all_<board>_clean - Remove all available images for <board>"
|
||||||
@echo
|
@echo
|
||||||
|
@echo " all_ut - Build all unit tests"
|
||||||
|
@echo " all_ut_tap - Run all unit tests and capture all TAP output to files"
|
||||||
|
@echo " all_ut_run - Run all unit tests and dump TAP output to console"
|
||||||
|
@echo
|
||||||
@echo " [Firmware]"
|
@echo " [Firmware]"
|
||||||
@echo " <board> - Build firmware for <board>"
|
@echo " <board> - Build firmware for <board>"
|
||||||
@echo " supported boards are ($(ALL_BOARDS))"
|
@echo " supported boards are ($(ALL_BOARDS))"
|
||||||
@ -118,6 +142,10 @@ help:
|
|||||||
@echo " [Unbrick a board]"
|
@echo " [Unbrick a board]"
|
||||||
@echo " unbrick_<board> - Use the STM32's built in boot ROM to write a bootloader to <board>"
|
@echo " unbrick_<board> - Use the STM32's built in boot ROM to write a bootloader to <board>"
|
||||||
@echo " supported boards are ($(BL_BOARDS))"
|
@echo " supported boards are ($(BL_BOARDS))"
|
||||||
|
@echo " [Unittests]"
|
||||||
|
@echo " ut_<test> - Build unit test <test>"
|
||||||
|
@echo " ut_<test>_tap - Run test and capture TAP output into a file"
|
||||||
|
@echo " ut_<test>_run - Run test and dump TAP output to console"
|
||||||
@echo
|
@echo
|
||||||
@echo " [Simulation]"
|
@echo " [Simulation]"
|
||||||
@echo " sim_osx - Build OpenPilot simulation firmware for OSX"
|
@echo " sim_osx - Build OpenPilot simulation firmware for OSX"
|
||||||
@ -158,316 +186,6 @@ $(TOOLS_DIR):
|
|||||||
$(BUILD_DIR):
|
$(BUILD_DIR):
|
||||||
mkdir -p $@
|
mkdir -p $@
|
||||||
|
|
||||||
###############################################################
|
|
||||||
#
|
|
||||||
# Installers for tools required by the ground and flight builds
|
|
||||||
#
|
|
||||||
# NOTE: These are not tied to the default goals
|
|
||||||
# and must be invoked manually
|
|
||||||
#
|
|
||||||
###############################################################
|
|
||||||
|
|
||||||
# Set up QT toolchain
|
|
||||||
QT_SDK_DIR := $(TOOLS_DIR)/qtsdk-v1.2.1
|
|
||||||
|
|
||||||
.PHONY: qt_sdk_install
|
|
||||||
# Choose the appropriate installer based on host architecture
|
|
||||||
ifneq (,$(filter $(ARCH), x86_64 amd64))
|
|
||||||
# 64-bit
|
|
||||||
qt_sdk_install: QT_SDK_FILE := QtSdk-offline-linux-x86_64-v1.2.1.run
|
|
||||||
qt_sdk_install: QT_SDK_URL := http://www.developer.nokia.com/dp?uri=http://sw.nokia.com/id/14b2039c-0e1f-4774-a4f2-9aa60b6d5313/Qt_SDK_Lin64_offline
|
|
||||||
else
|
|
||||||
# 32-bit
|
|
||||||
qt_sdk_install: QT_SDK_URL := http://www.developer.nokia.com/dp?uri=http://sw.nokia.com/id/8ea74da4-fec1-4277-8b26-c58cc82e204b/Qt_SDK_Lin32_offline
|
|
||||||
qt_sdk_install: QT_SDK_FILE := QtSdk-offline-linux-x86-v1.2.1.run
|
|
||||||
endif
|
|
||||||
# order-only prereq on directory existance:
|
|
||||||
qt_sdk_install : | $(DL_DIR) $(TOOLS_DIR)
|
|
||||||
qt_sdk_install: qt_sdk_clean
|
|
||||||
# download the source only if it's newer than what we already have
|
|
||||||
$(V1) wget -N --content-disposition -P "$(DL_DIR)" "$(QT_SDK_URL)"
|
|
||||||
# tell the user exactly which path they should select in the GUI
|
|
||||||
$(V1) echo "*** NOTE NOTE NOTE ***"
|
|
||||||
$(V1) echo "*"
|
|
||||||
$(V1) echo "* In the GUI, please use exactly this path as the installation path:"
|
|
||||||
$(V1) echo "* $(QT_SDK_DIR)"
|
|
||||||
$(V1) echo "*"
|
|
||||||
$(V1) echo "*** NOTE NOTE NOTE ***"
|
|
||||||
|
|
||||||
#installer is an executable, make it executable and run it
|
|
||||||
$(V1) chmod u+x "$(DL_DIR)/$(QT_SDK_FILE)"
|
|
||||||
$(V1) "$(DL_DIR)/$(QT_SDK_FILE)" -style cleanlooks
|
|
||||||
|
|
||||||
.PHONY: qt_sdk_clean
|
|
||||||
qt_sdk_clean:
|
|
||||||
$(V1) [ ! -d "$(QT_SDK_DIR)" ] || $(RM) -rf $(QT_SDK_DIR)
|
|
||||||
|
|
||||||
# Set up ARM (STM32) SDK
|
|
||||||
ARM_SDK_DIR := $(TOOLS_DIR)/gcc-arm-none-eabi-4_6-2012q1
|
|
||||||
|
|
||||||
.PHONY: arm_sdk_install
|
|
||||||
arm_sdk_install: ARM_SDK_URL := https://launchpad.net/gcc-arm-embedded/4.6/4.6-2012-q1-update/+download/gcc-arm-none-eabi-4_6-2012q1-20120316.tar.bz2
|
|
||||||
arm_sdk_install: ARM_SDK_FILE := $(notdir $(ARM_SDK_URL))
|
|
||||||
# order-only prereq on directory existance:
|
|
||||||
arm_sdk_install: | $(DL_DIR) $(TOOLS_DIR)
|
|
||||||
arm_sdk_install: arm_sdk_clean
|
|
||||||
# download the source only if it's newer than what we already have
|
|
||||||
$(V1) wget --no-check-certificate -N -P "$(DL_DIR)" "$(ARM_SDK_URL)"
|
|
||||||
|
|
||||||
# binary only release so just extract it
|
|
||||||
$(V1) tar -C $(TOOLS_DIR) -xjf "$(DL_DIR)/$(ARM_SDK_FILE)"
|
|
||||||
|
|
||||||
.PHONY: arm_sdk_clean
|
|
||||||
arm_sdk_clean:
|
|
||||||
$(V1) [ ! -d "$(ARM_SDK_DIR)" ] || $(RM) -r $(ARM_SDK_DIR)
|
|
||||||
|
|
||||||
# Set up openocd tools
|
|
||||||
OPENOCD_DIR := $(TOOLS_DIR)/openocd
|
|
||||||
OPENOCD_WIN_DIR := $(TOOLS_DIR)/openocd_win
|
|
||||||
OPENOCD_BUILD_DIR := $(DL_DIR)/openocd-build
|
|
||||||
|
|
||||||
.PHONY: openocd_install
|
|
||||||
openocd_install: | $(DL_DIR) $(TOOLS_DIR)
|
|
||||||
openocd_install: OPENOCD_URL := http://sourceforge.net/projects/openocd/files/openocd/0.5.0/openocd-0.5.0.tar.bz2/download
|
|
||||||
openocd_install: OPENOCD_FILE := openocd-0.5.0.tar.bz2
|
|
||||||
openocd_install: openocd_clean
|
|
||||||
# download the source only if it's newer than what we already have
|
|
||||||
$(V1) wget -N -P "$(DL_DIR)" --trust-server-name "$(OPENOCD_URL)"
|
|
||||||
|
|
||||||
# extract the source
|
|
||||||
$(V1) [ ! -d "$(OPENOCD_BUILD_DIR)" ] || $(RM) -r "$(OPENOCD_BUILD_DIR)"
|
|
||||||
$(V1) mkdir -p "$(OPENOCD_BUILD_DIR)"
|
|
||||||
$(V1) tar -C $(OPENOCD_BUILD_DIR) -xjf "$(DL_DIR)/$(OPENOCD_FILE)"
|
|
||||||
|
|
||||||
# build and install
|
|
||||||
$(V1) mkdir -p "$(OPENOCD_DIR)"
|
|
||||||
$(V1) ( \
|
|
||||||
cd $(OPENOCD_BUILD_DIR)/openocd-0.5.0 ; \
|
|
||||||
./configure --prefix="$(OPENOCD_DIR)" --enable-ft2232_libftdi ; \
|
|
||||||
$(MAKE) --silent ; \
|
|
||||||
$(MAKE) --silent install ; \
|
|
||||||
)
|
|
||||||
|
|
||||||
# delete the extracted source when we're done
|
|
||||||
$(V1) [ ! -d "$(OPENOCD_BUILD_DIR)" ] || $(RM) -rf "$(OPENOCD_BUILD_DIR)"
|
|
||||||
|
|
||||||
.PHONY: ftd2xx_install
|
|
||||||
|
|
||||||
FTD2XX_DIR := $(DL_DIR)/ftd2xx
|
|
||||||
|
|
||||||
ftd2xx_install: | $(DL_DIR)
|
|
||||||
ftd2xx_install: FTD2XX_URL := http://www.ftdichip.com/Drivers/CDM/Beta/CDM20817.zip
|
|
||||||
ftd2xx_install: FTD2XX_FILE := CDM20817.zip
|
|
||||||
ftd2xx_install: ftd2xx_clean
|
|
||||||
# download the file only if it's newer than what we already have
|
|
||||||
$(V0) @echo " DOWNLOAD $(FTD2XX_URL)"
|
|
||||||
$(V1) wget -q -N -P "$(DL_DIR)" "$(FTD2XX_URL)"
|
|
||||||
|
|
||||||
# extract the source
|
|
||||||
$(V0) @echo " EXTRACT $(FTD2XX_FILE) -> $(FTD2XX_DIR)"
|
|
||||||
$(V1) mkdir -p "$(FTD2XX_DIR)"
|
|
||||||
$(V1) unzip -q -d "$(FTD2XX_DIR)" "$(DL_DIR)/$(FTD2XX_FILE)"
|
|
||||||
|
|
||||||
.PHONY: ftd2xx_clean
|
|
||||||
ftd2xx_clean:
|
|
||||||
$(V0) @echo " CLEAN $(FTD2XX_DIR)"
|
|
||||||
$(V1) [ ! -d "$(FTD2XX_DIR)" ] || $(RM) -r "$(FTD2XX_DIR)"
|
|
||||||
|
|
||||||
.PHONY: ftd2xx_install
|
|
||||||
|
|
||||||
LIBUSB_WIN_DIR := $(DL_DIR)/libusb-win32-bin-1.2.6.0
|
|
||||||
|
|
||||||
libusb_win_install: | $(DL_DIR)
|
|
||||||
libusb_win_install: LIBUSB_WIN_URL := http://sourceforge.net/projects/libusb-win32/files/libusb-win32-releases/1.2.6.0/libusb-win32-bin-1.2.6.0.zip/download
|
|
||||||
libusb_win_install: LIBUSB_WIN_FILE := libusb-win32-bin-1.2.6.0.zip
|
|
||||||
libusb_win_install: libusb_win_clean
|
|
||||||
# download the file only if it's newer than what we already have
|
|
||||||
$(V0) @echo " DOWNLOAD $(LIBUSB_WIN_URL)"
|
|
||||||
$(V1) wget -q -N -P "$(DL_DIR)" --trust-server-name "$(LIBUSB_WIN_URL)"
|
|
||||||
|
|
||||||
# extract the source
|
|
||||||
$(V0) @echo " EXTRACT $(LIBUSB_WIN_FILE) -> $(LIBUSB_WIN_DIR)"
|
|
||||||
$(V1) mkdir -p "$(LIBUSB_WIN_DIR)"
|
|
||||||
$(V1) unzip -q -d "$(DL_DIR)" "$(DL_DIR)/$(LIBUSB_WIN_FILE)"
|
|
||||||
|
|
||||||
# fixup .h file needed by openocd build
|
|
||||||
$(V0) @echo " FIXUP $(LIBUSB_WIN_DIR)"
|
|
||||||
$(V1) ln -s "$(LIBUSB_WIN_DIR)/include/lusb0_usb.h" "$(LIBUSB_WIN_DIR)/include/usb.h"
|
|
||||||
|
|
||||||
.PHONY: libusb_win_clean
|
|
||||||
libusb_win_clean:
|
|
||||||
$(V0) @echo " CLEAN $(LIBUSB_WIN_DIR)"
|
|
||||||
$(V1) [ ! -d "$(LIBUSB_WIN_DIR)" ] || $(RM) -r "$(LIBUSB_WIN_DIR)"
|
|
||||||
|
|
||||||
.PHONY: openocd_git_win_install
|
|
||||||
|
|
||||||
openocd_git_win_install: | $(DL_DIR) $(TOOLS_DIR)
|
|
||||||
openocd_git_win_install: OPENOCD_URL := git://openocd.git.sourceforge.net/gitroot/openocd/openocd
|
|
||||||
openocd_git_win_install: OPENOCD_REV := f1c0133321c8fcadadd10bba5537c0a634eb183b
|
|
||||||
openocd_git_win_install: openocd_win_clean libusb_win_install ftd2xx_install
|
|
||||||
# download the source
|
|
||||||
$(V0) @echo " DOWNLOAD $(OPENOCD_URL) @ $(OPENOCD_REV)"
|
|
||||||
$(V1) [ ! -d "$(OPENOCD_BUILD_DIR)" ] || $(RM) -rf "$(OPENOCD_BUILD_DIR)"
|
|
||||||
$(V1) mkdir -p "$(OPENOCD_BUILD_DIR)"
|
|
||||||
$(V1) git clone --no-checkout $(OPENOCD_URL) "$(DL_DIR)/openocd-build"
|
|
||||||
$(V1) ( \
|
|
||||||
cd $(OPENOCD_BUILD_DIR) ; \
|
|
||||||
git checkout -q $(OPENOCD_REV) ; \
|
|
||||||
)
|
|
||||||
|
|
||||||
# apply patches
|
|
||||||
$(V0) @echo " PATCH $(OPENOCD_BUILD_DIR)"
|
|
||||||
$(V1) ( \
|
|
||||||
cd $(OPENOCD_BUILD_DIR) ; \
|
|
||||||
git apply < $(ROOT_DIR)/flight/Project/OpenOCD/0001-armv7m-remove-dummy-FP-regs-for-new-gdb.patch ; \
|
|
||||||
git apply < $(ROOT_DIR)/flight/Project/OpenOCD/0002-rtos-add-stm32_stlink-to-FreeRTOS-targets.patch ; \
|
|
||||||
)
|
|
||||||
|
|
||||||
# build and install
|
|
||||||
$(V0) @echo " BUILD $(OPENOCD_WIN_DIR)"
|
|
||||||
$(V1) mkdir -p "$(OPENOCD_WIN_DIR)"
|
|
||||||
$(V1) ( \
|
|
||||||
cd $(OPENOCD_BUILD_DIR) ; \
|
|
||||||
./bootstrap ; \
|
|
||||||
./configure --enable-maintainer-mode --prefix="$(OPENOCD_WIN_DIR)" \
|
|
||||||
--build=i686-pc-linux-gnu --host=i586-mingw32msvc \
|
|
||||||
CPPFLAGS=-I$(LIBUSB_WIN_DIR)/include \
|
|
||||||
LDFLAGS=-L$(LIBUSB_WIN_DIR)/lib/gcc \
|
|
||||||
--enable-ft2232_ftd2xx --with-ftd2xx-win32-zipdir=$(FTD2XX_DIR) \
|
|
||||||
--disable-werror \
|
|
||||||
--enable-stlink ; \
|
|
||||||
$(MAKE) ; \
|
|
||||||
$(MAKE) install ; \
|
|
||||||
)
|
|
||||||
|
|
||||||
# delete the extracted source when we're done
|
|
||||||
$(V1) [ ! -d "$(OPENOCD_BUILD_DIR)" ] || $(RM) -rf "$(OPENOCD_BUILD_DIR)"
|
|
||||||
|
|
||||||
.PHONY: openocd_win_clean
|
|
||||||
openocd_win_clean:
|
|
||||||
$(V0) @echo " CLEAN $(OPENOCD_WIN_DIR)"
|
|
||||||
$(V1) [ ! -d "$(OPENOCD_WIN_DIR)" ] || $(RM) -r "$(OPENOCD_WIN_DIR)"
|
|
||||||
|
|
||||||
.PHONY: openocd_git_install
|
|
||||||
|
|
||||||
openocd_git_install: | $(DL_DIR) $(TOOLS_DIR)
|
|
||||||
openocd_git_install: OPENOCD_URL := git://openocd.git.sourceforge.net/gitroot/openocd/openocd
|
|
||||||
openocd_git_install: OPENOCD_REV := f1c0133321c8fcadadd10bba5537c0a634eb183b
|
|
||||||
openocd_git_install: openocd_clean
|
|
||||||
# download the source
|
|
||||||
$(V0) @echo " DOWNLOAD $(OPENOCD_URL) @ $(OPENOCD_REV)"
|
|
||||||
$(V1) [ ! -d "$(OPENOCD_BUILD_DIR)" ] || $(RM) -rf "$(OPENOCD_BUILD_DIR)"
|
|
||||||
$(V1) mkdir -p "$(OPENOCD_BUILD_DIR)"
|
|
||||||
$(V1) git clone --no-checkout $(OPENOCD_URL) "$(OPENOCD_BUILD_DIR)"
|
|
||||||
$(V1) ( \
|
|
||||||
cd $(OPENOCD_BUILD_DIR) ; \
|
|
||||||
git checkout -q $(OPENOCD_REV) ; \
|
|
||||||
)
|
|
||||||
|
|
||||||
# apply patches
|
|
||||||
$(V0) @echo " PATCH $(OPENOCD_DIR)"
|
|
||||||
$(V1) ( \
|
|
||||||
cd $(OPENOCD_BUILD_DIR) ; \
|
|
||||||
git apply < $(ROOT_DIR)/flight/Project/OpenOCD/0001-armv7m-remove-dummy-FP-regs-for-new-gdb.patch ; \
|
|
||||||
git apply < $(ROOT_DIR)/flight/Project/OpenOCD/0002-rtos-add-stm32_stlink-to-FreeRTOS-targets.patch ; \
|
|
||||||
)
|
|
||||||
|
|
||||||
# build and install
|
|
||||||
$(V0) @echo " BUILD $(OPENOCD_DIR)"
|
|
||||||
$(V1) mkdir -p "$(OPENOCD_DIR)"
|
|
||||||
$(V1) ( \
|
|
||||||
cd $(OPENOCD_BUILD_DIR) ; \
|
|
||||||
./bootstrap ; \
|
|
||||||
./configure --enable-maintainer-mode --prefix="$(OPENOCD_DIR)" --enable-ft2232_libftdi --enable-buspirate --enable-stlink ; \
|
|
||||||
$(MAKE) ; \
|
|
||||||
$(MAKE) install ; \
|
|
||||||
)
|
|
||||||
|
|
||||||
# delete the extracted source when we're done
|
|
||||||
$(V1) [ ! -d "$(OPENOCD_BUILD_DIR)" ] || $(RM) -rf "$(OPENOCD_BUILD_DIR)"
|
|
||||||
|
|
||||||
.PHONY: openocd_clean
|
|
||||||
openocd_clean:
|
|
||||||
$(V0) @echo " CLEAN $(OPENOCD_DIR)"
|
|
||||||
$(V1) [ ! -d "$(OPENOCD_DIR)" ] || $(RM) -r "$(OPENOCD_DIR)"
|
|
||||||
|
|
||||||
STM32FLASH_DIR := $(TOOLS_DIR)/stm32flash
|
|
||||||
|
|
||||||
.PHONY: stm32flash_install
|
|
||||||
stm32flash_install: STM32FLASH_URL := http://stm32flash.googlecode.com/svn/trunk
|
|
||||||
stm32flash_install: STM32FLASH_REV := 61
|
|
||||||
stm32flash_install: stm32flash_clean
|
|
||||||
# download the source
|
|
||||||
$(V0) @echo " DOWNLOAD $(STM32FLASH_URL) @ r$(STM32FLASH_REV)"
|
|
||||||
$(V1) svn export -q -r "$(STM32FLASH_REV)" "$(STM32FLASH_URL)" "$(STM32FLASH_DIR)"
|
|
||||||
|
|
||||||
# build
|
|
||||||
$(V0) @echo " BUILD $(STM32FLASH_DIR)"
|
|
||||||
$(V1) $(MAKE) --silent -C $(STM32FLASH_DIR) all
|
|
||||||
|
|
||||||
.PHONY: stm32flash_clean
|
|
||||||
stm32flash_clean:
|
|
||||||
$(V0) @echo " CLEAN $(STM32FLASH_DIR)"
|
|
||||||
$(V1) [ ! -d "$(STM32FLASH_DIR)" ] || $(RM) -r "$(STM32FLASH_DIR)"
|
|
||||||
|
|
||||||
DFUUTIL_DIR := $(TOOLS_DIR)/dfu-util
|
|
||||||
|
|
||||||
.PHONY: dfuutil_install
|
|
||||||
dfuutil_install: DFUUTIL_URL := http://dfu-util.gnumonks.org/releases/dfu-util-0.5.tar.gz
|
|
||||||
dfuutil_install: DFUUTIL_FILE := $(notdir $(DFUUTIL_URL))
|
|
||||||
dfuutil_install: | $(DL_DIR) $(TOOLS_DIR)
|
|
||||||
dfuutil_install: dfuutil_clean
|
|
||||||
# download the source
|
|
||||||
$(V0) @echo " DOWNLOAD $(DFUUTIL_URL)"
|
|
||||||
$(V1) wget -N -P "$(DL_DIR)" "$(DFUUTIL_URL)"
|
|
||||||
|
|
||||||
# extract the source
|
|
||||||
$(V0) @echo " EXTRACT $(DFUUTIL_FILE)"
|
|
||||||
$(V1) [ ! -d "$(DL_DIR)/dfuutil-build" ] || $(RM) -r "$(DL_DIR)/dfuutil-build"
|
|
||||||
$(V1) mkdir -p "$(DL_DIR)/dfuutil-build"
|
|
||||||
$(V1) tar -C $(DL_DIR)/dfuutil-build -xf "$(DL_DIR)/$(DFUUTIL_FILE)"
|
|
||||||
|
|
||||||
# build
|
|
||||||
$(V0) @echo " BUILD $(DFUUTIL_DIR)"
|
|
||||||
$(V1) mkdir -p "$(DFUUTIL_DIR)"
|
|
||||||
$(V1) ( \
|
|
||||||
cd $(DL_DIR)/dfuutil-build/dfu-util-0.5 ; \
|
|
||||||
./configure --prefix="$(DFUUTIL_DIR)" ; \
|
|
||||||
$(MAKE) ; \
|
|
||||||
$(MAKE) install ; \
|
|
||||||
)
|
|
||||||
|
|
||||||
.PHONY: dfuutil_clean
|
|
||||||
dfuutil_clean:
|
|
||||||
$(V0) @echo " CLEAN $(DFUUTIL_DIR)"
|
|
||||||
$(V1) [ ! -d "$(DFUUTIL_DIR)" ] || $(RM) -r "$(DFUUTIL_DIR)"
|
|
||||||
|
|
||||||
# see http://developer.android.com/sdk/ for latest versions
|
|
||||||
ANDROID_SDK_DIR := $(TOOLS_DIR)/android-sdk-linux
|
|
||||||
.PHONY: android_sdk_install
|
|
||||||
android_sdk_install: ANDROID_SDK_URL := http://dl.google.com/android/android-sdk_r21.0.1-linux.tgz
|
|
||||||
android_sdk_install: ANDROID_SDK_FILE := $(notdir $(ANDROID_SDK_URL))
|
|
||||||
# order-only prereq on directory existance:
|
|
||||||
android_sdk_install: | $(DL_DIR) $(TOOLS_DIR)
|
|
||||||
android_sdk_install: android_sdk_clean
|
|
||||||
# download the source only if it's newer than what we already have
|
|
||||||
$(V0) @echo " DOWNLOAD $(ANDROID_SDK_URL)"
|
|
||||||
$(V1) wget --no-check-certificate -N -P "$(DL_DIR)" "$(ANDROID_SDK_URL)"
|
|
||||||
|
|
||||||
# binary only release so just extract it
|
|
||||||
$(V0) @echo " EXTRACT $(ANDROID_SDK_FILE)"
|
|
||||||
$(V1) tar -C $(TOOLS_DIR) -xf "$(DL_DIR)/$(ANDROID_SDK_FILE)"
|
|
||||||
|
|
||||||
.PHONY: android_sdk_clean
|
|
||||||
android_sdk_clean:
|
|
||||||
$(V0) @echo " CLEAN $(ANDROID_SDK_DIR)"
|
|
||||||
$(V1) [ ! -d "$(ANDROID_SDK_DIR)" ] || $(RM) -r $(ANDROID_SDK_DIR)
|
|
||||||
|
|
||||||
.PHONY: android_sdk_update
|
|
||||||
android_sdk_update:
|
|
||||||
$(V0) @echo " UPDATE $(ANDROID_SDK_DIR)"
|
|
||||||
$(ANDROID_SDK_DIR)/tools/android update sdk --no-ui -t platform-tools,android-14,addon-google_apis-google-14
|
|
||||||
|
|
||||||
##############################
|
##############################
|
||||||
#
|
#
|
||||||
# Set up paths to tools
|
# Set up paths to tools
|
||||||
@ -475,7 +193,7 @@ android_sdk_update:
|
|||||||
##############################
|
##############################
|
||||||
|
|
||||||
ifeq ($(shell [ -d "$(QT_SDK_DIR)" ] && echo "exists"), exists)
|
ifeq ($(shell [ -d "$(QT_SDK_DIR)" ] && echo "exists"), exists)
|
||||||
QMAKE=$(QT_SDK_DIR)/Desktop/Qt/4.8.1/gcc/bin/qmake
|
QMAKE = $(QT_SDK_QMAKE_PATH)
|
||||||
else
|
else
|
||||||
# not installed, hope it's in the path...
|
# not installed, hope it's in the path...
|
||||||
QMAKE = qmake
|
QMAKE = qmake
|
||||||
@ -728,6 +446,17 @@ uavo-collections_clean:
|
|||||||
#
|
#
|
||||||
##############################
|
##############################
|
||||||
|
|
||||||
|
# Define some pointers to the various important pieces of the flight code
|
||||||
|
# to prevent these being repeated in every sub makefile
|
||||||
|
PIOS := $(ROOT_DIR)/flight/PiOS
|
||||||
|
FLIGHTLIB := $(ROOT_DIR)/flight/Libraries
|
||||||
|
OPMODULEDIR := $(ROOT_DIR)/flight/Modules
|
||||||
|
OPUAVOBJ := $(ROOT_DIR)/flight/targets/UAVObjects
|
||||||
|
OPUAVTALK := $(ROOT_DIR)/flight/targets/UAVTalk
|
||||||
|
HWDEFS := $(ROOT_DIR)/flight/targets/board_hw_defs
|
||||||
|
DOXYGENDIR := $(ROOT_DIR)/flight/Doc/Doxygen
|
||||||
|
OPUAVSYNTHDIR := $(BUILD_DIR)/uavobject-synthetics/flight
|
||||||
|
|
||||||
# $(1) = Canonical board name all in lower case (e.g. coptercontrol)
|
# $(1) = Canonical board name all in lower case (e.g. coptercontrol)
|
||||||
# $(2) = Name of board used in source tree (e.g. CopterControl)
|
# $(2) = Name of board used in source tree (e.g. CopterControl)
|
||||||
# $(3) = Short name for board (e.g CC)
|
# $(3) = Short name for board (e.g CC)
|
||||||
@ -738,13 +467,26 @@ fw_$(1): fw_$(1)_opfw
|
|||||||
|
|
||||||
fw_$(1)_%: uavobjects_flight
|
fw_$(1)_%: uavobjects_flight
|
||||||
$(V1) mkdir -p $(BUILD_DIR)/fw_$(1)/dep
|
$(V1) mkdir -p $(BUILD_DIR)/fw_$(1)/dep
|
||||||
$(V1) cd $(ROOT_DIR)/flight/$(2) && \
|
$(V1) cd $(ROOT_DIR)/flight/targets/$(2) && \
|
||||||
$$(MAKE) -r --no-print-directory \
|
$$(MAKE) -r --no-print-directory \
|
||||||
BOARD_NAME=$(1) \
|
BOARD_NAME=$(1) \
|
||||||
BOARD_SHORT_NAME=$(3) \
|
BOARD_SHORT_NAME=$(3) \
|
||||||
BUILD_TYPE=fw \
|
BUILD_TYPE=fw \
|
||||||
TCHAIN_PREFIX="$(ARM_SDK_PREFIX)" \
|
TCHAIN_PREFIX="$(ARM_SDK_PREFIX)" \
|
||||||
REMOVE_CMD="$(RM)" OOCD_EXE="$(OPENOCD)" \
|
REMOVE_CMD="$(RM)" OOCD_EXE="$(OPENOCD)" \
|
||||||
|
\
|
||||||
|
TARGET=fw_$(1) \
|
||||||
|
OUTDIR=$(BUILD_DIR)/fw_$(1) \
|
||||||
|
\
|
||||||
|
PIOS=$(PIOS) \
|
||||||
|
FLIGHTLIB=$(FLIGHTLIB) \
|
||||||
|
OPMODULEDIR=$(OPMODULEDIR) \
|
||||||
|
OPUAVOBJ=$(OPUAVOBJ) \
|
||||||
|
OPUAVTALK=$(OPUAVTALK) \
|
||||||
|
HWDEFSINC=$(HWDEFS)/$(1) \
|
||||||
|
DOXYGENDIR=$(DOXYGENDIR) \
|
||||||
|
OPUAVSYNTHDIR=$(OPUAVSYNTHDIR) \
|
||||||
|
\
|
||||||
$$*
|
$$*
|
||||||
|
|
||||||
.PHONY: $(1)_clean
|
.PHONY: $(1)_clean
|
||||||
@ -763,13 +505,26 @@ bl_$(1)_bino: bl_$(1)_bin
|
|||||||
|
|
||||||
bl_$(1)_%:
|
bl_$(1)_%:
|
||||||
$(V1) mkdir -p $(BUILD_DIR)/bl_$(1)/dep
|
$(V1) mkdir -p $(BUILD_DIR)/bl_$(1)/dep
|
||||||
$(V1) cd $(ROOT_DIR)/flight/Bootloaders/$(2) && \
|
$(V1) cd $(ROOT_DIR)/flight/targets/Bootloaders/$(2) && \
|
||||||
$$(MAKE) -r --no-print-directory \
|
$$(MAKE) -r --no-print-directory \
|
||||||
BOARD_NAME=$(1) \
|
BOARD_NAME=$(1) \
|
||||||
BOARD_SHORT_NAME=$(3) \
|
BOARD_SHORT_NAME=$(3) \
|
||||||
BUILD_TYPE=bl \
|
BUILD_TYPE=bl \
|
||||||
TCHAIN_PREFIX="$(ARM_SDK_PREFIX)" \
|
TCHAIN_PREFIX="$(ARM_SDK_PREFIX)" \
|
||||||
REMOVE_CMD="$(RM)" OOCD_EXE="$(OPENOCD)" \
|
REMOVE_CMD="$(RM)" OOCD_EXE="$(OPENOCD)" \
|
||||||
|
\
|
||||||
|
TARGET=bl_$(1) \
|
||||||
|
OUTDIR=$(BUILD_DIR)/bl_$(1) \
|
||||||
|
\
|
||||||
|
PIOS=$(PIOS) \
|
||||||
|
FLIGHTLIB=$(FLIGHTLIB) \
|
||||||
|
OPMODULEDIR=$(OPMODULEDIR) \
|
||||||
|
OPUAVOBJ=$(OPUAVOBJ) \
|
||||||
|
OPUAVTALK=$(OPUAVTALK) \
|
||||||
|
HWDEFSINC=$(HWDEFS)/$(1) \
|
||||||
|
OPUAVSYNTHDIR=$(OPUAVSYNTHDIR) \
|
||||||
|
DOXYGENDIR=$(DOXYGENDIR) \
|
||||||
|
\
|
||||||
$$*
|
$$*
|
||||||
|
|
||||||
.PHONY: unbrick_$(1)
|
.PHONY: unbrick_$(1)
|
||||||
@ -799,13 +554,26 @@ bu_$(1): bu_$(1)_opfw
|
|||||||
|
|
||||||
bu_$(1)_%: bl_$(1)_bino
|
bu_$(1)_%: bl_$(1)_bino
|
||||||
$(V1) mkdir -p $(BUILD_DIR)/bu_$(1)/dep
|
$(V1) mkdir -p $(BUILD_DIR)/bu_$(1)/dep
|
||||||
$(V1) cd $(ROOT_DIR)/flight/Bootloaders/BootloaderUpdater && \
|
$(V1) cd $(ROOT_DIR)/flight/targets/Bootloaders/BootloaderUpdater && \
|
||||||
$$(MAKE) -r --no-print-directory \
|
$$(MAKE) -r --no-print-directory \
|
||||||
BOARD_NAME=$(1) \
|
BOARD_NAME=$(1) \
|
||||||
BOARD_SHORT_NAME=$(3) \
|
BOARD_SHORT_NAME=$(3) \
|
||||||
BUILD_TYPE=bu \
|
BUILD_TYPE=bu \
|
||||||
TCHAIN_PREFIX="$(ARM_SDK_PREFIX)" \
|
TCHAIN_PREFIX="$(ARM_SDK_PREFIX)" \
|
||||||
REMOVE_CMD="$(RM)" OOCD_EXE="$(OPENOCD)" \
|
REMOVE_CMD="$(RM)" OOCD_EXE="$(OPENOCD)" \
|
||||||
|
\
|
||||||
|
TARGET=bu_$(1) \
|
||||||
|
OUTDIR=$(BUILD_DIR)/bu_$(1) \
|
||||||
|
\
|
||||||
|
PIOS=$(PIOS) \
|
||||||
|
FLIGHTLIB=$(FLIGHTLIB) \
|
||||||
|
OPMODULEDIR=$(OPMODULEDIR) \
|
||||||
|
OPUAVOBJ=$(OPUAVOBJ) \
|
||||||
|
OPUAVTALK=$(OPUAVTALK) \
|
||||||
|
HWDEFSINC=$(HWDEFS)/$(1) \
|
||||||
|
OPUAVSYNTHDIR=$(OPUAVSYNTHDIR) \
|
||||||
|
DOXYGENDIR=$(DOXYGENDIR) \
|
||||||
|
\
|
||||||
$$*
|
$$*
|
||||||
|
|
||||||
.PHONY: bu_$(1)_clean
|
.PHONY: bu_$(1)_clean
|
||||||
@ -821,13 +589,17 @@ ef_$(1): ef_$(1)_bin
|
|||||||
|
|
||||||
ef_$(1)_%: bl_$(1)_bin fw_$(1)_opfw
|
ef_$(1)_%: bl_$(1)_bin fw_$(1)_opfw
|
||||||
$(V1) mkdir -p $(BUILD_DIR)/ef_$(1)/dep
|
$(V1) mkdir -p $(BUILD_DIR)/ef_$(1)/dep
|
||||||
$(V1) cd $(ROOT_DIR)/flight/EntireFlash && \
|
$(V1) cd $(ROOT_DIR)/flight/targets/EntireFlash && \
|
||||||
$$(MAKE) -r --no-print-directory \
|
$$(MAKE) -r --no-print-directory \
|
||||||
BOARD_NAME=$(1) \
|
BOARD_NAME=$(1) \
|
||||||
BOARD_SHORT_NAME=$(3) \
|
BOARD_SHORT_NAME=$(3) \
|
||||||
BUILD_TYPE=ef \
|
BUILD_TYPE=ef \
|
||||||
TCHAIN_PREFIX="$(ARM_SDK_PREFIX)" \
|
TCHAIN_PREFIX="$(ARM_SDK_PREFIX)" \
|
||||||
DFU_CMD="$(DFUUTIL_DIR)/bin/dfu-util" \
|
DFU_CMD="$(DFUUTIL_DIR)/bin/dfu-util" \
|
||||||
|
\
|
||||||
|
TARGET=ef_$(1) \
|
||||||
|
OUTDIR=$(BUILD_DIR)/ef_$(1) \
|
||||||
|
\
|
||||||
$$*
|
$$*
|
||||||
|
|
||||||
.PHONY: ef_$(1)_clean
|
.PHONY: ef_$(1)_clean
|
||||||
@ -906,12 +678,6 @@ BL_BOARDS := $(filter-out simposix, $(BL_BOARDS))
|
|||||||
BU_BOARDS := $(filter-out simposix, $(BU_BOARDS))
|
BU_BOARDS := $(filter-out simposix, $(BU_BOARDS))
|
||||||
EF_BOARDS := $(filter-out simposix, $(EF_BOARDS))
|
EF_BOARDS := $(filter-out simposix, $(EF_BOARDS))
|
||||||
|
|
||||||
# SimPosix doesn't have a BL, BU or EF target so we need to
|
|
||||||
# filter them out to prevent errors on the all_flight target.
|
|
||||||
BL_BOARDS := $(filter-out simposix, $(BL_BOARDS))
|
|
||||||
BU_BOARDS := $(filter-out simposix, $(BU_BOARDS))
|
|
||||||
EF_BOARDS := $(filter-out simposix, $(EF_BOARDS))
|
|
||||||
|
|
||||||
# Generate the targets for whatever boards are left in each list
|
# Generate the targets for whatever boards are left in each list
|
||||||
FW_TARGETS := $(addprefix fw_, $(FW_BOARDS))
|
FW_TARGETS := $(addprefix fw_, $(FW_BOARDS))
|
||||||
BL_TARGETS := $(addprefix bl_, $(BL_BOARDS))
|
BL_TARGETS := $(addprefix bl_, $(BL_BOARDS))
|
||||||
@ -959,7 +725,7 @@ sim_win32: sim_win32_exe
|
|||||||
sim_win32_%: uavobjects_flight
|
sim_win32_%: uavobjects_flight
|
||||||
$(V1) mkdir -p $(BUILD_DIR)/sitl_win32
|
$(V1) mkdir -p $(BUILD_DIR)/sitl_win32
|
||||||
$(V1) $(MAKE) --no-print-directory \
|
$(V1) $(MAKE) --no-print-directory \
|
||||||
-C $(ROOT_DIR)/flight/OpenPilot --file=$(ROOT_DIR)/flight/OpenPilot/Makefile.win32 $*
|
-C $(ROOT_DIR)/flight/targets/OpenPilot --file=$(ROOT_DIR)/flight/targets/OpenPilot/Makefile.win32 $*
|
||||||
|
|
||||||
.PHONY: sim_osx
|
.PHONY: sim_osx
|
||||||
sim_osx: sim_osx_elf
|
sim_osx: sim_osx_elf
|
||||||
@ -967,7 +733,79 @@ sim_osx: sim_osx_elf
|
|||||||
sim_osx_%: uavobjects_flight
|
sim_osx_%: uavobjects_flight
|
||||||
$(V1) mkdir -p $(BUILD_DIR)/sim_osx
|
$(V1) mkdir -p $(BUILD_DIR)/sim_osx
|
||||||
$(V1) $(MAKE) --no-print-directory \
|
$(V1) $(MAKE) --no-print-directory \
|
||||||
-C $(ROOT_DIR)/flight/Revolution --file=$(ROOT_DIR)/flight/Revolution/Makefile.osx $*
|
-C $(ROOT_DIR)/flight/targets/Revolution --file=$(ROOT_DIR)/flight/targets/Revolution/Makefile.osx $*
|
||||||
|
|
||||||
|
|
||||||
|
##############################
|
||||||
|
#
|
||||||
|
# Unit Tests
|
||||||
|
#
|
||||||
|
##############################
|
||||||
|
|
||||||
|
ALL_UNITTESTS := logfs
|
||||||
|
|
||||||
|
UT_OUT_DIR := $(BUILD_DIR)/unit_tests
|
||||||
|
|
||||||
|
$(UT_OUT_DIR):
|
||||||
|
$(V1) mkdir -p $@
|
||||||
|
|
||||||
|
.PHONY: all_ut
|
||||||
|
all_ut: $(addsuffix _elf, $(addprefix ut_, $(ALL_UNITTESTS)))
|
||||||
|
|
||||||
|
.PHONY: all_ut_xml
|
||||||
|
all_ut_xml: $(addsuffix _xml, $(addprefix ut_, $(ALL_UNITTESTS)))
|
||||||
|
|
||||||
|
.PHONY: all_ut_run
|
||||||
|
all_ut_run: $(addsuffix _run, $(addprefix ut_, $(ALL_UNITTESTS)))
|
||||||
|
|
||||||
|
.PHONY: all_ut_clean
|
||||||
|
all_ut_clean:
|
||||||
|
$(V0) @echo " CLEAN $@"
|
||||||
|
$(V1) [ ! -d "$(UT_OUT_DIR)" ] || $(RM) -r "$(UT_OUT_DIR)"
|
||||||
|
|
||||||
|
# $(1) = Unit test name
|
||||||
|
define UT_TEMPLATE
|
||||||
|
.PHONY: ut_$(1)
|
||||||
|
ut_$(1): ut_$(1)_run
|
||||||
|
|
||||||
|
ut_$(1)_%: $$(UT_OUT_DIR)
|
||||||
|
$(V1) mkdir -p $(UT_OUT_DIR)/$(1)
|
||||||
|
$(V1) cd $(ROOT_DIR)/flight/tests/$(1) && \
|
||||||
|
$$(MAKE) -r --no-print-directory \
|
||||||
|
BUILD_TYPE=ut \
|
||||||
|
BOARD_SHORT_NAME=$(1) \
|
||||||
|
TCHAIN_PREFIX="" \
|
||||||
|
REMOVE_CMD="$(RM)" \
|
||||||
|
\
|
||||||
|
TARGET=$(1) \
|
||||||
|
OUTDIR="$(UT_OUT_DIR)/$(1)" \
|
||||||
|
\
|
||||||
|
PIOS=$(PIOS) \
|
||||||
|
OPUAVOBJ=$(OPUAVOBJ) \
|
||||||
|
OPUAVTALK=$(OPUAVTALK) \
|
||||||
|
FLIGHTLIB=$(FLIGHTLIB) \
|
||||||
|
\
|
||||||
|
GTEST_DIR=$(GTEST_DIR) \
|
||||||
|
\
|
||||||
|
$$*
|
||||||
|
|
||||||
|
.PHONY: ut_$(1)_clean
|
||||||
|
ut_$(1)_clean:
|
||||||
|
$(V0) @echo " CLEAN $(1)"
|
||||||
|
$(V1) [ ! -d "$(UT_OUT_DIR)/$(1)" ] || $(RM) -r "$(UT_OUT_DIR)/$(1)"
|
||||||
|
|
||||||
|
endef
|
||||||
|
|
||||||
|
# Expand the unittest rules
|
||||||
|
$(foreach ut, $(ALL_UNITTESTS), $(eval $(call UT_TEMPLATE,$(ut))))
|
||||||
|
|
||||||
|
# Disable parallel make when the all_ut_run target is requested otherwise the TAP
|
||||||
|
# output is interleaved with the rest of the make output.
|
||||||
|
ifneq ($(strip $(filter all_ut_run,$(MAKECMDGOALS))),)
|
||||||
|
.NOTPARALLEL:
|
||||||
|
$(info *NOTE* Parallel make disabled by all_ut_run target so we have sane console output)
|
||||||
|
endif
|
||||||
|
|
||||||
##############################
|
##############################
|
||||||
#
|
#
|
||||||
# Packaging components
|
# Packaging components
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
/**
|
/**
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* @addtogroup PIOS PIOS Core hardware abstraction layer
|
* @addtogroup OpenPilotSystem OpenPilot System
|
||||||
* @{
|
* @{
|
||||||
* @addtogroup PIOS_CRC CRC Functions
|
* @addtogroup OpenPilotLibraries OpenPilot System Libraries
|
||||||
* @{
|
* @{
|
||||||
*
|
* @file sanitycheck.h
|
||||||
* @file pios_crc.h
|
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012.
|
||||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
* @brief Utilities to validate a flight configuration
|
||||||
* @brief CRC functions header.
|
|
||||||
* @see The GNU Public License (GPL) Version 3
|
* @see The GNU Public License (GPL) Version 3
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
@ -27,5 +26,9 @@
|
|||||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
uint8_t PIOS_CRC_updateByte(uint8_t crc, const uint8_t data);
|
#ifndef SANITYCHECK_H
|
||||||
uint8_t PIOS_CRC_updateCRC(uint8_t crc, const uint8_t* data, int32_t length);
|
#define SANITYCHECK_H
|
||||||
|
|
||||||
|
extern int32_t configuration_check();
|
||||||
|
|
||||||
|
#endif /* SANITYCHECK_H */
|
@ -33,6 +33,7 @@
|
|||||||
int32_t TaskMonitorInitialize(void);
|
int32_t TaskMonitorInitialize(void);
|
||||||
int32_t TaskMonitorAdd(TaskInfoRunningElem task, xTaskHandle handle);
|
int32_t TaskMonitorAdd(TaskInfoRunningElem task, xTaskHandle handle);
|
||||||
int32_t TaskMonitorRemove(TaskInfoRunningElem task);
|
int32_t TaskMonitorRemove(TaskInfoRunningElem task);
|
||||||
|
bool TaskMonitorQueryRunning(TaskInfoRunningElem task);
|
||||||
void TaskMonitorUpdateAll(void);
|
void TaskMonitorUpdateAll(void);
|
||||||
|
|
||||||
#endif // TASKMONITOR_H
|
#endif // TASKMONITOR_H
|
||||||
|
189
flight/Libraries/sanitycheck.c
Normal file
189
flight/Libraries/sanitycheck.c
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @addtogroup OpenPilot System OpenPilot System
|
||||||
|
* @{
|
||||||
|
* @addtogroup OpenPilot Libraries OpenPilot System Libraries
|
||||||
|
* @{
|
||||||
|
* @file sanitycheck.c
|
||||||
|
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012.
|
||||||
|
* @brief Utilities to validate a flight configuration
|
||||||
|
* @see The GNU Public License (GPL) Version 3
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
/*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "openpilot.h"
|
||||||
|
#include "taskmonitor.h"
|
||||||
|
#include <pios_board_info.h>
|
||||||
|
#include "sanitycheck.h"
|
||||||
|
#include "manualcontrolsettings.h"
|
||||||
|
#include "systemalarms.h"
|
||||||
|
#include "systemsettings.h"
|
||||||
|
|
||||||
|
/****************************
|
||||||
|
* Current checks:
|
||||||
|
* 1. If a flight mode switch allows autotune and autotune module not running
|
||||||
|
* 2. If airframe is a multirotor and either manual is available or a stabilization mode uses "none"
|
||||||
|
****************************/
|
||||||
|
|
||||||
|
//! Check a stabilization mode switch position for safety
|
||||||
|
static int32_t check_stabilization_settings(int index, bool multirotor);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run a preflight check over the hardware configuration
|
||||||
|
* and currently active modules
|
||||||
|
*/
|
||||||
|
int32_t configuration_check()
|
||||||
|
{
|
||||||
|
int32_t status = SYSTEMALARMS_ALARM_OK;
|
||||||
|
|
||||||
|
// Get board type
|
||||||
|
const struct pios_board_info * bdinfo = &pios_board_info_blob;
|
||||||
|
bool coptercontrol = bdinfo->board_type == 0x04;
|
||||||
|
|
||||||
|
// Classify airframe type
|
||||||
|
bool multirotor = true;
|
||||||
|
uint8_t airframe_type;
|
||||||
|
SystemSettingsAirframeTypeGet(&airframe_type);
|
||||||
|
switch(airframe_type) {
|
||||||
|
case SYSTEMSETTINGS_AIRFRAMETYPE_QUADX:
|
||||||
|
case SYSTEMSETTINGS_AIRFRAMETYPE_QUADP:
|
||||||
|
case SYSTEMSETTINGS_AIRFRAMETYPE_HEXA:
|
||||||
|
case SYSTEMSETTINGS_AIRFRAMETYPE_OCTO:
|
||||||
|
case SYSTEMSETTINGS_AIRFRAMETYPE_HEXAX:
|
||||||
|
case SYSTEMSETTINGS_AIRFRAMETYPE_OCTOV:
|
||||||
|
case SYSTEMSETTINGS_AIRFRAMETYPE_OCTOCOAXP:
|
||||||
|
case SYSTEMSETTINGS_AIRFRAMETYPE_HEXACOAX:
|
||||||
|
case SYSTEMSETTINGS_AIRFRAMETYPE_TRI:
|
||||||
|
multirotor = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
multirotor = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// For each available flight mode position sanity check the available
|
||||||
|
// modes
|
||||||
|
uint8_t num_modes;
|
||||||
|
uint8_t modes[MANUALCONTROLSETTINGS_FLIGHTMODEPOSITION_NUMELEM];
|
||||||
|
ManualControlSettingsFlightModeNumberGet(&num_modes);
|
||||||
|
ManualControlSettingsFlightModePositionGet(modes);
|
||||||
|
|
||||||
|
for(uint32_t i = 0; i < num_modes; i++) {
|
||||||
|
switch(modes[i]) {
|
||||||
|
case MANUALCONTROLSETTINGS_FLIGHTMODEPOSITION_MANUAL:
|
||||||
|
if (multirotor)
|
||||||
|
status = SYSTEMALARMS_ALARM_ERROR;
|
||||||
|
break;
|
||||||
|
case MANUALCONTROLSETTINGS_FLIGHTMODEPOSITION_STABILIZED1:
|
||||||
|
status = (status == SYSTEMALARMS_ALARM_OK) ? check_stabilization_settings(1, multirotor) : status;
|
||||||
|
break;
|
||||||
|
case MANUALCONTROLSETTINGS_FLIGHTMODEPOSITION_STABILIZED2:
|
||||||
|
status = (status == SYSTEMALARMS_ALARM_OK) ? check_stabilization_settings(2, multirotor) : status;
|
||||||
|
break;
|
||||||
|
case MANUALCONTROLSETTINGS_FLIGHTMODEPOSITION_STABILIZED3:
|
||||||
|
status = (status == SYSTEMALARMS_ALARM_OK) ? check_stabilization_settings(3, multirotor) : status;
|
||||||
|
break;
|
||||||
|
case MANUALCONTROLSETTINGS_FLIGHTMODEPOSITION_AUTOTUNE:
|
||||||
|
if (!TaskMonitorQueryRunning(TASKINFO_RUNNING_AUTOTUNE))
|
||||||
|
status = SYSTEMALARMS_ALARM_ERROR;
|
||||||
|
break;
|
||||||
|
case MANUALCONTROLSETTINGS_FLIGHTMODEPOSITION_ALTITUDEHOLD:
|
||||||
|
if (coptercontrol)
|
||||||
|
status = SYSTEMALARMS_ALARM_ERROR;
|
||||||
|
else {
|
||||||
|
// Revo supports altitude hold
|
||||||
|
if (!TaskMonitorQueryRunning(TASKINFO_RUNNING_ALTITUDEHOLD))
|
||||||
|
status = SYSTEMALARMS_ALARM_ERROR;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MANUALCONTROLSETTINGS_FLIGHTMODEPOSITION_VELOCITYCONTROL:
|
||||||
|
if (coptercontrol)
|
||||||
|
status = SYSTEMALARMS_ALARM_ERROR;
|
||||||
|
else {
|
||||||
|
// Revo supports altitude hold
|
||||||
|
if (!TaskMonitorQueryRunning(TASKINFO_RUNNING_PATHFOLLOWER))
|
||||||
|
status = SYSTEMALARMS_ALARM_ERROR;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MANUALCONTROLSETTINGS_FLIGHTMODEPOSITION_POSITIONHOLD:
|
||||||
|
if (coptercontrol)
|
||||||
|
status = SYSTEMALARMS_ALARM_ERROR;
|
||||||
|
else {
|
||||||
|
// Revo supports altitude hold
|
||||||
|
if (!TaskMonitorQueryRunning(TASKINFO_RUNNING_PATHFOLLOWER))
|
||||||
|
status = SYSTEMALARMS_ALARM_ERROR;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Uncovered modes are automatically an error
|
||||||
|
status = SYSTEMALARMS_ALARM_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Check on a multirotor no axis supports "None"
|
||||||
|
if(status != SYSTEMALARMS_ALARM_OK)
|
||||||
|
AlarmsSet(SYSTEMALARMS_ALARM_SYSTEMCONFIGURATION, status);
|
||||||
|
else
|
||||||
|
AlarmsClear(SYSTEMALARMS_ALARM_SYSTEMCONFIGURATION);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks the stabiliation settings for a paritcular mode and makes
|
||||||
|
* sure it is appropriate for the airframe
|
||||||
|
* @param[in] index Which stabilization mode to check
|
||||||
|
* @returns SYSTEMALARMS_ALARM_OK or SYSTEMALARMS_ALARM_ERROR
|
||||||
|
*/
|
||||||
|
static int32_t check_stabilization_settings(int index, bool multirotor)
|
||||||
|
{
|
||||||
|
// Make sure the modes have identical sizes
|
||||||
|
if (MANUALCONTROLSETTINGS_STABILIZATION1SETTINGS_NUMELEM != MANUALCONTROLSETTINGS_STABILIZATION2SETTINGS_NUMELEM ||
|
||||||
|
MANUALCONTROLSETTINGS_STABILIZATION1SETTINGS_NUMELEM != MANUALCONTROLSETTINGS_STABILIZATION3SETTINGS_NUMELEM)
|
||||||
|
return SYSTEMALARMS_ALARM_ERROR;
|
||||||
|
|
||||||
|
uint8_t modes[MANUALCONTROLSETTINGS_STABILIZATION1SETTINGS_NUMELEM];
|
||||||
|
|
||||||
|
// Get the different axis modes for this switch position
|
||||||
|
switch(index) {
|
||||||
|
case 1:
|
||||||
|
ManualControlSettingsStabilization1SettingsGet(modes);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
ManualControlSettingsStabilization2SettingsGet(modes);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
ManualControlSettingsStabilization3SettingsGet(modes);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return SYSTEMALARMS_ALARM_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// For multirotors verify that nothing is set to "none"
|
||||||
|
if (multirotor) {
|
||||||
|
for(uint32_t i = 0; i < NELEMENTS(modes); i++) {
|
||||||
|
if (modes[i] == MANUALCONTROLSETTINGS_STABILIZATION1SETTINGS_NONE)
|
||||||
|
return SYSTEMALARMS_ALARM_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Warning: This assumes that certain conditions in the XML file are met. That
|
||||||
|
// MANUALCONTROLSETTINGS_STABILIZATION1SETTINGS_NONE has the same numeric value for each channel
|
||||||
|
// and is the same for STABILIZATIONDESIRED_STABILIZATIONMODE_NONE
|
||||||
|
|
||||||
|
return SYSTEMALARMS_ALARM_OK;
|
||||||
|
}
|
@ -89,6 +89,16 @@ int32_t TaskMonitorRemove(TaskInfoRunningElem task)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Query if a task is running
|
||||||
|
*/
|
||||||
|
bool TaskMonitorQueryRunning(TaskInfoRunningElem task)
|
||||||
|
{
|
||||||
|
if (task < TASKINFO_RUNNING_NUMELEM && handles[task] != 0)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the status of all tasks
|
* Update the status of all tasks
|
||||||
*/
|
*/
|
||||||
|
@ -48,7 +48,8 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "pios.h"
|
#include "openpilot.h"
|
||||||
|
|
||||||
#include "flightstatus.h"
|
#include "flightstatus.h"
|
||||||
#include "hwsettings.h"
|
#include "hwsettings.h"
|
||||||
#include "manualcontrolcommand.h"
|
#include "manualcontrolcommand.h"
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
#include "baroaltitude.h"
|
#include "baroaltitude.h"
|
||||||
#include "flighttelemetrystats.h"
|
#include "flighttelemetrystats.h"
|
||||||
#include "flightstatus.h"
|
#include "flightstatus.h"
|
||||||
|
#include "sanitycheck.h"
|
||||||
#include "manualcontrol.h"
|
#include "manualcontrol.h"
|
||||||
#include "manualcontrolsettings.h"
|
#include "manualcontrolsettings.h"
|
||||||
#include "manualcontrolcommand.h"
|
#include "manualcontrolcommand.h"
|
||||||
@ -48,6 +49,7 @@
|
|||||||
#include "stabilizationsettings.h"
|
#include "stabilizationsettings.h"
|
||||||
#include "stabilizationdesired.h"
|
#include "stabilizationdesired.h"
|
||||||
#include "receiveractivity.h"
|
#include "receiveractivity.h"
|
||||||
|
#include "systemsettings.h"
|
||||||
|
|
||||||
#if defined(PIOS_INCLUDE_USB_RCTX)
|
#if defined(PIOS_INCLUDE_USB_RCTX)
|
||||||
#include "pios_usb_rctx.h"
|
#include "pios_usb_rctx.h"
|
||||||
@ -96,6 +98,7 @@ static void updatePathDesired(ManualControlCommandData * cmd, bool changed, bool
|
|||||||
static void processFlightMode(ManualControlSettingsData * settings, float flightMode);
|
static void processFlightMode(ManualControlSettingsData * settings, float flightMode);
|
||||||
static void processArm(ManualControlCommandData * cmd, ManualControlSettingsData * settings);
|
static void processArm(ManualControlCommandData * cmd, ManualControlSettingsData * settings);
|
||||||
static void setArmedIfChanged(uint8_t val);
|
static void setArmedIfChanged(uint8_t val);
|
||||||
|
static void configurationUpdatedCb(UAVObjEvent * ev);
|
||||||
|
|
||||||
static void manualControlTask(void *parameters);
|
static void manualControlTask(void *parameters);
|
||||||
static float scaleChannel(int16_t value, int16_t max, int16_t min, int16_t neutral);
|
static float scaleChannel(int16_t value, int16_t max, int16_t min, int16_t neutral);
|
||||||
@ -174,6 +177,15 @@ static void manualControlTask(void *parameters)
|
|||||||
AccessoryDesiredCreateInstance();
|
AccessoryDesiredCreateInstance();
|
||||||
AccessoryDesiredCreateInstance();
|
AccessoryDesiredCreateInstance();
|
||||||
|
|
||||||
|
// Run this initially to make sure the configuration is checked
|
||||||
|
configuration_check();
|
||||||
|
|
||||||
|
// Whenever the configuration changes, make sure it is safe to fly
|
||||||
|
SystemSettingsConnectCallback(configurationUpdatedCb);
|
||||||
|
ManualControlSettingsConnectCallback(configurationUpdatedCb);
|
||||||
|
|
||||||
|
// Whenever the configuration changes, make sure it is safe to fly
|
||||||
|
|
||||||
// Make sure unarmed on power up
|
// Make sure unarmed on power up
|
||||||
ManualControlCommandGet(&cmd);
|
ManualControlCommandGet(&cmd);
|
||||||
FlightStatusGet(&flightStatus);
|
FlightStatusGet(&flightStatus);
|
||||||
@ -1076,6 +1088,16 @@ static void applyLPF(float *value, ManualControlSettingsResponseTimeElem channel
|
|||||||
}
|
}
|
||||||
#endif // USE_INPUT_LPF
|
#endif // USE_INPUT_LPF
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called whenever a critical configuration component changes
|
||||||
|
*/
|
||||||
|
static void configurationUpdatedCb(UAVObjEvent * ev)
|
||||||
|
{
|
||||||
|
configuration_check();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
* @}
|
* @}
|
||||||
|
@ -46,7 +46,8 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "pios.h"
|
#include "openpilot.h"
|
||||||
|
|
||||||
#include "homelocation.h"
|
#include "homelocation.h"
|
||||||
#include "magnetometer.h"
|
#include "magnetometer.h"
|
||||||
#include "magbias.h"
|
#include "magbias.h"
|
||||||
|
@ -48,6 +48,7 @@
|
|||||||
#include "taskinfo.h"
|
#include "taskinfo.h"
|
||||||
#include "watchdogstatus.h"
|
#include "watchdogstatus.h"
|
||||||
#include "taskmonitor.h"
|
#include "taskmonitor.h"
|
||||||
|
#include "hwsettings.h"
|
||||||
|
|
||||||
//#define DEBUG_THIS_FILE
|
//#define DEBUG_THIS_FILE
|
||||||
|
|
||||||
@ -87,6 +88,7 @@ static bool mallocFailed;
|
|||||||
|
|
||||||
// Private functions
|
// Private functions
|
||||||
static void objectUpdatedCb(UAVObjEvent * ev);
|
static void objectUpdatedCb(UAVObjEvent * ev);
|
||||||
|
static void hwSettingsUpdatedCb(UAVObjEvent * ev);
|
||||||
static void updateStats();
|
static void updateStats();
|
||||||
static void updateSystemAlarms();
|
static void updateSystemAlarms();
|
||||||
static void systemTask(void *parameters);
|
static void systemTask(void *parameters);
|
||||||
@ -169,6 +171,9 @@ static void systemTask(void *parameters)
|
|||||||
// Listen for SettingPersistance object updates, connect a callback function
|
// Listen for SettingPersistance object updates, connect a callback function
|
||||||
ObjectPersistenceConnectQueue(objectPersistenceQueue);
|
ObjectPersistenceConnectQueue(objectPersistenceQueue);
|
||||||
|
|
||||||
|
// Whenever the configuration changes, make sure it is safe to fly
|
||||||
|
HwSettingsConnectCallback(hwSettingsUpdatedCb);
|
||||||
|
|
||||||
// Main system loop
|
// Main system loop
|
||||||
while (1) {
|
while (1) {
|
||||||
// Update the system statistics
|
// Update the system statistics
|
||||||
@ -300,7 +305,7 @@ static void objectUpdatedCb(UAVObjEvent * ev)
|
|||||||
} else if (objper.Operation == OBJECTPERSISTENCE_OPERATION_FULLERASE) {
|
} else if (objper.Operation == OBJECTPERSISTENCE_OPERATION_FULLERASE) {
|
||||||
retval = -1;
|
retval = -1;
|
||||||
#if defined(PIOS_INCLUDE_FLASH_SECTOR_SETTINGS)
|
#if defined(PIOS_INCLUDE_FLASH_SECTOR_SETTINGS)
|
||||||
retval = PIOS_FLASHFS_Format();
|
retval = PIOS_FLASHFS_Format(0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
switch(retval) {
|
switch(retval) {
|
||||||
@ -318,6 +323,14 @@ static void objectUpdatedCb(UAVObjEvent * ev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called whenever hardware settings changed
|
||||||
|
*/
|
||||||
|
static void hwSettingsUpdatedCb(UAVObjEvent * ev)
|
||||||
|
{
|
||||||
|
AlarmsSet(SYSTEMALARMS_ALARM_BOOTFAULT,SYSTEMALARMS_ALARM_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called periodically to update the I2C statistics
|
* Called periodically to update the I2C statistics
|
||||||
*/
|
*/
|
||||||
|
@ -1,120 +0,0 @@
|
|||||||
/**
|
|
||||||
******************************************************************************
|
|
||||||
* @addtogroup PIOS PIOS Core hardware abstraction layer
|
|
||||||
* @{
|
|
||||||
* @addtogroup PIOS_USB_BOARD Board specific USB definitions
|
|
||||||
* @brief Board specific USB definitions
|
|
||||||
* @{
|
|
||||||
*
|
|
||||||
* @file pios_usb_board_data.c
|
|
||||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
|
||||||
* @brief Board specific USB definitions
|
|
||||||
* @see The GNU Public License (GPL) Version 3
|
|
||||||
*
|
|
||||||
*****************************************************************************/
|
|
||||||
/*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "pios_usb_board_data.h" /* struct usb_*, USB_* */
|
|
||||||
#include "pios_sys.h" /* PIOS_SYS_SerialNumberGet */
|
|
||||||
#include "pios_usbhook.h" /* PIOS_USBHOOK_* */
|
|
||||||
|
|
||||||
static const uint8_t usb_product_id[20] = {
|
|
||||||
sizeof(usb_product_id),
|
|
||||||
USB_DESC_TYPE_STRING,
|
|
||||||
'O', 0,
|
|
||||||
'p', 0,
|
|
||||||
'e', 0,
|
|
||||||
'n', 0,
|
|
||||||
'P', 0,
|
|
||||||
'i', 0,
|
|
||||||
'l', 0,
|
|
||||||
'o', 0,
|
|
||||||
't', 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
static uint8_t usb_serial_number[52] = {
|
|
||||||
sizeof(usb_serial_number),
|
|
||||||
USB_DESC_TYPE_STRING,
|
|
||||||
0, 0,
|
|
||||||
0, 0,
|
|
||||||
0, 0,
|
|
||||||
0, 0,
|
|
||||||
0, 0,
|
|
||||||
0, 0,
|
|
||||||
0, 0,
|
|
||||||
0, 0,
|
|
||||||
0, 0,
|
|
||||||
0, 0,
|
|
||||||
0, 0,
|
|
||||||
0, 0,
|
|
||||||
0, 0,
|
|
||||||
0, 0,
|
|
||||||
0, 0,
|
|
||||||
0, 0,
|
|
||||||
0, 0,
|
|
||||||
0, 0,
|
|
||||||
0, 0,
|
|
||||||
0, 0,
|
|
||||||
0, 0,
|
|
||||||
0, 0,
|
|
||||||
0, 0,
|
|
||||||
0, 0,
|
|
||||||
0, 0
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct usb_string_langid usb_lang_id = {
|
|
||||||
.bLength = sizeof(usb_lang_id),
|
|
||||||
.bDescriptorType = USB_DESC_TYPE_STRING,
|
|
||||||
.bLangID = htousbs(USB_LANGID_ENGLISH_UK),
|
|
||||||
};
|
|
||||||
|
|
||||||
static const uint8_t usb_vendor_id[28] = {
|
|
||||||
sizeof(usb_vendor_id),
|
|
||||||
USB_DESC_TYPE_STRING,
|
|
||||||
'o', 0,
|
|
||||||
'p', 0,
|
|
||||||
'e', 0,
|
|
||||||
'n', 0,
|
|
||||||
'p', 0,
|
|
||||||
'i', 0,
|
|
||||||
'l', 0,
|
|
||||||
'o', 0,
|
|
||||||
't', 0,
|
|
||||||
'.', 0,
|
|
||||||
'o', 0,
|
|
||||||
'r', 0,
|
|
||||||
'g', 0
|
|
||||||
};
|
|
||||||
|
|
||||||
int32_t PIOS_USB_BOARD_DATA_Init(void)
|
|
||||||
{
|
|
||||||
/* Load device serial number into serial number string */
|
|
||||||
uint8_t sn[25];
|
|
||||||
PIOS_SYS_SerialNumberGet((char *)sn);
|
|
||||||
for (uint8_t i = 0; sn[i] != '\0' && (2 * i) < usb_serial_number[0]; i++) {
|
|
||||||
usb_serial_number[2 + 2 * i] = sn[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
PIOS_USBHOOK_RegisterString(USB_STRING_DESC_PRODUCT, (uint8_t *)&usb_product_id, sizeof(usb_product_id));
|
|
||||||
PIOS_USBHOOK_RegisterString(USB_STRING_DESC_SERIAL, (uint8_t *)&usb_serial_number, sizeof(usb_serial_number));
|
|
||||||
|
|
||||||
PIOS_USBHOOK_RegisterString(USB_STRING_DESC_LANG, (uint8_t *)&usb_lang_id, sizeof(usb_lang_id));
|
|
||||||
PIOS_USBHOOK_RegisterString(USB_STRING_DESC_VENDOR, (uint8_t *)&usb_vendor_id, sizeof(usb_vendor_id));
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
|||||||
#ifndef PIOS_BOARD_H_
|
|
||||||
#define PIOS_BOARD_H_
|
|
||||||
|
|
||||||
#ifdef USE_SIM_POSIX
|
|
||||||
#include "sim_posix.h"
|
|
||||||
#else
|
|
||||||
#error Board definition has not been provided.
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* PIOS_BOARD_H_ */
|
|
@ -1,66 +0,0 @@
|
|||||||
/**
|
|
||||||
******************************************************************************
|
|
||||||
* @addtogroup PIOS PIOS Core hardware abstraction layer
|
|
||||||
* @{
|
|
||||||
* @addtogroup PIOS_COM COM layer functions
|
|
||||||
* @brief Hardware communication layer
|
|
||||||
* @{
|
|
||||||
*
|
|
||||||
* @file pios_com.h
|
|
||||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
|
||||||
* Parts by Thorsten Klose (tk@midibox.org)
|
|
||||||
* @brief COM layer functions header
|
|
||||||
* @see The GNU Public License (GPL) Version 3
|
|
||||||
*
|
|
||||||
*****************************************************************************/
|
|
||||||
/*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef PIOS_COM_H
|
|
||||||
#define PIOS_COM_H
|
|
||||||
|
|
||||||
typedef uint16_t (*pios_com_callback)(uint32_t context, uint8_t * buf, uint16_t buf_len, uint16_t * headroom, bool * task_woken);
|
|
||||||
|
|
||||||
struct pios_com_driver {
|
|
||||||
void (*init)(uint32_t id);
|
|
||||||
void (*set_baud)(uint32_t id, uint32_t baud);
|
|
||||||
void (*tx_start)(uint32_t id, uint16_t tx_bytes_avail);
|
|
||||||
void (*rx_start)(uint32_t id, uint16_t rx_bytes_avail);
|
|
||||||
void (*bind_rx_cb)(uint32_t id, pios_com_callback rx_in_cb, uint32_t context);
|
|
||||||
void (*bind_tx_cb)(uint32_t id, pios_com_callback tx_out_cb, uint32_t context);
|
|
||||||
bool (*available)(uint32_t id);
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Public Functions */
|
|
||||||
extern int32_t PIOS_COM_Init(uint32_t * com_id, const struct pios_com_driver * driver, uint32_t lower_id, uint8_t * rx_buffer, uint16_t rx_buffer_len, uint8_t * tx_buffer, uint16_t tx_buffer_len);
|
|
||||||
extern int32_t PIOS_COM_ChangeBaud(uint32_t com_id, uint32_t baud);
|
|
||||||
extern int32_t PIOS_COM_SendCharNonBlocking(uint32_t com_id, char c);
|
|
||||||
extern int32_t PIOS_COM_SendChar(uint32_t com_id, char c);
|
|
||||||
extern int32_t PIOS_COM_SendBufferNonBlocking(uint32_t com_id, const uint8_t *buffer, uint16_t len);
|
|
||||||
extern int32_t PIOS_COM_SendBuffer(uint32_t com_id, const uint8_t *buffer, uint16_t len);
|
|
||||||
extern int32_t PIOS_COM_SendStringNonBlocking(uint32_t com_id, const char *str);
|
|
||||||
extern int32_t PIOS_COM_SendString(uint32_t com_id, const char *str);
|
|
||||||
extern int32_t PIOS_COM_SendFormattedStringNonBlocking(uint32_t com_id, const char *format, ...);
|
|
||||||
extern int32_t PIOS_COM_SendFormattedString(uint32_t com_id, const char *format, ...);
|
|
||||||
extern uint16_t PIOS_COM_ReceiveBuffer(uint32_t com_id, uint8_t * buf, uint16_t buf_len, uint32_t timeout_ms);
|
|
||||||
extern bool PIOS_COM_Available(uint32_t com_id);
|
|
||||||
|
|
||||||
#endif /* PIOS_COM_H */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
* @}
|
|
||||||
*/
|
|
@ -1,56 +0,0 @@
|
|||||||
/**
|
|
||||||
******************************************************************************
|
|
||||||
* @addtogroup PIOS PIOS Core hardware abstraction layer
|
|
||||||
* @{
|
|
||||||
* @defgroup PIOS_DEBUG Debugging Functions
|
|
||||||
* @brief Debugging functionality
|
|
||||||
* @{
|
|
||||||
*
|
|
||||||
* @file pios_i2c.h
|
|
||||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
|
||||||
* @brief Debug helper functions header.
|
|
||||||
* @see The GNU Public License (GPL) Version 3
|
|
||||||
*
|
|
||||||
*****************************************************************************/
|
|
||||||
/*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef PIOS_DEBUG_H
|
|
||||||
#define PIOS_DEBUG_H
|
|
||||||
|
|
||||||
extern const char *PIOS_DEBUG_AssertMsg;
|
|
||||||
|
|
||||||
void PIOS_DEBUG_Init(void);
|
|
||||||
void PIOS_DEBUG_PinHigh(uint8_t pin);
|
|
||||||
void PIOS_DEBUG_PinLow(uint8_t pin);
|
|
||||||
void PIOS_DEBUG_PinValue8Bit(uint8_t value);
|
|
||||||
void PIOS_DEBUG_PinValue4BitL(uint8_t value);
|
|
||||||
void PIOS_DEBUG_Panic(const char *msg);
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
#define PIOS_DEBUG_Assert(test) if (!(test)) PIOS_DEBUG_Panic(PIOS_DEBUG_AssertMsg);
|
|
||||||
#define PIOS_Assert(test) PIOS_DEBUG_Assert(test)
|
|
||||||
#else
|
|
||||||
#define PIOS_DEBUG_Assert(test)
|
|
||||||
#define PIOS_Assert(test) if (!(test)) while (1);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* PIOS_DEBUG_H */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
* @}
|
|
||||||
*/
|
|
@ -1,48 +0,0 @@
|
|||||||
/**
|
|
||||||
******************************************************************************
|
|
||||||
* @addtogroup PIOS PIOS Core hardware abstraction layer
|
|
||||||
* @{
|
|
||||||
* @addtogroup PIOS_DELAY Delay Functions
|
|
||||||
* @brief PiOS Delay functionality
|
|
||||||
* @{
|
|
||||||
*
|
|
||||||
* @file pios_settings.h
|
|
||||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
|
||||||
* @brief Settings functions header
|
|
||||||
* @see The GNU Public License (GPL) Version 3
|
|
||||||
*
|
|
||||||
*****************************************************************************/
|
|
||||||
/*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef PIOS_DELAY_H
|
|
||||||
#define PIOS_DELAY_H
|
|
||||||
|
|
||||||
/* Public Functions */
|
|
||||||
extern int32_t PIOS_DELAY_Init(void);
|
|
||||||
extern int32_t PIOS_DELAY_WaituS(uint32_t uS);
|
|
||||||
extern int32_t PIOS_DELAY_WaitmS(uint32_t mS);
|
|
||||||
extern uint32_t PIOS_DELAY_GetuS();
|
|
||||||
extern uint32_t PIOS_DELAY_GetuSSince(uint32_t t);
|
|
||||||
extern uint32_t PIOS_DELAY_GetRaw();
|
|
||||||
extern uint32_t PIOS_DELAY_DiffuS(uint32_t raw);
|
|
||||||
|
|
||||||
#endif /* PIOS_DELAY_H */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
* @}
|
|
||||||
*/
|
|
@ -1,72 +0,0 @@
|
|||||||
/**
|
|
||||||
******************************************************************************
|
|
||||||
* @addtogroup PIOS PIOS Initcall infrastructure
|
|
||||||
* @{
|
|
||||||
* @addtogroup PIOS_INITCALL Generic Initcall Macros
|
|
||||||
* @brief Initcall Macros
|
|
||||||
* @{
|
|
||||||
*
|
|
||||||
* @file pios_initcall.h
|
|
||||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2011.
|
|
||||||
* @brief Initcall header
|
|
||||||
* @see The GNU Public License (GPL) Version 3
|
|
||||||
*
|
|
||||||
*****************************************************************************/
|
|
||||||
/*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef PIOS_INITCALL_H
|
|
||||||
#define PIOS_INITCALL_H
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Just a stub define to make things compile.
|
|
||||||
* Automatically link based initialization currently doesn't work
|
|
||||||
* since posix really runs on a multitude of architectures
|
|
||||||
* and we cannot define a linker script for each of them atm
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
typedef int32_t (*initcall_t)(void);
|
|
||||||
typedef struct {
|
|
||||||
initcall_t fn_minit;
|
|
||||||
initcall_t fn_tinit;
|
|
||||||
} initmodule_t;
|
|
||||||
|
|
||||||
/* Init module section */
|
|
||||||
extern initmodule_t __module_initcall_start[], __module_initcall_end[];
|
|
||||||
|
|
||||||
extern void InitModules();
|
|
||||||
extern void StartModules();
|
|
||||||
|
|
||||||
#define MODULE_INITCALL(ifn, sfn)
|
|
||||||
|
|
||||||
#define MODULE_TASKCREATE_ALL { \
|
|
||||||
/* Start all module threads */ \
|
|
||||||
StartModules(); \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define MODULE_INITIALISE_ALL { \
|
|
||||||
/* Initialize modules */ \
|
|
||||||
InitModules(); \
|
|
||||||
/* Initialize the system thread */ \
|
|
||||||
SystemModInitialize();}
|
|
||||||
|
|
||||||
#endif /* PIOS_INITCALL_H */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
* @}
|
|
||||||
*/
|
|
@ -1,38 +0,0 @@
|
|||||||
/**
|
|
||||||
******************************************************************************
|
|
||||||
* @addtogroup PIOS PIOS Core hardware abstraction layer
|
|
||||||
* @{
|
|
||||||
* @addtogroup PIOS_IRQ IRQ Setup Functions
|
|
||||||
* @{
|
|
||||||
*
|
|
||||||
* @file pios_irq.h
|
|
||||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
|
||||||
* Parts by Thorsten Klose (tk@midibox.org)
|
|
||||||
* @brief IRQ functions header.
|
|
||||||
* @see The GNU Public License (GPL) Version 3
|
|
||||||
*
|
|
||||||
*****************************************************************************/
|
|
||||||
/*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef PIOS_IRQ_H
|
|
||||||
#define PIOS_IRQ_H
|
|
||||||
|
|
||||||
/* Public Functions */
|
|
||||||
extern int32_t PIOS_IRQ_Disable(void);
|
|
||||||
extern int32_t PIOS_IRQ_Enable(void);
|
|
||||||
|
|
||||||
#endif /* PIOS_IRQ_H */
|
|
@ -1,39 +0,0 @@
|
|||||||
/**
|
|
||||||
******************************************************************************
|
|
||||||
* @addtogroup PIOS PIOS Core hardware abstraction layer
|
|
||||||
* @{
|
|
||||||
* @addtogroup PIOS_LED LED Functions
|
|
||||||
* @{
|
|
||||||
*
|
|
||||||
* @file pios_led.h
|
|
||||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
|
||||||
* @brief LED functions header.
|
|
||||||
* @see The GNU Public License (GPL) Version 3
|
|
||||||
*
|
|
||||||
*****************************************************************************/
|
|
||||||
/*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef PIOS_LED_H
|
|
||||||
#define PIOS_LED_H
|
|
||||||
|
|
||||||
/* Public Functions */
|
|
||||||
extern void PIOS_LED_On(uint32_t led_id);
|
|
||||||
extern void PIOS_LED_Off(uint32_t led_id);
|
|
||||||
extern void PIOS_LED_Toggle(uint32_t led_id);
|
|
||||||
extern void PIOS_LED_Init();
|
|
||||||
|
|
||||||
#endif /* PIOS_LED_H */
|
|
@ -1,57 +0,0 @@
|
|||||||
/**
|
|
||||||
******************************************************************************
|
|
||||||
* @addtogroup PIOS PIOS Core hardware abstraction layer
|
|
||||||
* @{
|
|
||||||
* @addtogroup PIOS_RCVR RCVR layer functions
|
|
||||||
* @brief Hardware communication layer
|
|
||||||
* @{
|
|
||||||
*
|
|
||||||
* @file pios_rcvr.h
|
|
||||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
|
||||||
* @brief RCVR layer functions header
|
|
||||||
* @see The GNU Public License (GPL) Version 3
|
|
||||||
*
|
|
||||||
*****************************************************************************/
|
|
||||||
/*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef PIOS_RCVR_H
|
|
||||||
#define PIOS_RCVR_H
|
|
||||||
|
|
||||||
struct pios_rcvr_driver {
|
|
||||||
void (*init)(uint32_t id);
|
|
||||||
int32_t (*read)(uint32_t id, uint8_t channel);
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Public Functions */
|
|
||||||
extern int32_t PIOS_RCVR_Read(uint32_t rcvr_id, uint8_t channel);
|
|
||||||
|
|
||||||
/*! Define error codes for PIOS_RCVR_Get */
|
|
||||||
enum PIOS_RCVR_errors {
|
|
||||||
/*! Indicates that a failsafe condition or missing receiver detected for that channel */
|
|
||||||
PIOS_RCVR_TIMEOUT = 0,
|
|
||||||
/*! Channel is invalid for this driver (usually out of range supported) */
|
|
||||||
PIOS_RCVR_INVALID = -1,
|
|
||||||
/*! Indicates that the driver for this channel has not been initialized */
|
|
||||||
PIOS_RCVR_NODRIVER = -2
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* PIOS_RCVR_H */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
* @}
|
|
||||||
*/
|
|
@ -1,113 +0,0 @@
|
|||||||
/**
|
|
||||||
******************************************************************************
|
|
||||||
*
|
|
||||||
* @file pios_sdcard.h
|
|
||||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
|
||||||
* Parts by Thorsten Klose (tk@midibox.org)
|
|
||||||
* @brief System and hardware Init functions header.
|
|
||||||
* @see The GNU Public License (GPL) Version 3
|
|
||||||
*
|
|
||||||
*****************************************************************************/
|
|
||||||
/*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef PIOS_SDCARD_H
|
|
||||||
#define PIOS_SDCARD_H
|
|
||||||
|
|
||||||
#if defined(PIOS_INCLUDE_SDCARD)
|
|
||||||
|
|
||||||
/* Public Functions */
|
|
||||||
typedef struct {
|
|
||||||
uint8_t CSDStruct; /* CSD structure */
|
|
||||||
uint8_t SysSpecVersion; /* System specification version */
|
|
||||||
uint8_t Reserved1; /* Reserved */
|
|
||||||
uint8_t TAAC; /* Data read access-time 1 */
|
|
||||||
uint8_t NSAC; /* Data read access-time 2 in CLK cycles */
|
|
||||||
uint8_t MaxBusClkFrec; /* Max. bus clock frequency */
|
|
||||||
uint16_t CardComdClasses; /* Card command classes */
|
|
||||||
uint8_t RdBlockLen; /* Max. read data block length */
|
|
||||||
uint8_t PartBlockRead; /* Partial blocks for read allowed */
|
|
||||||
uint8_t WrBlockMisalign; /* Write block misalignment */
|
|
||||||
uint8_t RdBlockMisalign; /* Read block misalignment */
|
|
||||||
uint8_t DSRImpl; /* DSR implemented */
|
|
||||||
uint8_t Reserved2; /* Reserved */
|
|
||||||
uint16_t DeviceSize; /* Device Size */
|
|
||||||
uint8_t MaxRdCurrentVDDMin; /* Max. read current @ VDD min */
|
|
||||||
uint8_t MaxRdCurrentVDDMax; /* Max. read current @ VDD max */
|
|
||||||
uint8_t MaxWrCurrentVDDMin; /* Max. write current @ VDD min */
|
|
||||||
uint8_t MaxWrCurrentVDDMax; /* Max. write current @ VDD max */
|
|
||||||
uint8_t DeviceSizeMul; /* Device size multiplier */
|
|
||||||
uint8_t EraseGrSize; /* Erase group size */
|
|
||||||
uint8_t EraseGrMul; /* Erase group size multiplier */
|
|
||||||
uint8_t WrProtectGrSize; /* Write protect group size */
|
|
||||||
uint8_t WrProtectGrEnable; /* Write protect group enable */
|
|
||||||
uint8_t ManDeflECC; /* Manufacturer default ECC */
|
|
||||||
uint8_t WrSpeedFact; /* Write speed factor */
|
|
||||||
uint8_t MaxWrBlockLen; /* Max. write data block length */
|
|
||||||
uint8_t WriteBlockPaPartial; /* Partial blocks for write allowed */
|
|
||||||
uint8_t Reserved3; /* Reserved */
|
|
||||||
uint8_t ContentProtectAppli; /* Content protection application */
|
|
||||||
uint8_t FileFormatGrouop; /* File format group */
|
|
||||||
uint8_t CopyFlag; /* Copy flag (OTP) */
|
|
||||||
uint8_t PermWrProtect; /* Permanent write protection */
|
|
||||||
uint8_t TempWrProtect; /* Temporary write protection */
|
|
||||||
uint8_t FileFormat; /* File Format */
|
|
||||||
uint8_t ECC; /* ECC code */
|
|
||||||
uint8_t msd_CRC; /* CRC */
|
|
||||||
uint8_t Reserved4; /* always 1*/
|
|
||||||
} SDCARDCsdTypeDef;
|
|
||||||
|
|
||||||
/* Structure taken from Mass Storage Driver example provided by STM */
|
|
||||||
typedef struct {
|
|
||||||
uint8_t ManufacturerID; /* ManufacturerID */
|
|
||||||
uint16_t OEM_AppliID; /* OEM/Application ID */
|
|
||||||
char ProdName[6]; /* Product Name */
|
|
||||||
uint8_t ProdRev; /* Product Revision */
|
|
||||||
uint32_t ProdSN; /* Product Serial Number */
|
|
||||||
uint8_t Reserved1; /* Reserved1 */
|
|
||||||
uint16_t ManufactDate; /* Manufacturing Date */
|
|
||||||
uint8_t msd_CRC; /* CRC */
|
|
||||||
uint8_t Reserved2; /* always 1*/
|
|
||||||
} SDCARDCidTypeDef;
|
|
||||||
|
|
||||||
/* Global Variables */
|
|
||||||
//extern VOLINFO PIOS_SDCARD_VolInfo;
|
|
||||||
//extern uint8_t PIOS_SDCARD_Sector[SECTOR_SIZE];
|
|
||||||
|
|
||||||
/* Prototypes */
|
|
||||||
extern int32_t PIOS_SDCARD_Init(void);
|
|
||||||
extern int32_t PIOS_SDCARD_PowerOn(void);
|
|
||||||
extern int32_t PIOS_SDCARD_PowerOff(void);
|
|
||||||
extern int32_t PIOS_SDCARD_CheckAvailable(uint8_t was_available);
|
|
||||||
extern int32_t PIOS_SDCARD_SendSDCCmd(uint8_t cmd, uint32_t addr, uint8_t crc);
|
|
||||||
extern int32_t PIOS_SDCARD_SectorRead(uint32_t sector, uint8_t *buffer);
|
|
||||||
extern int32_t PIOS_SDCARD_SectorWrite(uint32_t sector, uint8_t *buffer);
|
|
||||||
extern int32_t PIOS_SDCARD_CIDRead(SDCARDCidTypeDef *cid);
|
|
||||||
extern int32_t PIOS_SDCARD_CSDRead(SDCARDCsdTypeDef *csd);
|
|
||||||
|
|
||||||
extern int32_t PIOS_SDCARD_StartupLog(void);
|
|
||||||
extern int32_t PIOS_SDCARD_IsMounted();
|
|
||||||
extern int32_t PIOS_SDCARD_MountFS(uint32_t StartupLog);
|
|
||||||
extern int32_t PIOS_SDCARD_GetFree(void);
|
|
||||||
|
|
||||||
//extern int32_t PIOS_SDCARD_ReadBuffer(PFILEINFO fileinfo, uint8_t *buffer, uint32_t len);
|
|
||||||
//extern int32_t PIOS_SDCARD_ReadLine(PFILEINFO fileinfo, uint8_t *buffer, uint32_t max_len);
|
|
||||||
extern int32_t PIOS_SDCARD_FileCopy(char *Source, char *Destination);
|
|
||||||
extern int32_t PIOS_SDCARD_FileDelete(char *Filename);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* PIOS_SDCARD_H */
|
|
@ -1,12 +0,0 @@
|
|||||||
/* Taken from include/linux/kernel.h from the Linux kernel tree */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* container_of - cast a member of a structure out to the containing structure
|
|
||||||
* @ptr: the pointer to the member.
|
|
||||||
* @type: the type of the container struct this is embedded in.
|
|
||||||
* @member: the name of the member within the struct.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#define container_of(ptr, type, member) ({ \
|
|
||||||
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
|
|
||||||
(type *)( (char *)__mptr - offsetof(type,member) );})
|
|
@ -1,35 +0,0 @@
|
|||||||
/**
|
|
||||||
******************************************************************************
|
|
||||||
*
|
|
||||||
* @file pios_sys.h
|
|
||||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
|
||||||
* Parts by Thorsten Klose (tk@midibox.org)
|
|
||||||
* @brief System and hardware Init functions header.
|
|
||||||
* @see The GNU Public License (GPL) Version 3
|
|
||||||
*
|
|
||||||
*****************************************************************************/
|
|
||||||
/*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef PIOS_SYS_H
|
|
||||||
#define PIOS_SYS_H
|
|
||||||
|
|
||||||
/* Public Functions */
|
|
||||||
extern void PIOS_SYS_Init(void);
|
|
||||||
extern int32_t PIOS_SYS_Reset(void);
|
|
||||||
extern int32_t PIOS_SYS_SerialNumberGet(char *str);
|
|
||||||
|
|
||||||
#endif /* PIOS_SYS_H */
|
|
@ -17,6 +17,8 @@
|
|||||||
#include "STM32F4xx_OSD.h"
|
#include "STM32F4xx_OSD.h"
|
||||||
#elif USE_STM32F4xx_RM
|
#elif USE_STM32F4xx_RM
|
||||||
#include "STM32F4xx_RevoMini.h"
|
#include "STM32F4xx_RevoMini.h"
|
||||||
|
#elif USE_SIM_POSIX
|
||||||
|
#include "sim_posix.h"
|
||||||
#else
|
#else
|
||||||
#error Board definition has not been provided.
|
#error Board definition has not been provided.
|
||||||
#endif
|
#endif
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
*
|
*
|
||||||
* @file pios_flash_w25x.c
|
* @file pios_flash_w25x.c
|
||||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||||
|
* @author PhoenixPilot, http://github.com/PhoenixPilot, Copyright (C) 2012
|
||||||
* @brief Driver for talking to W25X flash chip (and most JEDEC chips)
|
* @brief Driver for talking to W25X flash chip (and most JEDEC chips)
|
||||||
* @see The GNU Public License (GPL) Version 3
|
* @see The GNU Public License (GPL) Version 3
|
||||||
*
|
*
|
||||||
@ -28,6 +29,7 @@
|
|||||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
#include "pios.h"
|
#include "pios.h"
|
||||||
|
#include "pios_flash_jedec_priv.h"
|
||||||
|
|
||||||
#define JEDEC_WRITE_ENABLE 0x06
|
#define JEDEC_WRITE_ENABLE 0x06
|
||||||
#define JEDEC_WRITE_DISABLE 0x04
|
#define JEDEC_WRITE_DISABLE 0x04
|
||||||
@ -47,8 +49,6 @@
|
|||||||
#define JEDEC_STATUS_SEC 0x40
|
#define JEDEC_STATUS_SEC 0x40
|
||||||
#define JEDEC_STATUS_SRP0 0x80
|
#define JEDEC_STATUS_SRP0 0x80
|
||||||
|
|
||||||
static uint8_t device_type;
|
|
||||||
|
|
||||||
enum pios_jedec_dev_magic {
|
enum pios_jedec_dev_magic {
|
||||||
PIOS_JEDEC_DEV_MAGIC = 0xcb55aa55,
|
PIOS_JEDEC_DEV_MAGIC = 0xcb55aa55,
|
||||||
};
|
};
|
||||||
@ -58,8 +58,11 @@ struct jedec_flash_dev {
|
|||||||
uint32_t spi_id;
|
uint32_t spi_id;
|
||||||
uint32_t slave_num;
|
uint32_t slave_num;
|
||||||
bool claimed;
|
bool claimed;
|
||||||
uint32_t device_type;
|
|
||||||
uint32_t capacity;
|
uint8_t manufacturer;
|
||||||
|
uint8_t memorytype;
|
||||||
|
uint8_t capacity;
|
||||||
|
|
||||||
const struct pios_flash_jedec_cfg * cfg;
|
const struct pios_flash_jedec_cfg * cfg;
|
||||||
#if defined(FLASH_FREERTOS)
|
#if defined(FLASH_FREERTOS)
|
||||||
xSemaphoreHandle transaction_lock;
|
xSemaphoreHandle transaction_lock;
|
||||||
@ -67,58 +70,82 @@ struct jedec_flash_dev {
|
|||||||
enum pios_jedec_dev_magic magic;
|
enum pios_jedec_dev_magic magic;
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Global structure for this flash device
|
|
||||||
struct jedec_flash_dev * flash_dev;
|
|
||||||
|
|
||||||
//! Private functions
|
//! Private functions
|
||||||
static int32_t PIOS_Flash_Jedec_Validate(struct jedec_flash_dev * dev);
|
static int32_t PIOS_Flash_Jedec_Validate(struct jedec_flash_dev * flash_dev);
|
||||||
static struct jedec_flash_dev * PIOS_Flash_Jedec_alloc(void);
|
static struct jedec_flash_dev * PIOS_Flash_Jedec_alloc(void);
|
||||||
static int32_t PIOS_Flash_Jedec_ClaimBus();
|
|
||||||
static int32_t PIOS_Flash_Jedec_ReleaseBus();
|
|
||||||
static int32_t PIOS_Flash_Jedec_WriteEnable();
|
|
||||||
static int32_t PIOS_Flash_Jedec_Busy() ;
|
|
||||||
|
|
||||||
|
static int32_t PIOS_Flash_Jedec_ReadID(struct jedec_flash_dev * flash_dev);
|
||||||
|
static int32_t PIOS_Flash_Jedec_ReadStatus(struct jedec_flash_dev * flash_dev);
|
||||||
|
static int32_t PIOS_Flash_Jedec_ClaimBus(struct jedec_flash_dev * flash_dev);
|
||||||
|
static int32_t PIOS_Flash_Jedec_ReleaseBus(struct jedec_flash_dev * flash_dev);
|
||||||
|
static int32_t PIOS_Flash_Jedec_WriteEnable(struct jedec_flash_dev * flash_dev);
|
||||||
|
static int32_t PIOS_Flash_Jedec_Busy(struct jedec_flash_dev * flash_dev);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Allocate a new device
|
* @brief Allocate a new device
|
||||||
*/
|
*/
|
||||||
static struct jedec_flash_dev * PIOS_Flash_Jedec_alloc(void)
|
static struct jedec_flash_dev * PIOS_Flash_Jedec_alloc(void)
|
||||||
{
|
{
|
||||||
struct jedec_flash_dev * jedec_dev;
|
struct jedec_flash_dev * flash_dev;
|
||||||
|
|
||||||
jedec_dev = (struct jedec_flash_dev *)pvPortMalloc(sizeof(*jedec_dev));
|
flash_dev = (struct jedec_flash_dev *)pvPortMalloc(sizeof(*flash_dev));
|
||||||
if (!jedec_dev) return (NULL);
|
if (!flash_dev) return (NULL);
|
||||||
|
|
||||||
jedec_dev->claimed = false;
|
flash_dev->claimed = false;
|
||||||
jedec_dev->magic = PIOS_JEDEC_DEV_MAGIC;
|
flash_dev->magic = PIOS_JEDEC_DEV_MAGIC;
|
||||||
#if defined(FLASH_FREERTOS)
|
#if defined(FLASH_FREERTOS)
|
||||||
jedec_dev->transaction_lock = xSemaphoreCreateMutex();
|
flash_dev->transaction_lock = xSemaphoreCreateMutex();
|
||||||
#endif
|
#endif
|
||||||
return(jedec_dev);
|
return(flash_dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Validate the handle to the spi device
|
* @brief Validate the handle to the spi device
|
||||||
*/
|
*/
|
||||||
static int32_t PIOS_Flash_Jedec_Validate(struct jedec_flash_dev * dev) {
|
static int32_t PIOS_Flash_Jedec_Validate(struct jedec_flash_dev * flash_dev) {
|
||||||
if (dev == NULL)
|
if (flash_dev == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
if (dev->magic != PIOS_JEDEC_DEV_MAGIC)
|
if (flash_dev->magic != PIOS_JEDEC_DEV_MAGIC)
|
||||||
return -2;
|
return -2;
|
||||||
if (dev->spi_id == 0)
|
if (flash_dev->spi_id == 0)
|
||||||
return -3;
|
return -3;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize the flash device and enable write access
|
||||||
|
*/
|
||||||
|
int32_t PIOS_Flash_Jedec_Init(uintptr_t * flash_id, uint32_t spi_id, uint32_t slave_num, const struct pios_flash_jedec_cfg * cfg)
|
||||||
|
{
|
||||||
|
struct jedec_flash_dev * flash_dev = PIOS_Flash_Jedec_alloc();
|
||||||
|
if (flash_dev == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
flash_dev->spi_id = spi_id;
|
||||||
|
flash_dev->slave_num = slave_num;
|
||||||
|
flash_dev->cfg = cfg;
|
||||||
|
|
||||||
|
(void) PIOS_Flash_Jedec_ReadID(flash_dev);
|
||||||
|
if ((flash_dev->manufacturer != flash_dev->cfg->expect_manufacturer) ||
|
||||||
|
(flash_dev->memorytype != flash_dev->cfg->expect_memorytype) ||
|
||||||
|
(flash_dev->capacity != flash_dev->cfg->expect_capacity)) {
|
||||||
|
/* Mismatched device has been discovered */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Give back a handle to this flash device */
|
||||||
|
*flash_id = (uintptr_t) flash_dev;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Claim the SPI bus for flash use and assert CS pin
|
* @brief Claim the SPI bus for flash use and assert CS pin
|
||||||
* @return 0 for sucess, -1 for failure to get semaphore
|
* @return 0 for sucess, -1 for failure to get semaphore
|
||||||
*/
|
*/
|
||||||
static int32_t PIOS_Flash_Jedec_ClaimBus()
|
static int32_t PIOS_Flash_Jedec_ClaimBus(struct jedec_flash_dev * flash_dev)
|
||||||
{
|
{
|
||||||
if(PIOS_Flash_Jedec_Validate(flash_dev) != 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (PIOS_SPI_ClaimBus(flash_dev->spi_id) < 0)
|
if (PIOS_SPI_ClaimBus(flash_dev->spi_id) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@ -131,10 +158,8 @@ static int32_t PIOS_Flash_Jedec_ClaimBus()
|
|||||||
/**
|
/**
|
||||||
* @brief Release the SPI bus sempahore and ensure flash chip not using bus
|
* @brief Release the SPI bus sempahore and ensure flash chip not using bus
|
||||||
*/
|
*/
|
||||||
static int32_t PIOS_Flash_Jedec_ReleaseBus()
|
static int32_t PIOS_Flash_Jedec_ReleaseBus(struct jedec_flash_dev * flash_dev)
|
||||||
{
|
{
|
||||||
if(PIOS_Flash_Jedec_Validate(flash_dev) != 0)
|
|
||||||
return -1;
|
|
||||||
PIOS_SPI_RC_PinSet(flash_dev->spi_id, flash_dev->slave_num, 1);
|
PIOS_SPI_RC_PinSet(flash_dev->spi_id, flash_dev->slave_num, 1);
|
||||||
PIOS_SPI_ReleaseBus(flash_dev->spi_id);
|
PIOS_SPI_ReleaseBus(flash_dev->spi_id);
|
||||||
flash_dev->claimed = false;
|
flash_dev->claimed = false;
|
||||||
@ -145,9 +170,9 @@ static int32_t PIOS_Flash_Jedec_ReleaseBus()
|
|||||||
* @brief Returns if the flash chip is busy
|
* @brief Returns if the flash chip is busy
|
||||||
* @returns -1 for failure, 0 for not busy, 1 for busy
|
* @returns -1 for failure, 0 for not busy, 1 for busy
|
||||||
*/
|
*/
|
||||||
static int32_t PIOS_Flash_Jedec_Busy()
|
static int32_t PIOS_Flash_Jedec_Busy(struct jedec_flash_dev * flash_dev)
|
||||||
{
|
{
|
||||||
int32_t status = PIOS_Flash_Jedec_ReadStatus();
|
int32_t status = PIOS_Flash_Jedec_ReadStatus(flash_dev);
|
||||||
if (status < 0)
|
if (status < 0)
|
||||||
return -1;
|
return -1;
|
||||||
return status & JEDEC_STATUS_BUSY;
|
return status & JEDEC_STATUS_BUSY;
|
||||||
@ -157,52 +182,88 @@ static int32_t PIOS_Flash_Jedec_Busy()
|
|||||||
* @brief Execute the write enable instruction and returns the status
|
* @brief Execute the write enable instruction and returns the status
|
||||||
* @returns 0 if successful, -1 if unable to claim bus
|
* @returns 0 if successful, -1 if unable to claim bus
|
||||||
*/
|
*/
|
||||||
static int32_t PIOS_Flash_Jedec_WriteEnable()
|
static int32_t PIOS_Flash_Jedec_WriteEnable(struct jedec_flash_dev * flash_dev)
|
||||||
{
|
{
|
||||||
if(PIOS_Flash_Jedec_Validate(flash_dev) != 0)
|
if (PIOS_Flash_Jedec_ClaimBus(flash_dev) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
uint8_t out[] = {JEDEC_WRITE_ENABLE};
|
uint8_t out[] = {JEDEC_WRITE_ENABLE};
|
||||||
if(PIOS_Flash_Jedec_ClaimBus() != 0)
|
|
||||||
return -1;
|
|
||||||
PIOS_SPI_TransferBlock(flash_dev->spi_id,out,NULL,sizeof(out),NULL);
|
PIOS_SPI_TransferBlock(flash_dev->spi_id,out,NULL,sizeof(out),NULL);
|
||||||
PIOS_Flash_Jedec_ReleaseBus();
|
PIOS_Flash_Jedec_ReleaseBus(flash_dev);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Read the status register from flash chip and return it
|
||||||
|
*/
|
||||||
|
static int32_t PIOS_Flash_Jedec_ReadStatus(struct jedec_flash_dev * flash_dev)
|
||||||
|
{
|
||||||
|
if (PIOS_Flash_Jedec_ClaimBus(flash_dev) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
uint8_t out[2] = {JEDEC_READ_STATUS, 0};
|
||||||
|
uint8_t in[2] = {0,0};
|
||||||
|
if (PIOS_SPI_TransferBlock(flash_dev->spi_id,out,in,sizeof(out),NULL) < 0) {
|
||||||
|
PIOS_Flash_Jedec_ReleaseBus(flash_dev);
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
PIOS_Flash_Jedec_ReleaseBus(flash_dev);
|
||||||
|
|
||||||
|
return in[1];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initialize the flash device and enable write access
|
* @brief Read the status register from flash chip and return it
|
||||||
*/
|
*/
|
||||||
int32_t PIOS_Flash_Jedec_Init(uint32_t spi_id, uint32_t slave_num, const struct pios_flash_jedec_cfg * cfg)
|
static int32_t PIOS_Flash_Jedec_ReadID(struct jedec_flash_dev * flash_dev)
|
||||||
{
|
{
|
||||||
flash_dev = PIOS_Flash_Jedec_alloc();
|
if (PIOS_Flash_Jedec_ClaimBus(flash_dev) < 0)
|
||||||
if(flash_dev == NULL)
|
return -2;
|
||||||
return -1;
|
|
||||||
|
|
||||||
flash_dev->spi_id = spi_id;
|
uint8_t out[] = {JEDEC_DEVICE_ID, 0, 0, 0};
|
||||||
flash_dev->slave_num = slave_num;
|
uint8_t in[4];
|
||||||
flash_dev->cfg = cfg;
|
if (PIOS_SPI_TransferBlock(flash_dev->spi_id,out,in,sizeof(out),NULL) < 0) {
|
||||||
|
PIOS_Flash_Jedec_ReleaseBus(flash_dev);
|
||||||
device_type = PIOS_Flash_Jedec_ReadID();
|
return -3;
|
||||||
if(device_type == 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PIOS_Flash_Jedec_ReleaseBus(flash_dev);
|
||||||
|
|
||||||
|
flash_dev->manufacturer = in[1];
|
||||||
|
flash_dev->memorytype = in[2];
|
||||||
|
flash_dev->capacity = in[3];
|
||||||
|
|
||||||
|
return flash_dev->manufacturer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************************
|
||||||
|
*
|
||||||
|
* Provide a PIOS flash driver API
|
||||||
|
*
|
||||||
|
*********************************/
|
||||||
|
#include "pios_flash.h"
|
||||||
|
|
||||||
|
#if FLASH_USE_FREERTOS_LOCKS
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Grab the semaphore to perform a transaction
|
* @brief Grab the semaphore to perform a transaction
|
||||||
* @return 0 for success, -1 for timeout
|
* @return 0 for success, -1 for timeout
|
||||||
*/
|
*/
|
||||||
int32_t PIOS_Flash_Jedec_StartTransaction()
|
static int32_t PIOS_Flash_Jedec_StartTransaction(uintptr_t flash_id)
|
||||||
{
|
{
|
||||||
#if defined(FLASH_FREERTOS)
|
struct jedec_flash_dev * flash_dev = (struct jedec_flash_dev *)flash_id;
|
||||||
|
|
||||||
if (PIOS_Flash_Jedec_Validate(flash_dev) != 0)
|
if (PIOS_Flash_Jedec_Validate(flash_dev) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||||
if (xSemaphoreTake(flash_dev->transaction_lock, portMAX_DELAY) != pdTRUE)
|
if (xSemaphoreTake(flash_dev->transaction_lock, portMAX_DELAY) != pdTRUE)
|
||||||
return -1;
|
return -2;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,60 +271,34 @@ int32_t PIOS_Flash_Jedec_StartTransaction()
|
|||||||
* @brief Release the semaphore to perform a transaction
|
* @brief Release the semaphore to perform a transaction
|
||||||
* @return 0 for success, -1 for timeout
|
* @return 0 for success, -1 for timeout
|
||||||
*/
|
*/
|
||||||
int32_t PIOS_Flash_Jedec_EndTransaction()
|
static int32_t PIOS_Flash_Jedec_EndTransaction(uintptr_t flash_id)
|
||||||
{
|
{
|
||||||
#if defined(FLASH_FREERTOS)
|
struct jedec_flash_dev * flash_dev = (struct jedec_flash_dev *)flash_id;
|
||||||
|
|
||||||
if (PIOS_Flash_Jedec_Validate(flash_dev) != 0)
|
if (PIOS_Flash_Jedec_Validate(flash_dev) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||||
if (xSemaphoreGive(flash_dev->transaction_lock) != pdTRUE)
|
if (xSemaphoreGive(flash_dev->transaction_lock) != pdTRUE)
|
||||||
return -1;
|
return -2;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
#else /* FLASH_USE_FREERTOS_LOCKS */
|
||||||
* @brief Read the status register from flash chip and return it
|
|
||||||
*/
|
static int32_t PIOS_Flash_Jedec_StartTransaction(uintptr_t flash_id)
|
||||||
int32_t PIOS_Flash_Jedec_ReadStatus()
|
|
||||||
{
|
{
|
||||||
if(PIOS_Flash_Jedec_Validate(flash_dev) != 0)
|
return 0;
|
||||||
return -1;
|
|
||||||
|
|
||||||
uint8_t out[2] = {JEDEC_READ_STATUS, 0};
|
|
||||||
uint8_t in[2] = {0,0};
|
|
||||||
if(PIOS_Flash_Jedec_ClaimBus() < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if(PIOS_SPI_TransferBlock(flash_dev->spi_id,out,in,sizeof(out),NULL) < 0) {
|
|
||||||
PIOS_Flash_Jedec_ReleaseBus();
|
|
||||||
return -2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PIOS_Flash_Jedec_ReleaseBus();
|
static int32_t PIOS_Flash_Jedec_EndTransaction(uintptr_t flash_id)
|
||||||
return in[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Read the status register from flash chip and return it
|
|
||||||
*/
|
|
||||||
int32_t PIOS_Flash_Jedec_ReadID()
|
|
||||||
{
|
{
|
||||||
uint8_t out[] = {JEDEC_DEVICE_ID, 0, 0, 0};
|
return 0;
|
||||||
uint8_t in[4];
|
|
||||||
if (PIOS_Flash_Jedec_ClaimBus() < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if(PIOS_SPI_TransferBlock(flash_dev->spi_id,out,in,sizeof(out),NULL) < 0) {
|
|
||||||
PIOS_Flash_Jedec_ReleaseBus();
|
|
||||||
return -2;
|
|
||||||
}
|
}
|
||||||
PIOS_Flash_Jedec_ReleaseBus();
|
|
||||||
|
|
||||||
flash_dev->device_type = in[1];
|
#endif /* FLASH_USE_FREERTOS_LOCKS */
|
||||||
flash_dev->capacity = in[3];
|
|
||||||
return in[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Erase a sector on the flash chip
|
* @brief Erase a sector on the flash chip
|
||||||
@ -272,29 +307,31 @@ int32_t PIOS_Flash_Jedec_ReadID()
|
|||||||
* @retval -1 if unable to claim bus
|
* @retval -1 if unable to claim bus
|
||||||
* @retval
|
* @retval
|
||||||
*/
|
*/
|
||||||
int32_t PIOS_Flash_Jedec_EraseSector(uint32_t addr)
|
static int32_t PIOS_Flash_Jedec_EraseSector(uintptr_t flash_id, uint32_t addr)
|
||||||
{
|
{
|
||||||
|
struct jedec_flash_dev * flash_dev = (struct jedec_flash_dev *)flash_id;
|
||||||
|
|
||||||
if (PIOS_Flash_Jedec_Validate(flash_dev) != 0)
|
if (PIOS_Flash_Jedec_Validate(flash_dev) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
uint8_t ret;
|
uint8_t ret;
|
||||||
uint8_t out[] = {flash_dev->cfg->sector_erase, (addr >> 16) & 0xff, (addr >> 8) & 0xff , addr & 0xff};
|
uint8_t out[] = {flash_dev->cfg->sector_erase, (addr >> 16) & 0xff, (addr >> 8) & 0xff , addr & 0xff};
|
||||||
|
|
||||||
if((ret = PIOS_Flash_Jedec_WriteEnable()) != 0)
|
if ((ret = PIOS_Flash_Jedec_WriteEnable(flash_dev)) != 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if(PIOS_Flash_Jedec_ClaimBus() != 0)
|
if (PIOS_Flash_Jedec_ClaimBus(flash_dev) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (PIOS_SPI_TransferBlock(flash_dev->spi_id,out,NULL,sizeof(out),NULL) < 0) {
|
if (PIOS_SPI_TransferBlock(flash_dev->spi_id,out,NULL,sizeof(out),NULL) < 0) {
|
||||||
PIOS_Flash_Jedec_ReleaseBus();
|
PIOS_Flash_Jedec_ReleaseBus(flash_dev);
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
PIOS_Flash_Jedec_ReleaseBus();
|
PIOS_Flash_Jedec_ReleaseBus(flash_dev);
|
||||||
|
|
||||||
// Keep polling when bus is busy too
|
// Keep polling when bus is busy too
|
||||||
while(PIOS_Flash_Jedec_Busy() != 0) {
|
while (PIOS_Flash_Jedec_Busy(flash_dev) != 0) {
|
||||||
#if defined(FLASH_FREERTOS)
|
#if defined(FLASH_FREERTOS)
|
||||||
vTaskDelay(1);
|
vTaskDelay(1);
|
||||||
#endif
|
#endif
|
||||||
@ -307,30 +344,32 @@ int32_t PIOS_Flash_Jedec_EraseSector(uint32_t addr)
|
|||||||
* @brief Execute the whole chip
|
* @brief Execute the whole chip
|
||||||
* @returns 0 if successful, -1 if unable to claim bus
|
* @returns 0 if successful, -1 if unable to claim bus
|
||||||
*/
|
*/
|
||||||
int32_t PIOS_Flash_Jedec_EraseChip()
|
static int32_t PIOS_Flash_Jedec_EraseChip(uintptr_t flash_id)
|
||||||
{
|
{
|
||||||
|
struct jedec_flash_dev * flash_dev = (struct jedec_flash_dev *)flash_id;
|
||||||
|
|
||||||
if (PIOS_Flash_Jedec_Validate(flash_dev) != 0)
|
if (PIOS_Flash_Jedec_Validate(flash_dev) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
uint8_t ret;
|
uint8_t ret;
|
||||||
uint8_t out[] = {flash_dev->cfg->chip_erase};
|
uint8_t out[] = {flash_dev->cfg->chip_erase};
|
||||||
|
|
||||||
if((ret = PIOS_Flash_Jedec_WriteEnable()) != 0)
|
if ((ret = PIOS_Flash_Jedec_WriteEnable(flash_dev)) != 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if(PIOS_Flash_Jedec_ClaimBus() != 0)
|
if (PIOS_Flash_Jedec_ClaimBus(flash_dev) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (PIOS_SPI_TransferBlock(flash_dev->spi_id,out,NULL,sizeof(out),NULL) < 0) {
|
if (PIOS_SPI_TransferBlock(flash_dev->spi_id,out,NULL,sizeof(out),NULL) < 0) {
|
||||||
PIOS_Flash_Jedec_ReleaseBus();
|
PIOS_Flash_Jedec_ReleaseBus(flash_dev);
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
PIOS_Flash_Jedec_ReleaseBus();
|
PIOS_Flash_Jedec_ReleaseBus(flash_dev);
|
||||||
|
|
||||||
// Keep polling when bus is busy too
|
// Keep polling when bus is busy too
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while(PIOS_Flash_Jedec_Busy() != 0) {
|
while (PIOS_Flash_Jedec_Busy(flash_dev) != 0) {
|
||||||
#if defined(FLASH_FREERTOS)
|
#if defined(FLASH_FREERTOS)
|
||||||
vTaskDelay(1);
|
vTaskDelay(1);
|
||||||
if ((i++) % 100 == 0)
|
if ((i++) % 100 == 0)
|
||||||
@ -356,8 +395,10 @@ int32_t PIOS_Flash_Jedec_EraseChip()
|
|||||||
* @retval -2 Size exceeds 256 bytes
|
* @retval -2 Size exceeds 256 bytes
|
||||||
* @retval -3 Length to write would wrap around page boundary
|
* @retval -3 Length to write would wrap around page boundary
|
||||||
*/
|
*/
|
||||||
int32_t PIOS_Flash_Jedec_WriteData(uint32_t addr, uint8_t * data, uint16_t len)
|
static int32_t PIOS_Flash_Jedec_WriteData(uintptr_t flash_id, uint32_t addr, uint8_t * data, uint16_t len)
|
||||||
{
|
{
|
||||||
|
struct jedec_flash_dev * flash_dev = (struct jedec_flash_dev *)flash_id;
|
||||||
|
|
||||||
if(PIOS_Flash_Jedec_Validate(flash_dev) != 0)
|
if(PIOS_Flash_Jedec_Validate(flash_dev) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@ -372,41 +413,41 @@ int32_t PIOS_Flash_Jedec_WriteData(uint32_t addr, uint8_t * data, uint16_t len)
|
|||||||
if (((addr & 0xff) + len) > 0x100)
|
if (((addr & 0xff) + len) > 0x100)
|
||||||
return -3;
|
return -3;
|
||||||
|
|
||||||
if((ret = PIOS_Flash_Jedec_WriteEnable()) != 0)
|
if ((ret = PIOS_Flash_Jedec_WriteEnable(flash_dev)) != 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
/* Execute write page command and clock in address. Keep CS asserted */
|
/* Execute write page command and clock in address. Keep CS asserted */
|
||||||
if(PIOS_Flash_Jedec_ClaimBus() != 0)
|
if (PIOS_Flash_Jedec_ClaimBus(flash_dev) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (PIOS_SPI_TransferBlock(flash_dev->spi_id,out,NULL,sizeof(out),NULL) < 0) {
|
if (PIOS_SPI_TransferBlock(flash_dev->spi_id,out,NULL,sizeof(out),NULL) < 0) {
|
||||||
PIOS_Flash_Jedec_ReleaseBus();
|
PIOS_Flash_Jedec_ReleaseBus(flash_dev);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clock out data to flash */
|
/* Clock out data to flash */
|
||||||
if (PIOS_SPI_TransferBlock(flash_dev->spi_id,data,NULL,len,NULL) < 0) {
|
if (PIOS_SPI_TransferBlock(flash_dev->spi_id,data,NULL,len,NULL) < 0) {
|
||||||
PIOS_Flash_Jedec_ReleaseBus();
|
PIOS_Flash_Jedec_ReleaseBus(flash_dev);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
PIOS_Flash_Jedec_ReleaseBus();
|
PIOS_Flash_Jedec_ReleaseBus(flash_dev);
|
||||||
|
|
||||||
// Keep polling when bus is busy too
|
// Keep polling when bus is busy too
|
||||||
#if defined(FLASH_FREERTOS)
|
#if defined(FLASH_FREERTOS)
|
||||||
while(PIOS_Flash_Jedec_Busy() != 0) {
|
while (PIOS_Flash_Jedec_Busy(flash_dev) != 0) {
|
||||||
vTaskDelay(1);
|
vTaskDelay(1);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
||||||
// Query status this way to prevent accel chip locking us out
|
// Query status this way to prevent accel chip locking us out
|
||||||
if(PIOS_Flash_Jedec_ClaimBus() < 0)
|
if (PIOS_Flash_Jedec_ClaimBus(flash_dev) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
PIOS_SPI_TransferByte(flash_dev->spi_id, JEDEC_READ_STATUS);
|
PIOS_SPI_TransferByte(flash_dev->spi_id, JEDEC_READ_STATUS);
|
||||||
while (PIOS_SPI_TransferByte(flash_dev->spi_id, JEDEC_READ_STATUS) & JEDEC_STATUS_BUSY);
|
while (PIOS_SPI_TransferByte(flash_dev->spi_id, JEDEC_READ_STATUS) & JEDEC_STATUS_BUSY);
|
||||||
|
|
||||||
PIOS_Flash_Jedec_ReleaseBus();
|
PIOS_Flash_Jedec_ReleaseBus(flash_dev);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
@ -422,8 +463,10 @@ int32_t PIOS_Flash_Jedec_WriteData(uint32_t addr, uint8_t * data, uint16_t len)
|
|||||||
* @retval -2 Size exceeds 256 bytes
|
* @retval -2 Size exceeds 256 bytes
|
||||||
* @retval -3 Length to write would wrap around page boundary
|
* @retval -3 Length to write would wrap around page boundary
|
||||||
*/
|
*/
|
||||||
int32_t PIOS_Flash_Jedec_WriteChunks(uint32_t addr, struct pios_flash_chunk * p_chunk, uint32_t num)
|
static int32_t PIOS_Flash_Jedec_WriteChunks(uintptr_t flash_id, uint32_t addr, struct pios_flash_chunk chunks[], uint32_t num)
|
||||||
{
|
{
|
||||||
|
struct jedec_flash_dev * flash_dev = (struct jedec_flash_dev *)flash_id;
|
||||||
|
|
||||||
if (PIOS_Flash_Jedec_Validate(flash_dev) != 0)
|
if (PIOS_Flash_Jedec_Validate(flash_dev) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@ -433,7 +476,7 @@ int32_t PIOS_Flash_Jedec_WriteChunks(uint32_t addr, struct pios_flash_chunk * p_
|
|||||||
/* Can only write one page at a time */
|
/* Can only write one page at a time */
|
||||||
uint32_t len = 0;
|
uint32_t len = 0;
|
||||||
for (uint32_t i = 0; i < num; i++)
|
for (uint32_t i = 0; i < num; i++)
|
||||||
len += p_chunk[i].len;
|
len += chunks[i].len;
|
||||||
|
|
||||||
if (len > 0x100)
|
if (len > 0x100)
|
||||||
return -2;
|
return -2;
|
||||||
@ -442,29 +485,29 @@ int32_t PIOS_Flash_Jedec_WriteChunks(uint32_t addr, struct pios_flash_chunk * p_
|
|||||||
if (((addr & 0xff) + len) > 0x100)
|
if (((addr & 0xff) + len) > 0x100)
|
||||||
return -3;
|
return -3;
|
||||||
|
|
||||||
if((ret = PIOS_Flash_Jedec_WriteEnable()) != 0)
|
if ((ret = PIOS_Flash_Jedec_WriteEnable(flash_dev)) != 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
/* Execute write page command and clock in address. Keep CS asserted */
|
/* Execute write page command and clock in address. Keep CS asserted */
|
||||||
if(PIOS_Flash_Jedec_ClaimBus() != 0)
|
if (PIOS_Flash_Jedec_ClaimBus(flash_dev) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (PIOS_SPI_TransferBlock(flash_dev->spi_id,out,NULL,sizeof(out),NULL) < 0) {
|
if (PIOS_SPI_TransferBlock(flash_dev->spi_id,out,NULL,sizeof(out),NULL) < 0) {
|
||||||
PIOS_Flash_Jedec_ReleaseBus();
|
PIOS_Flash_Jedec_ReleaseBus(flash_dev);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t i = 0; i < num; i++) {
|
for (uint32_t i = 0; i < num; i++) {
|
||||||
struct pios_flash_chunk * chunk = &p_chunk[i];
|
struct pios_flash_chunk * chunk = &chunks[i];
|
||||||
|
|
||||||
/* Clock out data to flash */
|
/* Clock out data to flash */
|
||||||
if (PIOS_SPI_TransferBlock(flash_dev->spi_id,chunk->addr,NULL,chunk->len,NULL) < 0) {
|
if (PIOS_SPI_TransferBlock(flash_dev->spi_id,chunk->addr,NULL,chunk->len,NULL) < 0) {
|
||||||
PIOS_Flash_Jedec_ReleaseBus();
|
PIOS_Flash_Jedec_ReleaseBus(flash_dev);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
PIOS_Flash_Jedec_ReleaseBus();
|
PIOS_Flash_Jedec_ReleaseBus(flash_dev);
|
||||||
|
|
||||||
// Skip checking for busy with this to get OS running again fast
|
// Skip checking for busy with this to get OS running again fast
|
||||||
|
|
||||||
@ -479,29 +522,43 @@ int32_t PIOS_Flash_Jedec_WriteChunks(uint32_t addr, struct pios_flash_chunk * p_
|
|||||||
* @return Zero if success or error code
|
* @return Zero if success or error code
|
||||||
* @retval -1 Unable to claim SPI bus
|
* @retval -1 Unable to claim SPI bus
|
||||||
*/
|
*/
|
||||||
int32_t PIOS_Flash_Jedec_ReadData(uint32_t addr, uint8_t * data, uint16_t len)
|
static int32_t PIOS_Flash_Jedec_ReadData(uintptr_t flash_id, uint32_t addr, uint8_t * data, uint16_t len)
|
||||||
{
|
{
|
||||||
|
struct jedec_flash_dev * flash_dev = (struct jedec_flash_dev *)flash_id;
|
||||||
|
|
||||||
if (PIOS_Flash_Jedec_Validate(flash_dev) != 0)
|
if (PIOS_Flash_Jedec_Validate(flash_dev) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if(PIOS_Flash_Jedec_ClaimBus() == -1)
|
if (PIOS_Flash_Jedec_ClaimBus(flash_dev) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* Execute read command and clock in address. Keep CS asserted */
|
/* Execute read command and clock in address. Keep CS asserted */
|
||||||
uint8_t out[] = {JEDEC_READ_DATA, (addr >> 16) & 0xff, (addr >> 8) & 0xff , addr & 0xff};
|
uint8_t out[] = {JEDEC_READ_DATA, (addr >> 16) & 0xff, (addr >> 8) & 0xff , addr & 0xff};
|
||||||
|
|
||||||
if (PIOS_SPI_TransferBlock(flash_dev->spi_id,out,NULL,sizeof(out),NULL) < 0) {
|
if (PIOS_SPI_TransferBlock(flash_dev->spi_id,out,NULL,sizeof(out),NULL) < 0) {
|
||||||
PIOS_Flash_Jedec_ReleaseBus();
|
PIOS_Flash_Jedec_ReleaseBus(flash_dev);
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy the transfer data to the buffer */
|
/* Copy the transfer data to the buffer */
|
||||||
if (PIOS_SPI_TransferBlock(flash_dev->spi_id,NULL,data,len,NULL) < 0) {
|
if (PIOS_SPI_TransferBlock(flash_dev->spi_id,NULL,data,len,NULL) < 0) {
|
||||||
PIOS_Flash_Jedec_ReleaseBus();
|
PIOS_Flash_Jedec_ReleaseBus(flash_dev);
|
||||||
return -3;
|
return -3;
|
||||||
}
|
}
|
||||||
|
|
||||||
PIOS_Flash_Jedec_ReleaseBus();
|
PIOS_Flash_Jedec_ReleaseBus(flash_dev);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Provide a flash driver to external drivers */
|
||||||
|
const struct pios_flash_driver pios_jedec_flash_driver = {
|
||||||
|
.start_transaction = PIOS_Flash_Jedec_StartTransaction,
|
||||||
|
.end_transaction = PIOS_Flash_Jedec_EndTransaction,
|
||||||
|
.erase_chip = PIOS_Flash_Jedec_EraseChip,
|
||||||
|
.erase_sector = PIOS_Flash_Jedec_EraseSector,
|
||||||
|
.write_chunks = PIOS_Flash_Jedec_WriteChunks,
|
||||||
|
.write_data = PIOS_Flash_Jedec_WriteData,
|
||||||
|
.read_data = PIOS_Flash_Jedec_ReadData,
|
||||||
|
};
|
||||||
|
|
||||||
|
1026
flight/PiOS/Common/pios_flashfs_logfs.c
Normal file
1026
flight/PiOS/Common/pios_flashfs_logfs.c
Normal file
@ -0,0 +1,1026 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file pios_flashfs_logfs.c
|
||||||
|
* @author PhoenixPilot, http://github.com/PhoenixPilot, Copyright (C) 2012
|
||||||
|
* @addtogroup PIOS PIOS Core hardware abstraction layer
|
||||||
|
* @{
|
||||||
|
* @addtogroup PIOS_FLASHFS Flash Filesystem Function
|
||||||
|
* @{
|
||||||
|
* @brief Log Structured Filesystem for internal or external NOR Flash
|
||||||
|
*****************************************************************************/
|
||||||
|
/*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "openpilot.h"
|
||||||
|
|
||||||
|
#include "pios_flashfs_logfs_priv.h"
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#define MIN(x,y) ((x) < (y) ? (x) : (y))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Filesystem state data tracked in RAM
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct logfs_state {
|
||||||
|
const struct flashfs_logfs_cfg * cfg;
|
||||||
|
bool mounted;
|
||||||
|
uint8_t active_arena_id;
|
||||||
|
|
||||||
|
/* NOTE: num_active_slots + num_free_slots will not typically add
|
||||||
|
* up to the number of slots in the arena since some of the
|
||||||
|
* slots will be obsolete or otherwise invalidated
|
||||||
|
*/
|
||||||
|
uint16_t num_free_slots; /* slots in free state */
|
||||||
|
uint16_t num_active_slots; /* slots in active state */
|
||||||
|
|
||||||
|
/* Underlying flash driver glue */
|
||||||
|
const struct pios_flash_driver * driver;
|
||||||
|
uintptr_t flash_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct logfs_state logfs;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Internal Utility functions
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Return the offset in flash of a particular slot within an arena
|
||||||
|
* @return address of the requested slot
|
||||||
|
*/
|
||||||
|
static uintptr_t logfs_get_addr(uint8_t arena_id, uint16_t slot_id)
|
||||||
|
{
|
||||||
|
PIOS_Assert(arena_id < (logfs.cfg->total_fs_size / logfs.cfg->arena_size));
|
||||||
|
PIOS_Assert(slot_id < (logfs.cfg->arena_size / logfs.cfg->slot_size));
|
||||||
|
|
||||||
|
return (logfs.cfg->start_offset +
|
||||||
|
(arena_id * logfs.cfg->arena_size) +
|
||||||
|
(slot_id * logfs.cfg->slot_size));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The bits within these enum values must progress ONLY
|
||||||
|
* from 1 -> 0 so that we can write later ones on top
|
||||||
|
* of earlier ones in NOR flash without an erase cycle.
|
||||||
|
*/
|
||||||
|
enum arena_state {
|
||||||
|
/*
|
||||||
|
* The STM32F30X flash subsystem is only capable of
|
||||||
|
* writing words or halfwords. In this case we use halfwords.
|
||||||
|
* In addition to that it is only capable to write to erased
|
||||||
|
* cells (0xffff) or write a cell from anything to (0x0000).
|
||||||
|
* To cope with this, the F3 needs carefully crafted enum values.
|
||||||
|
* For this to work the underlying flash driver has to
|
||||||
|
* check each halfword if it has changed before writing.
|
||||||
|
*/
|
||||||
|
ARENA_STATE_ERASED = 0xFFFFFFFF,
|
||||||
|
ARENA_STATE_RESERVED = 0xE6E6FFFF,
|
||||||
|
ARENA_STATE_ACTIVE = 0xE6E66666,
|
||||||
|
ARENA_STATE_OBSOLETE = 0x00000000,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct arena_header {
|
||||||
|
uint32_t magic;
|
||||||
|
enum arena_state state;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************
|
||||||
|
* Arena life-cycle transition functions
|
||||||
|
****************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Erases all sectors within the given arena and sets arena to erased state.
|
||||||
|
* @return 0 if success, < 0 on failure
|
||||||
|
* @note Must be called while holding the flash transaction lock
|
||||||
|
*/
|
||||||
|
static int32_t logfs_erase_arena(uint8_t arena_id)
|
||||||
|
{
|
||||||
|
uintptr_t arena_addr = logfs_get_addr (arena_id, 0);
|
||||||
|
|
||||||
|
/* Erase all of the sectors in the arena */
|
||||||
|
for (uint8_t sector_id = 0;
|
||||||
|
sector_id < (logfs.cfg->arena_size / logfs.cfg->sector_size);
|
||||||
|
sector_id++) {
|
||||||
|
if (logfs.driver->erase_sector(logfs.flash_id,
|
||||||
|
arena_addr + (sector_id * logfs.cfg->sector_size))) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mark this arena as fully erased */
|
||||||
|
struct arena_header arena_hdr = {
|
||||||
|
.magic = logfs.cfg->fs_magic,
|
||||||
|
.state = ARENA_STATE_ERASED,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (logfs.driver->write_data(logfs.flash_id,
|
||||||
|
arena_addr,
|
||||||
|
(uint8_t *)&arena_hdr,
|
||||||
|
sizeof(arena_hdr)) != 0) {
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Arena is ready to be activated */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Marks the given arena as reserved so it can be filled.
|
||||||
|
* @return 0 if success, < 0 on failure
|
||||||
|
* @note Arena must have been previously erased before calling this
|
||||||
|
* @note Must be called while holding the flash transaction lock
|
||||||
|
*/
|
||||||
|
static int32_t logfs_reserve_arena (uint8_t arena_id)
|
||||||
|
{
|
||||||
|
uintptr_t arena_addr = logfs_get_addr (arena_id, 0);
|
||||||
|
|
||||||
|
/* Read in the current arena header */
|
||||||
|
struct arena_header arena_hdr;
|
||||||
|
if (logfs.driver->read_data(logfs.flash_id,
|
||||||
|
arena_addr,
|
||||||
|
(uint8_t *)&arena_hdr,
|
||||||
|
sizeof(arena_hdr)) != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (arena_hdr.state != ARENA_STATE_ERASED) {
|
||||||
|
/* Arena was not erased, can't reserve it */
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the arena state to reserved */
|
||||||
|
arena_hdr.state = ARENA_STATE_RESERVED;
|
||||||
|
|
||||||
|
/* Write the arena header back to flash */
|
||||||
|
if (logfs.driver->write_data(logfs.flash_id,
|
||||||
|
arena_addr,
|
||||||
|
(uint8_t *)&arena_hdr,
|
||||||
|
sizeof(arena_hdr)) != 0) {
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Arena is ready to be filled */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Erases all arenas available to this filesystem instance
|
||||||
|
* @return 0 if success, < 0 on failure
|
||||||
|
* @note Must be called while holding the flash transaction lock
|
||||||
|
*/
|
||||||
|
static int32_t logfs_erase_all_arenas()
|
||||||
|
{
|
||||||
|
uint16_t num_arenas = logfs.cfg->total_fs_size / logfs.cfg->arena_size;
|
||||||
|
|
||||||
|
for (uint16_t arena = 0; arena < num_arenas; arena++) {
|
||||||
|
if (logfs_erase_arena(arena) != 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Marks the given arena as active so it can be mounted.
|
||||||
|
* @return 0 if success, < 0 on failure
|
||||||
|
* @note Arena must have been previously erased or reserved before calling this
|
||||||
|
* @note Must be called while holding the flash transaction lock
|
||||||
|
*/
|
||||||
|
static int32_t logfs_activate_arena(uint8_t arena_id)
|
||||||
|
{
|
||||||
|
uintptr_t arena_addr = logfs_get_addr(arena_id, 0);
|
||||||
|
|
||||||
|
/* Make sure this arena has been previously erased */
|
||||||
|
struct arena_header arena_hdr;
|
||||||
|
if (logfs.driver->read_data(logfs.flash_id,
|
||||||
|
arena_addr,
|
||||||
|
(uint8_t *)&arena_hdr,
|
||||||
|
sizeof (arena_hdr)) != 0) {
|
||||||
|
/* Failed to read arena header */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if ((arena_hdr.state != ARENA_STATE_RESERVED) &&
|
||||||
|
(arena_hdr.state != ARENA_STATE_ERASED)) {
|
||||||
|
/* Arena was not erased or reserved, can't activate it */
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mark this arena as active */
|
||||||
|
arena_hdr.state = ARENA_STATE_ACTIVE;
|
||||||
|
if (logfs.driver->write_data(logfs.flash_id,
|
||||||
|
arena_addr,
|
||||||
|
(uint8_t *)&arena_hdr,
|
||||||
|
sizeof(arena_hdr)) != 0) {
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The arena is now activated and the log may be mounted */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Marks the given arena as obsolete.
|
||||||
|
* @return 0 if success, < 0 on failure
|
||||||
|
* @note Arena must have been previously active before calling this
|
||||||
|
* @note Must be called while holding the flash transaction lock
|
||||||
|
*/
|
||||||
|
static int32_t logfs_obsolete_arena(uint8_t arena_id)
|
||||||
|
{
|
||||||
|
uintptr_t arena_addr = logfs_get_addr (arena_id, 0);
|
||||||
|
|
||||||
|
/* We shouldn't be retiring the currently active arena */
|
||||||
|
PIOS_Assert(!logfs.mounted);
|
||||||
|
|
||||||
|
/* Make sure this arena was previously active */
|
||||||
|
struct arena_header arena_hdr;
|
||||||
|
if (logfs.driver->read_data(logfs.flash_id,
|
||||||
|
arena_addr,
|
||||||
|
(uint8_t *)&arena_hdr,
|
||||||
|
sizeof (arena_hdr)) != 0) {
|
||||||
|
/* Failed to read arena header */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arena_hdr.state != ARENA_STATE_ACTIVE) {
|
||||||
|
/* Arena was not previously active, can't obsolete it */
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mark this arena as obsolete */
|
||||||
|
arena_hdr.state = ARENA_STATE_OBSOLETE;
|
||||||
|
if (logfs.driver->write_data(logfs.flash_id,
|
||||||
|
arena_addr,
|
||||||
|
(uint8_t *)&arena_hdr,
|
||||||
|
sizeof(arena_hdr)) != 0) {
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Arena is now obsoleted */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Find the first active arena in flash
|
||||||
|
* @return arena_id (>=0) of first active arena
|
||||||
|
* @return -1 if no active arena is found
|
||||||
|
* @return -2 if failed to read arena header
|
||||||
|
* @note Must be called while holding the flash transaction lock
|
||||||
|
*/
|
||||||
|
static int32_t logfs_find_active_arena()
|
||||||
|
{
|
||||||
|
/* Search for the lowest numbered active arena */
|
||||||
|
for (uint8_t arena_id = 0;
|
||||||
|
arena_id < logfs.cfg->total_fs_size / logfs.cfg->arena_size;
|
||||||
|
arena_id++) {
|
||||||
|
uintptr_t arena_addr = logfs_get_addr (arena_id, 0);
|
||||||
|
/* Load the arena header */
|
||||||
|
struct arena_header arena_hdr;
|
||||||
|
if (logfs.driver->read_data(logfs.flash_id,
|
||||||
|
arena_addr,
|
||||||
|
(uint8_t *)&arena_hdr,
|
||||||
|
sizeof (arena_hdr)) != 0) {
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
if ((arena_hdr.state == ARENA_STATE_ACTIVE) &&
|
||||||
|
(arena_hdr.magic == logfs.cfg->fs_magic)) {
|
||||||
|
/* This is the first active arena */
|
||||||
|
return arena_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Didn't find an active arena */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The bits within these enum values must progress ONLY
|
||||||
|
* from 1 -> 0 so that we can write later ones on top
|
||||||
|
* of earlier ones in NOR flash without an erase cycle.
|
||||||
|
*/
|
||||||
|
enum slot_state {
|
||||||
|
/*
|
||||||
|
* The STM32F30X flash subsystem is only capable of
|
||||||
|
* writing words or halfwords. In this case we use halfwords.
|
||||||
|
* In addition to that it is only capable to write to erased
|
||||||
|
* cells (0xffff) or write a cell from anything to (0x0000).
|
||||||
|
* To cope with this, the F3 needs carfully crafted enum values.
|
||||||
|
* For this to work the underlying flash driver has to
|
||||||
|
* check each halfword if it has changed before writing.
|
||||||
|
*/
|
||||||
|
SLOT_STATE_EMPTY = 0xFFFFFFFF,
|
||||||
|
SLOT_STATE_RESERVED = 0xFAFAFFFF,
|
||||||
|
SLOT_STATE_ACTIVE = 0xFAFAAAAA,
|
||||||
|
SLOT_STATE_OBSOLETE = 0x00000000,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct slot_header {
|
||||||
|
enum slot_state state;
|
||||||
|
uint32_t obj_id;
|
||||||
|
uint16_t obj_inst_id;
|
||||||
|
uint16_t obj_size;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
/* NOTE: Must be called while holding the flash transaction lock */
|
||||||
|
static int32_t logfs_raw_copy_bytes (uintptr_t src_addr, uint16_t src_size, uintptr_t dst_addr)
|
||||||
|
{
|
||||||
|
#define RAW_COPY_BLOCK_SIZE 16
|
||||||
|
uint8_t data_block[RAW_COPY_BLOCK_SIZE];
|
||||||
|
|
||||||
|
while (src_size) {
|
||||||
|
uint16_t blk_size;
|
||||||
|
if (src_size >= RAW_COPY_BLOCK_SIZE) {
|
||||||
|
/* Copy a full block */
|
||||||
|
blk_size = RAW_COPY_BLOCK_SIZE;
|
||||||
|
} else {
|
||||||
|
/* Copy the remainder */
|
||||||
|
blk_size = src_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read a block of data from source */
|
||||||
|
if (logfs.driver->read_data(logfs.flash_id,
|
||||||
|
src_addr,
|
||||||
|
data_block,
|
||||||
|
blk_size) != 0) {
|
||||||
|
/* Failed to read next chunk from source */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write a block of data to destination */
|
||||||
|
if (logfs.driver->write_data(logfs.flash_id,
|
||||||
|
dst_addr,
|
||||||
|
data_block,
|
||||||
|
blk_size) != 0) {
|
||||||
|
/* Failed to write chunk to destination */
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update the src/dst pointers */
|
||||||
|
src_size -= blk_size;
|
||||||
|
src_addr += blk_size;
|
||||||
|
dst_addr += blk_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Is the entire filesystem full?
|
||||||
|
* true = all slots in the arena are in the ACTIVE state (ie. garbage collection won't free anything)
|
||||||
|
* false = some slots in the arena are either currently free or could be free'd by garbage collection
|
||||||
|
*/
|
||||||
|
static bool logfs_fs_is_full(void)
|
||||||
|
{
|
||||||
|
return (logfs.num_active_slots == (logfs.cfg->arena_size / logfs.cfg->slot_size) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Is the log full?
|
||||||
|
* true = there are no unwritten slots left in the log (garbage collection may or may not help)
|
||||||
|
* false = there are still some entirely unused slots left in the log
|
||||||
|
*/
|
||||||
|
static bool logfs_log_is_full(void)
|
||||||
|
{
|
||||||
|
return (logfs.num_free_slots == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t logfs_unmount_log(void)
|
||||||
|
{
|
||||||
|
PIOS_Assert (logfs.mounted);
|
||||||
|
|
||||||
|
logfs.num_active_slots = 0;
|
||||||
|
logfs.num_free_slots = 0;
|
||||||
|
logfs.mounted = false;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t logfs_mount_log(uint8_t arena_id)
|
||||||
|
{
|
||||||
|
PIOS_Assert (!logfs.mounted);
|
||||||
|
|
||||||
|
logfs.num_active_slots = 0;
|
||||||
|
logfs.num_free_slots = 0;
|
||||||
|
logfs.active_arena_id = arena_id;
|
||||||
|
|
||||||
|
/* Scan the log to find out how full it is */
|
||||||
|
for (uint16_t slot_id = 1;
|
||||||
|
slot_id < (logfs.cfg->arena_size / logfs.cfg->slot_size);
|
||||||
|
slot_id++) {
|
||||||
|
struct slot_header slot_hdr;
|
||||||
|
uintptr_t slot_addr = logfs_get_addr (logfs.active_arena_id, slot_id);
|
||||||
|
if (logfs.driver->read_data(logfs.flash_id,
|
||||||
|
slot_addr,
|
||||||
|
(uint8_t *)&slot_hdr,
|
||||||
|
sizeof (slot_hdr)) != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Empty slots must be in a continguous block at the
|
||||||
|
* end of the arena.
|
||||||
|
*/
|
||||||
|
PIOS_Assert (slot_hdr.state == SLOT_STATE_EMPTY ||
|
||||||
|
logfs.num_free_slots == 0);
|
||||||
|
|
||||||
|
switch (slot_hdr.state) {
|
||||||
|
case SLOT_STATE_EMPTY:
|
||||||
|
logfs.num_free_slots++;
|
||||||
|
break;
|
||||||
|
case SLOT_STATE_ACTIVE:
|
||||||
|
logfs.num_active_slots++;
|
||||||
|
break;
|
||||||
|
case SLOT_STATE_RESERVED:
|
||||||
|
case SLOT_STATE_OBSOLETE:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Scan is complete, mark the arena mounted */
|
||||||
|
logfs.active_arena_id = arena_id;
|
||||||
|
logfs.mounted = true;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize the flash object setting FS
|
||||||
|
* @return 0 if success, -1 if failure
|
||||||
|
*/
|
||||||
|
int32_t PIOS_FLASHFS_Logfs_Init(uintptr_t * fs_id, const struct flashfs_logfs_cfg * cfg, const struct pios_flash_driver * driver, uintptr_t flash_id)
|
||||||
|
{
|
||||||
|
PIOS_Assert(cfg);
|
||||||
|
PIOS_Assert(fs_id);
|
||||||
|
PIOS_Assert(driver);
|
||||||
|
|
||||||
|
/* We must have at least 2 arenas for garbage collection to work */
|
||||||
|
PIOS_Assert((cfg->total_fs_size / cfg->arena_size > 1));
|
||||||
|
|
||||||
|
/* Make sure the underlying flash driver provides the minimal set of required methods */
|
||||||
|
PIOS_Assert(driver->start_transaction);
|
||||||
|
PIOS_Assert(driver->end_transaction);
|
||||||
|
PIOS_Assert(driver->erase_sector);
|
||||||
|
PIOS_Assert(driver->write_data);
|
||||||
|
PIOS_Assert(driver->read_data);
|
||||||
|
|
||||||
|
/* Bind configuration parameters to this filesystem instance */
|
||||||
|
logfs.cfg = cfg; /* filesystem configuration */
|
||||||
|
logfs.driver = driver; /* lower-level flash driver */
|
||||||
|
logfs.flash_id = flash_id; /* lower-level flash device id */
|
||||||
|
logfs.mounted = false;
|
||||||
|
|
||||||
|
int8_t rc;
|
||||||
|
|
||||||
|
if (logfs.driver->start_transaction(logfs.flash_id) != 0) {
|
||||||
|
rc = -1;
|
||||||
|
goto out_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool found = false;
|
||||||
|
int32_t arena_id;
|
||||||
|
for (uint8_t try = 0; !found && try < 2; try++) {
|
||||||
|
/* Find the active arena */
|
||||||
|
arena_id = logfs_find_active_arena();
|
||||||
|
if (arena_id >= 0) {
|
||||||
|
/* Found the active arena */
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
/* No active arena found, erase and activate arena 0 */
|
||||||
|
if (logfs_erase_arena(0) != 0)
|
||||||
|
break;
|
||||||
|
if (logfs_activate_arena(0) != 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
|
/* Still no active arena, something is broken */
|
||||||
|
rc = -2;
|
||||||
|
goto out_end_trans;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We've found an active arena, mount it */
|
||||||
|
if (logfs_mount_log(arena_id) != 0) {
|
||||||
|
/* Failed to mount the log, something is broken */
|
||||||
|
rc = -3;
|
||||||
|
goto out_end_trans;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Log has been mounted */
|
||||||
|
rc = 0;
|
||||||
|
|
||||||
|
*fs_id = (uintptr_t) &logfs;
|
||||||
|
|
||||||
|
out_end_trans:
|
||||||
|
logfs.driver->end_transaction(logfs.flash_id);
|
||||||
|
|
||||||
|
out_exit:
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* NOTE: Must be called while holding the flash transaction lock */
|
||||||
|
static int32_t logfs_garbage_collect (void) {
|
||||||
|
PIOS_Assert (logfs.mounted);
|
||||||
|
|
||||||
|
/* Source arena is the active arena */
|
||||||
|
uint8_t src_arena_id = logfs.active_arena_id;
|
||||||
|
|
||||||
|
/* Compute destination arena */
|
||||||
|
uint8_t dst_arena_id = (logfs.active_arena_id + 1) % (logfs.cfg->total_fs_size / logfs.cfg->arena_size);
|
||||||
|
|
||||||
|
/* Erase destination arena */
|
||||||
|
if (logfs_erase_arena (dst_arena_id) != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reserve the destination arena so we can start filling it */
|
||||||
|
if (logfs_reserve_arena (dst_arena_id) != 0) {
|
||||||
|
/* Unable to reserve the arena */
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy active slots from active arena to destination arena */
|
||||||
|
uint16_t dst_slot_id = 1;
|
||||||
|
for (uint16_t src_slot_id = 1;
|
||||||
|
src_slot_id < (logfs.cfg->arena_size / logfs.cfg->slot_size);
|
||||||
|
src_slot_id++) {
|
||||||
|
struct slot_header slot_hdr;
|
||||||
|
uintptr_t src_addr = logfs_get_addr (src_arena_id, src_slot_id);
|
||||||
|
if (logfs.driver->read_data(logfs.flash_id,
|
||||||
|
src_addr,
|
||||||
|
(uint8_t *)&slot_hdr,
|
||||||
|
sizeof (slot_hdr)) != 0) {
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (slot_hdr.state == SLOT_STATE_ACTIVE) {
|
||||||
|
uintptr_t dst_addr = logfs_get_addr (dst_arena_id, dst_slot_id);
|
||||||
|
if (logfs_raw_copy_bytes(src_addr,
|
||||||
|
sizeof(slot_hdr) + slot_hdr.obj_size,
|
||||||
|
dst_addr) != 0) {
|
||||||
|
/* Failed to copy all bytes */
|
||||||
|
return -4;
|
||||||
|
}
|
||||||
|
dst_slot_id++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Activate the destination arena */
|
||||||
|
if (logfs_activate_arena (dst_arena_id) != 0) {
|
||||||
|
return -5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unmount the source arena */
|
||||||
|
if (logfs_unmount_log () != 0) {
|
||||||
|
return -6;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Obsolete the source arena */
|
||||||
|
if (logfs_obsolete_arena (src_arena_id) != 0) {
|
||||||
|
return -7;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mount the new arena */
|
||||||
|
if (logfs_mount_log (dst_arena_id) != 0) {
|
||||||
|
return -8;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* NOTE: Must be called while holding the flash transaction lock */
|
||||||
|
static int16_t logfs_object_find_next (struct slot_header * slot_hdr, uint16_t * curr_slot, uint32_t obj_id, uint16_t obj_inst_id)
|
||||||
|
{
|
||||||
|
PIOS_Assert(slot_hdr);
|
||||||
|
PIOS_Assert(curr_slot);
|
||||||
|
|
||||||
|
/* First slot in the arena is reserved for arena header, skip it. */
|
||||||
|
if (*curr_slot == 0) *curr_slot = 1;
|
||||||
|
|
||||||
|
for (uint16_t slot_id = *curr_slot;
|
||||||
|
slot_id < (logfs.cfg->arena_size / logfs.cfg->slot_size);
|
||||||
|
slot_id++) {
|
||||||
|
uintptr_t slot_addr = logfs_get_addr (logfs.active_arena_id, slot_id);
|
||||||
|
|
||||||
|
if (logfs.driver->read_data(logfs.flash_id,
|
||||||
|
slot_addr,
|
||||||
|
(uint8_t *)slot_hdr,
|
||||||
|
sizeof (*slot_hdr)) != 0) {
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
if (slot_hdr->state == SLOT_STATE_EMPTY) {
|
||||||
|
/* We hit the end of the log */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (slot_hdr->state == SLOT_STATE_ACTIVE &&
|
||||||
|
slot_hdr->obj_id == obj_id &&
|
||||||
|
slot_hdr->obj_inst_id == obj_inst_id) {
|
||||||
|
/* Found what we were looking for */
|
||||||
|
*curr_slot = slot_id;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No matching entry was found */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* NOTE: Must be called while holding the flash transaction lock */
|
||||||
|
/* OPTIMIZE: could trust that there is at most one active version of every object and terminate the search when we find one */
|
||||||
|
static int8_t logfs_delete_object (uint32_t obj_id, uint16_t obj_inst_id)
|
||||||
|
{
|
||||||
|
int8_t rc;
|
||||||
|
|
||||||
|
bool more = true;
|
||||||
|
uint16_t curr_slot_id = 0;
|
||||||
|
do {
|
||||||
|
struct slot_header slot_hdr;
|
||||||
|
switch (logfs_object_find_next (&slot_hdr, &curr_slot_id, obj_id, obj_inst_id)) {
|
||||||
|
case 0:
|
||||||
|
/* Found a matching slot. Obsolete it. */
|
||||||
|
slot_hdr.state = SLOT_STATE_OBSOLETE;
|
||||||
|
uintptr_t slot_addr = logfs_get_addr (logfs.active_arena_id, curr_slot_id);
|
||||||
|
|
||||||
|
if (logfs.driver->write_data(logfs.flash_id,
|
||||||
|
slot_addr,
|
||||||
|
(uint8_t *)&slot_hdr,
|
||||||
|
sizeof(slot_hdr)) != 0) {
|
||||||
|
rc = -2;
|
||||||
|
goto out_exit;
|
||||||
|
}
|
||||||
|
/* Object has been successfully obsoleted and is no longer active */
|
||||||
|
logfs.num_active_slots--;
|
||||||
|
break;
|
||||||
|
case -1:
|
||||||
|
/* Search completed, object not found */
|
||||||
|
more = false;
|
||||||
|
rc = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* Error occurred during search */
|
||||||
|
rc = -1;
|
||||||
|
goto out_exit;
|
||||||
|
}
|
||||||
|
} while (more);
|
||||||
|
|
||||||
|
out_exit:
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* NOTE: Must be called while holding the flash transaction lock */
|
||||||
|
static int8_t logfs_reserve_free_slot (uint16_t * slot_id, struct slot_header * slot_hdr, uint32_t obj_id, uint16_t obj_inst_id, uint16_t obj_size)
|
||||||
|
{
|
||||||
|
PIOS_Assert(slot_id);
|
||||||
|
PIOS_Assert(slot_hdr);
|
||||||
|
|
||||||
|
if (logfs.num_free_slots < 1) {
|
||||||
|
/* No free slots to allocate */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj_size > (logfs.cfg->slot_size - sizeof (slot_hdr))) {
|
||||||
|
/* This object is too big for the slot */
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t candidate_slot_id = (logfs.cfg->arena_size / logfs.cfg->slot_size) - logfs.num_free_slots;
|
||||||
|
PIOS_Assert(candidate_slot_id > 0);
|
||||||
|
|
||||||
|
uintptr_t slot_addr = logfs_get_addr (logfs.active_arena_id, candidate_slot_id);
|
||||||
|
|
||||||
|
if (logfs.driver->read_data(logfs.flash_id,
|
||||||
|
slot_addr,
|
||||||
|
(uint8_t *)slot_hdr,
|
||||||
|
sizeof (*slot_hdr)) != 0) {
|
||||||
|
/* Failed to read slot header for candidate slot */
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (slot_hdr->state != SLOT_STATE_EMPTY) {
|
||||||
|
/* Candidate slot isn't empty! Something is broken. */
|
||||||
|
PIOS_DEBUG_Assert(0);
|
||||||
|
return -4;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mark this slot as RESERVED */
|
||||||
|
slot_hdr->state = SLOT_STATE_RESERVED;
|
||||||
|
slot_hdr->obj_id = obj_id;
|
||||||
|
slot_hdr->obj_inst_id = obj_inst_id;
|
||||||
|
slot_hdr->obj_size = obj_size;
|
||||||
|
|
||||||
|
if (logfs.driver->write_data(logfs.flash_id,
|
||||||
|
slot_addr,
|
||||||
|
(uint8_t *)slot_hdr,
|
||||||
|
sizeof(*slot_hdr)) != 0) {
|
||||||
|
/* Failed to write the slot header */
|
||||||
|
return -5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME: If the header write (above) failed, may have partially written data, thus corrupting that slot but we would have missed decrementing this counter */
|
||||||
|
logfs.num_free_slots--;
|
||||||
|
|
||||||
|
*slot_id = candidate_slot_id;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* NOTE: Must be called while holding the flash transaction lock */
|
||||||
|
static int8_t logfs_append_to_log (uint32_t obj_id, uint16_t obj_inst_id, uint8_t * obj_data, uint16_t obj_size)
|
||||||
|
{
|
||||||
|
/* Reserve a free slot for our new object */
|
||||||
|
uint16_t free_slot_id;
|
||||||
|
struct slot_header slot_hdr;
|
||||||
|
if (logfs_reserve_free_slot (&free_slot_id, &slot_hdr, obj_id, obj_inst_id, obj_size) != 0) {
|
||||||
|
/* Failed to reserve a free slot */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compute slot address */
|
||||||
|
uintptr_t slot_addr = logfs_get_addr (logfs.active_arena_id, free_slot_id);
|
||||||
|
|
||||||
|
/* Write the data into the reserved slot, starting after the slot header */
|
||||||
|
uintptr_t slot_offset = sizeof(slot_hdr);
|
||||||
|
while (obj_size > 0) {
|
||||||
|
/* Individual writes must fit entirely within a single page buffer. */
|
||||||
|
uint16_t page_remaining = logfs.cfg->page_size - (slot_offset % logfs.cfg->page_size);
|
||||||
|
uint16_t write_size = MIN(obj_size, page_remaining);
|
||||||
|
if (logfs.driver->write_data (logfs.flash_id,
|
||||||
|
slot_addr + slot_offset,
|
||||||
|
obj_data,
|
||||||
|
write_size) != 0) {
|
||||||
|
/* Failed to write the object data to the slot */
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update our accounting */
|
||||||
|
obj_data += write_size;
|
||||||
|
slot_offset += write_size;
|
||||||
|
obj_size -= write_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mark this slot active in one atomic step */
|
||||||
|
slot_hdr.state = SLOT_STATE_ACTIVE;
|
||||||
|
if (logfs.driver->write_data (logfs.flash_id,
|
||||||
|
slot_addr,
|
||||||
|
(uint8_t *)&slot_hdr,
|
||||||
|
sizeof(slot_hdr)) != 0) {
|
||||||
|
/* Failed to mark the slot active */
|
||||||
|
return -4;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Object has been successfully written to the slot */
|
||||||
|
logfs.num_active_slots++;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**********************************
|
||||||
|
*
|
||||||
|
* Provide a PIOS_FLASHFS_* driver
|
||||||
|
*
|
||||||
|
*********************************/
|
||||||
|
#include "pios_flashfs.h" /* API for flash filesystem */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Saves one object instance to the filesystem
|
||||||
|
* @param[in] fs_id The filesystem to use for this action
|
||||||
|
* @param[in] obj UAVObject ID of the object to save
|
||||||
|
* @param[in] obj_inst_id The instance number of the object being saved
|
||||||
|
* @param[in] obj_data Contents of the object being saved
|
||||||
|
* @param[in] obj_size Size of the object being saved
|
||||||
|
* @return 0 if success or error code
|
||||||
|
* @retval -1 if failed to start transaction
|
||||||
|
* @retval -2 if failure to delete any previous versions of the object
|
||||||
|
* @retval -3 if filesystem is entirely full and garbage collection won't help
|
||||||
|
* @retval -4 if garbage collection failed
|
||||||
|
* @retval -5 if filesystem is full even after garbage collection should have freed space
|
||||||
|
* @retval -6 if writing the new object to the filesystem failed
|
||||||
|
*/
|
||||||
|
int32_t PIOS_FLASHFS_ObjSave(uint32_t fs_id, uint32_t obj_id, uint16_t obj_inst_id, uint8_t * obj_data, uint16_t obj_size)
|
||||||
|
{
|
||||||
|
int8_t rc;
|
||||||
|
|
||||||
|
PIOS_Assert(obj_size <= (logfs.cfg->slot_size - sizeof(struct slot_header)));
|
||||||
|
|
||||||
|
if (logfs.driver->start_transaction(logfs.flash_id) != 0) {
|
||||||
|
rc = -1;
|
||||||
|
goto out_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (logfs_delete_object (obj_id, obj_inst_id) != 0) {
|
||||||
|
rc = -2;
|
||||||
|
goto out_end_trans;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* All old versions of this object + instance have been invalidated.
|
||||||
|
* Write the new object.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Check if the arena is entirely full. */
|
||||||
|
if (logfs_fs_is_full()) {
|
||||||
|
/* Note: Filesystem Full means we're full of *active* records so gc won't help at all. */
|
||||||
|
rc = -3;
|
||||||
|
goto out_end_trans;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Is garbage collection required? */
|
||||||
|
if (logfs_log_is_full()) {
|
||||||
|
/* Note: Log Full means the log is full but may contain obsolete slots so gc may free some space */
|
||||||
|
if (logfs_garbage_collect() != 0) {
|
||||||
|
rc = -4;
|
||||||
|
goto out_end_trans;
|
||||||
|
}
|
||||||
|
/* Check one more time just to be sure we actually free'd some space */
|
||||||
|
if (logfs_log_is_full()) {
|
||||||
|
/*
|
||||||
|
* Log is still full even after gc!
|
||||||
|
* NOTE: This should not happen since the filesystem wasn't full
|
||||||
|
* when we checked above so gc should have helped.
|
||||||
|
*/
|
||||||
|
PIOS_DEBUG_Assert(0);
|
||||||
|
rc = -5;
|
||||||
|
goto out_end_trans;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We have room for our new object. Append it to the log. */
|
||||||
|
if (logfs_append_to_log(obj_id, obj_inst_id, obj_data, obj_size) != 0) {
|
||||||
|
/* Error during append */
|
||||||
|
rc = -6;
|
||||||
|
goto out_end_trans;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Object successfully written to the log */
|
||||||
|
rc = 0;
|
||||||
|
|
||||||
|
out_end_trans:
|
||||||
|
logfs.driver->end_transaction(logfs.flash_id);
|
||||||
|
|
||||||
|
out_exit:
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Load one object instance from the filesystem
|
||||||
|
* @param[in] fs_id The filesystem to use for this action
|
||||||
|
* @param[in] obj UAVObject ID of the object to load
|
||||||
|
* @param[in] obj_inst_id The instance of the object to load
|
||||||
|
* @param[in] obj_data Buffer to hold the contents of the loaded object
|
||||||
|
* @param[in] obj_size Size of the object to be loaded
|
||||||
|
* @return 0 if success or error code
|
||||||
|
* @retval -1 if failed to start transaction
|
||||||
|
* @retval -2 if object not found in filesystem
|
||||||
|
* @retval -3 if object size in filesystem does not exactly match buffer size
|
||||||
|
* @retval -4 if reading the object data from flash fails
|
||||||
|
*/
|
||||||
|
int32_t PIOS_FLASHFS_ObjLoad(uint32_t fs_id, uint32_t obj_id, uint16_t obj_inst_id, uint8_t * obj_data, uint16_t obj_size)
|
||||||
|
{
|
||||||
|
int8_t rc;
|
||||||
|
|
||||||
|
PIOS_Assert(obj_size <= (logfs.cfg->slot_size - sizeof(struct slot_header)));
|
||||||
|
|
||||||
|
if (logfs.driver->start_transaction(logfs.flash_id) != 0) {
|
||||||
|
rc = -1;
|
||||||
|
goto out_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find the object in the log */
|
||||||
|
uint16_t slot_id = 0;
|
||||||
|
struct slot_header slot_hdr;
|
||||||
|
if (logfs_object_find_next (&slot_hdr, &slot_id, obj_id, obj_inst_id) != 0) {
|
||||||
|
/* Object does not exist in fs */
|
||||||
|
rc = -2;
|
||||||
|
goto out_end_trans;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sanity check what we've found */
|
||||||
|
if (slot_hdr.obj_size != obj_size) {
|
||||||
|
/* Object sizes don't match. Not safe to copy contents. */
|
||||||
|
rc = -3;
|
||||||
|
goto out_end_trans;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read the contents of the object from the log */
|
||||||
|
if (obj_size > 0) {
|
||||||
|
uintptr_t slot_addr = logfs_get_addr (logfs.active_arena_id, slot_id);
|
||||||
|
if (logfs.driver->read_data(logfs.flash_id,
|
||||||
|
slot_addr + sizeof(slot_hdr),
|
||||||
|
(uint8_t *)obj_data,
|
||||||
|
obj_size) != 0) {
|
||||||
|
/* Failed to read object data from the log */
|
||||||
|
rc = -4;
|
||||||
|
goto out_end_trans;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Object successfully loaded */
|
||||||
|
rc = 0;
|
||||||
|
|
||||||
|
out_end_trans:
|
||||||
|
logfs.driver->end_transaction(logfs.flash_id);
|
||||||
|
|
||||||
|
out_exit:
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Delete one instance of an object from the filesystem
|
||||||
|
* @param[in] fs_id The filesystem to use for this action
|
||||||
|
* @param[in] obj UAVObject ID of the object to delete
|
||||||
|
* @param[in] obj_inst_id The instance of the object to delete
|
||||||
|
* @return 0 if success or error code
|
||||||
|
* @retval -1 if failed to start transaction
|
||||||
|
* @retval -2 if failed to delete the object from the filesystem
|
||||||
|
*/
|
||||||
|
int32_t PIOS_FLASHFS_ObjDelete(uint32_t fs_id, uint32_t obj_id, uint16_t obj_inst_id)
|
||||||
|
{
|
||||||
|
int8_t rc;
|
||||||
|
|
||||||
|
if (logfs.driver->start_transaction(logfs.flash_id) != 0) {
|
||||||
|
rc = -1;
|
||||||
|
goto out_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (logfs_delete_object (obj_id, obj_inst_id) != 0) {
|
||||||
|
rc = -2;
|
||||||
|
goto out_end_trans;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Object successfully deleted from the log */
|
||||||
|
rc = 0;
|
||||||
|
|
||||||
|
out_end_trans:
|
||||||
|
logfs.driver->end_transaction(logfs.flash_id);
|
||||||
|
|
||||||
|
out_exit:
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Erases all filesystem arenas and activate the first arena
|
||||||
|
* @param[in] fs_id The filesystem to use for this action
|
||||||
|
* @return 0 if success or error code
|
||||||
|
* @retval -1 if failed to start transaction
|
||||||
|
* @retval -2 if failed to erase all arenas
|
||||||
|
* @retval -3 if failed to activate arena 0
|
||||||
|
* @retval -4 if failed to mount arena 0
|
||||||
|
*/
|
||||||
|
int32_t PIOS_FLASHFS_Format(uint32_t fs_id)
|
||||||
|
{
|
||||||
|
int32_t rc;
|
||||||
|
|
||||||
|
if (logfs.mounted) {
|
||||||
|
logfs_unmount_log();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (logfs.driver->start_transaction(logfs.flash_id) != 0) {
|
||||||
|
rc = -1;
|
||||||
|
goto out_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (logfs_erase_all_arenas() != 0) {
|
||||||
|
rc = -2;
|
||||||
|
goto out_end_trans;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reinitialize arena 0 */
|
||||||
|
if (logfs_activate_arena(0) != 0) {
|
||||||
|
rc = -3;
|
||||||
|
goto out_end_trans;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mount arena 0 */
|
||||||
|
if (logfs_mount_log(0) != 0) {
|
||||||
|
rc = -4;
|
||||||
|
goto out_end_trans;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Chip erased and log remounted successfully */
|
||||||
|
rc = 0;
|
||||||
|
|
||||||
|
out_end_trans:
|
||||||
|
logfs.driver->end_transaction(logfs.flash_id);
|
||||||
|
|
||||||
|
out_exit:
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
* @}
|
||||||
|
*/
|
@ -1,402 +0,0 @@
|
|||||||
/**
|
|
||||||
******************************************************************************
|
|
||||||
*
|
|
||||||
* @addtogroup PIOS PIOS Core hardware abstraction layer
|
|
||||||
* @{
|
|
||||||
* @addtogroup PIOS_FLASHFS_OBJLIST Object list based flash filesystem (low ram)
|
|
||||||
* @{
|
|
||||||
*
|
|
||||||
* @file pios_flashfs_objlist.c
|
|
||||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
|
||||||
* @brief A file system for storing UAVObject in flash chip
|
|
||||||
* @see The GNU Public License (GPL) Version 3
|
|
||||||
*
|
|
||||||
*****************************************************************************/
|
|
||||||
/*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "openpilot.h"
|
|
||||||
#include "uavobjectmanager.h"
|
|
||||||
|
|
||||||
// Private functions
|
|
||||||
static int32_t PIOS_FLASHFS_ClearObjectTableHeader();
|
|
||||||
static int32_t PIOS_FLASHFS_GetObjAddress(uint32_t objId, uint16_t instId);
|
|
||||||
static int32_t PIOS_FLASHFS_GetNewAddress(uint32_t objId, uint16_t instId);
|
|
||||||
|
|
||||||
// Private variables
|
|
||||||
static int32_t numObjects = -1;
|
|
||||||
|
|
||||||
// Private structures
|
|
||||||
// Header for objects in the file system table
|
|
||||||
struct objectHeader {
|
|
||||||
uint32_t objMagic;
|
|
||||||
uint32_t objId;
|
|
||||||
uint32_t instId;
|
|
||||||
uint32_t address;
|
|
||||||
} __attribute__((packed));;
|
|
||||||
|
|
||||||
struct fileHeader {
|
|
||||||
uint32_t id;
|
|
||||||
uint16_t instId;
|
|
||||||
uint16_t size;
|
|
||||||
} __attribute__((packed));
|
|
||||||
|
|
||||||
|
|
||||||
#define MAX_BADMAGIC 1000
|
|
||||||
|
|
||||||
static const struct flashfs_cfg * cfg;
|
|
||||||
/**
|
|
||||||
* @brief Initialize the flash object setting FS
|
|
||||||
* @return 0 if success, -1 if failure
|
|
||||||
*/
|
|
||||||
int32_t PIOS_FLASHFS_Init(const struct flashfs_cfg * new_cfg)
|
|
||||||
{
|
|
||||||
cfg = new_cfg;
|
|
||||||
|
|
||||||
// Check for valid object table or create one
|
|
||||||
uint32_t object_table_magic;
|
|
||||||
uint32_t magic_fail_count = 0;
|
|
||||||
bool magic_good = false;
|
|
||||||
|
|
||||||
while(!magic_good) {
|
|
||||||
if (PIOS_Flash_Jedec_ReadData(0, (uint8_t *)&object_table_magic, sizeof(object_table_magic)) != 0)
|
|
||||||
return -1;
|
|
||||||
if(object_table_magic != new_cfg->table_magic) {
|
|
||||||
if(magic_fail_count++ > MAX_BADMAGIC) {
|
|
||||||
if(PIOS_FLASHFS_Format() != 0)
|
|
||||||
return -1;
|
|
||||||
#if defined(PIOS_LED_HEARTBEAT)
|
|
||||||
PIOS_LED_Toggle(PIOS_LED_HEARTBEAT);
|
|
||||||
#endif /* PIOS_LED_HEARTBEAT */
|
|
||||||
magic_fail_count = 0;
|
|
||||||
magic_good = true;
|
|
||||||
} else {
|
|
||||||
PIOS_DELAY_WaituS(1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
magic_good = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t addr = cfg->obj_table_start;
|
|
||||||
struct objectHeader header;
|
|
||||||
numObjects = 0;
|
|
||||||
|
|
||||||
// Loop through header area while objects detect to count how many saved
|
|
||||||
while(addr < cfg->obj_table_end) {
|
|
||||||
// Read the instance data
|
|
||||||
if (PIOS_Flash_Jedec_ReadData(addr, (uint8_t *)&header, sizeof(header)) != 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
// Counting number of valid headers
|
|
||||||
if(header.objMagic != cfg->obj_magic)
|
|
||||||
break;
|
|
||||||
|
|
||||||
numObjects++;
|
|
||||||
addr += sizeof(header);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Erase the whole flash chip and create the file system
|
|
||||||
* @return 0 if successful, -1 if not
|
|
||||||
*/
|
|
||||||
int32_t PIOS_FLASHFS_Format()
|
|
||||||
{
|
|
||||||
if(PIOS_Flash_Jedec_EraseChip() != 0)
|
|
||||||
return -1;
|
|
||||||
if(PIOS_FLASHFS_ClearObjectTableHeader() != 0)
|
|
||||||
return -1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Erase the headers for all objects in the flash chip
|
|
||||||
* @return 0 if successful, -1 if not
|
|
||||||
*/
|
|
||||||
static int32_t PIOS_FLASHFS_ClearObjectTableHeader()
|
|
||||||
{
|
|
||||||
if(PIOS_Flash_Jedec_EraseSector(0) != 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (PIOS_Flash_Jedec_WriteData(0, (uint8_t *)&cfg->table_magic, sizeof(cfg->table_magic)) != 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
uint32_t object_table_magic;
|
|
||||||
PIOS_Flash_Jedec_ReadData(0, (uint8_t *)&object_table_magic, sizeof(object_table_magic));
|
|
||||||
if(object_table_magic != cfg->table_magic)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get the address of an object
|
|
||||||
* @param obj UAVObjHandle for that object
|
|
||||||
* @parma instId Instance id for that object
|
|
||||||
* @return address if successful, -1 if not found
|
|
||||||
*/
|
|
||||||
static int32_t PIOS_FLASHFS_GetObjAddress(uint32_t objId, uint16_t instId)
|
|
||||||
{
|
|
||||||
int32_t addr = cfg->obj_table_start;
|
|
||||||
struct objectHeader header;
|
|
||||||
|
|
||||||
// Loop through header area while objects detect to count how many saved
|
|
||||||
while(addr < cfg->obj_table_end) {
|
|
||||||
// Read the instance data
|
|
||||||
if (PIOS_Flash_Jedec_ReadData(addr, (uint8_t *) &header, sizeof(header)) != 0)
|
|
||||||
return -1;
|
|
||||||
if(header.objMagic != cfg->obj_magic)
|
|
||||||
break; // stop searching once hit first non-object header
|
|
||||||
else if (header.objId == objId && header.instId == instId)
|
|
||||||
break;
|
|
||||||
addr += sizeof(header);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (header.objId == objId && header.instId == instId)
|
|
||||||
return header.address;
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns an address for a new object and creates entry into object table
|
|
||||||
* @param[in] obj Object handle for object to be saved
|
|
||||||
* @param[in] instId The instance id of object to be saved
|
|
||||||
* @return 0 if success or error code
|
|
||||||
* @retval -1 Object not found
|
|
||||||
* @retval -2 No room in object table
|
|
||||||
* @retval -3 Unable to write entry into object table
|
|
||||||
* @retval -4 FS not initialized
|
|
||||||
* @retval -5
|
|
||||||
*/
|
|
||||||
int32_t PIOS_FLASHFS_GetNewAddress(uint32_t objId, uint16_t instId)
|
|
||||||
{
|
|
||||||
struct objectHeader header;
|
|
||||||
|
|
||||||
if(numObjects < 0)
|
|
||||||
return -4;
|
|
||||||
|
|
||||||
// Don't worry about max size of flash chip here, other code will catch that
|
|
||||||
header.objMagic = cfg->obj_magic;
|
|
||||||
header.objId = objId;
|
|
||||||
header.instId = instId;
|
|
||||||
header.address = cfg->obj_table_end + cfg->sector_size * numObjects;
|
|
||||||
|
|
||||||
int32_t addr = cfg->obj_table_start + sizeof(header) * numObjects;
|
|
||||||
|
|
||||||
// No room for this header in object table
|
|
||||||
if((addr + sizeof(header)) > cfg->obj_table_end)
|
|
||||||
return -2;
|
|
||||||
|
|
||||||
// Verify the address is within the chip
|
|
||||||
if((addr + cfg->sector_size) > cfg->chip_size)
|
|
||||||
return -5;
|
|
||||||
|
|
||||||
if(PIOS_Flash_Jedec_WriteData(addr, (uint8_t *) &header, sizeof(header)) != 0)
|
|
||||||
return -3;
|
|
||||||
|
|
||||||
// This numObejcts value must stay consistent or there will be a break in the table
|
|
||||||
// and later the table will have bad values in it
|
|
||||||
numObjects++;
|
|
||||||
return header.address;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Saves one object instance per sector
|
|
||||||
* @param[in] obj UAVObjHandle the object to save
|
|
||||||
* @param[in] instId The instance of the object to save
|
|
||||||
* @return 0 if success or -1 if failure
|
|
||||||
* @note This uses one sector on the flash chip per object so that no buffering in ram
|
|
||||||
* must be done when erasing the sector before a save
|
|
||||||
*/
|
|
||||||
int32_t PIOS_FLASHFS_ObjSave(UAVObjHandle obj, uint16_t instId, uint8_t * data)
|
|
||||||
{
|
|
||||||
uint32_t objId = UAVObjGetID(obj);
|
|
||||||
uint8_t crc = 0;
|
|
||||||
|
|
||||||
if(PIOS_Flash_Jedec_StartTransaction() != 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
int32_t addr = PIOS_FLASHFS_GetObjAddress(objId, instId);
|
|
||||||
|
|
||||||
// Object currently not saved
|
|
||||||
if(addr < 0)
|
|
||||||
addr = PIOS_FLASHFS_GetNewAddress(objId, instId);
|
|
||||||
|
|
||||||
// Could not allocate a sector
|
|
||||||
if(addr < 0) {
|
|
||||||
PIOS_Flash_Jedec_EndTransaction();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct fileHeader header = {
|
|
||||||
.id = objId,
|
|
||||||
.instId = instId,
|
|
||||||
.size = UAVObjGetNumBytes(obj)
|
|
||||||
};
|
|
||||||
|
|
||||||
// Update CRC
|
|
||||||
crc = PIOS_CRC_updateCRC(0, (uint8_t *) &header, sizeof(header));
|
|
||||||
crc = PIOS_CRC_updateCRC(crc, (uint8_t *) data, UAVObjGetNumBytes(obj));
|
|
||||||
|
|
||||||
if(PIOS_Flash_Jedec_EraseSector(addr) != 0) {
|
|
||||||
PIOS_Flash_Jedec_EndTransaction();
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct pios_flash_chunk chunks[3] = {
|
|
||||||
{
|
|
||||||
.addr = (uint8_t *) &header,
|
|
||||||
.len = sizeof(header),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.addr = (uint8_t *) data,
|
|
||||||
.len = UAVObjGetNumBytes(obj)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.addr = (uint8_t *) &crc,
|
|
||||||
.len = sizeof(crc)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if(PIOS_Flash_Jedec_WriteChunks(addr, chunks, NELEMENTS(chunks)) != 0) {
|
|
||||||
PIOS_Flash_Jedec_EndTransaction();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(PIOS_Flash_Jedec_EndTransaction() != 0) {
|
|
||||||
PIOS_Flash_Jedec_EndTransaction();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Load one object instance per sector
|
|
||||||
* @param[in] obj UAVObjHandle the object to save
|
|
||||||
* @param[in] instId The instance of the object to save
|
|
||||||
* @return 0 if success or error code
|
|
||||||
* @retval -1 if object not in file table
|
|
||||||
* @retval -2 if unable to retrieve object header
|
|
||||||
* @retval -3 if loaded data instId or objId don't match
|
|
||||||
* @retval -4 if unable to retrieve instance data
|
|
||||||
* @retval -5 if unable to read CRC
|
|
||||||
* @retval -6 if CRC doesn't match
|
|
||||||
* @note This uses one sector on the flash chip per object so that no buffering in ram
|
|
||||||
* must be done when erasing the sector before a save
|
|
||||||
*/
|
|
||||||
int32_t PIOS_FLASHFS_ObjLoad(UAVObjHandle obj, uint16_t instId, uint8_t * data)
|
|
||||||
{
|
|
||||||
uint32_t objId = UAVObjGetID(obj);
|
|
||||||
uint16_t objSize = UAVObjGetNumBytes(obj);
|
|
||||||
uint8_t crc = 0;
|
|
||||||
uint8_t crcFlash = 0;
|
|
||||||
const uint8_t crc_read_step = 8;
|
|
||||||
uint8_t crc_read_buffer[crc_read_step];
|
|
||||||
|
|
||||||
if(PIOS_Flash_Jedec_StartTransaction() != 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
int32_t addr = PIOS_FLASHFS_GetObjAddress(objId, instId);
|
|
||||||
|
|
||||||
// Object currently not saved
|
|
||||||
if(addr < 0) {
|
|
||||||
PIOS_Flash_Jedec_EndTransaction();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct fileHeader header;
|
|
||||||
|
|
||||||
// Load header
|
|
||||||
// This information IS redundant with the object table id. Oh well. Better safe than sorry.
|
|
||||||
if(PIOS_Flash_Jedec_ReadData(addr, (uint8_t *) &header, sizeof(header)) != 0) {
|
|
||||||
PIOS_Flash_Jedec_EndTransaction();
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update CRC
|
|
||||||
crc = PIOS_CRC_updateCRC(0, (uint8_t *) &header, sizeof(header));
|
|
||||||
|
|
||||||
if((header.id != objId) || (header.instId != instId)) {
|
|
||||||
PIOS_Flash_Jedec_EndTransaction();
|
|
||||||
return -3;
|
|
||||||
}
|
|
||||||
|
|
||||||
// To avoid having to allocate the RAM for a copy of the object, we read by chunks
|
|
||||||
// and compute the CRC
|
|
||||||
for(uint32_t i = 0; i < objSize; i += crc_read_step) {
|
|
||||||
PIOS_Flash_Jedec_ReadData(addr + sizeof(header) + i, crc_read_buffer, crc_read_step);
|
|
||||||
uint8_t valid_bytes = ((i + crc_read_step) >= objSize) ? objSize - i : crc_read_step;
|
|
||||||
crc = PIOS_CRC_updateCRC(crc, crc_read_buffer, valid_bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read CRC (written so will work when CRC changes to uint16)
|
|
||||||
if(PIOS_Flash_Jedec_ReadData(addr + sizeof(header) + objSize, (uint8_t *) &crcFlash, sizeof(crcFlash)) != 0) {
|
|
||||||
PIOS_Flash_Jedec_EndTransaction();
|
|
||||||
return -5;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(crc != crcFlash) {
|
|
||||||
PIOS_Flash_Jedec_EndTransaction();
|
|
||||||
return -6;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read the instance data
|
|
||||||
if (PIOS_Flash_Jedec_ReadData(addr + sizeof(header), data, objSize) != 0) {
|
|
||||||
PIOS_Flash_Jedec_EndTransaction();
|
|
||||||
return -4;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(PIOS_Flash_Jedec_EndTransaction() != 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Delete object from flash
|
|
||||||
* @param[in] obj UAVObjHandle the object to save
|
|
||||||
* @param[in] instId The instance of the object to save
|
|
||||||
* @return 0 if success or error code
|
|
||||||
* @retval -1 if object not in file table
|
|
||||||
* @retval -2 Erase failed
|
|
||||||
* @note To avoid buffering the file table (1k ram!) the entry in the file table
|
|
||||||
* remains but destination sector is erased. This will make the load fail as the
|
|
||||||
* file header won't match the object. At next save it goes back there.
|
|
||||||
*/
|
|
||||||
int32_t PIOS_FLASHFS_ObjDelete(UAVObjHandle obj, uint16_t instId)
|
|
||||||
{
|
|
||||||
uint32_t objId = UAVObjGetID(obj);
|
|
||||||
|
|
||||||
int32_t addr = PIOS_FLASHFS_GetObjAddress(objId, instId);
|
|
||||||
|
|
||||||
// Object currently not saved
|
|
||||||
if(addr < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if(PIOS_Flash_Jedec_EraseSector(addr) != 0)
|
|
||||||
return -2;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -31,6 +31,8 @@
|
|||||||
/* Project Includes */
|
/* Project Includes */
|
||||||
#include "pios.h"
|
#include "pios.h"
|
||||||
|
|
||||||
|
#include "uavobjectmanager.h"
|
||||||
|
|
||||||
#if defined(PIOS_INCLUDE_GCSRCVR)
|
#if defined(PIOS_INCLUDE_GCSRCVR)
|
||||||
|
|
||||||
#include "pios_gcsrcvr_priv.h"
|
#include "pios_gcsrcvr_priv.h"
|
||||||
|
@ -141,7 +141,7 @@ static void PIOS_MPU6000_Config(struct pios_mpu6000_cfg const * cfg)
|
|||||||
|
|
||||||
// Reset chip
|
// Reset chip
|
||||||
while (PIOS_MPU6000_SetReg(PIOS_MPU6000_PWR_MGMT_REG, PIOS_MPU6000_PWRMGMT_IMU_RST) != 0);
|
while (PIOS_MPU6000_SetReg(PIOS_MPU6000_PWR_MGMT_REG, PIOS_MPU6000_PWRMGMT_IMU_RST) != 0);
|
||||||
PIOS_DELAY_WaitmS(300);
|
PIOS_DELAY_WaitmS(100);
|
||||||
|
|
||||||
// Reset chip and fifo
|
// Reset chip and fifo
|
||||||
while (PIOS_MPU6000_SetReg(PIOS_MPU6000_USER_CTRL_REG,
|
while (PIOS_MPU6000_SetReg(PIOS_MPU6000_USER_CTRL_REG,
|
||||||
|
337
flight/PiOS/STM32F4xx/pios_flash_internal.c
Normal file
337
flight/PiOS/STM32F4xx/pios_flash_internal.c
Normal file
@ -0,0 +1,337 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file pios_flash_internal.c
|
||||||
|
* @author PhoenixPilot, http://github.com/PhoenixPilot, Copyright (C) 2012
|
||||||
|
* @addtogroup
|
||||||
|
* @{
|
||||||
|
* @addtogroup
|
||||||
|
* @{
|
||||||
|
* @brief Provides a flash driver for the STM32 internal flash sectors
|
||||||
|
*****************************************************************************/
|
||||||
|
/*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "pios.h"
|
||||||
|
|
||||||
|
#if defined(PIOS_INCLUDE_FLASH_INTERNAL)
|
||||||
|
|
||||||
|
#include "stm32f4xx_flash.h"
|
||||||
|
#include "pios_flash_internal_priv.h"
|
||||||
|
#include "pios_flash.h"
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
struct device_flash_sector {
|
||||||
|
uint32_t start;
|
||||||
|
uint32_t size;
|
||||||
|
uint16_t st_sector;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct device_flash_sector flash_sectors[] = {
|
||||||
|
[0] = {
|
||||||
|
.start = 0x08000000,
|
||||||
|
.size = 16 * 1024,
|
||||||
|
.st_sector = FLASH_Sector_0,
|
||||||
|
},
|
||||||
|
[1] = {
|
||||||
|
.start = 0x08004000,
|
||||||
|
.size = 16 * 1024,
|
||||||
|
.st_sector = FLASH_Sector_1,
|
||||||
|
},
|
||||||
|
[2] = {
|
||||||
|
.start = 0x08008000,
|
||||||
|
.size = 16 * 1024,
|
||||||
|
.st_sector = FLASH_Sector_2,
|
||||||
|
},
|
||||||
|
[3] = {
|
||||||
|
.start = 0x0800C000,
|
||||||
|
.size = 16 * 1024,
|
||||||
|
.st_sector = FLASH_Sector_3,
|
||||||
|
},
|
||||||
|
[4] = {
|
||||||
|
.start = 0x08010000,
|
||||||
|
.size = 64 * 1024,
|
||||||
|
.st_sector = FLASH_Sector_4,
|
||||||
|
},
|
||||||
|
[5] = {
|
||||||
|
.start = 0x08020000,
|
||||||
|
.size = 128 * 1024,
|
||||||
|
.st_sector = FLASH_Sector_5,
|
||||||
|
},
|
||||||
|
[6] = {
|
||||||
|
.start = 0x08040000,
|
||||||
|
.size = 128 * 1024,
|
||||||
|
.st_sector = FLASH_Sector_6,
|
||||||
|
},
|
||||||
|
[7] = {
|
||||||
|
.start = 0x08060000,
|
||||||
|
.size = 128 * 1024,
|
||||||
|
.st_sector = FLASH_Sector_7,
|
||||||
|
},
|
||||||
|
[8] = {
|
||||||
|
.start = 0x08080000,
|
||||||
|
.size = 128 * 1024,
|
||||||
|
.st_sector = FLASH_Sector_8,
|
||||||
|
},
|
||||||
|
[9] = {
|
||||||
|
.start = 0x080A0000,
|
||||||
|
.size = 128 * 1024,
|
||||||
|
.st_sector = FLASH_Sector_9,
|
||||||
|
},
|
||||||
|
[10] = {
|
||||||
|
.start = 0x080C0000,
|
||||||
|
.size = 128 * 1024,
|
||||||
|
.st_sector = FLASH_Sector_10,
|
||||||
|
},
|
||||||
|
[11] = {
|
||||||
|
.start = 0x080E0000,
|
||||||
|
.size = 128 * 1024,
|
||||||
|
.st_sector = FLASH_Sector_11,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool PIOS_Flash_Internal_GetSectorInfo(uint32_t address, uint8_t * sector_number, uint32_t *sector_start, uint32_t *sector_size)
|
||||||
|
{
|
||||||
|
for (uint8_t i = 0; i < NELEMENTS(flash_sectors); i++) {
|
||||||
|
struct device_flash_sector * sector = &flash_sectors[i];
|
||||||
|
if ((address >= sector->start) &&
|
||||||
|
(address < (sector->start + sector->size))) {
|
||||||
|
/* address lies within this sector */
|
||||||
|
*sector_number = sector->st_sector;
|
||||||
|
*sector_start = sector->start;
|
||||||
|
*sector_size = sector->size;
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
enum pios_internal_flash_dev_magic {
|
||||||
|
PIOS_INTERNAL_FLASH_DEV_MAGIC = 0x33445902,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pios_internal_flash_dev {
|
||||||
|
enum pios_internal_flash_dev_magic magic;
|
||||||
|
|
||||||
|
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||||
|
xSemaphoreHandle transaction_lock;
|
||||||
|
#endif /* defined(PIOS_INCLUDE_FREERTOS) */
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool PIOS_Flash_Internal_Validate(struct pios_internal_flash_dev * flash_dev) {
|
||||||
|
return (flash_dev && (flash_dev->magic == PIOS_INTERNAL_FLASH_DEV_MAGIC));
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||||
|
static struct pios_internal_flash_dev * PIOS_Flash_Internal_alloc(void)
|
||||||
|
{
|
||||||
|
struct pios_internal_flash_dev * flash_dev;
|
||||||
|
|
||||||
|
flash_dev = (struct pios_internal_flash_dev *)pvPortMalloc(sizeof(* flash_dev));
|
||||||
|
if (!flash_dev) return (NULL);
|
||||||
|
|
||||||
|
flash_dev->magic = PIOS_INTERNAL_FLASH_DEV_MAGIC;
|
||||||
|
|
||||||
|
return(flash_dev);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static struct pios_internal_flash_dev pios_internal_flash_devs[PIOS_INTERNAL_FLASH_MAX_DEVS];
|
||||||
|
static uint8_t pios_internal_flash_num_devs;
|
||||||
|
static struct pios_internal_flash_dev * PIOS_Flash_Internal_alloc(void)
|
||||||
|
{
|
||||||
|
struct pios_internal_flash_dev * flash_dev;
|
||||||
|
|
||||||
|
if (pios_internal_flash_num_devs >= PIOS_INTERNAL_FLASH_MAX_DEVS) {
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
flash_dev = &pios_internal_flash_devs[pios_internal_flash_num_devs++];
|
||||||
|
flash_dev->magic = PIOS_INTERNAL_FLASH_DEV_MAGIC;
|
||||||
|
|
||||||
|
return (flash_dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* defined(PIOS_INCLUDE_FREERTOS) */
|
||||||
|
|
||||||
|
int32_t PIOS_Flash_Internal_Init(uintptr_t * flash_id, const struct pios_flash_internal_cfg * cfg)
|
||||||
|
{
|
||||||
|
struct pios_internal_flash_dev * flash_dev;
|
||||||
|
|
||||||
|
flash_dev = PIOS_Flash_Internal_alloc();
|
||||||
|
if (flash_dev == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||||
|
flash_dev->transaction_lock = xSemaphoreCreateMutex();
|
||||||
|
#endif /* defined(PIOS_INCLUDE_FREERTOS) */
|
||||||
|
|
||||||
|
*flash_id = (uintptr_t) flash_dev;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************************
|
||||||
|
*
|
||||||
|
* Provide a PIOS flash driver API
|
||||||
|
*
|
||||||
|
*********************************/
|
||||||
|
#include "pios_flash.h"
|
||||||
|
|
||||||
|
static int32_t PIOS_Flash_Internal_StartTransaction(uintptr_t flash_id)
|
||||||
|
{
|
||||||
|
struct pios_internal_flash_dev * flash_dev = (struct pios_internal_flash_dev *)flash_id;
|
||||||
|
|
||||||
|
if (!PIOS_Flash_Internal_Validate(flash_dev))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||||
|
if (xSemaphoreTake(flash_dev->transaction_lock, portMAX_DELAY) != pdTRUE)
|
||||||
|
return -2;
|
||||||
|
#endif /* defined(PIOS_INCLUDE_FREERTOS) */
|
||||||
|
|
||||||
|
/* Unlock the internal flash so we can write to it */
|
||||||
|
FLASH_Unlock();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t PIOS_Flash_Internal_EndTransaction(uintptr_t flash_id)
|
||||||
|
{
|
||||||
|
struct pios_internal_flash_dev * flash_dev = (struct pios_internal_flash_dev *)flash_id;
|
||||||
|
|
||||||
|
if (!PIOS_Flash_Internal_Validate(flash_dev))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||||
|
if (xSemaphoreGive(flash_dev->transaction_lock) != pdTRUE)
|
||||||
|
return -2;
|
||||||
|
#endif /* defined(PIOS_INCLUDE_FREERTOS) */
|
||||||
|
|
||||||
|
/* Lock the internal flash again so we can no longer write to it */
|
||||||
|
FLASH_Lock();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t PIOS_Flash_Internal_EraseSector(uintptr_t flash_id, uint32_t addr)
|
||||||
|
{
|
||||||
|
struct pios_internal_flash_dev * flash_dev = (struct pios_internal_flash_dev *)flash_id;
|
||||||
|
|
||||||
|
if (!PIOS_Flash_Internal_Validate(flash_dev))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
uint8_t sector_number;
|
||||||
|
uint32_t sector_start;
|
||||||
|
uint32_t sector_size;
|
||||||
|
if (!PIOS_Flash_Internal_GetSectorInfo(addr,
|
||||||
|
§or_number,
|
||||||
|
§or_start,
|
||||||
|
§or_size)) {
|
||||||
|
/* We're asking for an invalid flash address */
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FLASH_EraseSector(sector_number, VoltageRange_3) != FLASH_COMPLETE)
|
||||||
|
return -3;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t PIOS_Flash_Internal_WriteData(uintptr_t flash_id, uint32_t addr, uint8_t * data, uint16_t len)
|
||||||
|
{
|
||||||
|
PIOS_Assert(data);
|
||||||
|
|
||||||
|
struct pios_internal_flash_dev * flash_dev = (struct pios_internal_flash_dev *)flash_id;
|
||||||
|
|
||||||
|
if (!PIOS_Flash_Internal_Validate(flash_dev))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
uint8_t sector_number;
|
||||||
|
uint32_t sector_start;
|
||||||
|
uint32_t sector_size;
|
||||||
|
|
||||||
|
/* Ensure that the base address is in a valid sector */
|
||||||
|
if (!PIOS_Flash_Internal_GetSectorInfo(addr,
|
||||||
|
§or_number,
|
||||||
|
§or_start,
|
||||||
|
§or_size)) {
|
||||||
|
/* We're asking for an invalid flash address */
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure that the entire write occurs within the same sector */
|
||||||
|
if ((uintptr_t)addr + len > sector_start + sector_size) {
|
||||||
|
/* Write crosses the end of the sector */
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write the data */
|
||||||
|
for (uint16_t i = 0; i < len; i++) {
|
||||||
|
FLASH_Status status;
|
||||||
|
/*
|
||||||
|
* This is inefficient. Should try to do word writes.
|
||||||
|
* Not sure if word writes need to be aligned though.
|
||||||
|
*/
|
||||||
|
status = FLASH_ProgramByte(addr + i, data[i]);
|
||||||
|
PIOS_Assert(status == FLASH_COMPLETE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t PIOS_Flash_Internal_ReadData(uintptr_t flash_id, uint32_t addr, uint8_t * data, uint16_t len)
|
||||||
|
{
|
||||||
|
PIOS_Assert(data);
|
||||||
|
|
||||||
|
struct pios_internal_flash_dev * flash_dev = (struct pios_internal_flash_dev *)flash_id;
|
||||||
|
|
||||||
|
if (!PIOS_Flash_Internal_Validate(flash_dev))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
uint8_t sector_number;
|
||||||
|
uint32_t sector_start;
|
||||||
|
uint32_t sector_size;
|
||||||
|
|
||||||
|
/* Ensure that the base address is in a valid sector */
|
||||||
|
if (!PIOS_Flash_Internal_GetSectorInfo(addr,
|
||||||
|
§or_number,
|
||||||
|
§or_start,
|
||||||
|
§or_size)) {
|
||||||
|
/* We're asking for an invalid flash address */
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure that the entire read occurs within the same sector */
|
||||||
|
if ((uintptr_t)addr + len > sector_start + sector_size) {
|
||||||
|
/* Read crosses the end of the sector */
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read the data into the buffer directly */
|
||||||
|
memcpy(data, (void *)addr, len);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Provide a flash driver to external drivers */
|
||||||
|
const struct pios_flash_driver pios_internal_flash_driver = {
|
||||||
|
.start_transaction = PIOS_Flash_Internal_StartTransaction,
|
||||||
|
.end_transaction = PIOS_Flash_Internal_EndTransaction,
|
||||||
|
.erase_sector = PIOS_Flash_Internal_EraseSector,
|
||||||
|
.write_data = PIOS_Flash_Internal_WriteData,
|
||||||
|
.read_data = PIOS_Flash_Internal_ReadData,
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* defined(PIOS_INCLUDE_FLASH_INTERNAL) */
|
@ -33,9 +33,13 @@
|
|||||||
|
|
||||||
extern const char *PIOS_DEBUG_AssertMsg;
|
extern const char *PIOS_DEBUG_AssertMsg;
|
||||||
|
|
||||||
|
#ifdef USE_SIM_POSIX
|
||||||
|
void PIOS_DEBUG_Init(void);
|
||||||
|
#else
|
||||||
#include <pios_tim_priv.h>
|
#include <pios_tim_priv.h>
|
||||||
|
|
||||||
void PIOS_DEBUG_Init(const struct pios_tim_channel * channels, uint8_t num_channels);
|
void PIOS_DEBUG_Init(const struct pios_tim_channel * channels, uint8_t num_channels);
|
||||||
|
#endif
|
||||||
void PIOS_DEBUG_PinHigh(uint8_t pin);
|
void PIOS_DEBUG_PinHigh(uint8_t pin);
|
||||||
void PIOS_DEBUG_PinLow(uint8_t pin);
|
void PIOS_DEBUG_PinLow(uint8_t pin);
|
||||||
void PIOS_DEBUG_PinValue8Bit(uint8_t value);
|
void PIOS_DEBUG_PinValue8Bit(uint8_t value);
|
||||||
|
47
flight/PiOS/inc/pios_flash.h
Normal file
47
flight/PiOS/inc/pios_flash.h
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file pios_flash.h
|
||||||
|
* @author PhoenixPilot, http://github.com/PhoenixPilot, Copyright (C) 2012
|
||||||
|
* @addtogroup PIOS PIOS Core hardware abstraction layer
|
||||||
|
* @{
|
||||||
|
* @addtogroup PIOS_FLASH Flash Driver API Definition
|
||||||
|
* @{
|
||||||
|
* @brief Flash Driver API Definition
|
||||||
|
*****************************************************************************/
|
||||||
|
/*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PIOS_FLASH_H_
|
||||||
|
#define PIOS_FLASH_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
struct pios_flash_chunk {
|
||||||
|
uint8_t * addr;
|
||||||
|
uint32_t len;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pios_flash_driver {
|
||||||
|
int32_t (*start_transaction)(uintptr_t flash_id);
|
||||||
|
int32_t (*end_transaction)(uintptr_t flash_id);
|
||||||
|
int32_t (*erase_chip)(uintptr_t flash_id);
|
||||||
|
int32_t (*erase_sector)(uintptr_t flash_id, uint32_t addr);
|
||||||
|
int32_t (*write_data)(uintptr_t flash_id, uint32_t addr, uint8_t * data, uint16_t len);
|
||||||
|
int32_t (*write_chunks)(uintptr_t flash_id, uint32_t addr, struct pios_flash_chunk chunks[], uint32_t num_chunks);
|
||||||
|
int32_t (*read_data)(uintptr_t flash_id, uint32_t addr, uint8_t * data, uint16_t len);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* PIOS_FLASH_H_ */
|
@ -1,15 +1,12 @@
|
|||||||
/**
|
/**
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* @addtogroup PIOS PIOS Core hardware abstraction layer
|
* @file pios_flash_internal_priv.h
|
||||||
|
* @author PhoenixPilot, http://github.com/PhoenixPilot, Copyright (C) 2012
|
||||||
|
* @addtogroup
|
||||||
* @{
|
* @{
|
||||||
* @addtogroup PIOS_SERVO RC Servo Functions
|
* @addtogroup
|
||||||
* @{
|
* @{
|
||||||
*
|
* @brief Provides a flash driver for the STM32 internal flash sectors
|
||||||
* @file pios_servo.h
|
|
||||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
|
||||||
* @brief RC Servo functions header.
|
|
||||||
* @see The GNU Public License (GPL) Version 3
|
|
||||||
*
|
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
/*
|
/*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
@ -27,17 +24,17 @@
|
|||||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PIOS_SERVO_H
|
#ifndef PIOS_FLASH_INTERNAL_H_
|
||||||
#define PIOS_SERVO_H
|
#define PIOS_FLASH_INTERNAL_H_
|
||||||
|
|
||||||
/* Public Functions */
|
#include "pios_flash.h" /* API definition for flash drivers */
|
||||||
extern void PIOS_Servo_Init(void);
|
|
||||||
extern void PIOS_Servo_SetHz(const uint16_t * speeds, uint8_t num_banks);
|
|
||||||
extern void PIOS_Servo_Set(uint8_t Servo, uint16_t Position);
|
|
||||||
|
|
||||||
#endif /* PIOS_SERVO_H */
|
extern const struct pios_flash_driver pios_internal_flash_driver;
|
||||||
|
|
||||||
/**
|
struct pios_flash_internal_cfg {
|
||||||
* @}
|
;
|
||||||
* @}
|
};
|
||||||
*/
|
|
||||||
|
extern int32_t PIOS_Flash_Internal_Init(uintptr_t * flash_id, const struct pios_flash_internal_cfg * cfg);
|
||||||
|
|
||||||
|
#endif /* PIOS_FLASH_INTERNAL_H_ */
|
@ -1,50 +0,0 @@
|
|||||||
/**
|
|
||||||
******************************************************************************
|
|
||||||
*
|
|
||||||
* @addtogroup PIOS PIOS Core hardware abstraction layer
|
|
||||||
* @{
|
|
||||||
* @addtogroup PIOS_FLASH Flash device handler
|
|
||||||
* @{
|
|
||||||
*
|
|
||||||
* @file pios_flash_w25x.h
|
|
||||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
|
||||||
* @brief Driver for talking to W25X flash chip (and most JEDEC chips)
|
|
||||||
* @see The GNU Public License (GPL) Version 3
|
|
||||||
*
|
|
||||||
*****************************************************************************/
|
|
||||||
/*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct pios_flash_jedec_cfg {
|
|
||||||
uint32_t sector_erase;
|
|
||||||
uint32_t chip_erase;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct pios_flash_chunk {
|
|
||||||
uint8_t * addr;
|
|
||||||
uint32_t len;
|
|
||||||
};
|
|
||||||
|
|
||||||
int32_t PIOS_Flash_Jedec_Init(uint32_t spi_id, uint32_t slave_num, const struct pios_flash_jedec_cfg * cfg);
|
|
||||||
int32_t PIOS_Flash_Jedec_ReadStatus();
|
|
||||||
int32_t PIOS_Flash_Jedec_ReadID();
|
|
||||||
int32_t PIOS_Flash_Jedec_EraseChip();
|
|
||||||
int32_t PIOS_Flash_Jedec_EraseSector(uint32_t add);
|
|
||||||
int32_t PIOS_Flash_Jedec_WriteData(uint32_t addr, uint8_t * data, uint16_t len);
|
|
||||||
int32_t PIOS_Flash_Jedec_ReadData(uint32_t addr, uint8_t * data, uint16_t len);
|
|
||||||
int32_t PIOS_Flash_Jedec_WriteChunks(uint32_t addr, struct pios_flash_chunk * p_chunk, uint32_t num);
|
|
||||||
int32_t PIOS_Flash_Jedec_StartTransaction();
|
|
||||||
int32_t PIOS_Flash_Jedec_EndTransaction();
|
|
@ -1,15 +1,14 @@
|
|||||||
/**
|
/**
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
|
*
|
||||||
* @addtogroup PIOS PIOS Core hardware abstraction layer
|
* @addtogroup PIOS PIOS Core hardware abstraction layer
|
||||||
* @{
|
* @{
|
||||||
* @addtogroup PIOS_RCVR RCVR Functions
|
* @addtogroup PIOS_FLASH Flash device handler
|
||||||
* @brief PIOS interface for RCVR drivers
|
|
||||||
* @{
|
* @{
|
||||||
*
|
*
|
||||||
* @file pios_rcvr_priv.h
|
* @file pios_flash_jedec_priv.h
|
||||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||||
* Parts by Thorsten Klose (tk@midibox.org)
|
* @brief Driver for talking to most JEDEC flash chips
|
||||||
* @brief USART private definitions.
|
|
||||||
* @see The GNU Public License (GPL) Version 3
|
* @see The GNU Public License (GPL) Version 3
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
@ -29,20 +28,25 @@
|
|||||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PIOS_RCVR_PRIV_H
|
#ifndef PIOS_FLASH_JEDEC_H_
|
||||||
#define PIOS_RCVR_PRIV_H
|
#define PIOS_FLASH_JEDEC_H_
|
||||||
|
|
||||||
#include <pios.h>
|
#include "pios_flash.h" /* API definition for flash drivers */
|
||||||
|
|
||||||
extern uint32_t pios_rcvr_max_channel;
|
extern const struct pios_flash_driver pios_jedec_flash_driver;
|
||||||
|
|
||||||
extern int32_t PIOS_RCVR_Init(uint32_t * rcvr_id, const struct pios_rcvr_driver * driver, const uint32_t lower_id);
|
#define JEDEC_MANUFACTURER_ST 0x20
|
||||||
|
#define JEDEC_MANUFACTURER_MACRONIX 0xC2
|
||||||
|
#define JEDEC_MANUFACTURER_WINBOND 0xEF
|
||||||
|
|
||||||
extern void PIOS_RCVR_IRQ_Handler(uint32_t rcvr_id);
|
struct pios_flash_jedec_cfg {
|
||||||
|
uint8_t expect_manufacturer;
|
||||||
|
uint8_t expect_memorytype;
|
||||||
|
uint8_t expect_capacity;
|
||||||
|
uint32_t sector_erase;
|
||||||
|
uint32_t chip_erase;
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* PIOS_RCVR_PRIV_H */
|
int32_t PIOS_Flash_Jedec_Init(uintptr_t * flash_id, uint32_t spi_id, uint32_t slave_num, const struct pios_flash_jedec_cfg * cfg);
|
||||||
|
|
||||||
/**
|
#endif /* PIOS_FLASH_JEDEC_H_ */
|
||||||
* @}
|
|
||||||
* @}
|
|
||||||
*/
|
|
@ -1,17 +1,12 @@
|
|||||||
/**
|
/**
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
|
* @file pios_flashfs.h
|
||||||
|
* @author PhoenixPilot, http://github.com/PhoenixPilot, Copyright (C) 2012
|
||||||
* @addtogroup PIOS PIOS Core hardware abstraction layer
|
* @addtogroup PIOS PIOS Core hardware abstraction layer
|
||||||
* @{
|
* @{
|
||||||
* @addtogroup PIOS_COM COM layer functions
|
* @addtogroup PIOS_FLASHFS Flash Filesystem API Definition
|
||||||
* @brief Hardware communication layer
|
|
||||||
* @{
|
* @{
|
||||||
*
|
* @brief Flash Filesystem API Definition
|
||||||
* @file pios_com_priv.h
|
|
||||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
|
||||||
* Parts by Thorsten Klose (tk@midibox.org)
|
|
||||||
* @brief COM private definitions.
|
|
||||||
* @see The GNU Public License (GPL) Version 3
|
|
||||||
*
|
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
/*
|
/*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
@ -29,16 +24,14 @@
|
|||||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PIOS_COM_PRIV_H
|
#ifndef PIOS_FLASHFS_H_
|
||||||
#define PIOS_COM_PRIV_H
|
#define PIOS_FLASHFS_H_
|
||||||
|
|
||||||
#include <pios.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
extern int32_t PIOS_COM_ReceiveHandler(uint32_t com_id);
|
int32_t PIOS_FLASHFS_Format(uint32_t fs_id);
|
||||||
|
int32_t PIOS_FLASHFS_ObjSave(uint32_t fs_id, uint32_t obj_id, uint16_t obj_inst_id, uint8_t * obj_data, uint16_t obj_size);
|
||||||
|
int32_t PIOS_FLASHFS_ObjLoad(uint32_t fs_id, uint32_t obj_id, uint16_t obj_inst_id, uint8_t * obj_data, uint16_t obj_size);
|
||||||
|
int32_t PIOS_FLASHFS_ObjDelete(uint32_t fs_id, uint32_t obj_id, uint16_t obj_inst_id);
|
||||||
|
|
||||||
#endif /* PIOS_COM_PRIV_H */
|
#endif /* PIOS_FLASHFS_H_ */
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
* @}
|
|
||||||
*/
|
|
46
flight/PiOS/inc/pios_flashfs_logfs_priv.h
Normal file
46
flight/PiOS/inc/pios_flashfs_logfs_priv.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file pios_flashfs_logfs_priv.h
|
||||||
|
* @author PhoenixPilot, http://github.com/PhoenixPilot, Copyright (C) 2012
|
||||||
|
* @addtogroup PIOS PIOS Core hardware abstraction layer
|
||||||
|
* @{
|
||||||
|
* @addtogroup PIOS_FLASHFS Flash Filesystem Function
|
||||||
|
* @{
|
||||||
|
* @brief Log Structured Filesystem for internal or external NOR Flash
|
||||||
|
*****************************************************************************/
|
||||||
|
/*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PIOS_FLASHFS_LOGFS_PRIV_H_
|
||||||
|
#define PIOS_FLASHFS_LOGFS_PRIV_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "pios_flash.h" /* struct pios_flash_driver */
|
||||||
|
|
||||||
|
struct flashfs_logfs_cfg {
|
||||||
|
uint32_t fs_magic;
|
||||||
|
uint32_t total_fs_size; /* Total size of all generations of the filesystem */
|
||||||
|
uint32_t arena_size; /* Max size of one generation of the filesystem */
|
||||||
|
uint32_t slot_size; /* Max size of a "file" */
|
||||||
|
|
||||||
|
uint32_t start_offset; /* Offset into flash where this filesystem starts */
|
||||||
|
uint32_t sector_size; /* Size of a flash erase block */
|
||||||
|
uint32_t page_size; /* Maximum flash burst write size */
|
||||||
|
};
|
||||||
|
|
||||||
|
int32_t PIOS_FLASHFS_Logfs_Init(uintptr_t * fs_id, const struct flashfs_logfs_cfg * cfg, const struct pios_flash_driver * driver, uintptr_t flash_id);
|
||||||
|
|
||||||
|
#endif /* PIOS_FLASHFS_LOGFS_PRIV_H_ */
|
@ -1,47 +0,0 @@
|
|||||||
/**
|
|
||||||
******************************************************************************
|
|
||||||
*
|
|
||||||
* @addtogroup PIOS PIOS Core hardware abstraction layer
|
|
||||||
* @{
|
|
||||||
* @addtogroup PIOS_FLASHFS_OBJLIST Object list based flash filesystem (low ram)
|
|
||||||
* @{
|
|
||||||
*
|
|
||||||
* @file pios_flashfs_objlist.h
|
|
||||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
|
||||||
* @brief A file system for storing UAVObject in flash chip
|
|
||||||
* @see The GNU Public License (GPL) Version 3
|
|
||||||
*
|
|
||||||
*****************************************************************************/
|
|
||||||
/*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "openpilot.h"
|
|
||||||
#include "uavobjectmanager.h"
|
|
||||||
|
|
||||||
struct flashfs_cfg {
|
|
||||||
uint32_t table_magic;
|
|
||||||
uint32_t obj_magic;
|
|
||||||
uint32_t obj_table_start;
|
|
||||||
uint32_t obj_table_end;
|
|
||||||
uint32_t sector_size;
|
|
||||||
uint32_t chip_size;
|
|
||||||
};
|
|
||||||
|
|
||||||
int32_t PIOS_FLASHFS_Init(const struct flashfs_cfg * cfg);
|
|
||||||
int32_t PIOS_FLASHFS_Format();
|
|
||||||
int32_t PIOS_FLASHFS_ObjSave(UAVObjHandle obj, uint16_t instId, uint8_t * data);
|
|
||||||
int32_t PIOS_FLASHFS_ObjLoad(UAVObjHandle obj, uint16_t instId, uint8_t * data);
|
|
||||||
int32_t PIOS_FLASHFS_ObjDelete(UAVObjHandle obj, uint16_t instId);
|
|
@ -51,6 +51,26 @@ typedef struct {
|
|||||||
/* Init module section */
|
/* Init module section */
|
||||||
extern initmodule_t __module_initcall_start[], __module_initcall_end[];
|
extern initmodule_t __module_initcall_start[], __module_initcall_end[];
|
||||||
|
|
||||||
|
#ifdef USE_SIM_POSIX
|
||||||
|
|
||||||
|
extern void InitModules();
|
||||||
|
extern void StartModules();
|
||||||
|
|
||||||
|
#define MODULE_INITCALL(ifn, sfn)
|
||||||
|
|
||||||
|
#define MODULE_TASKCREATE_ALL { \
|
||||||
|
/* Start all module threads */ \
|
||||||
|
StartModules(); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MODULE_INITIALISE_ALL { \
|
||||||
|
/* Initialize modules */ \
|
||||||
|
InitModules(); \
|
||||||
|
/* Initialize the system thread */ \
|
||||||
|
SystemModInitialize();}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
/* initcalls are now grouped by functionality into separate
|
/* initcalls are now grouped by functionality into separate
|
||||||
* subsections. Ordering inside the subsections is determined
|
* subsections. Ordering inside the subsections is determined
|
||||||
* by link order.
|
* by link order.
|
||||||
@ -77,6 +97,7 @@ extern initmodule_t __module_initcall_start[], __module_initcall_end[];
|
|||||||
if (fn->fn_tinit) \
|
if (fn->fn_tinit) \
|
||||||
(fn->fn_tinit)(); }
|
(fn->fn_tinit)(); }
|
||||||
|
|
||||||
|
#endif /* USE_SIM_POSIX */
|
||||||
#endif /* PIOS_INITCALL_H */
|
#endif /* PIOS_INITCALL_H */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -80,17 +80,17 @@ typedef struct {
|
|||||||
uint16_t OEM_AppliID; /* OEM/Application ID */
|
uint16_t OEM_AppliID; /* OEM/Application ID */
|
||||||
char ProdName[6]; /* Product Name */
|
char ProdName[6]; /* Product Name */
|
||||||
uint8_t ProdRev; /* Product Revision */
|
uint8_t ProdRev; /* Product Revision */
|
||||||
u32 ProdSN; /* Product Serial Number */
|
uint32_t ProdSN; /* Product Serial Number */
|
||||||
uint8_t Reserved1; /* Reserved1 */
|
uint8_t Reserved1; /* Reserved1 */
|
||||||
uint16_t ManufactDate; /* Manufacturing Date */
|
uint16_t ManufactDate; /* Manufacturing Date */
|
||||||
uint8_t msd_CRC; /* CRC */
|
uint8_t msd_CRC; /* CRC */
|
||||||
uint8_t Reserved2; /* always 1 */
|
uint8_t Reserved2; /* always 1 */
|
||||||
} SDCARDCidTypeDef;
|
} SDCARDCidTypeDef;
|
||||||
|
#ifndef USE_SIM_POSIX
|
||||||
/* Global Variables */
|
/* Global Variables */
|
||||||
extern VOLINFO PIOS_SDCARD_VolInfo;
|
extern VOLINFO PIOS_SDCARD_VolInfo;
|
||||||
extern uint8_t PIOS_SDCARD_Sector[SECTOR_SIZE];
|
extern uint8_t PIOS_SDCARD_Sector[SECTOR_SIZE];
|
||||||
|
#endif
|
||||||
/* Prototypes */
|
/* Prototypes */
|
||||||
extern int32_t PIOS_SDCARD_Init(uint32_t spi_id);
|
extern int32_t PIOS_SDCARD_Init(uint32_t spi_id);
|
||||||
extern int32_t PIOS_SDCARD_PowerOn(void);
|
extern int32_t PIOS_SDCARD_PowerOn(void);
|
||||||
@ -106,9 +106,10 @@ extern int32_t PIOS_SDCARD_StartupLog(void);
|
|||||||
extern int32_t PIOS_SDCARD_IsMounted();
|
extern int32_t PIOS_SDCARD_IsMounted();
|
||||||
extern int32_t PIOS_SDCARD_MountFS(uint32_t StartupLog);
|
extern int32_t PIOS_SDCARD_MountFS(uint32_t StartupLog);
|
||||||
extern int32_t PIOS_SDCARD_GetFree(void);
|
extern int32_t PIOS_SDCARD_GetFree(void);
|
||||||
|
#ifndef USE_SIM_POSIX
|
||||||
extern int32_t PIOS_SDCARD_ReadBuffer(PFILEINFO fileinfo, uint8_t * buffer, uint32_t len);
|
extern int32_t PIOS_SDCARD_ReadBuffer(PFILEINFO fileinfo, uint8_t * buffer, uint32_t len);
|
||||||
extern int32_t PIOS_SDCARD_ReadLine(PFILEINFO fileinfo, uint8_t * buffer, uint32_t max_len);
|
extern int32_t PIOS_SDCARD_ReadLine(PFILEINFO fileinfo, uint8_t * buffer, uint32_t max_len);
|
||||||
|
#endif
|
||||||
extern int32_t PIOS_SDCARD_FileCopy(char *Source, char *Destination);
|
extern int32_t PIOS_SDCARD_FileCopy(char *Source, char *Destination);
|
||||||
extern int32_t PIOS_SDCARD_FileDelete(char *Filename);
|
extern int32_t PIOS_SDCARD_FileDelete(char *Filename);
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
*
|
*
|
||||||
* @file pios.h
|
* @file pios.h
|
||||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||||
|
* @author PhoenixPilot, http://github.com/PhoenixPilot, Copyright (C) 2012
|
||||||
* @brief Main PiOS header.
|
* @brief Main PiOS header.
|
||||||
* - Central header for the project.
|
* - Central header for the project.
|
||||||
* @see The GNU Public License (GPL) Version 3
|
* @see The GNU Public License (GPL) Version 3
|
||||||
@ -27,7 +28,9 @@
|
|||||||
|
|
||||||
#ifndef PIOS_H
|
#ifndef PIOS_H
|
||||||
#define PIOS_H
|
#define PIOS_H
|
||||||
|
#ifdef USE_SIM_POSIX
|
||||||
|
#include <pios_sim_posix.h>
|
||||||
|
#else
|
||||||
/* PIOS Feature Selection */
|
/* PIOS Feature Selection */
|
||||||
#include "pios_config.h"
|
#include "pios_config.h"
|
||||||
|
|
||||||
@ -154,8 +157,8 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(PIOS_INCLUDE_FLASH)
|
#if defined(PIOS_INCLUDE_FLASH)
|
||||||
#include <pios_flash_jedec.h>
|
#include <pios_flash.h>
|
||||||
#include <pios_flashfs_objlist.h>
|
#include <pios_flashfs.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(PIOS_INCLUDE_BL_HELPER)
|
#if defined(PIOS_INCLUDE_BL_HELPER)
|
||||||
@ -179,5 +182,5 @@
|
|||||||
#include <pios_crc.h>
|
#include <pios_crc.h>
|
||||||
|
|
||||||
#define NELEMENTS(x) (sizeof(x) / sizeof(*(x)))
|
#define NELEMENTS(x) (sizeof(x) / sizeof(*(x)))
|
||||||
|
#endif /* USE_SIMPOSIX */
|
||||||
#endif /* PIOS_H */
|
#endif /* PIOS_H */
|
||||||
|
@ -25,8 +25,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef PIOS_H
|
#ifndef PIOS_SIM_POSIX_H
|
||||||
#define PIOS_H
|
#define PIOS_SIM_POSIX_H
|
||||||
|
|
||||||
/* PIOS Feature Selection */
|
/* PIOS Feature Selection */
|
||||||
#include "pios_config.h"
|
#include "pios_config.h"
|
||||||
@ -49,7 +49,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
/* Generic initcall infrastructure */
|
/* Generic initcall infrastructure */
|
||||||
#include "pios_initcall.h"
|
#include <pios_initcall.h>
|
||||||
|
|
||||||
/* PIOS Board Specific Device Configuration */
|
/* PIOS Board Specific Device Configuration */
|
||||||
#include "pios_board.h"
|
#include "pios_board.h"
|
||||||
@ -68,6 +68,13 @@
|
|||||||
#include <pios_crc.h>
|
#include <pios_crc.h>
|
||||||
#include <pios_rcvr.h>
|
#include <pios_rcvr.h>
|
||||||
|
|
||||||
|
#if defined(PIOS_INCLUDE_IAP)
|
||||||
|
#include <pios_iap.h>
|
||||||
|
#endif
|
||||||
|
#if defined(PIOS_INCLUDE_BL_HELPER)
|
||||||
|
#include <pios_bl_helper.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#define NELEMENTS(x) (sizeof(x) / sizeof(*(x)))
|
#define NELEMENTS(x) (sizeof(x) / sizeof(*(x)))
|
||||||
|
|
||||||
#endif /* PIOS_H */
|
#endif /* PIOS_POSIX_H */
|
@ -2,13 +2,13 @@
|
|||||||
******************************************************************************
|
******************************************************************************
|
||||||
* @addtogroup PIOS PIOS Core hardware abstraction layer
|
* @addtogroup PIOS PIOS Core hardware abstraction layer
|
||||||
* @{
|
* @{
|
||||||
* @addtogroup PIOS_WDG Watchdog Functions
|
* @addtogroup PIOS_BOOTLOADER Functions
|
||||||
|
* @brief HAL code to interface to the OpenPilot AHRS module
|
||||||
* @{
|
* @{
|
||||||
*
|
*
|
||||||
* @file pios_wdg.h
|
* @file pios_bl_helper.c
|
||||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012.
|
||||||
* Parts by Thorsten Klose (tk@midibox.org)
|
* @brief Bootloader Helper Functions
|
||||||
* @brief SPI functions header.
|
|
||||||
* @see The GNU Public License (GPL) Version 3
|
* @see The GNU Public License (GPL) Version 3
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
@ -28,18 +28,26 @@
|
|||||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PIOS_WDG
|
/* Project Includes */
|
||||||
#define PIOS_WDG
|
#include "pios.h"
|
||||||
|
#if defined(PIOS_INCLUDE_BL_HELPER)
|
||||||
|
#include <pios_board_info.h>
|
||||||
|
|
||||||
void PIOS_WDG_Init();
|
uint32_t PIOS_BL_HELPER_CRC_Memory_Calc()
|
||||||
bool PIOS_WDG_RegisterFlag(uint16_t flag_requested);
|
{
|
||||||
bool PIOS_WDG_UpdateFlag(uint16_t flag);
|
return 0;
|
||||||
uint16_t PIOS_WDG_GetBootupFlags();
|
}
|
||||||
uint16_t PIOS_WDG_GetActiveFlags();
|
|
||||||
void PIOS_WDG_Clear(void);
|
|
||||||
|
|
||||||
#define PIOS_WDG_ACTUATOR 0x0001
|
extern const struct fw_version_info fw_version_blob;
|
||||||
#define PIOS_WDG_STABILIZATION 0x0002
|
void PIOS_BL_HELPER_FLASH_Read_Description(uint8_t * array, uint8_t size)
|
||||||
#define PIOS_WDG_MANUAL 0x0008
|
{
|
||||||
|
uint8_t * desc = (uint8_t *) &fw_version_blob;
|
||||||
|
for (uint32_t i = 0; i < size; i++) {
|
||||||
|
array[i] = desc[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PIOS_BL_HELPER_CRC_Ini()
|
||||||
|
{
|
||||||
|
}
|
||||||
#endif
|
#endif
|
20
flight/PiOS/posix/pios_board_info.c
Normal file
20
flight/PiOS/posix/pios_board_info.c
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#include <pios.h>
|
||||||
|
#include <pios_board.h>
|
||||||
|
|
||||||
|
#include "pios_board_info.h"
|
||||||
|
|
||||||
|
const struct pios_board_info pios_board_info_blob = {
|
||||||
|
.magic = PIOS_BOARD_INFO_BLOB_MAGIC,
|
||||||
|
.board_type = BOARD_TYPE,
|
||||||
|
.board_rev = BOARD_REVISION,
|
||||||
|
.bl_rev = BOOTLOADER_VERSION,
|
||||||
|
.hw_type = HW_TYPE,
|
||||||
|
.fw_base = FW_BANK_BASE,
|
||||||
|
.fw_size = FW_BANK_SIZE - FW_DESC_SIZE,
|
||||||
|
.desc_base = FW_BANK_BASE + FW_BANK_SIZE - FW_DESC_SIZE,
|
||||||
|
.desc_size = FW_DESC_SIZE,
|
||||||
|
#ifdef EE_BANK_BASE
|
||||||
|
.ee_base = EE_BANK_BASE,
|
||||||
|
.ee_size = EE_BANK_SIZE,
|
||||||
|
#endif
|
||||||
|
};
|
69
flight/PiOS/posix/pios_iap.c
Normal file
69
flight/PiOS/posix/pios_iap.c
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
/*!
|
||||||
|
* @File iap.c
|
||||||
|
* @Brief
|
||||||
|
*
|
||||||
|
* Created on: Sep 6, 2010
|
||||||
|
* Author: joe
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************************
|
||||||
|
* Header files
|
||||||
|
****************************************************************************************/
|
||||||
|
#include <pios.h>
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief PIOS_IAP_Init - performs required initializations for iap module.
|
||||||
|
* \param none.
|
||||||
|
* \return none.
|
||||||
|
* \retval none.
|
||||||
|
*
|
||||||
|
* Created: Sep 8, 2010 10:10:48 PM by joe
|
||||||
|
*/
|
||||||
|
void PIOS_IAP_Init( void )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Determines if an In-Application-Programming request has been made.
|
||||||
|
* \param *comm - Which communication stream to use for the IAP (USB, Telemetry, I2C, SPI, etc)
|
||||||
|
* \return TRUE - if correct sequence found, along with 'comm' updated.
|
||||||
|
* FALSE - Note that 'comm' will have an invalid comm identifier.
|
||||||
|
* \retval
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
uint32_t PIOS_IAP_CheckRequest( void )
|
||||||
|
{
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the 1st word of the request sequence.
|
||||||
|
* \param n/a
|
||||||
|
* \return n/a
|
||||||
|
* \retval
|
||||||
|
*/
|
||||||
|
void PIOS_IAP_SetRequest1(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void PIOS_IAP_SetRequest2(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void PIOS_IAP_ClearRequest(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t PIOS_IAP_ReadBootCount(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PIOS_IAP_WriteBootCount (uint16_t boot_count)
|
||||||
|
{
|
||||||
|
}
|
@ -38,7 +38,7 @@
|
|||||||
* \param[in] mode currently only mode 0 supported
|
* \param[in] mode currently only mode 0 supported
|
||||||
* \return < 0 if initialisation failed
|
* \return < 0 if initialisation failed
|
||||||
*/
|
*/
|
||||||
int32_t PIOS_SDCARD_Init(void)
|
int32_t PIOS_SDCARD_Init(uint32_t spi_id)
|
||||||
{
|
{
|
||||||
/* No error */
|
/* No error */
|
||||||
return 0;
|
return 0;
|
@ -110,6 +110,23 @@ int32_t PIOS_SYS_Reset(void)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the serial number as a string
|
||||||
|
* param[out] uint8_t pointer to a string which can store at least 12 bytes
|
||||||
|
* (12 bytes returned for STM32)
|
||||||
|
* return < 0 if feature not supported
|
||||||
|
*/
|
||||||
|
int32_t PIOS_SYS_SerialNumberGetBinary(uint8_t *array)
|
||||||
|
{
|
||||||
|
/* Stored in the so called "electronic signature" */
|
||||||
|
for (int i = 0; i < PIOS_SYS_SERIAL_NUM_BINARY_LEN; ++i) {
|
||||||
|
array[i] = 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No error */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the serial number as a string
|
* Returns the serial number as a string
|
||||||
* param[out] str pointer to a string which can store at least 32 digits + zero terminator!
|
* param[out] str pointer to a string which can store at least 32 digits + zero terminator!
|
||||||
@ -118,19 +135,12 @@ int32_t PIOS_SYS_Reset(void)
|
|||||||
*/
|
*/
|
||||||
int32_t PIOS_SYS_SerialNumberGet(char *str)
|
int32_t PIOS_SYS_SerialNumberGet(char *str)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
|
|
||||||
/* Stored in the so called "electronic signature" */
|
/* Stored in the so called "electronic signature" */
|
||||||
for(i=0; i<24; ++i) {
|
int i;
|
||||||
//uint8_t b = MEM8(0x1ffff7e8 + (i/2));
|
for (i = 0; i < PIOS_SYS_SERIAL_NUM_ASCII_LEN; ++i) {
|
||||||
//if( !(i & 1) )
|
str[i] = 'F';
|
||||||
//b >>= 4;
|
|
||||||
//b &= 0x0f;
|
|
||||||
|
|
||||||
//str[i] = ((b > 9) ? ('A'-10) : '0') + b;
|
|
||||||
str[i]='6';
|
|
||||||
}
|
}
|
||||||
str[i] = 0;
|
str[i] = '\0';
|
||||||
|
|
||||||
/* No error */
|
/* No error */
|
||||||
return 0;
|
return 0;
|
@ -51,8 +51,9 @@
|
|||||||
* @param[in] delayMs The delay period in ms
|
* @param[in] delayMs The delay period in ms
|
||||||
* @returns Maximum recommended delay between updates
|
* @returns Maximum recommended delay between updates
|
||||||
*/
|
*/
|
||||||
void PIOS_WDG_Init()
|
uint16_t PIOS_WDG_Init()
|
||||||
{
|
{
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
@ -6,11 +6,12 @@ interface stlink
|
|||||||
stlink_layout usb
|
stlink_layout usb
|
||||||
stlink_device_desc "ST-LINK/V2"
|
stlink_device_desc "ST-LINK/V2"
|
||||||
stlink_vid_pid 0x0483 0x3748
|
stlink_vid_pid 0x0483 0x3748
|
||||||
#
|
|
||||||
# dummy values, not really needed
|
# unused but set to disable warnings
|
||||||
#
|
adapter_khz 1000
|
||||||
adapter_khz 1
|
|
||||||
reset_config trst_and_srst
|
#reset_config trst_and_srst
|
||||||
|
reset_config srst_only srst_nogate
|
||||||
|
|
||||||
gdb_port 3333
|
gdb_port 3333
|
||||||
tcl_port 6666
|
tcl_port 6666
|
||||||
|
@ -1,27 +1,60 @@
|
|||||||
#
|
#
|
||||||
|
# STM32f4x stlink pseudo target
|
||||||
#
|
#
|
||||||
|
|
||||||
|
if { [info exists CHIPNAME] == 0 } {
|
||||||
|
set CHIPNAME stm32f4x
|
||||||
|
}
|
||||||
|
|
||||||
|
if { [info exists CPUTAPID] == 0 } {
|
||||||
|
set CPUTAPID 0x2ba01477
|
||||||
|
}
|
||||||
|
|
||||||
|
if { [info exists WORKAREASIZE] == 0 } {
|
||||||
|
set WORKAREASIZE 0x10000
|
||||||
|
}
|
||||||
|
|
||||||
#
|
#
|
||||||
|
# stm32 stlink pseudo target
|
||||||
|
#
|
||||||
|
|
||||||
if { [info exists CHIPNAME] } {
|
if { [info exists CHIPNAME] } {
|
||||||
set _CHIPNAME $CHIPNAME
|
set _CHIPNAME $CHIPNAME
|
||||||
} else {
|
} else {
|
||||||
set _CHIPNAME stm32f4x
|
set _CHIPNAME stm32f1x
|
||||||
}
|
}
|
||||||
|
|
||||||
# Work-area is a space in RAM used for flash programming
|
# Work-area is a space in RAM used for flash programming
|
||||||
# By default use 64kB
|
# By default use 16kB
|
||||||
if { [info exists WORKAREASIZE] } {
|
if { [info exists WORKAREASIZE] } {
|
||||||
set _WORKAREASIZE $WORKAREASIZE
|
set _WORKAREASIZE $WORKAREASIZE
|
||||||
} else {
|
} else {
|
||||||
set _WORKAREASIZE 0x10000
|
set _WORKAREASIZE 0x4000
|
||||||
}
|
}
|
||||||
|
|
||||||
if { [info exists CPUTAPID] } {
|
if { [info exists CPUTAPID] } {
|
||||||
set _CPUTAPID $CPUTAPID
|
set _CPUTAPID $CPUTAPID
|
||||||
} else {
|
} else {
|
||||||
set _CPUTAPID 0x2ba01477
|
# this is the SW-DP tap id not the jtag tap id
|
||||||
|
set _CPUTAPID 0x1ba01477
|
||||||
}
|
}
|
||||||
|
|
||||||
transport select stlink_swd
|
if { [info exists TRANSPORT] } {
|
||||||
|
set _TRANSPORT $TRANSPORT
|
||||||
|
if { $TRANSPORT == "stlink_jtag" } {
|
||||||
|
if { [info exists CPUTAPID] == 0 } {
|
||||||
|
# jtag requires us to use the jtag tap id
|
||||||
|
set _CPUTAPID 0x3ba00477
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
set _TRANSPORT stlink_swd
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# possibles value are stlink_swd or stlink_jtag
|
||||||
|
#
|
||||||
|
transport select $_TRANSPORT
|
||||||
|
|
||||||
stlink newtap $_CHIPNAME cpu -expected-id $_CPUTAPID
|
stlink newtap $_CHIPNAME cpu -expected-id $_CPUTAPID
|
||||||
|
|
||||||
@ -30,5 +63,7 @@ target create $_TARGETNAME stm32_stlink -chain-position $_TARGETNAME -rtos auto
|
|||||||
|
|
||||||
$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0
|
$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0
|
||||||
|
|
||||||
|
# stm32f4x family uses stm32f2x driver
|
||||||
set _FLASHNAME $_CHIPNAME.flash
|
set _FLASHNAME $_CHIPNAME.flash
|
||||||
flash bank $_FLASHNAME stm32f2x 0x08000000 0 0 0 $_TARGETNAME
|
flash bank $_FLASHNAME stm32f2x 0 0 0 0 $_TARGETNAME
|
||||||
|
|
||||||
|
@ -1,12 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<projectDescription>
|
|
||||||
<name>RemoteSystemsTempFiles</name>
|
|
||||||
<comment></comment>
|
|
||||||
<projects>
|
|
||||||
</projects>
|
|
||||||
<buildSpec>
|
|
||||||
</buildSpec>
|
|
||||||
<natures>
|
|
||||||
<nature>org.eclipse.rse.ui.remoteSystemsTempNature</nature>
|
|
||||||
</natures>
|
|
||||||
</projectDescription>
|
|
@ -23,16 +23,10 @@
|
|||||||
#####
|
#####
|
||||||
|
|
||||||
WHEREAMI := $(dir $(lastword $(MAKEFILE_LIST)))
|
WHEREAMI := $(dir $(lastword $(MAKEFILE_LIST)))
|
||||||
TOP := $(realpath $(WHEREAMI)/../../../)
|
TOP := $(realpath $(WHEREAMI)/../../../../)
|
||||||
include $(TOP)/make/firmware-defs.mk
|
include $(TOP)/make/firmware-defs.mk
|
||||||
include $(TOP)/make/boards/$(BOARD_NAME)/board-info.mk
|
include $(TOP)/make/boards/$(BOARD_NAME)/board-info.mk
|
||||||
|
|
||||||
# Target file name (without extension).
|
|
||||||
TARGET = bu_$(BOARD_NAME)
|
|
||||||
|
|
||||||
# Directory for output files (lst, obj, dep, elf, sym, map, hex, bin etc.)
|
|
||||||
OUTDIR := $(TOP)/build/$(TARGET)
|
|
||||||
|
|
||||||
# Set developer code and compile options
|
# Set developer code and compile options
|
||||||
# Set to YES to compile for debugging
|
# Set to YES to compile for debugging
|
||||||
DEBUG ?= NO
|
DEBUG ?= NO
|
||||||
@ -61,15 +55,6 @@ FLASH_TOOL = OPENOCD
|
|||||||
# Paths
|
# Paths
|
||||||
OPSYSTEM = .
|
OPSYSTEM = .
|
||||||
OPSYSTEMINC = $(OPSYSTEM)/inc
|
OPSYSTEMINC = $(OPSYSTEM)/inc
|
||||||
OPUAVTALK = ./UAVTalk
|
|
||||||
OPUAVTALKINC = $(OPUAVTALK)/inc
|
|
||||||
OPUAVOBJ = ./UAVObjects
|
|
||||||
OPUAVOBJINC = $(OPUAVOBJ)/inc
|
|
||||||
OPTESTS = ./Tests
|
|
||||||
OPMODULEDIR = ./Modules
|
|
||||||
FLIGHTLIB = ../../Libraries
|
|
||||||
FLIGHTLIBINC = ../../Libraries/inc
|
|
||||||
PIOS = ../../PiOS
|
|
||||||
PIOSINC = $(PIOS)/inc
|
PIOSINC = $(PIOS)/inc
|
||||||
PIOSSTM32F10X = $(PIOS)/STM32F10x
|
PIOSSTM32F10X = $(PIOS)/STM32F10x
|
||||||
PIOSCOMMON = $(PIOS)/Common
|
PIOSCOMMON = $(PIOS)/Common
|
||||||
@ -89,8 +74,6 @@ MSDDIR = $(APPLIBDIR)/msd
|
|||||||
RTOSDIR = $(APPLIBDIR)/FreeRTOS
|
RTOSDIR = $(APPLIBDIR)/FreeRTOS
|
||||||
RTOSSRCDIR = $(RTOSDIR)/Source
|
RTOSSRCDIR = $(RTOSDIR)/Source
|
||||||
RTOSINCDIR = $(RTOSSRCDIR)/include
|
RTOSINCDIR = $(RTOSSRCDIR)/include
|
||||||
DOXYGENDIR = ../Doc/Doxygen
|
|
||||||
HWDEFSINC = $(TOP)/flight/board_hw_defs/$(BOARD_NAME)
|
|
||||||
|
|
||||||
# List C source files here. (C dependencies are automatically generated.)
|
# List C source files here. (C dependencies are automatically generated.)
|
||||||
# use file-extension c for "c-only"-files
|
# use file-extension c for "c-only"-files
|
@ -23,16 +23,10 @@
|
|||||||
#####
|
#####
|
||||||
|
|
||||||
WHEREAMI := $(dir $(lastword $(MAKEFILE_LIST)))
|
WHEREAMI := $(dir $(lastword $(MAKEFILE_LIST)))
|
||||||
TOP := $(realpath $(WHEREAMI)/../../../)
|
TOP := $(realpath $(WHEREAMI)/../../../../)
|
||||||
include $(TOP)/make/firmware-defs.mk
|
include $(TOP)/make/firmware-defs.mk
|
||||||
include $(TOP)/make/boards/$(BOARD_NAME)/board-info.mk
|
include $(TOP)/make/boards/$(BOARD_NAME)/board-info.mk
|
||||||
|
|
||||||
# Target file name (without extension).
|
|
||||||
TARGET := bl_$(BOARD_NAME)
|
|
||||||
|
|
||||||
# Directory for output files (lst, obj, dep, elf, sym, map, hex, bin etc.)
|
|
||||||
OUTDIR := $(TOP)/build/$(TARGET)
|
|
||||||
|
|
||||||
# Set developer code and compile options
|
# Set developer code and compile options
|
||||||
# Set to YES to compile for debugging
|
# Set to YES to compile for debugging
|
||||||
DEBUG ?= NO
|
DEBUG ?= NO
|
||||||
@ -58,15 +52,7 @@ FLASH_TOOL = OPENOCD
|
|||||||
# Paths
|
# Paths
|
||||||
OPSYSTEM = .
|
OPSYSTEM = .
|
||||||
OPSYSTEMINC = $(OPSYSTEM)/inc
|
OPSYSTEMINC = $(OPSYSTEM)/inc
|
||||||
OPUAVTALK = ./UAVTalk
|
FLIGHTLIBINC = $(FLIGHTLIB)/inc
|
||||||
OPUAVTALKINC = $(OPUAVTALK)/inc
|
|
||||||
OPUAVOBJ = ./UAVObjects
|
|
||||||
OPUAVOBJINC = $(OPUAVOBJ)/inc
|
|
||||||
OPTESTS = ./Tests
|
|
||||||
OPMODULEDIR = ./Modules
|
|
||||||
FLIGHTLIB = ../../Libraries
|
|
||||||
FLIGHTLIBINC = ../../Libraries/inc
|
|
||||||
PIOS = ../../PiOS
|
|
||||||
PIOSINC = $(PIOS)/inc
|
PIOSINC = $(PIOS)/inc
|
||||||
PIOSSTM32F10X = $(PIOS)/STM32F10x
|
PIOSSTM32F10X = $(PIOS)/STM32F10x
|
||||||
PIOSCOMMON = $(PIOS)/Common
|
PIOSCOMMON = $(PIOS)/Common
|
||||||
@ -86,8 +72,6 @@ MSDDIR = $(APPLIBDIR)/msd
|
|||||||
RTOSDIR = $(APPLIBDIR)/FreeRTOS
|
RTOSDIR = $(APPLIBDIR)/FreeRTOS
|
||||||
RTOSSRCDIR = $(RTOSDIR)/Source
|
RTOSSRCDIR = $(RTOSDIR)/Source
|
||||||
RTOSINCDIR = $(RTOSSRCDIR)/include
|
RTOSINCDIR = $(RTOSSRCDIR)/include
|
||||||
DOXYGENDIR = ../Doc/Doxygen
|
|
||||||
HWDEFSINC = ../../board_hw_defs/$(BOARD_NAME)
|
|
||||||
|
|
||||||
# List C source files here. (C dependencies are automatically generated.)
|
# List C source files here. (C dependencies are automatically generated.)
|
||||||
# use file-extension c for "c-only"-files
|
# use file-extension c for "c-only"-files
|
@ -23,16 +23,10 @@
|
|||||||
#####
|
#####
|
||||||
|
|
||||||
WHEREAMI := $(dir $(lastword $(MAKEFILE_LIST)))
|
WHEREAMI := $(dir $(lastword $(MAKEFILE_LIST)))
|
||||||
TOP := $(realpath $(WHEREAMI)/../../../)
|
TOP := $(realpath $(WHEREAMI)/../../../../)
|
||||||
include $(TOP)/make/firmware-defs.mk
|
include $(TOP)/make/firmware-defs.mk
|
||||||
include $(TOP)/make/boards/$(BOARD_NAME)/board-info.mk
|
include $(TOP)/make/boards/$(BOARD_NAME)/board-info.mk
|
||||||
|
|
||||||
# Target file name (without extension).
|
|
||||||
TARGET := bl_$(BOARD_NAME)
|
|
||||||
|
|
||||||
# Directory for output files (lst, obj, dep, elf, sym, map, hex, bin etc.)
|
|
||||||
OUTDIR := $(TOP)/build/$(TARGET)
|
|
||||||
|
|
||||||
# Set developer code and compile options
|
# Set developer code and compile options
|
||||||
# Set to YES for debugging
|
# Set to YES for debugging
|
||||||
DEBUG ?= NO
|
DEBUG ?= NO
|
||||||
@ -49,10 +43,8 @@ endif
|
|||||||
# Paths
|
# Paths
|
||||||
OSD_BL = $(WHEREAMI)
|
OSD_BL = $(WHEREAMI)
|
||||||
OSD_BLINC = $(OSD_BL)/inc
|
OSD_BLINC = $(OSD_BL)/inc
|
||||||
PIOS = ../../PiOS
|
|
||||||
PIOSINC = $(PIOS)/inc
|
PIOSINC = $(PIOS)/inc
|
||||||
FLIGHTLIB = ../../Libraries
|
FLIGHTLIBINC = $(FLIGHTLIB)/inc
|
||||||
FLIGHTLIBINC = ../../Libraries/inc
|
|
||||||
PIOSSTM32F4XX = $(PIOS)/STM32F4xx
|
PIOSSTM32F4XX = $(PIOS)/STM32F4xx
|
||||||
PIOSCOMMON = $(PIOS)/Common
|
PIOSCOMMON = $(PIOS)/Common
|
||||||
PIOSBOARDS = $(PIOS)/Boards
|
PIOSBOARDS = $(PIOS)/Boards
|
||||||
@ -62,7 +54,6 @@ STMLIBDIR = $(APPLIBDIR)
|
|||||||
STMSPDDIR = $(STMLIBDIR)/STM32F4xx_StdPeriph_Driver
|
STMSPDDIR = $(STMLIBDIR)/STM32F4xx_StdPeriph_Driver
|
||||||
STMSPDSRCDIR = $(STMSPDDIR)/src
|
STMSPDSRCDIR = $(STMSPDDIR)/src
|
||||||
STMSPDINCDIR = $(STMSPDDIR)/inc
|
STMSPDINCDIR = $(STMSPDDIR)/inc
|
||||||
HWDEFSINC = ../../board_hw_defs/$(BOARD_NAME)
|
|
||||||
|
|
||||||
# List C source files here. (C dependencies are automatically generated.)
|
# List C source files here. (C dependencies are automatically generated.)
|
||||||
# use file-extension c for "c-only"-files
|
# use file-extension c for "c-only"-files
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user