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.

Compiler/AM3354: Compiling .asm and executing using commands from 'prussdrv.h' + JAL-issues with clpru

Part Number: AM3354

Tool/software: TI C/C++ Compiler

Hi!

I've been using the PASM-compiler, but decided to change my code to fit with the recommended clpru compiler. (For BeagleBone Black) Previously i've been able to

compile the source code directly to '.bin' and upload it using the prussdrv.h execute command, but clpru gives me an '.obj' and '.out'-flie. I've been looking for answers with linking '.obj'-files, but didn't find any good answers. Do anyone have a brief explanation of how my code should be linked to get the '.bin' file, alternatively other options using the '.obj'-file?

Until now i've loaded the '.obj'-file using prussdrv_exec_program(PRUNUM, "PROGRAM FILE"). 

This did however not work with JAL, with .asg i predefined a CALL_REG to store return address, but when running it gives no indication of jumping or returning.

;******************************************************************************
;* PRU C/C++ Codegen                                              Unix v2.1.4 *
;* Date/Time created: Tue Mar 21 04:57:50 2017                                *
;******************************************************************************
	.compiler_opts --abi=eabi --endian=little --hll_source=on --object_format=elf --silicon_version=3 --symdebug:none 
;	optpru --call_assumptions=3 --gen_opt_info=2 /tmp/08571jbUso2 /tmp/08571YOCaL9 --opt_info_filename=empty.nfo 
;	acpiapru -@/tmp/08571SM9heD 
	.sect	".text:main"
	.clink
	.global	||main||

;***************************************************************
;* FNAME: main                          FR SIZE:   0           *
;*                                                             *
;* FUNCTION ENVIRONMENT                                        *
;*                                                             *
;* FUNCTION PROPERTIES                                         *
;*                            0 Auto,  0 SOE     *
;***************************************************************

||main||:
;* --------------------------------------------------------------------------*
        ZERO      &r14, 4               ; [ALU_PRU] |2| 
        JMP       r3.w2                 ; [ALU_PRU]     

  	.asg		"0",		MOSI		;r30_0 (P9.31)
 	.asg		"1",		MISO		;r31_1 (P9.29)
	.asg		"2",		SPI_SCLK	;r31_2 (P9.30)
	.asg		"3",		CS_PIN		;r30_3 (P9.28)
	.asg		"r30",		PIN_OUT
	.asg		"r31", 		PIN_IN

 	.asg		"32",		PRU0_R31_VEC_VALID    ; allows notification of program completion
    	.asg		"1" ,		PRU_EVTOUT_0       ;he event number that is sent back
 	.asg		"r0",		CLOCK_STATE
	.asg		"r30.w0",	CALL_REG		;Call register for returning from instruction
	.asg		"r1",		DATA_SIZE		;Outgoing data size(from host) [bytes]
	.asg		"r2",		DATA_OUT 		;Outgoing data (from host)
 	.asg		"r3",		DATA_IN			;Incoming data (from slave)
	.asg		"r4", 		DATA_OUT_OFFSET	;Keep track of data loading from registers
	.asg		"r5",		DATA_IN_OFFSET	;Keep track of data loading to registers
  	.asg		"r6",		BIT_COUNTER	;Counts bits to decrement bytes
 	.asg		"r7",		SHARED_RAM_OFFSET	;Holds start address of PRU Shared RAM
	.asg		"r8",		CTRL_REG	;Holds signals from/to master
	.asg		"r9",		TEMP_CONST_REG	;Temporarily hold constants to MOV
	.asg		"r10",		TEST_REG

START:
        ; Enable the OCP master port -- allows transfer of data to Linux userspace
	LBCO    &r0, C4, 4, 4     ; load SYSCFG reg into r0 (use c4 const addr)
	CLR     r0, r0, 4        ; clear bit 4 (STANDBY_INIT)
	SBCO    &r0, C4, 4, 4     ; store the modified r0 back at the load addr
	
	LDI32 	DATA_OUT_OFFSET, 8			;Data to write starts at third register (first loaded manually)
	LBBO	&DATA_OUT, SHARED_RAM_OFFSET, 4, 4	;Loads first 4 bytes of data sent from host
	LDI32 	DATA_IN_OFFSET,  28			;Start-offset used to send read data to host
	LDI32	BIT_COUNTER, 31
	LDI32 	SHARED_RAM_OFFSET, 0x10000
	SET	PIN_OUT, PIN_OUT, CS_PIN
	QBA	WAIT_FOR_SIGNAL
