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
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectSpec>
<applicability>
<when>
<context
deviceFamily="PRU"
deviceId="AM261x"
/>
</when>
</applicability>

<project
title="Double Float Multiply"
name = "double_float_multiply_am261x-lp_icss_m0_pru0_fw_ti-pru-cgt"
products="com.ti.OPEN_PRU;MCU-PLUS-SDK-AM261X"
configurations="
Release,
Debug,
"
connection="TIXDS110_Connection.xml"
toolChain="TI"
cgtVersion="2.3.3"
device="AM261x"
deviceCore="ICSS_M0_PRU_0"
ignoreDefaultDeviceSettings="true"
ignoreDefaultCCSSettings="true"
endianness="little"
outputFormat="ELF"
outputType="executable"

compilerBuildOptions="
-I${CG_TOOL_ROOT}/include
-I${MCU_PLUS_SDK_PATH}/source
-I${OPEN_PRU_PATH}/source
-I${MCU_PLUS_SDK_PATH}/source/pru_io/firmware/common
-DPRU0
-DSLICE0
-v4
-DSOC_AM261X
"
linkerBuildOptions="
-m=double_float_multiply.${ConfigName}.map
--disable_auto_rts
--entry_point=main
--diag_suppress=10063-D
"

postBuildStep="
"

description="A Double Float Multiply FW project">

<configuration name="Debug"
compilerBuildOptions="
-D_DEBUG_=1
"
linkerBuildOptions="
"
></configuration>
<configuration name="Release"
compilerBuildOptions="
-O3
"
linkerBuildOptions="
"
></configuration>
<pathVariable name="MCU_PLUS_SDK_PATH" path="${COM_TI_MCU_PLUS_SDK_AM261X_INSTALL_DIR}" scope="project" />
<pathVariable name="OPEN_PRU_PATH" path="${COM_TI_OPEN_PRU_INSTALL_DIR}" scope="project" />
<file path="../../../main.asm" openOnCreation="false" excludeFromBuild="false" action="copy">
</file>
<file path="./linker.cmd" openOnCreation="false" excludeFromBuild="false" action="copy">
</file>
<file path="${OPEN_PRU_PATH}/docs/api_guide_am261x/EXAMPLES_PRU_DOUBLE_FLOAT_MULTIPLY.html"
openOnCreation="false" excludeFromBuild="false" targetName="README.html" action="link">
</file>
</project>
</projectSpec>
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* AM261x_PRU0.cmd
*
* Example Linker command file for linking assembly programs built with the TI-PRU-CGT
* on AM261x PRU0 cores
*/

/* Specify the System Memory Map */
MEMORY
{
PAGE 0:
/* 16 KB PRU Instruction RAM */
PRU_IMEM : org = 0x00000000 len = 0x00004000

PAGE 1:
/* Data RAMs */
/* 8 KB PRU Data RAM 0 */
PRU0_DMEM_0 : org = 0x00000000 len = 0x00002000
/* 8 KB PRU Data RAM 1 */
PRU1_DMEM_1 : org = 0x00002000 len = 0x00002000

PAGE 2:
/* C28 needs to be programmed to point to SHAREDMEM, default is 0 */
/* 32 KB PRU Shared RAM */
PRU_SHAREDMEM : org = 0x00010000 len = 0x00008000
}

/* Specify the sections allocation into memory */
SECTIONS {

.text > PRU_IMEM, PAGE 0
.stack > PRU0_DMEM_0, PAGE 1
.bss > PRU0_DMEM_0, PAGE 1
.cio > PRU0_DMEM_0, PAGE 1
.data > PRU0_DMEM_0, PAGE 1
.switch > PRU0_DMEM_0, PAGE 1
.sysmem > PRU0_DMEM_0, PAGE 1
.cinit > PRU0_DMEM_0, PAGE 1
.rodata > PRU0_DMEM_0, PAGE 1
.rofardata > PRU0_DMEM_0, PAGE 1
.farbss > PRU0_DMEM_0, PAGE 1
.fardata > PRU0_DMEM_0, PAGE 1
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
export OPEN_PRU_PATH?=$(abspath ../../../../../..)
include $(OPEN_PRU_PATH)/imports.mak

# Define build outputs
OUTPUT_NAME := double_float_multiply_am261x-lp_icss_m0_pru0_fw
HEX_ARRAY_PREFIX := PRU0Firmware
GEN_DIR := generated
TARGET := $(GEN_DIR)/$(OUTPUT_NAME).out
TARGET_HEX := $(GEN_DIR)/$(OUTPUT_NAME).h

# MCU+ projects: rename & move hex array output
MCU_HEX_NAME := pru0_load_bin.h
MCU_HEX_PATH := $(OPEN_PRU_PATH)/examples/double_float/firmware/am261x-lp/$(MCU_HEX_NAME)

# which directories to search for assembly & C source files?
FILES_PATH := .. ../../.. .
vpath %.asm $(FILES_PATH)
vpath %.c $(FILES_PATH)
vpath %.cmd $(FILES_PATH)
vpath %.obj $(GEN_DIR)
C_FILES := $(notdir $(foreach directory, $(FILES_PATH), $(wildcard $(directory)/*.c)))
ASM_FILES := $(notdir $(foreach directory, $(FILES_PATH), $(wildcard $(directory)/*.asm)))

# Generate an object file for every *.asm and *.c source file in FILES_PATH
OBJECTS := $(patsubst %.asm, $(GEN_DIR)/%.obj, $(notdir \
$(foreach directory, $(FILES_PATH), $(wildcard $(directory)/*.asm))))
OBJECTS += $(patsubst %.c, $(GEN_DIR)/%.obj, $(notdir \
$(foreach directory, $(FILES_PATH), $(wildcard $(directory)/*.c))))
Comment on lines +15 to +28

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

2. Duplicate main definition 🐞 Bug ✓ Correctness

The ti-pru-cgt makefiles auto-discover and compile all *.c under ../../.. (the firmware/
directory), which includes main_c_ref.c defining int main() while main.asm also defines
main, causing a link-time multiple-definition failure for gmake all builds.
Agent Prompt
### Issue description
The PRU firmware makefiles auto-discover all `*.c` in `FILES_PATH := .. ../../.. .`. Since `../../..` resolves to `examples/double_float/firmware/`, the reference file `main_c_ref.c` (which defines `int main()`) is compiled and linked alongside `main.asm` (which also defines `main`), causing a duplicate-symbol link failure.

### Issue Context
`main_c_ref.c` is documented as a reference-only implementation and should not be part of the default firmware build.

### Fix Focus Areas
Update all board-specific firmware makefiles to ensure `main_c_ref.c` is excluded from `C_FILES`/`OBJECTS` (or relocate the file so it isn’t discovered):
- examples/double_float/firmware/am261x-lp/icss_m0_pru0_fw/ti-pru-cgt/makefile[15-28]
- examples/double_float/firmware/am261x-lp/icss_m0_pru1_fw/ti-pru-cgt/makefile[15-28]
- examples/double_float/firmware/am261x-som/icss_m0_pru0_fw/ti-pru-cgt/makefile[15-28]
- examples/double_float/firmware/am261x-som/icss_m0_pru1_fw/ti-pru-cgt/makefile[15-28]
- examples/double_float/firmware/am263px-lp/icss_m0_pru0_fw/ti-pru-cgt/makefile[15-28]
- examples/double_float/firmware/am263px-lp/icss_m0_pru1_fw/ti-pru-cgt/makefile[15-28]
- examples/double_float/firmware/am263px-cc/icss_m0_pru0_fw/ti-pru-cgt/makefile[15-28]
- examples/double_float/firmware/am263px-cc/icss_m0_pru1_fw/ti-pru-cgt/makefile[15-28]
- examples/double_float/firmware/am263x-lp/icss_m0_pru0_fw/ti-pru-cgt/makefile[15-28]
- examples/double_float/firmware/am263x-lp/icss_m0_pru1_fw/ti-pru-cgt/makefile[15-28]
- examples/double_float/firmware/am263x-cc/icss_m0_pru0_fw/ti-pru-cgt/makefile[15-28]
- examples/double_float/firmware/am263x-cc/icss_m0_pru1_fw/ti-pru-cgt/makefile[15-28]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feedback seems valid. Is there something in place to prevent the makefile from grabbing main_c_ref.c and using it as a build source?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ask

This feedback seems valid. Is there something in place to prevent the makefile from grabbing main_c_ref.c and using it as a build source?

Answer:

No—based on the new makefile logic shown in the diff, there is currently nothing preventing main_c_ref.c from being auto-discovered and compiled.

Why it gets picked up:

  • The makefiles set FILES_PATH := .. ../../.. .
  • With the makefile located at examples/double_float/firmware/<board>/<core>/ti-pru-cgt/, the ../../.. entry resolves to examples/double_float/firmware/
  • main_c_ref.c lives exactly in that directory (examples/double_float/firmware/main_c_ref.c)
  • C_FILES and OBJECTS are populated via $(wildcard $(directory)/*.c), so main_c_ref.c is included automatically.
  • At link time you then have two entry points:
    • main.asm defines main: (exported with .global main)
    • main_c_ref.c defines int main(void)
      This will typically cause a “multiple definition of main” link error for gmake all.

The comment in main_c_ref.c (“NOT compiled into the default PRU firmware project”) may be true for CCS projects if the projectspec excludes it, but it is not true for these makefile builds as written.

Recommended mitigation (one of):

  • Exclude the reference file in makefiles:
    • e.g. after computing C_FILES, do C_FILES := $(filter-out main_c_ref.c,$(C_FILES))
    • and similarly remove from OBJECTS (or derive OBJECTS from filtered C_FILES/ASM_FILES rather than re-wildcarding).
  • Or move main_c_ref.c into a directory not searched by FILES_PATH (e.g. firmware/ref/), and only include it in a dedicated “C reference” build.
  • Or add a build switch (e.g. BUILD_C_REF=y) that selects either main.asm or main_c_ref.c, but not both.

As-is, the bot’s feedback is valid for the makefile-based builds.


# Linker command file
COMMAND_FILES := linker.cmd

# Include paths
INCLUDE := \
--include_path=$(CGT_TI_PRU_PATH)/include \
--include_path=$(OPEN_PRU_PATH)/source
ifeq ($(BUILD_MCUPLUS),y)
INCLUDE += \
--include_path=$(MCU_PLUS_SDK_PATH)/source \
--include_path=$(MCU_PLUS_SDK_PATH)/source/pru_io/firmware/common
endif

# Compiler flags (Defined in 'PRU Optimizing C/C++ Compiler User's Guide)
# commonly modified flags include:
# silicon version: -v (3: PRUSS, PRU-ICSS; 4: PRU_ICSSG)
# C code optimization: -O (off, 0, 1, 2, 3, 4)
CFLAGS := \
-v3 -O2 \
--display_error_number --diag_wrap=off --diag_warning=225 \
--asm_directory=$(GEN_DIR) --obj_directory=$(GEN_DIR) --pp_directory=$(GEN_DIR) \
-ppd -ppa -g --endian=little

# Linker flags (Defined in 'PRU Optimizing C/C++ Compiler User's Guide)
LFLAGS := \
-m$(GEN_DIR)/$(OUTPUT_NAME).map --xml_link_info=$(GEN_DIR)/$(OUTPUT_NAME)_linkInfo.xml \
--display_error_number --diag_wrap=off --diag_warning=225 --diag_suppress=10063-D \
--warn_sections --reread_libs

ifeq ($(C_FILES),)
# PRU firmware is assembly-only
# commonly modified flags include:
# entry point
LFLAGS += \
--entry_point=main --disable_auto_rts --ram_model

else
# PRU firmware has C code
# commonly modified flags include:
# stack size, heap size
LFLAGS += \
--stack_size=0x100 --heap_size=0x100 \
-i$(CGT_TI_PRU_PATH)/lib -i$(CGT_TI_PRU_PATH)/include --library=libc.a
endif

# Defines (pass instance specific definitions to the program)
# see --define or -D in 'PRU Optimizing C/C++ Compiler User's Guide'
# For example, to define PRU0, ICSSG1, SOC_AM243X, and set _DEBUG_=1:
# -DPRU0 -DICSSG1 --define=SOC_AM243X -D_DEBUG_=1
DFLAGS :=

# Libraries
# see --library in 'PRU Optimizing C/C++ Compiler User's Guide'
LIBS :=

# Only build if tools are defined
ifeq (,$(CGT_TI_PRU_PATH))
all clean:
@echo 'CGT_TI_PRU_PATH not set. Make sure that:'
@echo ' 1) OPEN_PRU_PATH points to the open-pru repo'
@echo ' 2) imports.mak exists at OPEN_PRU_PATH'
@echo ' 3) Both the open-pru repo and imports.mak are set up as per'
@echo ' OPEN_PRU_PATH/docs/getting_started.md'
else

# All Target
all: $(OBJECTS) $(COMMAND_FILES)
@$(MAKE) --no-print-directory -Onone "$(TARGET)"

# Invoke the compiler on all assembly files in vpath to create the object files
$(GEN_DIR)/%.obj: %.asm
$(MKDIR) $(GEN_DIR)
@echo 'Building file: "$^"'
@echo 'Invoking: PRU Compiler'
"$(CGT_TI_PRU_PATH)/bin/clpru" $(INCLUDE) $(CFLAGS) $(DFLAGS) $^
@echo 'Finished building: "$^"'
@echo ' '

# Invoke the compiler on all c files in vpath to create the object files
$(GEN_DIR)/%.obj: %.c
$(MKDIR) $(GEN_DIR)
@echo 'Building file: $^'
@echo 'Invoking: PRU Compiler'
"$(CGT_TI_PRU_PATH)/bin/clpru" $(INCLUDE) $(CFLAGS) $(DFLAGS) $^
@echo 'Finished building: "$^"'
@echo ' '

# Invoke the linker (-z flag) to make the .out file
$(TARGET): $(OBJECTS) $(COMMAND_FILES)
@echo 'Building target: "$@"'
@echo 'Invoking: PRU Linker'
"$(CGT_TI_PRU_PATH)/bin/clpru" $(CFLAGS) -z $^ $(LFLAGS) -o $(TARGET) $(LIBS)
@echo 'Finished building target: "$@"'
@echo ' '
@$(MAKE) --no-print-directory post-build

# To clean generated files
clean:
-$(RMDIR) $(GEN_DIR)
ifeq ($(BUILD_MCUPLUS),y)
-$(RM) $(MCU_HEX_PATH)
endif
@echo 'Finished clean'
@echo ' '
endif

# Generate hex array
post-build:
-$(CGT_TI_PRU_PATH)/bin/hexpru --diag_wrap=off --array --array:name_prefix=$(HEX_ARRAY_PREFIX) -o $(TARGET_HEX) $(TARGET)
-$(CAT) $(OPEN_PRU_PATH)/source/firmware/pru_load_bin_copyright.h $(TARGET_HEX) > $(TARGET_HEX).temp
-$(MOVE) $(TARGET_HEX).temp $(TARGET_HEX)
ifeq ($(BUILD_MCUPLUS),y)
-$(COPY) $(TARGET_HEX) $(MCU_HEX_PATH)
endif
@echo ' '

.PHONY: all clean

# Include the dependencies that the compiler creates (-ppd and -ppa flags)
-include $(OBJECTS:%.obj=%.pp)
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#
# Auto generated makefile
#

export OPEN_PRU_PATH?=$(abspath ../../../../../..)
include $(OPEN_PRU_PATH)/imports.mak

PROFILE?=Release

PROJECT_NAME=double_float_multiply_am261x-lp_icss_m0_pru0_fw_ti-pru-cgt

all:
$(CCS_ECLIPSE) -noSplash -data $(OPEN_PRU_PATH)/ccs_projects -application com.ti.ccstudio.apps.projectBuild -ccs.projects $(PROJECT_NAME) -ccs.configuration $(PROFILE)

clean:
$(CCS_ECLIPSE) -noSplash -data $(OPEN_PRU_PATH)/ccs_projects -application com.ti.ccstudio.apps.projectBuild -ccs.projects $(PROJECT_NAME) -ccs.configuration $(PROFILE) -ccs.clean

export:
$(MKDIR) $(OPEN_PRU_PATH)/ccs_projects
$(CCS_ECLIPSE) -noSplash -data $(OPEN_PRU_PATH)/ccs_projects -application com.ti.ccstudio.apps.projectCreate -ccs.projectSpec example.projectspec -ccs.overwrite full
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*
* ======== syscfg_c.rov.xs ========
* This file contains the information needed by the Runtime Object
* View (ROV) tool.
*/
var crovFiles = [
"kernel/freertos/rov/FreeRTOS.rov.js",
];
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectSpec>
<applicability>
<when>
<context
deviceFamily="PRU"
deviceId="AM261x"
/>
</when>
</applicability>

<project
title="Double Float Multiply"
name = "double_float_multiply_am261x-lp_icss_m0_pru1_fw_ti-pru-cgt"
products="com.ti.OPEN_PRU;MCU-PLUS-SDK-AM261X"
configurations="
Release,
Debug,
"
connection="TIXDS110_Connection.xml"
toolChain="TI"
cgtVersion="2.3.3"
device="AM261x"
deviceCore="ICSS_M0_PRU_1"
ignoreDefaultDeviceSettings="true"
ignoreDefaultCCSSettings="true"
endianness="little"
outputFormat="ELF"
outputType="executable"

compilerBuildOptions="
-I${CG_TOOL_ROOT}/include
-I${MCU_PLUS_SDK_PATH}/source
-I${OPEN_PRU_PATH}/source
-I${MCU_PLUS_SDK_PATH}/source/pru_io/firmware/common
-DPRU1
-DSLICE1
-v4
-DSOC_AM261X
"
linkerBuildOptions="
-m=double_float_multiply.${ConfigName}.map
--disable_auto_rts
--entry_point=main
--diag_suppress=10063-D
"

postBuildStep="
"

description="A Double Float Multiply FW project">

<configuration name="Debug"
compilerBuildOptions="
-D_DEBUG_=1
"
linkerBuildOptions="
"
></configuration>
<configuration name="Release"
compilerBuildOptions="
-O3
"
linkerBuildOptions="
"
></configuration>
<pathVariable name="MCU_PLUS_SDK_PATH" path="${COM_TI_MCU_PLUS_SDK_AM261X_INSTALL_DIR}" scope="project" />
<pathVariable name="OPEN_PRU_PATH" path="${COM_TI_OPEN_PRU_INSTALL_DIR}" scope="project" />
<file path="../../../main.asm" openOnCreation="false" excludeFromBuild="false" action="copy">
</file>
<file path="./linker.cmd" openOnCreation="false" excludeFromBuild="false" action="copy">
</file>
<file path="${OPEN_PRU_PATH}/docs/api_guide_am261x/EXAMPLES_PRU_DOUBLE_FLOAT_MULTIPLY.html"
openOnCreation="false" excludeFromBuild="false" targetName="README.html" action="link">
</file>
</project>
</projectSpec>
Loading
Loading