Michal, this is up to you. You can load binaries from files during runtime or convert the binaries to header data and use them as arrays directly.
I'm using second variant. Karl 2015-01-08 14:01 GMT+01:00 <[email protected]>: > Hi Karl, > This is useful information. But can you tell how to actually load text_bin > and data_bin into compiler?? Are you creating static table hardcoded into > .c file or there is some easier way to do this? > > > On Thursday, 20 November 2014 06:44:37 UTC, Karl Karpfen wrote: >> >> 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. >> >> -- > For more options, visit http://beagleboard.org/discuss > --- > You received this message because you are subscribed to a topic in the > Google Groups "BeagleBoard" group. > To unsubscribe from this topic, visit > https://groups.google.com/d/topic/beagleboard/rCO-2nKynVE/unsubscribe. > To unsubscribe from this group and all its topics, send an email to > [email protected]. > For more options, visit https://groups.google.com/d/optout. > -- 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.