WAIT_FOR_SIGNAL:
	LBBO	&CTRL_REG, SHARED_RAM_OFFSET, 0, 4	;Load signals from host
	QBBC	WAIT_FOR_SIGNAL, CTRL_REG, 0		;Repeat if LSB = 0
	CLR	CTRL_REG, CTRL_REG, 0				
	SBBO	&CTRL_REG, SHARED_RAM_OFFSET, 0, 4
	QBA	GET_DATA_SIZE
GET_DATA_SIZE:
	LBBO	&DATA_SIZE, SHARED_RAM_OFFSET, 4, 4 ;Aquire size of data to be transmitted
	QBA	WAIT_FOR_TRANSMISSION
WAIT_FOR_TRANSMISSION:
	JAL	CALL_REG, CHECK_CLOCK_LOW	;Check clock, r                                                                <---------------This JAL does not work
 	CLR 	PIN_OUT, PIN_OUT, CS_PIN				;Initiate communication
;Section responsible for sending/receiving data:
WRITE_BIT:
	LDI32	CTRL_REG, 3
	SBBO	&CTRL_REG, SHARED_RAM_OFFSET, 0, 4

	SUB	BIT_COUNTER, BIT_COUNTER, 1	;Decrement counter
	QBBC	WRITE_LOW, DATA_OUT, 31		;Check if bit 31 DATA_OUT is low
WRITE_HIGH:
	LDI32	CTRL_REG, 4
	SBBO	&CTRL_REG, SHARED_RAM_OFFSET, 0, 4

	SET	PIN_OUT, PIN_OUT, MOSI
	LSL	DATA_OUT, DATA_OUT, 1
	QBA	READ_BIT
WRITE_LOW:
	LDI32	CTRL_REG, 5
	SBBO	&CTRL_REG, SHARED_RAM_OFFSET, 0, 4

	CLR	PIN_OUT, PIN_OUT, MOSI
	LSL	DATA_OUT, DATA_OUT, 1
READ_BIT:
	LDI32	CTRL_REG, 6
	SBBO	&CTRL_REG, SHARED_RAM_OFFSET, 0, 4

	JAL	CALL_REG, CHECK_CLOCK_LOW
	QBBC	READ_LOW, PIN_IN, MISO
READ_LOW:
	LDI32	CTRL_REG, 7
	SBBO	&CTRL_REG, SHARED_RAM_OFFSET, 0, 4

	CLR	DATA_IN, DATA_IN, 1
	LSL	DATA_IN, DATA_IN, 1		
	QBNE	WRITE_BIT, BIT_COUNTER,0
	QBA	STORE_LOAD_DECREMENT
READ_HIGH:
	LDI32	CTRL_REG, 8
	SBBO	&CTRL_REG, SHARED_RAM_OFFSET, 0, 4

	SET	DATA_IN, DATA_IN, 1
	LSL	DATA_IN, DATA_IN, 1
	QBNE	WRITE_BIT, BIT_COUNTER, 0	
	QBA	STORE_LOAD_DECREMENT
;End of send/receive-section

STORE_LOAD_DECREMENT:
	LDI32	CTRL_REG, 9
	SBBO	&CTRL_REG, SHARED_RAM_OFFSET, 0, 4
;STORE:
	SBBO	&DATA_IN, SHARED_RAM_OFFSET, DATA_IN_OFFSET, 4
	ADD	DATA_IN_OFFSET, DATA_IN_OFFSET, 4	;Update counter for unused registers
;LOAD:
	LBBO	&DATA_OUT, SHARED_RAM_OFFSET, DATA_OUT_OFFSET, 4
	ADD	DATA_OUT_OFFSET, DATA_OUT_OFFSET, 4	;Update counter for unsent data
	
