Contiki 2.6

ram-segments.c

00001 #ifndef __RAM_SEGMENTS_C__1POIF5E8U4__
00002 #define __RAM_SEGMENTS_C__1POIF5E8U4__
00003 
00004 #include <loader/elfloader-otf.h>
00005 #include <loader/codeprop-otf.h>
00006 #include <sys/types.h>
00007 #include <string.h>
00008 #include <stdio.h>
00009 
00010 struct ram_output
00011 {
00012   struct elfloader_output output;
00013   char *base;
00014   unsigned int offset;
00015   void *text;
00016   void *rodata;
00017   void *data;
00018   void *bss;
00019 };
00020 
00021 static void *
00022 allocate_segment(struct elfloader_output * const output,
00023                  unsigned int type, int size)
00024 {
00025   struct ram_output * const ram = (struct ram_output *)output;
00026   void *block = malloc(size);
00027   if (!block) return NULL;
00028   switch(type) {
00029   case ELFLOADER_SEG_TEXT:
00030     if (ram->text) free(ram->text);
00031     ram->text = block;
00032     break;
00033   case ELFLOADER_SEG_RODATA:
00034     if (ram->rodata) free(ram->rodata);
00035     ram->rodata = block;
00036     break;
00037   case ELFLOADER_SEG_DATA:
00038     if (ram->data) free(ram->data);
00039     ram->data = block;
00040     break;
00041   case ELFLOADER_SEG_BSS:
00042     if (ram->bss) free(ram->bss);
00043     ram->bss = block;
00044     break;
00045   default:
00046     free(block);
00047     return NULL;
00048   }
00049   return block;
00050 }
00051 
00052 static int
00053 start_segment(struct elfloader_output *output,
00054                         unsigned int type, void *addr, int size)
00055 {
00056   ((struct ram_output*)output)->base = addr;
00057   ((struct ram_output*)output)->offset = 0;
00058   return ELFLOADER_OK;
00059 }
00060 
00061 static int
00062 end_segment(struct elfloader_output *output)
00063 {
00064   return ELFLOADER_OK;
00065 }
00066 
00067 static int
00068 write_segment(struct elfloader_output *output, const char *buf,
00069               unsigned int len)
00070 {
00071   struct ram_output * const ram = (struct ram_output *)output;
00072   memcpy(ram->base + ram->offset, buf, len);
00073   ram->offset += len;
00074   return len;
00075 }
00076 
00077 static unsigned int
00078 segment_offset(struct elfloader_output *output)
00079 {
00080   return ((struct ram_output*)output)->offset;
00081 }
00082 
00083 static const struct elfloader_output_ops elf_output_ops =
00084   {
00085     allocate_segment,
00086     start_segment,
00087     end_segment,
00088     write_segment,
00089     segment_offset
00090   };
00091 
00092 
00093 static struct ram_output seg_output = {
00094   {&elf_output_ops},
00095   NULL,
00096   0,
00097   NULL,
00098   NULL,
00099   NULL,
00100   NULL
00101 };
00102 
00103 PROCESS(ram_segments_cleanup_process, "RAM segments cleanup process");
00104 
00105 PROCESS_THREAD(ram_segments_cleanup_process, ev, data)
00106 {
00107   PROCESS_BEGIN();
00108   while(1) {
00109     PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_EXITED
00110                              || ev == PROCESS_EVENT_EXIT);
00111     if (ev == PROCESS_EVENT_EXIT) break;
00112     if (elfloader_autostart_processes ||
00113         elfloader_autostart_processes[0] == data) {
00114       PROCESS_PAUSE(); /* Let the process exit */
00115       if (seg_output.text) {
00116         free(seg_output.text);
00117         seg_output.text = NULL;
00118       }
00119       if (seg_output.rodata) {
00120         free(seg_output.rodata);
00121         seg_output.rodata = NULL;
00122       }
00123       if (seg_output.data) {
00124         free(seg_output.data);
00125         seg_output.data = NULL;
00126       }
00127       
00128       if (seg_output.bss) {
00129         free(seg_output.bss);
00130         seg_output.bss = NULL;
00131       }
00132       elfloader_autostart_processes = NULL;
00133     }
00134   }
00135   PROCESS_END();
00136 }
00137 struct elfloader_output *codeprop_output = &seg_output.output;
00138 
00139 #endif /* __RAM_SEGMENTS_C__1POIF5E8U4__ */