Jste zde

Multitáskové jádro

Další příspěvek do rozsáhlé sbírky programů v Assembleru pro deriváty rodiny Intel 51. Tentokrát

o tom, jak se pokusit na jednočipu o multitasking.

Chtěl bych poprosit autory softwarových příspěvků, aby je příště posílali včetně textového souboru, kde by o tom svém dílku trošičku napsali. Takhle to vypadá jak nějaký disasemblovaný kód. 
 

;*****************************************************************************
;*                                       &n bsp;                  &nbs p;                 *
;*        MTJ.ASM                  & nbsp;                  &nb sp;                    ;   *
;*        MultiTaskove Jadro                  &nb sp;                    ;           *
;*                                       &n bsp;                  &nbs p;                 *
;*        16.10.1997, Miroslav Stuchlik (c)                    ;               *
;*                                       &n bsp;                  &nbs p;                 *
;***************************************************************************** 

; Program je vytahem z funkciniho programu. Jadro rozhodne neni zcela optimalni
; ale funguje. Ve funkcnim programu bylo 16 uloh, ktere si navzajem predavaly
; parametry, spousteli a zastavovaly se navzajem. Ke spousteni 4 tasku byl
; pouzit seriovy port
; Zde je priklad se 4 primitivnimi tasky. Interrupty nejsou vyuzity.
; bank 0, 1 - vyuzivaji tasky
; bank 1, 2 - vyuziva system
; XRAM je delena po 256 bytech kazdemu tasku, z toho cast je pouzita pro
; archivaci ulohy je-li neaktivni
; Velikosti pameti pouzivane systemem i tasky si zajemce muze modifikovat
; sam podle potreby, zde je jen priklad
 

$INCLUDE ( reg520.inc ) 

STACK             equ   080h 

MAX_TASK_NUM      equ    04h 

SLEEP_TASK        equ    00h
ACTIVE_TASK       equ    01h 

; ***************************  Hlavni program  ****************************** 

CODE1 SEGMENT CODE
 RSEG CODE1 

START:
      ljmp  BEGIN 

;Interrupt Vectors
 

CSEG AT 000BH
IV_T0 CODE  000BH
      ljmp  T0_IRQ 

CSEG AT 0023H
IV_S0     CODE  0023H
      ljmp  S0_IRQ
 

;============================================================================
;===========================  Interrupt od CT0  =============================
;============================================================================
; XX00 = 0 : TASK je neaktivni
;      > 0 : TASK je aktivni
; XX01 = n : ( 256 - n ) = pocet tiku casovace do IRQ * 256
; XX02 = m : pocet znaku v bufferu stacku ( max 127 )
; XX03 - XX85 : data stacku
; XX90 - data 

T0_IRQ:
      clr   TR0                    ;     ; zastaveni citace ( TCON ) 

; -----------------------  Ulozeni rozpracovane ulohy  ----------------------
      push  ACC
      push  B
      push  PSW
      push  DPL
      push  DPH
      push  R00
      push  R01
      push  R02
      push  R03
      push  R04
      push  R05
      push  R06
      push  R07
      push  R10
      push  R11
      push  R12
      push  R13
      push  R14
      push  R15
      push  R16
      push  R17 

; -----------------------  Ulozeni parametru stare ulohy  -------------------
      mov   DPH, R20
      mov   DPL, #2                    ; cilova adresa 

      mov   a, SP
      mov   b, #STACK
      subb  a, b
      mov   r0, a                   & nbsp;  ; pocet bytu pro ulozeni
      movx  @DPTR, a
      inc   DPTR 

      mov   r1, #STACK                 ; zdrojova adresa 

   SAVE_LOOP:
      mov   a, @r1
      movx  @DPTR, a
      inc   r1
      inc   DPTR
      djnz  r0, SAVE_LOOP 

; --------------------------  Nalezeni aktivni ulohy  -----------------------
   NEW_TASK_NUM:
      inc   R20                    ;     ; inkrementace cisla ulohy
      mov   a, R20
      cjne  a, #MAX_TASK_NUM, TEST_TASK_ACTIVITY
      clr   a
      mov   R20, a 

   TEST_TASK_ACTIVITY:
      mov   DPH, a
      mov   DPL, #0
      movx  a, @DPTR                   ; DPTR = XX00
      jz    NEW_TASK_NUM 

