Hi Il giorno giovedì 20 novembre 2014 07:44:37 UTC+1, Karl Karpfen ha scritto: > > There are many information about PRU usage out there but most of them > expect to have a Linux-system running which initialises PRU. In case > somebody wants to utilitise it out of a bare-metal or Starterware > application one is lost in the dark. PRU-registers are documentend in > AM3358 TRM but creating working code out of these specifications is not an > easy thing. So after it is working for me I'll provide all information here. > > To create the code running on PRU I'm using TI's C-compiler from > http://software-dl.ti.com/codegen/non-esd/downloads/download.htm#PRU > > Compilation of the source-file "main.c" is done by calling > > clpru --silicon_version=3 -I/opt/ti/ccsv6/tools/compiler/ti-cgt-pru_2.1.0/ > include/ -I/opt/ti/ccsv6/tools/compiler/ti-cgt-pru_2.1.0/lib/ \ > -o4 --opt_for_speed=5 main.c -z AM3359_PRU.cmd -o PRU_tests.out -m > PRU_tests.map > > This generates an ELF-file PRU_tests.out and a linker map file > PRU_tests.map which is needed to evaluate the start-address of the PRU-code > later. > > Next split the ELF file into two separate sections for text (read-only, > executable program code) and data (readable and writable but not > executable): > > hexpru bin.cmd PRU_tests.out > > This results in two files text.bin and data.bin which later have to be > loaded into instruction- and data-RAM of PRU. Now one can start with the > code running on AM3358 that initialises PRU0. First some definitions are > necessary that contain register-addresses: > > #define HWREG(x) (*((volatile unsigned int *)(x))) > > #define CM_PER_PRU_ICSS_CLKCTRL (0x000000E8u) // set to 0x00000002 to > enable/wake up > > #define CM_PER_PRU_ICSS_CLKSTCTRL (0x00000140u) // unset to > 0x00000002 to enable/wake up > #define CM_PER_PRU_ICSS_CLKSTCTRL_UART_GCLK (0x00000040u) // activate > UART clock > #define CM_PER_PRU_ICSS_CLKSTCTRL_IEP_GCLK (0x00000020u) // activate > IEP clock > #define CM_PER_PRU_ICSS_CLKSTCTRL_OCP_GCLK (0x00000010u) // activate > OCP clock > > #define PRU_PHYS_BASE_CTRL 0x0000 > > #define PRUSS_CFG_BASE_SYSCFG 0x0004 > #define PRUSS_CFG_BASE_GPCFG0 0x0008 > #define PRUSS_CFG_BASE_GPCFG1 0x000C > #define PRUSS_CFG_BASE_CGR 0x0010 > #define PRUSS_CFG_BASE_PIN_MX 0x0040 > #define PRUSS_CFG_BASE_PMAO 0x0028 > > And the code that initialises PRU's required clocks, copies text.bin and > data.bin into related RAM-areas, specifies start-address taken out of MAP > file and starts the whole thing: > > volatile int i=0; > > // reset the PRU, this may not be necessary in case of initial start-up > HWREG(SOC_PRM_PER_REGS)|=0x00000002; > while ((HWREG(SOC_PRM_PER_REGS) & 0x00000002)==0); //wait until reset > was done > HWREG(SOC_PRM_PER_REGS)&=0xFFFFFFFD; // clear reset bit > > // wake-up and nebale PRU, enable OCP-clock (mandatory) > // UART and IEP clock have to be enabled here too when needed > HWREG(SOC_CM_PER_REGS+CM_PER_PRU_ICSS_CLKCTRL)=0x00000002; > HWREG(SOC_CM_PER_REGS+CM_PER_PRU_ICSS_CLKSTCTRL)=( > CM_PER_PRU_ICSS_CLKSTCTRL_OCP_GCLK); > > // have a short delay before next step > while (i<10000) > { > i++; > } > HWREG(PRUSS_CFG_BASE+PRUSS_CFG_BASE_SYSCFG)=(0x00000005); > while ((HWREG(PRUSS_CFG_BASE+PRUSS_CFG_BASE_SYSCFG) & 0x00000020)!=0); // > check wait state bit > > // copy text and data into PRU0 instruction and data RAM > memcpy((void*)PRU0IRAM_PHYS_BASE,(void*)text_bin,sizeof(text_bin)); > memcpy((void*)DATARAM0_PHYS_BASE,(void*)data_bin,sizeof(data_bin)); > > // set start address and execute > HWREG(PRU0CONTROL_PHYS_BASE+PRU_PHYS_BASE_CTRL)|=0x04200000; // set > start address > HWREG(PRU0CONTROL_PHYS_BASE+PRU_PHYS_BASE_CTRL)|=0x00000002; // execute > > > The delay before writing 0x00000005 into SYSCFG-register is necessary for > some reason, I don't know if this is a good solution or if there is a > wait-/ready-bit to be checked somewhere. > > The start-address where execution of PRU-code has to begin can be found in > created MAP-file. There an entry > > 00000420 _c_int00_noinit_noargs_noexit > > can be found. _c_int00_noinit_noargs_noexit is the entry point for code > generated with TI's C-compiler and 00000420 is it's address. It has to be > shifted up by 16 bit and written into CTRL-register. > > Any comments, ideas, improvements are welcome! And feel free to use this > code without any restrictions. >
Hi Karl, I use CCS 6 texas in Ubuntu. I write my main.c and use AM3359.cmd. My main.c toggle the GPIO. Another i use the following comand : ./hexpru ../bin.cmd <path_directory_my_project/project.out>. This create 2 binary file: text.bin and data.bin. Now, what i do to run my program in AM3359? P.S: I use PRU1!!! Thanks -- For more options, visit http://beagleboard.org/discuss --- You received this message because you are subscribed to the Google Groups "BeagleBoard" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
