void Process::run() { //proc -> status = ACTIVE; /* run_test() returns 0 if data waiting 1 if no data waiting, but not all upstream connections are closed 2 if no input ports or input ports are only IIP ports or all input ports closed */ for( ; ; ) { if (2 == run_test() && ! must_run && ! self_starting) break; Port * cpp = in_ports; while (cpp != 0) { for (int i = 0; i < cpp -> elem_count; i++) { if (cpp -> elem_list[i].gen.connxn == 0) continue; if (! cpp -> elem_list[i].is_IIP) cpp -> elem_list[i].closed = FALSE; } cpp = cpp -> succ; } // // execute component code! value = faddr (proc_anchor); // component code returns if (value > 0) printf ("Process %s returned with value %d\n", procname, value); if (owned_IPs > 0) printf("%s Deactivated with %d IPs not disposed of\n", procname, owned_IPs); cpp = in_ports; while (cpp != 0) { for (int i = 0; i < cpp -> elem_count; i++) { Cnxt * cnp = cpp -> elem_list[i].gen.connxn; if (cnp == 0) continue; if (cpp -> elem_list[i].is_IIP) cpp -> elem_list[i].closed = TRUE; } cpp = cpp -> succ; } if (trace) printf("%s Deactivated with retcode %d\n", procname, value); if (value > 4) { //proc -> terminating = TRUE; break; } int res; /* res = 0 if data in cnxt; 1 if upstream not closed; 2 if upstream closed */ res = run_test(); if (res == 2) break; if (res == 0) continue; dormwait(); } /* Process * lpProc; // This should only be done at termination time! if (lpProc -> end_port != 0) { lpProc -> value = thzcrep(lpProc, &lpProc -> int_ptr, 0, "\0"); lpProc -> int_pe.cpptr = lpProc -> end_port; lpProc -> value = thzsend(lpProc, &lpProc -> int_ptr, &lpProc -> int_pe, 0); if (lpProc -> value > 0) lpProc -> value = thzdrop(lpProc, &lpProc -> int_ptr); //break; } */ //close_outputPorts(proc); Port * cpp = out_ports; while (cpp != 0) { for (int i = 0; i < cpp -> elem_count; i++) { if (cpp -> elem_list[i].gen.connxn == 0) continue; /*value = */ thziclos(this, cpp, i); } cpp = cpp -> succ; } //close_inputPorts(proc); cpp = in_ports; while (cpp != 0) { for (int i = 0; i < cpp -> elem_count; i++) { if (cpp -> elem_list[i].gen.connxn == 0) continue; if (! cpp -> elem_list[i].is_IIP) thziclos(this, cpp, i); } cpp = cpp -> succ; } //printf("Terminated %s\n", proc -> procname); status = TERMINATED; if (trace) printf("%s Terminated with retcode %d\n", procname, value); //proc -> thread.join(); network -> latch -> count_down(); }
bool PruTimer::initPRU(const std::string &firmware_stepper, const std::string &firmware_endstops) { std::unique_lock<std::mutex> lk(mutex_memory); firmwareStepper = firmware_stepper; firmwareEndstop = firmware_endstops; #ifdef DEMO_PRU ddr_size=0x40000; ddr_mem = (uint8_t*)malloc(ddr_size); ddr_addr = (unsigned long)ddr_mem; LOG( "The DDR memory reserved for the PRU is 0x" << std::hex << ddr_size << " and has addr 0x" << std::hex << ddr_addr << std::endl); if (ddr_mem == NULL) { return false; } ddr_write_location = ddr_mem; ddr_nr_events = (uint32_t*)(ddr_mem+ddr_size-4); ddr_mem_end = ddr_mem+ddr_size-8; pru_control = (uint32_t*)(ddr_mem+ddr_size-8); *((uint32_t*)ddr_write_location)=0; //So that the PRU waits *ddr_nr_events = 0; currentReadingAddress = ddr_write_location; #else unsigned int ret; tpruss_intc_initdata pruss_intc_initdata = PRUSS_INTC_INITDATA; LOG( "Initializing PRU..." << std::endl); /* Initialize the PRU */ prussdrv_init (); /* Open PRU Interrupt */ ret = prussdrv_open(PRU_EVTOUT_0); if (ret) { LOG( "prussdrv_open failed" << std::endl); return false; } /* Open PRU sync Interrupt */ ret = prussdrv_open(PRU_EVTOUT_1); if (ret) { LOG( "prussdrv_open failed (sync interrupt)" << std::endl); return false; } /* Get the interrupt initialized */ prussdrv_pruintc_init(&pruss_intc_initdata); std::ifstream faddr("/sys/class/uio/uio0/maps/map1/addr"); if(!faddr.good()) { LOG( "Failed to read /sys/class/uio/uio0/maps/map1/addr\n"); return false; } std::ifstream fsize("/sys/class/uio/uio0/maps/map1/size"); if(!faddr.good()) { LOG( "Failed to read /sys/class/uio/uio0/maps/map1/size\n"); return false; } std::string s; std::getline(faddr, s); ddr_addr = std::stoul(s, nullptr, 16); std::getline(fsize, s); ddr_size = std::stoul(s, nullptr, 16); if(!ddr_size || !ddr_addr) { LOG("[ERROR] Unable to find DDR address and size for PRU" << std::endl); return false; } LOG( "The DDR memory reserved for the PRU is 0x" << std::hex << ddr_size << " and has addr 0x" << std::hex << ddr_addr << std::endl); /* open the device */ mem_fd = open("/dev/mem", O_RDWR | O_SYNC); if (mem_fd < 0) { LOG( "Failed to open /dev/mem " << strerror(errno) << std::endl);; return false; } /* map the memory */ ddr_mem = (uint8_t*)mmap(0, ddr_size, PROT_WRITE | PROT_READ, MAP_SHARED, mem_fd, ddr_addr); if (ddr_mem == NULL) { LOG( "Failed to map the device "<< strerror(errno) << std::endl); close(mem_fd); return false; } LOG( "Mapped memory starting at 0x" << std::hex << (unsigned long)ddr_mem << std::endl << std::dec); ddr_write_location = ddr_mem; ddr_nr_events = (uint32_t*)(ddr_mem+ddr_size-4); ddr_mem_end = ddr_mem+ddr_size-8; pru_control = (uint32_t*)(ddr_mem+ddr_size-8); initalizePRURegisters(); //bzero(ddr_mem, ddr_size); /* Execute firmwares on PRU */ LOG( ("\tINFO: Starting stepper firmware on PRU0\r\n")); ret = prussdrv_exec_program (PRU_NUM0, firmware_stepper.c_str()); if(ret!=0) { LOG( "[WARNING] Unable to execute firmware on PRU0" << std::endl); } LOG( ("\tINFO: Starting endstop firmware on PRU1\r\n")); ret=prussdrv_exec_program (PRU_NUM1, firmware_endstops.c_str()); if(ret!=0) { LOG( "[WARNING] Unable to execute firmware on PRU1" << std::endl); } //std::this_thread::sleep_for( std::chrono::milliseconds( 1000 ) ); /*prussdrv_pru_wait_event (PRU_EVTOUT_0); printf("\tINFO: PRU0 completed transfer of endstop.\r\n"); prussdrv_pru_clear_event (PRU_EVTOUT_0, PRU0_ARM_INTERRUPT);*/ #endif ddr_mem_used = 0; blocksID = std::queue<BlockDef>(); currentNbEvents = 0; totalQueuedMovesTime = 0; return true; }