Part Number: SK-AM64
Hello everyone,
I am at my wits end about this topic so I hope you can help me. Thank you for reading.
The Setup:
I am working on the SK-AM64 using CCS version 10.4.0.00006 on windows to program and test the PRU cores.
I have a target configuration that allows me to connect to the SK-AM64 using the onboard XDS110 emulator.
First I connect to Cortex_M3_0 and right after to CortexA53_0 to execute on connect config.gel files.
Afterwards I connect to one of the PRU cores and load binaries onto them, that I previously build in a CCS Project.
I have a project for each PRU Core with code and files taken from the pru-software-support-package(pssp) 6.1.0.
Those files include:
.cmd files
resource_table.h
basic sourcecode for the PRU Core.
The resource_table.h is aligned for each .cmd as seen in the examples of the pssp.
In the project settings I have added the following paths to the pssp, mind the version:
pru-software-support-package-6.0.0\include\am64x\
pru-software-support-package-6.0.0\include\
Using the pssp defines I am able to access registers like the cycle count register and the control register to enable and disable it.
My Problem:
For some reason I can not access the Control ( and probably other registers) of the TX_PRUn. It does work well for PRUn and RTUn, but it does not work for TX_PRUn.
When I attempt to enable the cycle count register, it does not get updated in the register view of CCS and the cycle count register remains at 0. Reading the value at the address of the control register gives me 0x1, even though in CCS view it says 0x101.
I tried both using the pssp defines and directly changing these registers to no avail. I can however activate the counter using the CCS registerview and setting it to enabled.
I also had a weird occurence of the PRU0 counter resetting while TX_PRU was running using this code with less delay. PRU0 was only reading the value at the time and got stuck, as its own cycle counter kept resetting.
My attempt to fix it:
As I do not get any warnings or errors buiilding the PRU project, I have a hard time pinning down this problem.
Due to the influence on PRU0 I believe the problem has something to do with the memory map, though. I checked the .cmd file for TX_PRU0 multible times by now, but the memory map seems to match the address values from the AM64 TRM. I also made sure that I got the most recent version of the .cmd file ,which I found in the pssp v6.1.0 examples for the AM64.
A resource_table example for TX_PRU does not exist, so using the examples for PRU and RTU I made a minor change to it, so it does include a resourcetable section which is 8 bit aligned.
/*
* AM64x_TX_PRU0.cmd
*
* Example Linker command file for linking programs built with the C compiler
* on AM64x TX_PRU0 cores
*
* Copyright (C) 2021-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 */
-stack 0x100 // explicitly Set stack size
-heap 0x100 // explicitly Set heap size
/* Specify the System Memory Map */
MEMORY
{
PAGE 0:
/* 6 KB TX_PRU Instruction RAM */
TX_PRU_IMEM : org = 0x00000000 len = 0x00001800
PAGE 1:
/* Data RAMs */
/* 8 KB PRU Data RAM 0; use only the first 4 KB for PRU0 and reserve
* the second 4 KB for RTU0 and Tx_PRU0 */
PRU0_DMEM_0 : org = 0x00000000 len = 0x00001000 CREGISTER=24
/* 8 KB PRU Data RAM 1; reserved completely for Slice1 cores - PRU1,
* RTU1 and Tx_PRU1; do not use for any Slice0 cores */
PRU0_DMEM_1 : org = 0x00002000 len = 0x00001000 CREGISTER=25
/* NOTE: Custom split of the second 4 KB of ICSS Data RAMs 0 and 1
* split equally between the corresponding RTU and Tx_PRU cores in
* each slice */
RTU0_DMEM_0 : org = 0x00001000 len = 0x00000800
TX_PRU0_DMEM_0 : org = 0x00001800 len = 0x00000800
RTU0_DMEM_1 : org = 0x00003000 len = 0x00000800
TX_PRU0_DMEM_1 : org = 0x00003800 len = 0x00000800
PAGE 2:
/* C28 needs to be programmed to point to SHAREDMEM, default is 0 */
/* 64 KB PRU Shared RAM */
PRU_SHAREDMEM : org = 0x00010000 len = 0x00010000 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
/* XXX: 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
MII_G_RT : org = 0x00033000 len = 0x00000F44 CREGISTER=9
TM_CFG_TX_PRU0 : org = 0x0002A400 len = 0x0000004C CREGISTER=10
TX_PRU0_CTRL : org = 0x00025000 len = 0x00000030 CREGISTER=11
PA_STATS_QRAM : org = 0x00027000 len = 0x00001000 CREGISTER=12
PA_STATS_CRAM : org = 0x0002C000 len = 0x00001000 CREGISTER=13
MII_MDIO : org = 0x00032400 len = 0x00000088 CREGISTER=21
PRU_RTU_RAT0 : org = 0x00008000 len = 0x00000854 CREGISTER=22
PRU_IEP0 : org = 0x0002E000 len = 0x00000100 CREGISTER=26
MII_RT : org = 0x00032000 len = 0x00000070 CREGISTER=27
/* External Regions */
/* Random length 0x100 assigned to the below regions */
RSVD14 : org = 0x00024800 len = 0x00000100 CREGISTER=14
RSVD15 : org = 0x60000000 len = 0x00000100 CREGISTER=15
RSVD16 : org = 0x70000000 len = 0x00000100 CREGISTER=16
RSVD17 : org = 0x80000000 len = 0x00000100 CREGISTER=17
RSVD18 : org = 0x90000000 len = 0x00000100 CREGISTER=18
RSVD19 : org = 0xA0000000 len = 0x00000100 CREGISTER=19
RSVD20 : org = 0xB0000000 len = 0x00000100 CREGISTER=20
RSVD23 : org = 0xC0000000 len = 0x00000100 CREGISTER=23
/* Random 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 Tx_PRU IRAM. Not necessary when loading
an ELF file, but useful when loading a binary */
.text:_c_int00* > 0x0, PAGE 0
.text > TX_PRU_IMEM, PAGE 0
.stack > TX_PRU0_DMEM_0, PAGE 1
.bss > TX_PRU0_DMEM_0, PAGE 1
.cio > TX_PRU0_DMEM_0, PAGE 1
.data > TX_PRU0_DMEM_0, PAGE 1
.switch > TX_PRU0_DMEM_0, PAGE 1
.sysmem > TX_PRU0_DMEM_0, PAGE 1
.cinit > TX_PRU0_DMEM_0, PAGE 1
.rodata > TX_PRU0_DMEM_0, PAGE 1
.rofardata > TX_PRU0_DMEM_0, PAGE 1
.farbss > TX_PRU0_DMEM_0, PAGE 1
.fardata > TX_PRU0_DMEM_0, PAGE 1
/* Ensure resource_table section is aligned on 8-byte address for
ARMv8 (64-bit) kernel */
.resource_table : ALIGN (8) > TX_PRU0_DMEM_0, PAGE 1
}
For reference the .cmd file of RTU0, which is working fine:
/*
* AM64x_RTU0.cmd
*
* Example Linker command file for linking programs built with the C compiler
* on AM64x RTU0 cores
*
* Copyright (C) 2021 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 */
-stack 0x100 // explicitly Set stack size
-heap 0x100 // explicitly Set heap size
/* Specify the System Memory Map */
MEMORY
{
PAGE 0:
/* 8 KB RTU Instruction RAM */
RTU_IMEM : org = 0x00000000 len = 0x00002000
PAGE 1:
/* Data RAMs */
/* 8 KB PRU Data RAM 0; use only the first 4 KB for PRU0 and reserve
* the second 4 KB for RTU0 and Tx_PRU0 */
PRU0_DMEM_0 : org = 0x00000000 len = 0x00001000 CREGISTER=24
/* 8 KB PRU Data RAM 1; reserved completely for Slice1 cores - PRU1,
* RTU1 and Tx_PRU1; do not use for any Slice0 cores */
PRU0_DMEM_1 : org = 0x00002000 len = 0x00001000 CREGISTER=25
/* NOTE: Custom split of the second 4 KB of ICSS Data RAMs 0 and 1
* split equally between the corresponding RTU and Tx_PRU cores in
* each slice */
RTU0_DMEM_0 : org = 0x00001000 len = 0x00000800
TX_PRU0_DMEM_0 : org = 0x00001800 len = 0x00000800
RTU0_DMEM_1 : org = 0x00003000 len = 0x00000800
TX_PRU0_DMEM_1 : org = 0x00003800 len = 0x00000800
PAGE 2:
/* C28 needs to be programmed to point to SHAREDMEM, default is 0 */
/* 64 KB PRU Shared RAM */
PRU_SHAREDMEM : org = 0x00010000 len = 0x00010000 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
/* XXX: 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
MII_G_RT : org = 0x00033000 len = 0x00000F44 CREGISTER=9
TM_CFG_RTU0 : org = 0x0002A100 len = 0x0000004C CREGISTER=10
RTU0_CTRL : org = 0x00023000 len = 0x00000030 CREGISTER=11
PA_STATS_QRAM : org = 0x00027000 len = 0x00001000 CREGISTER=12
PA_STATS_CRAM : org = 0x0002C000 len = 0x00001000 CREGISTER=13
/* TODO: AM64x TRM has conflicting info. Is ICSSG_PROTECT at 0x24800 or
* 0x24C00? If ICSSG_PROTECT is at 0x24C00, does CREGISTER entry 14
* actually point to 0x24C00, or is it truly pointing at 0x24800? */
ICSSG_PROTECT : org = 0x00024800 len = 0x00000008 CREGISTER=14
MII_MDIO : org = 0x00032400 len = 0x00000088 CREGISTER=21
PRU_RTU_RAT0 : org = 0x00008000 len = 0x00000854 CREGISTER=22
PRU_IEP0 : org = 0x0002E000 len = 0x00000100 CREGISTER=26
MII_RT : org = 0x00032000 len = 0x00000070 CREGISTER=27
/* External Regions */
/* Random length 0x1000 assigned to the below regions */
RSVD15 : org = 0x60000000 len = 0x00001000 CREGISTER=15
RSVD16 : org = 0x70000000 len = 0x00001000 CREGISTER=16
RSVD17 : org = 0x80000000 len = 0x00001000 CREGISTER=17
RSVD18 : org = 0x90000000 len = 0x00001000 CREGISTER=18
RSVD19 : org = 0xA0000000 len = 0x00001000 CREGISTER=19
RSVD20 : org = 0xB0000000 len = 0x00001000 CREGISTER=20
RSVD23 : org = 0xC0000000 len = 0x00001000 CREGISTER=23
/* Random 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 RTU IRAM. Not necessary when loading
an ELF file, but useful when loading a binary */
.text:_c_int00* > 0x0, PAGE 0
.text > RTU_IMEM, PAGE 0
.stack > RTU0_DMEM_0, PAGE 1
.bss > RTU0_DMEM_0, PAGE 1
.cio > RTU0_DMEM_0, PAGE 1
.data > RTU0_DMEM_0, PAGE 1
.switch > RTU0_DMEM_0, PAGE 1
.sysmem > RTU0_DMEM_0, PAGE 1
.cinit > RTU0_DMEM_0, PAGE 1
.rodata > RTU0_DMEM_0, PAGE 1
.rofardata > RTU0_DMEM_0, PAGE 1
.farbss > RTU0_DMEM_0, PAGE 1
.fardata > RTU0_DMEM_0, PAGE 1
/* Ensure resource_table section is aligned on 8-byte address for
ARMv8 (64-bit) kernel */
.resource_table : ALIGN (8) > RTU0_DMEM_0, PAGE 1
}
Not adding the resource table and excluding it from the included files for TX_PRU does not fix it, either.
The Testcode with more includes than necessary, because I reuse files a lot :
#include <stdint.h>
#include <pru_cfg.h>
#include <pru_intc.h>
#include <rsc_types.h>
#include <pru_ctrl.h>
#include <sys_pwmss.h>
#include <pru_rpmsg.h>
#include <resource_table.h>
#define REG(x) (*( (volatile uint32_t *) (x) ))
/**
* main.c
*/
int main(void)
{
uint32_t cyclecCountCTR = CT_TX_PRU0_CTRL.CONTROL;
uint32_t *cycleCountCTRPointer = &CT_TX_PRU0_CTRL.CONTROL;
while(1){
CT_PRU1_CTRL.CONTROL_bit.COUNTER_ENABLE = 0x0;
REG(0x00025000) |= 1 << 3;
CT_TX_PRU1_CTRL.CONTROL_bit.COUNTER_ENABLE = 0x0;
CT_TX_PRU1_CTRL.CYCLE_COUNT = 0;
CT_TX_PRU1_CTRL.CONTROL_bit.COUNTER_ENABLE = 0x1;
__delay_cycles(299999999);
}
}cyclecounterCTR becomes 0x101 while cyclecounterCTRPointer is set to 0x25000, which is the correct address according to TRM.
I am sorry if there is an obvious solution or an already existing thread about this, but I could not find anything here regarding this topic. If there is anything else you need to know, i will try to provide it in time.
Best regards,
Patrick Halfar
Update: I looked into the PRU Device Memory in CCS to test if the program on TX_PRU0 changes any values. My first search was at the Control Register of PRU0, which is at 0x22000, and I was indeed right. The value is changed at 0x22000, when I use the pssp defines. However writing and reading the address directly yields the expected result despite my first tests not showing any change.
That would lead me to believe that the error is involved with the pssp header pru_ctrl.h more than the memory map. I will update this post when I made any more progress.
