Skip to content

Instantly share code, notes, and snippets.

@jadonk
Last active April 10, 2025 00:50
Show Gist options
  • Save jadonk/f8e6197d7d0ce6063c0565e0fb28c1ad to your computer and use it in GitHub Desktop.
Save jadonk/f8e6197d7d0ce6063c0565e0fb28c1ad to your computer and use it in GitHub Desktop.
Broken AM62x PRU code with dmesg log
/*
* AM62x_PRU0.cmd
*
* Example Linker command file for linking programs built with the C compiler
* on AM62x PRU0 cores
*
* Copyright (C) 2022 Texas Instruments Incorporated - https://www.ti.com/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-cr /* Link using C conventions */
/* Specify the System Memory Map */
MEMORY
{
PAGE 0:
/* 12 KB PRU Instruction RAM */
PRU_IMEM : org = 0x00000000 len = 0x00003000
PAGE 1:
/* Data RAMs */
/* 8 KB PRU Data RAM 0 */
PRU0_DMEM_0 : org = 0x00000000 len = 0x00002000 CREGISTER=24
/* 8 KB PRU Data RAM 1 */
PRU0_DMEM_1 : org = 0x00002000 len = 0x00002000 CREGISTER=25
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 CREGISTER=28
/* Internal Peripherals */
/* NOTE: Use full INTC length instead of 0x200 to match the pruIntc
* structure definition in pru_intc.h, ignoring the second Constant
* Register #6 that starts at 0x200 offset within INTC */
PRU_INTC : org = 0x00020000 len = 0x00001504 CREGISTER=0
PRU_IEP1 : org = 0x0002F000 len = 0x00000100 CREGISTER=1
PRU_IEP1_0x100 : org = 0x0002F100 len = 0x0000021C CREGISTER=2
PRU_ECAP : org = 0x00030000 len = 0x00000060 CREGISTER=3
PRU_CFG : org = 0x00026000 len = 0x00000100 CREGISTER=4
PRU_CFG_0x100 : org = 0x00026100 len = 0x00000098 CREGISTER=5
/* PRU_INTC_0x200 is part of INTC space, and is therefore commented
* out as it conflicts with PRU_INTC size above. To use PRU_INTC_0x200,
* split up the pruIntc structure and CT_INTC variable in
* include/PROCESSOR/pru_intc.h */
/*PRU_INTC_0x200: org = 0x00020200 len = 0x00001304 CREGISTER=6*/
PRU_UART : org = 0x00028000 len = 0x00000038 CREGISTER=7
PRU_IEP0_0x100 : org = 0x0002E100 len = 0x0000021C CREGISTER=8
PRU0_CTRL : org = 0x00022000 len = 0x00000030 CREGISTER=11
PRU_RAT0 : org = 0x00008000 len = 0x00000854 CREGISTER=22
PRU_IEP0 : org = 0x0002E000 len = 0x00000100 CREGISTER=26
/* External Regions */
/* Random length 0x100 assigned to the below regions */
RSVD9 : org = 0x00033000 len = 0x0000100 CREGISTER=9
RSVD10 : org = 0x0002A000 len = 0x0000100 CREGISTER=10
RSVD12 : org = 0x00027000 len = 0x0000100 CREGISTER=12
RSVD13 : org = 0x0002C000 len = 0x0000100 CREGISTER=13
RSVD14 : org = 0x00024800 len = 0x0000100 CREGISTER=14
RSVD15 : org = 0x60000000 len = 0x0000100 CREGISTER=15
RSVD16 : org = 0x70000000 len = 0x0000100 CREGISTER=16
RSVD17 : org = 0x80000000 len = 0x0000100 CREGISTER=17
RSVD18 : org = 0x90000000 len = 0x0000100 CREGISTER=18
RSVD19 : org = 0xA0000000 len = 0x0000100 CREGISTER=19
RSVD20 : org = 0xB0000000 len = 0x0000100 CREGISTER=20
RSVD21 : org = 0x00032400 len = 0x0000100 CREGISTER=21
RSVD23 : org = 0xC0000000 len = 0x0000100 CREGISTER=23
RSVD27 : org = 0x00032000 len = 0x0000100 CREGISTER=27
/* length 0x10000 (max len value) assigned to programmable C29-31*/
RSVD29 : org = 0xD0000000 len = 0x00010000 CREGISTER=29
RSVD30 : org = 0xE0000000 len = 0x00010000 CREGISTER=30
RSVD31 : org = 0xF0000000 len = 0x00010000 CREGISTER=31
}
/* Specify the sections allocation into memory */
SECTIONS {
/* Forces _c_int00 to the start of PRU IRAM. Not necessary when loading
an ELF file, but useful when loading a binary */
.text:_c_int00* > 0x0, PAGE 0
.text > PRU_IMEM, PAGE 0
/* Using the beginning of PRU0 DMEM0 for commands, so this must be first */
.pru_dmem0 > PRU0_DMEM_0, PAGE 1
.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
.resource_table: type = COPY > 0
}
beagle@beagle:~/vsx-examples/Libraries/pru$ make TARGET=pwm.am62_pru0
Makefile:33: MODEL=BeagleBoard.org_PocketBeagle2,TARGET=pwm.am62_pru0
-    Stopping PRU 0
/bin/sh: 1: echo: echo: I/O error
Cannot stop 0
-       copying firmware file /tmp/vsx-examples/pwm.am62_pru0.out to /lib/firmware/am62x-pru0-fw
write_init_pins.sh
-    Starting PRU 0
make: *** [Makefile:193: start] Segmentation fault
[546004.831752] remoteproc remoteproc0: powering up 30074000.pru
[546004.832194] remoteproc remoteproc0: Booting fw image am62x-pru0-fw, size 27136
[546004.832244] Unable to handle kernel paging request at virtual address ffff800082f56004
[546004.832251] Mem abort info:
[546004.832253] ESR = 0x0000000096000061
[546004.832257] EC = 0x25: DABT (current EL), IL = 32 bits
[546004.832262] SET = 0, FnV = 0
[546004.832266] EA = 0, S1PTW = 0
[546004.832270] FSC = 0x21: alignment fault
[546004.832274] Data abort info:
[546004.832277] ISV = 0, ISS = 0x00000061, ISS2 = 0x00000000
[546004.832281] CM = 0, WnR = 1, TnD = 0, TagAccess = 0
[546004.832286] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
[546004.832291] swapper pgtable: 4k pages, 48-bit VAs, pgdp=00000000838f0000
[546004.832297] [ffff800082f56004] pgd=1000000084389003, p4d=1000000084389003, pud=100000008438a003, pmd=10000000815d4003, pte=0068000030040713
[546004.832323] Internal error: Oops: 0000000096000061 [#1] PREEMPT_RT SMP
[546004.832334] Modules linked in: rtl8xxxu mac80211 libarc4 pru_rproc irq_pruss_intc crct10dif_ce leds_pwm_multicolor led_class_multicolor seg_led_gpio line_display cpufreq_dt pwm_gpio rti_wdt algif_aead mma8452 ad7291 pinctrl_mcp23s08_spi pinctrl_mcp23s08 at24 pruss omap_mailbox cfg80211 loop efi_pstore dm_mod ip_tables
[546004.832421] CPU: 0 UID: 1000 PID: 114550 Comm: sh Not tainted 6.12.17-ti-arm64-r30 #1bookworm
[546004.832432] Hardware name: BeagleBoard.org PocketBeagle2 (DT)
[546004.832437] pstate: 20000005 (nzCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[546004.832446] pc : __memcpy+0x30/0x240
[546004.832463] lr : rproc_start+0x6c/0x1c0
[546004.832477] sp : ffff800087463a40
[546004.832481] x29: ffff800087463a40 x28: ffff00000a41b780 x27: 0000000000000000
[546004.832493] x26: 0000000000000000 x25: 0000000000000000 x24: ffff00000560aee0
[546004.832504] x23: 0000000000000000 x22: ffff000008de7838 x21: ffff00000560aee0
[546004.832515] x20: ffff800082f56000 x19: ffff000008de7800 x18: ffffffffffffffff
[546004.832526] x17: 0000000000000000 x16: 0000000000000000 x15: ffff8000874634c0
[546004.832537] x14: 0000000000000000 x13: 0000000000000000 x12: 0000000000000000
[546004.832547] x11: 0000000000000001 x10: fffffffffe36627f x9 : ffff800080f74c7c
[546004.832559] x8 : 0000000000002000 x7 : 0000000000000000 x6 : 0000000000000001
[546004.832569] x5 : ffff800082f56014 x4 : ffff00000560a1d4 x3 : ffff00000837c480
[546004.832581] x2 : 0000000000000014 x1 : ffff00000560a1c0 x0 : ffff800082f56000
[546004.832593] Call trace:
[546004.832598] __memcpy+0x30/0x240
[546004.832606] rproc_boot+0x194/0x578
[546004.832617] state_store+0x4c/0x120
[546004.832629] dev_attr_store+0x20/0x40
[546004.832644] sysfs_kf_write+0x4c/0x68
[546004.832658] kernfs_fop_write_iter+0x120/0x1f8
[546004.832669] vfs_write+0x240/0x380
[546004.832682] ksys_write+0x78/0x118
[546004.832691] __arm64_sys_write+0x24/0x38
[546004.832702] invoke_syscall+0x70/0x100
[546004.832715] el0_svc_common.constprop.0+0x48/0xf0
[546004.832725] do_el0_svc+0x24/0x38
[546004.832734] el0_svc+0x30/0x118
[546004.832745] el0t_64_sync_handler+0x100/0x130
[546004.832755] el0t_64_sync+0x190/0x198
[546004.832769] Code: 540000c3 a9401c26 a97f348c a9001c06 (a93f34ac)
[546004.832776] ---[ end trace 0000000000000000 ]---
# This Makefile tries to provide some defaults for building single-file programs on Beagle
# platforms in part by adding an additional suffix ahead of the source file extension. The
# original purpose was to provide ability to run these programs in the Cloud9 IDE environment.
#
# Optional definitions
#
# TARGET - executable to create (currently supports single .c, .cpp or .asm source)
# should have .<proc>(<n>) extension (lower case, check below for valid options)
# without TARGET, as of now, we don't have any build targets
# TODO: work with a list of targets, rather than a single file
# PRUN - TBD
# MODEL - board model from the device tree
# if not provided, an attempt will be made to read it directly
#
# Directories (external packages, etc.)
#
# COMMON points to where this primary Makefile and shell scripts live.
# PRU_CGT points to the TI PRU compiler directory.
# PRU_SUPPORT points to pru-software-support-package.
# C6X_CGT points to the TI C6X compiler directory.
# TIDL_API_DIR points to the TIDL API install directory.
# GEN_DIR points to where to build the binaries.
# MODEL is the board model (BeagleBoard.org_BeagleBone_AI, TI_AM335x_BeagleBone_Blue, etc.)
COMMON:=$(abspath $(lastword $(MAKEFILE_LIST)/..))
PRU_CGT:=/usr/share/ti/cgt-pru
PRU_SUPPORT:=/usr/lib/ti/pru-software-support-package
C6X_CGT:=/usr/share/ti/cgt-c6x
TIDL_API_DIR:=/usr/share/ti/tidl/tidl_api
GEN_DIR:=/tmp/vsx-examples
MODEL:=$(shell cat /proc/device-tree/model | sed 's/ /_/g' | tr -d '\000')
# $(warning MODEL=$(MODEL),TARGET=$(TARGET),COMMON=$(COMMON))
$(warning MODEL=$(MODEL),TARGET=$(TARGET))
#
# Define PROC and build variables
#
# Arguments:
# $@ - target name
#
# Variables defined:
# CHIP - target system-on-chip (am57xx, am335x)
# CHIP_REV - target system-on-chip with rev (am572x_2_0, am335x)
# PROC - cpu type (arm, pru, c6x, etc.)
# PRUN - identifier for target PRU core
# PRU_DIR - control directory for the PRU
# CC -
# LD -
# LDFLAGS -
# CFLAGS -
#
# Depends on udev rules: https://github.com/beagleboard/customizations/blob/master/etc/udev/rules.d/86-remoteproc-noroot.rules
# Check which model
define target-to-proc =
ifeq ($(suffix $(basename $(1))),.pru1_0)
CHIP=am57xx
CHIP_REV=am572x_2_0
PRU_DIR=/dev/remoteproc/pruss1-core0
PRUN=1_0
PROC=pru
EXE=.out
else ifeq ($(suffix $(basename $(1))),.pru1_1)
CHIP=am57xx
CHIP_REV=am572x_2_0
PRU_DIR=/dev/remoteproc/pruss1-core1
PRUN=1_1
PROC=pru
EXE=.out
else ifeq ($(suffix $(basename $(1))),.pru2_0)
CHIP=am57xx
CHIP_REV=am572x_2_0
PRU_DIR=/dev/remoteproc/pruss2-core0
PRUN=2_0
PROC=pru
EXE=.out
else ifeq ($(suffix $(basename $(1))),.pru2_1)
CHIP=am57xx
CHIP_REV=am572x_2_0
PRU_DIR=/dev/remoteproc/pruss2-core1
PRUN=2_1
PROC=pru
EXE=.out
else ifeq ($(suffix $(basename $(1))),.pru0)
CHIP=am335x
CHIP_REV=am335x
PRU_DIR=/sys/class/remoteproc/remoteproc1
PRUN=0
PROC=pru
EXE=.out
else ifeq ($(suffix $(basename $(1))),.pru1)
CHIP=am335x
CHIP_REV=am335x
PRU_DIR=/sys/class/remoteproc/remoteproc2
PRUN=1
PROC=pru
EXE=.out
else ifeq ($(suffix $(basename $(1))),.tidl)
CHIP=am57xx
PROC=tidl
EXE=.so
else ifeq ($(suffix $(basename $(1))),.am62_pru0)
CHIP=am62x
CHIP_REV=am62x
PRU_DIR=/sys/class/remoteproc/remoteproc0
PRUN=0
PROC=pru
EXE=.out
else
PROC=arm
EXE=.out
endif
endef
#
# Arguments:
# $@ - target name
#
# Variables required:
# CHIP - target system-on-chip (am57xx, am335x)
# CHIP_REV - target system-on-chip with rev (am572x_2_0, am335x)
# PROC - cpu type (arm, pru, c6x, etc.)
# PRUN - identifier for target PRU core
# PRU_DIR - control directory for the PRU
define proc-to-build-vars =
ifeq ("$(wildcard $(PRU_SUPPORT)/lib/rpmsg_lib.lib)","")
PRU_LIB=""
else
PRU_LIB="--library=$(PRU_SUPPORT)/lib/rpmsg_lib.lib"
endif
ifeq ($(PROC),pru)
LD=lnkpru -o
LDFLAGS=--reread_libs --warn_sections --stack_size=0x100 --heap_size=0x100 -m $(basename $(1)).map \
-i$(PRU_CGT)/lib -i$(PRU_CGT)/include $(COMMON)/$(CHIP)_$(PROC).cmd --library=libc.a $(PRU_LIB)
CC=clpru -fe
CFLAGS=--include_path=$(COMMON) --include_path=$(PRU_SUPPORT)/include \
--include_path=$(PRU_SUPPORT)/include/$(CHIP_REV) \
--include_path=$(PRU_CGT)/include -DCHIP=$(CHIP) -DCHIP_IS_$(CHIP) -DMODEL=$(MODEL) -DPROC=$(PROC) -DPRUN=$(PRUN) \
-v3 -O2 --printf_support=minimal --display_error_number --endian=little --hardware_mac=on \
--obj_directory=$(GEN_DIR) --pp_directory=$(GEN_DIR) --asm_directory=$(GEN_DIR) -ppd -ppa --asm_listing \
--c_src_interlist
else ifeq ($(PROC),tidl)
LD=g++ -o
LDFLAGS=-lopencv_highgui -lopencv_imgcodecs -lopencv_videoio -lopencv_imgproc -lopencv_core \
$(TIDL_API_DIR)/tidl_api.a $(TIDL_API_DIR)/tidl_imgutil.a \
-lTIOpenCL -locl_util -lpthread
CXX=g++ -c -o
CXXFLAGS=-DCHIP=$(CHIP) -DMODEL=$(MODEL) -DPROC=$(PROC) -fPIC -O3 -Wall -Werror -Wno-error=ignored-attributes \
-I. -I$(TIDL_API_DIR)/inc -std=c++14 -I/usr/share/ti/opencl
else
LD=gcc -o
LDFLAGS=-lc -lm
CC=gcc -c -o
CFLAGS=-DCHIP=$(CHIP) -DMODEL=$(MODEL) -DPROC=$(PROC)
endif
endef
#
#
#
ifeq ($(TARGET),)
#
# Build default local firmware
#
all: $(patsubst %.c,%.out,$(wildcard *.c))
else
#
# Original design for use in Cloud9 build environment with TARGET defined
#
$(eval $(call target-to-proc,$(TARGET).out))
# $(warning GEN_DIR=$(GEN_DIR),CHIP=$(CHIP),PROC=$(PROC),PRUN=$(PRUN),PRU_DIR=$(PRU_DIR),EXE=$(EXE))
all: stop install start
@echo "MODEL = $(MODEL)"
@echo "PROC = $(PROC)"
@echo "PRUN = $(PRUN)"
@echo "PRU_DIR = $(PRU_DIR)"
# TODO: think about what we want to say if stop fails
stop:
ifneq ($(PRU_DIR),)
@echo "- Stopping PRU $(PRUN)"
@echo stop > $(PRU_DIR)/state || echo Cannot stop $(PRUN)
endif
start:
ifneq ($(PRU_DIR),)
@echo write_init_pins.sh
@$(COMMON)/write_init_pins.sh /lib/firmware/$(CHIP)-pru$(PRUN)-fw
@echo "- Starting PRU $(PRUN)"
@echo start > $(PRU_DIR)/state
else ifeq ($(PROC),tidl)
ti-mct-heap-check -c
sudo mjpg_streamer -i "input_opencv.so -r 640x480 -d /dev/$(shell fgrep -v vpe /sys/class/video4linux/video*/name | perl -ne '/\/(video\d+)\/name/ && print $$1') \
--filter ./$(TARGET)$(EXE)" -o "output_http.so -p 8090 -w /usr/share/mjpg-streamer/www"
else
./$(TARGET)$(EXE)
endif
install: $(GEN_DIR)/$(TARGET)$(EXE)
ifneq ($(PRU_DIR),)
@echo '- copying firmware file $(GEN_DIR)/$(TARGET).out to /lib/firmware/$(CHIP)-pru$(PRUN)-fw'
@cp $(GEN_DIR)/$(TARGET)$(EXE) /lib/firmware/$(CHIP)-pru$(PRUN)-fw
else
@cp $(GEN_DIR)/$(TARGET)$(EXE) ./$(TARGET)$(EXE)
endif
endif
%.out: $(GEN_DIR)/%.out
@echo 'CP $^'
@cp $^ $@
%.so: $(GEN_DIR)/%.so
@echo 'CP $^'
@cp $^ $@
# TODO: look up how Makefiles typically break down the output file specification
# $(warning CHIP=$(CHIP),PROC=$(PROC))
# $(warning CC=$(CC),LD=$(LD),CFLAGS=$(CFLAGS),LDFLAGS=$(LDFLAGS))
$(GEN_DIR)/%.out: $(GEN_DIR)/%.o
@mkdir -p $(GEN_DIR)
@echo 'LD $^'
$(eval $(call target-to-proc,$@))
$(eval $(call proc-to-build-vars,$@))
@$(LD) $@ $^ $(LDFLAGS)
$(GEN_DIR)/%.so: $(GEN_DIR)/%.o
@mkdir -p $(GEN_DIR)
@echo 'LD $^'
$(eval $(call target-to-proc,$@))
$(eval $(call proc-to-build-vars,$@))
@$(LD) $@ -shared $^ $(LDFLAGS)
$(GEN_DIR)/%.o: %.asm
@mkdir -p $(GEN_DIR)
@echo 'CC $^'
$(eval $(call target-to-proc,$@))
$(eval $(call proc-to-build-vars,$@))
@$(CC) $@ $^ $(CFLAGS)
$(GEN_DIR)/%.o: %.c
@mkdir -p $(GEN_DIR)
@echo 'CC $^'
$(eval $(call target-to-proc,$@))
$(eval $(call proc-to-build-vars,$@))
@$(CC) $@ $^ $(CFLAGS)
$(GEN_DIR)/%.o: %.cpp
@mkdir -p $(GEN_DIR)
@echo 'CXX $^'
$(eval $(call target-to-proc,$@))
$(eval $(call proc-to-build-vars,$@))
@$(CXX) $@ $^ $(CXXFLAGS)
clean:
@echo 'CLEAN'
@rm *.out
@rm -rf $(GEN_DIR)
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* Copyright (C) 2025, Jason Kridner, BeagleBoard.org Foundation <[email protected]> */
/*
* pwm.am62_pru0.c - Example PWM firmware for AM62
*
* References:
* * SPRUHV6C - PRU Assembly Language Tools v2.3 User's Guide
* * SPRUHV7C - PRU Optimizing C/C++ Compiler v2.3 User's Guide
* * SPRULV7B - AM62x Processors Silicon Revision 1.0 Texas Instruments Families of Products Technical Reference Manual
* * https://git.ti.com/cgit/pru-software-support-package/pru-software-support-package/commit/?id=f3e3996c50b2c7bc7ed1f6f5374f3d8efb501a45
*/
#include <stdint.h>
#define NUM_GPO 20
#pragma DATA_SECTION(duty, ".pru_dmem0")
volatile uint32_t duty[NUM_GPO] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
uint32_t count[NUM_GPO] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
volatile register unsigned int __R30; /* R30 directly outputs to PRU GPO */
void main() {
int i, mask;
__R30 = 0;
while(1) {
mask = 0;
for(i=0; i<NUM_GPO; i++) {
if(count[i] == 0) {
if(duty[i] > 0) {
mask |= (1 << i); /* Invert GPO i */
count[i] = duty[i]; /* Start count */
}
}
else {
/* Need to make this the same number of cycles */
count[i]--; /* Decrement counter */
}
}
__R30 ^= mask; /* Apply updates at once */
}
}
/* This section is required by Linux to load the firmware using remoteproc */
#pragma DATA_SECTION(pru_remoteproc_ResourceTable, ".resource_table")
#pragma RETAIN(pru_remoteproc_ResourceTable)
struct resource_table {
uint32_t ver;
uint32_t num;
uint32_t reserved[2];
};
struct my_resource_table {
struct resource_table base;
uint32_t offset[1];
} pru_remoteproc_ResourceTable = { 1, 0, 0, 0, 0 };
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment