/************************************************************************************************************************ * Printing.c * High managment logical unit of slow motors in the system ( 6 dispensers and the screw motor) * profile run up begins from screw homing to begin position and only then from fast motors activation. * when every slow motor tuches the limit switch (no matter whether its screw or dispenser) * an interrupt occures in the system and as long as its pushing the limit switch all the system is prevented from operation. * because of that the work flow with interrupts must be : * design a function handle (what to do in the moment the interrupt arrives) * configure the wanted interrupt in the cfg file (according to the defined port and pin and its interrupt number and the handler) * enable interupt for predefined gpio in the application * when the interrupt arrives the handle will be automatically called * in case of the limit switches since the operation is continuess the interrupt must be disabled in order to continue the application running. * then the operation is not continues (like butten pushing) there is no need in disabling the interrupts * Printing module is responsible for : * operating diffrent winding algorithms with predefined parameters from the UI * operating the dispensers according to predefined dispensing rate from the UI **************************************************************************************************************************/ ////////////////////////////////State machine operation//////////////////////////////////// //the state machine operation is used to operate in runtime correct profile flow execution //by recieved esign flow of the user from the UI /////////////////////////////////////////////////////////////////////////////////////////// #include #include #include "include.h" #include #include #include #include "Common/report/report.h" #include "PMR/Printing/JobSegment.pb-c.h" #include "PMR/Printing/JobRequest.pb-c.h" #include "PMR/Printing/JobResponse.pb-c.h" #include "PMR/Printing/CurrentJobRequest.pb-c.h" #include "PMR/Printing/CurrentJobResponse.pb-c.h" #include "PMR/Printing/ResumeCurrentJobRequest.pb-c.h" #include "PMR/Printing/ResumeCurrentJobResponse.pb-c.h" #include "PMR/Printing/JobUploadStrategy.pb-c.h" #include "PMR/Printing/JobStatus.pb-c.h" #include "PMR/Printing/AbortJobRequest.pb-c.h" #include "PMR/Printing/AbortJobResponse.pb-c.h" #include "PMR/Hardware/Hardwaremotor.pb-c.h" #include "PMR/Hardware/HardwareWinder.pb-c.h" #include "PMR/common/MessageContainer.pb-c.h" #include "PMR/Diagnostics/EventType.pb-c.h" #include "PMR/MachineStatus/MachineStatus.pb-c.h" #include "Modules/General/MachineStatus.h" #include "Modules/General/process.h" #include "modules/Diagnostics/Diagnostics.h" #include "PMR/Stubs/StubJobRequest.pb-c.h" #include "PMR/Stubs/StubJobResponse.pb-c.h" #include "PMR/Stubs/StubAbortJobRequest.pb-c.h" #include "PMR/Stubs/StubAbortJobResponse.pb-c.h" #include "PMR/Diagnostics/ThreadJoggingRequest.pb-c.h" #include "PMR/Diagnostics/ThreadJoggingResponse.pb-c.h" #include "PMR/Diagnostics/ThreadAbortJoggingRequest.pb-c.h" #include "PMR/Diagnostics/ThreadAbortJoggingResponse.pb-c.h" #include "StateMachines/Initialization/PowerIdle.h" #include "drivers/Motors/Motor.h" #include "./printingSTM.h" #include "modules/thread/thread_ex.h" #include "modules/AlarmHandling/AlarmHandling.h" #include "modules/ids/ids_ex.h" #include "Modules/heaters/heaters_ex.h" #include "Modules/control/control.h" #define MAX_TICKET_SIZE 10000 Mailbox_Handle JobmsgQ = NULL; JobEndReasonEnum JobEndReason = JOB_OK; ErrorCode JobError_to_ErrorCode[JOB_ERRORS_MAX+1] = {ERROR_CODE__NONE,ERROR_CODE__JOB_UNSPECIFIED_ERROR,ERROR_CODE__JOB_THREAD_BREAK,ERROR_CODE__JOB_WINDER_DANCER_FAIL, ERROR_CODE__JOB_POOLER_DANCER_FAIL,ERROR_CODE__JOB_FEEDER_DANCER_FAIL,ERROR_CODE__JOB_OUT_OF_DYE,ERROR_CODE__JOB_OTHER_ALARM, ERROR_CODE__JOB_TEMPERATURE_ALARM,ERROR_CODE__JOB_LS_ALARM,ERROR_CODE__JOB_PRESSURE_ALARM,ERROR_CODE__JOB_CURRENT_ALARM, ERROR_CODE__JOB_MOTOR_ALARM,ERROR_CODE__JOB_LIDS_OPEN,ERROR_CODE__JOB_ABORTED_BY_USER,ERROR_CODE__JOB_SAFETY_ALARM,ERROR_CODE__JOB_OTHER_ALARM}; JobTicket *CurrentJob = NULL; JobRequest *CurrentRequest = NULL; double previousJobLength; uint32_t StubControlId = 0xFF; double StubLengthCounter = 0,StubLength = 0,StubSpeed=0; JobTicket Ticket; JobSegment *TSegment; JobBrushStop *TbrushStop; JobDispenser *Tdispenser; JobSpool *Tspool; bool CopyConfigured[MAX_SYSTEM_MODULES]; bool CleaningJobActive = false, JoggingJobActive = false; char ErrorMsg[100]; JobUploadStrategy uploadstrategy = JOB_UPLOAD_STRATEGY__Default; ModuleStateEnum PrepareWaiting[MAX_SYSTEM_MODULES] = {ModuleIdle,ModuleIdle,ModuleIdle,ModuleIdle,ModuleIdle}; double job_length = 0.0; /******************************************************************************************** * functions describes motor operation flow and movement state during profile execution * used to operate in runtime correct profileflow execution *********************************************************************************************/ //static ReturnCode IdleState(void *JobDetails); //static ReturnCode ValidateState(void *JobDetails); static ReturnCode PrepareState(void *JobDetails); static ReturnCode PrintState(void *JobDetails); //static ReturnCode CleanState(void *JobDetails); static ReturnCode ExitState(void *JobDetails); /********************************************************************** * the array and enum of JobState_t below must be in sync order ***********************************************************************/ //static ReturnCode (* state[])(void *JobDetails) = { IdleState, ValidateState, PrepareState, PrintState, CleanState}; void AbortJob(char *Msg); typedef enum { Idle= 0, Validate, PrepareJob, Print, Clean, ExitJob } JobState_t; typedef struct { JobState_t m_sourceState; ReturnCode m_returnCode; JobState_t m_destinationState; } Transition_t; ////////////////////////Slow Motor State//////////////////////////////////// bool JobActive = false; bool JobResumed = false; char JobToken[36+1]={0}; bool JobAbortedByUser = false; //////////////////////////////////////////////////////////////////////////// void StartJob(void *JobDetails); //******************************************************************************************************************** bool JobIsActive(void) { return JobActive; } /******************************************************************************************************************** *function describes entry point of motor in profile execution - accelerate from stop position *function described above used to operate motor operation flow and movement state during profile execution *********************************************************************************************************************/ /*static ReturnCode IdleState(void *JobDetails) { ReturnCode retcode; retcode = JobSuccess; return retcode; }*/ //******************************************************************************************************************** /*static ReturnCode ValidateState(void *JobDetails) { ReturnCode retcode; retcode = JobSuccess; return retcode; }*/ //******************************************************************************************************************** bool GetHeatersPrepareWaiting(void) { if (PrepareWaiting[Module_Heaters] == ModuleWaiting) return true; else return false; } //******************************************************************************************************************** static ReturnCode PrepareState(void *JobDetails) { ReturnCode retcode; retcode = JobSuccess; //start (fast??) heating DiagnosticsStart(); if (Configured[Module_IDS]) { PrepareWaiting[Module_IDS] = ModuleWaiting; // REPORT_MSG(Module_IDS,"Dispenser prepare waiting"); } if (Configured[Module_Thread]) { PrepareWaiting[Module_Thread] = ModuleWaiting; } if (Configured[Module_Winder]) { PrepareWaiting[Module_Winder] = ModuleWaiting; } if (Configured[Module_Heaters]) { if (HeaterCheckReady() == false) // if heaters are in heating / cooling state we must wait for them PrepareWaiting[Module_Heaters] = ModuleWaiting; } //wait for fast heating to end //start other peripheral systems: chiller, waist handling //check thread type if (Configured[Module_IDS]) { //REPORT_MSG(Module_IDS,"Dispenser prepare called"); IDSPrepareState(JobDetails); } /* if (Configured[Module_Heaters]) { //heaters preparation starts on process parameters handling }*/ if (Configured[Module_Thread]) { ThreadPrepareState(CurrentJob); } if (Configured[Module_Winder]) { if( Winder_Prepare(CurrentJob)!= OK) { SendJobProgress(0.0, 0, false, "Winder prepare failed !!!!"); } } return retcode; } //******************************************************************************************************************** uint32_t PrepareReady(int ModuleId, ModuleStateEnum result) { int i; bool ready = true; uint32_t retcode = 0,status = OK; JobMessageStruc Message; assert (ModuleIdmessageId = PrintRequest; Message.msglen = 10; if (JobmsgQ != NULL) Mailbox_post(JobmsgQ , &Message, BIOS_NO_WAIT); return retcode; } //******************************************************************************************************************** /*static ReturnCode CleanState(void *JobDetails) { ReturnCode retcode; retcode = JobSuccess; return retcode; }*/ //******************************************************************************************************************** static ReturnCode ExitState(void *JobDetails) { ReturnCode retcode; retcode = JobStop; return retcode; } /*static void JobClockHandle(UArg arg0) { //Clock_setTimeout(JobClock, 1000); //Clock_start(JobClock); }*/ //******************************************************************************************************************** /*void JobInit(void) { Clock_Params_init(&jobclkParams); jobclkParams.period = 0; jobclkParams.startFlag = FALSE; JobClock = Clock_create(JobClockHandle, 0, &jobclkParams, NULL); return ; }*/ //******************************************************************************************************************** void JobAbortFunc(MessageContainer* requestContainer) { MessageContainer responseContainer; uint8_t* container_buffer; AbortJobRequest* request = abort_job_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data); //AbortJob(); AbortJobResponse response = ABORT_JOB_RESPONSE__INIT; responseContainer = createContainer(MESSAGE_TYPE__AbortJobResponse, requestContainer->token, false, &response, &abort_job_response__pack, &abort_job_response__get_packed_size); container_buffer = my_malloc(message_container__get_packed_size(&responseContainer)); size_t container_size = message_container__pack(&responseContainer, container_buffer); my_free(responseContainer.data.data); SendChars((char*)container_buffer, container_size); abort_job_request__free_unpacked(request,NULL); JobEndReason = JOB_ABORTED_BY_USER; JobAbortedByUser = true; AbortJob("Job Aborted by user"); //We keep the job request until it is done } //******************************************************************************************************************** uint32_t ThreadJoggingFunc(int speed) { ProcessParameters ProcessParametersCopy; uint32_t status = OK; if (JobIsActive() == true) { status = ERROR; LOG_ERROR(JobIsActive(),"Jog JobIsActive"); } else { memcpy(&CopyConfigured,&Configured,sizeof(CopyConfigured)); usnprintf(ErrorMsg, 80,"Copy Configured T %d W %d I %d H %d W %d",CopyConfigured[Module_Thread],CopyConfigured[Module_Winder],CopyConfigured[Module_IDS],CopyConfigured[Module_Heaters],CopyConfigured[Module_Waste]); Report(ErrorMsg, __FILE__, __LINE__, 0, RpWarning, 0, 0); JoggingJobActive = true; //set the job handler to ignore heaters, ids and waste in the state machine Configured[Module_Thread] = true; Configured[Module_Winder] = true; Configured[Module_IDS] = false; Configured[Module_Heaters] = false; Configured[Module_Waste] = false; //set the requested speed without changing other process parameters memcpy (&ProcessParametersCopy,&ProcessParametersKeep,sizeof(ProcessParameters)); if(speed) ProcessParametersCopy.dyeingspeed = speed; else ProcessParametersCopy.dyeingspeed = 40; if (HandleProcessParameters(&ProcessParametersCopy)!= OK) { status = FAILED; } else { //load essential job prameters to enable thread running Ticket.n_segments = 1; n_segments = 1; Ticket.segments = my_malloc(sizeof(Ticket.segments)); TSegment = my_malloc(sizeof(JobSegment)); Tspool = my_malloc(sizeof(JobSpool)); TSegment->length = 200.0; TSegment->n_brushstops = 0; Ticket.segments[0] = TSegment; Tspool->backingrate = 32; Tspool->bottombackingrate = 32; Tspool->segmentoffsetpulses = 1000; Tspool->startoffsetpulses = 220; Tspool->rotationsperpassage = 3.1415926*2; Ticket.spool = Tspool; CurrentJob = &Ticket; InternalWindingConfigMessage(Tspool); StartJob(&Ticket); } } return status; } //******************************************************************************************************************** uint32_t ThreadCleaningJobFunc(int speed) { ProcessParameters ProcessParametersCopy; JobEndReasonEnum JobAlarmReason = JOB_OK; uint32_t status = OK; if (JobIsActive() == true) { status = ERROR; LOG_ERROR(JobIsActive(),"Jog JobIsActive"); } else { if (isMotorConfigured(CLEANER_DISPENSER + HARDWARE_MOTOR_TYPE__MOTO_DISPENSER_1)==false) { status = ERROR; LOG_ERROR(JobIsActive(),"Jog No cleaner dispenser"); } else { memcpy(&CopyConfigured,&Configured,sizeof(CopyConfigured)); CleaningJobActive = true; usnprintf(ErrorMsg, 80,"Copy Configured T %d W %d I %d H %d W %d",CopyConfigured[Module_Thread],CopyConfigured[Module_Winder],CopyConfigured[Module_IDS],CopyConfigured[Module_Heaters],CopyConfigured[Module_Waste]); Report(ErrorMsg, __FILE__, __LINE__, 0, RpWarning, 0, 0); //set the job handler to ignore heaters, ids and waste in the state machine Configured[Module_Thread] = true; Configured[Module_Winder] = true; Configured[Module_IDS] = true; Configured[Module_Heaters] = true; Configured[Module_Waste] = false; //set the requested speed without changing other process parameters memcpy (&ProcessParametersCopy,&ProcessParametersKeep,sizeof(ProcessParameters)); if(speed) ProcessParametersCopy.dyeingspeed = speed; else ProcessParametersCopy.dyeingspeed = 40; if (HandleProcessParameters(&ProcessParametersCopy)!= OK) { LOG_ERROR(FAILED,"Jog HandleProcessParameters"); status = FAILED; } else { //load essential job prameters to enable thread running Ticket.uploadstrategy = JOB_UPLOAD_STRATEGY__Default; Ticket.n_segments = 1; Ticket.enableintersegment = true; Ticket.intersegmentlength = 100; n_segments = 2; Ticket.segments = my_malloc(sizeof(Ticket.segments)*2); TSegment = my_malloc(sizeof(JobSegment)); Tspool = my_malloc(sizeof(JobSpool)); TbrushStop = my_malloc(sizeof(JobBrushStop)); TSegment->length = 10.0; TSegment->n_brushstops = 1; TSegment->brushstops = my_malloc(sizeof(TSegment->brushstops)); TSegment->brushstops[0] = TbrushStop; Tdispenser = my_malloc(sizeof(JobDispenser)); TbrushStop->has_index =true; TbrushStop->index = 0; TbrushStop->n_dispensers = 1; TbrushStop->dispensers = my_malloc(sizeof(TbrushStop->dispensers)); TbrushStop->dispensers[0] = Tdispenser; Tdispenser->nanolitterpersecond = 10000; Tdispenser->nanoliterperpulse = 2.34; Tdispenser->dispenserstepdivision = DISPENSER_STEP_DIVISION__Auto; Tdispenser->index = 4; //TI dispenser Ticket.segments[0] = TSegment; Ticket.segments[1] = TSegment; Tspool->backingrate = 32; Tspool->bottombackingrate = 32; Tspool->segmentoffsetpulses = 1000; Tspool->startoffsetpulses = 220; Tspool->rotationsperpassage = 3.1415926*2; Ticket.spool = Tspool; CurrentJob = &Ticket; JobAlarmReason = AlarmHandlingPrepareJob(CurrentJob); if (JobAlarmReason !=OK) { LOG_ERROR(JobAlarmReason,"Jog JobAlarmReason"); return ERROR; } InternalWindingConfigMessage(Tspool); StartJob(&Ticket); } } } return status; } void ThreadJoggingRequestFunc(MessageContainer* requestContainer) { uint32_t status = OK; MessageContainer responseContainer; ThreadJoggingRequest* request = thread_jogging_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data); ThreadJoggingResponse response = THREAD_JOGGING_RESPONSE__INIT; if (JobIsActive() == true) { AbortJob(0); //set the job handler to handle heaters, ids and waste in the state machine Task_sleep(100); //let the job end procedure role before returning the configuration to normal. usnprintf(ErrorMsg, 80,"Copy Configured T %d W %d I %d H %d W %d",CopyConfigured[Module_Thread],CopyConfigured[Module_Winder],CopyConfigured[Module_IDS],CopyConfigured[Module_Heaters],CopyConfigured[Module_Waste]); Report(ErrorMsg, __FILE__, __LINE__, 0, RpWarning, 0, 0); my_free(Ticket.segments); my_free(TSegment); my_free(Tspool); } else { status = ThreadJoggingFunc(request->speed); } responseContainer = createContainer(MESSAGE_TYPE__ThreadJoggingResponse, requestContainer->token, true, &response, &thread_jogging_response__pack, &thread_jogging_response__get_packed_size); if (status!= OK) { responseContainer.error = ERROR_CODE__INVALID_PARAMETER; responseContainer.errormessage = "JOb Active or incorrect parameters"; } // responseContainer.continuous = false; uint8_t* container_buffer = my_malloc(message_container__get_packed_size(&responseContainer)); size_t container_size = message_container__pack(&responseContainer, container_buffer); SendChars(container_buffer, container_size); my_free(responseContainer.data.data); return ; } void ThreadAbortJoggingFunc(void) { /* if (JobIsActive() == true) { AbortJob(0); //set the job handler to handle heaters, ids and waste in the state machine Task_sleep(100); //let the job end procedure role before returning the configuration to normal. usnprintf(ErrorMsg, 80,"Copy Configured T %d W %d I %d H %d W %d",CopyConfigured[Module_Thread],CopyConfigured[Module_Winder],CopyConfigured[Module_IDS],CopyConfigured[Module_Heaters],CopyConfigured[Module_Waste]); Report(ErrorMsg, __FILE__, __LINE__, 0, RpWarning, 0, 0); my_free(Ticket.segments); my_free(TSegment); my_free(Tspool); } */ } void ThreadAbortJoggingRequestFunc(MessageContainer* requestContainer) { //uint32_t status = OK; MessageContainer responseContainer; ThreadAbortJoggingRequest* request = thread_abort_jogging_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data); ThreadAbortJoggingResponse response = THREAD_ABORT_JOGGING_RESPONSE__INIT; ThreadAbortJoggingFunc(); responseContainer = createContainer(MESSAGE_TYPE__ThreadAbortJoggingResponse, requestContainer->token, false, &response, &thread_abort_jogging_response__pack, &thread_abort_jogging_response__get_packed_size); responseContainer.continuous = false; uint8_t* container_buffer = my_malloc(message_container__get_packed_size(&responseContainer)); if (container_buffer) { size_t container_size = message_container__pack(&responseContainer, container_buffer); SendChars(container_buffer, container_size); } if (responseContainer.data.data) my_free(responseContainer.data.data); return ; } //******************************************************************************************************************** uint32_t SendStubJobProgress(uint32_t IfIndex, uint32_t readValue) { MessageContainer responseContainer; uint8_t* container_buffer; bool done = false; // //REPORT_MSG(msdid++,logmsg); Report("Stub Job",__FILE__,__LINE__,StubLengthCounter,RpWarning,StubLength, StubSpeed); if (JobToken[0] == 0) return OK; StubJobResponse response = STUB_JOB_RESPONSE__INIT; JobStatus jobStatus = JOB_STATUS__INIT; jobStatus.has_progress = true; jobStatus.progress = StubLengthCounter/100; StubLengthCounter += StubSpeed; if (StubLengthCounter>=StubLength) { done = true; RemoveControlCallback(StubControlId, SendStubJobProgress); } jobStatus.has_currentsegmentindex = true; jobStatus.currentsegmentindex = 0; response.status = &jobStatus; responseContainer = createContainer(MESSAGE_TYPE__StubJobResponse, JobToken, done, &response, &stub_job_response__pack, &stub_job_response__get_packed_size); container_buffer = my_malloc(message_container__get_packed_size(&responseContainer)); if (container_buffer) { size_t container_size = message_container__pack(&responseContainer, container_buffer); SendChars(container_buffer, container_size); } if (responseContainer.data.data) my_free(responseContainer.data.data); return OK; } void Stub_JobRequest(MessageContainer* requestContainer) { uint32_t status = OK; MessageContainer responseContainer; StubJobRequest* request = stub_job_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data); JobTicket *Ticket = request->jobticket; StubJobResponse response = STUB_JOB_RESPONSE__INIT; JobStatus jobStatus = JOB_STATUS__INIT; StubSpeed = Ticket->processparameters->dyeingspeed; StubLength = Ticket->length*100; StubLengthCounter = 0; ustrncpy (JobToken, requestContainer->token,36); StubControlId = AddControlCallback(NULL, SendStubJobProgress, eOneSecond,TemplateDataReadCBFunction,0,0,0); jobStatus.has_progress = true; jobStatus.progress = 0.0; jobStatus.has_currentsegmentindex = false; response.status = &jobStatus; responseContainer = createContainer(MESSAGE_TYPE__StubJobResponse, JobToken, false, &response, &stub_job_response__pack, &stub_job_response__get_packed_size); if (status!= OK) { responseContainer.error = ERROR_CODE__INVALID_PROCESS_ID; responseContainer.errormessage = "JOb Active or incorrect parameters"; } // responseContainer.continuous = false; uint8_t* container_buffer = my_malloc(message_container__get_packed_size(&responseContainer)); if (container_buffer) { size_t container_size = message_container__pack(&responseContainer, container_buffer); SendChars(container_buffer, container_size); } if (responseContainer.data.data) my_free(responseContainer.data.data); return ; } void Stub_AbortJobRequest(MessageContainer* requestContainer) { //uint32_t status = OK; MessageContainer responseContainer; StubAbortJobRequest* request = stub_abort_job_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data); StubAbortJobResponse response = STUB_ABORT_JOB_RESPONSE__INIT; //RemoveControlCallback(StubControlId, SendStubJobProgress); StubLength = 0; StubLengthCounter = 10; //trigger job end message; responseContainer = createContainer(MESSAGE_TYPE__StubAbortJobResponse, requestContainer->token, false, &response, &stub_abort_job_response__pack, &stub_abort_job_response__get_packed_size); responseContainer.continuous = false; uint8_t* container_buffer = my_malloc(message_container__get_packed_size(&responseContainer)); if (container_buffer) { size_t container_size = message_container__pack(&responseContainer, container_buffer); SendChars(container_buffer, container_size); } if (responseContainer.data.data) my_free(responseContainer.data.data); return ; } //******************************************************************************************************************** void JobRequestFunc(MessageContainer* requestContainer) { uint32_t status = NOT_SUPPORTED; MessageContainer responseContainer; uint8_t* container_buffer; ErrorCode error = ERROR_CODE__NONE; JobEndReasonEnum JobAlarmReason = JOB_OK; if (JobActive == true) { LOG_ERROR(JobActive, "Job started while active"); status = FAILED; error = ERROR_CODE__NO_JOB_IN_PROGRESS; } else { JobRequest* request = job_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data); if (request != NULL) { ustrncpy (JobToken, requestContainer->token,36); previousJobLength = 0.0; JobTicket *Ticket = request->jobticket; int TicketSize = job_ticket__get_packed_size(Ticket); if (TicketSize >= MAX_TICKET_SIZE) { LOG_ERROR (TicketSize, "job ticket message too long"); status = FAILED; error = ERROR_CODE__BAD_CRC; usnprintf(ErrorMsg, 100, "job ticket message too long"); } else { //memcpy(CurrentJob, Ticket,TicketSize); CurrentJob = Ticket; // if (CurrentRequest!= NULL) // job_request__free_unpacked(CurrentRequest,NULL); CurrentRequest = request; n_segments = 0; if (CurrentJob->uploadstrategy == JOB_UPLOAD_STRATEGY__JobDescriptionFile) { LOG_ERROR(JobActive, "Job upload strategy file"); uploadstrategy = JOB_UPLOAD_STRATEGY__JobDescriptionFile; } else { uploadstrategy = JOB_UPLOAD_STRATEGY__Default; n_segments = CurrentJob->n_segments; } status = PASSED; JobEndReason = JOB_OK; TotalProcessedLength = 0.0; PoolerTotalProcessedLength = 0.0; JobAlarmReason = AlarmHandlingPrepareJob(CurrentJob); if (JobAlarmReason ==OK) { n_unit_segments = n_segments; if ((Ticket->has_numberofunits)&&(Ticket->numberofunits > 1)) { n_units = Ticket->numberofunits; } if (n_units>1) { n_segments = n_segments*n_units; } //#warning Process parameters in job request are not handled. push separately for now if (Ticket->processparameters) { if (HandleProcessParameters(Ticket->processparameters)!= OK) { status = FAILED; error = ERROR_CODE__INVALID_PARAMETER; usnprintf(ErrorMsg, 100, "Hardware Parameters Not Set"); } } //REPORT_MSG(0,"Process parameters in job request are not handled. push separately for now"); job_length = CurrentJob->length + dryerbufferMeters; Report("job length ",__FILE__,job_length,(int)CurrentJob->length,RpWarning,(int)dryerbufferCentimeters, 0); if (Ticket->spool) { if (InternalWindingConfigMessage(Ticket->spool)!= OK) { status = FAILED; error = ERROR_CODE__INVALID_PARAMETER; usnprintf(ErrorMsg, 100, "spool parameters error"); } } } else { status = FAILED; error = JobError_to_ErrorCode[JobAlarmReason]; usnprintf(ErrorMsg, 100, "Existing alarms prevent running"); } } if (status == PASSED) { Report("Job Request ",__FILE__,__LINE__,Ticket->processparameters->dyeingspeed,RpWarning,n_segments, Ticket->intersegmentlength); OpenJobFile(); StartJob(CurrentJob); } } else status = FAILED; } JobResponse response = JOB_RESPONSE__INIT; JobStatus jobStatus = JOB_STATUS__INIT; if (status == PASSED) { JobResumed = false; usnprintf(ErrorMsg, 100, "Job Accepted"); jobStatus.message =ErrorMsg; jobStatus.has_progress = true; jobStatus.progress = 0.0; jobStatus.has_currentsegmentindex = false; response.status = &jobStatus; response.has_canceled = false; responseContainer = createContainer(MESSAGE_TYPE__JobResponse, JobToken, false, &response, &job_response__pack, &job_response__get_packed_size); container_buffer = my_malloc(message_container__get_packed_size(&responseContainer)); } else { jobStatus.message = ErrorMsg; jobStatus.has_progress = true; jobStatus.progress = 0.0; jobStatus.has_currentsegmentindex = false; response.status = &jobStatus; response.has_canceled = true; response.canceled = true; responseContainer = createContainer(MESSAGE_TYPE__JobResponse, JobToken, true, &response, &job_response__pack, &job_response__get_packed_size); responseContainer.has_error = true; responseContainer.error = error; container_buffer = my_malloc(message_container__get_packed_size(&responseContainer)); } if (container_buffer) { size_t container_size = message_container__pack(&responseContainer, container_buffer); my_free(responseContainer.data.data); SendChars((char*)container_buffer, container_size); //We keep the job request until it is done // job_request__free_unpacked(request,NULL); } } //******************************************************************************************************************** char logmsg[254]; char infomsg[254]; uint8_t JobStatusBuffer[400]; ResumeCurrentJobResponse resumeresponse = RESUME_CURRENT_JOB_RESPONSE__INIT; JobResponse JobResponseMsg = JOB_RESPONSE__INIT; JobStatus jobStatus = JOB_STATUS__INIT; void SendJobProgress(double ProcessedLength, int SegmentId, bool done, char *Message) { MessageContainer responseContainer; uint8_t* container_buffer; //int len; //static msdid = 0; //int length = (int)(ProcessedLength*100); //len = usnprintf(logmsg, 254, "MSG: Job Progress Length %d, Seg %d Done %d ",length, SegmentId, done); //REPORT_MSG(msdid++,logmsg); //Report(logmsg,__FILE__,__LINE__,SegmentId,RpWarning,SegmentId, done); /*if (Message) { strcpy (infomsg,Message); Report(infomsg,__FILE__,__LINE__,55,RpWarning,33, 44); }*/ UInt Key = Task_disable(); double totlength = 0; if (JobToken[0] != 0) { if (Message) { jobStatus.message = Message; } //previousJobLength = ProcessedLength; jobStatus.has_progress = true; #ifdef FEEDER_LENGTH_CALCULATION totlength = TotalProcessedLength; if (TotalProcessedLength > job_length) { Report("job length bigger than assigned",__FILE__,__LINE__,TotalProcessedLength,RpWarning,job_length, done); //TotalProcessedLength = job_length; totlength = job_length; } #else totlength = PoolerTotalProcessedLength; if (PoolerTotalProcessedLength > job_length) { Report("job length bigger than assigned",__FILE__,__LINE__,PoolerTotalProcessedLength,RpWarning,job_length, done); //TotalProcessedLength = job_length; totlength = job_length; } #endif jobStatus.progress = totlength; jobStatus.has_currentsegmentindex = true; jobStatus.currentsegmentindex = SegmentId; if (JobResumed == true) { resumeresponse.status = &jobStatus; //responseContainer = createContainer(MESSAGE_TYPE__ResumeCurrentJobResponse, JobToken, done, &resumeresponse, &resume_current_job_response__pack, &resume_current_job_response__get_packed_size); responseContainer = createAllocatedContainer(MESSAGE_TYPE__ResumeCurrentJobResponse, JobToken, done, &resumeresponse, &resume_current_job_response__pack, &resume_current_job_response__get_packed_size,&JobStatusBuffer); } else { JobResponseMsg.status = &jobStatus; //responseContainer = createContainer(MESSAGE_TYPE__JobResponse, JobToken, done, &JobResponseMsg, &job_response__pack, &job_response__get_packed_size); responseContainer = createAllocatedContainer(MESSAGE_TYPE__JobResponse, JobToken, done, &JobResponseMsg, &job_response__pack, &job_response__get_packed_size,&JobStatusBuffer); } container_buffer = my_malloc(message_container__get_packed_size(&responseContainer)); if (done == true) { if(JobEndReason != JOB_OK) { responseContainer.has_error = true; responseContainer.error = JobError_to_ErrorCode[JobEndReason]; } if (JobAbortedByUser == true) { JobAbortedByUser = false; responseContainer.has_error = true; responseContainer.error = ERROR_CODE__CONTINUOUS_RESPONSE_ABORTED; } } if (container_buffer) { size_t container_size = message_container__pack(&responseContainer, container_buffer); // if (SendChars(container_buffer, container_size) == false) //comm tx mailbox full if (SendCharsWithType(container_buffer, container_size,MESSAGE_TYPE__JobResponse) == false) //comm tx mailbox full { //AlarmHandlingToken[0] = 0; my_free(container_buffer); } } } if (done == true) { if (CurrentRequest!= NULL) { // job_request__free_unpacked(CurrentRequest,NULL); CurrentRequest = NULL; } JobStopReporting(); if(JobEndReason != JOB_OK) { switch (JobEndReason) { case JOB_THREAD_BREAK: AlarmHandlingSetAlarm(EVENT_TYPE__THREAD_BREAK,true); break; case JOB_POOLER_DANCER_FAIL: AlarmHandlingSetAlarm(EVENT_TYPE__THREAD_TENSION_CONTROL_FAILURE_PULLER_DANCER,true); break; case JOB_FEEDER_DANCER_FAIL: AlarmHandlingSetAlarm(EVENT_TYPE__THREAD_TENSION_CONTROL_FAILURE_FEEDER_DANCER,true); break; case JOB_WINDER_DANCER_FAIL: AlarmHandlingSetAlarm(EVENT_TYPE__THREAD_TENSION_CONTROL_FAILURE_WINDER_DANCER,true); break; default: break; } } JobMessageStruc JobMessage; if(JobEndReason == JOB_OK) { JobMessage.messageId = PrintingResultsOk; } else { JobMessage.messageId = PrintingResultsFail; } JobMessage.msglen = MAX_MSG_LEN; if (JobmsgQ != NULL) Mailbox_post(JobmsgQ , &JobMessage, BIOS_NO_WAIT); } // if (responseContainer.data.data) // my_free(responseContainer.data.data); Task_restore(Key); } void JobStopReporting(void) { LOG_ERROR(0,"JobStopReporting"); JobToken[0] = 0; } void AbortJob(char *Msg) { //ReturnCode retcode; //retcode = JobSuccess; JobMessageStruc Message; PrintMessageStruc *PrtMessage = (PrintMessageStruc *)Message.messageData; Message.messageId = Abort; PrtMessage->messageId = PrintSystemFailure; strncpy(PrtMessage->messageData,Msg,99); //PrtMessage->messageData[99] = NULL; Message.msglen = 10; if (JobmsgQ != NULL) Mailbox_post(JobmsgQ , &Message, BIOS_NO_WAIT); } uint32_t CurrentJobRequestFunc(MessageContainer* requestContainer) { uint32_t status = OK; MessageContainer responseContainer; CurrentJobRequest* request = current_job_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data); CurrentJobResponse response = CURRENT_JOB_RESPONSE__INIT; if (JobActive == true) { response.has_isjobinprogress = true; response.isjobinprogress = true; response.jobticket = CurrentJob; } else { response.has_isjobinprogress = true; response.isjobinprogress = false; response.jobticket = NULL; } responseContainer = createContainer(MESSAGE_TYPE__CurrentJobResponse, requestContainer->token, false, &response, ¤t_job_response__pack, ¤t_job_response__get_packed_size); if (status!= OK) { responseContainer.error = ERROR_CODE__INVALID_PROCESS_ID; responseContainer.errormessage = "JOb Active or incorrect parameters"; } responseContainer.continuous = false; uint8_t* container_buffer = my_malloc(message_container__get_packed_size(&responseContainer)); if (container_buffer) { size_t container_size = message_container__pack(&responseContainer, container_buffer); SendChars(container_buffer, container_size); } if (responseContainer.data.data) my_free(responseContainer.data.data); return OK; } uint32_t ResumeCurrentJobRequestFunc(MessageContainer* requestContainer) { uint32_t status = OK; MessageContainer responseContainer; ResumeCurrentJobRequest* request = resume_current_job_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data); ResumeCurrentJobResponse response = RESUME_CURRENT_JOB_RESPONSE__INIT; JobStatus jobStatus = JOB_STATUS__INIT; if (JobActive == true) { ustrncpy (JobToken, requestContainer->token,36); JobResumed = true; usnprintf(ErrorMsg, 100, "Job Resumed"); Report("Job resumed",__FILE__,__LINE__, JobActive,RpMessage,JobResumed,0); jobStatus.message =ErrorMsg; jobStatus.has_progress = true; jobStatus.progress = 0.0; jobStatus.has_currentsegmentindex = false; response.status = &jobStatus; response.has_canceled = false; } else { usnprintf(ErrorMsg, 100, "Job not Resumed"); Report("Job not resumed",__FILE__,__LINE__, JobActive,RpMessage,JobResumed,0); jobStatus.message =ErrorMsg; jobStatus.has_progress = true; jobStatus.progress = 0.0; jobStatus.has_currentsegmentindex = false; response.status = &jobStatus; response.has_canceled = true; response.canceled = true; } responseContainer = createContainer(MESSAGE_TYPE__ResumeCurrentJobResponse, JobToken, false, &response, &resume_current_job_response__pack, &resume_current_job_response__get_packed_size); if (status!= OK) { responseContainer.error = ERROR_CODE__INVALID_PROCESS_ID; responseContainer.errormessage = "JOb Active or incorrect parameters"; } responseContainer.continuous = false; uint8_t* container_buffer = my_malloc(message_container__get_packed_size(&responseContainer)); if (container_buffer) { size_t container_size = message_container__pack(&responseContainer, container_buffer); SendChars(container_buffer, container_size); } if (responseContainer.data.data) my_free(responseContainer.data.data); return OK; } void StartJob(void *JobDetails) { JobMessageStruc Message; Message.messageId = JobRequestMsg; Message.msglen = MAX_MSG_LEN; if (JobmsgQ != NULL) Mailbox_post(JobmsgQ , &Message, BIOS_NO_WAIT); } /****************************************************************************** * ======== messageTsk ======== * Task for this function is created statically. See the project's .cfg file. * this message task is created statically in system initialization, ******************************************************************************/ Void jobTask(UArg arg0, UArg arg1) { JobMessageStruc Message; //char str[60]; //uint16_t length; //Clock_setTimeout(HostKAClock, 1000); //Clock_start(HostKAClock); JobmsgQ = Mailbox_create(MAX_MSG_LEN, 20, NULL,NULL); while(1) { Mailbox_pend(JobmsgQ , &Message, BIOS_WAIT_FOREVER); switch (Message.messageId) { case JobRequestMsg: JobEndReason = JOB_OK; Report("JobRequestMsg",__FILE__,__LINE__, JobActive,RpMessage,JobResumed,0); JobActive = true; SetMachineStatus(MACHINE_STATE__PreparingJob); JobResumed = false; setmachineActive(true); PrepareState (CurrentJob); break; case ValidationResultsFail: //send message data as a validation error message to host ExitState(Message.messageData); break; case PreparationResultsOk: PrintState(CurrentJob); break; case PreparationResultsFail: //send message data as a validation error message to host EndState(CurrentJob, "Prepare Failed"); //ExitState(Message.messageData); break; case PrintMessage: //send message data as a validation error message to host PrintSTMMsgHandler(&Message); break; case PrintingResultsOk: JobActive = false; setmachineActive(false); SetMachineStatus(MACHINE_STATE__Ready); resetIdleCounter(); CurrentJob = NULL; //if (CurrentRequest!= NULL) // job_request__free_unpacked(CurrentRequest,NULL); //CurrentRequest = NULL; SuspendLargeMessages = false; LOG_ERROR(4,"ResumeLargeMessages PrintingResultsOk"); //DiagnosticsStart(); //CleanState(CurrentJob); break; case PrintingResultsFail: JobActive = false; setmachineActive(false); SetMachineStatus(MACHINE_STATE__Error); resetIdleCounter(); CurrentJob = NULL; //if (CurrentRequest!= NULL) // job_request__free_unpacked(CurrentRequest,NULL); //CurrentRequest = NULL; SuspendLargeMessages = false; LOG_ERROR(3,"ResumeLargeMessages PrintingResultsFail"); //DiagnosticsStart(); //send message data as a validation error message to host ExitState(Message.messageData); break; case CleaningResultsOk: //send message data as a validation error message to host ExitState(Message.messageData); break; case CleaningResultsFail: //send message data as a validation error message to host ExitState(Message.messageData); break; case SystemFailure: //send message data as a validation error message to host ExitState(Message.messageData); break; case Abort: PrintSTMMsgHandler(&Message); break; default: break; } } }