; ----------------------  Natazeni delky chodu ulohy  -----------------------
   SET_TASK_LENGHT:
      inc   DPTR
      movx  a, @DPTR                   ; DPTR = XX01
      mov   TH0, a
      mov   TL0, #0 

; ----------------------  Natazeni parametru nove ulohy  --------------------
      inc   DPTR
      movx  a, @DPTR                   ; DPTR = XX02
      mov   r0, a                   & nbsp;  ; pocet bytu pro natazeni
      mov   r1, #80h                   ; cilova adresa
      inc   DPTR                  &nbs p;    ; zdrojova adresa ; DPTR = XX03
   LOAD_LOOP:
      movx  a, @DPTR
      mov   @r1, a
      inc   r1
      inc   DPTR
      djnz  r0, LOAD_LOOP 

; --------------------------  Natazeni nove ulohy  --------------------------
   LOAD_STACK:
      pop   R17
      pop   R16
      pop   R15
      pop   R14
      pop   R13
      pop   R12
      pop   R11
      pop   R10
      pop   R07
      pop   R06
      pop   R05
      pop   R04
      pop   R03
      pop   R02
      pop   R01
      pop   R00
      pop   DPH
      pop   DPL
      pop   PSW
      pop   B
      pop   ACC 

      setb  TR0                    ;     ; spusteni citace ( TCON ) 

      reti 

;============================================================================
;  ================  Interrupt od serioveho ( UART ) kanalu  ================
;============================================================================
S0_IRQ:
; -------------------------  Ulozeni registru  ------------------------------
      push  PSW
      push  ACC 

      mov   a, SCON0
      anl   a, #01h
      jz    TEST_SEND_DATA
      lcall REC_DATA
      jmp   END_S0_IRQ

   TEST_SEND_DATA:
      lcall SEND_DATA 

   END_S0_IRQ:
; ---------------------------  Nacteni registru  ----------------------------
      pop   ACC
      pop   PSW 

; -------------------------  Navrat z preruseni  ----------------------------
      reti 

;===========================  Odeslani dat  =================================
SEND_DATA:
      clr   TI
      ret 

; ==========================  Prijem  dat  ==================================
REC_DATA:
      clr   RI
      ret 

; ===========================================================================
; ====================  Inicializace procesoru a TASKu  =====================
; ===========================================================================
BEGIN:
      mov   SP,#STACK - 1 

mov   TA, #0AAH
mov   TA, #55H
mov   PMR, #01000101B 

; ------------------------  zakladni inicializace programu  -----------------
      lcall Setup 

; ---------------------------  Inicializace TASKu 0  ------------------------
      mov   r0, #0                      ; cislo 512 bytoveho bloku pro xdata
                   &n bsp;                   ; tasku 0
      mov   r1, #High( TASK0 )         ; adresa tasku 0
      mov   r2, #Low( TASK0 )
      mov   r3, #ACTIVE_TASK           ; stav tasku
      mov   r4, #0ah                   ; pocet tiku citace vyhrazenych
                   &n bsp;                   ; uloze - lze dynamicky menit
                   &n bsp;                   ; 0 = maximum ( dopocitava do FF )
      mov   R05, R04                   ; zapamatovani pro spusteni 1. tasku
      lcall INIT_TASK 

; ---------------------------  Inicializace TASKu 1  ------------------------
      mov   r0, #1
      mov   r1, #High( TASK1 )
      mov   r2, #Low( TASK1 )
      mov   r3, #ACTIVE_TASK
      mov   r4, #0h
      lcall INIT_TASK 

; ---------------------------  Inicializace TASKu 2  ------------------------
      mov   r0, #2
      mov   r1, #High( TASK2 )
      mov   r2, #Low( TASK2 )
      mov   r3, #SLEEP_TASK
      mov   r4, #0h
      lcall INIT_TASK 

