Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 15 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ include $(ROOT)/make/tools.mk
# Tool names
#
CROSS_CC = $(ARM_SDK_PREFIX)gcc
CROSS_CXX = $(ARM_SDK_PREFIX)g++
OBJCOPY = $(ARM_SDK_PREFIX)objcopy
SIZE = $(ARM_SDK_PREFIX)size

Expand All @@ -231,14 +232,18 @@ endif

DEBUG_FLAGS = -ggdb3 -DDEBUG

CFLAGS_CC = -std=gnu99 \
-Wstrict-prototypes

CFLAGS_CXX = -std=c++11 \
-fno-rtti

CFLAGS += $(ARCH_FLAGS) \
$(LTO_FLAGS) \
$(addprefix -D,$(OPTIONS)) \
$(addprefix -I,$(INCLUDE_DIRS)) \
$(DEBUG_FLAGS) \
-std=gnu99 \
-Wall -Wextra -Wunsafe-loop-optimizations -Wdouble-promotion \
-Wstrict-prototypes \
-Werror=switch \
-ffunction-sections \
-fdata-sections \
Expand Down Expand Up @@ -327,16 +332,16 @@ $(GENERATED_SETTINGS): $(SETTINGS_GENERATOR) $(SETTINGS_FILE) $(STAMP)
CFLAGS += -I$(TARGET_OBJ_DIR)

$(STAMP): .FORCE
$(V1) CPP_PATH="$(ARM_SDK_DIR)/bin" CFLAGS="$(CFLAGS)" TARGET=$(TARGET) ruby $(BUILD_STAMP) $(SETTINGS_FILE) $(STAMP)
$(V1) CPP_PATH="$(ARM_SDK_DIR)/bin" CFLAGS="$(CFLAGS_CC) $(CFLAGS)" TARGET=$(TARGET) ruby $(BUILD_STAMP) $(SETTINGS_FILE) $(STAMP)

# Use a pattern rule, since they're different than normal rules.
# See https://www.gnu.org/software/make/manual/make.html#Pattern-Examples
%generated.h %generated.c:
$(V1) echo "settings.yaml -> settings_generated.h, settings_generated.c" "$(STDOUT)"
$(V1) CPP_PATH="$(ARM_SDK_DIR)/bin" CFLAGS="$(CFLAGS)" TARGET=$(TARGET) ruby $(SETTINGS_GENERATOR) . $(SETTINGS_FILE) -o $(TARGET_OBJ_DIR)
$(V1) CPP_PATH="$(ARM_SDK_DIR)/bin" CFLAGS="$(CFLAGS_CC) $(CFLAGS)" TARGET=$(TARGET) ruby $(SETTINGS_GENERATOR) . $(SETTINGS_FILE) -o $(TARGET_OBJ_DIR)

settings-json:
$(V0) CPP_PATH="$(ARM_SDK_DIR)/bin" CFLAGS="$(CFLAGS)" TARGET=$(TARGET) ruby $(SETTINGS_GENERATOR) . $(SETTINGS_FILE) --json settings.json
$(V0) CPP_PATH="$(ARM_SDK_DIR)/bin" CFLAGS="$(CFLAGS_CC) $(CFLAGS)" TARGET=$(TARGET) ruby $(SETTINGS_GENERATOR) . $(SETTINGS_FILE) --json settings.json

clean-settings:
$(V1) $(RM) $(GENERATED_SETTINGS)
Expand Down Expand Up @@ -365,11 +370,15 @@ $(TARGET_ELF): $(TARGET_OBJS)
$(TARGET_OBJ_DIR)/%.o: %.c
$(V1) mkdir -p $(dir $@)
$(V1) echo %% $(notdir $<) "$(STDOUT)"
$(V1) $(CROSS_CC) -c -o $@ $(CFLAGS) $<
$(V1) $(CROSS_CC) -c -o $@ $(CFLAGS) $(CFLAGS_CC) $<
ifeq ($(GENERATE_ASM), 1)
$(V1) $(CROSS_CC) -S -fverbose-asm -Wa,-aslh -o $(patsubst %.o,%.txt.S,$@) -g $(ASM_CFLAGS) $<
endif

