UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

OpenAMP: fail to create channel when enable private timer in the bare-metal application

Reply
Highlighted
Newbie
Posts: 1
Registered: ‎05-07-2017

OpenAMP: fail to create channel when enable private timer in the bare-metal application

Hi, I am modifying Xilinx provided OpenAMP example to build my own application. Everything works fine until I add a Timer interrupt to the bare-metal application. I use the "matrix-multiplication" example.

 

int main(void)
{
	unsigned long proc_id = 0;
	unsigned long rsc_id = 0;
	struct hil_proc *hproc;
	int status = -1;
	XScuTimer Timer;
	XScuTimer_Config *ConfigPtr;

	LPRINTF("Starting application...\r\n");

	/* Initialize HW system components */
	init_system();

	//PWM initialization
	//enable PWM output
	PWM_mWriteReg (baseaddr_p, 0, 1);
	PWM_mWriteReg (baseaddr_p, 8, 100);	    //set PWM period

	//init timer
	int Status;

	ConfigPtr = XScuTimer_LookupConfig(TIMER_DEVICE_ID);
	Status = XScuTimer_CfgInitialize(&Timer, ConfigPtr,
					ConfigPtr->BaseAddr);
	if (Status != XST_SUCCESS) {return XST_FAILURE;	}

	//Status = XScuTimer_SelfTest(&Timer);
	//if (Status != XST_SUCCESS) {return XST_FAILURE;}

	//LPRINTF("Self-test finish ok...\r\n");

	XScuTimer_EnableAutoReload(&Timer);
	XScuTimer_LoadTimer(&Timer, (u32)TIMER_LOAD_VALUE);

	XScuGic_Config *IntcConfig;
	IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
	Status = XScuGic_CfgInitialize(&IntcInstance, IntcConfig,
					IntcConfig->CpuBaseAddress);

	if (Status != XST_SUCCESS) {return XST_FAILURE;}

	Xil_ExceptionInit();
	Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_IRQ_INT,
				(Xil_ExceptionHandler)XScuGic_InterruptHandler,
				&IntcInstance);

	Status = XScuGic_Connect(&IntcInstance, (u16)TIMER_IRPT_INTR,
				(Xil_ExceptionHandler)TimerIntrHandler,
				&Timer);

	XScuGic_Enable(&IntcInstance, (u16)TIMER_IRPT_INTR);
	XScuTimer_EnableInterrupt(&Timer);
	Xil_ExceptionEnable();


	XScuTimer_Start(&Timer);

	LPRINTF("Timer init done!! \r\n");


	/* Create HIL proc */
	hproc = platform_create_proc(proc_id);
	if (!hproc) {
		LPERROR("Failed to create hil proc.\n");
	} else {
		rsc_info.rsc_tab = get_resource_table((int)rsc_id, &rsc_info.size);
		if (!rsc_info.rsc_tab) {
			LPERROR("Failed to get resource table data.\n");
		} else {
			status = app(hproc);
		}
	}

	LPRINTF("Stopping application...\r\n");

	TimerDisableIntrSystem(&IntcInstance, (u16)TIMER_IRPT_INTR);

	cleanup_system();

	/* Suspend processor execution */
	while (1) {
		__asm__("wfi\n\t");
	}

	return status;
}

When I try to load this application, the output is:

root@XReal:~/work# ./load_dr_firmware.sh
CPU1: shutdown
 remoteproc0: 0.remoteproc is available
 remoteproc0: Note: remoteproc is still under development and considered experimental.
 remoteproc0: THE BINARY FORMAT IS NOT YET FINALIZED, and backward compatibility isn't yet guaranteed.
root@XReal:~/work#  remoteproc0: powering up 0.remoteproc
 remoteproc0: Booting fw image cpu1_baremetal_app_matrix.elf, size 792456
 remoteproc0: remote processor 0.remoteproc is now up
virtio_rpmsg_bus virtio0: rpmsg host is online
 remoteproc0: registered virtio0 (type 7)

nothing else follows. But the Timer interrupt works fine, the remote application works, only the communication between host linux and remote can not established. 

 

when I try to run linux application:

root@XReal:~/work# /bin/cpu0_linux_app_matrix.elf

 VIVO TEST START

 Open rpmsg dev!
Failed to open rpmsg file /dev/rpmsg0.: No such file or directory

 

when I comment out the interrupt initializer, and the Timer interrupt related code

Status = XScuGic_CfgInitialize(&IntcInstance, IntcConfig,
				IntcConfig->CpuBaseAddress);

the communication framework works fine:

 

root@XReal:~/work# ./load_dr_firmware.sh
CPU1: shutdown
 remoteproc0: 0.remoteproc is available
 remoteproc0: Note: remoteproc is still under development and considered experimental.
 remoteproc0: THE BINARY FORMAT IS NOT YET FINALIZED, and backward compatibility isn't yet guaranteed.
root@XReal:~/work#  remoteproc0: powering up 0.remoteproc
 remoteproc0: Booting fw image cpu1_baremetal_app_matrix.elf, size 792484
 remoteproc0: remote processor 0.remoteproc is now up
virtio_rpmsg_bus virtio0: rpmsg host is online
 remoteproc0: registered virtio0 (type 7)
virtio_rpmsg_bus virtio0: creating channel rpmsg-openamp-demo-channel addr 0x1
rpmsg_proxy_dev_rpmsg rpmsg0: rpmsg_user_dev_rpmsg_drv_probe
rpmsg_proxy_dev_rpmsg rpmsg0: Sent init_msg to target 0x0.
rpmsg_proxy_dev_rpmsg rpmsg0: new channel: 0x400 -> 0x1!

I use the following script to load firmware and start remote application

root@XReal:~/work# cat load_dr_firmware.sh
modprobe zynq_remoteproc firmware=cpu1_baremetal_app_matrix.elf
modprobe rpmsg_user_dev_driver

What should I do if I want both the openAMP and the Timer interrupt work. How does the "rpmsg_read_cb" interrupt works? Do those two interrupt conflicts?

 

 

Thank you.

 

 

Adventurer
Posts: 92
Registered: ‎02-22-2012

Re: OpenAMP: fail to create channel when enable private timer in the bare-metal application

I think you have hit "OpenAMP "chicken or egg" problem" that I have described time ago here  and is still present in Open AMP framework. Same problem was also described in forum and solved here.

 

The key point is that modified (additional) BM FW startup code "delays" the CPU1 (BM) RPMSG initialization so that it is done after CPU0 (LX) already did virtio_rpmsg_bus first notification kick. That is too late. In my form message is also description how I workaround the problem ("send kicking SGI from CPU1 to CPU0").

 

p.s.

Sometimes its helpful to search the forum for problems/solutions.