Motion Control and Motor Drives

cancel
Showing results for 
Search instead for 
Did you mean: 

Access violation during onboard programming

Hello all,

 

I've been using a PCI 7340 for a couple weeks now, and I've been asked to do some onboard programming with it. After skimming through the manual, I decided to try running the "Simple One-Axis Move (Onboard).c" found within the Flexmotion examples. The code is capable of controlling the motors, but I'm consistently faced with software crashes due to unhandled exceptions. for example: "Unhandled exception at 0x7c90e8c5 in Simple One Axis Move.exe: 0xC0000005: Access violation writing location 0x00030ff8". Sometimes I get this message instead: "A buffer overrun has occurred in Simple One Axis Move.exe which has corrupted the program's internal state." And almost always, there's a first-chance exception due to an access violation reading location. 

 

I sense that all these errors have a common source, but I have been unable to identify it. I have made some modifications in trying to fix the problem, so this is the code as it is now. The problem did however occur even before I made any changes:

 

//INCLUDES/////////////////////////

#include "flexmotn.h"

#include <stdio.h>

u16 m_boardID=2; // Board Identification number

i16 m_err=-1; // Error status

u16 m_csr=0; // Communication Status Register

 

void CheckError(u32 numexceptions, u32*exceptions)

{

//Variables for modal error handling

u16 commandID; // The commandID of the function

u16 resourceID; // The resource ID

i32 errorCode; // Error code

 if (m_err != 0)

{

printf(
"SOMETHING FAILED\n");

// Check to see if there were any Modal Errors

 if (m_csr & NIMC_MODAL_ERROR_MSG)

{

do

{

//Get the command ID, resource ID and error code of the modal error from the error stack on the board

flex_read_error_msg_rtn(m_boardID,&commandID,&resourceID,&errorCode);

DisplayError(errorCode,commandID,resourceID);

//Read the Communication Status Register

flex_read_csr_rtn(m_boardID,&m_csr);

}

while (m_csr & NIMC_MODAL_ERROR_MSG);

}

else // Display regular error

DisplayError(m_err,0,0);

}

}

 

 

0 Kudos
Message 1 of 12
(5,671 Views)

//////////////////////////////////////////////////////////////////////

// Main Function

void main(void)

{

u8 axis=1; // Axis Number

u8 program=2; // Program Number

i32 targetPos=200; // Target Position

f64 velocity = 10000.0; // Velocity in RPM

f64 accel = 100000.0; // Acceleration in RPS/sec

f64 decel = 100000.0; // Deceleration in RPS/sec

i32 scanVar; // Scan variable to read in values not supported bu

// by the scanf function

//m_err = flex_initialize_controller (m_boardID, NULL);

m_err = flex_clear_pu_status(m_boardID);

printf(
"clearing power-up status: %d\n",m_err);

CheckError(0,NULL);

do

{

//Read the communication Status register

m_err = flex_read_csr_rtn(m_boardID, &m_csr);

CheckError(0,NULL);

}
while (m_csr & NIMC_POWER_UP_RESET); printf("power-up reset bit setting to low: %d\n",m_err);

//m_err = flex_flush_rdb(m_boardID);

//printf("flushing return data buffer: %d\n",m_err);

//CheckError(0,NULL);

//Start Storing the program

m_err = flex_begin_store(m_boardID,program);

printf(
"start storing: %d\n",m_err);

CheckError(0,NULL);

//Set Operation Mode

m_err = flex_set_op_mode(m_boardID, axis, NIMC_ABSOLUTE_POSITION);

printf(
"setting operation mode: %d\n",m_err);

CheckError(0,NULL);

//Load a target position

m_err = flex_load_target_pos(m_boardID, axis, targetPos, 0xFF);

printf(
"loading position: %d\n",m_err);

CheckError(0,NULL);

//End Storing the program

m_err = flex_end_store(m_boardID,program);

CheckError(0,NULL);

printf(
"end storing: %d\n",m_err);

//Check the modal errors

m_err = flex_read_csr_rtn(m_boardID, &m_csr);

CheckError(0,NULL);

printf(
"reading modal error: %d\n",m_err);

 

if (m_csr & NIMC_MODAL_ERROR_MSG)

{

flex_stop_motion(m_boardID,NIMC_VECTOR_SPACE1, NIMC_DECEL_STOP, 0);//Stop the Motion

m_err = m_csr & NIMC_MODAL_ERROR_MSG;

CheckError(0,NULL);

printf(
"stopping motion: %d\n",m_err);

}

flex_run_prog (m_boardID,program);

system(
"pause");

return; // Exit the Application

}

 

 OUTPUT:

clearing power-up status: 0
power-up reset bit setting to low: 0
start storing: 0
setting operation mode: 0
loading position: 0
end storing: 0
reading modal error: 0
Press any key to continue . . .

 

And aftewards...

Unhandled exception at 0x00000000 in Simple One Axis Move.exe: 0xC0000005: Access violation reading location 0x00000000.

 

 

 

Thanks in advance.

