size of task stack

Started by Tom Stutsman July 9, 2004
I was wondering how you figure out how much task space to use for a
program running in the background. For instance if I am running some
servo's in the background on my robot I usually specify a task stack
(1 to 30), but I am going to be doing that plus run 2 (13 line) loop
programs controling one of the servo's, How big of a stack should I
specify?

Thanks,
TomBot



--- In , "Tom Stutsman" <tom_stutsman@y...>
wrote:
> I was wondering how you figure out how much task space to use for a
> program running in the background.

The answer depends on the structure of your program. Two tasks could
have vastly different stack requirements depending on how many
strings are used (and the default string size), how many local
variables are used in the task itself, how deeply nested are calls to
other routines and the local variables declared in those routines,
(including recursively called routines), etc.

One way to guess at the proper stack size is to initialize the bytes
of a stack to a known value before running the task and then examine
the task stack after it has run to determine how much of it was
used. This process is described in the BasicX Operating System
Reference manual (page 14 of version 2.1).

I have posted a link to a utility that might help statically
determine the required stack size of both the main routine and
individual tasks.

See this message for more information.
http://groups.yahoo.com/group/basicx/message/15961




On a similarly related topic..
I was using the Ramalyzer (THANKS 2 DON KINZER!!) to get a good idea
of organizing my program. I have quite a few subroutines, but
organized it so that no sub-routine was nested inside another.

However, I have one task with a WaitForInterrupt... It just killed
my requirements - four lines wanting 99 bytes. Mind you that I think
that I have that available, but I don't want to push the extremes of
my limited experience with conserving RAM.

Is there a better way to use the WaitForInterrupt?
I could "cheat" & use a GetPin and probably conserve overhead, but I
am sure that there is a proper way to do what I am doing

Thanks in advance for any input,
Thad

--- In , "Don Kinzer" <dkinzer@e...> wrote:
> --- In , "Tom Stutsman" <tom_stutsman@y...>
> wrote:
> > I was wondering how you figure out how much task space to use for
a
> > program running in the background.
>
> The answer depends on the structure of your program. Two tasks
could
> have vastly different stack requirements depending on how many
> strings are used (and the default string size), how many local
> variables are used in the task itself, how deeply nested are calls
to
> other routines and the local variables declared in those routines,
> (including recursively called routines), etc.
>
> One way to guess at the proper stack size is to initialize the
bytes
> of a stack to a known value before running the task and then
examine
> the task stack after it has run to determine how much of it was
> used. This process is described in the BasicX Operating System
> Reference manual (page 14 of version 2.1).
>
> I have posted a link to a utility that might help statically
> determine the required stack size of both the main routine and
> individual tasks.
>
> See this message for more information.
> http://groups.yahoo.com/group/basicx/message/15961





I've had good luck with something like the following...

I started with RC_SERVO_TASK_STACK_SIZE set WAY too big. To be sure -
after it printed the Servo Stack size (40), I tried it again with
initializing the stack to bx1111_1111 and checking for the first bx1111_1111.

Good Luck!
Ken_S.

Option Explicit
Option Strict On

'****************************************************************
'Public Const As Byte = 1 '*** Com1 Transmit
'Public Const As Byte = 2 '*** Com1 Receive
'Public Const As Byte = 3 '*** ATN Line
'Public Const As Byte = 4 '*** Ground

Public Const RADIO_Channel_1_Pin As Byte = 5 '*** PortC Bit 7
Public Const RADIO_Channel_2_Pin As Byte = 6 '*** PortC Bit 6
Public Const RADIO_Channel_3_Pin As Byte = 7 '*** PortC Bit 5
Public Const RADIO_Channel_4_Pin As Byte = 8 '*** PortC Bit 4

Public Const GPS_SERIAL_IN_PIN As Byte = 9 '*** PortC Bit 3
Public Const GPS_SERIAL_OUT_PIN As Byte = 10 '*** PortC Bit 2

