TABLE OF CONTENTS


/Task [ Modules ]

[ Top ] [ Modules ]

DESCRIPTION

Task related functions - Create, Kill, Suspend, Resume and Context Switch


Task/Os_task_settings [ Constants ]

[ Top ] [ Task ] [ Constants ]

DESCRIPTION

Task-related Settings

DECLARATION

#if Varexist( "Os_enable_floating_point") = False
   Const Os_enable_floating_point = False                   ' Set to true if a Task uses floating point math   '
#endif
#if Varexist( "Os_enable_task_signals") = False
   Const Os_enable_task_signals = False                     ' Set to true if Task signals are used   '
#endif

Task/Queue_Modes [ Constants ]

[ Top ] [ Task ] [ Constants ]

DESCRIPTION

Task queue mode / action when resource is not available

DECLARATION

Const Os_queuemode_noblock = 0                              ' immediately return an error, Task continues execution   '
Const Os_queuemode_block = 1                                ' wait until Free   '
Const Os_queuemode_timeout = 2                              ' wait until Free or return an error after timeout   '

Task/Suspend_Modes [ Constants ]

[ Top ] [ Task ] [ Constants ]

DESCRIPTION

Enumerates different suspend modes

DECLARATION

Const Os_task_suspend_nowakeup = 0                          ' never resume Task automatically   '
Const Os_task_suspend_interrupt = 1                         ' resume on HW Interrupt   '
Const Os_task_suspend_timersingleshot = 2                   ' resume ONE TIME after Timer expires   '
Const Os_task_suspend_timerrunning = 3                      ' resume periodically   '

Task/Task_Header [ Object Headers ]

[ Top ] [ Task ] [ Object Headers ]

DESCRIPTION

Header structure of the Task object

DECLARATION

Const Os_task_hdr_timer_ptr = 0
Const Os_task_hdr_hwstack_ptr = Os_timer_hdr_size + 0
Const Os_task_hdr_suspendmode_ptr = Os_timer_hdr_size + 2
Const Os_task_hdr_eventsource_ptr = Os_timer_hdr_size + 3
Const Os_task_hdr_value_ptr = Os_timer_hdr_size + 5
#if Os_enable_task_signals = True
   Const Os_task_hdr_signals_ptr = Os_timer_hdr_size + 7    ' event flags   '
   Const Os_task_hdr_size1 = 1
#else
   Const Os_task_hdr_size1 = 0
#endif
Const Os_task_hdr_size_common = Os_timer_hdr_size + Os_task_hdr_size1 + 7

Task/Os_task_active [ Variables ]

[ Top ] [ Task ] [ Variables ]

DESCRIPTION

Pointer to the currently executed Task

DECLARATION

Dim Os_task_active As Word
Me Alias Os_task_active

Task/Os_task_create [ Functions ]

[ Top ] [ Task ] [ Functions ]

DESCRIPTION

Creates a new Task and prepares the stacks

DECLARATION

Function Os_task_create(byval Entrypoint As Word , Byval Hwstack_size As Word , Byval Swstack_size As Word , Byval Frame_size As Word) As Word

INPUTS

    Entrypoint: Program address where the Task should begin to execute
    Hwstack_size, Swstack_size, Frame_size: private Task stacks

OUTPUTS

    Task block pointer

SEE ALSO

    Task/Os_task_kill

SOURCE

   Local Blocksize As Word
   Local Taskblock As Word
   Local Pointer As Word
   Local Databyte As Byte

   ' calc needed block size and allocate block   '
   Blocksize = Hwstack_size + Swstack_size
   Blocksize = Blocksize + Frame_size
   Blocksize = Blocksize + Os_task_hdr_size
   Taskblock = Malloc(blocksize)

   If Taskblock = 0 Then
      ' error allocating memory block   '
      Os_task_create = 0
      Exit Function
   End If
   Os_mem_clear Taskblock , Blocksize

   Pointer = Taskblock + Blocksize                          ' hw stack   '
   Blocksize = Taskblock + Os_task_hdr_size                 ' frame   '

   ' entry point -> hwstack   '
   Databyte = Low(entrypoint)
   Out Pointer , Databyte
   Decr Pointer                                             ' Low(Entrypoint)   '
   Databyte = High(entrypoint)
   Out Pointer , Databyte
   Decr Pointer                                             ' High(Entrypoint)   '

   ' remaining registers = 0 -> hwstack   '
   Pointer = Pointer - 6                                    ' R16, SREG, R0-R3   '

   ' frame pointer -> hwstack   '
   Databyte = Low(blocksize)
   Out Pointer , Databyte
   Decr Pointer                                             ' Low(Frame)   '
   Databyte = High(blocksize)
   Out Pointer , Databyte

   Pointer = Pointer - 14                                   ' High(Frame), R7, R10, R11, R17-R22, R24-R28   '

   #if Varexist( "RAMPZ") = True                            ' RAMPZ   '
      Decr Pointer
   #endif

   #if Os_enable_extended_io = True
      Decr Pointer                                          ' R23 (extended IO)   '
   #endif

   #if Os_enable_floating_point = True
      Pointer = Pointer - 4                                 ' R12-R15 (floating point)   '
   #endif

   ' sw stack -> hwstack   '
   Blocksize = Blocksize + Frame_size
   Blocksize = Blocksize + Swstack_size
   Databyte = Low(blocksize)
   Out Pointer , Databyte
   Decr Pointer                                             ' Low(Swstack)   '
   Databyte = High(blocksize)
   Out Pointer , Databyte

   Pointer = Pointer - 3                                    ' High(Swstack), R30, R31   '

   ' save hwstack pointer   '
   Setword Taskblock , Os_task_hdr_hwstack_ptr , Pointer
   Setbyte Taskblock , Os_timer_hdr_triggered_ptr , &HFF    ' Timer triggers a Task event   '

   Os_task_create = Taskblock
