Beispiel #1
0
void communication_task(){
	int status;

	rsc_info.rsc_tab = (struct resource_table *)&resources;
	rsc_info.size = sizeof(resources);

	zynqMP_r5_gic_initialize();

	/* Initialize RPMSG framework */
	status = remoteproc_resource_init(&rsc_info, rpmsg_channel_created, rpmsg_channel_deleted,
			rpmsg_read_cb ,&proc);
	if (status < 0) {
		return;
	}

#ifdef USE_FREERTOS
	comm_queueset = xQueueCreateSet( 2 );
	xQueueAddToSet( OpenAMPInstPtr.send_queue, comm_queueset);
	xQueueAddToSet( OpenAMPInstPtr.lock, comm_queueset);
#else
	env_create_sync_lock(&OpenAMPInstPtr.lock,LOCKED);
#endif
	env_enable_interrupt(VRING1_IPI_INTR_VECT,0,0);
	while (1) {
#ifdef USE_FREERTOS
		QueueSetMemberHandle_t xActivatedMember;

		xActivatedMember = xQueueSelectFromSet( comm_queueset, portMAX_DELAY);
		if( xActivatedMember == OpenAMPInstPtr.lock ) {
			env_acquire_sync_lock(OpenAMPInstPtr.lock);
			process_communication(OpenAMPInstPtr);
		}
		if (xActivatedMember == OpenAMPInstPtr.send_queue) {
			xQueueReceive( OpenAMPInstPtr.send_queue, &send_data, 0 );
			rpmsg_send(app_rp_chnl, send_data.data, send_data.length);
		}
#else
		env_acquire_sync_lock(OpenAMPInstPtr.lock);
		process_communication(OpenAMPInstPtr);
		echo_test();
		/* Wait for the result data on queue */
		if(pq_qlength(OpenAMPInstPtr.send_queue) > 0) {
			send_data = pq_dequeue(OpenAMPInstPtr.send_queue);
			/* Send the result of echo_test back to master. */
			rpmsg_send(app_rp_chnl, send_data->data, send_data->length);
		}
#endif

	}
}
Beispiel #2
0
/*************************************************************************
 *
 *   FUNCTION
 *
 *       _open
 *
 *   DESCRIPTION
 *
 *       Open a file.  Minimal implementation
 *
 *************************************************************************/
int _open(const char * filename, int flags, int mode) {
	int filename_len = strlen(filename) + 1;
	int payload_size = sizeof(struct _sys_rpc) + filename_len;
	int retval = -1;

	if ((!filename) || (filename_len > FILE_NAME_LEN)) {
		return -1;
	}

	/* Construct rpc payload */
	rpc_data->rpc->id = OPEN_SYSCALL_ID;
	rpc_data->rpc->sys_call_args.int_field1 = flags;
	rpc_data->rpc->sys_call_args.int_field2 = mode;
	rpc_data->rpc->sys_call_args.data_len = filename_len;
	memcpy(&rpc_data->rpc->sys_call_args.data, filename, filename_len);

	/* Transmit rpc request */
	env_lock_mutex(rpc_data->rpc_lock);
	send_rpc((void*) rpc_data->rpc, payload_size);
	env_unlock_mutex(rpc_data->rpc_lock);

	/* Wait for response from proxy on master */
	env_acquire_sync_lock(rpc_data->sync_lock);

	/* Obtain return args and return to caller */
	if (rpc_data->rpc_response->id == OPEN_SYSCALL_ID) {
		retval = rpc_data->rpc_response->sys_call_args.int_field1;
	}

	return retval;
}
Beispiel #3
0
/*************************************************************************
 *
 *   FUNCTION
 *
 *       _write
 *
 *   DESCRIPTION
 *
 *       Low level function to redirect IO to serial.
 *
 *************************************************************************/
