NOTICE: The Processors Wiki will End-of-Life in December of 2020. It is recommended to download any files or other content you may need that are hosted on processors.wiki.ti.com. The site is now set to read only.

PRU Linux Application Loader API Guide

From Texas Instruments Wiki
Jump to: navigation, search

Introduction[edit]

The PRUSSDRV User Space Library contains APIs that support the following:

  • Basic PRU control (i.e. enable/disable/reset PRU)
  • Helper functions (i.e. load and execute code in PRU)
  • Memory mapping of PRU/L3/External memories
  • PRU and Host event management (i.e. map sys_evt/channel/hosts in PRU INTC, generate interrupts, wait for occurrence of an event, and acknowledge interrupts)


The source code for the PRUSSDRV library is included in the PRU_SW Project (under pru_sw/trunk/app_loader/interface/prussdrv.c).


API Descriptions[edit]

The functions provided by the PRUSSDRV library are described below.

prussdrv_init[edit]

Initializes and allocates memory for the PRU Subsystem driver. This is a required function call.

    Function declaration:         int prussdrv_init (void) 
        
    Example function call:        prussdrv_init ( ); 

prussdrv_open[edit]

Opens an event out and initializes memory mapping. This is a required function call. The input is a pru_evtout_num (PRU_EVTOUT_0 - PRU_EVTOUT_7) corresponding to Host2 - Host9 of the PRU INTC. If no events are required for the user code, choose PRU_EVTOUT_0 for the input parameter. Otherwise, call this function for each event required by the user code. Note if multiple events are used, this function is called multiple times.

    Function declaration:         int prussdrv_open (unsigned int pru_evtout_num) 
        
    Example function call:        prussdrv_open ( PRU_EVTOUT_0 );  

prussdrv_pru_reset[edit]

Resets the PRU by invoking a soft reset in the PRU Control Register.

    Function declaration:         int prussdrv_pru_reset (unsigned int prunum)  
        
    Example function call:        prussdrv_pru_reset ( 0 );  //Resets PRU0      

prussdrv_pru_disable[edit]

Disables the PRU by writing 0 to the enable bit of the PRU Control Register.

    Function declaration:         int prussdrv_pru_disable (unsigned int prunum);  
        
    Example function call:        prussdrv_pru_disable ( 0 );  //Disables PRU0 

prussdrv_pru_enable[edit]

Enables the PRU by writing 1 to the enable bit of the PRU Control Register.

    Function declaration:         int prussdrv_pru_enable (unsigned int prunum);  
        
    Example function call:        prussdrv_pru_enable ( 0 );  //Enables PRU0 

prussdrv_pru_write_memory[edit]

Writes to either PRU Data RAM or Instruction RAM. Selects type of memory writing to and writes content at memarea pointer into memory. This function requires the input parameters described below:

1. pru_ram_idis defined within PRUSSDRV as:
#define PRUSS0_PRU0_DATARAM 0
#define PRUSS0_PRU1_DATARAM 1
#define PRUSS0_PRU0_IRAM 2
#define PRUSS0_PRU1_IRAM 3
2. wordoffset is the offset from *memarea.
3. *memarea is a pointer to the starting address where data/ content is stored.
4. bytelength is the size of the content being written to memory.
    Function declaration:         int prussdrv_pru_write_memory (unsigned int pru_ram_id, unsigned int wordoffset, unsigned int *memarea,  unsigned int bytelength); 
       
    Example function call:        prussdrv_pru_write_memory(PRUSS0_PRU0_IRAM, 0, (unsigned int *) fileDataArray, fileSize); 

prussdrv_pruintc_init[edit]

Initializes and enables the PRU interrupt controller. The input is a structure of arrays that determine which system events are enabled and how each is mapped to a host event. This structure (PRUSS_INTC_INITDATA) is defined in pruss_intc_mapping.h and can be modified by the user. Below is the PRUSS_INTC_INITDATA definition and description of each array in the structure:

#define PRUSS_INTC_INITDATA { \
{ PRU0_PRU1_INTERRUPT, PRU1_PRU0_INTERRUPT, PRU0_ARM_INTERRUPT, PRU1_ARM_INTERRUPT, ARM_PRU0_INTERRUPT, ARM_PRU1_INTERRUPT, -1 }, \
{ {PRU0_PRU1_INTERRUPT,CHANNEL1}, {PRU1_PRU0_INTERRUPT, CHANNEL0}, {PRU0_ARM_INTERRUPT,CHANNEL2}, {PRU1_ARM_INTERRUPT, CHANNEL3}, {ARM_PRU0_INTERRUPT, CHANNEL0},
{ARM_PRU1_INTERRUPT, CHANNEL1}, {-1,-1}}, \
{ {CHANNEL0,PRU0}, {CHANNEL1, PRU1}, {CHANNEL2, PRU_EVTOUT0}, {CHANNEL3, PRU_EVTOUT1}, {-1,-1} }, \
(PRU0_HOSTEN_MASK | PRU1_HOSTEN_MASK | PRU_EVTOUT0_HOSTEN_MASK | PRU_EVTOUT1_HOSTEN_MASK) /*Enable PRU0, PRU1, PRU_EVTOUT0 */ \
} \
Array 1: enables the system event numbers listed
Array 2: assigns system event numbers to channel numbers
Array 3: links channel numbers to host numbers
Array 4: creates mask to enable host interrupts (or event out numbers)
    Function declaration:         int prussdrv_pruintc_init (tpruss_intc_initdata *prussintc_init_data); 
        
    Example function call:        #include <pruss_intc_mapping.h>
                                  void main (void) { ...
                                       tpruss_intc_initdata pruss_intc_initdata = PRUSS_INTC_INITDATA;
                                       prussdrv_pruintc_init(&pruss_intc_initdata);
                                  }	

