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.

CCS: CCSv8 error with rts430.lib<boot.obj> using assembly language only

Tool/software: Code Composer Studio

I am using CCS version 8.3.0 and writing an assembly language only program for the PRU.  I have selected PRU tab and "Empty Assembly-only Project" when creating the project.  When I build the project I get the following error from the linker:

undefined first referenced                                                           
  symbol       in file                                                                
 --------- ----------------                                                           
 main      C:\ti\ccsv8\tools\compiler\ti-cgt-pru_2.3.1\lib\rtspruv3_le.lib<boot.c.obj>
 
error #10234-D: unresolved symbols remain
error #10010: errors encountered during linking; "dlk test 3.out" not built

From reading past thread on this error it appears something isn't happening correctly in the "Empty Assembly-only Project" selection and this library should only be linked for C programs?

If it matters, I am targeting a beaglebone black.

Any suggestions appreciated,

Thanks,
David.

  • Hi David,
    Did you explicitly set the program entry point (--entry_point) to the correct location? This is under the linker options (Build -> PRU Linker -> Advanced Options -> Symbol Management)

    Thanks
    ki
  • Ki,

    No I didn't. Entering different things in this field gets rid of the error but I'm having trouble finding the documentation explaining what the format for the entry point should be and understanding exactly where I want it to point to.

    Thanks,
    David.
  • I had a colleague take a close look at the issue and he was able to find the root cause of the issue. The project is being built with the RAM auto-initialization model (-cr). He mentioned that both of those options imply this link is for a C/C++ environment. Among other things, this sets the entry point to c_int00 (or some close variation of that symbol) and tries to get the boot code from the RTS library. The boot code calls main, which in this case is not present. Hence the error about an unresolved symbol 'main'.

    The tricky thing is that if you check the project build options, you don't see that option being used (at least when I used the asm template). But if you check the default linker command file (AM335x_PRU.cmd), you will see -cr defined on line 10. Remove that line and the linker error should go away. You will see some warning about "no suitable entry-point found; setting to 0". That is expected since no entry point is specified without the boot code. So the linker default to 0. You should specify where the program should start from when loaded.

    The asm project template clearly has some issues that need to be resolved. I'll file a bug for this.

    Thanks
    ki
  • Ki,

    Thanks for help.  Making progress but still getting errors.

    Removing line 10 did eliminate the error I was getting but I am still getting "error 10198-D: no input section is linked in".  I also get the warning you mentioned "10202-D: no suitable entry-point found; setting to 0".  Researching these on the web I found two relevant references:

    processors.wiki.ti.com/.../10198

    processors.wiki.ti.com/.../10202

    I tried the suggestions for error 10198-D but those did not eliminate the error but at least I didn't get any new errors.

    When I tried the suggestions for warning 10202-D I got errors on the ".global" line in the assembler file and errors when I added the label for start of my assembler code to the --entry_point field in symbol management.  Not sure what version of CSS this suggestion was for.  I assume I can live with the warning 10202-D so I'm not worried about this one.

    David.

  • David Kent1 said:
    I tried the suggestions for error 10198-D but those did not eliminate the error but at least I didn't get any new errors.

    adding the two directives (.retain and .retainrefs) should have gotten rid of the error. Can I see you asm file?

  • Ki,

    Here is the assembly code.  Also screen capture of the errors at end.

    David.

    ;This program is to learn programming of the PRU0 on the Beaglebone black
    ;written for CLPRU assembler
    ; v0.2 4/3/2019, D. Kent

    ; inputs
    ; r31.t2 is encoder index pulse
    ; r31.t3 is encoder A pulse
    ; r31.t1 is encoder B pulse
    ; r31.t15 is E_stop

    ; outputs
    ; r30.t5 is laser pulse

    ; register usage
    ; r0 is count of encoder A pulse falling edges between index pulse falling edges
    ; r1 is count of encoder B pulse falling edges between index pulse falling edges
    ; r2 is a scratch register used to check if encoder has changed state
    ; r3 is another scratch register
    ; r4 is another scratch register
    ; r5 is another scratch register



    INDEX_PULSE .set 8            ;length in clocks of pulse we output when we see falling edge of encoder index pulse
    A_PULSE .set 4
    B_PULSE .set 6
    ENC_A_MASK .set 0x8            ;mask for encoder A channel
    ENC_B_MASK .set 0x2            ;mask for encoder B channel
    ENC_INDEX_MASK .set 0x4        ;mask for encoder index channel
    ENC_INDEX_BIT .set 2        ;bit for encoder index channel
    ENC_ALL_MASK .set 0xE        ;mask for encoder all encoder channels

    ;.origin 0                        ; start of program in pru memory
    ;.entrypoint START                    ; Program will start at START

    .text
    ;got the below from processors.wiki.ti.com/.../10198
    .retain
    .retainrefs

    ;got the below from processors.wiki.ti.com/.../10202
    ;.global START                ;define the entry point


    START:
        ;setup stuff
        CLR r30.t5            ;make sure laser is OFF
        LDI r0, 0            ;clear the register we're using to count A pulses
        LDI r1, 0            ;clear the register we're using to count B pulses

        ;wait for the index pulse falling edge
        WBS r31, ENC_INDEX_BIT            ;wait for index pulse high.  Have to assume we might start looking with it high so need to look for falling edge next.
        WBC r31, ENC_INDEX_BIT            ;wait for falling edge of index pulse.  Should catch it within ±5nsec

    START_INDEX:
            ;laser ON for INDEX_PULSE clocks (5nsec per clock)
            LOOP END_LOOP1, INDEX_PULSE
                SET r30.t5
    END_LOOP1:
            CLR r30.t5

            ;now let's count the A and B pulse falling edges until next index pulse
            AND r2, r31, ENC_ALL_MASK        ;capture all the encoder channel states into r2.  Filter only encoder inputs.
    CAPTURE:
            MOV r3, r2                ;copy r2 to r3
    CAPTURE1:
            AND r2, r31, ENC_ALL_MASK        ;capture all the encoder channel states into r2.  Filter only encoder inputs.
            QBEQ CAPTURE1, r2, r3    ;if none of the encoder inputs changed read them again

            ;check for A pulse falling edge
            AND r4, r3, ENC_A_MASK                ;filter r3 for encoder A input
            AND r5, r2, ENC_A_MASK                ;filter r2 for encoder A input
            QBLE PULSE_A, r4, r5                ;branch if A did not change from 1 to 0
            ADD r0, r0, 1                        ;if A changed from 1 to 0 increment the pulse A counter
    PULSE_A:

            ;check for B pulse falling edge
            AND r4, r3, ENC_B_MASK                ;filter r3 for encoder B input
            AND r5, r2, ENC_B_MASK                ;filter r2 for encoder B input
            QBLE PULSE_B, r4, r5                ;branch if B did not change from 1 to 0
            ADD r1, r1, 1                        ;if B changed from 1 to 0 increment the pulse B counter
    PULSE_B:

        ;check for index pulse falling edge
        AND r4, r3, ENC_INDEX_MASK                ;filter r3 for encoder INDEX input
        AND r5, r2, ENC_INDEX_MASK                ;filter r2 for encoder INDEX input
        QBLE CAPTURE, r4, r5                    ;branch if INDEX did not change from 1 to 0

        ;Transfer pulse counts to shared memory so LINUX program can read them
        ;do we need interrupt to signal LINUX that we have data ready?

    DONE_START:

    Here are the errors

  • Thank you. I think the issue is having those two assembler directives on the first column (normally reserved for labels).
  • Ki-Soo Lee said:
    I think the issue is having those two assembler directives on the first column (normally reserved for labels).

    yes, this seems to be the case. Please see section 4.5.2 of the below user's guide:

    http://www.ti.com/lit/ug/spruhv6c/spruhv6c.pdf

    Thanks

    ki

  • That did it, thanks!