; ---------------------------  Inicializace TASKu 3  ------------------------
      mov   r0, #3
      mov   r1, #High( TASK3 )
      mov   r2, #Low( TASK3 )
      mov   r3, #ACTIVE_TASK
      mov   r4, #0h
      lcall INIT_TASK 

; ---------------------------  Zpusteni 1. tasku  ---------------------------
      mov   TH0, r5                    ; naplneni registru TH0 casovace 0
      mov   TL0, #0                    ; naplneni registru TL0 casovace 0
      setb  ET0                    ;     ; povoleni interruptu od CT0
      mov   R20, #0                    ; nastaveni aktivni ulohy
      setb  TR0                    ;     ; spusteni citace ( TCON )
      jmp   TASK0                  &nb sp;   ; a jeji zacnuti
                   &n bsp;                   ; zde je konec inicializaci a bezi MT 

; ==========================  Inicializace TASK  ============================
INIT_TASK:
      mov   DPH, r0
      mov   DPL, #0
      mov   a, r3
      movx  @DPTR, a                   ; zapis rezimu TASKu
      inc   DPTR
      mov   a, r4
      movx  @DPTR, a                   ; zapis casu pro TASK
      inc   DPTR
      mov   a, #2
      movx  @DPTR, a                   ; zapis casu pro TASK
      inc   DPTR
      mov   a, r2
      movx  @DPTR, a                   ; zapis dolni casti navratove adresy
      inc   DPTR
      mov   a, r1
      movx  @DPTR, a                   ; zapis horni casti navratove adresy 

      ret
 

;==============================  Inicializace  ==============================
Setup:
      lcall SwSetup
      lcall HwSetup
      setb  EA                 ; povoleni globalniho interruptu 

      ret
 

;============================  Inicializace SW  =============================
SwSetup:
;--------------------------  Nulovani oblasti STACK  ------------------------
      mov r0, #STACK - 1 

      clr a
   ClrData:
; -------------------------  Nulovani registru  -----------------------------
      mov   @r0, a
      djnz  r0, ClrData 

; -------------------------  Nulovani XDATA  --------------------------------
      mov   DPTR, #0
   ClrXdata:
      movx  @DPTR, a
      inc   DPTR
      mov   r0, DPH
      cjne  r0, #0FFh, ClrXdata
      mov   r0, DPL
      cjne  r0, #0FFh, ClrXdata 

      ret 

;============================  Inicializace HW  =============================
HwSetup: 

      mov   IE, #0h                   ; zakazani vsech irq 

;  ---------------  Nastaveni rezimu cinnosti citacu  -----------------------
      mov   PCON, #080h               ; nastaveni predelicky na 16
      mov   TMOD, #00100001B          ; nastaveni modu pro oba citace
                   &n bsp;                  ; naplneni registru TH1 casovace
      mov   TH1, #-3                  ; 3 = 19.200 Bd pri CLK = 11.0592 MHz
      setb  TR1                    ;    ; spusteni citace ( TCON ) 

;  --------------------  Nastaveni rezimu cinnosti UART  --------------------
                   &n bsp;                  ; registr SCON0
      setb  SM1                    ;    ; 8 bitu, casovac 1
      setb  REN                    ;    ; povolen prijem
      setb  ES                         ; povoleno preruseni od UART pro vstup
                   &n bsp;                  ; i vystup
      ret
 

; ===============================  TASK 0  ==================================
TASK0:                  &n bsp;              ; tato uloha neco udela a sama se
                   &n bsp;                   ; ukonci
      jb    P1.0, TASK0_END
      inc   DPTR

   TASK0_END:
      setb  TF0
      jmp   TASK0 

; ===============================  TASK 1  ==================================
TASK1:                  &n bsp;              ; tato uloha donekonecna provadi smycku
                   &n bsp;                   ; do preruseni od casovace, pak je spus-
                   &n bsp;                   ; tena dalsi uloha
      inc   a
      jmp   TASK1 

; ===============================  TASK 2  ==================================
TASK2:
      dec   a
      setb  TF0
      jmp   TASK1 