P.S. I commented out the loading velocity/accelearation and starting the actual move parts, and just deleted from this post. The code fails with those parts present as well.

Message Edited by pthaya on 04-03-2009 03:21 PM
0 Kudos
Message 2 of 12
(5,670 Views)

I haven't found a reason for your exceptions, but before we get too deeply into this issue I'd like to ask you, why you want to create an onboard program.

As I have already posted multiple times (e. g. here) there are just very few cases where onboard programming really makes sense. To make a long story short, onboard programs are not faster and they don't provide better determinism than host programs. One of the few cases where onboard programs make sense is stopping a motor independently from the PC, when a special condition is reached (e. g. a maximum force is reached).

 

So please explain, why you want to use onboard programming and what you are expecting from it.

 

Thanks,

Jochen

0 Kudos
Message 3 of 12
(5,640 Views)

Hi Jochen,

 

Thanks for your response. My project involves moving a positioner through a series of points repeatedly, i.e. we move back to the first point at the end of the cycle, and start again. Currently, at each point we're issuing a move command to the next point, waiting for the move to finish, sending a trigger for a set amount of time (a few milliseconds), and then issuing the move command to the point afterwards. My supervisor feels that having the messages issued through and received from Windows results in a greater time constraint than desired, which is why I'm now trying to program onto the motion card directly. The breakpoint, for example, will not be sent until Windows receives the information that the previous move was completed.

 

For the record, we are currently using a thread with real-time priority, but feel that onboard programming might be faster.

 

Thanks, 

pthaya

Message Edited by pthaya on 04-06-2009 01:11 PM
0 Kudos
Message 4 of 12
(5,629 Views)

pthaya,

 

thank you  for the explanation. I think there is a much better and more deterministic way to accomplish this task. I think the best approach for your application should be blending. With blending you can load the move constraints for a consecutive move, while the first move is running. With the blend factor you can determine the start time. This factor allows you to either blend moves (start the acceleration for the consecutive move at the time the first move starts to decelerate) or to start a new move immediately (no delay) after the first move has stopped. A third option is to add a deterministic delay between moves with millisecond resolution.You can change the blend factor after each move. Please refer to the documentation of the flex_load_blend_fact() function for more information.

 

Blending works fine as long as your moves don't become too short (moves should take longer than about 20 ms). If your moves are extremely short, you could consider using contouring instead of blending. In contouring mode the board steps through a list of positions with a fixed rate. The positions are provided in an array. As you can define this array by yourself this allows you to execute any sequence of moves with deterministic timing.

 

As blending provides the same level of determinism as contouring I recommend blending, as it is easier to implement, but it depends on the move lengths if blending is an option for you.

In any case both methods provide real hardware determinism which is way better than the timing provided by an onboard program. The main reason why onboard programs don't provide good determinism is the fact, that they run in a low priority thread on the onboard CPU as they shouldn't disturb the deterministic processes that are executed by the same CPU in parallel.

 

I hope this helps,

Jochen

0 Kudos
Message 5 of 12
(5,618 Views)

Hi Jochen,

 

Thanks for your advice. I gave your suggestion to my supervisor, who claimed that blending was not a feasible option due to our necessity to issue a trigger between intervals. Furthermore, she says she would prefer to do some testing with the onboard capabilities anyway.

 

The unhandled exception appears to have disappeared by itself when used in an MFC application, making things easier for us.

 

Thanks again,

pthaya

 

 

0 Kudos
Message 6 of 12
(5,611 Views)

pthaya,

 

in this case it's probably the best approach to run the complete sequence on the host program. I have done several benchmarks with onboard programs in the past with the result, that onboard programs are not significantly better than host programs in terms of determinism and performance. I just want to mention this to avoid disappointment if you invest  a lot of time in onboard programming without gaining a significant improvement compared to host programming.

 

Jochen

0 Kudos
Message 7 of 12
(5,599 Views)

Hi Jochen,

 

I very much appreciate your advice. Much time has already been invested into attempting onboard programming, and there's only a little left to do so we might as well finish it. 🙂

 

Thanks for everything.

 

Regards,

pthaya

0 Kudos
Message 8 of 12
(5,588 Views)

Hi pthaya,

 

Jochen is completely right. There isn't much point to use the onboard programming; it tends to lead to more problems than it's worth. However, if you really wish to keep on this track, I'd like to know which version of NI-Motion you are using. There have been previous cases with similar unhandled exceptions in our other drivers that are usually fixed in the latest version. As well, have you tried any of the other onboard examples?

0 Kudos
Message 9 of 12
(5,577 Views)

Hi Olivia,

 

I'm using NI Motion 7.7.  As I mentioned, the unhandled exceptions only occured when I ran a project with just the example, NIMCExample.c, NIMCExample.h and flexmotn.h . When I incorporated the functions into my MFC project, they simply vanished. Before realizing this, I also tried running the Sequence of One-Axis Moves (Onboard).c example as an independent applicaton and got the same exceptions.

 

Regards,

pthaya

Message Edited by pthaya on 04-09-2009 01:11 PM
0 Kudos
Message 10 of 12
(5,563 Views)