End Function

Task/Os_task_event [ Functions ]

[ Top ] [ Task ] [ Functions ]

DESCRIPTION

Handles wake-up events

DECLARATION

Sub Os_task_event()

SOURCE

   Local Suspendmode As Byte

   Suspendmode = Getbyte(os_event_task , Os_task_hdr_suspendmode_ptr)
   If Suspendmode = Os_task_suspend_timersingleshot Or Suspendmode = Os_task_suspend_timerrunning Then
      Os_timer_stop Os_event_task
   End If

   Os_sched_event

   Gosub Os_task_yield
End Sub

Task/Os_task_kill [ Functions ]

[ Top ] [ Task ] [ Functions ]

DESCRIPTION

Completely stops the Task and deletes it

DECLARATION

Sub Os_task_kill(byref Task As Word)

SEE ALSO

    Task/Os_task_create

SOURCE

   Os_task_suspendmode Task , Os_task_suspend_nowakeup , 0
   Os_task_suspend Task
   Free Task
End Sub

Task/Os_task_load_context_full [ Functions ]

[ Top ] [ Task ] [ Functions ]

DESCRIPTION

Loads the complete process context from the process hw stack, restores the used frame space and sets HW Stack and Frame pointers

DECLARATION

Macro Os_task_load_context_full

SOURCE

   Os_task_tempword_isr = Getword(Os_task_active , Os_task_hdr_hwstack_ptr)       ' restore hw stack pointer   '
   Hwstack = Os_task_tempword_isr

   ' restore RAMPZ if available   '
   #if Varexist( "RAMPZ") = True
      POP R16
      Out Rampz , R16
   #endif

   ' restore registers   '
   POP  R31
   POP  R30
   POP  R29                                                 ' R28, R29: swstack   '
   POP  R28
   POP  R27
   POP  R26
   POP  R25
   POP  R24
   #if Os_enable_extended_io = True
      POP  R23                                              ' R23: extended IO-space   '
   #endif
   POP  R22
   POP  R21
   POP  R20
   POP  R19
   POP  R18
   POP  R17
'   POP  R16   '

   #if Os_enable_floating_point = True
      POP  R15                                              ' R12-R15: floating point   '
      POP  R14
      POP  R13
      POP  R12
   #endif

   POP  R11
   POP  R10
'   POP  R9                                                 ' R6, R8, R9: not used by Bascom   '
'   POP  R8   '
   POP  R7
'   POP  R6   '
   pop  R5                                                  ' R4, R5: frame pointer   '
   pop  R4
   POP  R3
   POP  R2
   POP  R1
   pop  R0
   ' SREG   '
   POP  R16
   !OUT Sreg , R16
   POP  R16

   ' put the return address from SRAM back on the stack   '
   STS  {os_task_tempbyte_isr}, R16                         ' save used register   '

   LDS R16, {os_critical_nesting_level}                     ' Os_critical_exit without enabling interrupts, this is done by RETI   '
   DEC R16
   STS {os_critical_nesting_level}, R16

   LDS  R16, {os_task_tempbyte_isr}                         ' restore register   '
End Macro

Task/Os_task_resume [ Functions ]

[ Top ] [ Task ] [ Functions ]

DESCRIPTION

Resumes a Task by placing it on the ready list of the scheduler

DECLARATION

Sub Os_task_resume(byref Task As Word)

SEE ALSO

    Task/Os_task_suspend

SOURCE

   Local Suspendmode As Byte

   Suspendmode = Getbyte(Task , Os_task_hdr_suspendmode_ptr)
   If Suspendmode = Os_task_suspend_timersingleshot Or Suspendmode = Os_task_suspend_timerrunning Then
      Os_timer_stop Task
   End If

   Os_sched_resume Task
