]> 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_nucleusbm/func_test_suite.c
Moving OpenAMP sources to GIT repo.
[processor-sdk/open-amp.git] / apps / tests / master / nucleus / func_test_suite / nucleus_nucleusbm / func_test_suite.c
1 /* This is a test demonstration application that tests usage of remoteproc
2 and rpmsg APIs. This application is meant to run on the master CPU running Nucleus
3 and showcases booting of two sub-sequent remote firmware cycles using remoteproc and 
4 IPC with remote firmware using rpmsg; 1. It brings up a remote Nucleus based remote 
5 firmware which can respond to test calls, 2. It brings up a baremetal based 
6 remote firmware which can respond to test calls. Master app executes tests to validate
7 the rpmsg APIs and shutsdown the core once the test has been completed.*/
9 /* Including required headers */
11 #include  <stdio.h>
12 #include <string.h>
13 #include <stdlib.h>
14 #include "open_amp.h"
15 #include "test_suite.h"
16 #include "nucleus.h"
17 #include "kernel/nu_kernel.h"
20 /* Prototypes */
21 static void Main_Task_Entry( UNSIGNED argc , VOID *argv );
23 /* Application provided callbacks */
24 void rpmsg_channel_created( struct rpmsg_channel *rp_chnl );
25 void rpmsg_channel_deleted( struct rpmsg_channel *rp_chnl );
26 void rpmsg_read_default_cb( struct rpmsg_channel *rp_chnl , void *data , int len , void * pric ,
27                 unsigned long src );
28 void rpmsg_read_ept1_cb( struct rpmsg_channel *rp_chnl , void *data , int len , void * pric ,
29                 unsigned long src );
30 void rpmsg_read_ept2_cb( struct rpmsg_channel *rp_chnl , void *data , int len , void * pric ,
31                 unsigned long src );
33 int test_rpmsg_send(struct rpmsg_channel *rpmsg_chnl);
34 int test_rpmsg_send_offchannel(struct rpmsg_channel *rpmsg_chnl, unsigned long src, unsigned long dst);
36 int test_rpmsg_create_ept(struct rpmsg_channel *rpmsg_chnl);
38 int test_remoteproc_multiple_lifecycles(char * firmware_name);
40 int test_rpmsg_send_offchannel_impl(struct rpmsg_channel *rpmsg_chnl, unsigned long src, unsigned long dst);
42 int test_rpmsg_send_impl(struct rpmsg_channel *rpmsg_chnl);
44 int test_rpmsg_remote_channel_deletion(struct rpmsg_channel *rpmsg_chnl, char *channel_name);
46 int test_execute_suite(char * firmware_name);
49 /* Globals */
50 NU_TASK Task_Control_Block;
51 NU_SEMAPHORE App_Sem, Remote_Del_Sem;
52 struct rpmsg_endpoint *rp_ept1 , *rp_ept2;
53 struct rpmsg_channel *app_rp_chnl;
54 char fw_name1[] = "firmware1";
55 char fw_name2[] = "firmware2";
57 struct _payload* p_payload = NULL;
58 struct _payload* r_payload = NULL;
59 static const char display_string[] = ".";
60 /***********************************************************************
61  * *
62  * *   FUNCTION
63  * *
64  * *       Application_Initialize
65  * *
66  * *   DESCRIPTION
67  * *
68  * *       Demo application entry point
69  *
70  * ***********************************************************************/
71 VOID Application_Initialize(
72                 NU_MEMORY_POOL* mem_pool , NU_MEMORY_POOL* uncached_mem_pool )
73 {
74     VOID *pointer;
75     STATUS status = NU_SUCCESS;
77     /* Reference unused parameters to avoid toolset warnings */
78     NU_UNUSED_PARAM( uncached_mem_pool );
80     if ( status == NU_SUCCESS )
81     {
82         status = NU_Allocate_Memory(mem_pool, &pointer, STACK_SIZE, NU_NO_SUSPEND);
84         /* Create the main task for matrix processing */
85         if ( status == NU_SUCCESS )
86         {
87             status = NU_Create_Task( &Task_Control_Block , "MAIN" , Main_Task_Entry , 0 ,
88                             uncached_mem_pool , pointer , STACK_SIZE , TASK_PRIORITY , TASK_SLICE ,
89                             NU_PREEMPT , NU_START );
90         }
91         if ( status == NU_SUCCESS )
92         {
93             status = NU_Create_Semaphore( &App_Sem , "APP_SEM" , 0 , NU_FIFO );
94         }
96         if ( status == NU_SUCCESS )
97         {
98             status = NU_Create_Semaphore( &Remote_Del_Sem , "Del_SEM" , 0 , NU_FIFO );
99         }
101         NU_Allocate_Memory(uncached_mem_pool , (VOID **)&r_payload, 512 , NU_SUSPEND);
102     }
104     /* Check to see if previous operations were successful */
105     if ( status != NU_SUCCESS )
106     {
107         /* Loop forever */
108         while ( 1 );
109     }
112 /***********************************************************************
113  * *
114  * *   FUNCTION
115  * *
116  * *       Main_Task_Entry
117  * *
118  * *   DESCRIPTION
119  * *
120  * *       Entry function for the main task. This task prints a hello world
121  * *       message.
122  * *
123  * ***********************************************************************/
124 static VOID Main_Task_Entry( UNSIGNED argc , VOID *argv )
126     printf("\n\n\r************************************");
127     printf("*******************************************\r\n");
128     printf("\r\n              OpenAMP Test Suite \r\n");
129     printf("\r\n");
130     printf("\r\nThis test suite will execute multiple test cases for rpmsg and rempteproc \r\n");
131     printf("\r\nAPIs available within OpenAMP \r\n");
133     printf("\r\n******************************************");
134     printf("*************************************\n\r\n");
136     test_execute_suite(fw_name1);
138     test_execute_suite(fw_name2);
143 /* This callback gets invoked when the remote chanl is created */
144 void rpmsg_channel_created( struct rpmsg_channel *rp_chnl )
146     app_rp_chnl = rp_chnl;
148     rp_ept1 = rpmsg_create_ept(rp_chnl , rpmsg_read_ept1_cb , RPMSG_NULL , RPMSG_ADDR_ANY);
150     NU_Release_Semaphore( &App_Sem );
153 /* This callback gets invoked when the remote channel is deleted */
154 void rpmsg_channel_deleted( struct rpmsg_channel *rp_chnl )
156     rpmsg_destroy_ept( rp_ept1 );
158     NU_Release_Semaphore( &Remote_Del_Sem );
162 /* This is the read callback, note we are in a task context when this callback
163  is invoked, so kernel primitives can be used freely */
164 void rpmsg_read_default_cb( struct rpmsg_channel *rp_chnl , void *data , int len , void * priv ,
165                 unsigned long src )
167     memcpy( r_payload , data , len );
168     NU_Release_Semaphore( &App_Sem );
171 void rpmsg_read_ept1_cb( struct rpmsg_channel *rp_chnl , void *data , int len , void * priv ,
172                 unsigned long src )
174     memcpy( r_payload , data , len );
175     NU_Release_Semaphore( &App_Sem );
178 void rpmsg_read_ept2_cb( struct rpmsg_channel *rp_chnl , void *data , int len , void * priv ,
179                 unsigned long src )
181     memcpy( r_payload , data , len );
182     NU_Release_Semaphore( &App_Sem );
186 int test_execute_suite(char * firmware_name)
188     struct remote_proc *proc;
189     int status;
190     char default_channel[] = "rpmsg-openamp-demo-channel";
191     struct command* cmd;
192     NU_MEMORY_POOL     *sys_pool_ptr;
194     printf("\n\n\r************************************");
195     printf("*******************************************\r\n");
196     printf( "\r\nBoot remote context : %s \r\n" , firmware_name );
197     printf("\r\n******************************************");
198     printf("*************************************\n\r\n");
200     status = remoteproc_init( (void *) firmware_name ,rpmsg_channel_created, rpmsg_channel_deleted, rpmsg_read_default_cb, &proc);
202     if (status)
203     {
204         printf( "\r\n CRITICAL ERROR: remoteproc_init call for remote context %s failed \r\n", firmware_name);
206         return -1;
207     }
209     status = remoteproc_boot( proc );
211     if (status)
212     {
213         printf( "\r\n CRITICAL ERROR: remoteproc_boot call for remote context %s failed \r\n", firmware_name);
215         return -1;
216     }
218     /* Wait for channel creation event */
219     NU_Obtain_Semaphore( &App_Sem , NU_SUSPEND );
220         
221     /* Obtain remote firmware name */
222     NU_System_Memory_Get(NU_NULL, &sys_pool_ptr);
223     status = NU_Allocate_Memory(sys_pool_ptr , (void **)&(cmd), sizeof(struct command), NU_SUSPEND);
224     cmd->comm_start=CMD_START;
225     cmd->comm_code = QUERY_FW_NAME;
226     status = rpmsg_send(app_rp_chnl, cmd, sizeof(struct command));
227     NU_Deallocate_Memory(cmd);
228         
229     /* Wait to receive firmware name */
230     NU_Obtain_Semaphore( &App_Sem , NU_SUSPEND );
231         
232     printf("\r\nREMOTE FIRMWARE NAME : %s \r\n", (char*)r_payload);
234     /* Test rpmsg_send API */
235     status = test_rpmsg_send(app_rp_chnl);
237     if(!status)
238     {
239         printf( "\r\nRESULT:   PASSED \r\n" );
240     }
241     else
242     {
243         printf( "\r\nRESULT:   FAILED \r\n" );
244     }
246     /* Test rpmsg_send_offchannel API. */
247     status = test_rpmsg_send_offchannel(app_rp_chnl, rp_ept1->addr, app_rp_chnl->dst);
249     if(!status)
250     {
251         printf( "\r\nRESULT:   PASSED \r\n" );
252     }
253     else
254     {
255         printf( "\r\nRESULT:   FAILED \r\n" );
256     }
258     status = test_rpmsg_create_ept(app_rp_chnl);
260     if(!status)
261     {
262         printf( "\r\nRESULT:   PASSED \r\n" );
263     }
264     else
265     {
266         printf( "\r\nRESULT:   FAILED \r\n" );
267     }
269     printf("\n\n\r************************************");
270     printf("*******************************************\r\n");
271     printf(" This test case will test channel deletion \r\n");
272     printf("******************************************");
273     printf("*************************************\r\n\n");
275     status = test_rpmsg_remote_channel_deletion(app_rp_chnl, default_channel);
277     if(!status)
278     {
279         printf( "\r\nRESULT:   PASSED \r\n" );
280     }
281     else
282     {
283         printf( "\r\nRESULT:   FAILED \r\n" );
284     }
286     printf("\n\n\r************************************");
287     printf("*******************************************\r\n");
288     printf( "\r\n\nShutdown remote context : %s \r\n" , firmware_name );
289     printf("******************************************");
290     printf("*************************************\r\n\n");
292     status = remoteproc_shutdown(proc);
293     if(!status)
294     {
295         status = remoteproc_deinit(proc);
296     }
298     if(!status)
299     {
300         status = test_remoteproc_multiple_lifecycles(firmware_name);
301     }
303     if(!status)
304     {
305         printf( "\r\nRESULT:   PASSED \r\n" );
306     }
307     else
308     {
309         printf( "\r\nRESULT:   FAILED \r\n" );
310     }
312     printf("\r\nFUNCTIONAL TEST SUITE COMPLETED EXECUTION! \r\n");
314     return status;
317 int test_remoteproc_multiple_lifecycles(char * firmware_name)
319     int i, status;
320     struct remote_proc *proc;
322     printf("\n\n\r************************************");
323     printf("*******************************************\r\n");
324     printf(" This test case will test multiple lifecycles for firmware: %s \r\n", firmware_name);
325     printf("******************************************");
326     printf("*************************************\r\n\n");
328     for(i = 0; i < 10; i++)
329     {
330         status = remoteproc_init( (void *) firmware_name ,rpmsg_channel_created, rpmsg_channel_deleted, rpmsg_read_default_cb, &proc);
332         if (status)
333         {
334             printf( "\r\n ERROR: remoteproc_init failed\r\n");
336             break;
337         }
338                 
339             printf("\n\n\r************************************");
340                 printf("*******************************************\r\n");
341                 printf( "\r\n\nBoot remote context : %s \r\n" , firmware_name );
342                 printf("******************************************");
343                 printf("*************************************\r\n\n");
345         status = remoteproc_boot( proc );
347         if (status)
348         {
349             printf( "\r\n ERROR: remoteproc_boot failed\r\n");
351             break;
352         }
354         /* Wait for channel creation event */
355         status = NU_Obtain_Semaphore( &App_Sem , NU_SUSPEND );
357         if (!status)
358         {
359             status = test_rpmsg_send_impl(app_rp_chnl);
360         }
362         if(!status){
363             test_rpmsg_remote_channel_deletion(app_rp_chnl , app_rp_chnl->name);
364         }
365                 
366             printf("\n\n\r************************************");
367                 printf("*******************************************\r\n");
368                 printf( "\r\n\nShutdown remote context : %s \r\n" , firmware_name );
369                 printf("******************************************");
370                 printf("*************************************\r\n\n");
372         if (!status)
373         {
374             status = remoteproc_shutdown(proc);
375         }
376         if (status)
377         {
378             printf( "\r\n ERROR: remoteproc_shutdown failed\r\n");
380             break;
381         }
382         status = remoteproc_deinit(proc);
384         if (status)
385         {
386             printf( "\r\n ERROR: remoteproc_deinit failed\r\n");
388             break;
389         }
391         printf("%s", display_string);
393     }
395     return status;
398 int test_rpmsg_remote_channel_deletion(struct rpmsg_channel *rpmsg_chnl, char *channel_name)
400     struct command *cmd;
401     int status;
402     NU_MEMORY_POOL     *sys_pool_ptr;
403     struct chnl_cmd_data *chnl_data;
405     NU_System_Memory_Get(NU_NULL, &sys_pool_ptr);
407     status = NU_Allocate_Memory(sys_pool_ptr ,
408                                 (void **)&(cmd), sizeof(struct command)+ sizeof(struct chnl_cmd_data), NU_SUSPEND);
410     cmd->comm_code = DELETE_CHNL;
411     cmd->comm_start = CMD_START;
413     chnl_data = (struct chnl_cmd_data *)cmd->data;
415     strncpy(chnl_data->name , channel_name, sizeof(struct chnl_cmd_data));
417     /* Let the other side that uninit its resources */
418     status = rpmsg_send( rpmsg_chnl , cmd , sizeof(struct command) + sizeof(struct chnl_cmd_data) );
419     if(status)
420     {
421         return status;
422     }
423     /* Wait for echo back */
424     status = NU_Obtain_Semaphore( &App_Sem , NU_SUSPEND);
425     /* Wait for channel deletion event */
426     status = NU_Obtain_Semaphore( &Remote_Del_Sem , NU_SUSPEND);
428     return status;
431 int test_rpmsg_create_ept(struct rpmsg_channel *rpmsg_chnl)
433     struct command *cmd;
434     int status, i;
435     struct ept_cmd_data *ept_data;
436     NU_MEMORY_POOL     *sys_pool_ptr;
437     struct rpmsg_endpoint *test_ept[NUM_TEST_EPS];
439     NU_System_Memory_Get(NU_NULL, &sys_pool_ptr);
441     status = NU_Allocate_Memory(sys_pool_ptr ,
442                                 (void **)&(cmd), sizeof(struct command) + sizeof(struct ept_cmd_data), NU_SUSPEND);
444     if(status != NU_SUCCESS)
445     {
446         return status;
447     }
448     printf("\n\n\r************************************");
449     printf("*******************************************\r\n");
450     printf(" This test case will test rpmsg_create_ept API \r\n");
451     printf("******************************************");
452     printf("*************************************\r\n\n");
454     for(i = 0; i < NUM_TEST_EPS; i++)
455     {
456         /* Tell the remote to create a new endpoint. */
457         cmd->comm_code = CREATE_EPT;
458         cmd->comm_start = CMD_START;
460         /* Send create endpoint command to remote */
461         ept_data = (struct ept_cmd_data *)cmd->data;
462         ept_data->dst= EPT_TEST_ADDR + i;
463         ept_data->src= EPT_TEST_ADDR + i;
465         /* Let the other side know that it needs to create endpoint with the given address */
466         status = rpmsg_send(rpmsg_chnl, cmd, sizeof(struct command) + sizeof(struct ept_cmd_data));
468         if(!status)
469         {
470             /* Wait for ack */
471             status = NU_Obtain_Semaphore(&App_Sem , NU_SUSPEND);
472         }
474         if(!status)
475         {
476             printf("\r\nCreating an endpoint at address: %d \r\n", EPT_TEST_ADDR + i);
478             test_ept[i] = rpmsg_create_ept(rpmsg_chnl , rpmsg_read_ept2_cb , RPMSG_NULL , EPT_TEST_ADDR + i);
480             if ( !test_ept[i] )
481             {
482                 status = -1;
484                 printf("\r\n ERROR: rpmsg_create_ept API failed for endpoint address: %d \r\n", EPT_TEST_ADDR + i);
485             }
487         }
488         if(!status)
489         {
490             printf("\r\nTesting payloads on endpoint at address: %d \r\n", EPT_TEST_ADDR + i);
492             status = test_rpmsg_send_offchannel_impl(rpmsg_chnl, test_ept[i]->addr, test_ept[i]->addr);
493         }
495         if(!status)
496         {
497             /* Tell the remote to delete the endpoint. */
498             cmd->comm_code = DELETE_EPT;
499             cmd->comm_start = CMD_START;
500             /* Send delete endpoint command to remote */
501             ept_data = (struct ept_cmd_data *)cmd->data;
502             ept_data->dst= EPT_TEST_ADDR + i;
503             ept_data->src= EPT_TEST_ADDR + i;
505             /* Let the other side know that it needs to delete endpoint with the given address */
506             status = rpmsg_send(rpmsg_chnl, cmd, sizeof(struct command) + sizeof(struct ept_cmd_data));
507         }
509         if(!status)
510         {
511             /* Wait for ack */
512             status = NU_Obtain_Semaphore(&App_Sem , NU_SUSPEND);
513         }
515         if(!status)
516         {
517             rpmsg_destroy_ept(test_ept[i]);
518         }
519     }
521     NU_Deallocate_Memory(cmd);
522     if(status)
523         while(1);
525     return status;
528 int test_rpmsg_send_impl(struct rpmsg_channel *rpmsg_chnl)
530     struct command cmd;
531     int status;
532     int i, size, idx;
533     NU_MEMORY_POOL     *sys_pool_ptr;
535     NU_System_Memory_Get(NU_NULL, &sys_pool_ptr);
536     /* Tell the remote to be prepared for echo payloads. */
537     cmd.comm_start = CMD_START;
538     cmd.comm_code = START_ECHO;
540     status = rpmsg_send(rpmsg_chnl, &cmd, sizeof(struct command));
542     if(!status)
543     {
544         /* Wait for cmd ack. */
545         status = NU_Obtain_Semaphore(&App_Sem , NU_SUSPEND);
546         if(status)
547             while(1);
549         printf("\r\nTransmitting paylaods to remote \r\n");
551         for(i = 0, size=PAYLOAD_MIN_SIZE; i < NUM_PAYLOADS; i++, size++)
552         {
553             NU_Allocate_Memory(sys_pool_ptr , (void**)&p_payload, sizeof(struct _payload) + size , NU_SUSPEND );
555             p_payload->num = i;
556             p_payload->size = size;
558             /* Setup the buffer with a pattern*/
559             memset(p_payload->data, 0xA5, size);
561             /* Send data to remote side. */
562             status = rpmsg_send(rpmsg_chnl, p_payload, sizeof(struct _payload) + size);
564             if(status != 0)
565             {
566                 break;
567             }
569             /* Wait for echo. */
570             status = NU_Obtain_Semaphore(&App_Sem , NU_SUSPEND);
572             /* Validate the data integrity. */
573             for(idx = 0; idx < r_payload->size; idx++)
574             {
575                 if(p_payload->data[idx] != r_payload->data[idx])
576                 {
577                     status = -1;
578                     break;
579                 }
580             }
582             if(status != 0)
583             {
584                 break;
585             }
587             NU_Deallocate_Memory(p_payload);
588             printf("%s", display_string);
589         }
590         if(status)
591             while(1);
592         cmd.comm_start = CMD_START;
593         cmd.comm_code = STOP_ECHO;
595         status = rpmsg_send(rpmsg_chnl, &cmd, sizeof(struct command));
596         if(status)
597             while(1);
599         /* Wait for echo. */
600         status = NU_Obtain_Semaphore(&App_Sem , NU_SUSPEND);
601         if(status)
602             while(1);
603      }
606     return status;
608 int test_rpmsg_send(struct rpmsg_channel *rpmsg_chnl)
610     printf("\n\n\r************************************");
611     printf("*******************************************\r\n");
612     printf(" This test case will test rpmsg_send API \r\n");
613     printf("******************************************");
614     printf("*************************************\r\n\n");
616     return test_rpmsg_send_impl(rpmsg_chnl);
619 int test_rpmsg_send_offchannel_impl(struct rpmsg_channel *rpmsg_chnl, unsigned long src, unsigned long dst)
621     struct command cmd;
622     int status;
623     int i, size, idx;
624     NU_MEMORY_POOL     *sys_pool_ptr;
625     NU_System_Memory_Get(NU_NULL, &sys_pool_ptr);
627     /* Tell the remote to be prepared for echo payloads. */
628     cmd.comm_code = START_ECHO;
629     cmd.comm_start = CMD_START;
630     status = rpmsg_send(rpmsg_chnl, &cmd, sizeof(struct command));
632     if(!status)
633     {
634         /* Wait for cmd ack. */
635         status = NU_Obtain_Semaphore(&App_Sem , NU_SUSPEND);
636         if(status)
637             while(1);
639         for(i = 0, size=PAYLOAD_MIN_SIZE; i < NUM_PAYLOADS; i++, size++)
640         {
641             NU_Allocate_Memory(sys_pool_ptr , (void**)&p_payload, sizeof(struct _payload) + size , NU_SUSPEND );
642             p_payload->num = i;
643             p_payload->size = size;
645             /* Setup the buffer with a pattern*/
646             memset(p_payload->data, 0xA5, size);
648             /* Send data to remote side. */
649             status = rpmsg_send_offchannel(app_rp_chnl, src, dst, p_payload ,
650                                              sizeof(struct _payload) + size);
652             if(status)
653             {
654                 break;
655             }
657             /* Wait for echo. */
658             status = NU_Obtain_Semaphore(&App_Sem , NU_SUSPEND);
660             /* Validate the data integrity. */
661             for(idx = 0; idx < r_payload->size; idx++)
662             {
663                 if(p_payload->data[idx] != r_payload->data[idx])
664                 {
665                     status = -1;
666                     break;
667                 }
668             }
670             if(status)
671             {
672                 break;
673             }
675             printf("%s", display_string);
676             NU_Deallocate_Memory(p_payload);
677         }
678         cmd.comm_start = CMD_START;
679         cmd.comm_code = STOP_ECHO;
681         status = rpmsg_send(rpmsg_chnl, &cmd, sizeof(struct command));
682         /* Wait for cmd ack. */
683         status = NU_Obtain_Semaphore(&App_Sem , NU_SUSPEND);
684         if(status)
685             while(1);
686      }
688      return status;
691 int test_rpmsg_send_offchannel(struct rpmsg_channel *rpmsg_chnl, unsigned long src, unsigned long dst)
693     printf("\n\n\r************************************");
694     printf("*******************************************\r\n");
695     printf(" This test case will test rpmsg_send_offchannel API \r\n");
696     printf("******************************************");
697     printf("*************************************\r\n\n");
699     return test_rpmsg_send_offchannel_impl(rpmsg_chnl, src, dst);