; ===============================  TASK 3  ==================================
TASK3:
      setb  TF0
      jmp   TASK3 

;*******************************  K O N E C  ********************************
   END
 
 

 



;**********************************************************
;*                                       &n bsp;                 *
;* Register Declarations for DS83C520/DS87C520 Processor  *
;*                                       &n bsp;                 *
;*        include file for AX51                  &nbs p;        *
;*                                       &n bsp;                 *
;********************************************************** 

;****************
;  SFR Registers
;**************** 

EIP1    EQU 0F8H
B       EQU 0F0H
EIE     EQU 0E8H
ACC     EQU 0E0H
WDCON   EQU 0D8H
PSW     EQU 0D0H
TH2     EQU 0CDH
TL2     EQU 0CCH
RCAP2H  EQU 0CBH
RCAP2L  EQU 0CAH
T2MOD   EQU 0C9H
T2CON   EQU 0C8H
TA      EQU 0C7H
STATUS  EQU 0C5H
PMR     EQU 0C4H
ROMSIZE EQU 0C2H
SBUF1   EQU 0C1H
SCON1   EQU 0C0H
SADEN1  EQU 0BAH
SADEN0  EQU 0B9H
IP      EQU 0B8H
P3      EQU 0B0H
SADDR1  EQU 0AAH
SADDR0  EQU 0A9H
IE      EQU 0A8H
P2      EQU 0A0H
SBUF0   EQU 099H
SCON0   EQU 098H
EXIF    EQU 091H
P1      EQU 090H
CKCON   EQU 08EH
TH1     EQU 08DH
TH0     EQU 08CH
TL1     EQU 08BH
TL0     EQU 08AH
TMOD    EQU 089H
TCON    EQU 088H
PCON    EQU 087H
DPS     EQU 086H
DPH1    EQU 085H
DPL1    EQU 084H
DPH     EQU 083H
DPL     EQU 082H
SP      EQU 081H
P0      EQU 080H 

;******************
; BIT Addresses
;****************** 

;P0 - 080h
P00    BIT 080h
P01    BIT 081h
P02    BIT 082h
P03    BIT 083h
P04    BIT 084h
P05    BIT 085h
P06    BIT 086h
P07    BIT 087h 

;TCON - 088h
IT0    BIT 088h
IE0    BIT 089h
IT1    BIT 08Ah
IE1    BIT 08Bh
TR0    BIT 08Ch
TF0    BIT 08Dh
TR1    BIT 08Eh
TF1    BIT 08Fh 

;P1 - 090h
P10    BIT 090h
P11    BIT 091h
P12    BIT 092h
P13    BIT 093h
P14    BIT 094h
P15    BIT 095h
P16    BIT 096h
P17    BIT 097h 

;SCON0 - 098h
RI_0   BIT 098h
TI_0   BIT 099h
RB8_0  BIT 09Ah
TB8_0  BIT 09Bh
REN_0  BIT 09Ch
SM2_0  BIT 09Dh
SM1_0  BIT 09Eh
SM0_0  BIT 09Fh
FE_0   BIT 09Fh 

;P2 - 0A0h
P20    BIT 0A0h
P21    BIT 0A1h
P22    BIT 0A2h
P23    BIT 0A3h
P24    BIT 0A4h
P25    BIT 0A5h
P26    BIT 0A6h
P27    BIT 0A7h 

;IE - 0A8h
EX0    BIT 0A8h
ET0    BIT 0A9h
EX1    BIT 0AAh
ET1    BIT 0ABh
ES0    BIT 0ACh
ET2    BIT 0ADh
ES1    BIT 0AEh
EA     BIT 0AFh 

;P3 - 0B0h
P30    BIT 0B0h
P31    BIT 0B1h
P32    BIT 0B2h
P33    BIT 0B3h
P34    BIT 0B4h
P35    BIT 0B5h
P36    BIT 0B6h
P37    BIT 0B7h 

;IP - 0B8h
PX0    BIT 0B8h
PTO    BIT 0B9h
PX1    BIT 0BAh
PT1    BIT 0BBh
PS0    BIT 0BCh
PT2    BIT 0BDh
PS1    BIT 0BEh 

