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/AM5728: PRU code optimization

Part Number: AM5728

Tool/software: Code Composer Studio

I am now using C++ for PRU , and come across a problem that , the IMEM(Instruction Memory,12KB) is overwhelming

How should I optimize my code. Here is the map(only the .text part because .text is loaded into  IMEM) of my PRU code ,  any suggestion will be thankful .

I am wondering why  vla_alloc.c.obj takes so many room of the IMEM

.text      0    0000001c    00002f68     
                  0000001c    00000770     main.obj (.text:main)
                  0000078c    00000244     rtspruv3_le.lib : vla_alloc.c.obj (.text:__vla_alloc)
                  000009d0    00000200     rtrunner.obj (.text:_ZN8Rtrunner13handle_normalEv)
                  00000bd0    000001dc     wdbuf.obj (.text:_ZN5wdbuf12wdbuf_createEPKcj)
                  00000dac    000001d4     rtspruv3_le.lib : memory.c.obj (.text:realloc)
                  00000f80    000001bc     rtrunner.obj (.text:_ZN8Rtrunner19encode_Write_to_RcsEi)
                  0000113c    00000168     rtrunner.obj (.text:_ZN8RtrunnerC1Ev)
                  000012a4    00000154     rtspruv3_le.lib : memory.c.obj (.text:malloc)
                  000013f8    00000128     uart_comm.obj (.text:_ZN8UARTComm4readEP13BufferFromDSPi)
                  00001520    00000124     rcs_comm.obj (.text:_ZN7RCSComm4readEP13BufferFromRCS)
                  00001644    00000120     rtrunner.obj (.text:_ZN8Rtrunner19encode_Write_to_DspEi)
                  00001764    0000011c     rtrunner.obj (.text:_ZN8Rtrunner20generateDspWritebuffEi)
                  00001880    00000114     rtrunner.obj (.text:_ZN8Rtrunner18generateIniBufToWdEi)
                  00001994    000000e8     rtrunner.obj (.text:_ZN8Rtrunner16handle_servo_stoEv)
                  00001a7c    000000e0     rwdevice_wd.obj (.text:_ZN2Wd5writeEPKhRKj)
                  00001b5c    000000e0     rtrunner.obj (.text:_ZN8Rtrunner18encode_Write_to_WdEv)
                  00001c3c    000000dc     rwdevice_wd.obj (.text:_ZN2Wd4readEPhRKj)
                  00001d18    000000d8     rtspruv3_le.lib : vla_alloc.c.obj (.text:_Z21free_dead_allocationsPv$33)
                  00001df0    000000d8     rpmsg_lib.lib : pru_rpmsg.object (.text:pru_rpmsg_send)
                  00001ec8    000000c4                   : pru_rpmsg.object (.text:pru_rpmsg_receive)
                  00001f8c    000000c0     route_list.obj (.text:_ZN9RouteList5popUpEPhj)
                  0000204c    000000b8     rtspruv3_le.lib : vla_alloc.c.obj (.text:__vla_dealloc)
                  00002104    000000b0     rwdevice_rpmsg.obj (.text:_ZN5Rpmsg4initEPv)
                  000021b4    000000b0     route_list.obj (.text:_ZN9RouteList8pushBackEPKhj)
                  00002264    000000a8     rtspruv3_le.lib : memory.c.obj (.text:free)
                  0000230c    000000a0     rwdevice_wd.obj (.text:_ZN2WdD1Ev)
                  000023ac    00000094     rwdevice_rpmsg.obj (.text:_ZN5Rpmsg4readEPhRKj)
                  00002440    00000088     route_list.obj (.text:_ZN9RouteList7getDataEPhj)
                  000024c8    00000070     rwdevice_uart.obj (.text:_ZN4Uart5writeEPKhRKj)
                  00002538    00000064     rwdevice_rpmsg.obj (.text:_ZN5Rpmsg5writeEPKhRKj)
                  0000259c    00000060     rtrunner.obj (.text:_ZN8RtrunnerD1Ev)
                  000025fc    00000060     rpmsg_lib.lib : pru_rpmsg.object (.text:pru_rpmsg_init)
                  0000265c    00000060                   : pru_virtqueue.object (.text:pru_virtqueue_get_avail_buf)
                  000026bc    00000060                   : pru_virtqueue.object (.text:pru_virtqueue_init)
                  0000271c    0000005c     rwdevice_uart.obj (.text:_ZN4Uart4initEPv)
                  00002778    0000005c     rpmsg_lib.lib : pru_rpmsg.object (.text:pru_rpmsg_channel)
                  000027d4    0000005c                   : pru_virtqueue.object (.text:pru_virtqueue_add_used_buf)
                  00002830    00000054     buffer_from_rcs.obj (.text:_ZN13BufferFromRCSC1Ev)
                  00002884    00000054     crc.obj (.text:_ZN3CRC9crc_ccittEPKhi)
                  000028d8    00000050     rwdevice_uart.obj (.text:_ZN4Uart4readEPhRKj)
                  00002928    00000044     pru_list.obj (.text:_ZN7PruList8pushBackEPKhj)
                  0000296c    00000044     route_list.obj (.text:_ZN9RouteList7freeMemEv)
                  000029b0    0000003c     buffer_to_dsp.obj (.text:_ZN11BufferToDSP7setDataEPKhjjj)
                  000029ec    0000003c     buffer_to_dsp.obj (.text:_ZN11BufferToDSPD1Ev)
                  00002a28    0000003c     buffer_to_rcs.obj (.text:_ZN11BufferToRCS7setDataEPKhjjj)
                  00002a64    0000003c     buffer_to_rcs.obj (.text:_ZN11BufferToRCSD1Ev)
                  00002aa0    0000003c     buffer_from_dsp.obj (.text:_ZN13BufferFromDSPD1Ev)
                  00002adc    0000003c     buffer_from_rcs.obj (.text:_ZN13BufferFromRCSD1Ev)
                  00002b18    00000038     rwdevice_wd.obj (.text:_ZN2Wd4initEPv)
                  00002b50    00000038     buffer_to_rcs.obj (.text:_ZN9RWBufBase10updateDataEPKhj)
                  00002b88    00000034     buffer_to_dsp.obj (.text:_ZN11BufferToDSPC1Ev)
                  00002bbc    00000034     buffer_to_rcs.obj (.text:_ZN11BufferToRCSC1Ev)
                  00002bf0    00000034     buffer_from_dsp.obj (.text:_ZN13BufferFromDSPC1Ev)
                  00002c24    00000034     rtspruv3_le.lib : memcpy.asm.obj (.text)
                  00002c58    00000030     pru_counter_operation.obj (.text:_Z19restart_pru_counterv)
                  00002c88    00000028     rcs_comm.obj (.text:_ZN7RCSCommC1Ev)
                  00002cb0    00000028     route_list.obj (.text:_ZN9RouteListC1Ev)
                  00002cd8    00000028     route_list.obj (.text:_ZN9RouteListD1Ev)
                  00002d00    00000028     rpmsg_lib.lib : pru_virtqueue.object (.text:pru_virtqueue_kick)
                  00002d28    00000024     buffer_to_dsp.obj (.text:_ZN11BufferToDSP11setRoutePosEPKhj)
                  00002d4c    00000024     buffer_to_dsp.obj (.text:_ZN11BufferToDSP14setControlFlagEPKhj)
                  00002d70    00000024     rtspruv3_le.lib : mpyi.c.obj (.text:__pruabi_mpyi)
                  00002d94    00000020     wdbuf.obj (.text:_Z6strcpyPcPKc$24)
                  00002db4    00000020     rwdevice_wd.obj (.text:_ZN2WdC1Ev)
                  00002dd4    00000020     rtspruv3_le.lib : new.c.obj (.text:_Znwj)
                  00002df4    0000001c     pru_list.obj (.text:_ZN7PruListC1Ev)
                  00002e10    00000018     rtspruv3_le.lib : typeinfo.c.obj (.text:_ZN10__cxxabiv117__class_type_infoD0Ev)
                  00002e28    00000018                     : typeinfo.c.obj (.text:_ZN10__cxxabiv120__si_class_type_infoD0Ev)
                  00002e40    00000018     rwdevice_uart.obj (.text:_ZN4UartC1Ev)
                  00002e58    00000018     uart_comm.obj (.text:_ZN8UARTCommC1Ev)
                  00002e70    00000018     prulogger.obj (.text:_ZN9PruloggerC1Ev)
                  00002e88    00000018     rtspruv3_le.lib : error.c.obj (.text:__abort_execution)
                  00002ea0    00000018                     : memset.c.obj (.text:memset)
                  00002eb8    00000014     prulogger.obj (.text:_ZN9PruloggerD1Ev)
                  00002ecc    00000010     pru_counter_operation.obj (.text:_Z21get_pru_counter_valuev)
                  00002edc    00000010     buffer_from_rcs.obj (.text:_ZN13BufferFromRCS14getControlFlagEv)
                  00002eec    00000010     buffer_from_rcs.obj (.text:_ZN13BufferFromRCS5getIDEv)
                  00002efc    00000010     buffer_from_rcs.obj (.text:_ZN13BufferFromRCS8getParamEv)
                  00002f0c    00000010     rtspruv3_le.lib : delete.c.obj (.text:_ZdlPv)
                  00002f1c    0000000c     buffer_from_dsp.obj (.text:_ZN13BufferFromDSP12getTimestampEv)
                  00002f28    0000000c     buffer_from_dsp.obj (.text:_ZN13BufferFromDSP13getServoBrakeEv)
                  00002f34    0000000c     buffer_from_dsp.obj (.text:_ZN13BufferFromDSP6getAckEv)
                  00002f40    0000000c     buffer_from_dsp.obj (.text:_ZN13BufferFromDSP6getPosEv)
                  00002f4c    00000008     rtrunner.obj (.text:_ZN8Rtrunner7getdiffEhh)
                  00002f54    00000008     rtrunner.obj (.text:_ZN9RWBufBase10getDataPtrEv)
                  00002f5c    00000008     buffer_to_rcs.obj (.text:_ZN9RWBufBase13getDataLengthEv)
                  00002f64    00000008     route_list.obj (.text:_ZN9RouteList11getRouteLenEv)
                  00002f6c    00000008     rtspruv3_le.lib : exit.c.obj (.text:abort)
                  00002f74    00000008                     : exit.c.obj (.text:loader_exit)
                  00002f7c    00000004                     : typeinfo.c.obj (.text:_ZN10__cxxabiv117__class_type_infoD1Ev)
                  00002f80    00000004                     : typeinfo.c.obj (.text:_ZN10__cxxabiv120__si_class_type_infoD1Ev)

  • Your program must use variable length arrays.  Something like ...

    int example_function(int length)
    {
       int array[length];  /* variable length array */
       ...

    This is implemented by calling a function in the RTS named __vla_alloc.  As you have seen, that function takes up a lot of code space.

    It is likely your best solution is to change your code to not use variable length arrays.

    Thanks and regards,

    -George

  • Hello George:

    I have tried to eliminate the code using variable length arrays. But __vla_alloc still takes a big part of the code space.

    And atually I can see that  pru_virio_ring.h is using a lot of variable length array, which is maintained by TI group. 

    like ring[] shown below

    struct vring_avail {
    	uint16_t flags;
    	uint16_t idx;
    	uint16_t ring[];
    };
    
    /* u32 is used here for ids for padding reasons. */
    struct vring_used_elem {
    	/* Index of start of used descriptor chain. */
    	uint32_t id;
    	/* Total length of the descriptor chain which was used (written to) */
    	uint32_t len;
    };
    
    struct vring_used {
    	uint16_t flags;
    	uint16_t idx;
    	struct vring_used_elem ring[];
    };

     

    Thanks and regards,

    Philos

     

  • Those struct definitions do not necessarily mean VLA is used.  

    I presume you build and run your project with Code Composer Studio (CCS).  Please look at the call graph by using the menu selection View | Stack Usage.  Search it for __vla_alloc to find calls to that function.  See who is calling it.

    Thanks and regards,

    -George