'Public Const As Byte = 11 '*** PortC Bit 1
(Interrupt Pin)
'Public Const As Byte = 12 '*** PortC Bit 0 (Input
Capture Pin)
'Public Const As Byte = 13 '*** PortA Bit 7 (ADC 7)
'Public Const As Byte = 14 '*** PortA Bit 6 (ADC 6)
'Public Const As Byte = 15 '*** PortA Bit 5 (ADC 5)

Public Const RC_SERVO_SPEED_PIN As Byte = 16 '*** PortA Bit 4 (ADC 4)
Public Const SERVEO_1_PIN As Byte = 17 '*** PortA Bit 3 (ADC 3)
Public Const SERVEO_2_PIN As Byte = 18 '*** PortA Bit 2 (ADC 2)
Public Const SERVEO_3_PIN As Byte = 19 '*** PortA Bit 1 (ADC 1)
Public Const SERVEO_4_PIN As Byte = 20 '*** PortA Bit 0 (ADC 0)

'Public Const As Byte = 21 '*** VCC (5V Regulated)
'Public Const As Byte = 22 '*** Reset (Low Active)
'Public Const As Byte = 23 '*** Ground
'Public Const As Byte = 24 '*** Vin 5.5V to 12V
Unregulated

Public Const RED_LED_PIN As Byte = 25 '*** Red LED
Public Const GREEN_LED_PIN As Byte = 26 '*** Green LED
'Public Const As Byte = 27 '*** SPI Control

'****************************************************************
'*** Servo Outputs ***
Public gServo_1_Out_Period As Single
Public gServo_2_Out_Period As Single
Public gServo_3_Out_Period As Single
Public gServo_4_Out_Period As Single

'*** Flags ***
Public gEnable_Manual_Override As Boolean
Public gWatchdog_Flag As Boolean
Public gTimer_Semaphore As Boolean

'***************** RC Servo Task Stack **************************
Public Const RC_SERVO_TASK_STACK_SIZE As Byte = 40 '*** Start with this WAY
too big ***
Public RC_Servo_Task_Stack(1 to RC_SERVO_TASK_STACK_SIZE) As Byte

'******************************************************************************
Public Sub Main()
'*** Initialize ***
Call Initialize()

'*** Endless Loop ***
Do
Call Measure_RC_Servo_Task_Stack()

'*** DoEvents ***
Call Delay(0.0)
Loop
End Sub
'******************************************************************************
Private Sub Initialize()
'*** Kick Off Manual_Override_Task ***
Call Initialize_RC_Servo_Task()
CallTask "RC_Servo_Task", RC_Servo_Task_Stack
End Sub
'******************************************************************************

Private Const MIN_VALID_RADIO_PERIOD As Single = 500.0
Private Const MAX_VALID_RADIO_PERIOD As Single = 1500.0

'*********************************************************************************************************************************
Public Sub Initialize_RC_Servo_Task()
Dim x As Byte

'*** Set all Elements of RC_Servo_Task_Stack to 0 for later Measuring ***
For x = 1 To RC_SERVO_TASK_STACK_SIZE
RC_Servo_Task_Stack(x) = 0
Next
End Sub
'*********************************************************************************************************************************
Public Sub RC_Servo_Task()
Dim x As Single
Dim WaitUntil As Single

'*** Calculate Next 50mS Period ***
WaitUntil = Timer() + 0.050

'*** Endless Loop ***
Do
'*** Test for gEnable_Manual_Override = True ***
If ( (gEnable_Manual_Override = True) ) Then
'*** Test if Timer is Available (and Take Timer if it is) ***
If ( Semaphore(gTimer_Semaphore) = True ) Then
Call PutPin(GREEN_LED_PIN, bxOutputLow)
'*** Measure Radio Channel 1 ***
x = 0.0
Call PulseIn(RADIO_Channel_1_Pin, 1, x)
'*** Test for Valid Signal ***
If ( (x >= MIN_VALID_RADIO_PERIOD) AND (x <=
MAX_VALID_RADIO_PERIOD) ) Then
gServo_1_Out_Period = x