int _write(int fd, const char * ptr, int len) {
	int retval = -1;
	int payload_size = sizeof(struct _sys_rpc) + len;
	int null_term = 0;

	if (fd == 1) {
		null_term = 1;
	}

	rpc_data->rpc->id = WRITE_SYSCALL_ID;
	rpc_data->rpc->sys_call_args.int_field1 = fd;
	rpc_data->rpc->sys_call_args.int_field2 = len;
	rpc_data->rpc->sys_call_args.data_len = len + null_term;
	memcpy(rpc_data->rpc->sys_call_args.data, ptr, len);
	if (null_term) {
		*(char*) (rpc_data->rpc->sys_call_args.data + len + null_term) = 0;
	}

	env_lock_mutex(rpc_data->rpc_lock);
	send_rpc((void*) rpc_data->rpc, payload_size);
	env_unlock_mutex(rpc_data->rpc_lock);

	env_acquire_sync_lock(rpc_data->sync_lock);

	if (rpc_data->rpc_response->id == WRITE_SYSCALL_ID) {
		retval = rpc_data->rpc_response->sys_call_args.int_field1;
	}

	return retval;

}
Beispiel #4
0
/*************************************************************************
 *
 *   FUNCTION
 *
 *       _read
 *
 *   DESCRIPTION
 *
 *       Low level function to redirect IO to serial.
 *
 *************************************************************************/
int _read(int fd, char * buffer, int buflen) {
	int payload_size = sizeof(struct _sys_rpc);
	int retval = -1;

	if (!buffer || !buflen)
		return retval;

	/* Construct rpc payload */
	rpc_data->rpc->id = READ_SYSCALL_ID;
	rpc_data->rpc->sys_call_args.int_field1 = fd;
	rpc_data->rpc->sys_call_args.int_field2 = buflen;
	rpc_data->rpc->sys_call_args.data_len = 0; /*not used*/

	/* Transmit rpc request */
	env_lock_mutex(rpc_data->rpc_lock);
	get_response=0;
	send_rpc((void*) rpc_data->rpc, payload_size);
	env_unlock_mutex(rpc_data->rpc_lock);

	/* Wait for response from proxy on master */
	env_acquire_sync_lock(rpc_data->sync_lock);

	/* Obtain return args and return to caller */
	if (rpc_data->rpc_response->id == READ_SYSCALL_ID) {
		if (rpc_data->rpc_response->sys_call_args.int_field1 > 0) {
			memcpy(buffer, rpc_data->rpc_response->sys_call_args.data,
					rpc_data->rpc_response->sys_call_args.data_len);
		}

	    retval = rpc_data->rpc_response->sys_call_args.int_field1;
	}

	return retval;
}
Beispiel #5
0
/* wait for data and return data pointer when available */
void buffer_pull(void **data, int *len)
{
	/* empty ? then block-wait for notification of new data*/
	while (rb.head == rb.tail) env_acquire_sync_lock(rb.sync_lock);

	*data = (void *)&rb.buffer[sizeof(int)][rb.tail];
	*len  = *(int *)&rb.buffer[0][rb.tail];
	rb.tail = (rb.tail + 1) % RB_SZ;
}
Beispiel #6
0
/*************************************************************************
 *
 *   FUNCTION
 *
 *       _close
 *
 *   DESCRIPTION
 *
 *       Close a file.  Minimal implementation
 *
 *************************************************************************/
int _close(int fd) {
	int payload_size = sizeof(struct _sys_rpc);
	int retval = -1;

	rpc_data->rpc->id = CLOSE_SYSCALL_ID;
	rpc_data->rpc->sys_call_args.int_field1 = fd;
	rpc_data->rpc->sys_call_args.int_field2 = 0; /*not used*/
	rpc_data->rpc->sys_call_args.data_len = 0; /*not used*/

	env_lock_mutex(rpc_data->rpc_lock);
	send_rpc((void*) rpc_data->rpc, payload_size);
	env_unlock_mutex(rpc_data->rpc_lock);

	/* Wait for response from proxy on master */
	env_acquire_sync_lock(rpc_data->sync_lock);

	if (rpc_data->rpc_response->id == CLOSE_SYSCALL_ID) {
		retval = rpc_data->rpc_response->sys_call_args.int_field1;
	}

	return retval;
}
Beispiel #7
0
/*-----------------------------------------------------------------------------*
 *  Application specific
 *-----------------------------------------------------------------------------*/