;SCON1 - 0C0h
RI_1   BIT 0C0h
TI_1   BIT 0C1h
RB8_1  BIT 0C2h
TB8_1  BIT 0C3h
REN_1  BIT 0C4h
SM2_1  BIT 0C5h
SM1_1  BIT 0C6h
SM0_1  BIT 0C7h
FE_1   BIT 0C7h 

;T2CON - 0C8h
CP     BIT 0C8h
RL2    BIT 0C8h
CI_1   BIT 0C9h
T2     BIT 0C9h
TR2    BIT 0CAh
EXEN2  BIT 0CBh
TCLK   BIT 0CCh
RCLK   BIT 0CDh
EXF2   BIT 0CEh
TF2    BIT 0CFh 

;PSW - 0D0h
P      BIT 0D0h
FL     BIT 0D1h
OV     BIT 0D2h
RS0    BIT 0D3h
RS1    BIT 0D4h
F0     BIT 0D5h
AC     BIT 0D6h
CY     BIT 0D7h 

;WDCON - 0D8h
RWT    BIT 0D8h
EWT    BIT 0D9h
WTRF   BIT 0DAh
WDIF   BIT 0DBh
PFI    BIT 0DCh
EPFI   BIT 0DDh
POR    BIT 0DEh
SMOD_1 BIT 0DFh 

;PSW - 0E0h
;P      BIT 0E0h
;FL     BIT 0E1h
;OV     BIT 0E2h
;RS0    BIT 0E3h
;RS1    BIT 0E4h
;F0     BIT 0E5h
;AC     BIT 0E6h
;CY     BIT 0E7h 

;EIE - 0E8h
EX2    BIT 0E8h
EX3    BIT 0E9h
EX4    BIT 0EAh
EX5    BIT 0EBh
EWDI   BIT 0ECh 

;B - 0F0h
B0     BIT 0F0h
B1     BIT 0F1h
B2     BIT 0F2h
B3     BIT 0F3h
B4     BIT 0F4h
B5     BIT 0F5h
B6     BIT 0F6h
B7     BIT 0F7h 

;EIP - 0F8h
PX2    BIT 0F8h
PX3    BIT 0F9h
PX4    BIT 0FAh
PX5    BIT 0FBh
PWDI   BIT 0FCh 

;******************
;Interrupt Vectors
;****************** 

;RESTART    CODE 0000H
;IRQ_INT0   CODE 0003H
;IRQ_TF0    CODE 000BH
;IRQ_INT1   CODE 0013H
;IRQ_TF1    CODE 001BH
;IRQ_SCON0  CODE 0023H
;IRQ_TF2    CODE 002BH
;IRQ_PFI    CODE 0033H
;IRQ_SCON1  CODE 003BH
;IRQ_INT2   CODE 0043H
;IRQ_INT3   CODE 004BH
;IRQ_INT4   CODE 0053H
;IRQ_INT5   CODE 005BH
;IRQ_WDTI   CODE 0063H
 

;******************
; Banks
;****************** 

;Bank 0 

R00    EQU 000H
R01    EQU 001H
R02    EQU 002H
R03    EQU 003H
R04    EQU 004H
R05    EQU 005H
R06    EQU 006H
R07    EQU 007H
 

;Bank 1 

R10    EQU 008H
R11    EQU 009H
R12    EQU 00AH
R13    EQU 00BH
R14    EQU 00CH
R15    EQU 00DH
R16    EQU 00EH
R17    EQU 00FH 
 

;Bank 2

R20    EQU 010H
R21    EQU 011H
R22    EQU 012H
R23    EQU 013H
R24    EQU 014H
R25    EQU 015H
R26    EQU 016H
R27    EQU 017H
 

;Bank 3 

R30    EQU 018H
R31    EQU 019H
R32    EQU 01AH
R33    EQU 01BH
R34    EQU 01CH
R35    EQU 01DH
R36    EQU 01EH
R37    EQU 01FH

Hodnocení článku: