This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Compiler/TMS320C6746: Compiler generates instructions which cause the PRU to crash

Part Number: TMS320C6746

Tool/software: TI C/C++ Compiler

I have a simple bit of code for the PRU to read the cycle counter of the PRU.  If the cycle counter reaches 0xFFFFFFFFFF, I wish to set it to 0 and re-enable it.  (Too bad it does not roll over...this would be much more useful).

Code is in C and looks like this:

uint32_t volatile cnt;

int main(void) {

while (1) {
cnt=PRU1_CTRL.CYCLE.CYCLE;
if (cnt==0xFFFFFFFF) {

PRU1_CTRL.CYCLE.CYCLE=0;
PRU1_CTRL.CTRL.CTRL_bit.COUNTER_ENABLE=1;
}

}

}

Assembly listing generates for the 1st 3 lines: (using either version 2.1.5 or 2.2 of the compiler)

159 00000000 000000248000E0 LDI r0, 0x8000 ; [] $O$K3
160 00000004 0000002EFF8190 ZERO &r16, 4 ; [] $O$K8
161 00000008 000000240000E1! LDI r1, ||cnt|| ; [] $O$K4,cnt

Seems reasonable enough...r0 has the address of the control registers, r1   has the address of my variable "cnt" and 4 bytes of r16 are set to zero for use as a value to move into the cycle counter to set it to 0.

The problem is with the code generated by the ZERO pseudo-op.  2EFF8190.  It shows up in the debugger disassembly as

XIN 255, &R16.bo,4

The only info I can find on the hex op codes tells me the following:

The hex of the op code means Format 2.  

That is, the SUBOP is 7, reserved.

The information in the Wiki on the PRU assembly instructions regarding XIN is:

On XIN, the register file data starting at the register REG with a length of IM(124) is read in from the parallel XFR interface from the hardware device with the device id specified in IM(253).

That is, the immediate operand 255 is illegal?

In any case, this instruction crashes the PRU.

Perhaps there is a flag on the compiler to prevent it from generating illegal instructions? 

Any assistance would be nice.

  • Unfortunately, I cannot build your code as given.  Please submit a test case as described in the article How to Submit a Compiler Test Case.

    Thanks and regards,

    -George

  • Compiler version for the PRU is 2.1.5 (2.2.0 does something very similar).

    Compiler options are:

    -O4 --opt_for_speed=5 --include_path="C:/ti/ccsv61/ccsv6/tools/compiler/ti-cgt-pru_2.1.5/include" -g --preproc_with_comment --preproc_with_compile --display_error_number --diag_warning=225 --diag_wrap=off --endian=little

    If it helps, linker command file:

    -cr

    -stack 0x40

    -heap  0x00

    /*--entry_point=_c_int00_noinit_noargs_noexit*/

    MEMORY

    {

      PAGE 0:

         PMEM:  org=0x0 len=0xF00

      PAGE 1:

         DMEM:  org=0x0 len=0x100

         SMEM:  org=0x100 len=0x100

    }

    SECTIONS

    {

      .bss  : {}>DMEM, PAGE 1

      .data : {}>DMEM, PAGE 1, palign=2

      .init_array: {}>DMEM, PAGE 1, palign=2

      .stack: {}>SMEM, PAGE 1, palign=2

      .boot:  {} >PMEM, PAGE 0

      .text:{} >PMEM, PAGE 0

    }

    and pre-processed source file:

    typedef unsigned int   uint32_t;

    typedef struct {

      volatile struct {

         uint32_t rsvd1 : 3;

         uint32_t COUNTER_ENABLE : 1;

         uint32_t rsvd2 : 28;

      } CTRL_bit;

      uint32_t spacer[2];  //0x04,0x08

      volatile uint32_t CYCLE; //0x0C

    } pruCtrl;

    uint32_t volatile cnt;

    int main(void)

    {

      while (1) {

         cnt=(*((volatile pruCtrl*)0x8000)).CYCLE;

         if (cnt==0xFFFFFFFF) {

            (*((volatile pruCtrl*)0x8000)).CYCLE=0;

            (*((volatile pruCtrl*)0x8000)).CTRL_bit.COUNTER_ENABLE=1;

         }

      }

    }

     

    1538.main.pp.txt
    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    typedef unsigned int uint32_t;
    typedef struct {
    volatile struct {
    uint32_t rsvd1 : 3;
    uint32_t COUNTER_ENABLE : 1;
    uint32_t rsvd2 : 28;
    } CTRL_bit;
    uint32_t spacer[2]; //0x04,0x08
    volatile uint32_t CYCLE; //0x0C
    } pruCtrl;
    uint32_t volatile cnt;
    int main(void)
    {
    while (1) {
    cnt=(*((volatile pruCtrl*)0x8000)).CYCLE;
    if (cnt==0xFFFFFFFF) {
    (*((volatile pruCtrl*)0x8000)).CYCLE=0;
    (*((volatile pruCtrl*)0x8000)).CTRL_bit.COUNTER_ENABLE=1;
    }
    }
    }
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    prurelease.cmd.txt
    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    -cr
    -stack 0x40
    -heap 0x00
    /*--entry_point=_c_int00_noinit_noargs_noexit*/
    MEMORY
    {
    PAGE 0:
    PMEM: org=0x0 len=0xF00
    PAGE 1:
    DMEM: org=0x0 len=0x100
    SMEM: org=0x100 len=0x100
    }
    SECTIONS
    {
    .bss : {}>DMEM, PAGE 1
    .data : {}>DMEM, PAGE 1, palign=2
    .init_array: {}>DMEM, PAGE 1, palign=2
    .stack: {}>SMEM, PAGE 1, palign=2
    .boot: {} >PMEM, PAGE 0
    .text:{} >PMEM, PAGE 0
    }
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

  • It turns out the TMS320C6746 has an older version of PRU on it.  You need to add --silicon_version=1 to your build options.  That will prevent the invalid ZERO instruction from being used.  I apologize for the inconvenience.

    Thanks and regards,

    -George

  • Thanks George.  Just noticed your reply.  Indeed that resolves the issue.

    Before I saw this, I had already tried selecting silicon -v1 in the IDE as a work around to complete the project, but it is important for us to know that this is the proper solution.

    Again, thanks.