the AM335x TRM specifies a constants table for PRU which can be used for easier access of memory addresses. As an example: for I2C1 registers which originally use base-address 0x4802A000 a constant 2 is defined.
What I do not understand: how can one use these constants? How does the mapping from a constant to a base-address work where I have to add an offset in order to access desired registers?
Or is this an assembler-thingy only which can’t be used out of PRU-C-Software?
The support package is just examples of how to use RemoteProc/RPMSG. Remember to use V4.02 for the V4.1 Linux Kernel and V5 for the V4.4 Linux kernel. The V4.02 uses mailbox events and the V5 uses interrupt events. If you want ARM sample code which interacts with the PRU firmware, look in the Linux source code /samples/rpmsg.
These constants allow the C compiler to produce more efficient code. Of course you can also use them in assembly programs by explicitly using lbco/sbco instructions.
Let me give you an example how pru-gcc uses the constant table. Consider this C code snippet:
What is the declaration syntax for TI’s clpru C/C++ compiler for declaring constant entries? I tried to find where it might be documented in the PRU Optimizing C/C++ Compiler doc (spruhv7c.pdf). But it didn’t seem to make any reference to the PRU constant table. But I’m assuming it needs to know what memory addresses are in there so it can know when it can optimize.
And what include-file would those declarations be supplied in that need to make sure to include on order to ensure the compiler uses the more efficient syntax?
Hey Chris. This might be a little late. However I had similar questions and I believe you will find these answers in the PRU_C_USER_GUIDE.pdf
and specifically section 5.14.4 which states the following:
5.14.4 Type Attributes
The following type attributes are supported: aligned, cregister, deprecated, packed, transparent_union,
unused, and visibility.
The cregister attribute provides support for using the constant registers. If the cregister attribute is used,
the peripheral attribute can be used along with it. The syntax is:
int x __attribute__((cregister("MEM", [near|far]), peripheral));
The name "MEM" can be any name, although it will need to correspond to a memory range name in your
linker command file. The near or far parameter tells the compiler whether it can use the immediate
addressing mode (near) or register indirect addressing mode (far). If the data will be completely contained
within the first 256 bytes from the top of the constant register pointer then use near, otherwise use far. The
default is near.
The peripheral attribute can only be used with the cregister attribute and has two effects. First, it puts the
object in a section that will not be loaded onto the device. This prevents initialization of the peripheral at
runtime. Second, it allows the same object to be defined in multiple source files without a linker error. The
intent is that peripherals can be completely described in a header file.
The linker command file must be modified for the cregister attribute to work, otherwise relocation errors
occur. See the PRU Assembly Language Tools User's Guide for details about the linker command file.
The updated linker command file syntax is:
MEMORY
{
MEM: o=xxx l=xxx CREGISTER=4
}