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/TMS320C6748: How to load PRU from C6748

Part Number: TMS320C6748

Tool/software: Code Composer Studio

I have found a compiler http://software-dl.ti.com/codegen/non-esd/downloads/beta.htm which works on examples from this web page: https://git.ti.com/pru-software-support-package

The output is *.out and *.object both of which are ELF format. This needs further processing so the C6748 can transfer it into the PRU instruction memory. Are there any other programs that can to that?

Is it possible to have CCS compile a PRU project? I can see the tools from the preferences, but I don't see any way to create a PRU project.

Thanks,

Mike

  • Hi Mike,

    I've forwarded this to the design team. Their response will be posted here.

    Best Regards,
    Yordan
  • Thanks!

    I found a web page that shows different PRU's with various clock rates. So I started digging into the manuals I have , and there is a diagram on page 119 of the C6748 technical reference that shows the PRU getting its clock from SYSCLK2. If I run the DSP at max (456 MHz) will the PRU run at 228? As you can tell I haven't even figured out how to turn it on yet, but I'm getting there!
    Mike
  • So I made some progress, I powered up the PRU and can see it's memory from the CCS debugger. The version ID is 0x4E825900 - I think the 4E8 refers to the C6748 since all version IDs of subsystems seem to start with that. But what version of PRU hardware do I have? The C6748 manual says there is a scan instruction, but the wiki pages say the newer PRU's don't have a scan. Not that I can figure out how to use it, but it would be nice to know which version of hardware I am dealing with.

    I also found the PRU Assembly Language Tools User's Guide which explains a lot of my questions. Even if I can't do it within CCS, I can still create a *.asm file, assemble and link it with clpru, and then take that output as an entire chunk which I have to load into the PRU memory based on the load address in the file using my own code. I find it difficult to believe I can't find anyone who has not done this before! My web searching is just not finding anything, so if anyone has any pointers I'd love to chase after them.

    Mike
  • I read a good chunk of the PRU Assembly Language Tools User's Guide and began to wonder how you tell the linker to separate the memory zones since the internal run addresses are the same. There is no description, but on several web pages and in one example they show a MEMORY{ PAGE 0: PRUIMEM or I_MEM ... PAGE 1: PRUDMEM or D_MEM...} Why is page 0 instruction ram and page 1 data ram? Is this documented anywhere? Hopefully it will work for the C6748 - otherwise I have to get clever with UNION. Does the ELF output know the C6748 load address or do I have to be explicit within the linker command file?

    Mike
  • Here is a simple program to strip out just the code section from the clpru linker. I can load this directly using the debugger into the program memory on PRU0 and set the enable and reset bits in the control register and the program runs. So the answer to my original question is no - there is no way to do this from within CCS. But I'm on my way to getting my project done, so that's all that matters. Hopefully somebody else will find this useful someday.


     ****************************************************************************
     *                                                                          *
     *        This program reads in final linked ELF file from clpru -z command *
     *   and strips out the program section which will load into pru program    *
     *   memory.  Can create sophisticated version later which can also load    *
     *   initialization data into pru data memory, but for now ignore that.     *
     *                                                                          *
     *                 Author = Mike Rosing                                     *
     *                 Date = 19 Feb. 2017                                      *
     *                                                                          *
     ***************************************************************************/
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <elf.h>
    #include <string.h>
    
    int main(int argc, char *argv[])
    {
      FILE *pru, *strp;
      int i, j, k;
      char *flbfr, *flptr;
      Elf32_Ehdr *elf;
      Elf32_Phdr *pgm;
      char filename[128], *dot;
      
      if(argc < 2)
      {
        printf("Use %s <filename>\n", argv[0]);
        exit(0);
      }
      pru = fopen(argv[1], "r");
      if(!pru)
      {
        printf("can't find file %s\n", argv[1]);
        exit(-1);
      }
      
    /*  read in entire file.  assume size not so big. */
    
      flbfr = (char*)malloc(1024*16);
      i = 0;
      while((!feof(pru)) && (i < 16*1024))
      {
        flbfr[i] = fgetc(pru);
        i++;
      }
      elf = (Elf32_Ehdr*)flbfr;
      printf("entry point = %x\n", elf->e_entry);
      printf("program header offset = %x\n", elf->e_phoff);
      printf("elf header size = %d\n", elf->e_ehsize);
      printf("program header size = %d\n", elf->e_phentsize);
      printf("number of program headers = %d\n", elf->e_phnum);
      pgm = (Elf32_Phdr*)&flbfr[elf->e_phoff];
      for(i=0; i<elf->e_phnum; i++)
      {
        printf("program part %d\n", i);
        printf("program type = %x\n", pgm->p_type);
        printf("program location = %x\n", pgm->p_offset);
        printf("virtual address = %x\n", pgm->p_vaddr);
        printf("physical address = %x\n", pgm->p_paddr);
        printf("program size = %d\n", pgm->p_filesz);
        printf("program memory size = %d\n", pgm->p_memsz);
        printf("flags = %x\n", pgm->p_flags);
        printf("alignment = %d\n", pgm->p_align);
        printf("\n");
        pgm++;
      }
    
    /* create output file  */
      
      sprintf(filename, "%s", argv[1]);
      dot = strstr(filename, ".");
      if(!dot)
        strcat(filename, ".prog");
      else
        sprintf(dot, ".prog");
      strp = fopen(filename, "w");
      if(!strp)
      {
        printf("can not create file %s\n", filename);
        exit(-2);
      }
    
    /*  reset pointer to first program segment  */
    
      pgm = (Elf32_Phdr*)&flbfr[elf->e_phoff];
      for(i=0; i<elf->e_phnum; i++)
      {
        if((pgm->p_type == 1) && (pgm->p_flags & 1))
        {
    //      fwrite(&pgm->p_paddr, sizeof(char), 4, strp);
          fwrite(&flbfr[pgm->p_offset], sizeof(char), pgm->p_filesz, strp);
          fclose(strp);
          break;
        }
        pgm++;
      }
      printf("check output of %s\n", filename);
    }