prussdrv_map_l3mem[edit]

Maps the L3 memory to input pointer. Memory is then accessed by an array.

    Function declaration:         int prussdrv_map_l3mem (void **address);  
        
    Example function call:        unsigned int *l3mem;
                                  prussdrv_map_l3mem(&l3mem); 


prussdrv_map_extmem[edit]

Maps the DDR external memory to input pointer. Memory is then accessed by an array. Note the base address of prussdrv_map_extmem is 0xC1000000 (not 0xC0000000).

    Function declaration:         int prussdrv_map_extmem (void **address);  
        
    Example function call:        unsigned int *extmem;
                                  prussdrv_map_extmem(&extmem); 
                                  unsigned int bytes_available = prussdrv_extmem_size();

prussdrv_extmem_size[edit]

Reports how much DDR external memory was mapped by uio_pruss. (This can be set with modprobe uio_pruss extram_pool_sz=...)

    Function declaration:         unsigned int prussdrv_extmem_size (void);  
        
    Example function call:        unsigned int bytes_available = prussdrv_extmem_size();

prussdrv_map_prumem[edit]

Maps the PRU DRAM memory to input pointer. Memory is then accessed by an array. Minimum one event needs to be opened to access memory map. Call this function (prussdrv_map_prumem()) after the prussdrv_open(PRU_EVTOUT_x) function.

    Function declaration:         int prussdrv_map_prumem (unsigned int pru_ram_id, void **address);  
        
    Example function call:        unsigned int *pruDataMem;
                                  prussdrv_map_prumem (&pruDataMem); 

prussdrv_get_phys_addr[edit]

Pass in a PRU/L3/external memories pointer, and returns the corresponding physical address.

    Function declaration:         unsigned int prussdrv_get_phys_addr (void *address);  
        
    Example function call:        unsigned int phys_addr;
                                  phys_addr = prussdrv_get_phys_addr (l3mem); //l3mem is a mmap returned value 

prussdrv_get_virt_addr[edit]

Pass in a PRU/L3/external memory physical address, and returns a pointer containing the corresponding virtual address.

    Function declaration:         void *prussdrv_get_virt_addr (unsigned int phyaddr)  
        
    Example function call:        void *virt_addr;
                                  unsigned int l3_phys_addr = 0x8000000;
                                  virt_addr = prussdrv_get_virt_addr (l3_phys_addr);

prussdrv_pru_wait_event[edit]

Waits for PRU event out.

    Function declaration:         int prussdrv_pru_wait_event (unsigned int pru_evtout_num);  
        
    Example function call:        prussdrv_pru_wait_event ( PRU_EVTOUT_0 ); 

prussdrv_pru_send_event[edit]

Sends system event to PRU.

    Function declaration:         int prussdrv_pru_send_event (unsigned int eventnum);  
        
    Example function call:        prussdrv_pru_send_event ( 32 ); 

prussdrv_pru_clear_event[edit]

Clears system event.

    Function declaration:         int prussdrv_pru_clear_event (unsigned int host_interrupt, unsigned int eventnum);  
        
    Example function call:        prussdrv_pru_clear_event ( PRU_EVTOUT0, PRU0_ARM_INTERRUPT ); 

prussdrv_pru_send_wait_clear_event[edit]

Sends system event to PRU, waits for PRU event out, and clears system event.

    Function declaration:         int prussdrv_pru_send_wait_clear_event  (unsigned int send_eventnum, unsigned int pru_evtout_num, unsigned int ack_eventnum);
        
    Example function call:        prussdrv_pru_send_wait_clear_event  ( 32, PRU_EVTOUT_0, 32); 

prussdrv_exit[edit]

Releases PRUSS clocks and disables prussdrv module.

    Function declaration:         int prussdrv_exit (void);
        
    Example function call:        prussdrv_exit ( ); 

prussdrv_exec_program[edit]