$(TARGET_OBJ_DIR)/%.o: %.cpp
$(V1) mkdir -p $(dir $@)
$(V1) echo %% $(notdir $<) "$(STDOUT)"
$(V1) $(CROSS_CXX) -c -o $@ $(CFLAGS) $(CFLAGS_CXX) $<

# Assemble
$(TARGET_OBJ_DIR)/%.o: %.s
Expand Down
6 changes: 5 additions & 1 deletion make/source.mk
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
COMMON_CPP_SRC = \
scheduler/schedulerTask.cpp \
main.cpp

COMMON_SRC = \
$(TARGET_DIR_SRC) \
main.c \
$(COMMON_CPP_SRC) \
target/common_hardware.c \
build/assert.c \
build/build_config.c \
Expand Down
49 changes: 49 additions & 0 deletions src/main/common/base.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* This file is part of INAV Project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Alternatively, the contents of this file may be used under the terms
* of the GNU General Public License Version 3, as described below:
*
* This file is free software: you may copy, redistribute 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 file 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, see http://www.gnu.org/licenses/.
*/

#pragma once

#ifdef __cplusplus
#define EXTERN_C extern "C"

#include <cstddef>
#include <cstdint>
#include <new>

// All classes should be derived from this
class base_c {
protected:
static void * operator new(std::size_t);
static void * operator new [] (std::size_t);

public:
static inline void * operator new(std::size_t s, void *p) { (void)s; return p; }
};

#else

#define EXTERN_C extern

#endif

30 changes: 16 additions & 14 deletions src/main/drivers/serial.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ typedef struct {
ioTag_t txPin;
} serialPortPins_t;

#include <common/base.h>