End Sub

Task/Os_task_save_context_full [ Functions ]

[ Top ] [ Task ] [ Functions ]

DESCRIPTION

Saves the complete process context to the process hw stack, stores the used frame space and saves HW Stack and Frame pointers

DECLARATION

Macro Os_task_save_context_full

SOURCE

   PUSH R16
   in   R16 , SREG
   PUSH R16                                                 ' save SREG to hw stack   '

   ' disable interrupts (might be called from outside the kernel isr, ex. a Task suspending himself)   '
   Os_enter_critical

   ' save registers   '
   PUSH R0
   PUSH R1
   PUSH R2
   PUSH R3
   PUSH R4                                                  ' R4, R5: frame pointer   '
   PUSH R5
'   PUSH R6                                                 ' R6, R8, R9: not used by Bascom   '
   PUSH R7
'   PUSH R8   '
'   PUSH R9   '
   PUSH R10
   PUSH R11

   #if Os_enable_floating_point = True
      PUSH R12                                              ' R12-R15: floating point math   '
      PUSH R13
      PUSH R14
      PUSH R15
   #endif

'   PUSH R16   '
   PUSH R17
   PUSH R18
   PUSH R19
   PUSH R20
   PUSH R21
   PUSH R22
   #if Os_enable_extended_io = True
      PUSH R23                                              ' extended IO-space   '
   #endif
   PUSH R24
   PUSH R25
   PUSH R26
   PUSH R27
   PUSH R28                                                 ' R28, R29: swstack   '
   PUSH R29
   PUSH R30
   PUSH R31

   ' save RAMPZ if available   '
   #if Varexist( "RAMPZ") = True
      IN R16, RAMPZ
      PUSH R16
   #endif

   Os_task_tempword_isr = Hwstack

   ' switch to kernel context (Task stacks remain untouched by kernel functions)   '
   Hwstack = Sys_hwstack_start
   Swstack = Sys_swstack_start
   Frame = Sys_frame_start

   Setword Os_task_active , Os_task_hdr_hwstack_ptr , Os_task_tempword_isr       ' save tasks hw stack pointer   '
End Macro

Task/Os_task_suspend [ Functions ]

[ Top ] [ Task ] [ Functions ]

DESCRIPTION

Sends a Task into sleep mode.

DECLARATION

Sub Os_task_suspend(byref Task As Word)

SEE ALSO

    Task/Os_task_resume

SOURCE

   Local Suspendmode As Byte
   'Local Temp_word As Word   '

   Suspendmode = Getbyte(Task , Os_task_hdr_suspendmode_ptr)
   If Suspendmode = Os_task_suspend_timersingleshot Or Suspendmode = Os_task_suspend_timerrunning Then
      Os_timer_start Task
   End If

   Os_sched_suspend Task
End Sub

Task/Os_task_suspendmode [ Functions ]

[ Top ] [ Task ] [ Functions ]

DESCRIPTION

Sets the suspend mode and the wake-up source for a given Task.

DECLARATION

Sub Os_task_suspendmode(byref Task As Word , Byval Suspendmode As Byte , Byval Value As Word)

SEE ALSO

    Task/Suspend_Modes

SOURCE

   Local Task_suspendmode As Byte

   Task_suspendmode = Getbyte(Task , Os_task_hdr_suspendmode_ptr)
   Setbyte Task , Os_task_hdr_suspendmode_ptr , Suspendmode
   If Task_suspendmode = Os_task_suspend_interrupt Then
      If Suspendmode <> Os_task_suspend_timerrunning Then
         Os_int_deregister Task
      End If
   End If
   If Task_suspendmode = Os_task_suspend_timersingleshot Or Task_suspendmode = Os_task_suspend_timerrunning Then
      If Suspendmode <> Os_task_suspend_timersingleshot Or Suspendmode <> Os_task_suspend_timerrunning Then
         Os_timer_stop Task
      End If
   End If

   If Suspendmode = Os_task_suspend_interrupt Then
      Task_suspendmode = Value
      Os_int_register_task Task , Task_suspendmode
   End If
   If Suspendmode = Os_task_suspend_timersingleshot Or Suspendmode = Os_task_suspend_timerrunning Then
      Setword Task , Os_timer_hdr_interval_ptr , Value
   End If
End Sub

Task/Os_task_yield [ Functions ]

[ Top ] [ Task ] [ Functions ]

DESCRIPTION

Stops execution of the current Task and hands over its CPU time to the next Task.

DECLARATION

Os_task_yield:

SOURCE

   ' save the context   '
   Os_task_save_context_full

   ' select the next Task   '
   Os_sched_yield

   ' restore its context   '
   Os_task_load_context_full
reti                                                        ' return and set the global Interrupt enable flag   '