问题描述:

I've got a Stellaris Launchpad board with a Cortex M4F on it. I want to use FreeRTOS on the board with some of my own C++ code. FreeRTOS, however, is written in C so will not compile with G++; I've tried.

I read somewhere that I should compile FreeRTOS with gcc, then compile my application code with g++, then pull them together using the linker. This makes sense, but I'm really struggling with how to put this behaviour down in a Makefile. I found this Makefile which just confused me more.

Currently, I'm just using the Makefile distributed with the FreeRTOS example in the Stellaris demos, but that's set up for C code only. This question is asking something similar to what I'm after, but I can't wrap my head around how to compile FreeRTOS with GCC and the rest of my code with G++.

FreeRTOS apparently wraps it's code in extern "C" { } directives but attempting using G++ still fails when compiling the FreeRTOS codebase.

I don't like posting large amounts of code on SO, but the more information the better I suppose. The Stellaris demos have a common makedefs file:

# Get the operating system name. If this is Cygwin, the .d files will be

# munged to convert c: into /cygdrive/c so that "make" will be happy with the

# auto-generated dependencies.

os:=${shell uname -s}

# The compiler to be used.

ifndef COMPILER

COMPILER=gcc

endif

# Definitions for using GCC.

ifeq (${COMPILER}, g++)

# Get the prefix for the tools to use. Use arm-stellaris-eabi if it exists,

# otherwise fall back to arm-none-eabi.

PREFIX=${shell type arm-stellaris-eabi-gcc > /dev/null 2>&1 && \

echo arm-stellaris-eabi || echo arm-none-eabi}

# The command for calling the compiler.

CC=${PREFIX}-${COMPILER}

# The location of the C compiler

# ARMGCC_ROOT is used by some makefiles that need to know where the compiler

# is installed. It is not used further for normal stellarisware apps

ARMGCC_ROOT:=${shell dirname '${shell sh -c "which ${CC}"}'}/..

# Determine the compiler CPU/FPU options based on the processor variant.

ifndef VARIANT

CPU=-mcpu=cortex-m3

FPU=

else

ifeq (${VARIANT}, cm3)

CPU=-mcpu=cortex-m3

FPU=

else

ifeq (${VARIANT}, cm4f)

CPU=-mcpu=cortex-m4

FPU=-mfpu=fpv4-sp-d16 -mfloat-abi=softfp

else

$(error Unknown processor variant ${VARIANT}!)

endif

endif

endif

# The flags passed to the assembler.

AFLAGS=-mthumb \

${CPU} \

${FPU} \

-MD

# The flags passed to the compiler.

CFLAGS=-mthumb \

${CPU} \

${FPU} \

-Os \

-ffunction-sections \

-fdata-sections \

-MD \

-Wall \

-pedantic \

-DPART_${PART} \

-c

# The command for calling the library archiver.

AR=${PREFIX}-ar

# The command for calling the linker.

LD=${PREFIX}-ld

# The flags passed to the linker.

LDFLAGS=--gc-sections

# Get the location of libgcc.a from the GCC front-end.

LIBGCC=${shell ${CC} ${CFLAGS} -print-libgcc-file-name}

# Get the location of libc.a from the GCC front-end.

LIBC=${shell ${CC} ${CFLAGS} -print-file-name=libc.a}

# Get the location of libm.a from the GCC front-end.

LIBM=${shell ${CC} ${CFLAGS} -print-file-name=libm.a}

# The command for extracting images from the linked executables.

OBJCOPY=${PREFIX}-objcopy

# Tell the compiler to include debugging information if the DEBUG environment

# variable is set.

ifdef DEBUG

CFLAGS+=-g -D DEBUG

endif

# Add the tool specific CFLAGS.

CFLAGS+=${CFLAGSgcc}

# Add the include file paths to AFLAGS and CFLAGS.

AFLAGS+=${patsubst %,-I%,${subst :, ,${IPATH}}}

CFLAGS+=${patsubst %,-I%,${subst :, ,${IPATH}}}

# The rule for building the object file from each C source file.

${COMPILER}${SUFFIX}/%.o: %.c

@if [ 'x${VERBOSE}' = x ]; \

then \

echo " CC ${<}"; \

else \

echo ${CC} ${CFLAGS} -D${COMPILER} -o ${@} ${<}; \

fi

@${CC} ${CFLAGS} -D${COMPILER} -o ${@} ${<}

ifneq ($(findstring CYGWIN, ${os}), )

@sed -i -r 's/ ([A-Za-z]):/ \/cygdrive\/\1/g' ${@:.o=.d}

endif

# The rule for building the object file from each assembly source file.

${COMPILER}${SUFFIX}/%.o: %.S

@if [ 'x${VERBOSE}' = x ]; \

then \

echo " AS ${<}"; \

else \

echo ${CC} ${AFLAGS} -D${COMPILER} -o ${@} -c ${<}; \

fi

@${CC} ${AFLAGS} -D${COMPILER} -o ${@} -c ${<}

ifneq ($(findstring CYGWIN, ${os}), )

@sed -i -r 's/ ([A-Za-z]):/ \/cygdrive\/\1/g' ${@:.o=.d}

endif

# The rule for creating an object library.

${COMPILER}${SUFFIX}/%.a:

@if [ 'x${VERBOSE}' = x ]; \

then \