static void rpc_demo(void)
{
	int fd, bytes_written, bytes_read;
	char fname[] = "remote.file";
	char wbuff[50];
	char rbuff[1024];
	char ubuff[50];
	float fdata;
	int idata;
	int ret;
	int status = 0;

	/* Initialize HW and SW components/objects */
	init_system();

	env_create_sync_lock(&chnl_cb_flag, LOCKED);

	/* Resource table needs to be provided to remoteproc_resource_init() */
	rsc_info.rsc_tab = (struct resource_table *)&resources;
	rsc_info.size = sizeof(resources);

	/* Initialize OpenAMP framework */
	status = remoteproc_resource_init(&rsc_info, rpmsg_channel_created,
                            rpmsg_channel_deleted, rpmsg_read_cb,
							&proc);
	if (RPROC_SUCCESS != status) {
		/* print error directly on serial port */
		xil_printf("Error: initializing OpenAMP framework\n");
        return;
	}

	/* wait for notification that will happen on channel creation (interrupt) */
	env_acquire_sync_lock(chnl_cb_flag);

	/* redirect I/Os */
	rpmsg_retarget_init(app_rp_chnl, shutdown_cb);

	printf("\r\nRemote>Baremetal Remote Procedure Call (RPC) Demonstration\r\n");
	printf("\r\nRemote>***************************************************\r\n");

	printf("\r\nRemote>Rpmsg based retargetting to proxy initialized..\r\n");

	/* Remote performing file IO on Master */
	printf("\r\nRemote>FileIO demo ..\r\n");

	printf("\r\nRemote>Creating a file on master and writing to it..\r\n");
	fd = open(fname, REDEF_O_CREAT | REDEF_O_WRONLY | REDEF_O_APPEND,
			S_IRUSR | S_IWUSR);
	printf("\r\nRemote>Opened file '%s' with fd = %d\r\n", fname, fd);

	sprintf(wbuff, "This is a test string being written to file..");
	bytes_written = write(fd, wbuff, strlen(wbuff));
	printf("\r\nRemote>Wrote to fd = %d, size = %d, content = %s\r\n", fd,
			bytes_written, wbuff);
	close(fd);
	printf("\r\nRemote>Closed fd = %d\r\n", fd);

	/* Remote performing file IO on Master */
	printf("\r\nRemote>Reading a file on master and displaying its contents..\r\n");
	fd = open(fname, REDEF_O_RDONLY, S_IRUSR | S_IWUSR);
	printf("\r\nRemote>Opened file '%s' with fd = %d\r\n", fname, fd);
	bytes_read = read(fd, rbuff, 1024);
	*(char*) (&rbuff[0] + bytes_read + 1) = 0;
	printf( "\r\nRemote>Read from fd = %d, size = %d, printing contents below .. %s\r\n",
			fd, bytes_read, rbuff);
	close(fd);
	printf("\r\nRemote>Closed fd = %d\r\n", fd);

	while (1) {
		/* Remote performing STDIO on Master */
		printf("\r\nRemote>Remote firmware using scanf and printf ..\r\n");
		printf("\r\nRemote>Scanning user input from master..\r\n");
		printf("\r\nRemote>Enter name\r\n");
		ret = scanf("%s", ubuff);
		if (ret) {
			printf("\r\nRemote>Enter age\r\n");
			ret = scanf("%d", &idata);
			if(ret) {
				printf("\r\nRemote>Enter value for pi\r\n");
				ret = scanf("%f", &fdata);
				if(ret) {
					printf("\r\nRemote>User name = '%s'\r\n", ubuff);
					printf("\r\nRemote>User age = '%d'\r\n", idata);
					printf("\r\nRemote>User entered value of pi = '%f'\r\n", fdata);
				}
			}
		}
		if(!ret) {
			scanf("%s", ubuff);
			printf("Remote> Invalid value. Starting again....");
		} else {
			printf("\r\nRemote>Repeat demo ? (enter yes or no) \r\n");
			scanf("%s", ubuff);
			if((strcmp(ubuff,"no")) && (strcmp(ubuff,"yes"))) {
				printf("\r\nRemote>Invalid option. Starting again....\r\n");
			} else if((!strcmp(ubuff,"no"))) {
				printf("\r\nRemote>RPC retargetting quitting ...\r\n");
				sprintf(wbuff, RPC_CHANNEL_READY_TO_CLOSE);
				rpmsg_retarget_send(wbuff, sizeof(RPC_CHANNEL_READY_TO_CLOSE) + 1);
				break;
			}
		}
	}
	printf("\r\nRemote> Firmware's rpmsg-openamp-demo-channel going down! \r\n");
}