'*** Measure Radio Channel 2 ***
x = 0.0
Call PulseIn(RADIO_Channel_2_Pin, 1, x)
'*** Test for Valid Signal ***
If ( (x >= MIN_VALID_RADIO_PERIOD) AND (x <=
MAX_VALID_RADIO_PERIOD) ) Then
gServo_2_Out_Period = x
End If

'*** Measure Radio Channel 3 ***
x = 0.0
Call PulseIn(RADIO_Channel_3_Pin, 1, x)
'*** Test for Valid Signal ***
If ( (x >= MIN_VALID_RADIO_PERIOD) AND (x <=
MAX_VALID_RADIO_PERIOD) ) Then
gServo_3_Out_Period = x
End If

'*** Measure Radio Channel 4 ***
x = 0.0
Call PulseIn(RADIO_Channel_4_Pin, 1, x)
'*** Test for Valid Signal ***
If ( (x >= MIN_VALID_RADIO_PERIOD) AND (x <=
MAX_VALID_RADIO_PERIOD) ) Then
gServo_4_Out_Period = x
End If
End If
'*** Set Timer_In_Use_Semaphore = False ***
gTimer_Semaphore = False
End If
End If

Call PutPin(GREEN_LED_PIN, bxOutputHigh)
'*** Wait Until Next 50mS Period ***
x = 0.0
Do While ( Timer() < WaitUntil )
x = x + 1.0
Call Delay(0.0)
Loop
gDebugSingle = CSng(x)

'*** Calculate Next 50mS Period ***
WaitUntil = Timer() + 0.050

'*** Test for Timer Available ***
If ( Semaphore(gTimer_Semaphore) = True ) Then
Call PutPin(GREEN_LED_PIN, bxOutputLow)
'*** Output to Servos ***
Call PulseOut(SERVEO_1_PIN, gServo_1_Out_Period, 1)
Call PulseOut(SERVEO_2_PIN, gServo_2_Out_Period, 1)
Call PulseOut(SERVEO_3_PIN, gServo_3_Out_Period, 1)
Call PulseOut(SERVEO_4_PIN, gServo_4_Out_Period, 1)

'*** Set Timer_In_Use_Semaphore = False ***
gTimer_Semaphore = False
Call PutPin(GREEN_LED_PIN, bxOutputHigh)
End If

'*** Test for gWatchdog_Flag = True ***
If ( gWatchdog_Flag = True ) Then
Call Watchdog()
gWatchdog_Flag = False
End If
Loop
End Sub
'*********************************************************************************************************************************
Public Sub Measure_RC_Servo_Task_Stack()
Dim x As Byte

'*** Find First Used Element of RC_Servo_Task_Stack() ***
x = RC_SERVO_TASK_STACK_SIZE
Do While ( (x > 0) AND (RC_Servo_Task_Stack(x) = 0) )
x = x - 1
Loop
Debug.Print "RC_Servo_Stack=" & CStr(x)
End Sub At 05:02 PM 7/9/2004, you wrote:
>I was wondering how you figure out how much task space to use for a
>program running in the background. For instance if I am running some
>servo's in the background on my robot I usually specify a task stack
>(1 to 30), but I am going to be doing that plus run 2 (13 line) loop
>programs controling one of the servo's, How big of a stack should I
>specify?
>
>Thanks,
>TomBot >Yahoo! Groups Links >
>



Add me to the list of Don Kinzer appreciators.

Ramalyze helped me find 65 bytes of RAM without losing any
functionality. It took me awhile to understand what I was looking at
but, once that gelled, it paid off well.

Thanks, Don! Tom
Tom Becker
--... ...--
www.RighTime.com
The RighTime Clock Company, Inc., Cape Coral, Florida USA
+1239 540 5700