echo " AR ${@}"; \

else \

echo ${AR} -cr ${@} ${^}; \

fi

@${AR} -cr ${@} ${^}

# The rule for linking the application.

${COMPILER}${SUFFIX}/%.axf:

@if [ 'x${SCATTERgcc_${notdir ${@:.axf=}}}' = x ]; \

then \

ldname="${ROOT}/${COMPILER}/standalone.ld"; \

else \

ldname="${SCATTERgcc_${notdir ${@:.axf=}}}"; \

fi; \

if [ 'x${VERBOSE}' = x ]; \

then \

echo " LD ${@} ${LNK_SCP}"; \

else \

echo ${LD} -T $${ldname} \

--entry ${ENTRY_${notdir ${@:.axf=}}} \

${LDFLAGSgcc_${notdir ${@:.axf=}}} \

${LDFLAGS} -o ${@} $(filter %.o %.a, ${^}) \

'${LIBM}' '${LIBC}' '${LIBGCC}'; \

fi; \

${LD} -T $${ldname} \

--entry ${ENTRY_${notdir ${@:.axf=}}} \

${LDFLAGSgcc_${notdir ${@:.axf=}}} \

${LDFLAGS} -o ${@} $(filter %.o %.a, ${^}) \

'${LIBM}' '${LIBC}' '${LIBGCC}'

@${OBJCOPY} -O binary ${@} ${@:.axf=.bin}

endif

The above file is included by the Makefile itself (below):

# Defines the part type that this project uses.

PART=LM4F120H5QR

# Set the processor variant.

VARIANT=cm4f

# The base directory for StellarisWare.

ROOT=../lib

COMPILER=gcc

# Include the common make definitions.

include ${ROOT}/makedefs

# Where to find source files that do not live in this directory.

VPATH=${ROOT}/FreeRTOS/Source/portable/GCC/ARM_CM4F

VPATH+=${ROOT}/FreeRTOS/Source/portable/MemMang/

VPATH+=${ROOT}/FreeRTOS/Source

VPATH+=${ROOT}/drivers

VPATH+=${ROOT}/utils

# Where to find header files that do not live in the source directory.

IPATH=.

IPATH+=..

IPATH+=${ROOT}

IPATH+=${ROOT}/FreeRTOS/Source/portable/GCC/ARM_CM4F

IPATH+=${ROOT}/FreeRTOS

IPATH+=${ROOT}/FreeRTOS/Source/include

IPATH+=${ROOT}

# The default rule, which causes the FreeRTOS example to be built.

all: ${COMPILER}

all: ${COMPILER}/freertos_demo.axf

# The rule to clean out all the build products.

clean:

@rm -rf ${COMPILER} ${wildcard *~}

# The rule to create the target directory.

${COMPILER}:

@mkdir -p ${COMPILER}

# Rules for building the FreeRTOS example.

${COMPILER}/freertos_demo.axf: ${COMPILER}/buttons.o

${COMPILER}/freertos_demo.axf: ${COMPILER}/freertos_demo.o

${COMPILER}/freertos_demo.axf: ${COMPILER}/heap_2.o

${COMPILER}/freertos_demo.axf: ${COMPILER}/led_task.o

${COMPILER}/freertos_demo.axf: ${COMPILER}/list.o

${COMPILER}/freertos_demo.axf: ${COMPILER}/port.o

${COMPILER}/freertos_demo.axf: ${COMPILER}/queue.o

${COMPILER}/freertos_demo.axf: ${COMPILER}/rgb.o

${COMPILER}/freertos_demo.axf: ${COMPILER}/startup_${COMPILER}.o

${COMPILER}/freertos_demo.axf: ${COMPILER}/switch_task.o

${COMPILER}/freertos_demo.axf: ${COMPILER}/tasks.o

${COMPILER}/freertos_demo.axf: ${COMPILER}/uartstdio.o

${COMPILER}/freertos_demo.axf: ${COMPILER}/ustdlib.o

${COMPILER}/freertos_demo.axf: ${ROOT}/driverlib/${COMPILER}-cm4f/libdriver-cm4f.a

${COMPILER}/freertos_demo.axf: freertos_demo.ld

SCATTERgcc_freertos_demo=freertos_demo.ld

ENTRY_freertos_demo=ResetISR

CFLAGSgcc=-DTARGET_IS_BLIZZARD_RA1

# Include the automatically generated dependency files.

ifneq (${MAKECMDGOALS},clean)

-include ${wildcard ${COMPILER}/*.d} __dummy__

endif

Some of my directory structure is as follows:

Projects/

lib/

FreeRTOS/

driverlib/

drivers/

inc/

utils/

makedefs

TestProject/

loads.cpp

of.cpp

files.h

here.h

Makefile

If I'm correct in saying that FreeRTOS must be compiled with GCC, then linked with my C++ project code, how can I modify my current Makefile to do that? I want a reasonably generic solution so I can re-use it in other projects, but I don't know much about the C/C++ build process or Makefiles, hence me asking this (lengthy) question. I don't want/mean to sound like I'm asking a "do this for me" question, but I really cannot work out how to do this despite searching on Google and on SO.

网友答案:

I don't use FreeRTOS with C++ myself, but it has been discussed many times on the FreeRTOS forum and there are a few C++ frameworks in the FreeRTOS Interactive site.

相关阅读:
Top