Discussion forum for the BasicX family of microcontroller chips.
|
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 |
|
|
|
As I have started into the adventure of C and things much deeper into the workings of the Atmel processor line I have grown in my appreciation of what BasicX has done for me. The truth is that if I had to start where I am now, I would not have. And I am only a small part of the way up the mountain. Someone once told me that the only way to eat an elephant is 1 bite (byte) at a time. That seems to apply to programming in C also! Bob Roos |
|
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 |