Enable Hardware Watchdog

Discussion about Z-Uno product. Visit http://z-uno.z-wave.me for more details.
User avatar
PoltoS
Posts: 7565
Joined: 26 Jan 2011 19:36

Re: Enable Hardware Watchdog

Post by PoltoS »

Arduino have a few times bigger stack and very different memory layout. It is also different in passing pointers and have more registers. Z-Wave chip is based on 8051 arch - much more limited one.

Check this nested call: AcqusitionMotor->ReadForce->ReadResistance->ReadVoltage
p0lyg0n1
Posts: 242
Joined: 04 Aug 2016 07:14

Re: Enable Hardware Watchdog

Post by p0lyg0n1 »

Arduino boards has AVR microchips installed on it. Z-Uno uses another architecture (i8051). AVR has about 256 bytes of stack and doesn't run another code at the same time. Z-Uno has just about 130bytes of stack and it runs two firmwares in the same time: main firmware that makes all Z-Wave processing and the sketch. So, we have to be shorter. You can simply calc the maximum usage of stack(it's not precise, but gives you a near value of stack usage):
1. For every parameter add its size to sum: byte=1,word=int=2,long=dword=4,float=2 etc.
2. Do the same thing for every inner (local) variable
3. The same thing to return parameter.
4. Every call uses about 4 bytes (2 for return code, 2 to push a base pointer).

For example:
float funcA(float a, float b)
{
float d = 0.5*a;
float c = 0.2878*d;
return d;
}

It will take:
1. Parameters: flota+float = 4 + 4 = 8bytes
2. Local variables: float+float = 4 + 4 = 8 bytes
3. return result: float = 4 bytes
4. return address + previous base pointer (for every call the same): 4bytes
And we have: 8 + 8 + 4 + 4 = 24bytes of stack to call function like this.
If you call the nested (funcA(){ return funcB(...);}, funcB(){ return funcD(); } etc.) 4 functions like this you will have 24*4 (just for example) = 96 and it will be too much ;-)
If we have an radio/timer or another interrupt (it's always happen async with your code) in the deep point of your functions the device will die...
petergebruers
Posts: 255
Joined: 26 Jul 2015 17:29

Re: Enable Hardware Watchdog

Post by petergebruers »

Can I shamefully self-promote a script of mine?

https://github.com/petergebruers/Z-Uno-BH1750

In that script I wrote:

// Global variables

// Z-Uno is a SOC with limited resources compared to e.g a Raspberry Pi
// or esp-32. To limit stack usage and parameter passing and data shuffling,
// I tend to use global variables instead of local or parameter passing. This goes against
// the idea of "abstraction" and "isolation of data". Whether this is better
// for such a small project is debatable...

This is to avoid stack issues. I bet lots of programmers do not like the code, because of all the globals. For example, look at function:

void CalculateDelay()

It uses no parameters and returns nothing, it only uses global variables. No abstraction at all! My teacher of "Structured Programming" would not be pleased.

Why did I not just move the code of CalculateDelay to the main loop, I use it only once? That would save even more stack space. A separate function is more readable and it allows me to debug the function with another compiler. You could add "inline" to the definition, but I do not think the compiler really inlines it... I have to recheck that with 2.1.1.

Also, memory used in interrupt handler and speed of the handler are optimized...

If you know some assembler, you can have a look at the .lst file, it lists locals, autos, and registers used in function calls...
petergebruers
Posts: 255
Joined: 26 Jul 2015 17:29

Re: Enable Hardware Watchdog

Post by petergebruers »

-
Last edited by petergebruers on 26 Oct 2017 00:25, edited 1 time in total.
apica
Posts: 15
Joined: 19 Oct 2017 12:46

Re: Enable Hardware Watchdog

Post by apica »

p0lyg0n1 wrote:
21 Oct 2017 01:56
Arduino boards has AVR microchips installed on it. Z-Uno uses another architecture (i8051). AVR has about 256 bytes of stack and doesn't run another code at the same time. Z-Uno has just about 130bytes of stack and it runs two firmwares in the same time: main firmware that makes all Z-Wave processing and the sketch. So, we have to be shorter. You can simply calc the maximum usage of stack(it's not precise, but gives you a near value of stack usage):
Thank you for your reply! I didn't had any information about how big the stack is, and I never though it would be that low. From where I should get this information? Is there a complete datasheet with information for developers?
p0lyg0n1 wrote:
21 Oct 2017 01:56
1. For every parameter add its size to sum: byte=1,word=int=2,long=dword=4,float=2 etc.
2. Do the same thing for every inner (local) variable
3. The same thing to return parameter.
4. Every call uses about 4 bytes (2 for return code, 2 to push a base pointer).

For example:
float funcA(float a, float b)
{
float d = 0.5*a;
float c = 0.2878*d;
return d;
}

It will take:
1. Parameters: flota+float = 4 + 4 = 8bytes
2. Local variables: float+float = 4 + 4 = 8 bytes
3. return result: float = 4 bytes
4. return address + previous base pointer (for every call the same): 4bytes
And we have: 8 + 8 + 4 + 4 = 24bytes of stack to call function like this.
If you call the nested (funcA(){ return funcB(...);}, funcB(){ return funcD(); } etc.) 4 functions like this you will have 24*4 (just for example) = 96 and it will be too much ;-)
If we have an radio/timer or another interrupt (it's always happen async with your code) in the deep point of your functions the device will die...
Your method is a good way to estimate it. I'll keep that in mind.

Thank you!
pjpankhurst
Posts: 31
Joined: 07 Sep 2017 00:40

Re: Enable Hardware Watchdog

Post by pjpankhurst »

This would explain the issues I was seeing when I ported my app from Arduino to Z-uno..my gut feel was that it may be a stack issue and this seems to confirm it as a prime candidate, especially as the issue has gone away on the new release and I noticed in the release note there had been a lot of stack optimisation work
Post Reply