Executes a binary file of opcodes on the PRU using the following steps:

  1. Disable PRU
  2. Write contents to PRU iRAM
  3. Enable PRU to begin executing instructions stored in iRAM
    Function declaration:         int prussdrv_exec_program (int prunum, char *filename);
        
    Example function call:        prussdrv_exec_program ( 0, "./PRU_example.bin"); 

prussdrv_start_irqthread[edit]

Initializes interrupt handler (or IRQ thread) for particular event. This function requires the following input parameters:

1. pru_evtout_num: the event number associated with (or hooked to) the interrupt handler.
2. priority: an integer, where a lower pririty number is given higher priority.
3. irqhandler: the interrupt handler name.
    Function declaration:         int prussdrv_start_irqthread (unsigned int pru_evtout_num,  int priority, function_handler irqhandler);

        
    Example function call:        #include pthread
                                  
                                  void *pruevtout0_thread(void *arg) {       // Example interrupt handler thread
                                     do {
                                         prussdrv_pru_wait_event (PRU_EVTOUT_0);
                                         // Handle event
                                         prussdrv_pru_clear_event (PRU_EVTOUT0, PRU0_ARM_INTERRUPT);
                                     } while (1);
                                  }
                                  
                                  void main (void) { ...
                                         prussdrv_start_irqthread (PRU_EVTOUT_0, sched_get_priority_max(SCHED_FIFO) - 2, pruevtout0_thread);
                                  } 




Skeleton Application Code[edit]

The following is a skeleton application code that uses the PRUSSDRV APIs to load and execute a set of instructions to the PRU and handle an PRU-generated interrupt.

   /* Driver header file */
   #include <prussdrv.h>
   #include <pruss_intc_mapping.h> 
   
   #define PRU_NUM 	0
   
   /* IRQ handler thread */
   void *pruevtout0_thread(void *arg) {
       do {
          prussdrv_pru_wait_event (PRU_EVTOUT_0);
          prussdrv_pru_clear_event (PRU_EVTOUT0, PRU0_ARM_INTERRUPT);
       } while (1);
   }
   
   void main (void)
   {
       /* Initialize structure used by prussdrv_pruintc_intc   */
       /* PRUSS_INTC_INITDATA is found in pruss_intc_mapping.h */
       tpruss_intc_initdata pruss_intc_initdata = PRUSS_INTC_INITDATA;
   
       /* Allocate and initialize memory */
       prussdrv_init ();		
       prussdrv_open (PRU_EVTOUT_0);
       
       /* Map PRU's INTC */
       prussdrv_pruintc_init(&pruss_intc_initdata);
       
       /* Load and execute binary on PRU */
       prussdrv_exec_program (PRU_NUM, "./PRU_example.bin");
       
       /* Wait for event completion from PRU */
       prussdrv_pru_wait_event (PRU_EVTOUT_0);  // This assumes the PRU generates an interrupt 
                                                // connected to event out 0 immediately before halting
   
       /* Disable PRU and close memory mappings */
       prussdrv_pru_disable(PRU_NUM); 
       prussdrv_exit ();
    }
E2e.jpg {{
  1. switchcategory:MultiCore=
  • For technical support on MultiCore devices, please post your questions in the C6000 MultiCore Forum
  • For questions related to the BIOS MultiCore SDK (MCSDK), please use the BIOS Forum

Please post only comments related to the article PRU Linux Application Loader API Guide here.

Keystone=
  • For technical support on MultiCore devices, please post your questions in the C6000 MultiCore Forum
  • For questions related to the BIOS MultiCore SDK (MCSDK), please use the BIOS Forum

Please post only comments related to the article PRU Linux Application Loader API Guide here.

C2000=For technical support on the C2000 please post your questions on The C2000 Forum. Please post only comments about the article PRU Linux Application Loader API Guide here. DaVinci=For technical support on DaVincoplease post your questions on The DaVinci Forum. Please post only comments about the article PRU Linux Application Loader API Guide here. MSP430=For technical support on MSP430 please post your questions on The MSP430 Forum. Please post only comments about the article PRU Linux Application Loader API Guide here. OMAP35x=For technical support on OMAP please post your questions on The OMAP Forum. Please post only comments about the article PRU Linux Application Loader API Guide here. OMAPL1=For technical support on OMAP please post your questions on The OMAP Forum. Please post only comments about the article PRU Linux Application Loader API Guide here. MAVRK=For technical support on MAVRK please post your questions on The MAVRK Toolbox Forum. Please post only comments about the article PRU Linux Application Loader API Guide here. For technical support please post your questions at http://e2e.ti.com. Please post only comments about the article PRU Linux Application Loader API Guide here.

}}

Hyperlink blue.png Links

Amplifiers & Linear
Audio
Broadband RF/IF & Digital Radio
Clocks & Timers
Data Converters

DLP & MEMS
High-Reliability
Interface
Logic
Power Management

Processors

Switches & Multiplexers
Temperature Sensors & Control ICs
Wireless Connectivity