From eed1c74b1a4198f0125090abd844acaa9c2af83d Mon Sep 17 00:00:00 2001 From: Andrea <andrea.ponte1987@gmail.com> Date: Mon, 17 Dec 2012 17:30:00 +0100 Subject: [PATCH] New system calls: open, close, seek, system added. --- .directory | 3 + .gitignore | 10 + app_template/crt0.s | 53 + app_template/log.txt | 5 + app_template/main.c | 71 +- app_template/main.map | 139 + app_template/main.txt | 405 ++ app_template/prog3.h | 91 +- app_template_withlibs/main.map | 6 + chg.patch | 3313 +++++++++++++++++ log.txt | 5 + main.cpp | 10 + miosix/Makefile | 1 + .../common/interfaces-impl/disk.cpp | 27 +- .../common/interfaces-impl/portability.cpp | 9 +- miosix/compiler/cleanup.sh | 0 miosix/compiler/download.sh | 0 miosix/compiler/install-script.sh | 0 miosix/compiler/mx-postlinker/Makefile | 4 +- miosix/compiler/uninstall.sh | 0 miosix/kernel/SystemMap.cpp | 66 + miosix/kernel/SystemMap.h | 34 + miosix/kernel/filesystem/ff.c | 3 +- miosix/kernel/filesystem/filesystem.cpp | 17 +- miosix/kernel/process.cpp | 63 +- miosix/kernel/process.h | 2 + miosix/kernel/syscalls.cpp | 4 +- miosix/util/util.cpp | 7 + miosix/util/util.h | 9 + .../nbproject/configurations.xml | 569 ++- .../nbproject/private/configurations.xml | 2 +- .../nbproject/private/private.xml | 7 + .../stm32f207ig_stm3220g-eval.properties | 0 sd.patch | 59 + system_app_test/Makefile | 44 + system_app_test/crt0.o | Bin 0 -> 1464 bytes system_app_test/crt0.s | 130 + system_app_test/log.txt | 5 + system_app_test/main.c | 20 + system_app_test/main.c~ | 51 + system_app_test/main.elf | Bin 0 -> 220 bytes system_app_test/main.map | 128 + system_app_test/miosix.ld | 66 + system_app_test/prog3.h | 22 + system_app_test/test.txt | 76 + 45 files changed, 5472 insertions(+), 64 deletions(-) create mode 100644 .directory create mode 100644 .gitignore create mode 100644 app_template/log.txt create mode 100644 app_template/main.map create mode 100644 app_template/main.txt create mode 100644 app_template_withlibs/main.map create mode 100644 chg.patch create mode 100644 log.txt mode change 100644 => 100755 miosix/compiler/cleanup.sh mode change 100644 => 100755 miosix/compiler/download.sh mode change 100644 => 100755 miosix/compiler/install-script.sh mode change 100644 => 100755 miosix/compiler/uninstall.sh create mode 100644 miosix/kernel/SystemMap.cpp create mode 100644 miosix/kernel/SystemMap.h create mode 100644 miosix_np_processes/nbproject/private/stm32f207ig_stm3220g-eval.properties create mode 100644 sd.patch create mode 100644 system_app_test/Makefile create mode 100644 system_app_test/crt0.o create mode 100644 system_app_test/crt0.s create mode 100644 system_app_test/log.txt create mode 100644 system_app_test/main.c create mode 100644 system_app_test/main.c~ create mode 100755 system_app_test/main.elf create mode 100644 system_app_test/main.map create mode 100644 system_app_test/miosix.ld create mode 100644 system_app_test/prog3.h create mode 100644 system_app_test/test.txt diff --git a/.directory b/.directory new file mode 100644 index 00000000..3c542a57 --- /dev/null +++ b/.directory @@ -0,0 +1,3 @@ +[Dolphin] +Timestamp=2012,12,17,17,4,38 +Version=3 diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..d08a834f --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +*/nbproject/ +*.bz2 +*.gz +*.o +*.a +*.elf +*.map +*.hex +*.bin +*~ diff --git a/app_template/crt0.s b/app_template/crt0.s index 2eba4bfa..d02fabab 100644 --- a/app_template/crt0.s +++ b/app_template/crt0.s @@ -31,6 +31,59 @@ _exit: movs r3, #2 svc 0 +/** + * open, open a file + * \param fd file descriptor + * \param file access mode + * \param xxx access permisions + * \return file descriptor or -1 if errors + */ +.section .text.open +.global open +.type open, %function +open: + movs r3, #6 + svc 0 + bx lr + +/** + * close, close a file + * \param fd file descriptor + */ +.section .text.close +.global close +.type close, %function +close: + movs r3, #7 + svc 0 + bx lr + +/** + * seek + * \param fd file descriptor + * \param pos moving offset + * \param start position, SEEK_SET, SEEK_CUR or SEEK_END +*/ +.section .text.seek +.global seek +.type seek, %function +seek: + movs r3, #8 + svc 0 + bx lr + + +/** + * system, fork and execture a program, blocking + * \param program to execute + */ +.section .text.system +.global system +.type system, %function +system: + movs r3, #9 + svc 0 + bx lr /** * write, write to file * \param fd file descriptor diff --git a/app_template/log.txt b/app_template/log.txt new file mode 100644 index 00000000..947e1fa9 --- /dev/null +++ b/app_template/log.txt @@ -0,0 +1,5 @@ +arm-miosix-eabi-g++ -mcpu=cortex-m3 -mthumb -mfix-cortex-m3-ldrd -fpie -msingle-pic-base -Wl,--gc-sections,-Map,main.map,-T./miosix.ld,-n,-pie,--spare-dynamic-tags,3 -O2 -nostdlib -fPIC -o main.elf main.o crt0.o -Wl,--start-group -lstdc++ -lc -lm -lgcc -Wl,--end-group +/opt/arm-miosix-eabi/lib/gcc/arm-eabi/4.5.2/../../../../arm-eabi/bin/ld: /opt/arm-miosix-eabi/lib/gcc/arm-eabi/4.5.2/../../../../arm-eabi/lib/thumb/thumb2/libc.a(lib_a-syslseek.o): relocation R_ARM_THM_MOVW_ABS_NC against `_impure_ptr' can not be used when making a shared object; recompile with -fPIC +/opt/arm-miosix-eabi/lib/gcc/arm-eabi/4.5.2/../../../../arm-eabi/lib/thumb/thumb2/libc.a: could not read symbols: Bad value +collect2: ld returned 1 exit status +make: *** [all] Error 1 diff --git a/app_template/main.c b/app_template/main.c index 109e99de..2e3bcb22 100644 --- a/app_template/main.c +++ b/app_template/main.c @@ -1,6 +1,11 @@ - #include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <string.h> +#include <stdio.h> + int mystrlen(const char *s) { int result=0; @@ -10,8 +15,25 @@ int mystrlen(const char *s) int main() { - static const char str[]="0=divzero 1=sleep 5s, 2=exit 3=bkpt 4=dangling\n"; + int i = 0; + static const char str[]="Test application:\n0=divzero\n1=sleep 5s\n2=exit\n3=bkpt\n4=dangling\n5=open\n6=system\n"; static const char str2[]="Unexpected command\n"; + static const char okMsg[] = "Everything's shiny, Cap'n\n"; + + /* + char strTest[500] = {'a'}; + + strTest[0] = 0; + + int c = (int)strTest[0]; + + unsigned int *p = &i; + + p -= 567; + + *p = 0x00; + */ + for(;;) { char result[100]; @@ -20,6 +42,9 @@ int main() if(len<1) continue; int i=10/(int)(result[0]-'0'); unsigned int *p=(unsigned int *)0xc0000000; + + int fp = 0; + switch(result[0]) { case '0': @@ -36,6 +61,48 @@ int main() case '4': usleep(*p); break; + case '5': + fp = open("/test.txt", O_RDWR|O_TRUNC, 0); + + if(fp != 0){ + write(1, "File opened\n", 12); + int check = 0; + + if(write(fp, "ciao", 4) == 4){ + write(1, "Write ok\n", 9); + check |= 0x01; + } + + //close(fp); + //fp = open("/test.txt", O_RDWR, 0); + seek(fp, SEEK_SET, 0); + + if(write(fp, "123", 3) == 3){ + write(1, "Write ok\n", 9); + check |= 0x01; + } + + seek(fp, SEEK_SET, 0); + + if(read(fp, result, 100) == 4){ + write(1, "Read ok\n", 8); + check |= 0x02; + } + + if(close(fp) == 0){ + write(1, "Close ok\n", 9); + check |= 0x04; + } + + if(check == 0x07) + write(1, okMsg, mystrlen(okMsg)); + } + + + break; + case '6': + system("test"); + break; default: write(1,str2,mystrlen(str2)); } diff --git a/app_template/main.map b/app_template/main.map new file mode 100644 index 00000000..333d4b33 --- /dev/null +++ b/app_template/main.map @@ -0,0 +1,139 @@ + +Discarded input sections + + .text 0x0000000000000000 0x0 main.o + .data 0x0000000000000000 0x0 main.o + .bss 0x0000000000000000 0x0 main.o + .text.mystrlen + 0x0000000000000000 0x14 main.o + .comment 0x0000000000000000 0x12 main.o + .ARM.attributes + 0x0000000000000000 0x31 main.o + .data 0x0000000000000000 0x0 crt0.o + .bss 0x0000000000000000 0x0 crt0.o + .ARM.attributes + 0x0000000000000000 0x21 crt0.o + +Memory Configuration + +Name Origin Length Attributes +*default* 0x0000000000000000 0xffffffffffffffff + +Linker script and memory map + + 0x0000000000000094 . = (0x0 + SIZEOF_HEADERS) + +.text 0x0000000000000098 0x1f2 + *(.text) + .text 0x0000000000000098 0x8 crt0.o + 0x0000000000000098 _start + *(.text.*) + .text.main 0x00000000000000a0 0x1bc main.o + 0x00000000000000a0 main + .text._exit 0x000000000000025c 0x4 crt0.o + 0x000000000000025c _exit + .text.open 0x0000000000000260 0x6 crt0.o + 0x0000000000000260 open + .text.close 0x0000000000000266 0x6 crt0.o + 0x0000000000000266 close + .text.seek 0x000000000000026c 0x6 crt0.o + 0x000000000000026c seek + .text.system 0x0000000000000272 0x6 crt0.o + 0x0000000000000272 system + .text.write 0x0000000000000278 0x6 crt0.o + 0x0000000000000278 write + .text.read 0x000000000000027e 0x6 crt0.o + 0x000000000000027e read + .text.usleep 0x0000000000000284 0x6 crt0.o + 0x0000000000000284 usleep + *(.gnu.linkonce.t.*) + +.glue_7 0x000000000000028c 0x0 + .glue_7 0x0000000000000000 0x0 linker stubs + +.glue_7t 0x000000000000028c 0x0 + .glue_7t 0x0000000000000000 0x0 linker stubs + +.vfp11_veneer 0x000000000000028c 0x0 + .vfp11_veneer 0x0000000000000000 0x0 linker stubs + +.v4_bx 0x000000000000028c 0x0 + .v4_bx 0x0000000000000000 0x0 linker stubs + +.plt 0x000000000000028c 0x0 + .plt 0x0000000000000000 0x0 main.o + +.rel.dyn 0x000000000000028c 0x0 + .rel.plt 0x0000000000000000 0x0 main.o + +.rel.data + *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) + +.rel.got 0x000000000000028c 0x0 + *(.rel.got) + .rel.got 0x0000000000000000 0x0 main.o + 0x0000000010000000 . = 0x10000000 + +.got 0x0000000010000000 0xc + *(.got.plt) + .got.plt 0x0000000010000000 0xc main.o + 0x0000000010000000 _GLOBAL_OFFSET_TABLE_ + *(.igot.plt) + *(.got) + .got 0x0000000000000000 0x0 main.o + *(.igot) + +.dynamic 0x000000001000000c 0x28 + *(.dynamic) + .dynamic 0x000000001000000c 0x28 main.o + 0x000000001000000c _DYNAMIC + +.rodata 0x0000000010000038 0xd8 + *(.rodata) + .rodata 0x0000000010000038 0x84 main.o + *(.rodata.*) + .rodata.str1.4 + 0x00000000100000bc 0x54 main.o + *(.gnu.linkonce.r.*) + +.gnu.version_d 0x0000000010000110 0x0 + .gnu.version_d + 0x0000000000000000 0x0 main.o + +.gnu.version 0x0000000010000110 0x0 + .gnu.version 0x0000000000000000 0x0 main.o + +.gnu.version_r 0x0000000010000110 0x0 + .gnu.version_r + 0x0000000000000000 0x0 main.o + +.data + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + +.bss + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + +.dynbss 0x0000000010000110 0x0 + .dynbss 0x0000000000000000 0x0 main.o + +/DISCARD/ + *(.interp) + *(.dynsym) + *(.dynstr) + *(.hash) + *(.comment) + *(.ARM.attributes) +LOAD main.o +LOAD crt0.o +START GROUP +LOAD /opt/arm-miosix-eabi/lib/gcc/arm-eabi/4.5.2/../../../../arm-eabi/lib/thumb/thumb2/libstdc++.a +LOAD /opt/arm-miosix-eabi/lib/gcc/arm-eabi/4.5.2/../../../../arm-eabi/lib/thumb/thumb2/libc.a +LOAD /opt/arm-miosix-eabi/lib/gcc/arm-eabi/4.5.2/../../../../arm-eabi/lib/thumb/thumb2/libm.a +LOAD /opt/arm-miosix-eabi/lib/gcc/arm-eabi/4.5.2/thumb/thumb2/libgcc.a +END GROUP +OUTPUT(main.elf elf32-littlearm) diff --git a/app_template/main.txt b/app_template/main.txt new file mode 100644 index 00000000..f6aa0391 --- /dev/null +++ b/app_template/main.txt @@ -0,0 +1,405 @@ + +main.elf: file format elf32-littlearm +main.elf +architecture: arm, flags 0x00000050: +HAS_SYMS, DYNAMIC +start address 0x00000099 + +Program Header: + LOAD off 0x00000098 vaddr 0x00000098 paddr 0x00000098 align 2**3 + filesz 0x000001f2 memsz 0x000001f2 flags r-x + LOAD off 0x00000290 vaddr 0x10000000 paddr 0x10000000 align 2**3 + filesz 0x00000110 memsz 0x00000110 flags rw- + DYNAMIC off 0x0000029c vaddr 0x1000000c paddr 0x1000000c align 2**2 + filesz 0x00000028 memsz 0x00000028 flags rw- + +Dynamic Section: + DEBUG 0x00000000 +private flags = 5000002: [Version5 EABI] [has entry point] + +Sections: +Idx Name Size VMA LMA File off Algn + 0 .text 000001f2 00000098 00000098 00000098 2**3 + CONTENTS, ALLOC, LOAD, READONLY, CODE + 1 .got 0000000c 10000000 10000000 00000290 2**2 + CONTENTS, ALLOC, LOAD, DATA + 2 .dynamic 00000028 1000000c 1000000c 0000029c 2**2 + CONTENTS, ALLOC, LOAD, DATA + 3 .rodata 000000d8 10000038 10000038 000002c8 2**3 + CONTENTS, ALLOC, LOAD, READONLY, DATA +SYMBOL TABLE: +00000098 l d .text 00000000 .text +10000000 l d .got 00000000 .got +1000000c l d .dynamic 00000000 .dynamic +10000038 l d .rodata 00000000 .rodata +00000000 l df *ABS* 00000000 main.c +10000038 l O .rodata 00000051 str.2690 +1000008c l O .rodata 0000001b okMsg.2692 +100000a8 l O .rodata 00000014 str2.2691 +1000000c l O *ABS* 00000000 _DYNAMIC +10000000 l O *ABS* 00000000 _GLOBAL_OFFSET_TABLE_ +00000284 g F .text 00000000 usleep +00000272 g F .text 00000000 system +00000278 g F .text 00000000 write +00000098 g F .text 00000000 _start +0000027e g F .text 00000000 read +000000a0 g F .text 000001bc main +0000026c g F .text 00000000 seek +0000025c g F .text 00000000 _exit +00000260 g F .text 00000000 open +00000266 g F .text 00000000 close + + +Contents of section .text: + 0098 00f002f8 00f0def8 2de9f04d dff89081 ........-..M.... + 00a8 644fdff8 94a1dff8 94b19cb0 644d03ae dO..........dM.. + 00b8 c8444f44 ca44cb44 09eb0503 002213f8 .DOD.D.D.....".. + 00c8 014f0132 002cfad1 09eb0501 012000f0 .O.2.,....... .. + 00d8 cff86422 20463146 00f0cdf8 0028ebdd ..d" F1F.....(.. + 00e8 9df80c30 303b062b 74d8dfe8 03f06c65 ...00;.+t.....le + 00f8 615f5908 04004046 00f0b7f8 dce73846 a_Y...@F......8F + 0108 40f20241 002200f0 a7f80446 0028d3d0 @..A.".....F.(.. + 0118 0c220120 514600f0 abf80422 20465946 .". QF....." FYF + 0128 00f0a6f8 042870d0 00210191 00210a46 .....(p..!...!.F + 0138 204600f0 97f84349 03222046 494400f0 F....CI." FID.. + 0148 97f80328 6ad00022 11462046 00f08af8 ...(j..".F F.... + 0158 64222046 314600f0 8ef80428 4ad02046 d" F1F.....(J. F + 0168 00f07df8 04460028 a6d13749 01204944 ..}..F.(..7I. ID + 0178 092200f0 7df80199 41f00403 072b9bd1 ."..}...A....+.. + 0188 09eb0503 54332246 13f8011f 01320029 ....T3"F.....2.) + 0198 fad109eb 05015431 012000f0 69f88be7 ......T1. ..i... + 01a8 4ff04043 186800f0 69f885e7 00be83e7 O.@C.h..i....... + 01b8 00201cb0 bde8f08d 44f64030 c0f24c00 . ......D.@0..L. + 01c8 00f05cf8 78e70023 0a2090fb f3f000f0 ..\.x..#. ...... + 01d8 55f871e7 09eb0503 70330022 13f8011f U.q.....p3.".... + 01e8 01320029 fad109eb 05017031 012000f0 .2.)......p1. .. + 01f8 3ff861e7 15490120 49440822 00f038f8 ?.a..I. ID."..8. + 0208 019b43f0 02030193 a9e71149 01204944 ..C........I. ID + 0218 092200f0 2df80123 019387e7 0c490922 ."..-..#.....I." + 0228 01204944 00f024f8 01220192 8be700bf . ID..$.."...... + 0238 08010000 bc000000 c8000000 d8000000 ................ + 0248 38000000 ec000000 fc000000 f0000000 8............... + 0258 e0000000 022300df 062300df 70470723 .....#...#..pG.# + 0268 00df7047 082300df 70470923 00df7047 ..pG.#..pG.#..pG + 0278 032300df 70470423 00df7047 052300df .#..pG.#..pG.#.. + 0288 7047 pG +Contents of section .got: + 10000000 0c000010 00000000 00000000 ............ +Contents of section .dynamic: + 1000000c 15000000 00000000 00000000 00000000 ................ + 1000001c 00000000 00000000 00000000 00000000 ................ + 1000002c 00000000 00000000 ........ +Contents of section .rodata: + 10000038 54657374 20617070 6c696361 74696f6e Test application + 10000048 3a0a303d 6469767a 65726f0a 313d736c :.0=divzero.1=sl + 10000058 65657020 35730a32 3d657869 740a333d eep 5s.2=exit.3= + 10000068 626b7074 0a343d64 616e676c 696e670a bkpt.4=dangling. + 10000078 353d6f70 656e0a36 3d737973 74656d0a 5=open.6=system. + 10000088 00000000 45766572 79746869 6e672773 ....Everything's + 10000098 20736869 6e792c20 43617027 6e0a0000 shiny, Cap'n... + 100000a8 556e6578 70656374 65642063 6f6d6d61 Unexpected comma + 100000b8 6e640a00 2f746573 742e7478 74000000 nd../test.txt... + 100000c8 46696c65 206f7065 6e65640a 00000000 File opened..... + 100000d8 6369616f 00000000 57726974 65206f6b ciao....Write ok + 100000e8 0a000000 31323300 52656164 206f6b0a ....123.Read ok. + 100000f8 00000000 436c6f73 65206f6b 0a000000 ....Close ok.... + 10000108 74657374 00000000 test.... + +Disassembly of section .text: + +00000098 <_start>: +_start(): + 98: f000 f802 bl a0 <main> + 9c: f000 f8de bl 25c <_exit> + +000000a0 <main>: +main(): + a0: e92d 4df0 stmdb sp!, {r4, r5, r6, r7, r8, sl, fp, lr} + a4: f8df 8190 ldr.w r8, [pc, #400] ; 238 <main+0x198> + a8: 4f64 ldr r7, [pc, #400] ; (23c <main+0x19c>) + aa: f8df a194 ldr.w sl, [pc, #404] ; 240 <main+0x1a0> + ae: f8df b194 ldr.w fp, [pc, #404] ; 244 <main+0x1a4> + b2: b09c sub sp, #112 ; 0x70 + b4: 4d64 ldr r5, [pc, #400] ; (248 <main+0x1a8>) + b6: ae03 add r6, sp, #12 + b8: 44c8 add r8, r9 + ba: 444f add r7, r9 + bc: 44ca add sl, r9 + be: 44cb add fp, r9 + c0: eb09 0305 add.w r3, r9, r5 + c4: 2200 movs r2, #0 + c6: f813 4f01 ldrb.w r4, [r3, #1]! + ca: 3201 adds r2, #1 + cc: 2c00 cmp r4, #0 + ce: d1fa bne.n c6 <main+0x26> + d0: eb09 0105 add.w r1, r9, r5 + d4: 2001 movs r0, #1 + d6: f000 f8cf bl 278 <write> + da: 2264 movs r2, #100 ; 0x64 + dc: 4620 mov r0, r4 + de: 4631 mov r1, r6 + e0: f000 f8cd bl 27e <read> + e4: 2800 cmp r0, #0 + e6: ddeb ble.n c0 <main+0x20> + e8: f89d 300c ldrb.w r3, [sp, #12] + ec: 3b30 subs r3, #48 ; 0x30 + ee: 2b06 cmp r3, #6 + f0: d874 bhi.n 1dc <main+0x13c> + f2: e8df f003 tbb [pc, r3] + f6: 5f61656c svcpl 0x0061656c + fa: 00040859 andeq r0, r4, r9, asr r8 + fe: 4640 mov r0, r8 + 100: f000 f8b7 bl 272 <system> + 104: e7dc b.n c0 <main+0x20> + 106: 4638 mov r0, r7 + 108: f240 4102 movw r1, #1026 ; 0x402 + 10c: 2200 movs r2, #0 + 10e: f000 f8a7 bl 260 <open> + 112: 4604 mov r4, r0 + 114: 2800 cmp r0, #0 + 116: d0d3 beq.n c0 <main+0x20> + 118: 220c movs r2, #12 + 11a: 2001 movs r0, #1 + 11c: 4651 mov r1, sl + 11e: f000 f8ab bl 278 <write> + 122: 2204 movs r2, #4 + 124: 4620 mov r0, r4 + 126: 4659 mov r1, fp + 128: f000 f8a6 bl 278 <write> + 12c: 2804 cmp r0, #4 + 12e: d070 beq.n 212 <main+0x172> + 130: 2100 movs r1, #0 + 132: 9101 str r1, [sp, #4] + 134: 2100 movs r1, #0 + 136: 460a mov r2, r1 + 138: 4620 mov r0, r4 + 13a: f000 f897 bl 26c <seek> + 13e: 4943 ldr r1, [pc, #268] ; (24c <main+0x1ac>) + 140: 2203 movs r2, #3 + 142: 4620 mov r0, r4 + 144: 4449 add r1, r9 + 146: f000 f897 bl 278 <write> + 14a: 2803 cmp r0, #3 + 14c: d06a beq.n 224 <main+0x184> + 14e: 2200 movs r2, #0 + 150: 4611 mov r1, r2 + 152: 4620 mov r0, r4 + 154: f000 f88a bl 26c <seek> + 158: 2264 movs r2, #100 ; 0x64 + 15a: 4620 mov r0, r4 + 15c: 4631 mov r1, r6 + 15e: f000 f88e bl 27e <read> + 162: 2804 cmp r0, #4 + 164: d04a beq.n 1fc <main+0x15c> + 166: 4620 mov r0, r4 + 168: f000 f87d bl 266 <close> + 16c: 4604 mov r4, r0 + 16e: 2800 cmp r0, #0 + 170: d1a6 bne.n c0 <main+0x20> + 172: 4937 ldr r1, [pc, #220] ; (250 <main+0x1b0>) + 174: 2001 movs r0, #1 + 176: 4449 add r1, r9 + 178: 2209 movs r2, #9 + 17a: f000 f87d bl 278 <write> + 17e: 9901 ldr r1, [sp, #4] + 180: f041 0304 orr.w r3, r1, #4 + 184: 2b07 cmp r3, #7 + 186: d19b bne.n c0 <main+0x20> + 188: eb09 0305 add.w r3, r9, r5 + 18c: 3354 adds r3, #84 ; 0x54 + 18e: 4622 mov r2, r4 + 190: f813 1f01 ldrb.w r1, [r3, #1]! + 194: 3201 adds r2, #1 + 196: 2900 cmp r1, #0 + 198: d1fa bne.n 190 <main+0xf0> + 19a: eb09 0105 add.w r1, r9, r5 + 19e: 3154 adds r1, #84 ; 0x54 + 1a0: 2001 movs r0, #1 + 1a2: f000 f869 bl 278 <write> + 1a6: e78b b.n c0 <main+0x20> + 1a8: f04f 4340 mov.w r3, #3221225472 ; 0xc0000000 + 1ac: 6818 ldr r0, [r3, #0] + 1ae: f000 f869 bl 284 <usleep> + 1b2: e785 b.n c0 <main+0x20> + 1b4: be00 bkpt 0x0000 + 1b6: e783 b.n c0 <main+0x20> + 1b8: 2000 movs r0, #0 + 1ba: b01c add sp, #112 ; 0x70 + 1bc: e8bd 8df0 ldmia.w sp!, {r4, r5, r6, r7, r8, sl, fp, pc} + 1c0: f644 3040 movw r0, #19264 ; 0x4b40 + 1c4: f2c0 004c movt r0, #76 ; 0x4c + 1c8: f000 f85c bl 284 <usleep> + 1cc: e778 b.n c0 <main+0x20> + 1ce: 2300 movs r3, #0 + 1d0: 200a movs r0, #10 + 1d2: fb90 f0f3 sdiv r0, r0, r3 + 1d6: f000 f855 bl 284 <usleep> + 1da: e771 b.n c0 <main+0x20> + 1dc: eb09 0305 add.w r3, r9, r5 + 1e0: 3370 adds r3, #112 ; 0x70 + 1e2: 2200 movs r2, #0 + 1e4: f813 1f01 ldrb.w r1, [r3, #1]! + 1e8: 3201 adds r2, #1 + 1ea: 2900 cmp r1, #0 + 1ec: d1fa bne.n 1e4 <main+0x144> + 1ee: eb09 0105 add.w r1, r9, r5 + 1f2: 3170 adds r1, #112 ; 0x70 + 1f4: 2001 movs r0, #1 + 1f6: f000 f83f bl 278 <write> + 1fa: e761 b.n c0 <main+0x20> + 1fc: 4915 ldr r1, [pc, #84] ; (254 <main+0x1b4>) + 1fe: 2001 movs r0, #1 + 200: 4449 add r1, r9 + 202: 2208 movs r2, #8 + 204: f000 f838 bl 278 <write> + 208: 9b01 ldr r3, [sp, #4] + 20a: f043 0302 orr.w r3, r3, #2 + 20e: 9301 str r3, [sp, #4] + 210: e7a9 b.n 166 <main+0xc6> + 212: 4911 ldr r1, [pc, #68] ; (258 <main+0x1b8>) + 214: 2001 movs r0, #1 + 216: 4449 add r1, r9 + 218: 2209 movs r2, #9 + 21a: f000 f82d bl 278 <write> + 21e: 2301 movs r3, #1 + 220: 9301 str r3, [sp, #4] + 222: e787 b.n 134 <main+0x94> + 224: 490c ldr r1, [pc, #48] ; (258 <main+0x1b8>) + 226: 2209 movs r2, #9 + 228: 2001 movs r0, #1 + 22a: 4449 add r1, r9 + 22c: f000 f824 bl 278 <write> + 230: 2201 movs r2, #1 + 232: 9201 str r2, [sp, #4] + 234: e78b b.n 14e <main+0xae> + 236: bf00 nop + 238: 00000108 andeq r0, r0, r8, lsl #2 + 23c: 000000bc strheq r0, [r0], -ip + 240: 000000c8 andeq r0, r0, r8, asr #1 + 244: 000000d8 ldrdeq r0, [r0], -r8 + 248: 00000038 andeq r0, r0, r8, lsr r0 + 24c: 000000ec andeq r0, r0, ip, ror #1 + 250: 000000fc strdeq r0, [r0], -ip + 254: 000000f0 strdeq r0, [r0], -r0 ; <UNPREDICTABLE> + 258: 000000e0 andeq r0, r0, r0, ror #1 + +0000025c <_exit>: +_exit(): + 25c: 2302 movs r3, #2 + 25e: df00 svc 0 + +00000260 <open>: +open(): + 260: 2306 movs r3, #6 + 262: df00 svc 0 + 264: 4770 bx lr + +00000266 <close>: +close(): + 266: 2307 movs r3, #7 + 268: df00 svc 0 + 26a: 4770 bx lr + +0000026c <seek>: +seek(): + 26c: 2308 movs r3, #8 + 26e: df00 svc 0 + 270: 4770 bx lr + +00000272 <system>: +system(): + 272: 2309 movs r3, #9 + 274: df00 svc 0 + 276: 4770 bx lr + +00000278 <write>: +write(): + 278: 2303 movs r3, #3 + 27a: df00 svc 0 + 27c: 4770 bx lr + +0000027e <read>: +read(): + 27e: 2304 movs r3, #4 + 280: df00 svc 0 + 282: 4770 bx lr + +00000284 <usleep>: +usleep(): + 284: 2305 movs r3, #5 + 286: df00 svc 0 + 288: 4770 bx lr + +Disassembly of section .got: + +10000000 <.got>: +10000000: 1000000c andne r0, r0, ip + ... + +Disassembly of section .dynamic: + +1000000c <.dynamic>: +1000000c: 00000015 andeq r0, r0, r5, lsl r0 + ... + +Disassembly of section .rodata: + +10000038 <str.2690>: +10000038: 74736554 ldrbtvc r6, [r3], #-1364 ; 0x554 +1000003c: 70706120 rsbsvc r6, r0, r0, lsr #2 +10000040: 6163696c cmnvs r3, ip, ror #18 +10000044: 6e6f6974 mcrvs 9, 3, r6, cr15, cr4, {3} +10000048: 3d300a3a vldmdbcc r0!, {s0-s57} +1000004c: 7a766964 bvc 11d9a5e4 <str2.2691+0x1d9a53c> +10000050: 0a6f7265 beq 11bdc9ec <str2.2691+0x1bdc944> +10000054: 6c733d31 ldclvs 13, cr3, [r3], #-196 ; 0xffffff3c +10000058: 20706565 rsbscs r6, r0, r5, ror #10 +1000005c: 320a7335 andcc r7, sl, #-738197504 ; 0xd4000000 +10000060: 6978653d ldmdbvs r8!, {r0, r2, r3, r4, r5, r8, sl, sp, lr}^ +10000064: 3d330a74 vldmdbcc r3!, {s0-s115} +10000068: 74706b62 ldrbtvc r6, [r0], #-2914 ; 0xb62 +1000006c: 643d340a ldrtvs r3, [sp], #-1034 ; 0x40a +10000070: 6c676e61 stclvs 14, cr6, [r7], #-388 ; 0xfffffe7c +10000074: 0a676e69 beq 119dba20 <str2.2691+0x19db978> +10000078: 706f3d35 rsbvc r3, pc, r5, lsr sp ; <UNPREDICTABLE> +1000007c: 360a6e65 strcc r6, [sl], -r5, ror #28 +10000080: 7379733d cmnvc r9, #-201326592 ; 0xf4000000 +10000084: 0a6d6574 beq 11b5965c <str2.2691+0x1b595b4> +10000088: 00000000 andeq r0, r0, r0 + +1000008c <okMsg.2692>: +1000008c: 72657645 rsbvc r7, r5, #72351744 ; 0x4500000 +10000090: 69687479 stmdbvs r8!, {r0, r3, r4, r5, r6, sl, ip, sp, lr}^ +10000094: 7327676e teqvc r7, #28835840 ; 0x1b80000 +10000098: 69687320 stmdbvs r8!, {r5, r8, r9, ip, sp, lr}^ +1000009c: 202c796e eorcs r7, ip, lr, ror #18 +100000a0: 27706143 ldrbcs r6, [r0, -r3, asr #2]! +100000a4: 00000a6e andeq r0, r0, lr, ror #20 + +100000a8 <str2.2691>: +100000a8: 78656e55 stmdavc r5!, {r0, r2, r4, r6, r9, sl, fp, sp, lr}^ +100000ac: 74636570 strbtvc r6, [r3], #-1392 ; 0x570 +100000b0: 63206465 teqvs r0, #1694498816 ; 0x65000000 +100000b4: 616d6d6f cmnvs sp, pc, ror #26 +100000b8: 000a646e andeq r6, sl, lr, ror #8 +100000bc: 7365742f cmnvc r5, #788529152 ; 0x2f000000 +100000c0: 78742e74 ldmdavc r4!, {r2, r4, r5, r6, r9, sl, fp, sp}^ +100000c4: 00000074 andeq r0, r0, r4, ror r0 +100000c8: 656c6946 strbvs r6, [ip, #-2374]! ; 0x946 +100000cc: 65706f20 ldrbvs r6, [r0, #-3872]! ; 0xf20 +100000d0: 0a64656e beq 11919690 <str2.2691+0x19195e8> +100000d4: 00000000 andeq r0, r0, r0 +100000d8: 6f616963 svcvs 0x00616963 +100000dc: 00000000 andeq r0, r0, r0 +100000e0: 74697257 strbtvc r7, [r9], #-599 ; 0x257 +100000e4: 6b6f2065 blvs 11bc8280 <str2.2691+0x1bc81d8> +100000e8: 0000000a andeq r0, r0, sl +100000ec: 00333231 eorseq r3, r3, r1, lsr r2 +100000f0: 64616552 strbtvs r6, [r1], #-1362 ; 0x552 +100000f4: 0a6b6f20 beq 11adbd7c <str2.2691+0x1adbcd4> +100000f8: 00000000 andeq r0, r0, r0 +100000fc: 736f6c43 cmnvc pc, #17152 ; 0x4300 +10000100: 6b6f2065 blvs 11bc829c <str2.2691+0x1bc81f4> +10000104: 0000000a andeq r0, r0, sl +10000108: 74736574 ldrbtvc r6, [r3], #-1396 ; 0x574 +1000010c: 00000000 andeq r0, r0, r0 diff --git a/app_template/prog3.h b/app_template/prog3.h index a7a34f4a..968bdcdb 100644 --- a/app_template/prog3.h +++ b/app_template/prog3.h @@ -4,39 +4,78 @@ const unsigned char __attribute__((aligned(8))) main_elf[] = { 0x99, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x05, 0x34, 0x00, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, - 0x98, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0xba, 0x00, 0x00, 0x00, - 0xba, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x58, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, - 0x00, 0x00, 0x00, 0x10, 0x7c, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, + 0x98, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0xf2, 0x01, 0x00, 0x00, + 0xf2, 0x01, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x90, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x10, 0x10, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x64, 0x01, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10, 0x0c, 0x00, 0x00, 0x10, + 0x9c, 0x02, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10, 0x0c, 0x00, 0x00, 0x10, 0x28, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x02, 0xf8, - 0x00, 0xf0, 0x4e, 0xf8, 0x2d, 0xe9, 0xf0, 0x45, 0x24, 0x4d, 0x9b, 0xb0, - 0x01, 0xae, 0x4d, 0x44, 0x4f, 0xf0, 0x00, 0x08, 0x4f, 0xf0, 0x40, 0x47, - 0x4f, 0xf0, 0x0a, 0x0a, 0x2b, 0x46, 0x00, 0x22, 0x13, 0xf8, 0x01, 0x4f, - 0x01, 0x32, 0x00, 0x2c, 0xfa, 0xd1, 0x01, 0x20, 0x29, 0x46, 0x00, 0xf0, - 0x39, 0xf8, 0x64, 0x22, 0x20, 0x46, 0x31, 0x46, 0x00, 0xf0, 0x37, 0xf8, - 0x00, 0x28, 0xed, 0xdd, 0x9d, 0xf8, 0x04, 0x30, 0x30, 0x3b, 0x04, 0x2b, - 0x1a, 0xd8, 0xdf, 0xe8, 0x03, 0xf0, 0x14, 0x0d, 0x09, 0x07, 0x03, 0x00, - 0x38, 0x68, 0x00, 0xf0, 0x2b, 0xf8, 0xdf, 0xe7, 0x00, 0xbe, 0xdd, 0xe7, - 0x00, 0x20, 0x1b, 0xb0, 0xbd, 0xe8, 0xf0, 0x85, 0x44, 0xf6, 0x40, 0x30, - 0xc0, 0xf2, 0x4c, 0x00, 0x00, 0xf0, 0x1e, 0xf8, 0xd2, 0xe7, 0x9a, 0xfb, - 0xf8, 0xf0, 0x00, 0xf0, 0x19, 0xf8, 0xcd, 0xe7, 0x05, 0xf1, 0x30, 0x03, - 0x00, 0x22, 0x13, 0xf8, 0x01, 0x1f, 0x01, 0x32, 0x00, 0x29, 0xfa, 0xd1, - 0x05, 0xf1, 0x30, 0x01, 0x01, 0x20, 0x00, 0xf0, 0x05, 0xf8, 0xbf, 0xe7, - 0x38, 0x00, 0x00, 0x00, 0x02, 0x23, 0x00, 0xdf, 0x03, 0x23, 0x00, 0xdf, + 0x00, 0xf0, 0xde, 0xf8, 0x2d, 0xe9, 0xf0, 0x4d, 0xdf, 0xf8, 0x90, 0x81, + 0x64, 0x4f, 0xdf, 0xf8, 0x94, 0xa1, 0xdf, 0xf8, 0x94, 0xb1, 0x9c, 0xb0, + 0x64, 0x4d, 0x03, 0xae, 0xc8, 0x44, 0x4f, 0x44, 0xca, 0x44, 0xcb, 0x44, + 0x09, 0xeb, 0x05, 0x03, 0x00, 0x22, 0x13, 0xf8, 0x01, 0x4f, 0x01, 0x32, + 0x00, 0x2c, 0xfa, 0xd1, 0x09, 0xeb, 0x05, 0x01, 0x01, 0x20, 0x00, 0xf0, + 0xcf, 0xf8, 0x64, 0x22, 0x20, 0x46, 0x31, 0x46, 0x00, 0xf0, 0xcd, 0xf8, + 0x00, 0x28, 0xeb, 0xdd, 0x9d, 0xf8, 0x0c, 0x30, 0x30, 0x3b, 0x06, 0x2b, + 0x74, 0xd8, 0xdf, 0xe8, 0x03, 0xf0, 0x6c, 0x65, 0x61, 0x5f, 0x59, 0x08, + 0x04, 0x00, 0x40, 0x46, 0x00, 0xf0, 0xb7, 0xf8, 0xdc, 0xe7, 0x38, 0x46, + 0x40, 0xf2, 0x02, 0x41, 0x00, 0x22, 0x00, 0xf0, 0xa7, 0xf8, 0x04, 0x46, + 0x00, 0x28, 0xd3, 0xd0, 0x0c, 0x22, 0x01, 0x20, 0x51, 0x46, 0x00, 0xf0, + 0xab, 0xf8, 0x04, 0x22, 0x20, 0x46, 0x59, 0x46, 0x00, 0xf0, 0xa6, 0xf8, + 0x04, 0x28, 0x70, 0xd0, 0x00, 0x21, 0x01, 0x91, 0x00, 0x21, 0x0a, 0x46, + 0x20, 0x46, 0x00, 0xf0, 0x97, 0xf8, 0x43, 0x49, 0x03, 0x22, 0x20, 0x46, + 0x49, 0x44, 0x00, 0xf0, 0x97, 0xf8, 0x03, 0x28, 0x6a, 0xd0, 0x00, 0x22, + 0x11, 0x46, 0x20, 0x46, 0x00, 0xf0, 0x8a, 0xf8, 0x64, 0x22, 0x20, 0x46, + 0x31, 0x46, 0x00, 0xf0, 0x8e, 0xf8, 0x04, 0x28, 0x4a, 0xd0, 0x20, 0x46, + 0x00, 0xf0, 0x7d, 0xf8, 0x04, 0x46, 0x00, 0x28, 0xa6, 0xd1, 0x37, 0x49, + 0x01, 0x20, 0x49, 0x44, 0x09, 0x22, 0x00, 0xf0, 0x7d, 0xf8, 0x01, 0x99, + 0x41, 0xf0, 0x04, 0x03, 0x07, 0x2b, 0x9b, 0xd1, 0x09, 0xeb, 0x05, 0x03, + 0x54, 0x33, 0x22, 0x46, 0x13, 0xf8, 0x01, 0x1f, 0x01, 0x32, 0x00, 0x29, + 0xfa, 0xd1, 0x09, 0xeb, 0x05, 0x01, 0x54, 0x31, 0x01, 0x20, 0x00, 0xf0, + 0x69, 0xf8, 0x8b, 0xe7, 0x4f, 0xf0, 0x40, 0x43, 0x18, 0x68, 0x00, 0xf0, + 0x69, 0xf8, 0x85, 0xe7, 0x00, 0xbe, 0x83, 0xe7, 0x00, 0x20, 0x1c, 0xb0, + 0xbd, 0xe8, 0xf0, 0x8d, 0x44, 0xf6, 0x40, 0x30, 0xc0, 0xf2, 0x4c, 0x00, + 0x00, 0xf0, 0x5c, 0xf8, 0x78, 0xe7, 0x00, 0x23, 0x0a, 0x20, 0x90, 0xfb, + 0xf3, 0xf0, 0x00, 0xf0, 0x55, 0xf8, 0x71, 0xe7, 0x09, 0xeb, 0x05, 0x03, + 0x70, 0x33, 0x00, 0x22, 0x13, 0xf8, 0x01, 0x1f, 0x01, 0x32, 0x00, 0x29, + 0xfa, 0xd1, 0x09, 0xeb, 0x05, 0x01, 0x70, 0x31, 0x01, 0x20, 0x00, 0xf0, + 0x3f, 0xf8, 0x61, 0xe7, 0x15, 0x49, 0x01, 0x20, 0x49, 0x44, 0x08, 0x22, + 0x00, 0xf0, 0x38, 0xf8, 0x01, 0x9b, 0x43, 0xf0, 0x02, 0x03, 0x01, 0x93, + 0xa9, 0xe7, 0x11, 0x49, 0x01, 0x20, 0x49, 0x44, 0x09, 0x22, 0x00, 0xf0, + 0x2d, 0xf8, 0x01, 0x23, 0x01, 0x93, 0x87, 0xe7, 0x0c, 0x49, 0x09, 0x22, + 0x01, 0x20, 0x49, 0x44, 0x00, 0xf0, 0x24, 0xf8, 0x01, 0x22, 0x01, 0x92, + 0x8b, 0xe7, 0x00, 0xbf, 0x08, 0x01, 0x00, 0x00, 0xbc, 0x00, 0x00, 0x00, + 0xc8, 0x00, 0x00, 0x00, 0xd8, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, + 0xec, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, + 0xe0, 0x00, 0x00, 0x00, 0x02, 0x23, 0x00, 0xdf, 0x06, 0x23, 0x00, 0xdf, + 0x70, 0x47, 0x07, 0x23, 0x00, 0xdf, 0x70, 0x47, 0x08, 0x23, 0x00, 0xdf, + 0x70, 0x47, 0x09, 0x23, 0x00, 0xdf, 0x70, 0x47, 0x03, 0x23, 0x00, 0xdf, 0x70, 0x47, 0x04, 0x23, 0x00, 0xdf, 0x70, 0x47, 0x05, 0x23, 0x00, 0xdf, 0x70, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x08, 0x00, 0x00, 0x4d, 0x69, 0x6f, 0x73, 0x69, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x30, 0x3d, 0x64, 0x69, 0x76, 0x7a, 0x65, 0x72, - 0x6f, 0x20, 0x31, 0x3d, 0x73, 0x6c, 0x65, 0x65, 0x70, 0x20, 0x35, 0x73, - 0x2c, 0x20, 0x32, 0x3d, 0x65, 0x78, 0x69, 0x74, 0x20, 0x33, 0x3d, 0x62, - 0x6b, 0x70, 0x74, 0x20, 0x34, 0x3d, 0x64, 0x61, 0x6e, 0x67, 0x6c, 0x69, - 0x6e, 0x67, 0x0a, 0x00, 0x55, 0x6e, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, - 0x65, 0x64, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x0a, 0x00 + 0x00, 0x00, 0x00, 0x00, 0x54, 0x65, 0x73, 0x74, 0x20, 0x61, 0x70, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x0a, 0x30, 0x3d, + 0x64, 0x69, 0x76, 0x7a, 0x65, 0x72, 0x6f, 0x0a, 0x31, 0x3d, 0x73, 0x6c, + 0x65, 0x65, 0x70, 0x20, 0x35, 0x73, 0x0a, 0x32, 0x3d, 0x65, 0x78, 0x69, + 0x74, 0x0a, 0x33, 0x3d, 0x62, 0x6b, 0x70, 0x74, 0x0a, 0x34, 0x3d, 0x64, + 0x61, 0x6e, 0x67, 0x6c, 0x69, 0x6e, 0x67, 0x0a, 0x35, 0x3d, 0x6f, 0x70, + 0x65, 0x6e, 0x0a, 0x36, 0x3d, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x45, 0x76, 0x65, 0x72, 0x79, 0x74, 0x68, 0x69, + 0x6e, 0x67, 0x27, 0x73, 0x20, 0x73, 0x68, 0x69, 0x6e, 0x79, 0x2c, 0x20, + 0x43, 0x61, 0x70, 0x27, 0x6e, 0x0a, 0x00, 0x00, 0x55, 0x6e, 0x65, 0x78, + 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x61, + 0x6e, 0x64, 0x0a, 0x00, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x74, 0x78, + 0x74, 0x00, 0x00, 0x00, 0x46, 0x69, 0x6c, 0x65, 0x20, 0x6f, 0x70, 0x65, + 0x6e, 0x65, 0x64, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x63, 0x69, 0x61, 0x6f, + 0x00, 0x00, 0x00, 0x00, 0x57, 0x72, 0x69, 0x74, 0x65, 0x20, 0x6f, 0x6b, + 0x0a, 0x00, 0x00, 0x00, 0x31, 0x32, 0x33, 0x00, 0x52, 0x65, 0x61, 0x64, + 0x20, 0x6f, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x43, 0x6c, 0x6f, 0x73, + 0x65, 0x20, 0x6f, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, + 0x00, 0x00, 0x00, 0x00 }; -unsigned int main_elf_len = 468; +unsigned int main_elf_len = 928; diff --git a/app_template_withlibs/main.map b/app_template_withlibs/main.map new file mode 100644 index 00000000..08ed19c2 --- /dev/null +++ b/app_template_withlibs/main.map @@ -0,0 +1,6 @@ +Archive member included because of file (symbol) + +/opt/arm-miosix-eabi/lib/gcc/arm-eabi/4.5.2/../../../../arm-eabi/lib/thumb/thumb2/libc.a(lib_a-printf.o) + main.o (printf) +/opt/arm-miosix-eabi/lib/gcc/arm-eabi/4.5.2/../../../../arm-eabi/lib/thumb/thumb2/libc.a(lib_a-vfprintf.o) + /opt/arm-miosix-eabi/lib/gcc/arm-eabi/4.5.2/../../../../arm-eabi/lib/thumb/thumb2/libc.a(lib_a-printf.o) (_vfprintf_r) diff --git a/chg.patch b/chg.patch new file mode 100644 index 00000000..d2a6d30b --- /dev/null +++ b/chg.patch @@ -0,0 +1,3313 @@ +diff --git a/Time results.txt b/Time results.txt +new file mode 100644 +index 0000000..e0d36a9 +--- /dev/null ++++ b/Time results.txt +@@ -0,0 +1,21 @@ ++OS cold boot 450us ++ ++Process with 32K of RAM ++swapout= 18.2ms (+/-0.5ms) ++swapin= 18.9ms ++ ++Process with 16K of RAM ++swapout= 9.5ms (+/-0.5ms) ++swapin= 10.2ms ++ ++Process with 8K of RAM ++swapout= 4.7ms (+/-0.5ms) ++swapin= 5.8ms ++ ++Process with 4K of RAM ++swapout= 2.5ms (+/-0.5ms) ++swapin= 3.6ms ++ ++Process with 2K of RAM ++swapout= 1.7ms (+/-0.5ms) ++swapin= 2.5ms +diff --git a/app_template_withlibs/Makefile b/app_template_withlibs/Makefile +deleted file mode 100644 +index 81a35d4..0000000 +--- a/app_template_withlibs/Makefile ++++ /dev/null +@@ -1,47 +0,0 @@ +-## +-## Makefile for writing PROGRAMS for the Miosix embedded OS +-## TFT:Terraneo Federico Technlogies +-## +- +-SRC := \ +-main.c \ +-syscallfuffa.c +- +-## Replaces both "foo.cpp"-->"foo.o" and "foo.c"-->"foo.o" +-OBJ := $(addsuffix .o, $(basename $(SRC))) +- +-AS := arm-miosix-eabi-as +-CC := arm-miosix-eabi-gcc +-CXX := arm-miosix-eabi-g++ +-SZ := arm-miosix-eabi-size +- +-AFLAGS := -mcpu=cortex-m3 -mthumb +-CFLAGS := -mcpu=cortex-m3 -mthumb -fpie -msingle-pic-base \ +- -ffunction-sections -O2 -Wall -c +-CXXFLAGS := $(CFLAGS) +-LFLAGS := -mcpu=cortex-m3 -mthumb -fpie -msingle-pic-base \ +- -Wl,--gc-sections,-Map,main.map,-T./miosix.ld,-n,-pie,--spare-dynamic-tags,3 \ +- -O2 -nostdlib +-# LFLAGS := -mcpu=cortex-m3 -mthumb -fpie -msingle-pic-base \ +-# -Wl,--gc-sections,-Map,main.map,-T./miosix.ld,-n,-pie,--spare-dynamic-tags,3 \ +-# -O2 -nostdlib +- +-LINK_LIBS := -Wl,--start-group -lstdc++ -lc -lm -lgcc -Wl,--end-group +- +-all: $(OBJ) crt0.o +- $(CXX) $(LFLAGS) -o main.elf $(OBJ) crt0.o $(LINK_LIBS) +- $(SZ) main.elf +- @mx-postlinker main.elf --ramsize=16384 --stacksize=2048 --strip-sectheader +- @xxd -i main.elf | sed 's/unsigned char/const unsigned char __attribute__((aligned(8)))/' > prog3.h +- +-clean: +- -rm $(OBJ) crt0.o main.elf main.map +- +-%.o: %.s +- $(AS) $(AFLAGS) $< -o $@ +- +-%.o : %.c +- $(CC) $(CFLAGS) $< -o $@ +- +-%.o : %.cpp +- $(CXX) $(CXXFLAGS) $< -o $@ +diff --git a/app_template_withlibs/crt0.s b/app_template_withlibs/crt0.s +deleted file mode 100644 +index 2eba4bf..0000000 +--- a/app_template_withlibs/crt0.s ++++ /dev/null +@@ -1,77 +0,0 @@ +-/* +- * Startup script for writing PROGRAMS for the Miosix embedded OS +- * TFT:Terraneo Federico Technlogies +- */ +- +-.syntax unified +-.cpu cortex-m3 +-.thumb +- +-.section .text +- +-/** +- * _start, program entry point +- */ +-.global _start +-.type _start, %function +-_start: +- /* TODO: .ctor */ +- bl main +- /* TODO: .dtor */ +- bl _exit +- +-/** +- * _exit, terminate process +- * \param v exit value +- */ +-.section .text._exit +-.global _exit +-.type _exit, %function +-_exit: +- movs r3, #2 +- svc 0 +- +-/** +- * write, write to file +- * \param fd file descriptor +- * \param buf data to be written +- * \param len buffer length +- * \return number of written bytes or -1 if errors +- */ +-.section .text.write +-.global write +-.type write, %function +-write: +- movs r3, #3 +- svc 0 +- bx lr +- +-/** +- * read, read from file +- * \param fd file descriptor +- * \param buf data to be read +- * \param len buffer length +- * \return number of read bytes or -1 if errors +- */ +-.section .text.read +-.global read +-.type read, %function +-read: +- movs r3, #4 +- svc 0 +- bx lr +- +-/** +- * usleep, sleep a specified number of microseconds +- * \param us number of microseconds to sleep +- * \return 0 on success or -1 if errors +- */ +-.section .text.usleep +-.global usleep +-.type usleep, %function +-usleep: +- movs r3, #5 +- svc 0 +- bx lr +- +-.end +diff --git a/app_template_withlibs/main.c b/app_template_withlibs/main.c +deleted file mode 100644 +index 57197b7..0000000 +--- a/app_template_withlibs/main.c ++++ /dev/null +@@ -1,39 +0,0 @@ +- +-#include <unistd.h> +-#include <string.h> +-#include <stdio.h> +- +-int main() +-{ +- printf("hello world %d\n",25); +- static const char str[]="0=divzero 1=sleep 5s, 2=exit 3=bkpt 4=dangling\n"; +- static const char str2[]="Unexpected command\n"; +- for(;;) +- { +- char result[100]; +- write(1,str,strlen(str)); +- int len=read(0,result,sizeof(result)); +- if(len<1) continue; +- int i=10/(int)(result[0]-'0'); +- unsigned int *p=(unsigned int *)0xc0000000; +- switch(result[0]) +- { +- case '0': +- usleep(i); +- break; +- case '1': +- usleep(5000000); +- break; +- case '2': +- return 0; +- case '3': +- asm volatile("bkpt"); +- break; +- case '4': +- usleep(*p); +- break; +- default: +- write(1,str2,strlen(str2)); +- } +- } +-} +diff --git a/app_template_withlibs/miosix.ld b/app_template_withlibs/miosix.ld +deleted file mode 100644 +index 0b86aaf..0000000 +--- a/app_template_withlibs/miosix.ld ++++ /dev/null +@@ -1,77 +0,0 @@ +-/* +- * Linker script for writing PROGRAMS for the Miosix embedded OS +- * TFT:Terraneo Federico Technlogies +- */ +- +-OUTPUT_FORMAT("elf32-littlearm") +-OUTPUT_ARCH(arm) +-ENTRY(_start) +- +-SECTIONS +-{ +- /* Here starts the first elf segment, that stays in flash */ +- . = 0 + SIZEOF_HEADERS; +- +- .text : ALIGN(8) +- { +- *(.text) +- *(.text.*) +- *(.gnu.linkonce.t.*) +- } +- +- .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) } +- .rel.got : { *(.rel.got) } +- +- __exidx_start = .; +- .ARM.exidx : +- { +- *(.ARM.exidx* .gnu.linkonce.armexidx.*) +- } +- __exidx_end = .; +- +- _end = .; +- PROVIDE(end = .); +- +- /* Here starts the second segment, that is copied in RAM and relocated */ +- . = 0x10000000; +- +- .got : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) } +- +- /* FIXME: If this is put in the other segment, it makes it writable */ +- .dynamic : { *(.dynamic) } +- +- /* FIXME: The compiler insists in addressing rodata relative to r9 */ +- .rodata : ALIGN(8) +- { +- *(.rodata) +- *(.rodata.*) +- *(.gnu.linkonce.r.*) +- } +- +- .data : ALIGN(8) +- { +- *(.data) +- *(.data.*) +- *(.gnu.linkonce.d.*) +- } +- +- .bss : ALIGN(8) +- { +- *(.bss) +- *(.bss.*) +- *(.gnu.linkonce.b.*) +- *(COMMON) +- } +- +- /* These are removed since are unused and increase binary size */ +- /DISCARD/ : +- { +- *(.interp) +- *(.dynsym) +- *(.dynstr) +- *(.hash) +- *(.comment) +- *(.ARM.attributes) +- *(.debug*) +- } +-} +diff --git a/app_template_withlibs/prog3.h b/app_template_withlibs/prog3.h +deleted file mode 100644 +index 8855c4f..0000000 +--- a/app_template_withlibs/prog3.h ++++ /dev/null +@@ -1,40 +0,0 @@ +-const unsigned char __attribute__((aligned(8))) main_elf[] = { +- 0x7f, 0x45, 0x4c, 0x46, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x00, +- 0x99, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x02, 0x00, 0x00, 0x05, 0x34, 0x00, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, +- 0x98, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x9e, 0x00, 0x00, 0x00, +- 0x9e, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, +- 0x01, 0x00, 0x00, 0x00, 0x38, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, +- 0x00, 0x00, 0x00, 0x10, 0x7c, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, +- 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, +- 0x44, 0x01, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10, 0x0c, 0x00, 0x00, 0x10, +- 0x28, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, +- 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x02, 0xf8, +- 0x00, 0xf0, 0x40, 0xf8, 0x70, 0xb5, 0x1d, 0x4e, 0x1d, 0x4c, 0x7e, 0x44, +- 0x9a, 0xb0, 0x7c, 0x44, 0x30, 0x36, 0x4f, 0xf0, 0x40, 0x45, 0x2f, 0x22, +- 0x21, 0x46, 0x01, 0x20, 0x00, 0xf0, 0x34, 0xf8, 0x64, 0x22, 0x00, 0x20, +- 0x01, 0xa9, 0x00, 0xf0, 0x32, 0xf8, 0x00, 0x28, 0xf3, 0xdd, 0x9d, 0xf8, +- 0x04, 0x30, 0x30, 0x3b, 0x04, 0x2b, 0x1b, 0xd8, 0xdf, 0xe8, 0x03, 0xf0, +- 0x13, 0x0c, 0x09, 0x07, 0x03, 0x00, 0x28, 0x68, 0x00, 0xf0, 0x26, 0xf8, +- 0xe5, 0xe7, 0x00, 0xbe, 0xe3, 0xe7, 0x00, 0x20, 0x1a, 0xb0, 0x70, 0xbd, +- 0x44, 0xf6, 0x40, 0x30, 0xc0, 0xf2, 0x4c, 0x00, 0x00, 0xf0, 0x1a, 0xf8, +- 0xd9, 0xe7, 0x00, 0x23, 0x0a, 0x20, 0x90, 0xfb, 0xf3, 0xf0, 0x00, 0xf0, +- 0x13, 0xf8, 0xd2, 0xe7, 0x01, 0x20, 0x31, 0x46, 0x13, 0x22, 0x00, 0xf0, +- 0x07, 0xf8, 0xcc, 0xe7, 0x8e, 0xff, 0xff, 0x0f, 0x8a, 0xff, 0xff, 0x0f, +- 0x02, 0x23, 0x00, 0xdf, 0x03, 0x23, 0x00, 0xdf, 0x70, 0x47, 0x04, 0x23, +- 0x00, 0xdf, 0x70, 0x47, 0x05, 0x23, 0x00, 0xdf, 0x70, 0x47, 0x00, 0x00, +- 0x0c, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, +- 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x08, 0x00, 0x00, +- 0x4d, 0x69, 0x6f, 0x73, 0x69, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x3d, 0x64, 0x69, +- 0x76, 0x7a, 0x65, 0x72, 0x6f, 0x20, 0x31, 0x3d, 0x73, 0x6c, 0x65, 0x65, +- 0x70, 0x20, 0x35, 0x73, 0x2c, 0x20, 0x32, 0x3d, 0x65, 0x78, 0x69, 0x74, +- 0x20, 0x33, 0x3d, 0x62, 0x6b, 0x70, 0x74, 0x20, 0x34, 0x3d, 0x64, 0x61, +- 0x6e, 0x67, 0x6c, 0x69, 0x6e, 0x67, 0x0a, 0x00, 0x55, 0x6e, 0x65, 0x78, +- 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x61, +- 0x6e, 0x64, 0x0a, 0x00 +-}; +-unsigned int main_elf_len = 436; +diff --git a/app_template_withlibs/syscallfuffa.c b/app_template_withlibs/syscallfuffa.c +deleted file mode 100644 +index 3c12251..0000000 +--- a/app_template_withlibs/syscallfuffa.c ++++ /dev/null +@@ -1,62 +0,0 @@ +- +-#include <stdio.h> +-#include <stdlib.h> +-#include <string.h> +-#include <reent.h> +-#include <sys/times.h> +-#include <sys/stat.h> +-#include <sys/fcntl.h> +-#include <unistd.h> +- +-void pthread_mutex_unlock() {} +-void pthread_mutex_lock() {} +-void pthread_mutex_destroy() {} +- +-int __register_exitproc(int type, void (*fn)(void), void *arg, void *d) { return 0; } +-void __call_exitprocs(int code, void *d) {} +- +-void *__dso_handle=(void*) &__dso_handle; +- +-void *_sbrk_r(struct _reent *ptr, ptrdiff_t incr) { return (void*)-1; } +-void __malloc_lock() {} +-void __malloc_unlock() {} +-int _open_r(struct _reent *ptr, const char *name, int flags, int mode) { return -1; } +-int _close_r(struct _reent *ptr, int fd) { return -1; } +- +-int _write(int fd, const void *buf, size_t cnt) +-{ +- return write(fd,buf,cnt); +-} +- +-int _write_r(struct _reent *ptr, int fd, const void *buf, size_t cnt) +-{ +- return write(fd,buf,cnt); +-} +- +-int _read(int fd, void *buf, size_t cnt) +-{ +- return read(fd,buf,cnt); +-} +- +-int _read_r(struct _reent *ptr, int fd, void *buf, size_t cnt) +-{ +- return read(fd,buf,cnt); +-} +- +-off_t _lseek(int fd, off_t pos, int whence) { return -1; } +-off_t _lseek_r(struct _reent *ptr, int fd, off_t pos, int whence) { return -1; } +-int _fstat(int fd, struct stat *pstat) { return -1; } +-int _fstat_r(struct _reent *ptr, int fd, struct stat *pstat) { return -1; } +-int _stat_r(struct _reent *ptr, const char *file, struct stat *pstat) { return -1; } +-int isatty(int fd) { return -1; } +-int _isatty(int fd) { return -1; } +-int mkdir(const char *path, mode_t mode) { return -1; } +-int _unlink_r(struct _reent *ptr, const char *file) { return -1; } +-clock_t _times_r(struct _reent *ptr, struct tms *tim) { return -1; } +-int _link_r(struct _reent *ptr, const char *f_old, const char *f_new) { return -1; } +-int _kill(int pid, int sig) { return -1; } +-int _kill_r(struct _reent* ptr, int pid, int sig) { return -1; } +-int _getpid() { return 1; } +-int _getpid_r(struct _reent* ptr) { return 1; } +-int _fork_r(struct _reent *ptr) { return -1; } +-int _wait_r(struct _reent *ptr, int *status) { return -1; } +diff --git a/fail.txt b/fail.txt +new file mode 100644 +index 0000000..d9887fa +--- /dev/null ++++ b/fail.txt +@@ -0,0 +1,37 @@ ++Miosix v1.60 (stm32f207ig_stm3220g-eval, Jul 12 2012 17:34:40, gcc 4.5.2) ++Starting Kernel... Ok ++Starting Filesystem... No disk ++Available heap 24576 out of 29868 Bytes ++tick=40 ++First boot ++ ++0=divzero 1=sleep 5s, 2=exit 3=bkpt 4=dangling ++1 ++0x200039b0 | 58 bf 00 20 00 00 00 00 38 80 00 20 7c bf 00 20 | X.......8...|... ++0x200039c0 | 00 00 00 c0 00 00 00 00 00 80 00 20 0a 00 00 00 | ................ ++0x200039d0 | bb bb bb bb | .... ++Swapping 1 processes ++save base=0x1c578 size=468 ++0x00000000 | 00 02 00 20 79 56 00 00 01 66 01 00 19 66 01 00 | ....yV...f...f.. ++0x00000010 | cd 66 01 00 31 68 01 00 09 69 01 00 00 00 00 00 | .f..1h...i...... ++0x00000020 | 00 00 00 00 | .... ++about to suspend, tick=2724 ++Miosix v1.60 (stm32f207ig_stm3220g-eval, Jul 12 2012 17:34:40, gcc 4.5.2) ++Starting Kernel... Ok ++Starting Filesystem... No disk ++Available heap 24576 out of 29868 Bytes ++tick=7764 ++RTC boot ++Reloading 1 processes ++reload base=0x1c578 size=468 ++0x4002407e | 00 02 00 20 79 56 00 00 01 66 01 00 19 66 01 00 | ....yV...f...f.. ++0x4002408e | cd 66 01 00 31 68 01 00 09 69 01 00 00 00 00 00 | .f..1h...i...... ++0x4002409e | 00 00 00 00 | .... ++Process 1 terminated due to a fault ++* Code base address was 0x1c578 ++* Data base address was 0x20008000 ++* MPU region 0 0x0-0x20000 r-x ++* MPU region 1 0x20008000-0x2000c000 rw- ++* Invalid data access (PC was 0x4030201) ++Process terminated ++Process segfaulted +diff --git a/main.cpp b/main.cpp +index 75f70ce..b991f7f 100644 +--- a/main.cpp ++++ b/main.cpp +@@ -2,8 +2,10 @@ + #include <cstdio> + #include <sys/wait.h> + #include <signal.h> ++#include <string.h> + #include "miosix.h" + #include "kernel/process.h" ++#include "interfaces/suspend_support.h" + #include "app_template/prog3.h" + + using namespace std; +@@ -23,6 +25,35 @@ void ledThread(void *) + int main() + { + Thread::create(ledThread,STACK_MIN); ++ SuspendManager::startHibernationDaemon(); ++ iprintf("tick=%llu\n",getTick()); ++ if(firstBoot()) ++ { ++ puts("First boot"); ++// //Watermarking ++// memset(getBackupSramBase(),0xff,getBackupSramSize()); ++// char *buf=new char[1024]; ++// memset(buf,0xff,1024); ++// Mram& mram=Mram::instance(); ++// mram.exitSleepMode(); ++// for(int i=0,j=0;i<mram.size()/1024;i++,j+=1024) ++// mram.write(j,buf,1024); ++// mram.enterSleepMode(); ++// delete[] buf; ++ } else { ++ puts("RTC boot"); ++ SuspendManager::resume(); ++ ++ int ec; ++ Process::wait(&ec); ++ iprintf("Process terminated\n"); ++ if(WIFEXITED(ec)) ++ { ++ iprintf("Exit code is %d\n",WEXITSTATUS(ec)); ++ } else if(WIFSIGNALED(ec)) { ++ if(WTERMSIG(ec)==SIGSEGV) iprintf("Process segfaulted\n"); ++ } ++ } + + ElfProgram prog(reinterpret_cast<const unsigned int*>(main_elf),main_elf_len); + for(int i=0;;i++) +diff --git a/miosix/Makefile b/miosix/Makefile +index e601cfc..483c893 100644 +--- a/miosix/Makefile ++++ b/miosix/Makefile +@@ -20,6 +20,7 @@ kernel/syscalls.cpp \ + kernel/elf_program.cpp \ + kernel/process.cpp \ + kernel/process_pool.cpp \ ++kernel/suspend_manager.cpp \ + kernel/scheduler/priority/priority_scheduler.cpp \ + kernel/scheduler/control/control_scheduler.cpp \ + kernel/scheduler/edf/edf_scheduler.cpp \ +diff --git a/miosix/arch/cortexM3_stm32f2/common/interfaces-impl/portability.cpp b/miosix/arch/cortexM3_stm32f2/common/interfaces-impl/portability.cpp +index 47fe617..c309f92 100644 +--- a/miosix/arch/cortexM3_stm32f2/common/interfaces-impl/portability.cpp ++++ b/miosix/arch/cortexM3_stm32f2/common/interfaces-impl/portability.cpp +@@ -29,6 +29,7 @@ + #include "interfaces/portability.h" + #include "kernel/kernel.h" + #include "kernel/error.h" ++#include "util/util.h" + #include "interfaces/bsp.h" + #include "kernel/scheduler/scheduler.h" + #include "kernel/scheduler/tick_interrupt.h" +@@ -263,27 +264,27 @@ MPUConfiguration::MPUConfiguration(unsigned int *elfBase, unsigned int elfSize, + regValues[1]=2<<MPU_RASR_AP_Pos + | MPU_RASR_C_Msk + | 1 //Enable bit +- | ((ffs(elfSize)-2)<<1); ++ | ((miosix::fhbs(elfSize)-2)<<1); + regValues[3]=3<<MPU_RASR_AP_Pos + | MPU_RASR_XN_Msk + | MPU_RASR_C_Msk + | MPU_RASR_S_Msk + | 1 //Enable bit +- | ((ffs(imageSize)-2)<<1); ++ | ((miosix::fhbs(imageSize)-2)<<1); + #else //__CODE_IN_XRAM + regValues[1]=2<<MPU_RASR_AP_Pos + | MPU_RASR_C_Msk + | MPU_RASR_B_Msk + | MPU_RASR_S_Msk + | 1 //Enable bit +- | ((ffs(elfSize)-2)<<1); ++ | ((miosix::fhbs(elfSize)-2)<<1); + regValues[3]=3<<MPU_RASR_AP_Pos + | MPU_RASR_XN_Msk + | MPU_RASR_C_Msk + | MPU_RASR_B_Msk + | MPU_RASR_S_Msk + | 1 //Enable bit +- | ((ffs(imageSize)-2)<<1); ++ | ((miosix::fhbs(imageSize)-2)<<1); + #endif //__CODE_IN_XRAM + } + +diff --git a/miosix/arch/cortexM3_stm32f2/common/interfaces-impl/suspend_support_impl.cpp b/miosix/arch/cortexM3_stm32f2/common/interfaces-impl/suspend_support_impl.cpp +new file mode 100644 +index 0000000..dda8f03 +--- /dev/null ++++ b/miosix/arch/cortexM3_stm32f2/common/interfaces-impl/suspend_support_impl.cpp +@@ -0,0 +1,115 @@ ++/*************************************************************************** ++ * Copyright (C) 2012 by Terraneo Federico and Luigi Rucco * ++ * * ++ * This program is free software; you can redistribute it and/or modify * ++ * it under the terms of the GNU General Public License as published by * ++ * the Free Software Foundation; either version 2 of the License, or * ++ * (at your option) any later version. * ++ * * ++ * This program is distributed in the hope that it will be useful, * ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of * ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * ++ * GNU General Public License for more details. * ++ * * ++ * As a special exception, if other files instantiate templates or use * ++ * macros or inline functions from this file, or you compile this file * ++ * and link it with other works to produce a work based on this file, * ++ * this file does not by itself cause the resulting work to be covered * ++ * by the GNU General Public License. However the source code for this * ++ * file must still be made available in accordance with the GNU General * ++ * Public License. This exception does not invalidate any other reasons * ++ * why a work based on this file might be covered by the GNU General * ++ * Public License. * ++ * * ++ * You should have received a copy of the GNU General Public License * ++ * along with this program; if not, see <http://www.gnu.org/licenses/> * ++ ***************************************************************************/ ++ ++#include <stdio.h> ++#include "interfaces/suspend_support.h" ++#include "kernel/process_pool.h" ++#include "miosix.h" ++#include "interfaces/arch_registers.h" ++ ++#ifdef WITH_HIBERNATION ++ ++namespace miosix { ++ ++void IRQinitializeSuspendSupport() ++{ ++ RCC->APB1ENR |= RCC_APB1ENR_PWREN; ++ PWR->CR |= PWR_CR_DBP; ++ PWR->CSR |= PWR_CSR_BRE; ++ while((PWR->CSR & PWR_CSR_BRR)==0) ; ++ RCC->AHB1ENR |= RCC_AHB1ENR_BKPSRAMEN; ++ ++ RCC->BDCR |= RCC_BDCR_LSEON; ++ while((RCC->BDCR & RCC_BDCR_LSERDY)==0) ; //wait ++ RCC->BDCR |= RCC_BDCR_RTCSEL_0 | RCC_BDCR_RTCEN; ++ RTC->WPR=0xca; ++ RTC->WPR=0x53; ++ ++ //FIXME: hack ++ if(firstBoot()==false) ++ { ++ long long tick=static_cast<long long>(getBackupSramBase()[1022])<<32 ++ | static_cast<long long>(getBackupSramBase()[1021]); ++ tick+=getBackupSramBase()[1023]*1000; ++ IRQsetTick(tick); ++ } ++} ++ ++void doSuspend(unsigned int seconds) ++{ ++ if(seconds==0) return; ++ if(seconds>31) seconds=31; ++ ++ while(Console::txComplete()==false) ; ++ ++ { ++ FastInterruptDisableLock dLock; ++ ++ RCC->CSR |= RCC_CSR_RMVF; //This makes firstBoot() return false next time ++ RTC->CR &= ~RTC_CR_WUTE; ++ while((RTC->ISR & RTC_ISR_WUTWF)==0) ; //Wait ++ RTC->WUTR=seconds*2048; //10s ++ RTC->CR |= RTC_CR_WUTE | RTC_CR_WUTIE; ++ ++ RTC->ISR= ~RTC_ISR_WUTF; ++ EXTI->EMR |= 1<<22; ++ EXTI->RTSR |= 1<<22; ++ ++ PWR->CR |= PWR_CR_PDDS | PWR_CR_CWUF; ++ SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; ++ //Using WFE instead of WFI because if while we are with interrupts ++ //disabled an interrupt (such as the tick interrupt) occurs, it ++ //remains pending and the WFI becomes a nop, and the device never goes ++ //in sleep mode. WFE events are latched in a separate pending register ++ //so interrupts do not interfere with them ++ __WFE(); ++ //Should never reach here ++ NVIC_SystemReset(); ++ } ++} ++ ++bool firstBoot() ++{ ++ static const unsigned int firstBootMask= ++ RCC_CSR_LPWRRSTF ++ | RCC_CSR_WWDGRSTF ++ | RCC_CSR_WDGRSTF ++ | RCC_CSR_SFTRSTF ++ | RCC_CSR_PORRSTF ++ | RCC_CSR_PADRSTF ++ | RCC_CSR_BORRSTF; ++ return (RCC->CSR & firstBootMask) ? true : false; ++} ++ ++int getAllocatorSramAreaSize() ++{ ++ return ProcessPool::instance().getSerializableSize(); ++} ++ ++} //namespace miosix ++ ++#endif //WITH_HIBERNATION +\ No newline at end of file +diff --git a/miosix/arch/cortexM3_stm32f2/common/interfaces-impl/suspend_support_impl.h b/miosix/arch/cortexM3_stm32f2/common/interfaces-impl/suspend_support_impl.h +new file mode 100644 +index 0000000..2783f1e +--- /dev/null ++++ b/miosix/arch/cortexM3_stm32f2/common/interfaces-impl/suspend_support_impl.h +@@ -0,0 +1,73 @@ ++/*************************************************************************** ++ * Copyright (C) 2012 by Terraneo Federico and Luigi Rucco * ++ * * ++ * This program is free software; you can redistribute it and/or modify * ++ * it under the terms of the GNU General Public License as published by * ++ * the Free Software Foundation; either version 2 of the License, or * ++ * (at your option) any later version. * ++ * * ++ * This program is distributed in the hope that it will be useful, * ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of * ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * ++ * GNU General Public License for more details. * ++ * * ++ * As a special exception, if other files instantiate templates or use * ++ * macros or inline functions from this file, or you compile this file * ++ * and link it with other works to produce a work based on this file, * ++ * this file does not by itself cause the resulting work to be covered * ++ * by the GNU General Public License. However the source code for this * ++ * file must still be made available in accordance with the GNU General * ++ * Public License. This exception does not invalidate any other reasons * ++ * why a work based on this file might be covered by the GNU General * ++ * Public License. * ++ * * ++ * You should have received a copy of the GNU General Public License * ++ * along with this program; if not, see <http://www.gnu.org/licenses/> * ++ ***************************************************************************/ ++ ++#ifndef SUSPEND_SUPPORT_IMPL_H ++#define SUSPEND_SUPPORT_IMPL_H ++ ++#ifdef WITH_HIBERNATION ++ ++#include "drivers/mram.h" ++ ++namespace miosix { ++ ++inline unsigned int *getBackupSramBase() ++{ ++ return reinterpret_cast<unsigned int*>(0x40024000); ++} ++ ++inline int getBackupSramSize() ++{ ++ return 4096; ++} ++ ++inline int getBackupAllocatorSramAreaSize() ++{ ++ return sizeof(unsigned int*)*4; ++} ++ ++inline int getProcessesSramAreaSize() ++{ ++ return 1024; ++} ++ ++inline int getRoutingTableSramAreaSize() ++{ ++ return 1024; ++} ++ ++inline int getSmartDriversQueueSramAreaSize() ++{ ++ return getBackupSramSize()- ++ getAllocatorSramAreaSize() - ++ getProcessesSramAreaSize() - ++ getSmartDriversQueueSramAreaSize(); ++} ++ ++} //namespace miosix ++ ++#endif //WITH_HIBERNATION ++#endif //SUSPEND_SUPPORT_IMPL_H +diff --git a/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/drivers/mram.cpp b/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/drivers/mram.cpp +new file mode 100644 +index 0000000..ff7fa91 +--- /dev/null ++++ b/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/drivers/mram.cpp +@@ -0,0 +1,340 @@ ++/*************************************************************************** ++ * Copyright (C) 2012 by Terraneo Federico * ++ * * ++ * This program is free software; you can redistribute it and/or modify * ++ * it under the terms of the GNU General Public License as published by * ++ * the Free Software Foundation; either version 2 of the License, or * ++ * (at your option) any later version. * ++ * * ++ * This program is distributed in the hope that it will be useful, * ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of * ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * ++ * GNU General Public License for more details. * ++ * * ++ * As a special exception, if other files instantiate templates or use * ++ * macros or inline functions from this file, or you compile this file * ++ * and link it with other works to produce a work based on this file, * ++ * this file does not by itself cause the resulting work to be covered * ++ * by the GNU General Public License. However the source code for this * ++ * file must still be made available in accordance with the GNU General * ++ * Public License. This exception does not invalidate any other reasons * ++ * why a work based on this file might be covered by the GNU General * ++ * Public License. * ++ * * ++ * You should have received a copy of the GNU General Public License * ++ * along with this program; if not, see <http://www.gnu.org/licenses/> * ++ ***************************************************************************/ ++ ++#include "mram.h" ++#include <miosix.h> ++#include <kernel/scheduler/scheduler.h> ++#include <interfaces/delays.h> ++ ++using namespace miosix; ++ ++//Gpio mapping ++typedef Gpio<GPIOI_BASE,2> miso; ++typedef Gpio<GPIOI_BASE,3> mosi; ++typedef Gpio<GPIOI_BASE,1> sck; ++typedef Gpio<GPIOI_BASE,0> cs; ++ ++/** ++ * DMA RX end of transfer ++ */ ++void __attribute__((naked)) DMA1_Stream3_IRQHandler() ++{ ++ saveContext(); ++ asm volatile("bl _Z20SPI2rxDmaHandlerImplv"); ++ restoreContext(); ++} ++ ++/** ++ * DMA TX end of transfer ++ */ ++void __attribute__((naked)) DMA1_Stream4_IRQHandler() ++{ ++ saveContext(); ++ asm volatile("bl _Z20SPI2txDmaHandlerImplv"); ++ restoreContext(); ++} ++ ++static Thread *waiting; ++static bool error; ++ ++/** ++ * DMA RX end of transfer actual implementation ++ */ ++void __attribute__((used)) SPI2rxDmaHandlerImpl() ++{ ++ if(DMA1->LISR & (DMA_LISR_TEIF3 | DMA_LISR_DMEIF3)) error=true; ++ DMA1->LIFCR=DMA_LIFCR_CTCIF3 ++ | DMA_LIFCR_CTEIF3 ++ | DMA_LIFCR_CDMEIF3; ++ waiting->IRQwakeup(); ++ if(waiting->IRQgetPriority()>Thread::IRQgetCurrentThread()->IRQgetPriority()) ++ Scheduler::IRQfindNextThread(); ++ waiting=0; ++} ++ ++/** ++ * DMA TX end of transfer actual implementation ++ */ ++void __attribute__((used)) SPI2txDmaHandlerImpl() ++{ ++ if(DMA1->HISR & (DMA_HISR_TEIF4 | DMA_HISR_DMEIF4)) error=true; ++ DMA1->HIFCR=DMA_HIFCR_CTCIF4 ++ | DMA_HIFCR_CTEIF4 ++ | DMA_HIFCR_CDMEIF4; ++ waiting->IRQwakeup(); ++ if(waiting->IRQgetPriority()>Thread::IRQgetCurrentThread()->IRQgetPriority()) ++ Scheduler::IRQfindNextThread(); ++ waiting=0; ++} ++ ++/** ++ * Transfer a byte through SPI2 where the mram is connected ++ * \param data byte to send ++ * \return byte received ++ */ ++static unsigned char spi2sendRecv(unsigned char data=0) ++{ ++ SPI2->DR=data; ++ while((SPI2->SR & SPI_SR_RXNE)==0) ; ++ return SPI2->DR; ++} ++ ++// ++// class Mram ++// ++ ++Mram& Mram::instance() ++{ ++ static Mram singleton; ++ return singleton; ++} ++ ++unsigned int Mram::size() const { return 128*1024; } ++ ++bool Mram::write(unsigned int addr, const void *data, int size) ++{ ++ // Write time, with CPU @ 120MHz and SPI2 @ 15MHz, is ++ // 2 us fixed time (mutex locking) ++ // 3.5 us fixed time (sending the address an peripheral register setup) ++ // 0.533us per byte transferred in DMA mode ++ // 4.5 us fixed time (context switch and peripheral register cleanup) ++ // 2 us fixed time (mutex unlock) ++ ++ if(addr>=this->size() || addr+size>this->size()) return false; ++ pthread_mutex_lock(&mutex); ++ if(sleepMode) { pthread_mutex_unlock(&mutex); return false; } ++ cs::low(); ++ spi2sendRecv(0x02); //Write command ++ spi2sendRecv((addr>>16) & 0xff); ++ spi2sendRecv((addr>>8) & 0xff); ++ spi2sendRecv(addr & 0xff); ++ ++ //DMA1 stream 4 channel 0 = SPI2_TX ++ ++ error=false; ++ ++ //Wait until the SPI is busy, required otherwise the last byte is not ++ //fully sent ++ while((SPI2->SR & SPI_SR_TXE)==0) ; ++ while(SPI2->SR & SPI_SR_BSY) ; ++ SPI2->CR1=0; ++ SPI2->CR2=SPI_CR2_TXDMAEN; ++ SPI2->CR1=SPI_CR1_SSM ++ | SPI_CR1_SSI ++ | SPI_CR1_MSTR ++ | SPI_CR1_SPE; ++ ++ waiting=Thread::getCurrentThread(); ++ NVIC_ClearPendingIRQ(DMA1_Stream4_IRQn); ++ NVIC_SetPriority(DMA1_Stream4_IRQn,10);//Low priority for DMA ++ NVIC_EnableIRQ(DMA1_Stream4_IRQn); ++ ++ DMA1_Stream4->CR=0; ++ DMA1_Stream4->PAR=reinterpret_cast<unsigned int>(&SPI2->DR); ++ DMA1_Stream4->M0AR=reinterpret_cast<unsigned int>(data); ++ DMA1_Stream4->NDTR=size; ++ DMA1_Stream4->CR=DMA_SxCR_PL_1 //High priority because fifo disabled ++ | DMA_SxCR_MINC //Increment memory pointer ++ | DMA_SxCR_DIR_0 //Memory to peripheral ++ | DMA_SxCR_TCIE //Interrupt on transfer complete ++ | DMA_SxCR_TEIE //Interrupt on transfer error ++ | DMA_SxCR_DMEIE //Interrupt on direct mode error ++ | DMA_SxCR_EN; //Start DMA ++ ++ { ++ FastInterruptDisableLock dLock; ++ while(waiting!=0) ++ { ++ waiting->IRQwait(); ++ { ++ FastInterruptEnableLock eLock(dLock); ++ Thread::yield(); ++ } ++ } ++ } ++ ++ NVIC_DisableIRQ(DMA1_Stream4_IRQn); ++ ++ //Wait for last byte to be sent ++ while((SPI2->SR & SPI_SR_TXE)==0) ; ++ while(SPI2->SR & SPI_SR_BSY) ; ++ SPI2->CR1=0; ++ SPI2->CR2=0; ++ SPI2->CR1=SPI_CR1_SSM ++ | SPI_CR1_SSI ++ | SPI_CR1_MSTR ++ | SPI_CR1_SPE; ++ ++ //Quirk: reset RXNE by reading DR, or a byte remains in the input buffer ++ volatile short temp=SPI1->DR; ++ (void)temp; ++ ++ cs::high(); ++ bool result=!error; ++ pthread_mutex_unlock(&mutex); ++ return result; ++} ++ ++bool Mram::read(unsigned int addr, void *data, int size) ++{ ++ // Read time, with CPU @ 120MHz and SPI2 @ 15MHz, is ++ // 2 us fixed time (mutex locking) ++ // 3.5 us fixed time (sending the address an peripheral register setup) ++ // 0.533us per byte transferred in DMA mode ++ // 4.5 us fixed time (context switch and peripheral register cleanup) ++ // 2 us fixed time (mutex unlock) ++ if(addr>=this->size() || addr+size>this->size()) return false; ++ pthread_mutex_lock(&mutex); ++ if(sleepMode) { pthread_mutex_unlock(&mutex); return false; } ++ cs::low(); ++ spi2sendRecv(0x03); //Read command ++ spi2sendRecv((addr>>16) & 0xff); ++ spi2sendRecv((addr>>8) & 0xff); ++ spi2sendRecv(addr & 0xff); ++ ++ //DMA1 stream 3 channel 0 = SPI2_RX ++ ++ error=false; ++ ++ //Wait until the SPI is busy, required otherwise the last byte is not ++ //fully sent ++ while((SPI2->SR & SPI_SR_TXE)==0) ; ++ while(SPI2->SR & SPI_SR_BSY) ; ++ //Quirk: reset RXNE by reading DR before starting the DMA, or the first ++ //byte in the DMA buffer is garbage ++ volatile short temp=SPI2->DR; ++ (void)temp; ++ SPI2->CR1=0; ++ SPI2->CR2=SPI_CR2_RXDMAEN; ++ ++ waiting=Thread::getCurrentThread(); ++ NVIC_ClearPendingIRQ(DMA1_Stream3_IRQn); ++ NVIC_SetPriority(DMA1_Stream3_IRQn,10);//Low priority for DMA ++ NVIC_EnableIRQ(DMA1_Stream3_IRQn); ++ ++ DMA1_Stream3->CR=0; ++ DMA1_Stream3->PAR=reinterpret_cast<unsigned int>(&SPI2->DR); ++ DMA1_Stream3->M0AR=reinterpret_cast<unsigned int>(data); ++ DMA1_Stream3->NDTR=size; ++ DMA1_Stream3->CR=DMA_SxCR_PL_1 //High priority because fifo disabled ++ | DMA_SxCR_MINC //Increment memory pointer ++ | DMA_SxCR_TCIE //Interrupt on transfer complete ++ | DMA_SxCR_TEIE //Interrupt on transfer error ++ | DMA_SxCR_DMEIE //Interrupt on direct mode error ++ | DMA_SxCR_EN; //Start DMA ++ ++ //Quirk: start the SPI in RXONLY mode only *after* the DMA has been ++ //setup or the SPI doesn't wait for the DMA and the first bytes are lost ++ SPI2->CR1=SPI_CR1_RXONLY ++ | SPI_CR1_SSM ++ | SPI_CR1_SSI ++ | SPI_CR1_MSTR ++ | SPI_CR1_SPE; ++ ++ { ++ FastInterruptDisableLock dLock; ++ while(waiting!=0) ++ { ++ waiting->IRQwait(); ++ { ++ FastInterruptEnableLock eLock(dLock); ++ Thread::yield(); ++ } ++ } ++ } ++ ++ NVIC_DisableIRQ(DMA1_Stream3_IRQn); ++ SPI2->CR1=0; ++ ++ //Quirk, disabling the SPI in RXONLY mode is difficult ++ while(SPI2->SR & SPI_SR_RXNE) temp=SPI2->DR; ++ delayUs(1); //The last transfer may still be in progress ++ while(SPI2->SR & SPI_SR_RXNE) temp=SPI2->DR; ++ ++ SPI2->CR2=0; ++ SPI2->CR1=SPI_CR1_SSM ++ | SPI_CR1_SSI ++ | SPI_CR1_MSTR ++ | SPI_CR1_SPE; ++ ++ cs::high(); ++ bool result=!error; ++ pthread_mutex_unlock(&mutex); ++ return result; ++} ++ ++void Mram::exitSleepMode() ++{ ++ pthread_mutex_lock(&mutex); ++ cs::low(); ++ spi2sendRecv(0xab); //Exit sleep mode command ++ cs::high(); ++ Thread::sleep(1); //It needs at least 400us to go out of sleep mode ++ cs::low(); ++ spi2sendRecv(0x06); //Write enable command ++ cs::high(); ++ sleepMode=false; ++ pthread_mutex_unlock(&mutex); ++} ++ ++void Mram::enterSleepMode() ++{ ++ pthread_mutex_lock(&mutex); ++ cs::low(); ++ spi2sendRecv(0x04); //Write disable command ++ cs::high(); ++ for(int i=0;i<5;i++) __NOP(); //To meet 40ns CS high time between commands ++ cs::low(); ++ spi2sendRecv(0xb9); //Entr sleep mode command ++ cs::high(); ++ delayUs(3); //It needs at least 3us to enter sleep mode ++ sleepMode=true; ++ pthread_mutex_unlock(&mutex); ++} ++ ++Mram::Mram() : sleepMode(true) ++{ ++ pthread_mutex_init(&mutex,0); ++ { ++ FastInterruptDisableLock dLock; ++ mosi::mode(Mode::ALTERNATE); ++ mosi::alternateFunction(5); ++ miso::mode(Mode::ALTERNATE); ++ miso::alternateFunction(5); ++ sck::mode(Mode::ALTERNATE); ++ sck::alternateFunction(5); ++ cs::mode(Mode::OUTPUT); ++ cs::high(); ++ RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN; ++ RCC->APB1ENR |= RCC_APB1ENR_SPI2EN; ++ SPI2->CR2=0; ++ SPI2->CR1=SPI_CR1_SSM //Software cs ++ | SPI_CR1_SSI //Hardware cs internally tied high ++ | SPI_CR1_MSTR //Master mode ++ | SPI_CR1_SPE; //SPI enabled ++ } ++} +diff --git a/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/drivers/mram.h b/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/drivers/mram.h +new file mode 100644 +index 0000000..34f2c95 +--- /dev/null ++++ b/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/drivers/mram.h +@@ -0,0 +1,95 @@ ++/*************************************************************************** ++ * Copyright (C) 2012 by Terraneo Federico * ++ * * ++ * This program is free software; you can redistribute it and/or modify * ++ * it under the terms of the GNU General Public License as published by * ++ * the Free Software Foundation; either version 2 of the License, or * ++ * (at your option) any later version. * ++ * * ++ * This program is distributed in the hope that it will be useful, * ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of * ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * ++ * GNU General Public License for more details. * ++ * * ++ * As a special exception, if other files instantiate templates or use * ++ * macros or inline functions from this file, or you compile this file * ++ * and link it with other works to produce a work based on this file, * ++ * this file does not by itself cause the resulting work to be covered * ++ * by the GNU General Public License. However the source code for this * ++ * file must still be made available in accordance with the GNU General * ++ * Public License. This exception does not invalidate any other reasons * ++ * why a work based on this file might be covered by the GNU General * ++ * Public License. * ++ * * ++ * You should have received a copy of the GNU General Public License * ++ * along with this program; if not, see <http://www.gnu.org/licenses/> * ++ ***************************************************************************/ ++ ++#include <pthread.h> ++ ++#ifndef MRAM_H ++#define MRAM_H ++ ++/** ++ * Class to access the mram memory ++ */ ++class Mram ++{ ++public: ++ /** ++ * Singleton ++ * \return an instance of the Mram class ++ */ ++ static Mram& instance(); ++ ++ /** ++ * \return the MRAM's size in bytes ++ */ ++ unsigned int size() const; ++ ++ /** ++ * Write a block of data into the mram ++ * \param addr start address into the mram where the data block will be ++ * written ++ * \param data data block ++ * \param size data block size ++ * \return true on success, false on failure ++ */ ++ bool write(unsigned int addr, const void *data, int size); ++ ++ /** ++ * Read a block of data from the mram ++ * \param addr start address into the mram where the data block will be read ++ * \param data data block ++ * \param size data block size ++ * \return true on success, false on failure ++ */ ++ bool read(unsigned int addr, void *data, int size); ++ ++ /** ++ * This member function needs to be called before accessing the mram ++ */ ++ void exitSleepMode(); ++ ++ /** ++ * This member function can be called after performing operations on the ++ * mram to put it back in sleep mode ++ */ ++ void enterSleepMode(); ++ ++ /** ++ * \return true if the mram is in sleep mode ++ */ ++ bool isSleeping() const { return sleepMode; } ++ ++private: ++ Mram(); ++ ++ Mram(const Mram&); ++ Mram& operator= (const Mram&); ++ ++ pthread_mutex_t mutex; ///Mutex to protect concurrent access to the hardware ++ bool sleepMode; ++}; ++ ++#endif //MRAM_H +diff --git a/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/interfaces-impl/bsp.cpp b/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/interfaces-impl/bsp.cpp +index 0950086..cd41faa 100644 +--- a/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/interfaces-impl/bsp.cpp ++++ b/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/interfaces-impl/bsp.cpp +@@ -45,6 +45,7 @@ + #include "config/miosix_settings.h" + #include "kernel/logging.h" + #include "console-impl.h" ++#include "interfaces/suspend_support.h" + + namespace miosix { + +@@ -77,6 +78,10 @@ void IRQbspInit() + #ifndef STDOUT_REDIRECTED_TO_DCC + IRQstm32f2serialPortInit(); + #endif //STDOUT_REDIRECTED_TO_DCC ++ ++ #ifdef WITH_HIBERNATION ++ IRQinitializeSuspendSupport(); ++ #endif //WITH_HIBERNATION + } + + void bspInit2() +diff --git a/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/stm32_1m+128k_rom_processes.ld b/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/stm32_1m+128k_rom_processes.ld +new file mode 100644 +index 0000000..6dc5b31 +--- /dev/null ++++ b/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/stm32_1m+128k_rom_processes.ld +@@ -0,0 +1,170 @@ ++/* ++ * C++ enabled linker script for stm32 (1M FLASH, 128K RAM) ++ * Developed by TFT: Terraneo Federico Technologies ++ * Optimized for use with the Miosix kernel ++ */ ++ ++/* ++ * This linker script puts: ++ * - read only data and code (.text, .rodata, .eh_*) in flash ++ * - stacks, heap and sections .data and .bss in the first 32KB of the internal ram ++ * - leaves the rest of the RAM (upper 96KB) is used as the process pool for ++ * allocating processes. ++ * - the external ram (if available) is not used. ++ */ ++ ++/* ++ * The main stack is used for interrupt handling by the kernel. ++ * ++ * *** Readme *** ++ * This linker script places the main stack (used by the kernel for interrupts) ++ * at the bottom of the ram, instead of the top. This is done for two reasons: ++ * ++ * - as an optimization for microcontrollers with little ram memory. In fact ++ * the implementation of malloc from newlib requests memory to the OS in 4KB ++ * block (except the first block that can be smaller). This is probably done ++ * for compatibility with OSes with an MMU and paged memory. To see why this ++ * is bad, consider a microcontroller with 8KB of ram: when malloc finishes ++ * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will ++ * fail because the top part of the ram is used by the main stack. As a ++ * result, the top part of the memory will not be used by malloc, even if ++ * available (and it is nearly *half* the ram on an 8KB mcu). By placing the ++ * main stack at the bottom of the ram, the upper 4KB block will be entirely ++ * free and available as heap space. ++ * ++ * - In case of main stack overflow the cpu will fault because access to memory ++ * before the beginning of the ram faults. Instead with the default stack ++ * placement the main stack will silently collide with the heap. ++ * Note: if increasing the main stack size also increase the ORIGIN value in ++ * the MEMORY definitions below accordingly. ++ */ ++_main_stack_size = 0x00000200; /* main stack = 512Bytes */ ++_main_stack_top = 0x20000000 + _main_stack_size; ++ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); ++ ++/* end of the heap (32KB) */ ++_heap_end = 0x20008000; /* end of available ram */ ++_process_pool_start = _heap_end; /* from 32KB to 128KB */ ++_process_pool_end = 0x20020000; ++ ++/* identify the Entry Point */ ++ENTRY(_Z13Reset_Handlerv) ++ ++/* specify the memory areas */ ++MEMORY ++{ ++ flash(rx) : ORIGIN = 0, LENGTH = 1M ++ ++ /* ++ * Note, the ram starts at 0x20000000 but it is necessary to add the size ++ * of the main stack, so it is 0x20000200. ++ */ ++ ram(wx) : ORIGIN = 0x20000200, LENGTH = 32K-0x200 ++} ++ ++/* now define the output sections */ ++SECTIONS ++{ ++ . = 0; ++ ++ /* .text section: code goes to flash */ ++ .text : ++ { ++ /* Startup code must go at address 0 */ ++ KEEP(*(.isr_vector)) ++ ++ *(.text) ++ *(.text.*) ++ *(.gnu.linkonce.t.*) ++ /* these sections for thumb interwork? */ ++ *(.glue_7) ++ *(.glue_7t) ++ /* these sections for C++? */ ++ *(.gcc_except_table) ++ *(.gcc_except_table.*) ++ *(.ARM.extab*) ++ *(.gnu.linkonce.armextab.*) ++ ++ . = ALIGN(4); ++ /* .rodata: constant data */ ++ *(.rodata) ++ *(.rodata.*) ++ *(.gnu.linkonce.r.*) ++ ++ /* C++ Static constructors/destructors (eabi) */ ++ . = ALIGN(4); ++ KEEP(*(.init)) ++ ++ . = ALIGN(4); ++ __preinit_array_start = .; ++ KEEP (*(.preinit_array)) ++ __preinit_array_end = .; ++ ++ . = ALIGN(4); ++ __init_array_start = .; ++ KEEP (*(SORT(.init_array.*))) ++ KEEP (*(.init_array)) ++ __init_array_end = .; ++ ++ . = ALIGN(4); ++ KEEP(*(.fini)) ++ ++ . = ALIGN(4); ++ __fini_array_start = .; ++ KEEP (*(.fini_array)) ++ KEEP (*(SORT(.fini_array.*))) ++ __fini_array_end = .; ++ ++ /* C++ Static constructors/destructors (elf) */ ++ . = ALIGN(4); ++ _ctor_start = .; ++ KEEP (*crtbegin.o(.ctors)) ++ KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) ++ KEEP (*(SORT(.ctors.*))) ++ KEEP (*crtend.o(.ctors)) ++ _ctor_end = .; ++ ++ . = ALIGN(4); ++ KEEP (*crtbegin.o(.dtors)) ++ KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) ++ KEEP (*(SORT(.dtors.*))) ++ KEEP (*crtend.o(.dtors)) ++ } > flash ++ ++ /* .ARM.exidx is sorted, so has to go in its own output section. */ ++ __exidx_start = .; ++ .ARM.exidx : ++ { ++ *(.ARM.exidx* .gnu.linkonce.armexidx.*) ++ } > flash ++ __exidx_end = .; ++ ++ . = ALIGN(8); ++ _etext = .; ++ ++ /* .data section: global variables go to ram, but also store a copy to ++ flash to initialize them */ ++ .data : ALIGN(8) ++ { ++ _data = .; ++ *(.data) ++ *(.data.*) ++ *(.gnu.linkonce.d.*) ++ . = ALIGN(8); ++ _edata = .; ++ } > ram AT > flash ++ ++ /* .bss section: uninitialized global variables go to ram */ ++ _bss_start = .; ++ .bss : ++ { ++ *(.bss) ++ *(.bss.*) ++ *(.gnu.linkonce.b.*) ++ . = ALIGN(8); ++ } > ram ++ _bss_end = .; ++ ++ _end = .; ++ PROVIDE(end = .); ++} +diff --git a/miosix/config/Makefile.inc b/miosix/config/Makefile.inc +index 940be46..5e8a726 100644 +--- a/miosix/config/Makefile.inc ++++ b/miosix/config/Makefile.inc +@@ -28,8 +28,8 @@ OPT_BOARD := stm32f207ig_stm3220g-eval + ## -O2 is recomended otherwise, as it provides a good balance between code + ## size and speed + ## +-OPT_OPTIMIZATION := -O0 +-#OPT_OPTIMIZATION := -O2 ++#OPT_OPTIMIZATION := -O0 ++OPT_OPTIMIZATION := -O2 + #OPT_OPTIMIZATION := -O3 + #OPT_OPTIMIZATION := -Os + +@@ -167,7 +167,8 @@ ifeq ($(OPT_BOARD),stm32f207ig_stm3220g-eval) + #LINKER_SCRIPT := $(LINKER_SCRIPT_PATH)stm32_1m+128k_rom.ld + #LINKER_SCRIPT := $(LINKER_SCRIPT_PATH)stm32_1m+128k_xram.ld + #LINKER_SCRIPT := $(LINKER_SCRIPT_PATH)stm32_1m+128k_all_in_xram.ld +- LINKER_SCRIPT := $(LINKER_SCRIPT_PATH)stm32_1m+128k_all_in_xram_processes.ld ++ LINKER_SCRIPT := $(LINKER_SCRIPT_PATH)stm32_1m+128k_rom_processes.ld ++ #LINKER_SCRIPT := $(LINKER_SCRIPT_PATH)stm32_1m+128k_all_in_xram_processes.ld + + ## Enable/disable initialization of external RAM at boot. Three options: + ## __ENABLE_XRAM : If you want the heap in xram (with an appropriate linker +@@ -177,7 +178,7 @@ ifeq ($(OPT_BOARD),stm32f207ig_stm3220g-eval) + ## none selected : don't use xram (with an appropriate linker script + ## selected above) + #XRAM := -D__ENABLE_XRAM +- XRAM := -D__ENABLE_XRAM -D__CODE_IN_XRAM ++ #XRAM := -D__ENABLE_XRAM -D__CODE_IN_XRAM + + endif + +@@ -665,11 +666,13 @@ else ifeq ($(ARCH),cortexM3_stm32f2) + + ## Select architecture specific files + ## These are the files in arch/<arch name>/<board name> +- ARCH_SRC := \ +- $(ARCH_INC)/interfaces-impl/disk.cpp \ +- $(BOARD_INC)/interfaces-impl/console.cpp \ +- $(BOARD_INC)/interfaces-impl/delays.cpp \ +- $(BOARD_INC)/interfaces-impl/bsp.cpp ++ ARCH_SRC := \ ++ $(ARCH_INC)/interfaces-impl/disk.cpp \ ++ $(BOARD_INC)/interfaces-impl/console.cpp \ ++ $(BOARD_INC)/interfaces-impl/delays.cpp \ ++ $(ARCH_INC)/interfaces-impl/suspend_support_impl.cpp \ ++ $(BOARD_INC)/interfaces-impl/bsp.cpp \ ++ $(BOARD_INC)/drivers/mram.cpp + + ## Add a #define to allow querying board name + CFLAGS_BASE += -D_BOARD_STM3220G_EVAL +diff --git a/miosix/config/miosix_settings.h b/miosix/config/miosix_settings.h +index e0952f6..648c3c4 100644 +--- a/miosix/config/miosix_settings.h ++++ b/miosix/config/miosix_settings.h +@@ -68,10 +68,19 @@ namespace miosix { + /// call service and, if the hardware supports it, the MPU to provide memory + /// isolation of processes + #define WITH_PROCESSES ++ ++/// \def WITH_HIBERNATION ++/// Enable process hibernation, allowing to save the state of processes and ++/// put the system in low power mode ++#define WITH_HIBERNATION + + #if defined(WITH_PROCESSES) && defined(__NO_EXCEPTIONS) + #error Processes require C++ exception support + #endif //defined(WITH_PROCESSES) && defined(__NO_EXCEPTIONS) ++ ++#if defined(WITH_HIBERNATION) && !defined(WITH_PROCESSES) ++#error Hibernation requires processes ++#endif //defined(WITH_HIBERNATION) && !defined(WITH_PROCESSES) + + // + // Filesystem options +@@ -93,6 +102,9 @@ namespace miosix { + /// Maximum number of open files. Trying to open more will fail. + const unsigned char MAX_OPEN_FILES=8; + ++/// Maximum number of threads a process can spawn ++const unsigned char MAX_THREADS_PER_PROCESS=2; ++ + // + // C/C++ standard library I/O (stdin, stdout and stderr related) + // +diff --git a/miosix/doc/textdoc/Changelog.txt b/miosix/doc/textdoc/Changelog.txt +index 0965bd7..e04e3ab 100644 +--- a/miosix/doc/textdoc/Changelog.txt ++++ b/miosix/doc/textdoc/Changelog.txt +@@ -1,7 +1,6 @@ + Changelog for Miosix np embedded OS + + v1.60 +-- Fixed a bug in FastMutex::get(): the member function was unimplemented. + - Fixed a bug in ST code for the stm3220g-eval board: despite having a 2MB RAM, + A18, A19 and A20 were left as GPIOs, resulting in issues when accessing the + upper part of the RAM. +diff --git a/miosix/interfaces/portability.h b/miosix/interfaces/portability.h +index 6d30928..89feb7b 100644 +--- a/miosix/interfaces/portability.h ++++ b/miosix/interfaces/portability.h +@@ -261,11 +261,29 @@ class MPUConfiguration + * Print the MPU configuration for debugging purposes + */ + void dumpConfiguration(); +- ++ ++ /** ++ * \return the number of registers ++ */ ++ int getNumRegisters() ++ { ++ return numRegisters; ++ } ++ ++ /** ++ * \return the pointer to the register array, used to configure the MPU ++ */ ++ unsigned int* getRegValuesPtr() ++ { ++ return regValues; ++ } ++ ++ static const int numRegisters=4; ++ + //Uses default copy constructor and operator= + private: + ///These value are copied into the MPU registers to configure them +- unsigned int regValues[4]; ++ unsigned int regValues[numRegisters]; + }; + + #endif //WITH_PROCESSES +diff --git a/miosix/interfaces/suspend_support.h b/miosix/interfaces/suspend_support.h +new file mode 100644 +index 0000000..96d69cd +--- /dev/null ++++ b/miosix/interfaces/suspend_support.h +@@ -0,0 +1,101 @@ ++/*************************************************************************** ++ * Copyright (C) 2012 by Terraneo Federico and Luigi Rucco * ++ * * ++ * This program is free software; you can redistribute it and/or modify * ++ * it under the terms of the GNU General Public License as published by * ++ * the Free Software Foundation; either version 2 of the License, or * ++ * (at your option) any later version. * ++ * * ++ * This program is distributed in the hope that it will be useful, * ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of * ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * ++ * GNU General Public License for more details. * ++ * * ++ * As a special exception, if other files instantiate templates or use * ++ * macros or inline functions from this file, or you compile this file * ++ * and link it with other works to produce a work based on this file, * ++ * this file does not by itself cause the resulting work to be covered * ++ * by the GNU General Public License. However the source code for this * ++ * file must still be made available in accordance with the GNU General * ++ * Public License. This exception does not invalidate any other reasons * ++ * why a work based on this file might be covered by the GNU General * ++ * Public License. * ++ * * ++ * You should have received a copy of the GNU General Public License * ++ * along with this program; if not, see <http://www.gnu.org/licenses/> * ++ ***************************************************************************/ ++#ifndef SUSPEND_SUPPORT_H ++#define SUSPEND_SUPPORT_H ++ ++#include "config/miosix_settings.h" ++ ++#ifdef WITH_HIBERNATION ++ ++namespace miosix { ++ ++/** ++ * \return a pointer to the beginning of the backup SRAM area, that preserves ++ * its content through hibernation ++ */ ++inline unsigned int *getBackupSramBase(); ++ ++/** ++ * \return the size of the backup SRAM ++ */ ++inline int getBackupSramSize(); ++ ++/** ++ * Needs to be called from IRQbspInit() if hibernation support is enabled. ++ * None of the functions in this haeder can be called prior to this, as they ++ * might access uninitialized resources ++ */ ++void IRQinitializeSuspendSupport(); ++ ++/** ++ * Enter hibernation mode for the specified number of seconds ++ * \param seconds after how much time the system will reboot ++ */ ++void doSuspend(unsigned int seconds); ++ ++/** ++ * \return true if this is the first boot, i.e. a boot caused by a reset ++ * assertion or power on. If returns false, this is a boot caused by an RTC ++ * wakeup, and in this case swapped processes need to be reloaded. ++ */ ++bool firstBoot(); ++ ++/** ++ * \return size of the backup SRAM for the allocator status ++ * ++ */ ++int getAllocatorSramAreaSize(); ++ ++/** ++ * \return size of the backup SRAM for the backup allocator status ++ * this includes four pointers, i.e. the base pointers to the four ++ * region of the backup memory ++ */ ++inline int getBackupAllocatorSramAreaSize(); ++ ++/** ++ * \return size of the backup SRAM for the Processes status serialization ++ */ ++inline int getProcessesSramAreaSize(); ++ ++/** ++ * \return size of the backup SRAM for network topology information ++ */ ++inline int getRoutingTableSramAreaSize(); ++ ++/** ++ * \return size of the backup SRAM for the queue of the smart drivers ++ */ ++inline int getSmartDriversQueueSramAreaSize(); ++ ++} //namespace miosix ++ ++// This contains the macros and the implementation of inline functions ++#include "interfaces-impl/suspend_support_impl.h" ++ ++#endif //WITH_HIBERNATION ++#endif //SUSPEND_SUPPORT_H +diff --git a/miosix/kernel/elf_program.cpp b/miosix/kernel/elf_program.cpp +index bab4dea..98edc3f 100644 +--- a/miosix/kernel/elf_program.cpp ++++ b/miosix/kernel/elf_program.cpp +@@ -30,6 +30,9 @@ + #include <stdexcept> + #include <cstring> + #include <cstdio> ++#ifdef WITH_HIBERNATION ++#include "interfaces/suspend_support.h" ++#endif + + using namespace std; + +@@ -142,9 +145,9 @@ bool ElfProgram::validateHeader() + bool ElfProgram::validateDynamicSegment(const Elf32_Phdr *dynamic, + unsigned int dataSegmentSize) + { +- unsigned int base=getElfBase(); ++ const unsigned int base=reinterpret_cast<unsigned int>(getElfBase()); + const Elf32_Dyn *dyn= +- reinterpret_cast<const Elf32_Dyn*>(getElfBase()+dynamic->p_offset); ++ reinterpret_cast<const Elf32_Dyn*>(base+dynamic->p_offset); + const int dynSize=dynamic->p_memsz/sizeof(Elf32_Dyn); + Elf32_Addr dtRel=0; + Elf32_Word dtRelsz=0; +@@ -235,7 +238,7 @@ bool ElfProgram::validateDynamicSegment(const Elf32_Phdr *dynamic, + void ProcessImage::load(const ElfProgram& program) + { + if(image) ProcessPool::instance().deallocate(image); +- const unsigned int base=program.getElfBase(); ++ const unsigned int base=reinterpret_cast<unsigned int>(program.getElfBase()); + const Elf32_Phdr *phdr=program.getProgramHeaderTable(); + const Elf32_Phdr *dataSegment=0; + Elf32_Addr dtRel=0; +@@ -311,6 +314,22 @@ void ProcessImage::load(const ElfProgram& program) + } + } + ++#ifdef WITH_HIBERNATION ++void ProcessImage::resume(ProcessStatus* status) ++{ ++ image=status->processImageBase; ++ size=status->processImageSize; ++ //TODO: optimize ++ Mram& mram=Mram::instance(); ++ mram.exitSleepMode(); ++ //reload the image from MRAM to the main RAM ++ mram.read(reinterpret_cast<unsigned int>(image)- ++ ProcessPool::instance().getBaseAddress(), ++ image,size); ++ mram.enterSleepMode(); ++} ++#endif //WITH_HIBERNATION ++ + ProcessImage::~ProcessImage() + { + if(image) ProcessPool::instance().deallocate(image); +diff --git a/miosix/kernel/elf_program.h b/miosix/kernel/elf_program.h +index 5d5abed..08b09f3 100644 +--- a/miosix/kernel/elf_program.h ++++ b/miosix/kernel/elf_program.h +@@ -31,6 +31,7 @@ + #include <utility> + #include "elf_types.h" + #include "config/miosix_settings.h" ++#include "suspend_manager.h" + + #ifdef WITH_PROCESSES + +@@ -88,11 +89,11 @@ public: + } + + /** +- * \return a number representing the elf base address in memory ++ * \return the elf base address in memory + */ +- unsigned int getElfBase() const ++ const unsigned int *getElfBase() const + { +- return reinterpret_cast<unsigned int>(elf); ++ return elf; + } + + /** +@@ -143,6 +144,15 @@ public: + */ + void load(const ElfProgram& program); + ++ #ifdef WITH_HIBERNATION ++ /** ++ * Resume the image of a process in RAM after and hibernation ++ * including copying .data, zeroing .bss and performing ++ * relocations ++ */ ++ void resume(ProcessStatus* status); ++ #endif //WITH_HIBERNATION ++ + /** + * \return a pointer to the base of the program image + */ +diff --git a/miosix/kernel/kernel.cpp b/miosix/kernel/kernel.cpp +index 8bae046..0d7f8d5 100644 +--- a/miosix/kernel/kernel.cpp ++++ b/miosix/kernel/kernel.cpp +@@ -34,6 +34,7 @@ + #include "sync.h" + #include "process.h" + #include "kernel/scheduler/scheduler.h" ++#include "arch/cortexM4_stm32f4/common/arch_settings.h" + #include <stdexcept> + #include <algorithm> + #include <string.h> +@@ -215,6 +216,13 @@ long long getTick() + } + } + ++#ifdef WITH_HIBERNATION ++void IRQsetTick(long long newTick) ++{ ++ tick=newTick; ++} ++#endif //WITH_HIBERNATION ++ + /** + * \internal + * Used by Thread::sleep() to add a thread to sleeping list. The list is sorted +@@ -738,6 +746,18 @@ void Thread::setupUserspaceContext(unsigned int entry, unsigned int *gotBase, + miosix_private::initCtxsave(cur->userCtxsave,startfunc,ep,0,gotBase); + } + ++#ifdef WITH_HIBERNATION ++void Thread::serializeUserspaceContext(unsigned int registers[CTXSAVE_SIZE]) ++{ ++ memcpy(registers,this->userCtxsave,CTXSAVE_SIZE*sizeof(unsigned int)); ++} ++ ++void Thread::resumeUserspaceContext(unsigned int registers[CTXSAVE_SIZE]) ++{ ++ memcpy(cur->userCtxsave,registers,CTXSAVE_SIZE*sizeof(unsigned int)); ++} ++#endif //WITH_HIBERNATION ++ + #endif //WITH_PROCESSES + + Thread::~Thread() +diff --git a/miosix/kernel/kernel.h b/miosix/kernel/kernel.h +index c2abb0d..3128a37 100644 +--- a/miosix/kernel/kernel.h ++++ b/miosix/kernel/kernel.h +@@ -386,6 +386,16 @@ bool isKernelRunning(); + */ + long long getTick(); + ++#ifdef WITH_HIBERNATION ++/** ++ * \internal ++ * Used when resuming from hibernation to make sure the absolute time does not ++ * restart from zero. Note that calling this function everywhere but in ++ * IRQbspInit will result in undefined behaviour ++ */ ++void IRQsetTick(long long newTick); ++#endif //WITH_HIBERNATION ++ + //Declaration of the struct, definition follows below + struct SleepData; + +@@ -871,7 +881,7 @@ private: + }; + + #ifdef WITH_PROCESSES +- ++ + /** + * \internal + * Causes a thread belonging to a process to switch to userspace, and +@@ -903,6 +913,24 @@ private: + static void setupUserspaceContext(unsigned int entry, unsigned int *gotBase, + unsigned int ramImageSize); + ++ #ifdef WITH_HIBERNATION ++ ++ /** ++ * Serialize the userspace registers of a thread.Can only be called on ++ * a thread that is not running in userpsace ++ * \param registers are the saved registers during hibernation ++ */ ++ void serializeUserspaceContext(unsigned int registers[CTXSAVE_SIZE]); ++ ++ /** ++ * Resume the userspace context of the thread, so that it can be later ++ * switched to userspace. Must be called only once for each thread instance ++ * \param registers are the saved registers during hibernation ++ */ ++ static void resumeUserspaceContext(unsigned int registers[CTXSAVE_SIZE]); ++ ++ #endif //WITH_HIBERNATION ++ + #endif //WITH_PROCESSES + + /** +diff --git a/miosix/kernel/process.cpp b/miosix/kernel/process.cpp +index 9ac56c2..06d7e55 100644 +--- a/miosix/kernel/process.cpp ++++ b/miosix/kernel/process.cpp +@@ -31,6 +31,7 @@ + #include <cstring> + #include <sys/wait.h> + #include <signal.h> ++#include "suspend_manager.h" + #include "sync.h" + #include "process_pool.h" + #include "process.h" +@@ -74,6 +75,7 @@ namespace miosix { + + pid_t Process::create(const ElfProgram& program) + { ++ Lock<Mutex> l(SuspendManager::suspMutex); + auto_ptr<Process> proc(new Process(program)); + { + Lock<Mutex> l(procMutex); +@@ -105,12 +107,134 @@ pid_t Process::create(const ElfProgram& program) + //thread has already been created but there's no memory to list it + //among the threads of a process + proc->threads.push_back(thr); ++ proc->numActiveThreads++; + thr->wakeup(); //Actually start the thread, now that everything is set up + pid_t result=proc->pid; + proc.release(); //Do not delete the pointer + return result; + } + ++pid_t Process::create(ProcessStatus* status, int threadId) ++{ ++ Lock<Mutex> l(SuspendManager::suspMutex); ++ map<pid_t,Process*>::iterator findProc; ++ findProc=processes.find(status->pid); ++ ++ if(findProc==processes.end()) ++ throw runtime_error("Unable to recreate the process after hibernation"); ++ Process* proc=findProc->second; ++ ++ proc->image.resume(status); ++ ++ //TODO: look at it -- begin ++ #ifndef __CODE_IN_XRAM ++ //FIXME -- begin ++ //Till a flash file system that ensures proper alignment of the programs ++ //loaded in flash is implemented, make the whole flash visible as a big MPU ++ //region ++ extern unsigned int _etext asm("_etext"); ++ unsigned int flashEnd=reinterpret_cast<unsigned int>(&_etext); ++ if(flashEnd & (flashEnd-1)) flashEnd=1<<fhbs(flashEnd); ++ proc->mpu=miosix_private::MPUConfiguration(0,flashEnd, ++ proc->image.getProcessBasePointer(),proc->image.getProcessImageSize()); ++// mpu=miosix_private::MPUConfiguration(program.getElfBase(),roundedSize, ++// image.getProcessBasePointer(),image.getProcessImageSize()); ++ //FIXME -- end ++ #else //__CODE_IN_XRAM ++ loadedProgram=ProcessPool::instance().allocate(roundedSize); ++ memcpy(loadedProgram,program.getElfBase(),elfSize); ++ mpu=miosix_private::MPUConfiguration(loadedProgram,roundedSize, ++ image.getProcessBasePointer(),image.getProcessImageSize()); ++ #endif //__CODE_IN_XRAM ++ //TODO: look at it -- end ++ ++ ++ Thread *thr=Thread::createUserspace(Process::start, ++ status->interruptionPoints[threadId].registers, ++ Thread::DEFAULT,proc); ++ proc->toBeSwappedOut=true; ++ ++ if(thr==0) ++ { ++ Lock<Mutex> l(procMutex); ++ processes.erase(proc->pid); ++ if(Thread::getCurrentThread()->proc!=0) ++ { ++ Thread::getCurrentThread()->proc->childs.remove(proc); ++ } else kernelChilds.remove(proc); ++ delete proc; ++ throw runtime_error("Thread recreation failed"); ++ } ++ //Cannot throw bad_alloc due to the reserve in Process's constructor. ++ //This ensures we will never be in the uncomfortable situation where a ++ //thread has already been created but there's no memory to list it ++ //among the threads of a process ++ proc->threads.push_back(thr); ++ proc->numActiveThreads++; ++ thr->wakeup(); //Actually start the thread, now that everything is set up ++ pid_t result=proc->pid; ++ return result; ++} ++ ++pid_t Process::resume(const ElfProgram& program, ProcessStatus* status) ++{ ++ auto_ptr<Process> proc(new Process(program,true)); ++ //in this block we set the number of ++ { ++ Lock<Mutex> l(SuspendManager::suspMutex); ++ proc->suspended=true; ++ SuspendManager::suspendedProcesses.push_back(proc.get()); ++ } ++ proc->pid=status->pid; ++ proc->ppid=status->ppid; ++ if(status->status & 1) proc->zombie=true; ++ else proc->zombie=false; ++ proc->exitCode=status->exitCode; ++ proc->toBeSwappedOut=false; ++ ++ map<pid_t,Process*>::iterator findProc; ++ { ++ Lock<Mutex> l(procMutex); ++ if(proc->ppid!=0) ++ { ++ findProc=processes.find(proc->ppid); ++ //now we check if the parent is resumed and eventually become part ++ //of its childs list ++ if(findProc!=processes.end()) ++ { ++ if(proc->zombie==false) ++ { ++ findProc->second->childs.push_back(proc.get()); ++ } else { ++ findProc->second->zombies.push_back(proc.get()); ++ } ++ } ++ } else { ++ kernelChilds.push_back(proc.get()); ++ } ++ ++ //since there is not a sequential resume schedule, we need to check if ++ //we are parent of children already resumed and eventually add them to ++ //the parent childs list. The following "for" cycle pursues this goal ++ for(findProc=processes.begin(); findProc!=processes.end(); findProc++) ++ { ++ if(findProc->second->ppid==proc->pid) ++ { ++ if(findProc->second->zombie==false) ++ proc->childs.push_back(findProc->second); ++ else ++ proc->zombies.push_back(findProc->second); ++ ++ } ++ } ++ ++ processes[proc->pid]=proc.get(); ++ } ++ ++ proc.release(); //Do not delete the pointer ++ return proc->pid; ++} ++ + pid_t Process::getppid(pid_t proc) + { + Lock<Mutex> l(procMutex); +@@ -220,35 +344,97 @@ pid_t Process::waitpid(pid_t pid, int* exit, int options) + } + } + ++void Process::serialize(ProcessStatus* ptr) ++{ ++ ptr->pid=this->pid; ++ ptr->ppid=this->ppid; ++ ptr->processImageBase = this->image.getProcessBasePointer(); ++ ptr->processImageSize = this->image.getProcessImageSize(); ++ memcpy(ptr->fileDescriptors,this->fileTable,MAX_OPEN_FILES*sizeof(int)); ++ #ifndef __CODE_IN_XRAM ++ ptr->programBase=this->program->getElfBase(); ++ ptr->programSize=this->program->getElfSize(); ++ iprintf("save base=%p size=%d\n",ptr->programBase,ptr->programSize); ++ #else //__CODE_IN_XRAM ++ ptr->programBase=this->loadedProgram; ++ ptr->programBase=reinterpret_cast<unsigned int*>(this->roundedSize); ++ #endif //__CODE_IN_XRAM ++ ++ ptr->exitCode=this->exitCode; ++ ptr->numThreads=this->threads.size(); ++ ++ if(this->zombie) ++ ptr->status=1; ++ else ++ ptr->status=0; ++ ++ //in this cycle the interruptionPoint structure is serialized ++ for(unsigned int i=0;i<this->threads.size();i++) ++ { ++ list<SyscallResumeTime>::iterator it; ++ for(it=SuspendManager::syscallReturnTime.begin(); ++ it!=SuspendManager::syscallReturnTime.end(); ++ it++) ++ { ++ if(this->pid==it->pid && i==it->threadNum) ++ { ++ ptr->interruptionPoints[i].absSyscallTime=it->resumeTime; ++ ptr->interruptionPoints[i].intPointID=it->intPointID; ++ ptr->interruptionPoints[i].fileID=it->fileID; ++ ptr->interruptionPoints[i].wakeNow=0; ++ //FIXME: the following two will become similar to those commented ++ ptr->interruptionPoints[i].backupQueue=NULL; ++ ptr->interruptionPoints[i].queueSize=0; ++ //ptr->interruptionPoints[i].backupQueue=getBackupQueueBase(this->pid, i); ++ //ptr->interruptionPoints[i].queueSize=getBackupQueueSize(this->pid, i); ++ ptr->interruptionPoints[i].targetSampleMem= ++ reinterpret_cast<unsigned int*>(this->sampleBuf); ++ ptr->interruptionPoints[i].sizeOfSample=this->sizeOfSample; ++ ptr->interruptionPoints[i].sampNum=0; //must be filled by smart driver ++ this->threads[i]->serializeUserspaceContext( ++ ptr->interruptionPoints[i].registers); ++ } ++ } ++ } ++ ++} ++ ++ + Process::~Process() + { ++ if(program) ++ delete program; + #ifdef __CODE_IN_XRAM + ProcessPool::instance().deallocate(loadedProgram); + #endif //__CODE_IN_XRAM + } + +-Process::Process(const ElfProgram& program) : program(program), waitCount(0), +- zombie(false) ++ ++Process::Process(const ElfProgram& program, bool resuming) ++ : numActiveThreads(0), waitCount(0), zombie(false), suspended(false), ++ toBeSwappedOut(true) + { ++ this->program=new ElfProgram(program); + //This is required so that bad_alloc can never be thrown when the first + //thread of the process will be stored in this vector + threads.reserve(1); +- //Done here so if not enough memory the new process is not even created +- image.load(program); + unsigned int elfSize=program.getElfSize(); +- unsigned int roundedSize=elfSize; ++ roundedSize=elfSize; + //Allocatable blocks must be greater than ProcessPool::blockSize, and must + //be a power of two due to MPU limitations + if(elfSize<ProcessPool::blockSize) roundedSize=ProcessPool::blockSize; +- else if(elfSize & (elfSize-1)) roundedSize=1<<ffs(elfSize); ++ else if(elfSize & (elfSize-1)) roundedSize=1<<fhbs(elfSize); ++ if(resuming) return; ++ //Done here so if not enough memory the new process is not even created ++ image.load(program); + #ifndef __CODE_IN_XRAM + //FIXME -- begin + //Till a flash file system that ensures proper alignment of the programs + //loaded in flash is implemented, make the whole flash visible as a big MPU + //region +- extern unsigned char _end asm("_end"); +- unsigned int flashEnd=reinterpret_cast<unsigned int>(&_end); +- if(flashEnd & (flashEnd-1)) flashEnd=1<<ffs(flashEnd); ++ extern unsigned int _etext asm("_etext"); ++ unsigned int flashEnd=reinterpret_cast<unsigned int>(&_etext); ++ if(flashEnd & (flashEnd-1)) flashEnd=1<<fhbs(flashEnd); + mpu=miosix_private::MPUConfiguration(0,flashEnd, + image.getProcessBasePointer(),image.getProcessImageSize()); + // mpu=miosix_private::MPUConfiguration(program.getElfBase(),roundedSize, +@@ -256,23 +442,40 @@ Process::Process(const ElfProgram& program) : program(program), waitCount(0), + //FIXME -- end + #else //__CODE_IN_XRAM + loadedProgram=ProcessPool::instance().allocate(roundedSize); +- memcpy(loadedProgram,reinterpret_cast<char*>(program.getElfBase()),elfSize); ++ memcpy(loadedProgram,program.getElfBase(),elfSize); + mpu=miosix_private::MPUConfiguration(loadedProgram,roundedSize, + image.getProcessBasePointer(),image.getProcessImageSize()); + #endif //__CODE_IN_XRAM + } + ++ ++ + void *Process::start(void *argv) + { + Process *proc=Thread::getCurrentThread()->proc; + if(proc==0) errorHandler(UNEXPECTED); +- unsigned int entry=proc->program.getEntryPoint(); ++ unsigned int entry=proc->program->getEntryPoint(); + #ifdef __CODE_IN_XRAM +- entry=entry-proc->program.getElfBase()+ ++ entry=entry-reinterpret_cast<unsigned int>(proc->program->getElfBase())+ + reinterpret_cast<unsigned int>(proc->loadedProgram); + #endif //__CODE_IN_XRAM +- Thread::setupUserspaceContext(entry,proc->image.getProcessBasePointer(), +- proc->image.getProcessImageSize()); ++ if(proc->suspended==false) ++ Thread::setupUserspaceContext(entry,proc->image.getProcessBasePointer(), ++ proc->image.getProcessImageSize()); ++ else ++ { ++ if(argv) ++ Thread::resumeUserspaceContext(reinterpret_cast<unsigned int*>(argv)); ++ else ++ errorHandler(UNEXPECTED); ++ //in the following block the process is removed from the list of the ++ //suspended processes, after hibernation ++ { ++ Lock<Mutex> l(SuspendManager::suspMutex); ++ proc->suspended=false; ++ SuspendManager::suspendedProcesses.remove(proc); ++ } ++ } + bool running=true; + do { + miosix_private::SyscallParameters sp=Thread::switchToUserspace(); +@@ -282,18 +485,28 @@ void *Process::start(void *argv) + proc->exitCode=SIGSEGV; //Segfault + #ifdef WITH_ERRLOG + iprintf("Process %d terminated due to a fault\n" +- "* Code base address was 0x%x\n" ++ "* Code base address was %p\n" + "* Data base address was %p\n",proc->pid, + #ifndef __CODE_IN_XRAM +- proc->program.getElfBase(), ++ proc->program->getElfBase(), + #else //__CODE_IN_XRAM +- reinterpret_cast<unsigned int>(proc->loadedProgram), ++ proc->loadedProgram, + #endif //__CODE_IN_XRAM + proc->image.getProcessBasePointer()); + proc->mpu.dumpConfiguration(); + proc->fault.print(); + #endif //WITH_ERRLOG + } else { ++ int threadID=-1; ++ ++ for(unsigned int i=0;i<proc->threads.size();i++) ++ { ++ if(proc->threads[i]==Thread::getCurrentThread()) ++ threadID=i; ++ } ++ if(threadID==-1) ++ errorHandler(UNEXPECTED); ++ + switch(sp.getSyscallId()) + { + case 2: +@@ -302,17 +515,22 @@ void *Process::start(void *argv) + break; + case 3: + //FIXME: check that the pointer belongs to the process ++ + sp.setReturnValue(write(sp.getFirstParameter(), + reinterpret_cast<const char*>(sp.getSecondParameter()), + sp.getThirdParameter())); + break; + case 4: + //FIXME: check that the pointer belongs to the process ++ + sp.setReturnValue(read(sp.getFirstParameter(), + reinterpret_cast<char*>(sp.getSecondParameter()), + sp.getThirdParameter())); + break; +- case 5: ++ case 5: ++ if(sp.getFirstParameter()>=1000000) ++ SuspendManager::enterInterruptionPoint(proc,threadID, ++ sp.getFirstParameter()/1000000,5,-1); + sp.setReturnValue(usleep(sp.getFirstParameter())); + break; + default: +@@ -368,13 +586,14 @@ pid_t Process::getNewPid() + } + } + ++ + map<pid_t,Process*> Process::processes; + std::list<Process *> Process::kernelChilds; + std::list<Process *> Process::kernelZombies; + pid_t Process::pidCounter=1; + Mutex Process::procMutex; + ConditionVariable Process::genericWaiting; +- ++ + } //namespace miosix + + #endif //WITH_PROCESSES +diff --git a/miosix/kernel/process.h b/miosix/kernel/process.h +index dc54e1a..cf83b5f 100644 +--- a/miosix/kernel/process.h ++++ b/miosix/kernel/process.h +@@ -36,6 +36,7 @@ + #include "sync.h" + #include "elf_program.h" + #include "config/miosix_settings.h" ++#include "suspend_manager.h" + + #ifdef WITH_PROCESSES + +@@ -57,6 +58,27 @@ public: + static pid_t create(const ElfProgram& program); + + /** ++ * Overloaded version that recreate a process after hibernation ++ * \param status is the serialized status of the process ++ * \param threadID is the number of the thread to be resumed ++ * \return the same pid of the original process ++ * \throws std::exception or a subclass in case of errors, including ++ * not emough memory to spawn the process ++ */ ++ static pid_t create(ProcessStatus* status, int threadId); ++ ++ ++ /** ++ * Recreate a process after the hibernation, exactly as it was before ++ * \param program Program that the process will execute ++ * \param ptr to the serialized status of the process in the backup RAM ++ * \return the pid of the newly created process ++ * \throws std::exception or a subclass in case of errors, including ++ * not emough memory to spawn the process ++ */ ++ static pid_t resume(const ElfProgram& program, ProcessStatus* status); ++ ++ /** + * Given a process, returns the pid of its parent. + * \param proc the pid of a process + * \return the pid of the parent process, or zero if the process was created +@@ -85,6 +107,20 @@ public: + static pid_t waitpid(pid_t pid, int *exit, int options); + + /** ++ * Save the state of the allocator ++ * \param ptr pointer to a memory area of type ProcessStatus ++ * \param interruptionId id of the syscal that caused the interruption ++ * \param fileID file opened by the syscall ++ * \param sleepTime time to sleep for the syscall, actual or estimed, ++ * the latter case accounts for all the syscalls that are not sleep() ++ * \param sampleBuf pointer to the area of memore where the results of ++ * the syscall will be copied. Usefuls in case of smart drivers ++ */ ++ void serialize(ProcessStatus* ptr); ++ ++ ++ ++ /** + * Destructor + */ + ~Process(); +@@ -96,8 +132,11 @@ private: + /** + * Constructor + * \param program program that will be executed by the process ++ * \param resuming true if resuming from hibernation + */ +- Process(const ElfProgram& program); ++ Process(const ElfProgram& program, bool resuming=false); ++ ++ + + /** + * Contains the process' main loop. +@@ -106,13 +145,14 @@ private: + */ + static void *start(void *argv); + ++ + /** + * \return an unique pid that is not zero and is not already in use in the + * system, used to assign a pid to a new process.<br> + */ + static pid_t getNewPid(); + +- ElfProgram program; ///<The program that is running inside the process ++ ElfProgram* program; ///<The program that is running inside the process + #ifdef __CODE_IN_XRAM + /// When __CODE_IN_XRAM is defined, the programs are loaded in the process + /// pool so the memory is aligned and the MPU works +@@ -121,12 +161,13 @@ private: + ProcessImage image; ///<The RAM image of a process + miosix_private::FaultData fault; ///< Contains information about faults + miosix_private::MPUConfiguration mpu; ///<Memory protection data +- + std::vector<Thread *> threads; ///<Threads that belong to the process + std::list<Process *> childs; ///<Living child processes are stored here + std::list<Process *> zombies; ///<Dead child processes are stored here + pid_t pid; ///<The pid of this process + pid_t ppid; ///<The parent pid of this process ++ ///number of the threads active, i.e. not suspended, in the process ++ int numActiveThreads; + ///Contains the count of active wait calls which specifically requested + ///to wait on this process + int waitCount; +@@ -134,7 +175,11 @@ private: + ///wait on this condition variable + ConditionVariable waiting; + bool zombie; ///< True for terminated not yet joined processes ++ bool suspended; ++ bool toBeSwappedOut;///This is set true only if a processs need to be ++ ///swapped out when hibernating + short int exitCode; ///< Contains the exit code ++ int fileTable[MAX_OPEN_FILES];///table of files opened by the process + + ///Maps the pid to the Process instance. Includes zombie processes + static std::map<pid_t,Process *> processes; +@@ -146,6 +191,16 @@ private: + static Mutex procMutex; + ///Used to wait on process termination + static ConditionVariable genericWaiting; ++ //Used to take account of the ELF size opportunely rounded to suit for MPU ++ unsigned int roundedSize; ++ //FIXME: the following two must be implemented in future (smart drivers) ++ ///The following buffer has to be initialized in the constructor to store samples ++ void* sampleBuf; ++ ///the following will store the size of a sample to be retrieved from sensors ++ ///it should be initialized in the constructor too ++ int sizeOfSample; ++ ++ + + //Needs access to fault,mpu + friend class Thread; +@@ -155,6 +210,8 @@ private: + friend class ControlScheduler; + //Needs access to mpu + friend class EDFScheduler; ++ //Nedds access interruption point and resume methods, to handle hibernation ++ friend class SuspendManager; + }; + + } //namespace miosix +diff --git a/miosix/kernel/process_pool.cpp b/miosix/kernel/process_pool.cpp +index a3401f4..8d53fbe 100644 +--- a/miosix/kernel/process_pool.cpp ++++ b/miosix/kernel/process_pool.cpp +@@ -90,7 +90,7 @@ void ProcessPool::deallocate(unsigned int *ptr) + #ifndef TEST_ALLOC + miosix::Lock<miosix::FastMutex> l(mutex); + #endif //TEST_ALLOC +- map<unsigned int*, unsigned int>::iterator it= allocatedBlocks.find(ptr); ++ map<const unsigned int*, unsigned int>::iterator it= allocatedBlocks.find(ptr); + if(it==allocatedBlocks.end())throw runtime_error(""); + unsigned int size =(it->second)/blockSize; + unsigned int firstBit=(reinterpret_cast<unsigned int>(ptr)- +diff --git a/miosix/kernel/process_pool.h b/miosix/kernel/process_pool.h +index 26f5d15..c9b6064 100644 +--- a/miosix/kernel/process_pool.h ++++ b/miosix/kernel/process_pool.h +@@ -25,20 +25,30 @@ + * along with this program; if not, see <http://www.gnu.org/licenses/> * + ***************************************************************************/ + +-#ifndef PROCESS_POOL +-#define PROCESS_POOL ++#ifndef PROCESS_POOL_H ++#define PROCESS_POOL_H ++ ++#include "config/miosix_settings.h" ++ ++#ifdef WITH_PROCESSES + + #include <map> + + #ifndef TEST_ALLOC ++ + #include <miosix.h> ++#include <cstring> ++#ifdef WITH_HIBERNATION ++#include "suspend_manager.h" ++#endif //WITH_HIBERNATION ++ + #else //TEST_ALLOC ++ + #include <iostream> + #include <typeinfo> + #include <sstream> +-#endif //TEST_ALLOC + +-#ifdef WITH_PROCESSES ++#endif //TEST_ALLOC + + namespace miosix { + +@@ -105,13 +115,53 @@ public: + } + } + #endif //TEST_ALLOC +- ++ + ///This constant specifies the size of the minimum allocatable block, + ///in bits. So for example 10 is 1KB. + static const unsigned int blockBits=10; + ///This constant is the the size of the minimum allocatable block, in bytes. + static const unsigned int blockSize=1<<blockBits; ++ ++ #ifdef WITH_HIBERNATION ++ /** ++ * \return a pointer to the base address of the memory pool ++ */ ++ const unsigned int getBaseAddress() const ++ { ++ return reinterpret_cast<unsigned int>(poolBase); ++ } ++ /** ++ * \return the dimension of the data to be serialized at the ++ * moment of the hibernation ++ */ ++ int getSerializableSize() ++ { ++ return (sizeof(unsigned int)+poolSize/blockSize/8); ++ } + ++ void serialize(unsigned int* ptr) ++ { ++ *ptr=poolSize; //TODO: this does not need to be serialized ++ ptr++; ++ memcpy(ptr, bitmap,poolSize/blockSize/8); ++ } ++ ++ void resume(unsigned int* ptrAlloc, ProcessStatus* backupPtr, int numProc) ++ { ++ poolSize=*ptrAlloc; ++ ptrAlloc++; ++ memcpy(bitmap,ptrAlloc,poolSize/blockSize/8); ++ for(int i=0;i<numProc;i++) ++ { ++ allocatedBlocks[backupPtr->processImageBase]=backupPtr->processImageSize; ++ #ifdef __CODE_IN_XRAM ++ allocatedBlocks[backupPtr->programBase]=backupPtr->programSize; ++ #endif //__CODE_IN_XRAM ++ backupPtr++; ++ } ++ } ++ #endif //WITH_HIBERNATION ++ + private: + ProcessPool(const ProcessPool&); + ProcessPool& operator= (const ProcessPool&); +@@ -160,7 +210,7 @@ private: + unsigned int *poolBase; ///< Base address of the entire pool + unsigned int poolSize; ///< Size of the pool, in bytes + ///Lists all allocated blocks, allows to retrieve their sizes +- std::map<unsigned int*,unsigned int> allocatedBlocks; ++ std::map<const unsigned int*,unsigned int> allocatedBlocks; + #ifndef TEST_ALLOC + miosix::FastMutex mutex; ///< Mutex to guard concurrent access + #endif //TEST_ALLOC +@@ -170,4 +220,4 @@ private: + + #endif //WITH_PROCESSES + +-#endif //PROCESS_POOL ++#endif //PROCESS_POOL_H +diff --git a/miosix/kernel/suspend_manager.cpp b/miosix/kernel/suspend_manager.cpp +new file mode 100644 +index 0000000..fb11ee3 +--- /dev/null ++++ b/miosix/kernel/suspend_manager.cpp +@@ -0,0 +1,248 @@ ++/*************************************************************************** ++ * Copyright (C) 2012 by Luigi Rucco and Terraneo Federico * ++ * * ++ * This program is free software; you can redistribute it and/or modify * ++ * it under the terms of the GNU General Public License as published by * ++ * the Free Software Foundation; either version 2 of the License, or * ++ * (at your option) any later version. * ++ * * ++ * This program is distributed in the hope that it will be useful, * ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of * ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * ++ * GNU General Public License for more details. * ++ * * ++ * As a special exception, if other files instantiate templates or use * ++ * macros or inline functions from this file, or you compile this file * ++ * and link it with other works to produce a work based on this file, * ++ * this file does not by itself cause the resulting work to be covered * ++ * by the GNU General Public License. However the source code for this * ++ * file must still be made available in accordance with the GNU General * ++ * Public License. This exception does not invalidate any other reasons * ++ * why a work based on this file might be covered by the GNU General * ++ * Public License. * ++ * * ++ * You should have received a copy of the GNU General Public License * ++ * along with this program; if not, see <http://www.gnu.org/licenses/> * ++ ***************************************************************************/ ++ ++#include "suspend_manager.h" ++#include "interfaces/suspend_support.h" ++#include "elf_program.h" ++#include "process.h" ++#include "interfaces/suspend_support.h" ++#include "process_pool.h" ++#include <cstring> ++#include <cstdio> ++#include <stdexcept> ++ ++#ifdef WITH_HIBERNATION ++ ++using namespace std; ++ ++namespace miosix { ++ ++ProcessStatus* SuspendManager::getProcessesBackupAreaBase() ++{ ++ return reinterpret_cast<struct ProcessStatus*>( ++ reinterpret_cast<unsigned int>(getBackupSramBase())+ ++ getAllocatorSramAreaSize()+ ++ getBackupAllocatorSramAreaSize()); ++} ++ ++/* ++ *The following functions is used to sort the list of resuming time ++ */ ++bool compareResumeTime(SyscallResumeTime first, SyscallResumeTime second ) ++{ ++ return first.resumeTime<second.resumeTime; ++} ++ ++/* ++ *The following function is called each time a thread enter in a system call ++ * in order to update the status of the thread, and eventually of the process, ++ * from 'suspended=false' to 'suspended=true', possibly. Moreover, if all the ++ * processes are suspended, this function signal the hibernation thread (through ++ * the condition variable), which will decide whether to hibernate or not the ++ * system. ++ */ ++void SuspendManager::enterInterruptionPoint(Process* proc, int threadID, ++ long long resumeTime, int intPointID, int fileID) ++{ ++ SyscallResumeTime newSuspThread; ++ newSuspThread.status=NULL; ++ newSuspThread.pid=proc->pid; ++ newSuspThread.resumeTime=resumeTime+getTick()/1000; ++ newSuspThread.threadNum=threadID; ++ newSuspThread.intPointID=intPointID; ++ newSuspThread.fileID=fileID; ++ ++ { ++ Lock<Mutex> l(suspMutex); ++ proc->numActiveThreads--; ++ //FIXME: what if the system does not go in hibernation for a long time ++ //because the threshold is never met? this thing continues to push data ++ //in this list, causing a memory leak that will crash the whole OS!! ++ syscallReturnTime.push_back(newSuspThread); ++ if(proc->numActiveThreads==0) ++ { ++ proc->suspended=true; ++ suspendedProcesses.push_back(proc); ++ } ++ if(suspendedProcesses.size()==Process::processes.size()) ++ hibernWaiting.broadcast(); ++ } ++ ++} ++ ++ ++/* ++ *The following thread create the threds of processes at the time they myust be ++ * resumed ++ */ ++void SuspendManager::wakeupDaemon(void*) ++{ ++ map<pid_t,Process*>::iterator findProc; ++ Lock<Mutex> l(suspMutex); ++ while(syscallReturnTime.empty()==false) ++ { ++ SyscallResumeTime ret=syscallReturnTime.front(); ++ if(ret.resumeTime>=getTick()/1000) ++ { ++ findProc=Process::processes.find(ret.pid); ++ //check if the process is already alive...it could happen that ++ //the main thread has already been spawned and is also terminated ++ //so other threads waiting to be resumed must be not be created. ++ //In any case, at the end of the cycle, the process must be ++ //erased from the syscallReturnTime list ++ if(findProc!=Process::processes.end()) ++ Process::create(ret.status,ret.threadNum); ++ syscallReturnTime.pop_front(); ++ } else { ++ long long resumeTime=ret.resumeTime; ++ { ++ Unlock<Mutex> u(l); ++ sleep(resumeTime-getTick()/1000); ++ } ++ } ++ } ++} ++ ++/* ++ *The following thread function wait for all the processes to be suspended and ++ * then decide whether to hibernate or not.. ++ */ ++void SuspendManager::hibernateDaemon(void*) ++{ ++ Lock<Mutex>l(suspMutex); ++ for(;;) ++ { ++ hibernWaiting.wait(l); ++ syscallReturnTime.sort(compareResumeTime); ++ list<SyscallResumeTime>::iterator it; ++ it=syscallReturnTime.begin(); ++ //NOTE: the following if, as well as the upper and lower bunds, ++ //will be replaced by the policy, once refined ++ if((it->resumeTime-getTick()/1000)<=hibernationThreshold) continue; ++ ProcessStatus* proc=getProcessesBackupAreaBase(); ++ iprintf("Swapping %d processes\n",suspendedProcesses.size()); ++ list<Process*>::iterator findProc; ++ for(findProc=suspendedProcesses.begin(); ++ findProc!=suspendedProcesses.end();findProc++) ++ { ++ (*findProc)->serialize(proc); ++ ++ if((*findProc)->toBeSwappedOut) ++ { ++ //TODO: optimize ++ Mram& mram=Mram::instance(); ++ mram.exitSleepMode(); ++ //Copy the process image from RAM to MRAM ++ mram.write(reinterpret_cast<unsigned int>( ++ (*findProc)->image.getProcessBasePointer())- ++ ProcessPool::instance().getBaseAddress(), ++ (*findProc)->image.getProcessBasePointer(), ++ (*findProc)->image.getProcessImageSize()); ++ mram.enterSleepMode(); ++ //Now serialize the state of the SRAM allocator ++ ProcessPool::instance().serialize(getBackupSramBase()); ++ ++ //Now serialize the state of the backup SRAM allocator ++ (*(getBackupSramBase()+ ++ getAllocatorSramAreaSize()/sizeof(int)))= ++ suspendedProcesses.size(); ++ } ++ proc++; ++ } ++ ++// iprintf("Backup SRAM\n"); ++// memDump((char*)getBackupSramBase(),getBackupSramSize()); ++// Mram& mram=Mram::instance(); ++// mram.exitSleepMode(); ++// char *buf=new char[131072]; ++// mram.read(0,buf,32768); ++// mram.read(32768,buf+32768,32768); ++// mram.read(2*32768,buf+2*32768,32768); ++// mram.read(3*32768,buf+3*32768,32768); ++// mram.enterSleepMode(); ++// iprintf("MRAM\n"); ++// memDump(buf,131072); ++// delete[] buf; ++ ++ long long prev=getTick(); ++ int sleepTime=syscallReturnTime.begin()->resumeTime-prev/1000; ++ iprintf("about to suspend, tick=%lld\n",prev); ++ getBackupSramBase()[1021]=prev & 0xffffffff; //FIXME: hack ++ getBackupSramBase()[1022]=prev>>32; ++ getBackupSramBase()[1023]=sleepTime; ++ doSuspend(sleepTime); ++ } ++} ++ ++int SuspendManager::resume() ++{ ++ ProcessStatus* proc=getProcessesBackupAreaBase(); ++ ++ ProcessPool::instance().resume(getBackupSramBase(), ++ getProcessesBackupAreaBase(), ++ *(getBackupSramBase()+(getAllocatorSramAreaSize()/sizeof(int)))); ++ //in the following block the processes map and ++ //the list syscallReturnTime are populated ++ { ++ Lock<Mutex>l(SuspendManager::suspMutex); ++ SyscallResumeTime retTime; ++ int numProc=*(getBackupSramBase()+(getAllocatorSramAreaSize()/sizeof(int))); ++ iprintf("Reloading %d processes\n",numProc); ++ for(int i=0;i<numProc;i++) ++ { ++ iprintf("reload base=%p size=%d\n",proc->programBase,proc->programSize); ++ Process::resume(ElfProgram(proc->programBase,proc->programSize),proc); ++ for(int i=0;i<proc->numThreads;i++) ++ { ++ retTime.pid=proc->pid; ++ retTime.threadNum=i; ++ retTime.resumeTime=proc->interruptionPoints[i].absSyscallTime; ++ retTime.status=proc; ++ syscallReturnTime.push_back(retTime); ++ } ++ proc++; ++ } ++ syscallReturnTime.sort(compareResumeTime); ++ } ++ ++ Thread::create(wakeupDaemon,2048); ++ return proc->pid; ++} ++ ++void SuspendManager::startHibernationDaemon() ++{ ++ Thread::create(hibernateDaemon,2048); ++} ++ ++std::list<SyscallResumeTime> SuspendManager::syscallReturnTime; ++Mutex SuspendManager::suspMutex(Mutex::RECURSIVE); ++ConditionVariable SuspendManager::hibernWaiting; ++std::list<Process *> SuspendManager::suspendedProcesses; ++ ++}//namespace miosix ++ ++#endif //WITH_HIBERNATION +diff --git a/miosix/kernel/suspend_manager.h b/miosix/kernel/suspend_manager.h +new file mode 100644 +index 0000000..1c48e4f +--- /dev/null ++++ b/miosix/kernel/suspend_manager.h +@@ -0,0 +1,141 @@ ++/*************************************************************************** ++ * Copyright (C) 2012 by Luigi Rucco and Terraneo Federico * ++ * * ++ * This program is free software; you can redistribute it and/or modify * ++ * it under the terms of the GNU General Public License as published by * ++ * the Free Software Foundation; either version 2 of the License, or * ++ * (at your option) any later version. * ++ * * ++ * This program is distributed in the hope that it will be useful, * ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of * ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * ++ * GNU General Public License for more details. * ++ * * ++ * As a special exception, if other files instantiate templates or use * ++ * macros or inline functions from this file, or you compile this file * ++ * and link it with other works to produce a work based on this file, * ++ * this file does not by itself cause the resulting work to be covered * ++ * by the GNU General Public License. However the source code for this * ++ * file must still be made available in accordance with the GNU General * ++ * Public License. This exception does not invalidate any other reasons * ++ * why a work based on this file might be covered by the GNU General * ++ * Public License. * ++ * * ++ * You should have received a copy of the GNU General Public License * ++ * along with this program; if not, see <http://www.gnu.org/licenses/> * ++ ***************************************************************************/ ++ ++#ifndef SUSPEND_MANAGER_H ++#define SUSPEND_MANAGER_H ++ ++#include <list> ++#include <miosix.h> ++#include "interfaces/portability.h" ++#include "config/miosix_settings.h" ++ ++#ifdef WITH_HIBERNATION ++ ++namespace miosix { ++ ++///This struct is used to serialize the interrupion point status for processes ++///and threads spawned by that process ++struct IntPointStatus{ ++ int intPointID; //ID of the syscall which caused the interruption ++ int fileID; //file eventually opened by the syscall, -1 if no file opened ++ long long absSyscallTime; //absolute time taken by the syscall to resume ++ unsigned int* backupQueue; //ptr to the process queue in the backupe SRAM ++ int queueSize; //size of the queue associated to the process ++ char wakeNow;//set to one if the process or thread has to wake up now ++ char sizeOfSample; //size of the data sampled in the hibernation period ++ char padding1[2]; ++ int sampNum; //number of the samples eventually performed by smart driver ++ unsigned int registers[CTXSAVE_SIZE]; ++ unsigned int* targetSampleMem; //process memory pointer to copy the queue ++}__attribute__((packed)); ++ ++ ++///This struct is used to serialize the process status in the backup SRAM ++struct ProcessStatus ++{ ++ int pid; ++ int ppid; ++ short int status; ++ short int numThreads; ++ int exitCode; ++ unsigned int* processImageBase; ++ int processImageSize; ++ const unsigned int* programBase; ++ int programSize; ++ int fileDescriptors[MAX_OPEN_FILES]; ++ struct IntPointStatus interruptionPoints[1+MAX_THREADS_PER_PROCESS]; ++} __attribute__((packed)); ++ ++//this struct is used to keep track of the resume time after a syscall for each ++//process and for each thread in a process ++struct SyscallResumeTime ++{ ++ int pid; ++ short int threadNum; ++ long long resumeTime; ++ int intPointID; ++ int fileID; ++ ProcessStatus* status; ++}__attribute__((packed)); ++ ++ ++class SuspendManager ++{ ++public: ++ /** ++ * /return the base address of the process status backup area ++ */ ++ static ProcessStatus* getProcessesBackupAreaBase(); ++ ++ /** ++ * Find the the serialized processes with invalid bit set, ++ * which must be serialzied again. Return -1 if no dirty processes status ++ * are found ++ */ ++ static int resume(); ++ ++ /** ++ * Enables the hibernation support ++ */ ++ static void startHibernationDaemon(); ++ ++private: ++ static void wakeupDaemon(void*); ++ static void hibernateDaemon(void*); ++ /** ++ * @param pid pid of the process in which the syscall has benn called ++ * @param threadID id of the thread which called the system call ++ * @param resumeTime is the time at which the thread will be resumed after ++ * the suspension due to the system call ++ */ ++ static void enterInterruptionPoint(Process* proc, int threadID, ++ long long resumeTime, int syscallID, int fileID); ++ ++ static std::list<SyscallResumeTime> syscallReturnTime; ++ ///Used to guard access to the number of suspended processes ++ static Mutex suspMutex; ++ ///Used to wait on the condition that all process must be suspended to ++ ///decide if to hibernate or not the system. The suspension of all processes ++ ///is a necessary condition for hibernationm, but not sufficient. The final ++ ///decision is taken according to the hibernation policy. ++ static ConditionVariable hibernWaiting; ++ ///this map lists the suspended processes ++ static std::list<Process *> suspendedProcesses; ++ ++ //Sleep time below which hibernation will not occur (in seconds) ++ static const int hibernationThreshold=1; ++ ++ //Needs access to process table, serialization/loading methods ++ friend class Process; ++ ++}; ++ ++}//namespace miosix ++ ++#endif //WITH_HIBERNATION ++ ++#endif //SUSPEND_MANAGER_H +diff --git a/miosix/kernel/sync.h b/miosix/kernel/sync.h +index 26339a5..1f484c1 100644 +--- a/miosix/kernel/sync.h ++++ b/miosix/kernel/sync.h +@@ -115,12 +115,9 @@ public: + + /** + * \internal +- * \return the FastMutex implementation defined mutex type ++ * \return the FastMutex implemntation defined mutex type + */ +- pthread_mutex_t *get() +- { +- return &impl; +- } ++ pthread_mutex_t *get(); + + /** + * Destructor +diff --git a/miosix/temp/ram_test/mram_test.cpp b/miosix/temp/ram_test/mram_test.cpp +new file mode 100644 +index 0000000..3c8133a +--- /dev/null ++++ b/miosix/temp/ram_test/mram_test.cpp +@@ -0,0 +1,67 @@ ++ ++// To test the MRAM for hibernation ++ ++#include <cstdio> ++#include <cstdlib> ++#include <cstring> ++#include "sha1.h" ++#include <interfaces/suspend_support.h> ++ ++using namespace std; ++ ++bool shaCmp(unsigned int a[5], unsigned int b[5]) ++{ ++ if(memcmp(a,b,20)==0) return false; ++ iprintf("Mismatch\n"); ++ for(int i=0;i<5;i++) iprintf("%04x",a[i]); iprintf("\n"); ++ for(int i=0;i<5;i++) iprintf("%04x",b[i]); iprintf("\n"); ++ return true; ++} ++ ++bool mramTest(int writeSize, int readSize) ++{ ++ char *writeBuffer=new char[writeSize]; ++ char *readBuffer=new char[readSize]; ++ Mram& mram=Mram::instance(); ++ mram.exitSleepMode(); ++ ++ SHA1 sha; ++ sha.Reset(); ++ //Just to shuffle initialization between tests ++ srand(0x7ad3c099+0xad45fce0*writeSize+0x658da2fb*readSize); ++ for(unsigned int i=0;i<mram.size();i+=writeSize) ++ { ++ for(int j=0;j<writeSize;j++) writeBuffer[j]=rand() & 0xff; ++ mram.write(i,writeBuffer,writeSize); ++ sha.Input(writeBuffer,writeSize); ++ } ++ unsigned int a[5]; ++ sha.Result(a); ++ ++ sha.Reset(); ++ for(unsigned int i=0;i<mram.size();i+=readSize) ++ { ++ mram.read(i,readBuffer,readSize); ++ sha.Input(readBuffer,readSize); ++ } ++ unsigned int b[5]; ++ sha.Result(b); ++ ++ delete[] writeBuffer; ++ delete[] readBuffer; ++ ++ return shaCmp(a,b); ++} ++ ++int main() ++{ ++ getchar(); ++ puts("MRAM test"); ++ puts("Testing w=1024, r=1024"); ++ if(mramTest(1024,1024)) return 1; ++ puts("Testing w=512, r=1024"); ++ if(mramTest(512,1024)) return 1; ++ puts("Testing w=1024, r=512"); ++ if(mramTest(1024,512)) return 1; ++ puts("Ok"); ++} +diff --git a/miosix/util/util.cpp b/miosix/util/util.cpp +index 6f1ca57..242b64a 100644 +--- a/miosix/util/util.cpp ++++ b/miosix/util/util.cpp +@@ -163,4 +163,12 @@ unsigned int MemoryProfiling::getCurrentFreeHeap() + return (unsigned int)&_heap_end - (unsigned int)highWatermark; + } + ++int fhbs(unsigned int x) ++{ ++ //TODO: Optimize! ++ int result=0; ++ while(x) { x>>=1; result++; } ++ return result; ++} ++ + } //namespace miosix +diff --git a/miosix/util/util.h b/miosix/util/util.h +index 09a8af4..c0c433b 100644 +--- a/miosix/util/util.h ++++ b/miosix/util/util.h +@@ -110,6 +110,15 @@ private: + void memDump(const char *start, int len); + + /** ++ * Find highest bit set ++ * \param x a 32bit number ++ * \return 0 if the number is zero, or the position of the highest bit ++ * FIXME: Put this function in a more appropriate place, away from the ++ * interfaces/arch ++ */ ++int fhbs(unsigned int x); ++ ++/** + * \} + */ + +diff --git a/miosix_np_processes/nbproject/configurations.xml b/miosix_np_processes/nbproject/configurations.xml +index f048ef9..d1eaa78 100644 +--- a/miosix_np_processes/nbproject/configurations.xml ++++ b/miosix_np_processes/nbproject/configurations.xml +@@ -7,12 +7,6 @@ + <in>main.c</in> + <in>prog3.h</in> + </df> +- <df name="app_template_withlibs"> +- <in>crt0.s</in> +- <in>main.c</in> +- <in>prog3.h</in> +- <in>syscallfuffa.c</in> +- </df> + <df name="miosix"> + <df name="arch"> + <df name="arm7_lpc2000"> +@@ -162,6 +156,8 @@ + <in>gpio_impl.h</in> + <in>portability.cpp</in> + <in>portability_impl.h</in> ++ <in>suspend_support_impl.cpp</in> ++ <in>suspend_support_impl.h</in> + </df> + <in>arch_settings.h</in> + </df> +@@ -169,6 +165,10 @@ + <df name="core"> + <in>stage_1_boot.cpp</in> + </df> ++ <df name="drivers"> ++ <in>mram.cpp</in> ++ <in>mram.h</in> ++ </df> + <df name="interfaces-impl"> + <in>bsp.cpp</in> + <in>bsp_impl.h</in> +@@ -267,6 +267,7 @@ + <in>endianness.h</in> + <in>gpio.h</in> + <in>portability.h</in> ++ <in>suspend_support.h</in> + </df> + <df name="kernel"> + <df name="filesystem"> +@@ -315,6 +316,8 @@ + <in>pthread.cpp</in> + <in>pthread_private.h</in> + <in>stage_2_boot.cpp</in> ++ <in>suspend_manager.cpp</in> ++ <in>suspend_manager.h</in> + <in>sync.cpp</in> + <in>sync.h</in> + <in>syscalls.cpp</in> +diff --git a/profiling.patch b/profiling.patch +new file mode 100644 +index 0000000..32295a7 +--- /dev/null ++++ b/profiling.patch +@@ -0,0 +1,175 @@ ++diff --git a/main.cpp b/main.cpp ++index b991f7f..8486f3b 100644 ++--- a/main.cpp +++++ b/main.cpp ++@@ -26,10 +26,11 @@ int main() ++ { ++ Thread::create(ledThread,STACK_MIN); ++ SuspendManager::startHibernationDaemon(); ++- iprintf("tick=%llu\n",getTick()); +++// iprintf("tick=%llu\n",getTick()); ++ if(firstBoot()) ++ { ++- puts("First boot"); +++ Gpio<GPIOC_BASE,7>::low(); //FIXME: remove +++// puts("First boot"); ++ // //Watermarking ++ // memset(getBackupSramBase(),0xff,getBackupSramSize()); ++ // char *buf=new char[1024]; ++@@ -41,7 +42,7 @@ int main() ++ // mram.enterSleepMode(); ++ // delete[] buf; ++ } else { ++- puts("RTC boot"); +++// puts("RTC boot"); ++ SuspendManager::resume(); ++ ++ int ec; ++diff --git a/miosix/arch/cortexM3_stm32f2/common/interfaces-impl/suspend_support_impl.cpp b/miosix/arch/cortexM3_stm32f2/common/interfaces-impl/suspend_support_impl.cpp ++index dda8f03..688d725 100644 ++--- a/miosix/arch/cortexM3_stm32f2/common/interfaces-impl/suspend_support_impl.cpp +++++ b/miosix/arch/cortexM3_stm32f2/common/interfaces-impl/suspend_support_impl.cpp ++@@ -30,6 +30,7 @@ ++ #include "kernel/process_pool.h" ++ #include "miosix.h" ++ #include "interfaces/arch_registers.h" +++#include "interfaces/gpio.h" //FIXME: remove ++ ++ #ifdef WITH_HIBERNATION ++ ++@@ -81,6 +82,9 @@ void doSuspend(unsigned int seconds) ++ ++ PWR->CR |= PWR_CR_PDDS | PWR_CR_CWUF; ++ SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; +++ +++ Gpio<GPIOC_BASE,7>::low(); //FIXME: remove +++ ++ //Using WFE instead of WFI because if while we are with interrupts ++ //disabled an interrupt (such as the tick interrupt) occurs, it ++ //remains pending and the WFI becomes a nop, and the device never goes ++diff --git a/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/core/stage_1_boot.cpp b/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/core/stage_1_boot.cpp ++index 18663fb..cfe8e6f 100644 ++--- a/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/core/stage_1_boot.cpp +++++ b/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/core/stage_1_boot.cpp ++@@ -2,6 +2,7 @@ ++ #include "interfaces/arch_registers.h" ++ #include "core/interrupts.h" //For the unexpected interrupt call ++ #include <string.h> +++#include "interfaces/gpio.h" //FIXME: remove ++ ++ /* ++ * startup.cpp ++@@ -116,6 +117,10 @@ void Reset_Handler() ++ asm volatile("ldr sp, =_main_stack_top\n\t"); ++ #endif //__CODE_IN_XRAM ++ +++ RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN; //FIXME: remove +++ miosix::Gpio<GPIOC_BASE,7>::mode(miosix::Mode::OUTPUT); +++ miosix::Gpio<GPIOC_BASE,7>::high(); +++ ++ /* ++ * SystemInit() is called *before* initializing .data and zeroing .bss ++ * Despite all startup files provided by ST do the opposite, there are three ++diff --git a/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/interfaces-impl/bsp.cpp b/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/interfaces-impl/bsp.cpp ++index cd41faa..d8bb6de 100644 ++--- a/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/interfaces-impl/bsp.cpp +++++ b/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/interfaces-impl/bsp.cpp ++@@ -72,9 +72,9 @@ void IRQbspInit() ++ GPIOI->OSPEEDR=0xaaaaaaaa; ++ _led::mode(Mode::OUTPUT); ++ sdCardDetect::mode(Mode::INPUT_PULL_UP); ++- ledOn(); ++- delayMs(100); ++- ledOff(); +++// ledOn(); +++// delayMs(100); +++// ledOff(); ++ #ifndef STDOUT_REDIRECTED_TO_DCC ++ IRQstm32f2serialPortInit(); ++ #endif //STDOUT_REDIRECTED_TO_DCC ++diff --git a/miosix/config/miosix_settings.h b/miosix/config/miosix_settings.h ++index 648c3c4..a26da30 100644 ++--- a/miosix/config/miosix_settings.h +++++ b/miosix/config/miosix_settings.h ++@@ -123,7 +123,7 @@ const unsigned char MAX_THREADS_PER_PROCESS=2; ++ /// \def WITH_BOOTLOG ++ /// Uncomment to print bootlogs on stdout. ++ /// By default it is defined (bootlogs are printed) ++-#define WITH_BOOTLOG +++//#define WITH_BOOTLOG ++ ++ /// \def WITH_ERRLOG ++ /// Uncomment for debug information on stdout. ++@@ -142,7 +142,7 @@ const unsigned char MAX_THREADS_PER_PROCESS=2; ++ * mode, so to use debugging it is necessary to disble sleep in the idle thread. ++ * By default it is not defined (idle thread calls sleep). ++ */ ++-#define JTAG_DISABLE_SLEEP +++//#define JTAG_DISABLE_SLEEP ++ ++ /// Minimum stack size (MUST be divisible by 4) ++ const unsigned int STACK_MIN=256; ++diff --git a/miosix/kernel/process.cpp b/miosix/kernel/process.cpp ++index 06d7e55..16f88d7 100644 ++--- a/miosix/kernel/process.cpp +++++ b/miosix/kernel/process.cpp ++@@ -354,7 +354,7 @@ void Process::serialize(ProcessStatus* ptr) ++ #ifndef __CODE_IN_XRAM ++ ptr->programBase=this->program->getElfBase(); ++ ptr->programSize=this->program->getElfSize(); ++- iprintf("save base=%p size=%d\n",ptr->programBase,ptr->programSize); +++// iprintf("save base=%p size=%d\n",ptr->programBase,ptr->programSize); ++ #else //__CODE_IN_XRAM ++ ptr->programBase=this->loadedProgram; ++ ptr->programBase=reinterpret_cast<unsigned int*>(this->roundedSize); ++diff --git a/miosix/kernel/suspend_manager.cpp b/miosix/kernel/suspend_manager.cpp ++index fb11ee3..bc2cf7b 100644 ++--- a/miosix/kernel/suspend_manager.cpp +++++ b/miosix/kernel/suspend_manager.cpp ++@@ -68,6 +68,7 @@ bool compareResumeTime(SyscallResumeTime first, SyscallResumeTime second ) ++ void SuspendManager::enterInterruptionPoint(Process* proc, int threadID, ++ long long resumeTime, int intPointID, int fileID) ++ { +++ Gpio<GPIOC_BASE,7>::high(); //FIXME: remove ++ SyscallResumeTime newSuspThread; ++ newSuspThread.status=NULL; ++ newSuspThread.pid=proc->pid; ++@@ -125,6 +126,7 @@ void SuspendManager::wakeupDaemon(void*) ++ } ++ } ++ } +++ Gpio<GPIOC_BASE,7>::low(); //FIXME: remove ++ } ++ ++ /* ++@@ -144,7 +146,7 @@ void SuspendManager::hibernateDaemon(void*) ++ //will be replaced by the policy, once refined ++ if((it->resumeTime-getTick()/1000)<=hibernationThreshold) continue; ++ ProcessStatus* proc=getProcessesBackupAreaBase(); ++- iprintf("Swapping %d processes\n",suspendedProcesses.size()); +++// iprintf("Swapping %d processes\n",suspendedProcesses.size()); ++ list<Process*>::iterator findProc; ++ for(findProc=suspendedProcesses.begin(); ++ findProc!=suspendedProcesses.end();findProc++) ++@@ -190,7 +192,7 @@ void SuspendManager::hibernateDaemon(void*) ++ ++ long long prev=getTick(); ++ int sleepTime=syscallReturnTime.begin()->resumeTime-prev/1000; ++- iprintf("about to suspend, tick=%lld\n",prev); +++// iprintf("about to suspend, tick=%lld\n",prev); ++ getBackupSramBase()[1021]=prev & 0xffffffff; //FIXME: hack ++ getBackupSramBase()[1022]=prev>>32; ++ getBackupSramBase()[1023]=sleepTime; ++@@ -211,10 +213,10 @@ int SuspendManager::resume() ++ Lock<Mutex>l(SuspendManager::suspMutex); ++ SyscallResumeTime retTime; ++ int numProc=*(getBackupSramBase()+(getAllocatorSramAreaSize()/sizeof(int))); ++- iprintf("Reloading %d processes\n",numProc); +++// iprintf("Reloading %d processes\n",numProc); ++ for(int i=0;i<numProc;i++) ++ { ++- iprintf("reload base=%p size=%d\n",proc->programBase,proc->programSize); +++// iprintf("reload base=%p size=%d\n",proc->programBase,proc->programSize); ++ Process::resume(ElfProgram(proc->programBase,proc->programSize),proc); ++ for(int i=0;i<proc->numThreads;i++) ++ { +diff --git a/screenlog.0 b/screenlog.0 +new file mode 100644 +index 0000000..f9b725a +--- /dev/null ++++ b/screenlog.0 +@@ -0,0 +1,52 @@ ++Miosix v1.60 (stm32f207ig_stm3220g-eval, Jul 13 2012 12:46:00, gcc 4.5.2) ++Starting Kernel... Ok ++Starting Filesystem... No disk ++Available heap 24576 out of 29868 Bytes ++tick=40 ++First boot ++ ++0=divzero 1=sleep 5s, 2=exit 3=bkpt 4=dangling ++1 ++Swapping 1 processes ++save base=0x1c3a8 size=468 ++about to suspend, tick=3576 ++Miosix v1.60 (stm32f207ig_stm3220g-eval, Jul 13 2012 12:46:00, gcc 4.5.2) ++Starting Kernel... Ok ++Starting Filesystem... No disk ++Available heap 24576 out of 29868 Bytes ++tick=8616 ++RTC boot ++Reloading 1 processes ++reload base=0x1c3a8 size=468 ++0=divzero 1=sleep 5s, 2=exit 3=bkpt 4=dangling ++2 ++Process terminated ++Exit code is 0 ++ ++0=divzero 1=sleep 5s, 2=exit 3=bkpt 4=dangling ++1 ++Swapping 1 processes ++save base=0x1c3a8 size=468 ++about to suspend, tick=30342 ++Miosix v1.60 (stm32f207ig_stm3220g-eval, Jul 13 2012 12:46:00, gcc 4.5.2) ++Starting Kernel... Ok ++Starting Filesystem... No disk ++Available heap 24576 out of 29868 Bytes ++tick=35382 ++RTC boot ++Reloading 1 processes ++reload base=0x1c3a8 size=468 ++0=divzero 1=sleep 5s, 2=exit 3=bkpt 4=dangling ++1 ++Swapping 1 processes ++save base=0x1c3a8 size=468 ++about to suspend, tick=38120 ++Miosix v1.60 (stm32f207ig_stm3220g-eval, Jul 13 2012 12:46:00, gcc 4.5.2) ++Starting Kernel... Ok ++Starting Filesystem... No disk ++Available heap 24576 out of 29868 Bytes ++tick=43160 ++RTC boot ++Reloading 1 processes ++reload base=0x1c3a8 size=468 ++0=divzero 1=sleep 5s, 2=exit 3=bkpt 4=dangling diff --git a/log.txt b/log.txt new file mode 100644 index 00000000..947e1fa9 --- /dev/null +++ b/log.txt @@ -0,0 +1,5 @@ +arm-miosix-eabi-g++ -mcpu=cortex-m3 -mthumb -mfix-cortex-m3-ldrd -fpie -msingle-pic-base -Wl,--gc-sections,-Map,main.map,-T./miosix.ld,-n,-pie,--spare-dynamic-tags,3 -O2 -nostdlib -fPIC -o main.elf main.o crt0.o -Wl,--start-group -lstdc++ -lc -lm -lgcc -Wl,--end-group +/opt/arm-miosix-eabi/lib/gcc/arm-eabi/4.5.2/../../../../arm-eabi/bin/ld: /opt/arm-miosix-eabi/lib/gcc/arm-eabi/4.5.2/../../../../arm-eabi/lib/thumb/thumb2/libc.a(lib_a-syslseek.o): relocation R_ARM_THM_MOVW_ABS_NC against `_impure_ptr' can not be used when making a shared object; recompile with -fPIC +/opt/arm-miosix-eabi/lib/gcc/arm-eabi/4.5.2/../../../../arm-eabi/lib/thumb/thumb2/libc.a: could not read symbols: Bad value +collect2: ld returned 1 exit status +make: *** [all] Error 1 diff --git a/main.cpp b/main.cpp index 75f70ce4..27b83cd5 100644 --- a/main.cpp +++ b/main.cpp @@ -4,8 +4,12 @@ #include <signal.h> #include "miosix.h" #include "kernel/process.h" +#include "kernel/SystemMap.h" + #include "app_template/prog3.h" +#include "system_app_test/prog3.h" + using namespace std; using namespace miosix; @@ -23,6 +27,12 @@ void ledThread(void *) int main() { Thread::create(ledThread,STACK_MIN); + + SystemMap::instance().addElfProgram("test", reinterpret_cast<const unsigned int*>(test_elf), test_elf_len); + + iprintf("SystemMap::size: %d\n", SystemMap::instance().getElfCount()); + std::pair<const unsigned int*, unsigned int> res = SystemMap::instance().getElfProgram("test"); + iprintf("SystemMap test entry size: %X %d\n", res.first, res.second); ElfProgram prog(reinterpret_cast<const unsigned int*>(main_elf),main_elf_len); for(int i=0;;i++) diff --git a/miosix/Makefile b/miosix/Makefile index e601cfc6..2f87255a 100644 --- a/miosix/Makefile +++ b/miosix/Makefile @@ -26,6 +26,7 @@ kernel/scheduler/edf/edf_scheduler.cpp \ kernel/filesystem/filesystem.cpp \ kernel/filesystem/ff.c \ kernel/filesystem/diskio.cpp \ +kernel/SystemMap.cpp \ util/util.cpp \ util/version.cpp \ util/crc16.cpp \ diff --git a/miosix/arch/cortexM3_stm32f2/common/interfaces-impl/disk.cpp b/miosix/arch/cortexM3_stm32f2/common/interfaces-impl/disk.cpp index 970a5384..7fae5568 100644 --- a/miosix/arch/cortexM3_stm32f2/common/interfaces-impl/disk.cpp +++ b/miosix/arch/cortexM3_stm32f2/common/interfaces-impl/disk.cpp @@ -70,9 +70,9 @@ static CardType cardType=Invalid; //SD card GPIOs typedef Gpio<GPIOC_BASE,8> sdD0; -typedef Gpio<GPIOC_BASE,9> sdD1; -typedef Gpio<GPIOC_BASE,10> sdD2; -typedef Gpio<GPIOC_BASE,11> sdD3; +//typedef Gpio<GPIOC_BASE,9> sdD1; //QUIRK: use serial port and SD +//typedef Gpio<GPIOC_BASE,10> sdD2; +//typedef Gpio<GPIOC_BASE,11> sdD3; typedef Gpio<GPIOC_BASE,12> sdCLK; typedef Gpio<GPIOD_BASE,2> sdCMD; @@ -705,8 +705,9 @@ private: static const unsigned int CLOCK_MAX=0; //48MHz/(0+2) =24MHz ///\internal Clock enabled, bus width 4bit, clock powersave enabled. - static const unsigned int CLKCR_FLAGS=SDIO_CLKCR_CLKEN | - SDIO_CLKCR_WIDBUS_0 | SDIO_CLKCR_PWRSAV; + //static const unsigned int CLKCR_FLAGS=SDIO_CLKCR_CLKEN | + // SDIO_CLKCR_WIDBUS_0 | SDIO_CLKCR_PWRSAV; + static const unsigned int CLKCR_FLAGS=SDIO_CLKCR_CLKEN; //QUIRK: use serial port and SD ///\internal Maximum number of calls to IRQreduceClockSpeed() allowed static const unsigned char MAX_ALLOWED_REDUCTIONS=5; @@ -1092,12 +1093,12 @@ static void initSDIOPeripheral() RCC->APB2ENR |= RCC_APB2ENR_SDIOEN; sdD0::mode(Mode::ALTERNATE); sdD0::alternateFunction(12); - sdD1::mode(Mode::ALTERNATE); - sdD1::alternateFunction(12); - sdD2::mode(Mode::ALTERNATE); - sdD2::alternateFunction(12); - sdD3::mode(Mode::ALTERNATE); - sdD3::alternateFunction(12); +// sdD1::mode(Mode::ALTERNATE); //QUIRK: use serial port and SD +// sdD1::alternateFunction(12); +// sdD2::mode(Mode::ALTERNATE); +// sdD2::alternateFunction(12); +// sdD3::mode(Mode::ALTERNATE); +// sdD3::alternateFunction(12); sdCLK::mode(Mode::ALTERNATE); sdCLK::alternateFunction(12); sdCMD::mode(Mode::ALTERNATE); @@ -1273,8 +1274,8 @@ void Disk::init() return; } - r=Command::send(Command::ACMD6,2); //Set 4 bit bus width - if(r.validateR1Response()==false) return; + //r=Command::send(Command::ACMD6,2); //Set 4 bit bus width + //if(r.validateR1Response()==false) return; //QUIRK: use serial port and SD if(cardType!=SDHC) { diff --git a/miosix/arch/cortexM3_stm32f2/common/interfaces-impl/portability.cpp b/miosix/arch/cortexM3_stm32f2/common/interfaces-impl/portability.cpp index 47fe617a..fdfb9264 100644 --- a/miosix/arch/cortexM3_stm32f2/common/interfaces-impl/portability.cpp +++ b/miosix/arch/cortexM3_stm32f2/common/interfaces-impl/portability.cpp @@ -28,6 +28,7 @@ #include "interfaces/portability.h" #include "kernel/kernel.h" +#include "util/util.h" #include "kernel/error.h" #include "interfaces/bsp.h" #include "kernel/scheduler/scheduler.h" @@ -263,27 +264,27 @@ MPUConfiguration::MPUConfiguration(unsigned int *elfBase, unsigned int elfSize, regValues[1]=2<<MPU_RASR_AP_Pos | MPU_RASR_C_Msk | 1 //Enable bit - | ((ffs(elfSize)-2)<<1); + | ((miosix::fhbs(elfSize)-2)<<1); regValues[3]=3<<MPU_RASR_AP_Pos | MPU_RASR_XN_Msk | MPU_RASR_C_Msk | MPU_RASR_S_Msk | 1 //Enable bit - | ((ffs(imageSize)-2)<<1); + | ((miosix::fhbs(imageSize)-2)<<1); #else //__CODE_IN_XRAM regValues[1]=2<<MPU_RASR_AP_Pos | MPU_RASR_C_Msk | MPU_RASR_B_Msk | MPU_RASR_S_Msk | 1 //Enable bit - | ((ffs(elfSize)-2)<<1); + | ((miosix::fhbs(elfSize)-2)<<1); regValues[3]=3<<MPU_RASR_AP_Pos | MPU_RASR_XN_Msk | MPU_RASR_C_Msk | MPU_RASR_B_Msk | MPU_RASR_S_Msk | 1 //Enable bit - | ((ffs(imageSize)-2)<<1); + | ((miosix::fhbs(imageSize)-2)<<1); #endif //__CODE_IN_XRAM } diff --git a/miosix/compiler/cleanup.sh b/miosix/compiler/cleanup.sh old mode 100644 new mode 100755 diff --git a/miosix/compiler/download.sh b/miosix/compiler/download.sh old mode 100644 new mode 100755 diff --git a/miosix/compiler/install-script.sh b/miosix/compiler/install-script.sh old mode 100644 new mode 100755 diff --git a/miosix/compiler/mx-postlinker/Makefile b/miosix/compiler/mx-postlinker/Makefile index b5fe7c84..581c0c83 100644 --- a/miosix/compiler/mx-postlinker/Makefile +++ b/miosix/compiler/mx-postlinker/Makefile @@ -1,5 +1,5 @@ -CXX:= g++ -CXXFLAGS:= -O2 -c +CXX:= g++ -m32 +CXXFLAGS:= -O2 -c -m32 OBJS:= postlinker.o main.o #create program target diff --git a/miosix/compiler/uninstall.sh b/miosix/compiler/uninstall.sh old mode 100644 new mode 100755 diff --git a/miosix/kernel/SystemMap.cpp b/miosix/kernel/SystemMap.cpp new file mode 100644 index 00000000..2d76507e --- /dev/null +++ b/miosix/kernel/SystemMap.cpp @@ -0,0 +1,66 @@ +#include "SystemMap.h" + +using namespace std; + +namespace miosix { + +static Mutex initMapMutex;//To guard initialization of the singleton + +SystemMap::SystemMap() { +} + +SystemMap::SystemMap(const SystemMap& orig) { +} + +SystemMap::~SystemMap() { +} + +SystemMap &SystemMap::instance(){ + static SystemMap *pSingleton = 0; + { + Lock<Mutex> lock(initMapMutex); + + if(pSingleton == 0) + pSingleton = new SystemMap(); + } + + return *pSingleton; +} + +void SystemMap::addElfProgram(const char* name, const unsigned int *elf, unsigned int size){ + unsigned int hash = hashString(name); + + if(mPrograms.find(hash) == mPrograms.end()) + mPrograms.insert(make_pair(hash, make_pair(elf, size))); +} + +pair<const unsigned int*, unsigned int> SystemMap::getElfProgram(const char* name) const { + ProgramsMap::const_iterator it = mPrograms.find(hashString(name)); + + if(it == mPrograms.end()) + return make_pair<const unsigned int*, unsigned int>(0, 0); + + return it->second; +} + +unsigned int SystemMap::getElfCount() const{ + return mPrograms.size(); +} + +unsigned int SystemMap::hashString(const char* pStr) const { + unsigned int hash = 0; + + for(; *pStr != '\0'; ++pStr){ + hash += *pStr; + hash += (hash << 10); + hash += (hash >> 6); + } + + hash += (hash << 3); + hash ^= (hash >> 11); + hash += (hash << 15); + + return hash; +} + +} \ No newline at end of file diff --git a/miosix/kernel/SystemMap.h b/miosix/kernel/SystemMap.h new file mode 100644 index 00000000..1e82ed0b --- /dev/null +++ b/miosix/kernel/SystemMap.h @@ -0,0 +1,34 @@ +#ifndef SYSTEMMAP_H +#define SYSTEMMAP_H + +#include "kernel/sync.h" + +#include <map> + +namespace miosix { + +class SystemMap { +public: + SystemMap(); + virtual ~SystemMap(); + + static SystemMap &instance(); + + //Privata ? and friendly + void addElfProgram(const char *name, const unsigned int *elf, unsigned int size); + std::pair<const unsigned int*, unsigned int> getElfProgram(const char *name) const; + + unsigned int getElfCount() const; + +private: + unsigned int hashString(const char *pStr) const; + + SystemMap(const SystemMap& orig); + + typedef std::map<unsigned int, std::pair<const unsigned int*, unsigned int> > ProgramsMap; + ProgramsMap mPrograms; +}; + +} + +#endif /* SYSTEMMAP_H */ diff --git a/miosix/kernel/filesystem/ff.c b/miosix/kernel/filesystem/ff.c index 9a3a2cef..c9d60d0f 100644 --- a/miosix/kernel/filesystem/ff.c +++ b/miosix/kernel/filesystem/ff.c @@ -824,10 +824,9 @@ FRESULT f_open ( BYTE *dir; char fn[8+3+1]; - fp->fs = NULL; /* Clear file object */ #if !_FS_READONLY - mode &= (FA_READ|FA_WRITE|FA_CREATE_ALWAYS|FA_OPEN_ALWAYS|FA_CREATE_NEW); + mode &= (FA_READ|FA_WRITE|FA_CREATE_ALWAYS|FA_CREATE_NEW|FA_OPEN_ALWAYS); res = auto_mount(&path, &dj.fs, (BYTE)(mode & (FA_WRITE|FA_CREATE_ALWAYS|FA_OPEN_ALWAYS|FA_CREATE_NEW))); #else mode &= FA_READ; diff --git a/miosix/kernel/filesystem/filesystem.cpp b/miosix/kernel/filesystem/filesystem.cpp index 465d1c2f..a8191cc3 100644 --- a/miosix/kernel/filesystem/filesystem.cpp +++ b/miosix/kernel/filesystem/filesystem.cpp @@ -104,11 +104,18 @@ int Filesystem::openFile(const char *name, int flags, int mode) //Set file flags BYTE openflags=0; - if(flags & _FREAD) openflags|=FA_READ; - if(flags & _FWRITE) openflags|=FA_WRITE; - if(flags & _FTRUNC) openflags|=FA_CREATE_ALWAYS;//Truncate - else if(flags & _FAPPEND) openflags|=FA_OPEN_ALWAYS;//If not exists create - else openflags|=FA_OPEN_EXISTING;//If not exists fail + if(flags & _FREAD) + openflags|=FA_READ; + + if(flags & _FWRITE) + openflags|=FA_WRITE; + + if(flags & _FTRUNC) + openflags|=FA_CREATE_ALWAYS;//Truncate + else if(flags & _FAPPEND) + openflags|=FA_OPEN_ALWAYS;//If not exists create + else + openflags|=FA_OPEN_EXISTING;//If not exists fail //Allocate the FatFs file data structure #ifdef __NO_EXCEPTIONS diff --git a/miosix/kernel/process.cpp b/miosix/kernel/process.cpp index 9ac56c20..91c8a7b3 100644 --- a/miosix/kernel/process.cpp +++ b/miosix/kernel/process.cpp @@ -34,6 +34,7 @@ #include "sync.h" #include "process_pool.h" #include "process.h" +#include "SystemMap.h" using namespace std; @@ -225,6 +226,10 @@ Process::~Process() #ifdef __CODE_IN_XRAM ProcessPool::instance().deallocate(loadedProgram); #endif //__CODE_IN_XRAM + + //close alla opened files + for(set<int>::iterator it = mFiles.begin(); it != mFiles.end(); ++it) + close(*it); } Process::Process(const ElfProgram& program) : program(program), waitCount(0), @@ -312,9 +317,63 @@ void *Process::start(void *argv) reinterpret_cast<char*>(sp.getSecondParameter()), sp.getThirdParameter())); break; - case 5: - sp.setReturnValue(usleep(sp.getFirstParameter())); + case 5: + sp.setReturnValue(usleep(sp.getFirstParameter())); break; + case 6: + //open + { + int fp = open(reinterpret_cast<const char*>(sp.getFirstParameter()), //filename + sp.getSecondParameter(), //flags + sp.getThirdParameter()); //permission, used? + if (fp != -1) + proc->mFiles.insert(fp); + + sp.setReturnValue(fp); + } + break; + case 7: + //close + if(proc->mFiles.find(sp.getFirstParameter()) != proc->mFiles.end()){ + int ret = close(sp.getFirstParameter()); + + if(ret == 0) + proc->mFiles.erase(sp.getFirstParameter()); + + sp.setReturnValue(ret); + } else + sp.setReturnValue(-1); + break; + case 8: + //lseek + if(proc->mFiles.find(sp.getFirstParameter()) != proc->mFiles.end()) + sp.setReturnValue(Filesystem::instance().lseekFile(sp.getFirstParameter(), + sp.getSecondParameter(), + sp.getThirdParameter())); + else + sp.setReturnValue(-1); + + break; + case 9: + //system, NOT TESTED YET!!! + { + std::pair<const unsigned int*, unsigned int> res = SystemMap::instance().getElfProgram(reinterpret_cast<const char*>(sp.getFirstParameter())); + + if(res.first == 0 || res.second == 0){ + iprintf("Program not found.\n"); + sp.setReturnValue(-1); + break; + } + + ElfProgram program(res.first, res.second); + int ret = 0; + + pid_t child = Process::create(program); + Process::waitpid(child, &ret, 0); + + sp.setReturnValue(ret); + } + break; default: running=false; proc->exitCode=SIGSYS; //Bad syscall diff --git a/miosix/kernel/process.h b/miosix/kernel/process.h index dc54e1af..466f0be9 100644 --- a/miosix/kernel/process.h +++ b/miosix/kernel/process.h @@ -31,6 +31,7 @@ #include <vector> #include <map> #include <list> +#include <set> #include <sys/types.h> #include "kernel.h" #include "sync.h" @@ -125,6 +126,7 @@ private: std::vector<Thread *> threads; ///<Threads that belong to the process std::list<Process *> childs; ///<Living child processes are stored here std::list<Process *> zombies; ///<Dead child processes are stored here + std::set<int> mFiles; ///<Files openend by this process pid_t pid; ///<The pid of this process pid_t ppid; ///<The parent pid of this process ///Contains the count of active wait calls which specifically requested diff --git a/miosix/kernel/syscalls.cpp b/miosix/kernel/syscalls.cpp index 550da2fe..086af5cb 100644 --- a/miosix/kernel/syscalls.cpp +++ b/miosix/kernel/syscalls.cpp @@ -407,8 +407,7 @@ void *_sbrk_r(struct _reent *ptr, ptrdiff_t incr) /** * \internal - * __malloc_lock, called by malloc to ensure no context switch happens during - * memory allocation (the heap is global and shared between the threads, so + * __malloc_lock, called by malloc t_memory allocation (the heap is global and shared between the threads, so * memory allocation should not be interrupted by a context switch) * * WARNING: @@ -461,6 +460,7 @@ int _close_r(struct _reent *ptr, int fd) #endif //WITH_FILESYSTEM } + /** * \internal * _write (for C++ library) diff --git a/miosix/util/util.cpp b/miosix/util/util.cpp index 6f1ca57c..e3d6df21 100644 --- a/miosix/util/util.cpp +++ b/miosix/util/util.cpp @@ -41,6 +41,13 @@ using namespace std; namespace miosix { +int fhbs(unsigned int x){ + //TODO: Optimize! + int result=0; + while(x) { x>>=1; result++; } + return result; +} + /** * \internal * used by memDump diff --git a/miosix/util/util.h b/miosix/util/util.h index 09a8af4d..addf775f 100644 --- a/miosix/util/util.h +++ b/miosix/util/util.h @@ -34,6 +34,15 @@ #define UTIL_H namespace miosix { + +/** +* Find highest bit set +* \param x a 32bit number +* \return 0 if the number is zero, or the position of the highest bit +* FIXME: Put this function in a more appropriate place, away from the +* interfaces/arch +**/ +int fhbs(unsigned int x); /** * \addtogroup Util diff --git a/miosix_np_processes/nbproject/configurations.xml b/miosix_np_processes/nbproject/configurations.xml index f048ef9d..f7cc6131 100644 --- a/miosix_np_processes/nbproject/configurations.xml +++ b/miosix_np_processes/nbproject/configurations.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> -<configurationDescriptor version="80"> +<configurationDescriptor version="84"> <logicalFolder name="root" displayName="root" projectFiles="true" kind="ROOT"> - <df name="miosix_np_2" root=".."> + <df name="miosix-kernel" root=".."> <df name="app_template"> <in>crt0.s</in> <in>main.c</in> @@ -299,6 +299,8 @@ <in>scheduler.h</in> <in>tick_interrupt.h</in> </df> + <in>SystemMap.cpp</in> + <in>SystemMap.h</in> <in>buffer_queue.h</in> <in>elf_program.cpp</in> <in>elf_program.h</in> @@ -341,11 +343,17 @@ </df> <df name="miosix_np_processes"> </df> + <df name="system_app_test"> + <in>crt0.s</in> + <in>main.c</in> + <in>prog3.h</in> + </df> <in>main.cpp</in> </df> <logicalFolder name="ExternalFiles" displayName="Important Files" - projectFiles="false"> + projectFiles="false" + root=".."> <itemPath>../makefile</itemPath> <itemPath>miosix_np_2-Makefile.mk</itemPath> </logicalFolder> @@ -361,6 +369,8 @@ <remote-sources-mode>LOCAL_SOURCES</remote-sources-mode> <compilerSet>ARM_MIOSIX_EABI|GNU</compilerSet> </toolsSet> + <codeAssistance> + </codeAssistance> <makefileType> <makeTool> <buildCommandWorkingDir>..</buildCommandWorkingDir> @@ -409,6 +419,8 @@ <remote-sources-mode>LOCAL_SOURCES</remote-sources-mode> <compilerSet>ARM_MIOSIX_EABI|GNU</compilerSet> </toolsSet> + <codeAssistance> + </codeAssistance> <makefileType> <makeTool> <buildCommandWorkingDir>..</buildCommandWorkingDir> @@ -453,6 +465,8 @@ <remote-sources-mode>LOCAL_SOURCES</remote-sources-mode> <compilerSet>ARM_MIOSIX_EABI|GNU</compilerSet> </toolsSet> + <codeAssistance> + </codeAssistance> <makefileType> <makeTool> <buildCommandWorkingDir>..</buildCommandWorkingDir> @@ -499,6 +513,8 @@ <remote-sources-mode>LOCAL_SOURCES</remote-sources-mode> <compilerSet>ARM_MIOSIX_EABI|GNU</compilerSet> </toolsSet> + <codeAssistance> + </codeAssistance> <makefileType> <makeTool> <buildCommandWorkingDir>..</buildCommandWorkingDir> @@ -545,6 +561,8 @@ <remote-sources-mode>LOCAL_SOURCES</remote-sources-mode> <compilerSet>ARM_MIOSIX_EABI|GNU</compilerSet> </toolsSet> + <codeAssistance> + </codeAssistance> <makefileType> <makeTool> <buildCommandWorkingDir>..</buildCommandWorkingDir> @@ -591,6 +609,8 @@ <remote-sources-mode>LOCAL_SOURCES</remote-sources-mode> <compilerSet>ARM_MIOSIX_EABI|GNU</compilerSet> </toolsSet> + <codeAssistance> + </codeAssistance> <makefileType> <makeTool> <buildCommandWorkingDir>..</buildCommandWorkingDir> @@ -637,6 +657,8 @@ <remote-sources-mode>LOCAL_SOURCES</remote-sources-mode> <compilerSet>ARM_MIOSIX_EABI|GNU</compilerSet> </toolsSet> + <codeAssistance> + </codeAssistance> <makefileType> <makeTool> <buildCommandWorkingDir>..</buildCommandWorkingDir> @@ -683,6 +705,8 @@ <remote-sources-mode>LOCAL_SOURCES</remote-sources-mode> <compilerSet>ARM_MIOSIX_EABI|GNU</compilerSet> </toolsSet> + <codeAssistance> + </codeAssistance> <makefileType> <makeTool> <buildCommandWorkingDir>..</buildCommandWorkingDir> @@ -727,6 +751,8 @@ <remote-sources-mode>LOCAL_SOURCES</remote-sources-mode> <compilerSet>ARM_MIOSIX_EABI|GNU</compilerSet> </toolsSet> + <codeAssistance> + </codeAssistance> <makefileType> <makeTool> <buildCommandWorkingDir>..</buildCommandWorkingDir> @@ -736,8 +762,8 @@ <cTool> <incDir> <pElem>..</pElem> - <pElem>../miosix</pElem> <pElem>../miosix/arch/common</pElem> + <pElem>../miosix</pElem> <pElem>../miosix/arch/cortexM3_stm32f2/common</pElem> <pElem>../miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval</pElem> </incDir> @@ -751,8 +777,8 @@ <ccTool> <incDir> <pElem>..</pElem> - <pElem>../miosix</pElem> <pElem>../miosix/arch/common</pElem> + <pElem>../miosix</pElem> <pElem>../miosix/arch/cortexM3_stm32f2/common</pElem> <pElem>../miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval</pElem> </incDir> @@ -765,12 +791,545 @@ </ccTool> </makeTool> </makefileType> + <item path="../app_template/main.c" ex="false" tool="0" flavor2="2"> + <cTool> + </cTool> + </item> + <item path="../app_template_withlibs/main.c" ex="false" tool="0" flavor2="2"> + <cTool> + </cTool> + </item> + <item path="../app_template_withlibs/syscallfuffa.c" + ex="false" + tool="0" + flavor2="2"> + <cTool> + </cTool> + </item> + <item path="../main.cpp" ex="false" tool="1" flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/arch/arm7_lpc2000/lpc2138_miosix_board/core/interrupts.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/arch/arm7_lpc2000/lpc2138_miosix_board/drivers/serial.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/arch/arm7_lpc2000/lpc2138_miosix_board/interfaces-impl/bsp.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/arch/arm7_lpc2000/lpc2138_miosix_board/interfaces-impl/console.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/arch/arm7_lpc2000/lpc2138_miosix_board/interfaces-impl/delays.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/arch/arm7_lpc2000/lpc2138_miosix_board/interfaces-impl/disk.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/arch/arm7_lpc2000/lpc2138_miosix_board/interfaces-impl/portability.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/arch/common/drivers/dcc.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/arch/cortexM3_stm32/common/CMSIS/core_cm3.c" + ex="false" + tool="0" + flavor2="2"> + <cTool> + </cTool> + </item> + <item path="../miosix/arch/cortexM3_stm32/common/CMSIS/system_stm32f10x.c" + ex="false" + tool="0" + flavor2="2"> + <cTool> + </cTool> + </item> + <item path="../miosix/arch/cortexM3_stm32/common/core/interrupts.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/arch/cortexM3_stm32/common/drivers/serial.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/arch/cortexM3_stm32/common/interfaces-impl/delays.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/arch/cortexM3_stm32/common/interfaces-impl/disk.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/arch/cortexM3_stm32/common/interfaces-impl/gpio_impl.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/arch/cortexM3_stm32/common/interfaces-impl/portability.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/arch/cortexM3_stm32/stm32f100rb_stm32vldiscovery/core/stage_1_boot.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/arch/cortexM3_stm32/stm32f100rb_stm32vldiscovery/interfaces-impl/bsp.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/arch/cortexM3_stm32/stm32f100rb_stm32vldiscovery/interfaces-impl/console.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/arch/cortexM3_stm32/stm32f103ve_mp3v2/core/stage_1_boot.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/arch/cortexM3_stm32/stm32f103ve_mp3v2/interfaces-impl/bsp.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/arch/cortexM3_stm32/stm32f103ve_mp3v2/interfaces-impl/console.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/arch/cortexM3_stm32/stm32f103ve_strive_mini/core/stage_1_boot.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/arch/cortexM3_stm32/stm32f103ve_strive_mini/interfaces-impl/bsp.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/arch/cortexM3_stm32/stm32f103ve_strive_mini/interfaces-impl/console.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/arch/cortexM3_stm32/stm32f103ze_redbull_v2/core/stage_1_boot.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/arch/cortexM3_stm32/stm32f103ze_redbull_v2/interfaces-impl/bsp.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/arch/cortexM3_stm32/stm32f103ze_redbull_v2/interfaces-impl/console.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/arch/cortexM3_stm32/stm32f103ze_stm3210e-eval/core/stage_1_boot.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/arch/cortexM3_stm32/stm32f103ze_stm3210e-eval/interfaces-impl/bsp.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/arch/cortexM3_stm32/stm32f103ze_stm3210e-eval/interfaces-impl/console.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/arch/cortexM3_stm32f2/common/CMSIS/core_cm3.c" + ex="false" + tool="0" + flavor2="2"> + <cTool> + </cTool> + </item> + <item path="../miosix/arch/cortexM3_stm32f2/common/CMSIS/system_stm32f2xx.c" + ex="false" + tool="0" + flavor2="2"> + <cTool> + </cTool> + </item> + <item path="../miosix/arch/cortexM3_stm32f2/common/core/interrupts.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/arch/cortexM3_stm32f2/common/interfaces-impl/disk.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/arch/cortexM3_stm32f2/common/interfaces-impl/gpio_impl.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/arch/cortexM3_stm32f2/common/interfaces-impl/portability.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/core/stage_1_boot.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/interfaces-impl/bsp.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/interfaces-impl/console.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/interfaces-impl/delays.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/arch/cortexM3_stm32f2/stm32f207zg_EthBoardV2/core/stage_1_boot.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/arch/cortexM3_stm32f2/stm32f207zg_EthBoardV2/interfaces-impl/bsp.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/arch/cortexM3_stm32f2/stm32f207zg_EthBoardV2/interfaces-impl/console.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/arch/cortexM3_stm32f2/stm32f207zg_EthBoardV2/interfaces-impl/delays.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/arch/cortexM4_stm32f4/common/CMSIS/system_stm32f4xx.c" + ex="false" + tool="0" + flavor2="2"> + <cTool> + </cTool> + </item> + <item path="../miosix/arch/cortexM4_stm32f4/common/core/interrupts.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/arch/cortexM4_stm32f4/common/interfaces-impl/delays.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/arch/cortexM4_stm32f4/common/interfaces-impl/gpio_impl.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/arch/cortexM4_stm32f4/common/interfaces-impl/portability.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/arch/cortexM4_stm32f4/stm32f407vg_stm32f4discovery/core/stage_1_boot.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/arch/cortexM4_stm32f4/stm32f407vg_stm32f4discovery/interfaces-impl/bsp.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/arch/cortexM4_stm32f4/stm32f407vg_stm32f4discovery/interfaces-impl/console.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/examples/sad_trombone/adpcm.c" + ex="false" + tool="0" + flavor2="2"> + <cTool> + </cTool> + </item> + <item path="../miosix/examples/sad_trombone/convert.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/examples/sad_trombone/main.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/examples/sad_trombone/player.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/examples/thread_native/native_thread_example.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/examples/thread_pthread/pthread_example.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/kernel/elf_program.cpp" ex="false" tool="1" flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/kernel/error.cpp" ex="false" tool="1" flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/kernel/filesystem/diskio.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/kernel/filesystem/ff.c" ex="false" tool="0" flavor2="2"> + <cTool> + </cTool> + </item> + <item path="../miosix/kernel/filesystem/filesystem.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/kernel/kernel.cpp" ex="false" tool="1" flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/kernel/process.cpp" ex="false" tool="1" flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/kernel/process_pool.cpp" ex="false" tool="1" flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/kernel/pthread.cpp" ex="false" tool="1" flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/kernel/scheduler/control/control_scheduler.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/kernel/scheduler/edf/edf_scheduler.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/kernel/scheduler/priority/priority_scheduler.cpp" + ex="false" + tool="1" + flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/kernel/stage_2_boot.cpp" ex="false" tool="1" flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/kernel/sync.cpp" ex="false" tool="1" flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/kernel/syscalls.cpp" ex="false" tool="1" flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/kernel/unistd.cpp" ex="false" tool="1" flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/testsuite/testsuite.cpp" ex="false" tool="1" flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/util/crc16.cpp" ex="false" tool="1" flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/util/lcd44780.cpp" ex="false" tool="1" flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/util/util.cpp" ex="false" tool="1" flavor2="4"> + <ccTool> + </ccTool> + </item> + <item path="../miosix/util/version.cpp" ex="false" tool="1" flavor2="4"> + <ccTool> + </ccTool> + </item> </conf> <conf name="stm32f207zg_ethboard_v2" type="0"> <toolsSet> <remote-sources-mode>LOCAL_SOURCES</remote-sources-mode> <compilerSet>ARM_MIOSIX_EABI|GNU</compilerSet> </toolsSet> + <codeAssistance> + </codeAssistance> <makefileType> <makeTool> <buildCommandWorkingDir>..</buildCommandWorkingDir> diff --git a/miosix_np_processes/nbproject/private/configurations.xml b/miosix_np_processes/nbproject/private/configurations.xml index ad5c7713..5cdaf53c 100644 --- a/miosix_np_processes/nbproject/private/configurations.xml +++ b/miosix_np_processes/nbproject/private/configurations.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<configurationDescriptor version="80"> +<configurationDescriptor version="84"> <projectmakefile>miosix_np_2-Makefile.mk</projectmakefile> <confs> <conf name="Default" type="0"> diff --git a/miosix_np_processes/nbproject/private/private.xml b/miosix_np_processes/nbproject/private/private.xml index 3cbb1f78..8053867a 100644 --- a/miosix_np_processes/nbproject/private/private.xml +++ b/miosix_np_processes/nbproject/private/private.xml @@ -8,4 +8,11 @@ <activeConfIndexElem>8</activeConfIndexElem> </data> <editor-bookmarks xmlns="http://www.netbeans.org/ns/editor-bookmarks/1"/> + <editor-bookmarks xmlns="http://www.netbeans.org/ns/editor-bookmarks/2" lastBookmarkId="0"/> + <preferences xmlns="http://www.netbeans.org/ns/auxiliary-configuration-preferences/1"> + <module name="org-netbeans-modules-cnd-discovery"> + <property name="folder" value="/home/andrea/embedded/from_git/miosix-kernel"/> + <property name="rootFolder" value="/home/andrea/embedded/from_git/miosix-kernel"/> + </module> + </preferences> </project-private> diff --git a/miosix_np_processes/nbproject/private/stm32f207ig_stm3220g-eval.properties b/miosix_np_processes/nbproject/private/stm32f207ig_stm3220g-eval.properties new file mode 100644 index 00000000..e69de29b diff --git a/sd.patch b/sd.patch new file mode 100644 index 00000000..a6f2cd40 --- /dev/null +++ b/sd.patch @@ -0,0 +1,59 @@ +diff --git a/miosix/arch/cortexM3_stm32f2/common/interfaces-impl/disk.cpp b/miosix/arch/cortexM3_stm32f2/common/interfaces-impl/disk.cpp +index 970a538..7fae556 100644 +--- a/miosix/arch/cortexM3_stm32f2/common/interfaces-impl/disk.cpp ++++ b/miosix/arch/cortexM3_stm32f2/common/interfaces-impl/disk.cpp +@@ -70,9 +70,9 @@ static CardType cardType=Invalid; + + //SD card GPIOs + typedef Gpio<GPIOC_BASE,8> sdD0; +-typedef Gpio<GPIOC_BASE,9> sdD1; +-typedef Gpio<GPIOC_BASE,10> sdD2; +-typedef Gpio<GPIOC_BASE,11> sdD3; ++//typedef Gpio<GPIOC_BASE,9> sdD1; //QUIRK: use serial port and SD ++//typedef Gpio<GPIOC_BASE,10> sdD2; ++//typedef Gpio<GPIOC_BASE,11> sdD3; + typedef Gpio<GPIOC_BASE,12> sdCLK; + typedef Gpio<GPIOD_BASE,2> sdCMD; + +@@ -705,8 +705,9 @@ private: + static const unsigned int CLOCK_MAX=0; //48MHz/(0+2) =24MHz + + ///\internal Clock enabled, bus width 4bit, clock powersave enabled. +- static const unsigned int CLKCR_FLAGS=SDIO_CLKCR_CLKEN | +- SDIO_CLKCR_WIDBUS_0 | SDIO_CLKCR_PWRSAV; ++ //static const unsigned int CLKCR_FLAGS=SDIO_CLKCR_CLKEN | ++ // SDIO_CLKCR_WIDBUS_0 | SDIO_CLKCR_PWRSAV; ++ static const unsigned int CLKCR_FLAGS=SDIO_CLKCR_CLKEN; //QUIRK: use serial port and SD + + ///\internal Maximum number of calls to IRQreduceClockSpeed() allowed + static const unsigned char MAX_ALLOWED_REDUCTIONS=5; +@@ -1092,12 +1093,12 @@ static void initSDIOPeripheral() + RCC->APB2ENR |= RCC_APB2ENR_SDIOEN; + sdD0::mode(Mode::ALTERNATE); + sdD0::alternateFunction(12); +- sdD1::mode(Mode::ALTERNATE); +- sdD1::alternateFunction(12); +- sdD2::mode(Mode::ALTERNATE); +- sdD2::alternateFunction(12); +- sdD3::mode(Mode::ALTERNATE); +- sdD3::alternateFunction(12); ++// sdD1::mode(Mode::ALTERNATE); //QUIRK: use serial port and SD ++// sdD1::alternateFunction(12); ++// sdD2::mode(Mode::ALTERNATE); ++// sdD2::alternateFunction(12); ++// sdD3::mode(Mode::ALTERNATE); ++// sdD3::alternateFunction(12); + sdCLK::mode(Mode::ALTERNATE); + sdCLK::alternateFunction(12); + sdCMD::mode(Mode::ALTERNATE); +@@ -1273,8 +1274,8 @@ void Disk::init() + return; + } + +- r=Command::send(Command::ACMD6,2); //Set 4 bit bus width +- if(r.validateR1Response()==false) return; ++ //r=Command::send(Command::ACMD6,2); //Set 4 bit bus width ++ //if(r.validateR1Response()==false) return; //QUIRK: use serial port and SD + + if(cardType!=SDHC) + { diff --git a/system_app_test/Makefile b/system_app_test/Makefile new file mode 100644 index 00000000..c822afb4 --- /dev/null +++ b/system_app_test/Makefile @@ -0,0 +1,44 @@ +## +## Makefile for writing PROGRAMS for the Miosix embedded OS +## TFT:Terraneo Federico Technlogies +## + +SRC := \ +main.c + +## Replaces both "foo.cpp"-->"foo.o" and "foo.c"-->"foo.o" +OBJ := $(addsuffix .o, $(basename $(SRC))) + +AS := arm-miosix-eabi-as +CC := arm-miosix-eabi-gcc +CXX := arm-miosix-eabi-g++ +SZ := arm-miosix-eabi-size + +AFLAGS := -mcpu=cortex-m3 -mthumb +CFLAGS := -mcpu=cortex-m3 -mthumb -mfix-cortex-m3-ldrd -fpie -msingle-pic-base \ + -ffunction-sections -O2 -Wall -c +CXXFLAGS := $(CFLAGS) +LFLAGS := -mcpu=cortex-m3 -mthumb -mfix-cortex-m3-ldrd -fpie -msingle-pic-base \ + -Wl,--gc-sections,-Map,test.map,-T./miosix.ld,-n,-pie,--spare-dynamic-tags,3 \ + -O2 -nostdlib + +LINK_LIBS := -Wl,--start-group -lstdc++ -lc -lm -lgcc -Wl,--end-group + +all: $(OBJ) crt0.o + $(CXX) $(LFLAGS) -o test.elf $(OBJ) crt0.o $(LINK_LIBS) + $(SZ) test.elf + @arm-miosix-eabi-objdump -Dslx test.elf > test.txt + @mx-postlinker test.elf --ramsize=16384 --stacksize=2048 --strip-sectheader + @xxd -i test.elf | sed 's/unsigned char/const unsigned char __attribute__((aligned(8)))/' > prog3.h + +clean: + -rm $(OBJ) crt0.o test.elf test.map test.txt + +%.o: %.s + $(AS) $(AFLAGS) $< -o $@ + +%.o : %.c + $(CC) $(CFLAGS) $< -o $@ + +%.o : %.cpp + $(CXX) $(CXXFLAGS) $< -o $@ diff --git a/system_app_test/crt0.o b/system_app_test/crt0.o new file mode 100644 index 0000000000000000000000000000000000000000..45821e39a1ba00b79dc79f44dce1f616a26ba10c GIT binary patch literal 1464 zcmb<-^>JflWMqH=Mg|QA1doA12Et)A0V~j85MbbC`2YRie-LI;X1LF$%y7TJogGYa zf=OmD$pR)>!K9-C0|P^1YGP6*1EUxN0|Tpbeo;wkg|4qL0~;5+FDDa&UU6k^Nn#R% zUU5kggwBAmic)j*N>VFI81zySOA;CMl8TENzyf;lsTG+eP<DPnY95rCoReRi3S}2p z7MG;vLOJC{nI$lZqSV9`sBmd<PHJiagPvoMuU=wFNl|7}X-R4^*t<j$@(c{%Fk^$N z2Za>}lntUFLCC-$&A`CG2@-(f6|4*l0t^fcd{F%?3=9k)eX3ACGgO@ol!j3-^R%Jr z38^!Hng??q$UKl;=;ndML1x3$IWRCVz}O(QAUP22j%J=44t2q3>U?mhOF&Z>ghO2p znz{%a>dMj7#o<ub!oa}5%)n3p@)HQBFfcGEf*4Q?^RFO89aNNop_PGwVG5iFiF*(i zq@D@HfZ{pK3=9_-85sB(7#Ktt7#Kid4vKG38i2(aNNEl$1A`Ta0mUG5piG<;GdRT| zq?tiJL2wzE8CcL%pqk3ez=|f%iliG9E^KJ>$SDCN&yFU~j;5ajO&*l85lWaDIML)m zp@J;Wg(lC1kOapEH<~;*nmi9UykWi;Vqj!IRso6!5Jt$eGJwh^1fLC@UlDwEaN0od zIT$pc=?rAC5CbQJ9txj}!5D?l&A^~i!Vq6vl2}y2keis9#{en7z(p6N(1I3Mkb(+a VL_rHDkPQqBT%wRP#3jbS0021faPj~E literal 0 HcmV?d00001 diff --git a/system_app_test/crt0.s b/system_app_test/crt0.s new file mode 100644 index 00000000..7733008e --- /dev/null +++ b/system_app_test/crt0.s @@ -0,0 +1,130 @@ +/* + * Startup script for writing PROGRAMS for the Miosix embedded OS + * TFT:Terraneo Federico Technlogies + */ + +.syntax unified +.cpu cortex-m3 +.thumb + +.section .text + +/** + * _start, program entry point + */ +.global _start +.type _start, %function +_start: + /* TODO: .ctor */ + bl main + /* TODO: .dtor */ + bl _exit + +/** + * _exit, terminate process + * \param v exit value + */ +.section .text._exit +.global _exit +.type _exit, %function +_exit: + movs r3, #2 + svc 0 + +/** + * open, open a file + * \param fd file descriptor + * \param file access mode + * \param xxx access permisions + * \return file descriptor or -1 if errors + */ +.section .text.open +.global open +.type open, %function +open: + movs r3, #6 + svc 0 + bx lr + +/** + * close, close a file + * \param fd file descriptor + */ +.section .text.close +.global close +.type close, %function +close: + movs r3, #7 + svc 0 + bx lr + +/** + * lseek + * \param fd file descriptor + * \param pos moving offset + * \param start position, SEEK_SET, SEEK_CUR or SEEK_END + +.section .text.lseek +.global lseek +.type lseek, %function + + movs r3, #8 + svc 0 + bx lr +*/ + +/** + * system, fork and execture a program, blocking + * \param program to execute + */ +.section .text.system +.global system +.type system, %function +system: + movs r3, #9 + svc 0 + bx lr +/** + * write, write to file + * \param fd file descriptor + * \param buf data to be written + * \param len buffer length + * \return number of written bytes or -1 if errors + */ +.section .text.write +.global write +.type write, %function +write: + movs r3, #3 + svc 0 + bx lr + +/** + * read, read from file + * \param fd file descriptor + * \param buf data to be read + * \param len buffer length + * \return number of read bytes or -1 if errors + */ +.section .text.read +.global read +.type read, %function +read: + movs r3, #4 + svc 0 + bx lr + +/** + * usleep, sleep a specified number of microseconds + * \param us number of microseconds to sleep + * \return 0 on success or -1 if errors + */ +.section .text.usleep +.global usleep +.type usleep, %function +usleep: + movs r3, #5 + svc 0 + bx lr + +.end diff --git a/system_app_test/log.txt b/system_app_test/log.txt new file mode 100644 index 00000000..947e1fa9 --- /dev/null +++ b/system_app_test/log.txt @@ -0,0 +1,5 @@ +arm-miosix-eabi-g++ -mcpu=cortex-m3 -mthumb -mfix-cortex-m3-ldrd -fpie -msingle-pic-base -Wl,--gc-sections,-Map,main.map,-T./miosix.ld,-n,-pie,--spare-dynamic-tags,3 -O2 -nostdlib -fPIC -o main.elf main.o crt0.o -Wl,--start-group -lstdc++ -lc -lm -lgcc -Wl,--end-group +/opt/arm-miosix-eabi/lib/gcc/arm-eabi/4.5.2/../../../../arm-eabi/bin/ld: /opt/arm-miosix-eabi/lib/gcc/arm-eabi/4.5.2/../../../../arm-eabi/lib/thumb/thumb2/libc.a(lib_a-syslseek.o): relocation R_ARM_THM_MOVW_ABS_NC against `_impure_ptr' can not be used when making a shared object; recompile with -fPIC +/opt/arm-miosix-eabi/lib/gcc/arm-eabi/4.5.2/../../../../arm-eabi/lib/thumb/thumb2/libc.a: could not read symbols: Bad value +collect2: ld returned 1 exit status +make: *** [all] Error 1 diff --git a/system_app_test/main.c b/system_app_test/main.c new file mode 100644 index 00000000..c6ba3cc4 --- /dev/null +++ b/system_app_test/main.c @@ -0,0 +1,20 @@ +#include <unistd.h> + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <string.h> +#include <stdio.h> + +int main(){ + int x[64 * 1024]; + + int i = 123; + unsigned int *p = &i; + + p = p - 1; + *p = 567; + + + return 123; +} diff --git a/system_app_test/main.c~ b/system_app_test/main.c~ new file mode 100644 index 00000000..482b2198 --- /dev/null +++ b/system_app_test/main.c~ @@ -0,0 +1,51 @@ + +#include <unistd.h> + +int mystrlen(const char *s) +{ + int result=0; + while(*s++) result++; + return result; +} + +int main() +{ + static const char str[]="Test: 0=divzero 1=sleep 5s, 2=exit 3=bkpt 4=dangling 5=open\n"; + static const char str2[]="Unexpected command\n"; + for(;;) + { + char result[100]; + write(1,str,mystrlen(str)); + int len=read(0,result,sizeof(result)); + if(len<1) continue; + int i=10/(int)(result[0]-'0'); + unsigned int *p=(unsigned int *)0xc0000000; + + int fp = 0; + + switch(result[0]) + { + case '0': + usleep(i); + break; + case '1': + usleep(5000000); + break; + case '2': + return 0; + case '3': + asm volatile("bkpt"); + break; + case '4': + usleep(*p); + break; + case '5': + fp = open("", 123); + if(fp == 123) + write(1, "ok\0", 3); + break; + default: + write(1,str2,mystrlen(str2)); + } + } +} diff --git a/system_app_test/main.elf b/system_app_test/main.elf new file mode 100755 index 0000000000000000000000000000000000000000..415be3f1ab0bc0cef7286b18c4a94ec83d56800d GIT binary patch literal 220 zcmb<-^>JflWMqH=CI$@#5N{>}1A_@vkcokT)r3KTff>pN$<JV5V1Qu(1_lNYW@TVt z;9y_?>t6v;3lbIpnFGRX3=9k`3=9lR3=9lg7#J9M7#IXVSc8Fq0fb@lV67jRelUQr lLV-JzGQ)k4I<Pnc1A{1x0kYNsY@YzgV&BaC;>-$!Bme_!59<H` literal 0 HcmV?d00001 diff --git a/system_app_test/main.map b/system_app_test/main.map new file mode 100644 index 00000000..d8545ea3 --- /dev/null +++ b/system_app_test/main.map @@ -0,0 +1,128 @@ + +Discarded input sections + + .text 0x0000000000000000 0x0 main.o + .data 0x0000000000000000 0x0 main.o + .bss 0x0000000000000000 0x0 main.o + .text.mystrlen + 0x0000000000000000 0x14 main.o + .comment 0x0000000000000000 0x12 main.o + .ARM.attributes + 0x0000000000000000 0x31 main.o + .data 0x0000000000000000 0x0 crt0.o + .bss 0x0000000000000000 0x0 crt0.o + .text.open 0x0000000000000000 0x6 crt0.o + .text.close 0x0000000000000000 0x6 crt0.o + .text.system 0x0000000000000000 0x6 crt0.o + .text.write 0x0000000000000000 0x6 crt0.o + .text.read 0x0000000000000000 0x6 crt0.o + .text.usleep 0x0000000000000000 0x6 crt0.o + .ARM.attributes + 0x0000000000000000 0x21 crt0.o + +Memory Configuration + +Name Origin Length Attributes +*default* 0x0000000000000000 0xffffffffffffffff + +Linker script and memory map + + 0x0000000000000094 . = (0x0 + SIZEOF_HEADERS) + +.text 0x0000000000000098 0x10 + *(.text) + .text 0x0000000000000098 0x8 crt0.o + 0x0000000000000098 _start + *(.text.*) + .text.main 0x00000000000000a0 0x4 main.o + 0x00000000000000a0 main + .text._exit 0x00000000000000a4 0x4 crt0.o + 0x00000000000000a4 _exit + *(.gnu.linkonce.t.*) + +.glue_7 0x00000000000000a8 0x0 + .glue_7 0x0000000000000000 0x0 linker stubs + +.glue_7t 0x00000000000000a8 0x0 + .glue_7t 0x0000000000000000 0x0 linker stubs + +.vfp11_veneer 0x00000000000000a8 0x0 + .vfp11_veneer 0x0000000000000000 0x0 linker stubs + +.v4_bx 0x00000000000000a8 0x0 + .v4_bx 0x0000000000000000 0x0 linker stubs + +.plt 0x00000000000000a8 0x0 + .plt 0x0000000000000000 0x0 main.o + +.rel.dyn 0x00000000000000a8 0x0 + .rel.plt 0x0000000000000000 0x0 main.o + +.rel.data + *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) + +.rel.got 0x00000000000000a8 0x0 + *(.rel.got) + .rel.got 0x0000000000000000 0x0 main.o + 0x0000000010000000 . = 0x10000000 + +.got 0x0000000010000000 0xc + *(.got.plt) + .got.plt 0x0000000010000000 0xc main.o + 0x0000000010000000 _GLOBAL_OFFSET_TABLE_ + *(.igot.plt) + *(.got) + .got 0x0000000000000000 0x0 main.o + *(.igot) + +.dynamic 0x000000001000000c 0x28 + *(.dynamic) + .dynamic 0x000000001000000c 0x28 main.o + 0x000000001000000c _DYNAMIC + +.rodata + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + +.gnu.version_d 0x0000000010000034 0x0 + .gnu.version_d + 0x0000000000000000 0x0 main.o + +.gnu.version 0x0000000010000034 0x0 + .gnu.version 0x0000000000000000 0x0 main.o + +.gnu.version_r 0x0000000010000034 0x0 + .gnu.version_r + 0x0000000000000000 0x0 main.o + +.data + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + +.bss + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + +.dynbss 0x0000000010000034 0x0 + .dynbss 0x0000000000000000 0x0 main.o + +/DISCARD/ + *(.interp) + *(.dynsym) + *(.dynstr) + *(.hash) + *(.comment) + *(.ARM.attributes) +LOAD main.o +LOAD crt0.o +START GROUP +LOAD /opt/arm-miosix-eabi/lib/gcc/arm-eabi/4.5.2/../../../../arm-eabi/lib/thumb/thumb2/libstdc++.a +LOAD /opt/arm-miosix-eabi/lib/gcc/arm-eabi/4.5.2/../../../../arm-eabi/lib/thumb/thumb2/libc.a +LOAD /opt/arm-miosix-eabi/lib/gcc/arm-eabi/4.5.2/../../../../arm-eabi/lib/thumb/thumb2/libm.a +LOAD /opt/arm-miosix-eabi/lib/gcc/arm-eabi/4.5.2/thumb/thumb2/libgcc.a +END GROUP +OUTPUT(main.elf elf32-littlearm) diff --git a/system_app_test/miosix.ld b/system_app_test/miosix.ld new file mode 100644 index 00000000..c91c803e --- /dev/null +++ b/system_app_test/miosix.ld @@ -0,0 +1,66 @@ +/* + * Linker script for writing PROGRAMS for the Miosix embedded OS + * TFT:Terraneo Federico Technlogies + */ + +OUTPUT_FORMAT("elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) + +SECTIONS +{ + /* Here starts the first elf segment, that stays in flash */ + . = 0 + SIZEOF_HEADERS; + + .text : ALIGN(8) + { + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + } + + .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) } + .rel.got : { *(.rel.got) } + + /* Here starts the second segment, that is copied in RAM and relocated */ + . = 0x10000000; + + .got : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) } + + /* FIXME: If this is put in the other segment, it makes it writable */ + .dynamic : { *(.dynamic) } + + /* FIXME: The compiler insists in addressing rodata relative to r9 */ + .rodata : ALIGN(8) + { + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + } + + .data : ALIGN(8) + { + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + } + + .bss : ALIGN(8) + { + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + } + + /* These are removed since are unused and increase binary size */ + /DISCARD/ : + { + *(.interp) + *(.dynsym) + *(.dynstr) + *(.hash) + *(.comment) + *(.ARM.attributes) + } +} diff --git a/system_app_test/prog3.h b/system_app_test/prog3.h new file mode 100644 index 00000000..df98510d --- /dev/null +++ b/system_app_test/prog3.h @@ -0,0 +1,22 @@ +const unsigned char __attribute__((aligned(8))) test_elf[] = { + 0x7f, 0x45, 0x4c, 0x46, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x99, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x05, 0x34, 0x00, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, + 0x98, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x10, 0x34, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0xb4, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10, 0x0c, 0x00, 0x00, 0x10, + 0x28, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x02, 0xf8, + 0x00, 0xf0, 0x02, 0xf8, 0x7b, 0x20, 0x70, 0x47, 0x02, 0x23, 0x00, 0xdf, + 0x0c, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x08, 0x00, 0x00, + 0x4d, 0x69, 0x6f, 0x73, 0x69, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; +unsigned int test_elf_len = 220; diff --git a/system_app_test/test.txt b/system_app_test/test.txt new file mode 100644 index 00000000..2c5c7a70 --- /dev/null +++ b/system_app_test/test.txt @@ -0,0 +1,76 @@ + +test.elf: file format elf32-littlearm +test.elf +architecture: arm, flags 0x00000050: +HAS_SYMS, DYNAMIC +start address 0x00000099 + +Program Header: + LOAD off 0x00000098 vaddr 0x00000098 paddr 0x00000098 align 2**3 + filesz 0x00000010 memsz 0x00000010 flags r-x + LOAD off 0x000000a8 vaddr 0x10000000 paddr 0x10000000 align 2**2 + filesz 0x00000034 memsz 0x00000034 flags rw- + DYNAMIC off 0x000000b4 vaddr 0x1000000c paddr 0x1000000c align 2**2 + filesz 0x00000028 memsz 0x00000028 flags rw- + +Dynamic Section: + DEBUG 0x00000000 +private flags = 5000002: [Version5 EABI] [has entry point] + +Sections: +Idx Name Size VMA LMA File off Algn + 0 .text 00000010 00000098 00000098 00000098 2**3 + CONTENTS, ALLOC, LOAD, READONLY, CODE + 1 .got 0000000c 10000000 10000000 000000a8 2**2 + CONTENTS, ALLOC, LOAD, DATA + 2 .dynamic 00000028 1000000c 1000000c 000000b4 2**2 + CONTENTS, ALLOC, LOAD, DATA +SYMBOL TABLE: +00000098 l d .text 00000000 .text +10000000 l d .got 00000000 .got +1000000c l d .dynamic 00000000 .dynamic +00000000 l df *ABS* 00000000 main.c +1000000c l O *ABS* 00000000 _DYNAMIC +10000000 l O *ABS* 00000000 _GLOBAL_OFFSET_TABLE_ +00000098 g F .text 00000000 _start +000000a0 g F .text 00000004 main +000000a4 g F .text 00000000 _exit + + +Contents of section .text: + 0098 00f002f8 00f002f8 7b207047 022300df ........{ pG.#.. +Contents of section .got: + 10000000 0c000010 00000000 00000000 ............ +Contents of section .dynamic: + 1000000c 15000000 00000000 00000000 00000000 ................ + 1000001c 00000000 00000000 00000000 00000000 ................ + 1000002c 00000000 00000000 ........ + +Disassembly of section .text: + +00000098 <_start>: +_start(): + 98: f000 f802 bl a0 <main> + 9c: f000 f802 bl a4 <_exit> + +000000a0 <main>: +main(): + a0: 207b movs r0, #123 ; 0x7b + a2: 4770 bx lr + +000000a4 <_exit>: +_exit(): + a4: 2302 movs r3, #2 + a6: df00 svc 0 + +Disassembly of section .got: + +10000000 <.got>: +10000000: 1000000c andne r0, r0, ip + ... + +Disassembly of section .dynamic: + +1000000c <.dynamic>: +1000000c: 00000015 andeq r0, r0, r5, lsl r0 + ... -- GitLab