]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - processor-sdk/open-amp.git/blob - apps/tests/master/nucleus/func_test_suite/nucleus_linux/func_test_suite.c
Moving OpenAMP sources to GIT repo.
[processor-sdk/open-amp.git] / apps / tests / master / nucleus / func_test_suite / nucleus_linux / func_test_suite.c
1 /* Including required headers */
2 #include  <stdio.h>
3 #include <string.h>
4 #include <stdlib.h>
5 #include "open_amp.h"
6 #include "test_suite.h"
7 #include "nucleus.h"
8 #include "kernel/nu_kernel.h"
11 /* Prototypes */
12 static void Main_Task_Entry( UNSIGNED argc , VOID *argv );
14 /* Application provided callbacks */
15 void rpmsg_channel_created( struct rpmsg_channel *rp_chnl );
16 void rpmsg_channel_deleted( struct rpmsg_channel *rp_chnl );
17 void rpmsg_read_default_cb( struct rpmsg_channel *rp_chnl , void *data , int len , void * pric ,
18                 unsigned long src );
19 void rpmsg_read_ept1_cb( struct rpmsg_channel *rp_chnl , void *data , int len , void * pric ,
20                 unsigned long src );
21 void rpmsg_read_ept2_cb( struct rpmsg_channel *rp_chnl , void *data , int len , void * pric ,
22                 unsigned long src );
24 int test_rpmsg_send(struct rpmsg_channel *rpmsg_chnl);
25 int test_rpmsg_send_offchannel(struct rpmsg_channel *rpmsg_chnl, unsigned long src, unsigned long dst);
27 int test_rpmsg_create_ept(struct rpmsg_channel *rpmsg_chnl);
29 int test_remoteproc_multiple_lifecycles(char * firmware_name);
31 int test_rpmsg_send_offchannel_impl(struct rpmsg_channel *rpmsg_chnl, unsigned long src, unsigned long dst);
33 int test_rpmsg_send_impl(struct rpmsg_channel *rpmsg_chnl);
35 int test_rpmsg_remote_channel_deletion(struct rpmsg_channel *rpmsg_chnl, char *channel_name);
37 int test_execute_suite(char * firmware_name);
40 /* Globals */
41 NU_TASK Task_Control_Block;
42 NU_SEMAPHORE App_Sem, Remote_Del_Sem;
43 struct rpmsg_endpoint *rp_ept1 , *rp_ept2;
44 struct rpmsg_channel *app_rp_chnl;
45 char fw_name1[] = "firmware1";
47 struct _payload* p_payload = NULL;
48 struct _payload* r_payload = NULL;
49 /***********************************************************************
50  * *
51  * *   FUNCTION
52  * *
53  * *       Application_Initialize
54  * *
55  * *   DESCRIPTION
56  * *
57  * *       Demo application entry point
58  *
59  * ***********************************************************************/
60 VOID Application_Initialize(
61                 NU_MEMORY_POOL* mem_pool , NU_MEMORY_POOL* uncached_mem_pool )
62 {
63     VOID *pointer;
64     STATUS status = NU_SUCCESS;
66     /* Reference unused parameters to avoid toolset warnings */
67     NU_UNUSED_PARAM( uncached_mem_pool );
69     if ( status == NU_SUCCESS )
70     {
71         status = NU_Allocate_Memory(mem_pool, &pointer, STACK_SIZE, NU_NO_SUSPEND);
73         /* Create the main task for matrix processing */
74         if ( status == NU_SUCCESS )
75         {
76             status = NU_Create_Task( &Task_Control_Block , "MAIN" , Main_Task_Entry , 0 ,
77                             uncached_mem_pool , pointer , STACK_SIZE , TASK_PRIORITY , TASK_SLICE ,
78                             NU_PREEMPT , NU_START );
79         }
80         if ( status == NU_SUCCESS )
81         {
82             status = NU_Create_Semaphore( &App_Sem , "APP_SEM" , 0 , NU_FIFO );
83         }
85         if ( status == NU_SUCCESS )
86         {
87             status = NU_Create_Semaphore( &Remote_Del_Sem , "Del_SEM" , 0 , NU_FIFO );
88         }
90         NU_Allocate_Memory(uncached_mem_pool , (VOID **)&r_payload, 512 , NU_SUSPEND);
91     }
93     /* Check to see if previous operations were successful */
94     if ( status != NU_SUCCESS )
95     {
96         /* Loop forever */
97         while ( 1 );
98     }
99 }
101 /***********************************************************************
102  * *
103  * *   FUNCTION
104  * *
105  * *       Main_Task_Entry
106  * *
107  * *   DESCRIPTION
108  * *
109  * *       Entry function for the main task. This task prints a hello world
110  * *       message.
111  * *
112  * ***********************************************************************/
113 static VOID Main_Task_Entry( UNSIGNED argc , VOID *argv )
115     printf("\n\n\r************************************");
116     printf("*******************************************\r\n");
117     printf("\r\n              OpenAMP Test Suite \r\n");
118     printf("\r\n");
119     printf("\r\nThis test suite will execute multiple test cases for rpmsg and rempteproc \r\n");
120     printf("\r\nAPIs available within OpenAMP \r\n");
122     printf("\r\n******************************************");
123     printf("*************************************\n\r\n");
125     test_execute_suite(fw_name1);
128 /* This callback gets invoked when the remote chanl is created */
129 void rpmsg_channel_created( struct rpmsg_channel *rp_chnl )
131     app_rp_chnl = rp_chnl;
133     rp_ept1 = rpmsg_create_ept(rp_chnl , rpmsg_read_ept1_cb , RPMSG_NULL , RPMSG_ADDR_ANY);
136 /* This callback gets invoked when the remote channel is deleted */
137 void rpmsg_channel_deleted( struct rpmsg_channel *rp_chnl )
139     rpmsg_destroy_ept( rp_ept1 );
141     NU_Release_Semaphore( &Remote_Del_Sem );
145 /* This is the read callback, note we are in a task context when this callback
146  is invoked, so kernel primitives can be used freely */
147 void rpmsg_read_default_cb( struct rpmsg_channel *rp_chnl , void *data , int len , void * priv ,
148                 unsigned long src )
150     memcpy( r_payload , data , len );
151     NU_Release_Semaphore( &App_Sem );
154 void rpmsg_read_ept1_cb( struct rpmsg_channel *rp_chnl , void *data , int len , void * priv ,
155                 unsigned long src )
157     memcpy( r_payload , data , len );
158     NU_Release_Semaphore( &App_Sem );
161 void rpmsg_read_ept2_cb( struct rpmsg_channel *rp_chnl , void *data , int len , void * priv ,
162                 unsigned long src )
164     memcpy( r_payload , data , len );
165     NU_Release_Semaphore( &App_Sem );
168 void send_test_case_report(char *result_string)
170     struct command* cmd;
171     NU_MEMORY_POOL     *sys_pool_ptr;
172     int status;
174     NU_System_Memory_Get(NU_NULL, &sys_pool_ptr);
175     
176     status = NU_Allocate_Memory(sys_pool_ptr , (void **)&(cmd), sizeof(struct command) + strlen(result_string) + 1, NU_SUSPEND);
177     
178     if(status == NU_SUCCESS)
179     {
180         cmd->comm_start=CMD_START;
181         cmd->comm_code = PRINT_RESULT;
182         
183         strcpy(cmd->data, result_string);
184             
185         status = rpmsg_send(app_rp_chnl, cmd, sizeof(struct command) + strlen(result_string) + 1);
186         
187         NU_Deallocate_Memory(cmd);
188         
189         /* Wait to receive echo*/
190         NU_Obtain_Semaphore( &App_Sem , NU_SUSPEND );
191     }
194 int test_execute_suite(char * firmware_name)
196     struct remote_proc *proc;
197     int status;
198     char default_channel[] = "rpmsg-openamp-demo-channel";
199     struct command* cmd;
200     NU_MEMORY_POOL     *sys_pool_ptr;
202     printf("\n\n\r************************************");
203     printf("*******************************************\r\n");
204     printf( "\r\nBoot remote context : %s \r\n" , firmware_name );
205     printf("\r\n******************************************");
206     printf("*************************************\n\r\n");
208     status = remoteproc_init( (void *) firmware_name ,rpmsg_channel_created, rpmsg_channel_deleted, rpmsg_read_default_cb, &proc);
210     if (status)
211     {
212         printf( "\r\n CRITICAL ERROR: remoteproc_init call for remote context %s failed \r\n", firmware_name);
214         return -1;
215     }
217     status = remoteproc_boot( proc );
219     if (status)
220     {
221         printf( "\r\n CRITICAL ERROR: remoteproc_boot call for remote context %s failed \r\n", firmware_name);
223         return -1;
224     }
226     /* Wait for channel creation event */
227     NU_Obtain_Semaphore( &App_Sem , NU_SUSPEND );
228     
229     /* Obtain remote firmware name */
230     NU_System_Memory_Get(NU_NULL, &sys_pool_ptr);
231     status = NU_Allocate_Memory(sys_pool_ptr , (void **)&(cmd), sizeof(struct command), NU_SUSPEND);
232     cmd->comm_start=CMD_START;
233     cmd->comm_code = QUERY_FW_NAME;
234     status = rpmsg_send(app_rp_chnl, cmd, sizeof(struct command));
235     NU_Deallocate_Memory(cmd);
236     
237     /* Wait to receive firmware name */
238     NU_Obtain_Semaphore( &App_Sem , NU_SUSPEND );
239     
240     /* Test rpmsg_send API */
241     status = test_rpmsg_send(app_rp_chnl);
243     if(!status)
244     {
245         send_test_case_report("\r\nRPMSG Send Test: Passed\r\n");
246     }
247     else
248     {
249         send_test_case_report("\r\nRPMSG Send Test: Failed\r\n");
250     }
252     /* Test rpmsg_send_offchannel API. */
253     status = test_rpmsg_send_offchannel(app_rp_chnl, rp_ept1->addr, app_rp_chnl->dst);
255     if(!status)
256     {
257         send_test_case_report("\r\nRPMSG Send Offchannel Test: Passed\r\n");
258     }
259     else
260     {
261         send_test_case_report("\r\nRPMSG Send Offchannel: Failed\r\n");
262     }
264     status = test_rpmsg_create_ept(app_rp_chnl);
266     if(!status)
267     {
268         send_test_case_report("\r\nRPMSG Create EPT Test: Passed\r\n");
269     }
270     else
271     {
272         send_test_case_report("\r\nRPMSG Create EPT Test: Failed\r\n");
273     }
274     
275     send_test_case_report("\r\nChannel Deletion. Shutdown would be next\r\n");
276     
277     status = test_rpmsg_remote_channel_deletion(app_rp_chnl, default_channel);
279     NU_Sleep(100 * 18);
280     
281     status = remoteproc_shutdown(proc);
282     if(!status)
283     {
284         status = remoteproc_deinit(proc);
285     }
287     /* The multiple life-cycles test has been disabled for remote Linux configuration
288        as it would require manual user input at linux console to complete 
289        the rpmsg connection and would be cumbersome for the user. The multiple
290        lifecycles have been tested seperately. */
291     
292     
293     /*if(!status)
294     {
295         status = test_remoteproc_multiple_lifecycles(firmware_name);
296     }*/
298     return status;
301 int test_remoteproc_multiple_lifecycles(char * firmware_name)
303     int i, status;
304     struct remote_proc *proc;
306     for(i = 0; i < 2; i++)
307     {
308         status = remoteproc_init( (void *) firmware_name ,rpmsg_channel_created, rpmsg_channel_deleted, rpmsg_read_default_cb, &proc);
310         if (status)
311         {
312             break;
313         }
314         
315         status = remoteproc_boot( proc );
317         if (status)
318         {
319             break;
320         }
322         /* Wait for channel creation event */
323         status = NU_Obtain_Semaphore( &App_Sem , NU_SUSPEND );
325         if (!status)
326         {
327             status = test_rpmsg_send_impl(app_rp_chnl);
328         }
330         if(!status){
331             test_rpmsg_remote_channel_deletion(app_rp_chnl , app_rp_chnl->name);
332         }
333         
334         NU_Sleep(100 * 18);
335             
336         if (!status)
337         {
338             status = remoteproc_shutdown(proc);
339         }
340         if (status)
341         {
342             break;
343         }
344         status = remoteproc_deinit(proc);
346         if (status)
347         {
348             break;
349         }
351     }
353     return status;
356 int test_rpmsg_remote_channel_deletion(struct rpmsg_channel *rpmsg_chnl, char *channel_name)
358     struct command *cmd;
359     int status;
360     NU_MEMORY_POOL     *sys_pool_ptr;
361     struct chnl_cmd_data *chnl_data;
363     NU_System_Memory_Get(NU_NULL, &sys_pool_ptr);
365     status = NU_Allocate_Memory(sys_pool_ptr ,
366                                 (void **)&(cmd), sizeof(struct command)+ sizeof(struct chnl_cmd_data), NU_SUSPEND);
368     cmd->comm_code = DELETE_CHNL;
369     cmd->comm_start = CMD_START;
371     chnl_data = (struct chnl_cmd_data *)cmd->data;
373     strncpy(chnl_data->name , channel_name, sizeof(struct chnl_cmd_data));
375     /* Let the other side that uninit its resources */
376     status = rpmsg_send( rpmsg_chnl , cmd , sizeof(struct command) + sizeof(struct chnl_cmd_data) );
377     if(status)
378     {
379         return status;
380     }
381     /* Wait for echo back */
382     status = NU_Obtain_Semaphore( &App_Sem , NU_SUSPEND);
384     return status;
387 int test_rpmsg_create_ept(struct rpmsg_channel *rpmsg_chnl)
389     struct command *cmd;
390     int status, i;
391     struct ept_cmd_data *ept_data;
392     NU_MEMORY_POOL     *sys_pool_ptr;
393     struct rpmsg_endpoint *test_ept[NUM_TEST_EPS];
395     NU_System_Memory_Get(NU_NULL, &sys_pool_ptr);
397     status = NU_Allocate_Memory(sys_pool_ptr ,
398                                 (void **)&(cmd), sizeof(struct command) + sizeof(struct ept_cmd_data), NU_SUSPEND);
400     if(status != NU_SUCCESS)
401     {
402         return status;
403     }
405     for(i = 0; i < NUM_TEST_EPS; i++)
406     {
407         /* Tell the remote to create a new endpoint. */
408         cmd->comm_code = CREATE_EPT;
409         cmd->comm_start = CMD_START;
411         /* Send create endpoint command to remote */
412         ept_data = (struct ept_cmd_data *)cmd->data;
413         ept_data->dst= EPT_TEST_ADDR + i;
414         ept_data->src= EPT_TEST_ADDR + i;
416         /* Let the other side know that it needs to create endpoint with the given address */
417         status = rpmsg_send(rpmsg_chnl, cmd, sizeof(struct command) + sizeof(struct ept_cmd_data));
419         if(!status)
420         {
421             /* Wait for ack */
422             status = NU_Obtain_Semaphore(&App_Sem , NU_SUSPEND);
423         }
425         if(!status)
426         {
427             test_ept[i] = rpmsg_create_ept(rpmsg_chnl , rpmsg_read_ept2_cb , RPMSG_NULL , EPT_TEST_ADDR + i);
429             if ( !test_ept[i] )
430             {
431                 status = -1;
432             }
434         }
435         if(!status)
436         {
437             status = test_rpmsg_send_offchannel_impl(rpmsg_chnl, test_ept[i]->addr, test_ept[i]->addr);
438         }
440         if(!status)
441         {
442             /* Tell the remote to delete the endpoint. */
443             cmd->comm_code = DELETE_EPT;
444             cmd->comm_start = CMD_START;
445             /* Send delete endpoint command to remote */
446             ept_data = (struct ept_cmd_data *)cmd->data;
447             ept_data->dst= EPT_TEST_ADDR + i;
448             ept_data->src= EPT_TEST_ADDR + i;
450             /* Let the other side know that it needs to delete endpoint with the given address */
451             status = rpmsg_send(rpmsg_chnl, cmd, sizeof(struct command) + sizeof(struct ept_cmd_data));
452         }
454         if(!status)
455         {
456             /* Wait for ack */
457             status = NU_Obtain_Semaphore(&App_Sem , NU_SUSPEND);
458         }
460         if(!status)
461         {
462             rpmsg_destroy_ept(test_ept[i]);
463         }
464     }
466     NU_Deallocate_Memory(cmd);
467     if(status)
468     {
469         return -1;
470     }
472     return status;
475 int test_rpmsg_send_impl(struct rpmsg_channel *rpmsg_chnl)
477     struct command cmd;
478     int status;
479     int i, size, idx;
480     NU_MEMORY_POOL     *sys_pool_ptr;
482     NU_System_Memory_Get(NU_NULL, &sys_pool_ptr);
483     /* Tell the remote to be prepared for echo payloads. */
484     cmd.comm_start = CMD_START;
485     cmd.comm_code = START_ECHO;
487     status = rpmsg_send(rpmsg_chnl, &cmd, sizeof(struct command));
489     if(!status)
490     {
491         /* Wait for cmd ack. */
492         status = NU_Obtain_Semaphore(&App_Sem , NU_SUSPEND);
493         if(status)
494         {
495             return -1;
496         }
497         for(i = 0, size=PAYLOAD_MIN_SIZE; i < NUM_PAYLOADS; i++, size++)
498         {
499             NU_Allocate_Memory(sys_pool_ptr , (void**)&p_payload, sizeof(struct _payload) + size , NU_SUSPEND );
501             p_payload->num = i;
502             p_payload->size = size;
504             /* Setup the buffer with a pattern*/
505             memset(p_payload->data, 0xA5, size);
507             /* Send data to remote side. */
508             status = rpmsg_send(rpmsg_chnl, p_payload, sizeof(struct _payload) + size);
510             if(status != 0)
511             {
512                 break;
513             }
515             /* Wait for echo. */
516             status = NU_Obtain_Semaphore(&App_Sem , NU_SUSPEND);
518             /* Validate the data integrity. */
519             for(idx = 0; idx < r_payload->size; idx++)
520             {
521                 if(p_payload->data[idx] != r_payload->data[idx])
522                 {
523                     status = -1;
524                     break;
525                 }
526             }
528             if(status != 0)
529             {
530                 break;
531             }
533             NU_Deallocate_Memory(p_payload);
535         }
536         if(status)
537         {
538             return -1;
539         }
540         cmd.comm_start = CMD_START;
541         cmd.comm_code = STOP_ECHO;
543         status = rpmsg_send(rpmsg_chnl, &cmd, sizeof(struct command));
544         if(status)
545         if(status)
546         {
547             return -1;
548         }
550         /* Wait for echo. */
551         status = NU_Obtain_Semaphore(&App_Sem , NU_SUSPEND);
552         
553         if(status)
554         {
555             return -1;
556         }
557      }
559     return status;
561 int test_rpmsg_send(struct rpmsg_channel *rpmsg_chnl)
563     return test_rpmsg_send_impl(rpmsg_chnl);
566 int test_rpmsg_send_offchannel_impl(struct rpmsg_channel *rpmsg_chnl, unsigned long src, unsigned long dst)
568     struct command cmd;
569     int status;
570     int i, size, idx;
571     NU_MEMORY_POOL     *sys_pool_ptr;
572     NU_System_Memory_Get(NU_NULL, &sys_pool_ptr);
574     /* Tell the remote to be prepared for echo payloads. */
575     cmd.comm_code = START_ECHO;
576     cmd.comm_start = CMD_START;
577     status = rpmsg_send(rpmsg_chnl, &cmd, sizeof(struct command));
579     if(!status)
580     {
581         /* Wait for cmd ack. */
582         status = NU_Obtain_Semaphore(&App_Sem , NU_SUSPEND);
583         if(status)
584         {
585             return -1;
586         }
588         for(i = 0, size=PAYLOAD_MIN_SIZE; i < NUM_PAYLOADS; i++, size++)
589         {
590             NU_Allocate_Memory(sys_pool_ptr , (void**)&p_payload, sizeof(struct _payload) + size , NU_SUSPEND );
591             p_payload->num = i;
592             p_payload->size = size;
594             /* Setup the buffer with a pattern*/
595             memset(p_payload->data, 0xA5, size);
597             /* Send data to remote side. */
598             status = rpmsg_send_offchannel(app_rp_chnl, src, dst, p_payload ,
599                                              sizeof(struct _payload) + size);
601             if(status)
602             {
603                 break;
604             }
606             /* Wait for echo. */
607             status = NU_Obtain_Semaphore(&App_Sem , NU_SUSPEND);
609             /* Validate the data integrity. */
610             for(idx = 0; idx < r_payload->size; idx++)
611             {
612                 if(p_payload->data[idx] != r_payload->data[idx])
613                 {
614                     status = -1;
615                     break;
616                 }
617             }
619             if(status)
620             {
621                 break;
622             }
624             NU_Deallocate_Memory(p_payload);
625         }
626         cmd.comm_start = CMD_START;
627         cmd.comm_code = STOP_ECHO;
629         status = rpmsg_send(rpmsg_chnl, &cmd, sizeof(struct command));
630         /* Wait for cmd ack. */
631         status = NU_Obtain_Semaphore(&App_Sem , NU_SUSPEND);
632         if(status)
633         {
634             return -1;
635         }
636      }
638      return status;
641 int test_rpmsg_send_offchannel(struct rpmsg_channel *rpmsg_chnl, unsigned long src, unsigned long dst)
643     return test_rpmsg_send_offchannel_impl(rpmsg_chnl, src, dst);