typedef enum portMode_t {
MODE_RX = 1 << 0,
MODE_TX = 1 << 1,
Expand Down Expand Up @@ -100,19 +102,19 @@ struct serialPortVTable {
void (*endWrite)(serialPort_t *instance);
};

void serialWrite(serialPort_t *instance, uint8_t ch);
uint32_t serialRxBytesWaiting(const serialPort_t *instance);
uint32_t serialTxBytesFree(const serialPort_t *instance);
void serialWriteBuf(serialPort_t *instance, const uint8_t *data, int count);
uint8_t serialRead(serialPort_t *instance);
void serialSetBaudRate(serialPort_t *instance, uint32_t baudRate);
void serialSetMode(serialPort_t *instance, portMode_t mode);
bool isSerialTransmitBufferEmpty(const serialPort_t *instance);
void serialPrint(serialPort_t *instance, const char *str);
uint32_t serialGetBaudRate(serialPort_t *instance);
bool serialIsConnected(const serialPort_t *instance);
EXTERN_C void serialWrite(serialPort_t *instance, uint8_t ch);
EXTERN_C uint32_t serialRxBytesWaiting(const serialPort_t *instance);
EXTERN_C uint32_t serialTxBytesFree(const serialPort_t *instance);
EXTERN_C void serialWriteBuf(serialPort_t *instance, const uint8_t *data, int count);
EXTERN_C uint8_t serialRead(serialPort_t *instance);
EXTERN_C void serialSetBaudRate(serialPort_t *instance, uint32_t baudRate);
EXTERN_C void serialSetMode(serialPort_t *instance, portMode_t mode);
EXTERN_C bool isSerialTransmitBufferEmpty(const serialPort_t *instance);
EXTERN_C void serialPrint(serialPort_t *instance, const char *str);
EXTERN_C uint32_t serialGetBaudRate(serialPort_t *instance);
EXTERN_C bool serialIsConnected(const serialPort_t *instance);

// A shim that adapts the bufWriter API to the serialWriteBuf() API.
void serialWriteBufShim(void *instance, const uint8_t *data, int count);
void serialBeginWrite(serialPort_t *instance);
void serialEndWrite(serialPort_t *instance);
EXTERN_C void serialWriteBufShim(void *instance, const uint8_t *data, int count);
EXTERN_C void serialBeginWrite(serialPort_t *instance);
EXTERN_C void serialEndWrite(serialPort_t *instance);
14 changes: 8 additions & 6 deletions src/main/drivers/serial_softserial.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

#pragma once

#include <common/base.h>

#define SOFTSERIAL_BUFFER_SIZE 256

typedef enum {
Expand All @@ -27,9 +29,9 @@ typedef enum {
serialPort_t *openSoftSerial(softSerialPortIndex_e portIndex, serialReceiveCallbackPtr rxCallback, void *rxCallbackData, uint32_t baud, portMode_t mode, portOptions_t options);

// serialPort API
void softSerialWriteByte(serialPort_t *instance, uint8_t ch);
uint32_t softSerialRxBytesWaiting(const serialPort_t *instance);
uint32_t softSerialTxBytesFree(const serialPort_t *instance);
uint8_t softSerialReadByte(serialPort_t *instance);
void softSerialSetBaudRate(serialPort_t *s, uint32_t baudRate);
bool isSoftSerialTransmitBufferEmpty(const serialPort_t *s);
EXTERN_C void softSerialWriteByte(serialPort_t *instance, uint8_t ch);
EXTERN_C uint32_t softSerialRxBytesWaiting(const serialPort_t *instance);
EXTERN_C uint32_t softSerialTxBytesFree(const serialPort_t *instance);
EXTERN_C uint8_t softSerialReadByte(serialPort_t *instance);
EXTERN_C void softSerialSetBaudRate(serialPort_t *s, uint32_t baudRate);
EXTERN_C bool isSoftSerialTransmitBufferEmpty(const serialPort_t *s);
6 changes: 4 additions & 2 deletions src/main/fc/fc_init.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

#pragma once

#include <common/base.h>

typedef enum {
SYSTEM_STATE_INITIALISING = 0,
SYSTEM_STATE_CONFIG_LOADED = (1 << 0),
Expand All @@ -26,5 +28,5 @@ typedef enum {
SYSTEM_STATE_READY = (1 << 7)
} systemState_e;

extern uint8_t systemState;
void init(void);
EXTERN_C uint8_t systemState;
EXTERN_C void init(void);
19 changes: 16 additions & 3 deletions src/main/main.c → src/main/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
#include <stdbool.h>
#include <stdint.h>

#include "platform.h"
#include <platform.h>
#include <common/base.h>

#include "build/debug.h"
#include "drivers/serial.h"
#include "drivers/serial_softserial.h"
Expand All @@ -31,7 +33,6 @@
serialPort_t *loopbackPort;
#endif


static void loopbackInit(void)
{
#ifdef SOFTSERIAL_LOOPBACK
Expand All @@ -53,7 +54,19 @@ static void processLoopback(void)
#endif
}

int main(void)
/* CRT init function, called by __libc_init_array() before passing control to main */
extern "C" void __attribute__ ((weak)) _init(void)
{
}

/* Prevent demangle from being pulled in */
extern "C" void __cxa_pure_virtual(void)
{
// FIXME: Crash safely here
while (true);
}

extern "C" int main(void)
{
init();
loopbackInit();
Expand Down
25 changes: 13 additions & 12 deletions src/main/scheduler/scheduler.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

#pragma once

#include "common/base.h"
#include "common/time.h"

//#define SCHEDULER_DEBUG
Expand Down Expand Up @@ -144,20 +145,20 @@ typedef struct {
#endif
} cfTask_t;

extern cfTask_t cfTasks[TASK_COUNT];
extern uint16_t averageSystemLoadPercent;
EXTERN_C cfTask_t cfTasks[TASK_COUNT];
EXTERN_C uint16_t averageSystemLoadPercent;

void getCheckFuncInfo(cfCheckFuncInfo_t *checkFuncInfo);
void getTaskInfo(cfTaskId_e taskId, cfTaskInfo_t *taskInfo);
void rescheduleTask(cfTaskId_e taskId, timeDelta_t newPeriodUs);
void setTaskEnabled(cfTaskId_e taskId, bool newEnabledState);
timeDelta_t getTaskDeltaTime(cfTaskId_e taskId);
void schedulerResetTaskStatistics(cfTaskId_e taskId);
EXTERN_C void getCheckFuncInfo(cfCheckFuncInfo_t *checkFuncInfo);
EXTERN_C void getTaskInfo(cfTaskId_e taskId, cfTaskInfo_t *taskInfo);
EXTERN_C void rescheduleTask(cfTaskId_e taskId, timeDelta_t newPeriodUs);
EXTERN_C void setTaskEnabled(cfTaskId_e taskId, bool newEnabledState);
EXTERN_C timeDelta_t getTaskDeltaTime(cfTaskId_e taskId);
EXTERN_C void schedulerResetTaskStatistics(cfTaskId_e taskId);

void schedulerInit(void);
void scheduler(void);
void taskSystem(timeUs_t currentTimeUs);
void taskRunRealtimeCallbacks(timeUs_t currentTimeUs);
EXTERN_C void schedulerInit(void);
EXTERN_C void scheduler(void);
EXTERN_C void taskSystem(timeUs_t currentTimeUs);
EXTERN_C void taskRunRealtimeCallbacks(timeUs_t currentTimeUs);

#define TASK_PERIOD_HZ(hz) (1000000 / (hz))
#define TASK_PERIOD_MS(ms) ((ms) * 1000)
Expand Down
48 changes: 48 additions & 0 deletions src/main/scheduler/schedulerTask.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* This file is part of INAV Project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Alternatively, the contents of this file may be used under the terms
* of the GNU General Public License Version 3, as described below:
*
* This file is free software: you may copy, redistribute 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 file 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, see http://www.gnu.org/licenses/.
*/

#include <common/base.h>
#include <scheduler/schedulerTask.h>

void task_c::setReady(bool _ready)
{
ready = _ready;
}

bool task_c::isReady(void) const
{
return ready;
}

void task_c::run(const timeUs_t currentTimeUs, const timeDelta_t deltaTimeUs)
{
task(currentTimeUs, deltaTimeUs);
setReady(false);
}

void task_c::task(const timeUs_t currentTimeUs, const timeDelta_t deltaTimeUs)
{
(void)currentTimeUs;
(void)deltaTimeUs;
}
41 changes: 41 additions & 0 deletions src/main/scheduler/schedulerTask.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* This file is part of INAV Project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Alternatively, the contents of this file may be used under the terms
* of the GNU General Public License Version 3, as described below:
*
* This file is free software: you may copy, redistribute 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 file 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, see http://www.gnu.org/licenses/.
*/

#pragma once

#include <common/base.h>
#include <common/time.h>

// All schedulable objects should be derived from task_c
class task_c : base_c {
protected:
bool ready;
// Scheduler calls run(), which in turn calls task() main function
void run(const timeUs_t currentTimeUs, const timeDelta_t deltaTimeUs);

public:
virtual bool isReady(void) const;
virtual void setReady(bool ready);
virtual void task(const timeUs_t currentTimeUs, const timeDelta_t deltaTimeUs);
};
6 changes: 5 additions & 1 deletion src/main/startup/startup_stm32f30x_md_gcc.S
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,11 @@ LoopMarkHeapStack:

/* Call the clock system intitialization function.*/
bl SystemInit
/* Call the application's entry point.*/

/* Call static constructors */
bl __libc_init_array

/* Call the application entry point */
bl main
bx lr

Expand Down
Loading