Duet3D Logo Duet3D
    • Tags
    • Documentation
    • Order
    • Register
    • Login

    Duet 2 disconnects after running a custom M command

    Scheduled Pinned Locked Moved
    Firmware developers
    2
    8
    348
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • jazbaatbadalgayeundefined
      jazbaatbadalgaye
      last edited by jazbaatbadalgaye

      I wrote a custom M command to insert a drive movement in the move queue. The firmware complies and flashes fine but whenever I run the M command, the blue light flashes once and the board disconnects from YAT. I tried using the stackanalyzer tool but unfortunately it did not give me any results whatsoever. How else can I figure out where the fault is occurring?

      Here is the M Code :

      case 840:	// insert move 
      {
      	for (size_t axis = 0; axis < numVisibleAxes; ++axis)
      	{
      		if (gb.Seen(axisLetters[axis]))
      		{
      			const uint32_t ipval = gb.GetUIValue();
      			//reply.catf("input given is  : %.3f \n",(double)ipval);
      			//reprap.GetMove().insertmymove(simulationMode,firstUnpreparedMove,(int)ipval);
      			reprap.GetMove().insertmymove(simulationMode, ipval, axis);
      		}
      	}
      }
      break;
      

      where the function is defined in DDA.cpp as

      void DDA::MoveInsert(uint8_t simMode, uint32_t input,size_t axis) noexcept
      {
      	debugPrintf("Sim mode : %d \n" , simMode);
      	debugPrintf("Input : %" PRIu32 "\n" , input);
      
      	Platform& platform = reprap.GetPlatform();
      	PrepParams params;
      	AxesBitmap additionalAxisMotorsToEnable, axisMotorsEnabled;
      
      	int32_t delta = input*80 - prev->endPoint[axis];
      	if (delta != 0)
      	{
      		platform.EnableDrivers(axis);
      		if (platform.GetDriversBitmap(axis) != 0)				
      		{
      			DriveMovement* const pdm = DriveMovement::Allocate(axis, DMState::accel0);
      			pdm->totalSteps = labs(delta);
      			pdm->direction = (delta >= 0);
      			if (pdm->PrepareCartesianAxis(*this, params))
      			{
      				pdm->directionChanged = false;
      				if (reprap.Debug(moduleDda) && pdm->totalSteps > 1000000)
      				{
      					DebugPrintAll("pr");
      				}
      				InsertDM(pdm);
      			}
      			else
      			{
      				pdm->state = DMState::idle;
      				pdm->nextDM = completedDMs;
      				completedDMs = pdm;
      			}
      		}
      		axisMotorsEnabled.SetBit(axis);
      		additionalAxisMotorsToEnable |= reprap.GetMove().GetKinematics().GetConnectedAxes(axis);
      	}
      
      	const DDAState st = prev->state;
      	afterPrepare.moveStartTime = (st == DDAState::executing || st == DDAState::frozen)
      					? prev->afterPrepare.moveStartTime + prev->clocksNeeded			
      						: StepTimer::GetTimerTicks() + AbsoluteMinimumPreparedTime;
      
      	if (flags.checkEndstops)
      	{
      		platform.EnableAllSteppingDrivers();
      		CheckEndstops(platform);									
      	}
      
      	if (reprap.Debug(moduleDda) && reprap.Debug(moduleMove))		
      	{
      		DebugPrintAll("pr");
      	}
      
      	if (state != completed)
      	{
      		state = frozen;					
      	}
      }
      

      Edit

      Upon running M122 I obtain the following log :

      === Diagnostics ===<LF>RepRapFirmware for Duet 2 WiFi/Ethernet version 3.3+ (2021-10-12 17:16:29) running on Duet WiFi 1.02 or later<LF>
      Board ID: 08DJM-9178L-L2MSD-6JKDG-3SS6M-18GAQ<LF>Used output buffers: 1 of 24 (1 max)<LF>=== RTOS ===<LF>Static ram: 23884<LF>Dynamic ram: 750
      40 of which 0 recycled<LF>Never used RAM 14484, free system stack 193 words<LF>Tasks: NETWORK(ready,6.7%,369) HEAT(delaying,0.0%,342) Mo
      ve(notifyWait,0.1%,364) MAIN(running,93.2%,463) IDLE(ready,0.0%,29), total 100.0%<LF>Owned mutexes: USB(MAIN)<LF>=== Platform ===<LF>Last r
      eset 00:50:31 ago, cause: software<LF>Last software reset time unknown, reason: HardFault bfarValid precise, GCodes spinning, availab
      le RAM 14484, slot 0<LF>Software reset code 0x0063 HFSR 0x40000000 CFSR 0x00008200 ICSR 0x00400803 BFAR 0xa5a5a5a9 SP 0x200023f0 Task
       MAIN Freestk 811 ok<LF>Stack: a5a5a5a5 00000000 00000002 00000000 00000038 004422db 00424db4 210f0000 00000000 0042c4b1 200024c4 200
      00e68 00000000 00000058 00000000 00000005 20000e68 2000a2b8 20008b70 2000a324 20008b70 0043811d 00000000 2000a2b8 20008b70 0043ff4
      3 00000000<LF>Error status: 0x00<LF>Step timer max interval 0<LF>MCU temperature: min 37.3, current 38.9, max 39.3<LF>Supply voltage: min 1.6,
       current 1.7, max 1.8, under voltage events: 0, over voltage events: 0, power good: no<LF>Heap OK, handles allocated/used 0/0, heap m
      emory allocated/used/recyclable 0/0/0, gc cycles 0<LF>Driver 0: position 0, ok, SG min/max not available<LF>Driver 1: position 0, ok, SG
       min/max not available<LF>Driver 2: position 0, ok, SG min/max not available<LF>Driver 3: position 0, ok, SG min/max not available<LF>Drive
      r 4: position 0, ok, SG min/max not available<LF>Driver 5: position 0<LF>Driver 6: position 0<LF>Driver 7: position 0<LF>Driver 8: position 0<LF>
      Driver 9: position 0<LF>Driver 10: position 0<LF>Driver 11: position 0<LF>Date/time: 1970-01-01 00:00:00<LF>Cache data hit count 4294967295<LF>Sl
      owest loop: 5.88ms; fastest: 0.13ms<LF>I2C nak errors 0, send timeouts 0, receive timeouts 0, finishTimeouts 0, resets 0<LF>=== Storage 
      ===<LF>Free file entries: 10<LF>SD card 0 detected, interface speed: 20.0MBytes/sec<LF>SD card longest read time 3.3ms, write time 0.0ms, m
      ax retries 0<LF>=== Move ===<LF>DMs created 83, maxWait 0ms, bed compensation in use: none, comp offset 0.000<LF>=== MainDDARing ===<LF>Schedu
      led moves 0, completed moves 0, hiccups 0, stepErrors 0, LaErrors 0, Underruns [0, 0, 0], CDDA state -1<LF>=== AuxDDARing ===<LF>Schedul
      ed moves 0, completed moves 0, hiccups 0, stepErrors 0, LaErrors 0, Underruns [0, 0, 0], CDDA state -1<LF>=== Heat ===<LF>Bed heaters = 
      0 -1 -1 -1, chamberHeaters = -1 -1 -1 -1<LF>=== GCodes ===<LF>Segments left: 0<LF>Movement lock held by null<LF>HTTP is idle in state(s) 0<LF>Tel
      net is idle in state(s) 0<LF>File is idle in state(s) 0<LF>USB is ready with "M122" in state(s) 0<LF>Aux is idle in state(s) 0<LF>Trigger is i
      dle in state(s) 0<LF>Queue is idle in state(s) 0<LF>LCD is idle in state(s) 0<LF>Daemon is idle in state(s) 0<LF>Autopause is idle in state(s)
       0<LF>Code queue is empty.<LF>=== Network ===<LF>Slowest loop: 1.26ms; fastest: 0.00ms<LF>Responder states: HTTP(0) HTTP(0) HTTP(0) HTTP(0) FT
      P(0) Telnet(0), 0 sessions<LF>HTTP sessions: 0 of 8<LF>- WiFi -<LF>Network state is changingMode<LF>WiFi module is idle<LF>Failed messages: pendi
      ng 0, notready 0, noresp 0<LF>Failed to get WiFi status<LF>Socket states: 0 0 0 0 0 0 0 0<LF>ok<LF>Error retrieving WiFi status message: SPI t
      imeout<LF>WiFi module is idle<LF>Failed to change WiFi mode: SPI timeout<LF>
      

      I can see that there is a software reset and the reason seems to be

      HardFault bfarValid precise
      

      which I believe is the register hold the address where fault occurred. However, I have no idea how pinpoint the section of code which results in an error. Any help would be greatly appreciated.

      dc42undefined 1 Reply Last reply Reply Quote 0
      • dc42undefined
        dc42 administrators @jazbaatbadalgaye
        last edited by

        @jazbaatbadalgaye you haven't shown the code you added in the Move and DDARing classes to establish a DDA to call InsertMyMove on. Perhaps the DDA is invalid.

        You can use the stack analyser to identify the function that the fault occurred in and the offset within that function. Then you can use the assembly file for that module to identify the exact instruction that caused the fault. After that it's a matter of relating the assembly code to the C++ source code.,

        Duet WiFi hardware designer and firmware engineer
        Please do not ask me for Duet support via PM or email, use the forum
        http://www.escher3d.com, https://miscsolutions.wordpress.com

        jazbaatbadalgayeundefined 1 Reply Last reply Reply Quote 0
        • jazbaatbadalgayeundefined
          jazbaatbadalgaye @dc42
          last edited by

          @dc42 So i am copying the output given to me by the M122 command and saving it as logM122.txt. I copied both files (mymapfile.map file + m122 output) into ../../stackanalyzer/win and run the follwing command

          stackanalyzer -m122 logM122.txt -mapFile mymapfile.map
          

          But I don't see any output on the terminal. Is there a separate file or something that is created by stackanalyzer?

          jazbaatbadalgayeundefined 1 Reply Last reply Reply Quote 0
          • jazbaatbadalgayeundefined
            jazbaatbadalgaye @jazbaatbadalgaye
            last edited by jazbaatbadalgaye

            @jazbaatbadalgaye

            //in move.cpp
            
            void Move::insertmymove(uint8_t simMode, uint32_t input, size_t axis) //insert my move 
            {
            	mainDDARing.prepmoves(simulationMode, input, axis);  //prepmoves
            }
            
            
            //in DDARing
            
            void DDARing:prepmoves(uint8_t simMode, uint32_t input,size_t axis) noexcept
            {
            	addPointer2->MoveInsert(simMode, input,axis); 
            }
            

            This is what I have in DDARing and Move.cpp.

            // in DDA.cpp
            
            void DDA::MoveInsert(uint8_t simMode, uint32_t input,size_t axis) noexcept
            {
            	debugPrintf("Sim mode : %d \n" , simMode);
            	debugPrintf("Input : %" PRIu32 "\n" , input);
             
            	Platform& platform = reprap.GetPlatform();
            	PrepParams params;
            	AxesBitmap additionalAxisMotorsToEnable, axisMotorsEnabled;
             
            	int32_t delta = input*80 - prev->endPoint[axis];
            	if (delta != 0)
            	{
            		platform.EnableDrivers(axis);
            		if (platform.GetDriversBitmap(axis) != 0)				
            		{
            			DriveMovement* const pdm = DriveMovement::Allocate(axis, DMState::accel0);
            			pdm->totalSteps = labs(delta);
            			pdm->direction = (delta >= 0);
            			if (pdm->PrepareCartesianAxis(*this, params))
            			{
            				pdm->directionChanged = false;
            				if (reprap.Debug(moduleDda) && pdm->totalSteps > 1000000)
            				{
            					DebugPrintAll("pr");
            				}
            				InsertDM(pdm);
            			}
            			else
            			{
            				pdm->state = DMState::idle;
            				pdm->nextDM = completedDMs;
            				completedDMs = pdm;
            			}
            		}
            		axisMotorsEnabled.SetBit(axis);
            		additionalAxisMotorsToEnable |= reprap.GetMove().GetKinematics().GetConnectedAxes(axis);
            	}
             
            	const DDAState st = prev->state;
            	afterPrepare.moveStartTime = (st == DDAState::executing || st == DDAState::frozen)
            					? prev->afterPrepare.moveStartTime + prev->clocksNeeded			
            						: StepTimer::GetTimerTicks() + AbsoluteMinimumPreparedTime;
             
            	if (flags.checkEndstops)
            	{
            		platform.EnableAllSteppingDrivers();
            		CheckEndstops(platform);									
            	}
             
            	if (reprap.Debug(moduleDda) && reprap.Debug(moduleMove))		
            	{
            		DebugPrintAll("pr");
            	}
             
            	if (state != completed)
            	{
            		state = frozen;					
            	}
            }
            

            This is what I have in DDA.cpp

            case 840:	// insert move 
            {
            	for (size_t axis = 0; axis < numVisibleAxes; ++axis)
            	{
            		if (gb.Seen(axisLetters[axis]))
            		{
            			const uint32_t ipval = gb.GetUIValue();
            			//reply.catf("input given is  : %.3f \n",(double)ipval);
            			reprap.GetMove().insertmymove(simulationMode, ipval, axis);
            		}
            	}
            }
            break;
            

            And this what I have in GCodes2.cpp

            1 Reply Last reply Reply Quote 0
            • dc42undefined
              dc42 administrators
              last edited by dc42

              @jazbaatbadalgaye the map file needs to be the .map file that was created alongside the firmware binary. Also you need to configure YAT to recognise LF only as a line terminator so that the output is in the correct format. See the Getting Connected page.

              Duet WiFi hardware designer and firmware engineer
              Please do not ask me for Duet support via PM or email, use the forum
              http://www.escher3d.com, https://miscsolutions.wordpress.com

              jazbaatbadalgayeundefined 2 Replies Last reply Reply Quote 0
              • jazbaatbadalgayeundefined
                jazbaatbadalgaye @dc42
                last edited by

                @dc42 Yes, I am using the same mapfile named Duet2combinedfirmware.map. I just renamed it after copying. I will try giving it the absolute path

                1 Reply Last reply Reply Quote 0
                • jazbaatbadalgayeundefined
                  jazbaatbadalgaye @dc42
                  last edited by jazbaatbadalgaye

                  @dc42 okay changing it to LF did the trick! Thanks a bunch.

                  Faulted at:
                  .text._ZN3DDA11StepDriversER8Platformm
                                  0x00425e74      0x148 ./src/Movement/DDA.o
                                  0x00425e74                DDA::MoveInsert(unsigned char, unsigned long, unsigned int)
                  Error is at offset: 0x4
                  

                  So I can see that the the MoveInsert is giving me an error as suspected.

                  How to interpret the

                  Error is at offset: 0x4
                  

                  I have the DDA.s which I believe is the assembly file (?). So I look for the 5th byte in the assembly file?

                  dc42undefined 1 Reply Last reply Reply Quote 0
                  • dc42undefined
                    dc42 administrators @jazbaatbadalgaye
                    last edited by

                    @jazbaatbadalgaye said in Duet 2 disconnects after running a custom M command:

                    I have the DDA.s which I believe is the assembly file (?). So I look for the 5th byte in the assembly file?

                    Look in the assembly file for the instruction that is at offset 4 within function DDA::MoveInsert.

                    Duet WiFi hardware designer and firmware engineer
                    Please do not ask me for Duet support via PM or email, use the forum
                    http://www.escher3d.com, https://miscsolutions.wordpress.com

                    1 Reply Last reply Reply Quote 0
                    • First post
                      Last post
                    Unless otherwise noted, all forum content is licensed under CC-BY-SA