cancel
Showing results for 
Search instead for 
Did you mean: 

Value of passed variable changes during function call !?

JHöfl.1
Associate II

I'm having a real nasty bug and finally found the reason for it. But the thing is, that I don't understand where it comes from.

I calculate a variable within method A of a class and at the end of said method i pass it to method B by value. When stepping through the code. I get the correct result for my variable of 700 befor passing it to method B, but it evaluates to 200 within method B. The variable is local to method A. I also use the m_ naming convention for class members.

I'm fairly desperate by now and willing to share most of my code if it helps, at least the class that is.

here are the two methods and the values I call them with:

Method A gets called with targetPos as 1000.

void Stepper::SetTargetPos(uint16_t targetPos)
{
	if (!m_enabled || targetPos == m_posTimer->CNT)
	{
		return;
	}
 
	if (targetPos > m_posTimer->ARR)
	{
		m_targetPos = m_posTimer->ARR;
	}
	else
	{
		m_targetPos = targetPos;
	}
 
	uint16_t currentPos = m_posTimer->CNT;
 
	uint16_t dist;
	if (currentPos < m_targetPos)
	{
		SetDirection(DIR_DOWN);
		dist = targetPos - currentPos;
	}
	else
	{
		SetDirection(DIR_UP);
		dist = currentPos - targetPos;
	}
 
	uint16_t brkDist;
	uint16_t idx;
	// Bremsweg und maximale Geschwidigkeit berechenn
	// Fall: Ausreichend Strecke um 100% zu erreichen ausgehend von v0 = 10%, vend = 10%
	if (dist >= m_rampDataLen * 1.8f)
	{
		brkDist = m_rampDataLen * 0.9f;
		idx = m_rampDataLen;
	}
	// Fall: Nicht ausreichend Strecke
	else
	{
		brkDist = dist * 0.5f;
		idx = m_rampDataLen / 10 + brkDist;
	}
 
	m_posTimer->CCR2 =
			(currentPos < m_targetPos) ?
					m_targetPos - brkDist : m_targetPos + brkDist;
 
	m_currentIdx = m_rampDataLen / 10;
	m_signalTimer->ARR = m_rampUpData[m_currentIdx];
	m_posReached = 0;
 
	// Zielposition in Postitionstimer hinterlegen
	m_posTimer->CCR3 = m_targetPos;
	// CCR2 und CCR3 Interrupts aktivieren
	SET_BIT(m_posTimer->DIER, ((TIM_DIER_CC2IE) | (TIM_DIER_CC3IE)));
 
	SetTargetIdx(idx);
}

Method B gets called with 700 (confirmed by stepping through).

void Stepper::SetTargetIdx(uint16_t targetIdx)
{
	if (!m_enabled || m_braking)
	{
		return;
	}
 
	// UpdateCurrentIdx();
 
	if (targetIdx > m_rampDataLen)
	{
		m_targetIdx = m_rampDataLen;
	}
	else
	{
		m_targetIdx = targetIdx;
	}
 
	if (m_currentIdx == m_targetIdx)
	{
		m_idxReached = 0;
		Go();
		return;
	}
 
	uint16_t count;
	uint32_t start;
 
	if (m_currentIdx < m_targetIdx)	// Zieldrehzahl höher -> rampUp
	{
		count = m_targetIdx - m_currentIdx;
		start = (uint32_t) &m_rampUpData[m_currentIdx];
	}
	else
	{
		count = m_currentIdx - m_targetIdx;
		start = (uint32_t) &m_rampDownData[m_rampDataLen - m_currentIdx];
	}
 
	SetDma(start, count);
 
	m_idxReached = 0;
	Go();
 
}

here are the files for stepper.h and stepper.cpp

1 ACCEPTED SOLUTION

Accepted Solutions
TDK
Guru

You can set up a hardware watchpoint on the variable to figure out exactly what/when the value changes. Could be an out of bounds write, or stack overflow.

If you feel a post has answered your question, please click "Accept as Solution".

View solution in original post

5 REPLIES 5
KnarfB
Principal III

Hmm. Don't see issues with your code. You could step at instruction code level through the call. IIRC the first parameter should be the this pointer in r0, then idx in r1. You could also make ids a static variable for the moment to validate that its not the (stack) memory which is accidently overwritten.

What compiler/IDE/chip are you using?

hth

KnarfB

KnarfB
Principal III

... or strip down the methods to a bare minimum

TDK
Guru

You can set up a hardware watchpoint on the variable to figure out exactly what/when the value changes. Could be an out of bounds write, or stack overflow.

If you feel a post has answered your question, please click "Accept as Solution".
JHöfl.1
Associate II

The culprit was one of the ccr interrupts that are activated right befor the method is called. Within them i call the method aswell but with a different value for idx.

I only noticed from looking at the call stack.

Thanks for the tip. I haven’t used this feature befor. It was really helpful.