diff --git a/Makefile b/Makefile index 1f741a862888f514581152a232a250426033b9ee..c5c788c70861b741f3ecc9b3aad8ec354ec339ad 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ SUBDIRS := miosix ## List here your source files (both .s, .c and .cpp) ## SRC := \ -main.cpp +main_processes.cpp ## ## List here additional static libraries with relative path diff --git a/miosix/arch/cortexM4_stm32f4/common/interfaces-impl/portability.cpp b/miosix/arch/cortexM4_stm32f4/common/interfaces-impl/portability.cpp index 8e85fe65fdfa7306de0e0e64e33bb9d78fe65b09..98b1c072066e163aebe4c5cbcdf158ad73ae3a4f 100644 --- a/miosix/arch/cortexM4_stm32f4/common/interfaces-impl/portability.cpp +++ b/miosix/arch/cortexM4_stm32f4/common/interfaces-impl/portability.cpp @@ -277,6 +277,8 @@ void initCtxsave(unsigned int *ctxsave, void *(*pc)(void *), unsigned int *sp, ctxsave[0]=reinterpret_cast<unsigned long>(stackPtr); //--> psp ctxsave[6]=reinterpret_cast<unsigned long>(gotBase); //--> r9 //leaving the content of r4-r8,r10-r11 uninitialized + ctxsave[9]=0xfffffffd; //EXC_RETURN=thread mode, use psp, no floating ops + //leaving the content of s16-s31 uninitialized } static unsigned int sizeToMpu(unsigned int size) diff --git a/miosix/config/Makefile.inc b/miosix/config/Makefile.inc index 7aaca4d797a1c0457fc5e6a8dfe84846429d3ec2..db9bd7a9fb11a8c4873dbfd0fdb139e1b22e31bc 100644 --- a/miosix/config/Makefile.inc +++ b/miosix/config/Makefile.inc @@ -13,12 +13,12 @@ ## architecture ## #OPT_BOARD := lpc2138_miosix_board -OPT_BOARD := stm32f103ze_stm3210e-eval +#OPT_BOARD := stm32f103ze_stm3210e-eval #OPT_BOARD := stm32f103ve_mp3v2 #OPT_BOARD := stm32f100rb_stm32vldiscovery #OPT_BOARD := stm32f103ve_strive_mini #OPT_BOARD := stm32f103ze_redbull_v2 -#OPT_BOARD := stm32f407vg_stm32f4discovery +OPT_BOARD := stm32f407vg_stm32f4discovery #OPT_BOARD := stm32f207ig_stm3220g-eval #OPT_BOARD := stm32f207zg_ethboard_v2 #OPT_BOARD := stm32f207ze_als_camboard @@ -32,8 +32,8 @@ OPT_BOARD := stm32f103ze_stm3210e-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 @@ -137,9 +137,9 @@ ifeq ($(OPT_BOARD),stm32f407vg_stm32f4discovery) ## 3) Same as 1) but space has been reserved for a process pool, allowing ## to configure the kernel with "#define WITH_PROCESSES" LINKER_SCRIPT_PATH := arch/cortexM4_stm32f4/stm32f407vg_stm32f4discovery/ - LINKER_SCRIPT := $(LINKER_SCRIPT_PATH)stm32_1m+192k_rom.ld + #LINKER_SCRIPT := $(LINKER_SCRIPT_PATH)stm32_1m+192k_rom.ld #LINKER_SCRIPT := $(LINKER_SCRIPT_PATH)stm32_1m+192k_ram.ld - #LINKER_SCRIPT := $(LINKER_SCRIPT_PATH)stm32_1m+192k_rom_processes.ld + LINKER_SCRIPT := $(LINKER_SCRIPT_PATH)stm32_1m+192k_rom_processes.ld ## This causes the interrupt vector table to be relocated in SRAM, must be ## uncommented when using the ram linker script diff --git a/miosix/config/miosix_settings.h b/miosix/config/miosix_settings.h index 475b1a7342cd59e5cf9658839223f0215e3648d6..9bf45c016dc17ec918d2f6206d828c086796d4ed 100644 --- a/miosix/config/miosix_settings.h +++ b/miosix/config/miosix_settings.h @@ -67,7 +67,7 @@ namespace miosix { /// This enables the dynamic loader to load elf programs, the extended system /// call service and, if the hardware supports it, the MPU to provide memory /// isolation of processes -//#define WITH_PROCESSES +#define WITH_PROCESSES #if defined(WITH_PROCESSES) && defined(__NO_EXCEPTIONS) #error Processes require C++ exception support @@ -125,7 +125,7 @@ const unsigned char MAX_OPEN_FILES=8; * 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/filesystem/file_access.cpp b/miosix/filesystem/file_access.cpp index 6d9eb5a73c24b3c84b645bf81af72b8f01ab3605..06466f983da24b37c99fb4ed0717eaf249110450 100644 --- a/miosix/filesystem/file_access.cpp +++ b/miosix/filesystem/file_access.cpp @@ -10,6 +10,8 @@ using namespace std; +#undef WITH_PROCESSES // <----------------------- FIXME! remove this! + #ifdef WITH_FILESYSTEM namespace miosix { diff --git a/miosix/kernel/kernel.cpp b/miosix/kernel/kernel.cpp index eb041051d34966e8cce8e6e3fe6c60b0fb7f9bdb..9ef0323a9c8f160a2d321ff0c44bcd03a42c6c87 100644 --- a/miosix/kernel/kernel.cpp +++ b/miosix/kernel/kernel.cpp @@ -741,7 +741,7 @@ void Thread::setupUserspaceContext(unsigned int entry, unsigned int *gotBase, unsigned int ramImageSize) { void *(*startfunc)(void*)=reinterpret_cast<void *(*)(void*)>(entry); - unsigned int *ep=gotBase+ramImageSize/4; + unsigned int *ep=gotBase+ramImageSize/sizeof(int); miosix_private::initCtxsave(cur->userCtxsave,startfunc,ep,0,gotBase); } diff --git a/miosix/kernel/process.cpp b/miosix/kernel/process.cpp index edbaef3ff7c1945389d2691cc07b72416a429a7b..18a6ba0bf9f1c1f1d801b7ce7dfbb7c4d21c1357 100644 --- a/miosix/kernel/process.cpp +++ b/miosix/kernel/process.cpp @@ -31,6 +31,9 @@ #include <cstring> #include <algorithm> #include <sys/wait.h> +#include <sys/types.h> +#include <unistd.h> +#include <fcntl.h> #include <signal.h> #include <limits.h> @@ -72,15 +75,50 @@ using namespace std; namespace miosix { +/** + * This class contains information on all the processes in the system + */ +class Processes +{ +public: + /** + * \return the instance of this class (singleton) + */ + static Processes& instance(); + + ///Maps the pid to the Process instance. Includes zombie processes + map<pid_t,Process *> processes; + list<Process *> kernelChilds; + list<Process *> kernelZombies; + ///Used to assign a new pid to a process + pid_t pidCounter; + ///Uset to guard access to processes and pidCounter + Mutex procMutex; + ///Used to wait on process termination + ConditionVariable genericWaiting; + +private: + Processes() {} + Processes(const Processes&); + Processes& operator=(const Processes&); +}; + +Processes& Processes::instance() +{ + static Processes singleton; + return singleton; +} + // // class Process // pid_t Process::create(const ElfProgram& program) { + Processes& p=Processes::instance(); auto_ptr<Process> proc(new Process(program)); { - Lock<Mutex> l(procMutex); + Lock<Mutex> l(p.procMutex); proc->pid=getNewPid(); if(Thread::getCurrentThread()->proc!=0) { @@ -88,20 +126,20 @@ pid_t Process::create(const ElfProgram& program) Thread::getCurrentThread()->proc->childs.push_back(proc.get()); } else { proc->ppid=0; - kernelChilds.push_back(proc.get()); + p.kernelChilds.push_back(proc.get()); } - processes[proc->pid]=proc.get(); + p.processes[proc->pid]=proc.get(); } Thread *thr=Thread::createUserspace(Process::start,0,Thread::DEFAULT, proc.get()); if(thr==0) { - Lock<Mutex> l(procMutex); - processes.erase(proc->pid); + Lock<Mutex> l(p.procMutex); + p.processes.erase(proc->pid); if(Thread::getCurrentThread()->proc!=0) { Thread::getCurrentThread()->proc->childs.remove(proc.get()); - } else kernelChilds.remove(proc.get()); + } else p.kernelChilds.remove(proc.get()); throw runtime_error("Thread creation failed"); } //Cannot throw bad_alloc due to the reserve in Process's constructor. @@ -117,15 +155,17 @@ pid_t Process::create(const ElfProgram& program) pid_t Process::getppid(pid_t proc) { - Lock<Mutex> l(procMutex); - map<pid_t,Process *>::iterator it=processes.find(proc); - if(it==processes.end()) return -1; + Processes& p=Processes::instance(); + Lock<Mutex> l(p.procMutex); + map<pid_t,Process *>::iterator it=p.processes.find(proc); + if(it==p.processes.end()) return -1; return it->second->ppid; } pid_t Process::waitpid(pid_t pid, int* exit, int options) { - Lock<Mutex> l(procMutex); + Processes& p=Processes::instance(); + Lock<Mutex> l(p.procMutex); Process *self=Thread::getCurrentThread()->proc; if(self==0) { @@ -133,15 +173,15 @@ pid_t Process::waitpid(pid_t pid, int* exit, int options) if(pid<=0) { //Wait for a generic child process - if(kernelZombies.empty() && (options & WNOHANG)) return 0; - while(kernelZombies.empty()) + if(p.kernelZombies.empty() && (options & WNOHANG)) return 0; + while(p.kernelZombies.empty()) { - if(kernelChilds.empty()) return -1; - genericWaiting.wait(l); + if(p.kernelChilds.empty()) return -1; + p.genericWaiting.wait(l); } - Process *joined=kernelZombies.front(); - kernelZombies.pop_front(); - processes.erase(joined->pid); + Process *joined=p.kernelZombies.front(); + p.kernelZombies.pop_front(); + p.processes.erase(joined->pid); if(joined->waitCount!=0) errorHandler(UNEXPECTED); if(exit!=0) *exit=joined->exitCode; pid_t result=joined->pid; @@ -149,8 +189,8 @@ pid_t Process::waitpid(pid_t pid, int* exit, int options) return result; } else { //Wait on a specific child process - map<pid_t,Process *>::iterator it=processes.find(pid); - if(it==processes.end() || it->second->ppid!=0) return -1; + map<pid_t,Process *>::iterator it=p.processes.find(pid); + if(it==p.processes.end() || it->second->ppid!=0) return -1; Process *joined=it->second; if(joined->zombie==false) { @@ -169,8 +209,8 @@ pid_t Process::waitpid(pid_t pid, int* exit, int options) { if(exit!=0) *exit=joined->exitCode; result=joined->pid; - kernelZombies.remove(joined); - processes.erase(joined->pid); + p.kernelZombies.remove(joined); + p.processes.erase(joined->pid); delete joined; } return result; @@ -184,11 +224,11 @@ pid_t Process::waitpid(pid_t pid, int* exit, int options) while(self->zombies.empty()) { if(self->childs.empty()) return -1; - genericWaiting.wait(l); + p.genericWaiting.wait(l); } Process *joined=self->zombies.front(); self->zombies.pop_front(); - processes.erase(joined->pid); + p.processes.erase(joined->pid); if(joined->waitCount!=0) errorHandler(UNEXPECTED); if(exit!=0) *exit=joined->exitCode; pid_t result=joined->pid; @@ -196,8 +236,8 @@ pid_t Process::waitpid(pid_t pid, int* exit, int options) return result; } else { //Wait on a specific child process - map<pid_t,Process *>::iterator it=processes.find(pid); - if(it==processes.end() || it->second->ppid!=self->pid + map<pid_t,Process *>::iterator it=p.processes.find(pid); + if(it==p.processes.end() || it->second->ppid!=self->pid || pid==self->pid) return -1; Process *joined=it->second; if(joined->zombie==false) @@ -216,7 +256,7 @@ pid_t Process::waitpid(pid_t pid, int* exit, int options) result=joined->pid; if(exit!=0) *exit=joined->exitCode; self->zombies.remove(joined); - processes.erase(joined->pid); + p.processes.erase(joined->pid); delete joined; } return result; @@ -395,9 +435,9 @@ void *Process::start(void *argv) case 8: //seek if(proc->mFiles.find(sp.getFirstParameter()) != proc->mFiles.end()) - sp.setReturnValue(Filesystem::instance().lseekFile(sp.getFirstParameter(), - sp.getSecondParameter(), - sp.getThirdParameter())); + sp.setReturnValue(lseek(sp.getFirstParameter(), + sp.getSecondParameter(), + sp.getThirdParameter())); else sp.setReturnValue(-1); @@ -435,29 +475,30 @@ void *Process::start(void *argv) if(Thread::testTerminate()) running=false; } while(running); { - Lock<Mutex> l(procMutex); + Processes& p=Processes::instance(); + Lock<Mutex> l(p.procMutex); proc->zombie=true; list<Process*>::iterator it; for(it=proc->childs.begin();it!=proc->childs.end();++it) (*it)->ppid=0; for(it=proc->zombies.begin();it!=proc->zombies.end();++it) (*it)->ppid=0; - kernelChilds.splice(kernelChilds.begin(),proc->childs); - kernelZombies.splice(kernelZombies.begin(),proc->zombies); + p.kernelChilds.splice(p.kernelChilds.begin(),proc->childs); + p.kernelZombies.splice(p.kernelZombies.begin(),proc->zombies); if(proc->ppid!=0) { - map<pid_t,Process *>::iterator it=processes.find(proc->ppid); - if(it==processes.end()) errorHandler(UNEXPECTED); + map<pid_t,Process *>::iterator it=p.processes.find(proc->ppid); + if(it==p.processes.end()) errorHandler(UNEXPECTED); it->second->childs.remove(proc); if(proc->waitCount>0) proc->waiting.broadcast(); else { it->second->zombies.push_back(proc); - genericWaiting.broadcast(); + p.genericWaiting.broadcast(); } } else { - kernelChilds.remove(proc); + p.kernelChilds.remove(proc); if(proc->waitCount>0) proc->waiting.broadcast(); else { - kernelZombies.push_back(proc); - genericWaiting.broadcast(); + p.kernelZombies.push_back(proc); + p.genericWaiting.broadcast(); } } } @@ -466,22 +507,16 @@ void *Process::start(void *argv) pid_t Process::getNewPid() { - for(;;pidCounter++) + Processes& p=Processes::instance(); + for(;;p.pidCounter++) { - if(pidCounter<0) pidCounter=1; - if(pidCounter==0) continue; //Zero is not a valid pid - map<pid_t,Process*>::iterator it=processes.find(pidCounter); - if(it!=processes.end()) continue; //Pid number already used - return pidCounter++; + if(p.pidCounter<0) p.pidCounter=1; + if(p.pidCounter==0) continue; //Zero is not a valid pid + map<pid_t,Process*>::iterator it=p.processes.find(p.pidCounter); + if(it!=p.processes.end()) continue; //Pid number already used + return p.pidCounter++; } } - -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 diff --git a/miosix/kernel/process.h b/miosix/kernel/process.h index 466f0be9b1c99bb672078ba64d85f748e9f6c517..74000c49a4c36fe1a3c093ae61f41a366944c8af 100644 --- a/miosix/kernel/process.h +++ b/miosix/kernel/process.h @@ -138,17 +138,6 @@ private: bool zombie; ///< True for terminated not yet joined processes short int exitCode; ///< Contains the exit code - ///Maps the pid to the Process instance. Includes zombie processes - static std::map<pid_t,Process *> processes; - static std::list<Process *> kernelChilds; - static std::list<Process *> kernelZombies; - ///Used to assign a new pid to a process - static pid_t pidCounter; - ///Uset to guard access to processes and pidCounter - static Mutex procMutex; - ///Used to wait on process termination - static ConditionVariable genericWaiting; - //Needs access to fault,mpu friend class Thread; //Needs access to mpu diff --git a/miosix_np_2/nbproject/configurations.xml b/miosix_np_2/nbproject/configurations.xml index 67a1bf426ca87c1c3514d31b10edfce8fec6b108..39084b9013a071155ed4f90f2bb5bc540d0f598c 100644 --- a/miosix_np_2/nbproject/configurations.xml +++ b/miosix_np_2/nbproject/configurations.xml @@ -369,13 +369,22 @@ <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> + <in>elf_types.h</in> <in>error.cpp</in> <in>error.h</in> <in>intrusive.h</in> <in>kernel.cpp</in> <in>kernel.h</in> <in>logging.h</in> + <in>process.cpp</in> + <in>process.h</in> + <in>process_pool.cpp</in> + <in>process_pool.h</in> <in>pthread.cpp</in> <in>pthread_private.h</in> <in>stage_2_boot.cpp</in> @@ -406,6 +415,7 @@ <in>miosix.h</in> </df> <in>main.cpp</in> + <in>main_processes.cpp</in> </df> <logicalFolder name="ExternalFiles" displayName="Important Files" @@ -2687,6 +2697,8 @@ </makefileType> <item path="../main.cpp" ex="false" tool="1" flavor2="0"> </item> + <item path="../main_processes.cpp" ex="false" tool="1" flavor2="0"> + </item> <item path="../miosix/arch/arm7_lpc2000/common/arch_settings.h" ex="false" tool="3" @@ -3624,8 +3636,18 @@ </item> <item path="../miosix/interfaces/portability.h" ex="false" tool="3" flavor2="0"> </item> + <item path="../miosix/kernel/SystemMap.cpp" ex="false" tool="1" flavor2="0"> + </item> + <item path="../miosix/kernel/SystemMap.h" ex="false" tool="3" flavor2="0"> + </item> <item path="../miosix/kernel/buffer_queue.h" ex="false" tool="3" flavor2="0"> </item> + <item path="../miosix/kernel/elf_program.cpp" ex="false" tool="1" flavor2="0"> + </item> + <item path="../miosix/kernel/elf_program.h" ex="false" tool="3" flavor2="0"> + </item> + <item path="../miosix/kernel/elf_types.h" ex="false" tool="3" flavor2="0"> + </item> <item path="../miosix/kernel/error.cpp" ex="false" tool="1" flavor2="0"> </item> <item path="../miosix/kernel/error.h" ex="false" tool="3" flavor2="0"> @@ -3638,6 +3660,14 @@ </item> <item path="../miosix/kernel/logging.h" ex="false" tool="3" flavor2="0"> </item> + <item path="../miosix/kernel/process.cpp" ex="false" tool="1" flavor2="0"> + </item> + <item path="../miosix/kernel/process.h" ex="false" tool="3" flavor2="0"> + </item> + <item path="../miosix/kernel/process_pool.cpp" ex="false" tool="1" flavor2="0"> + </item> + <item path="../miosix/kernel/process_pool.h" ex="false" tool="3" flavor2="0"> + </item> <item path="../miosix/kernel/pthread.cpp" ex="false" tool="1" flavor2="0"> </item> <item path="../miosix/kernel/pthread_private.h" ex="false" tool="3" flavor2="0"> diff --git a/miosix_np_2/nbproject/private/configurations.xml b/miosix_np_2/nbproject/private/configurations.xml index 22bd63d0bec88ddb006f5e8f678ef3fc00a3e017..8f9a726dbc00d5814d9d85bc30d206159af49289 100644 --- a/miosix_np_2/nbproject/private/configurations.xml +++ b/miosix_np_2/nbproject/private/configurations.xml @@ -2,6 +2,17 @@ <configurationDescriptor version="89"> <logicalFolder name="root" displayName="root" projectFiles="true" kind="ROOT"> <df root=".." name="miosix_np_2"> + <df name="app_template"> + <in>crt0.s</in> + <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"> @@ -388,13 +399,22 @@ <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> + <in>elf_types.h</in> <in>error.cpp</in> <in>error.h</in> <in>intrusive.h</in> <in>kernel.cpp</in> <in>kernel.h</in> <in>logging.h</in> + <in>process.cpp</in> + <in>process.h</in> + <in>process_pool.cpp</in> + <in>process_pool.h</in> <in>pthread.cpp</in> <in>pthread_private.h</in> <in>stage_2_boot.cpp</in> @@ -427,6 +447,7 @@ <df name="miosix_np_2"> </df> <in>main.cpp</in> + <in>main_processes.cpp</in> </df> </logicalFolder> <projectmakefile>miosix_np_2-Makefile.mk</projectmakefile>