cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Contributor
Contributor
924 Views
Registered: ‎03-13-2017

OpenAMP proxy test

Hello!
There is a peculiar function in the proxy_app code (from the application that runs on linux - as it says here):

int terminate_rpc_app()
{
	//int bytes_written;
	int msg = TERM_SYSCALL_ID;

	printf ("Master> sending shutdown signal.\n");
	return 0;
	//bytes_written = write(proxy->rpmsg_proxy_fd, &msg, sizeof(int));
	//return bytes_written;
}

The thing is, lines were commented before i got there. But that message is sent to the remote processor nonetheless!
So, in attempt to find out what triggers the transmission to the remote, i removed signaling infrastructure in the beginning  of the main function (just in case), commented out all function calls from the end of the main function and added sleep:

int main(int argc, char *argv[])
{
    struct sigaction exit_action;
    struct sigaction kill_action;
    unsigned int bytes_rcvd;
    int i = 0;
    int opt = 0;
    int ret = 0;
    char *user_fw_path = 0;

    /* Initialize signalling infrastructure */
    //memset(&exit_action, 0, sizeof(struct sigaction));
    //memset(&kill_action, 0, sizeof(struct sigaction));
    //exit_action.sa_handler = exit_action_handler;
    //kill_action.sa_handler = kill_action_handler;
    //sigaction(SIGTERM, &exit_action, NULL);
    //sigaction(SIGINT, &exit_action, NULL);
    //sigaction(SIGKILL, &kill_action, NULL);
    //sigaction(SIGHUP, &kill_action, NULL);

    while ((opt = getopt(argc, argv, "vhf:r:")) != -1) {
        switch (opt) {
        case 'f':
            user_fw_path = optarg;
            break;
        case 'r':
            r5_id = atoi(optarg);
            if (r5_id != 0 && r5_id != 1) {
                display_help_msg();
                return -1;
            }
            break;
        case 'v':
            printf("\r\nLinux proxy application version 1.1\r\n");
            return 0;
        case 'h':
            display_help_msg();
            return 0;
        default:
            printf("getopt return unsupported option: -%c\n",opt);
            break;
        }
    }

    /* Bring up remote firmware */
    printf("\r\nMaster>Loading remote firmware\r\n");
    if (user_fw_path) {
        sprintf(sbuf, "cp %s %s", user_fw_path, fw_dst_path);
        system(sbuf);
    }

    /* Write firmware name to remoteproc sysfs interface */
    sprintf(sbuf,
        "/sys/class/remoteproc/remoteproc%u/firmware",
        r5_id);
    if (0 != file_write(sbuf, "image_rpc_demo")) {
        return -1;
    }

    /* Tell remoteproc to load and start remote cpu */
    sprintf(sbuf,
        "/sys/class/remoteproc/remoteproc%u/state",
        r5_id);
    if (0 != file_write(sbuf, "start")) {
        return -1;
    }

    /* Create rpmsg proxy device */
    printf("\r\nMaster>Create rpmsg proxy device\r\n");
    system("modprobe rpmsg_proxy_dev_driver");

    /* Allocate memory for proxy data structure */
    proxy = malloc(sizeof(struct _proxy_data));
    if (proxy == 0) {
        printf("\r\nMaster>Failed to allocate memory.\r\n");
        return -1;
    }
    proxy->active = 1;

    /* Open proxy rpmsg device */
    printf("\r\nMaster>Opening rpmsg proxy device\r\n");
    i = 0;
    do {
        proxy->rpmsg_proxy_fd = open("/dev/rpmsg_proxy0", O_RDWR);
        sleep(1);
    } while (proxy->rpmsg_proxy_fd < 0 && (i++ < 2));

    if (proxy->rpmsg_proxy_fd < 0) {
        printf("\r\nMaster>Failed to open rpmsg proxy driver device file.\r\n");
        ret = -1;
        goto error0;
    }

    /* Allocate memory for rpc payloads */
    proxy->rpc = malloc(RPC_BUFF_SIZE);
    proxy->rpc_response = malloc(RPC_BUFF_SIZE);

    /* RPC service starts */
    printf("\r\nMaster>RPC service started !!\r\n");
    while (proxy->active) {
        /* Block on read for rpc requests from remote context */
        do {
            bytes_rcvd = read(proxy->rpmsg_proxy_fd, proxy->rpc,
                    RPC_BUFF_SIZE);
            if (!proxy->active)
                break;
        } while(bytes_rcvd <= 0);

        /* User event, break! */
        if (!proxy->active)
            break;

        /* Handle rpc */
        if (handle_rpc(proxy->rpc)) {
            printf("\r\nMaster>Err:Handling remote procedure");
            printf(" call!\r\n");
            printf("\r\nrpc id %d\r\n", proxy->rpc->id);
            printf("\r\nrpc int field1 %d\r\n",
                proxy->rpc->sys_call_args.int_field1);
            printf("\r\nrpc int field2 %d\r\n",
                proxy->rpc->sys_call_args.int_field2);
            break;
        }
    }
    sleep(10);
    printf("\r\nMaster>RPC service exiting !!\r\n");

    /* Send shutdown signal to remote application */
    //terminate_rpc_app();
    /* Close proxy rpmsg device */
    //close(proxy->rpmsg_proxy_fd);

    /* Free up resources */
    //free(proxy->rpc);
    //free(proxy->rpc_response);

error0:
    //free(proxy);

    //stop_remote();

    return ret;
}

So what happens now is: when master receives  RPC_CHANNEL_READY_TO_CLOSE message, handle_rpc sets proxy->active to false, causing break from cycle, then 10 seconds later (when master ought to have finished app execution) remote receives a message (on different rpc endpoint this time, calling not rpc_cb(), defined in rpmsg_retarget.c, but  rpmsg_read_cb(), defined in rpc.demo.c) and suspends processor execution.
But there is no (evident) sending in master code! Am i overlooking something obvious?

 

source code was found in $PETALINUX_FOLDER/17.1/components/yocto/source/arm/layers/meta-openamp/recipes-openamp/rpmsg-examples/rpmsg-proxy-app

0 Kudos