;DECREMENT:
	SUB	DATA_SIZE, DATA_SIZE, 4				;Decrement number of bytes
	LDI32	BIT_COUNTER, 31					;Reset bit counter
	QBNE	WRITE_BIT, DATA_SIZE, 0				;Keep sending bytes until all data sent
	LDI	r31.b0, PRU0_R31_VEC_VALID | PRU_EVTOUT_0	;Transmission done, alert host
	QBA	WAIT_FOR_SIGNAL					;Wait for new data
	
CHECK_CLOCK_LOW:
	;/////////TEST////////////
	;LDI32	CTRL_REG,10
	;SBBO	&CTRL_REG, SHARED_RAM_OFFSET, 0, 4
	;;;//END_TEST/////////////
	QBBS	CHECK_CLOCK_LOW, PIN_OUT, SPI_SCLK		
	JMP	CALL_REG	
CHECK_CLOCK_HIGH:
	LDI	CTRL_REG, 11
	SBBO	&CTRL_REG, SHARED_RAM_OFFSET, 0, 4

	QBBC	CHECK_CLOCK_HIGH, PIN_OUT,  SPI_SCLK
	JMP	CALL_REG	
END:
	LDI32	CTRL_REG, 190
	SBBO	&CTRL_REG, SHARED_RAM_OFFSET, 0, 4
	LDI	r31.b0, PRU0_R31_VEC_VALID | PRU_EVTOUT_0
	HALT								

/////////C-Code for uploading program to PRU and communicating with it:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include <prussdrv.h>
#include <pruss_intc_mapping.h>

#define ADC_PRU_NUM	   0   // using PRU0 for the ADC capture
#define CLK_PRU_NUM	   1   // using PRU1 for the sample clock
#define DATA_IN_OFFSET	  28

enum CONTROL {
	PAUSED = 0,
	RUNNING = 1,
	UPDATE = 3
};


int main (void)
{
	prussdrv_init();
   if(getuid()!=0){
      printf("You must run this program as root. Exiting.\n");
      exit(EXIT_FAILURE);
   }
	prussdrv_open(PRU_EVTOUT_0);
   // 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;
	prussdrv_pruintc_init(&pruss_intc_initdata);
   	volatile void *shared_memory_void = NULL;
	volatile uint32_t *shared_memory = NULL;
   	prussdrv_map_prumem(PRUSS0_SHARED_DATARAM, (void**) &shared_memory_void);
   	shared_memory = (uint32_t*) shared_memory_void;
   	uint32_t ctrl_Reg = 1;
   	uint32_t writeData[6];
   	writeData[0] = 61;
   	writeData[1] = 104;

for (int i = 0; i < 4; i++)
{
	writeData[i+2] = 0;
}
for (int i = 0; i < 6; i++)
{
	shared_memory[i+2] = writeData[i];
}
	shared_memory[0] = 1;
	shared_memory[1] = 200;	

   	//prussdrv_pru_write_memory(PRUSS0_SHARED_DATARAM, 0, ctrl_Reg, 4);
   	//prussdrv_pru_write_memory(PRUSS0_SHARED_DATARAM, 4, writeData, 24);

   	// Load and execute the PRU program on the PRU
	prussdrv_exec_program (ADC_PRU_NUM, "./test.obj");
	printf("PRU running, waiting for transmission... %d\n", shared_memory[0]);
	while(shared_memory[0] != 0)
	{
	}
	printf("PRU transmission started, shared_memory[0] = %d.\n", shared_memory[0]);
	uint32_t shared_memory_old = 0;
	//printf("change in value: %d\n", shared_memory[0]);
	while(shared_memory[0] != 190)
	{
		
		if (shared_memory[0] != shared_memory_old);
		{
		printf("%d\n", shared_memory[0]);
		shared_memory_old = shared_memory[0];
		}
		
	}
	printf("End of program");




	// Disable PRU and close memory mappings 
   	prussdrv_pru_disable(ADC_PRU_NUM);
   	prussdrv_pru_disable(CLK_PRU_NUM);

   	prussdrv_exit ();
   	return EXIT_SUCCESS; 
}