static void mat_mul_demo(void) { while (1) { void *data; int len; /* wait for data... */ buffer_pull(&data, &len); /* Process incoming message/data */ if (*(int *)data == SHUTDOWN_MSG) { /* disable interrupts and free resources */ remoteproc_resource_deinit(proc); break; } else { env_memcpy(matrix_array, data, len); /* Process received data and multiple matrices. */ Matrix_Multiply(&matrix_array[0], &matrix_array[1], &matrix_result); /* Send result back */ if (RPMSG_SUCCESS != rpmsg_send(app_rp_chnl, &matrix_result, sizeof(matrix))) { xil_printf("Error: rpmsg_send failed\n"); } } } }
static void rpmsg_read_cb(struct rpmsg_channel *rp_chnl, void *data, int len, void * priv, unsigned long src) { if ((*(int *) data) == SHUTDOWN_MSG) { remoteproc_resource_deinit(proc); } else { /* Send data back to master*/ rpmsg_send(rp_chnl, data, len); } }
static void mat_mul_demo(void *unused_arg) { int status = 0; (void)unused_arg; /* Create buffer to send data between RPMSG callback and processing task */ buffer_create(); /* Initialize HW and SW components/objects */ init_system(); /* 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) { xil_printf("Error: initializing OpenAMP framework\n"); return; } /* Stay in data processing loop until we receive a 'shutdown' message */ while (1) { void *data; int len; /* wait for data... */ buffer_pull(&data, &len); /* Process incoming message/data */ if (*(int *)data == SHUTDOWN_MSG) { /* disable interrupts and free resources */ remoteproc_resource_deinit(proc); /* Terminate this task */ vTaskDelete(NULL); break; } else { env_memcpy(matrix_array, data, len); /* Process received data and multiple matrices. */ Matrix_Multiply(&matrix_array[0], &matrix_array[1], &matrix_result); /* Send result back */ if (RPMSG_SUCCESS != rpmsg_send(app_rp_chnl, &matrix_result, sizeof(matrix))) { xil_printf("Error: rpmsg_send failed\n"); } } } }
/** * remoteproc_resource_init * * Initializes resources for remoteproc remote configuration. Only * remoteproc remote applications are allowed to call this function. * * @param rsc_info - pointer to resource table info control * block * @param channel_created - callback function for channel creation * @param channel_destroyed - callback function for channel deletion * @param default_cb - default callback for channel I/O * @param rproc_handle - pointer to new remoteproc instance * * @param returns - status of function execution * */ int remoteproc_resource_init(struct rsc_table_info *rsc_info, rpmsg_chnl_cb_t channel_created, rpmsg_chnl_cb_t channel_destroyed, rpmsg_rx_cb_t default_cb, struct remote_proc** rproc_handle) { struct remote_proc *rproc; int status; if(!rsc_info) { return RPROC_ERR_PARAM; } /* Initialize environment component */ status = env_init(); if (status != RPROC_SUCCESS) { return status; } rproc = env_allocate_memory(sizeof(struct remote_proc)); if (rproc) { env_memset(rproc, 0x00, sizeof(struct remote_proc)); /* There can be only one master for remote configuration so use the * rsvd cpu id for creating hil proc */ rproc->proc = hil_create_proc(HIL_RSVD_CPU_ID); if (rproc->proc) { /* Parse resource table */ status = handle_rsc_table(rproc, rsc_info->rsc_tab, rsc_info->size); if (status == RPROC_SUCCESS) { /* Initialize RPMSG "messaging" component */ *rproc_handle = rproc; status = rpmsg_init(rproc->proc->cpu_id, &rproc->rdev, channel_created, channel_destroyed, default_cb, RPMSG_MASTER); } else { status = RPROC_ERR_NO_RSC_TABLE; } } else { status = RPROC_ERR_CPU_ID; } } else { status = RPROC_ERR_NO_MEM; } /* Cleanup in case of error */ if (status != RPROC_SUCCESS) { *rproc_handle = 0; (void) remoteproc_resource_deinit(rproc); return status; } return status; }
static void rpmsg_read_cb(struct rpmsg_channel *rp_chnl, void *data, int len, void *priv, unsigned long src) { if ((*(int *)data) == SHUTDOWN_MSG) { remoteproc_resource_deinit(proc); } else { env_memcpy(matrix_array, data, len); /* Process received data and multiple matrices. */ Matrix_Multiply(&matrix_array[0], &matrix_array[1], &matrix_result); /* Send the result of matrix multiplication back to master. */ rpmsg_send(app_rp_chnl, &matrix_result, sizeof(matrix)); } }
static void rpmsg_read_cb(struct rpmsg_channel *rp_chnl, void *data, int len, void * priv, unsigned long src) { if ((*(int *) data) == SHUTDOWN_MSG) { remoteproc_resource_deinit(proc); #ifdef USE_FREERTOS int TempTimerId; stop_scheduler = xTimerCreate("TMR", DELAY_200MSEC, pdFALSE, (void *)&TempTimerId, StopSchedulerTmrCallBack); xTimerStart(stop_scheduler, 0); #endif }else{ recv_mat_data.data = data; recv_mat_data.length = len; #ifdef USE_FREERTOS xQueueSend(mat_mul_queue , &recv_mat_data, portMAX_DELAY ); #else pq_enqueue(mat_mul_queue, &recv_mat_data); #endif } }
static void shutdown_cb(struct rpmsg_channel *rp_chnl) { rpmsg_retarget_deinit(rp_chnl); remoteproc_resource_deinit(proc); }
int main() { struct remote_proc *proc; int uninit = 0; struct ept_cmd_data *ept_data; #ifdef ZYNQ7_BAREMETAL /* Switch to System Mode */ SWITCH_TO_SYS_MODE(); #endif /* Initialize HW system components */ init_system(); rsc_info.rsc_tab = (struct resource_table *)&resources; rsc_info.size = sizeof(resources); /* This API creates the virtio devices for this remote node and initializes other relevant resources defined in the resource table */ remoteproc_resource_init(&rsc_info, rpmsg_channel_created, rpmsg_channel_deleted, rpmsg_read_default_cb, &proc); for (;;) { if (intr_flag) { struct command *cmd = (struct command *)r_buffer; if (cmd->comm_start == CMD_START) { unsigned int cm_code = cmd->comm_code; void *data = cmd->data; switch (cm_code) { case CREATE_EPT: ept_data = (struct ept_cmd_data *)data; rp_ept = rpmsg_create_ept(app_rp_chnl, rpmsg_read_ept_cb, RPMSG_NULL, ept_data->dst); if (rp_ept) { /* Send data back to ack. */ rpmsg_sendto(app_rp_chnl, r_buffer, Len, Src); } break; case DELETE_EPT: rpmsg_destroy_ept(rp_ept); rpmsg_sendto(app_rp_chnl, r_buffer, Len, Src); break; case CREATE_CHNL: break; case DELETE_CHNL: rpmsg_sendto(app_rp_chnl, r_buffer, Len, Src); remoteproc_resource_deinit(proc); uninit = 1; break; case QUERY_FW_NAME: rpmsg_send(app_rp_chnl, &firmware_name[0], strlen(firmware_name) + 1); break; default: rpmsg_sendto(app_rp_chnl, r_buffer, Len, Src); break; } } else { rpmsg_sendto(app_rp_chnl, r_buffer, Len, Src); } intr_flag = 0; if (uninit) break; } sleep(); } return 0; }