Advertisement
abdullahkahraman

RTOS implementation using assembly

Jun 12th, 2012
307
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. list p=16f616
  2. #include p16f616.inc
  3.  
  4. ;*** Configuration Bits ***
  5. __CONFIG _FOSC_INTOSCIO & _WDTE_OFF & _WDT_OFF & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _IOSCFS_8MHZ & _BOREN_ON
  6. ;**************************
  7.  
  8. ;*** Variable Definitions ***
  9. VARS        UDATA                   ; Define undefined data(s).
  10. numOfTasks  res     1               ; This variable holds the number of tasks multiplied by 2.
  11. currentTask res     1               ; Index variable that points to the current task's index in "tasks"
  12. tasks       res     4               ; This is task "array". Every task occupies 2 bytes.
  13. ;****************************
  14.  
  15. ;*** Reset Vector ***
  16. RESET   CODE    0x0000              ; Define a code block starting at 0x0000, which is reset vector, labeled "RESET"
  17.         goto    start               ; Start the program.
  18. ;********************
  19.  
  20. ;*** Main Code ***
  21. MAIN    CODE
  22. start                               ; Label the start of the program as "start".
  23.         banksel TRISA               ; Select appropriate bank for TRISA.
  24.         clrf    TRISA               ; Clear TRISA register. Configure all of the PORTA pins as digital outputs.
  25.         clrf    TRISC               ; Clear TRISC register. TRISC and TRISA are at the same bank, no need for "banksel".
  26.         clrf    ANSEL               ; Clear ANSEL register and configure all the analog pins as digital i/o.
  27.         banksel PORTA               ; Select appropriate bank for PORTA.
  28.         clrf    PORTA               ; Clear PORTA register.
  29.         clrf    PORTC               ; Clear PORTC register. PORTC and PORTA are at the same bank, no need for "banksel".
  30.        
  31.  
  32.         movlw   0x04                ; W = Number of tasks * 2.
  33.         movwf   numOfTasks          ; Since every task has two datas in it, we will multiply by 2.
  34.         clrf    currentTask         ; Set the task#0 as current task.
  35.  
  36.         CALL    task0               ; Call task#0 since we need to initialize it. We are going to get..
  37.                                     ; ..its PCL and PCLATH values at the start address.
  38.         movlw   0x02                ; W = 2
  39.         addwf   currentTask, f      ; Increment currentTask by 2, since every task occupies 2 places.
  40.  
  41.         CALL    task1               ; Call task#1, for initialazation.
  42.  
  43. taskswitcher
  44.         movlw   0x02                ; W = 2
  45.         addwf   currentTask, f      ; Add 2 to currentTask, store it in currentTask.
  46.         movf    numOfTasks, w       ; W = numOfTasks
  47.         subwf   currentTask, w      ; w= f - w
  48.         btfsc   STATUS, 0           ; If currentTask >= numOfTasks
  49.         clrf    currentTask         ; Clear currentTask
  50.  
  51.         movlw   tasks               ; Store the address of tasks, which is the start address of our task "array".
  52.         addwf   currentTask, w      ; Add current task's index to the start address.
  53.                                     ; For example; task1's index is 2:  [task0_1][task0_2][task1_1][task1_2]....
  54.                                     ;                                       0        1        2        3
  55.         movwf   FSR                 ; We have the index of current task in W. Copy it to FSR
  56.         movf    INDF, w             ; Copy the contents of current task's first item to W
  57.         movwf   PCLATH              ; Copy W to PCLATH. As a result, current task's PCLATH will be in PCLATH register.
  58.  
  59.         incf    FSR, f              ; Increment index, so that we will point to the next item of current task.
  60.         movf    INDF, w             ; Copy the contents of current task's second item to W.
  61.         movwf   PCL                 ; Copy W to PCL. Finally, current task's PCL will be in PCL register.
  62.  
  63.         goto    $                   ; This instruction is not effective. But, enter the endless loop.
  64.  
  65. ;*** TASK 0 ***
  66. TASK0   CODE
  67. ;**************
  68. task0
  69.         movlw   tasks               ; Store the address of tasks, which is the start address of our task "array".
  70.         addwf   currentTask, w      ; Add current task's index to the start address.
  71.  
  72.         movwf   FSR                 ; We have the index of current task in W. Copy it to FSR
  73.         movf    PCLATH, w           ; Copy PCLATH register's contents to W register.
  74.         movwf   INDF                ; Copy W to current task's first item. We now store PCLATH.
  75.  
  76.         incf    FSR,f               ; Increment index, so that we will point to the next item of current task.
  77.         movlw   low($+3)            ; Copy PCL+3 to W register. This will let us save the PCL of the start of the task.
  78.         movwf   INDF                ; Copy W to task's next item. With that, we will initialize the current task.
  79.         return                      ; We have gathered our initialazation information. Return back to main.
  80.  
  81. task0main
  82.         banksel PORTA               ; Select the appropriate bank for PORTA
  83.         movlw   0xAA                ; Move literal to W so that W = 0xAA
  84.         movwf   PORTA               ; PORTA = 0xAA. Use a LATA register to create more robust code.
  85.  
  86.         movlw   tasks               ; Store the address of tasks, which is the start address of our task "array".
  87.         addwf   currentTask, w      ; Add current task's index to the start address.
  88.  
  89.         movwf   FSR                 ; We have the index of current task in W. Copy it to FSR
  90.         movf    PCLATH, w           ; Copy PCLATH register's contents to W register.
  91.         movwf   INDF                ; Copy W to current task's first item. We now store PCLATH of the current state of the task.
  92.  
  93.         incf    FSR,f               ; Increment index, so that we will point to the next item of current task.
  94.         movlw   low($+3)            ; Copy PCL+3 to W register. This will let us save the PCL of the current state of the task.
  95.         movwf   INDF                ; Copy W to task's next item. With that, we will initialize the current task.
  96.  
  97.         goto    taskswitcher        ; Yield the CPU to the awaiting task by going to task switcher.
  98.  
  99.         banksel PORTA               ; Select the appropriate bank for PORTA
  100.         movlw   0x55                ; Move literal to W so that W = 0x55
  101.         movwf   PORTA               ; PORTA = 0xAA. Use a LATA register to create more robust code.
  102.  
  103.         goto    task0main           ; Loop by going back to "task0main". We will continuously toggle PORTA.
  104.  
  105. ;*** TASK 0 ***
  106. TASK1   CODE
  107. ;**************
  108. task1
  109.         movlw   tasks               ; Store the address of tasks, which is the start address of our task "array".
  110.         addwf   currentTask, w      ; Add current task's index to the start address.
  111.  
  112.         movwf   FSR                 ; We have the index of current task in W. Copy it to FSR
  113.         movf    PCLATH, w           ; Copy PCLATH register's contents to W register.
  114.         movwf   INDF                ; Copy W to current task's first item. We now store PCLATH.
  115.  
  116.         incf    FSR,f               ; Increment index, so that we will point to the next item of current task.
  117.         movlw   low($+3)            ; Copy PCL+3 to W register. This will let us save the PCL of the start of the task.
  118.         movwf   INDF                ; Copy W to task's next item. With that, we will initialize the current task.
  119.         return                      ; We have gathered our initialazation information. Return back to main.
  120.  
  121. task1main
  122.         banksel PORTA               ; Select the appropriate bank for PORTA
  123.         movlw   0xAA                ; Move literal to W so that W = 0xAA
  124.         movwf   PORTA               ; PORTA = 0xAA. Use a LATA register to create more robust code.
  125.  
  126.         movlw   tasks               ; Store the address of tasks, which is the start address of our task "array".
  127.         addwf   currentTask, w      ; Add current task's index to the start address.
  128.  
  129.         movwf   FSR                 ; We have the index of current task in W. Copy it to FSR
  130.         movf    PCLATH, w           ; Copy PCLATH register's contents to W register.
  131.         movwf   INDF                ; Copy W to current task's first item. We now store PCLATH of the current state of the task.
  132.  
  133.         incf    FSR,f               ; Increment index, so that we will point to the next item of current task.
  134.         movlw   low($+3)            ; Copy PCL+3 to W register. This will let us save the PCL of the current state of the task.
  135.         movwf   INDF                ; Copy W to task's next item. With that, we will initialize the current task.
  136.  
  137.         goto    taskswitcher        ; Yield the CPU to the awaiting task by going to task switcher.
  138.  
  139.         banksel PORTA               ; Select the appropriate bank for PORTA
  140.         movlw   0x55                ; Move literal to W so that W = 0x55
  141.         movwf   PORTA               ; PORTA = 0xAA. Use a LATA register to create more robust code.
  142.  
  143.         goto    task1main           ; Loop by going back to "task1main". We will continuously toggle PORTA.
  144.  
  145.         END                         ; END of the program.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement