Systemy operacyjne dla systemów wbudowanych

Transkrypt

Systemy operacyjne dla systemów wbudowanych
Programowanie mikroprocesorów
jednoukładowych
Systemy operacyjne dla systemów wbudowanych
Mariusz Naumowicz
Programowanie mikroprocesorów jednoukładowych
13 grudnia 2016
1 / 30
Plan I
SLOS
Inicjalizacja
Model pamięci
Obsługa przerwań i wyjątków
Mariusz Naumowicz
Programowanie mikroprocesorów jednoukładowych
13 grudnia 2016
2 / 30
Simple Little Operating System
SLOS to mały system operacyjny napisan na rdzeń ARM7TDMI oraz płytę ewaluacyjną
Evaluator-7T. Jest prosty w modyfikacji i jest uruchamiany przez Sandstone firmware.
Mariusz Naumowicz
Programowanie mikroprocesorów jednoukładowych
13 grudnia 2016
3 / 30
Inicjalizacja systemu I
Listing 1: Inicjalizacja
1
2
3
4
5
6
7
8
9
10
11
12
13
AREA ENTRYSLOS , CODE, READONLY
ENTRY
LDR pc , v e c t o r R e s e t
LDR pc , v e c t o r U n d e f i n e d
LDR pc , v e c t o r S W I
LDR pc , v e c t o r P r e f e t c h A b o r t
LDR pc , v e c t o r D a t a A b o r t
LDR pc , v e c t o r R e s e r v e d
LDR pc , v e c t o r I R Q
LDR pc , v e c t o r F I Q
v e c t o r R e s e t DCD c o r e I n i t i a l i z e
v e c t o r U n d e f i n e d DCD c o r e U n d e f i n e d H a n d l e r
v e c t o r S W I DCD c o r e S W I H a n d l e r
Mariusz Naumowicz
Programowanie mikroprocesorów jednoukładowych
13 grudnia 2016
4 / 30
Inicjalizacja systemu II
14
15
16
17
18
v e c t o r P r e f e t c h A b o r t DCD c o r e P r e f e t c h A b o r t H a n d l e r
v e c t o r D a t a A b o r t DCD c o r e D a t a A b o r t H a n d l e r
v e c t o r R e s e r v e d DCD c o r e R e s e r v e d H a n d l e r
v e c t o r I R Q DCD c o r e I R Q H a n d l e r
v e c t o r F I Q DCD c o r e F I Q H a n d l e r
Listing 2: Ustawienia FIQ
1
2
3
4
5
6
7
8
bringupInitFIQRegisters
MOV r2 , r 1 4 ; s a v e r 1 4
BL switchToFIQMode ; ch an g e FIQ mode
MOV r8 ,#0 ; r 8 _ f i q =0
MOV r9 ,#0 ; r 9 _ f i q =0
MOV r10 ,#0 ; r 1 0 _ f i q =0
BL switchToSVCMode ; ch a ng e SVC mode
MOV pc , r 2 ; r e t u r n
Mariusz Naumowicz
Programowanie mikroprocesorów jednoukładowych
13 grudnia 2016
5 / 30
Inicjalizacja systemu III
9 coreInitialize
10 BL b r i n g u p I n i t F I Q R e g i s t e r s
Listing 3: Ustawienia stosu
1
2
3
4
5
6
MOV
MSR
MOV
MSR
MOV
MSR
sp ,#0 x80000 ; SVC s t a c k
cp s r _ c ,# N o I n t | SYS32md
sp ,#0 x40000 ; u s e r / s y s t e m s t a c k
cp s r _ c ,# N o I n t | IRQ32md
sp ,#0 x9000 ; IRQ s t a c k
cp s r _ c ,# N o I n t | SVC32md
Wyniki działania powyższych listingów:
I
inicjalizacja niskopoziomowego debugowania
I
stos dla SVC, IRQ oraz systemu jest ustawiony
Mariusz Naumowicz
Programowanie mikroprocesorów jednoukładowych
13 grudnia 2016
6 / 30
Inicjalizacja systemu IV
Listing 4: Inicjalizacja PCB
1
2
3
4
5
6
7
8
9
; v o i d pcbSetUp ( v o i d ∗ e n t r y A d d r , v o i d ∗PCB , UINT o f f s e t ) ;
pcbSetUp
STR r0 , [ r1 ,#−4] ; PCB[ −4]= C_TaskEntry
STR r0 , [ r1 ,# −64] ; PCB[ −64]= C_TaskEntry
SUB r0 , sp , r 2
STR r0 , [ r1 ,#−8] ; PCB[ −8]= sp−<o f f s e t >
MOV r0 ,#0 x50 ; c p s r _ c
STR r0 , [ r1 ,# −68] ; PCB[ −68]= i F t _ U s e r
MOV pc , l r
Mariusz Naumowicz
Programowanie mikroprocesorów jednoukładowych
13 grudnia 2016
7 / 30
Inicjalizacja systemu V
Listing 5: Ustawienie identyfikatora
1
2
3
4
5
LDR
MOV
STR
LDR
MOV
r0 ,= PCB_CurrentTask
r1 ,#0
r1 , [ r 0 ]
l r ,= C_Entry
pc , l r ; e n t e r t h e CEntry w o r l d
I
Inicjalizacja PCB dla wszystkich trzech zadań
I
Ustawienie aktualnego PCB jako zadania 1 (identyfikator 0)
Mariusz Naumowicz
Programowanie mikroprocesorów jednoukładowych
13 grudnia 2016
8 / 30
Inicjalizacja systemu VI
1
2
3
4
5
6
void c i n i t _ i n i t ( void )
{
eventIODeviceInit ();
eventServicesInit ();
eventTickInit (2);
}
1 i n t C_Entry ( v o i d )
2 {
3 cinit_init ();
4 eventTickStart ();
5 __asm
6 {
7 MSR cp s r _ c ,#0 x50
Mariusz Naumowicz
Programowanie mikroprocesorów jednoukładowych
13 grudnia 2016
9 / 30
Inicjalizacja systemu VII
8
9
10
11
}
C_EntryTask1 ( ) ;
return 0;
}
Rezultatem wywołania wszystkich funkcji inicjalizujących napisanych w C jest:
I
Sterowiniki urządzeń są zainicjalizowane.
I
Usługi są zainicjalizowane.
I
Okresowy zegar jest zainicjalizowany i uruchomiony.
I
Przerwania IRQ są aktywne w rejsterze cpsr.
I
Procesor jest ustawiony w trybie użytkownika.
I
Punkt startu zadania pierwszego jest wywołany (np. C_EntryTask1).
Mariusz Naumowicz
Programowanie mikroprocesorów jednoukładowych
13 grudnia 2016
10 / 30
Model pamięci
Mariusz Naumowicz
Programowanie mikroprocesorów jednoukładowych
13 grudnia 2016
11 / 30
Obsługa przerwań i wyjątków I
Wyjątek
Reset
SWI
IRQ
Mariusz Naumowicz
Cel
inicjalizacja systemu operacyjnego
mechanizm dostępu do sterowników
mechanizm obsługi zdarzeń
Programowanie mikroprocesorów jednoukładowych
13 grudnia 2016
12 / 30
Obsługa SWI I
1
2
3
4
5
6
7
8
coreSWIHandler
STMFD s p ! , { r0−r12 , r 1 4 } ; s a v e c o n t e x t
LDR r10 , [ r14 ,#−4] ; l o a d SWI i n s t r u c t i o n
BIC r10 , r10 ,#0 x f f 0 0 0 0 0 0 ; mask o f f t h e MSB 8 b i t s
MOV r1 , r 1 3 ; copy r 1 3 _ s v c t o r 1
MRS r2 , s p s r ; copy s p s r t o r 2
STMFD r 1 3 ! , { r 2 } ; s a v e r 2 o n t o t h e s t a c k
BL s w i _ j u m p t a b l e ; b r a n c h t o t h e s w i _ j u m p t a b l e
1 LDMFD r 1 3 ! , { r 2 } ; r e s t o r e t h e r 2 ( s p s r )
2 MSR s p s r _ c x s f , r 2 ; copy r 2 back t o s p s r
3 LDMFD r 1 3 ! , { r0−r12 , pc }^ ; r e s t o r e c o n t e x t and r e t u r n
Mariusz Naumowicz
Programowanie mikroprocesorów jednoukładowych
13 grudnia 2016
13 / 30
Obsługa SWI II
1 swi_jumptable
2 MOV r0 , r 1 0 ; move t h e SWI number t o r 0
3 B e v e n t s S W I H a n d l e r ; b r a n c h t o SWI h a n d l e r
1
2
3
4
5
6
7
8
9
10
v o i d e v e n t s S W I H a n d l e r ( i n t swi_number , SwiRegs ∗ r )
{
i f ( swi_number==SLOS )
{
i f ( r−>r [0]== E v e n t _ I O D e v i c e I n i t )
{
/∗ do n o t e n a b l e IRQ i n t e r r u p t s . . . . ∗/
io_initialize_drivers ();
}
else
Mariusz Naumowicz
Programowanie mikroprocesorów jednoukładowych
13 grudnia 2016
14 / 30
Obsługa SWI III
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
{
/∗ i f n o t i n i t i a l i z i n g ch an g e t o s y s t e m mode
and e n a b l e IRQs ∗/
i f (STATE!=1) { m o d i f y C o n t r o l C P S R (SYSTEM | IRQoN ) ; }
s w i t c h ( r−>r [ 0 ] )
{
c a s e /∗ SWI ∗/ Event_IODeviceOpen :
r−>r [ 0 ] =
( unsigned i n t ) io_open_driver
(
/∗ i n t ∗ ID ∗/ ( UID ∗ ) r−>r [ 1 ] ,
/∗ u n s i g n e d m a j o r _ d e v i c e ∗/ r−>r [ 2 ] ,
/∗ u n s i g n e d m i n o r _ d e v i c e ∗/ r−>r [ 3 ]
);
break ;
Mariusz Naumowicz
Programowanie mikroprocesorów jednoukładowych
13 grudnia 2016
15 / 30
Obsługa SWI IV
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
c a s e /∗
/∗ c a l l
break ;
c a s e /∗
/∗ c a l l
break ;
c a s e /∗
/∗ c a l l
break ;
c a s e /∗
/∗ c a l l
break ;
c a s e /∗
/∗ c a l l
break ;
Mariusz Naumowicz
SWI ∗/ E v e n t _ I O D e v i c e C l o s e :
i o _ o p e n _ d r i v e r ∗/
SWI ∗/ E v e n t _ I O D e v i c e W r i t e B y t e :
i o _ w r i t e b y t e _ d r i v e r ∗/
SWI ∗/ E v e n t _ I O D e v i c e R e a d B y t e :
i o _ r e a d b y t e _ d r i v e r ∗/
SWI ∗/ E v e n t _ I O D e v i c e W r i t e B i t :
i o _ w r i t e b i t _ d r i v e r ∗/
SWI ∗/ E v e n t _ I O D e v i c e R e a d B i t :
i o _ r e a d b i t _ d r i v e r ∗/
Programowanie mikroprocesorów jednoukładowych
13 grudnia 2016
16 / 30
Obsługa SWI V
41
42
43
44
45
46
47
48
49
50
51
52
53
c a s e /∗ SWI ∗/ E v e n t _ I O D e v i c e W r i t e B l o c k :
/∗ c a l l i o _ w r i t e b l o c k _ d r i v e r ∗/
break ;
c a s e /∗ SWI ∗/ E v e n t _ I O D e v i c e R e a d B l o c k :
/∗ c a l l i o _ r e a d b l o c k _ d r i v e r ∗/
break ;
}
/∗ i f n o t i n i t i a l i z i n g ch an g e back t o s v c mode
and d i s a b l e IRQs ∗/
i f (STATE!=1) { m o d i f y C o n t r o l C P S R (SVC | IRQoFF ) ; }
}
}
}
Mariusz Naumowicz
Programowanie mikroprocesorów jednoukładowych
13 grudnia 2016
17 / 30
Obsługa IRQ I
1
2
3
4
5
6
7
8
9
10
11
12
TICKINT EQU 0 x400
BUTTONINT EQU 0 x001
eventsIRQHandler
SUB r14 , r14 , #4 ; r 1 4 _ i r q −=4
STMFD r 1 3 ! , { r0−r3 , r12 , r 1 4 } ; s a v e c o n t e x t
LDR r0 , INTPND ; r 0=i n t p e n d i n g r e g
LDR r0 , [ r 0 ] ; r 0=memory [ r 0 ]
TST r0 ,#TICKINT ; i f t i c k i n t
BNE e v e n t s T i c k V e n e e r ; t h e n t i c k ISR
TST r0 ,#BUTTONINT ; i f b u t t o n i n t e r r u p t
BNE e v e n t s B u t t o n V e n e e r ; t h e n b u t t o n ISR
LDMFD r 1 3 ! , { r0−r3 , r12 , pc }^ ; r e t u r n t o t a s k
Mariusz Naumowicz
Programowanie mikroprocesorów jednoukładowych
13 grudnia 2016
18 / 30
Obsługa IRQ II
1 eventsTickVeneer
2 BL e v e n t s T i c k S e r v i c e ; r e s e t t i c k h a r d w a r e
3 B k e r n e l S c h e d u l e r ; branch to s c h e d u l e r
Mariusz Naumowicz
Programowanie mikroprocesorów jednoukładowych
13 grudnia 2016
19 / 30
Planista I
1
2
3
4
5
6
7
8
t a s k t =0, t ’ ;
scheduler ()
{
t ’ = t + 1;
i f t ’ = MAX_NUMBER_OF_TASKS t h e n
t ’ = 0 // t h e f i r s t t a s k .
end ;
ContextSwitch ( t , t ’ )
Mariusz Naumowicz
Programowanie mikroprocesorów jednoukładowych
13 grudnia 2016
20 / 30
Przełączanie zadań I
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
MaxNumTasks EQU 3
F i r s t T a s k EQU 0
CurrentTask
LDR r3 ,= PCB_CurrentTask ; [ 1 ] r 3=PCB_CurrentTask
LDR r0 , [ r 3 ] ; r 0= c u r r e n t Task ID
LDR r1 ,=PCB_Table ; [ 2 ] r 1=PCB_Table a d d r e s s
LDR r1 , [ r1 , r0 , LSL#2] ; r 1=mem32 [ r 1+r 0 << 2 ]
LDR r2 ,= PCB_PtrCurrentTask ; [ 3 ] r 2=PCB_PtrCurrentTask
STR r1 , [ r 2 ] ; mem32 [ r 2 ]= r 1 : t a s k a d d r
; ∗∗ PCB_PtrCurrentTask − u p d a t e d w i t h t h e a d d r o f t h e c u r r e n t t a s k
; ∗∗ r 2 = PCB_PtrCurrentTask a d d r e s s
; ∗∗ r 1 = c u r r e n t t a s k PCB a d d r e s s
; ∗∗ r 0 = c u r r e n t t a s k ID
NextTask
ADD r0 , r0 ,#1 ; [ 4 ] r 0 = ( C u r r e n t T a s k I D )+1
Mariusz Naumowicz
Programowanie mikroprocesorów jednoukładowych
13 grudnia 2016
21 / 30
Przełączanie zadań II
16
17
18
19
20
21
22
CMP r0 ,#MaxNumTasks ; i f r 0==MaxNumTasks
MOVEQ r0 ,# F i r s t T a s k ; t h e n r 0 = F i r s t T a s k ( 0 )
STR r0 , [ r 3 ] ; [ 5 ] mem32 [ r 3 ]= n e x t Task ID
LDR r1 ,=PCB_Table ; [ 6 ] r 1=PCB_Table a d d r
LDR r1 , [ r1 , r0 , LSL#2] ; r 1=memory [ r 1+r 0 << 2 ]
LDR r0 ,= PCB_PtrNextTask ; [ 7 ] r 0=PCB_PtrNextTask
STR r1 , [ r 0 ] ; memory [ r 0 ]= n e x t t a s k a d d r
Rezultaty uruchomienia powyższego kodu:
I
PCB_PtrCurrentTask wskazuje na adres aktualnie aktywnego PCB.
I
PCB_PtrNextTask wskazuje na adres następnego aktywnego PCB.
I
PCB_CurrentTask przechowuje wartość identyfikatora następnego zadania.
Mariusz Naumowicz
Programowanie mikroprocesorów jednoukładowych
13 grudnia 2016
22 / 30
Przełączanie kontekstu I
1
2
3
4
5
6
7
8
9
O f f s e t 1 5 R e g s EQU 15∗4
handler_contextswitch
LDMFD r 1 3 ! , { r0−r3 , r12 , r 1 4 } ; [ 1 . 1 ] r e s t o r e r e g i s t e r s
LDR r13 ,= PCB_PtrCurrentTask ; [ 1 . 2 ]
LDR r13 , [ r 1 3 ] ; r 1 3=mem32 [ r 1 3 ]
SUB r13 , r13 ,# O f f s e t 1 5 R e g s ; r13 −=15∗Reg : p l a c e r 1 3
STMIA r13 , { r0−r 1 4 }^ ; [ 1 . 3 ] s a v e u s e r mode r e g i s t e r s
MRS r0 , s p s r ; copy s p s r
STMDB r13 , { r0 , r 1 4 } ; s a v e r 0 ( s p s r ) & r 1 4 ( l r )
Rezultaty zapisu aktualnego kontekstu jest:
I
Stos IRQ jest resetowany i zapisany do PCB_IRQStack.
I
Rejestr użytkownika dla zadania t jest zapisany do aktualnego PCB.
Mariusz Naumowicz
Programowanie mikroprocesorów jednoukładowych
13 grudnia 2016
23 / 30
Wczytywanie kontekstu I
1
2
3
4
5
6
7
8
9
LDR r13 ,= PCB_PtrNextTask ; [ 2 . 1 ] r 1 3=PCB_PtrNextTask
LDR r13 , [ r 1 3 ] ; r 1 3=mem32 [ r 1 3 ] : n e x t PCB
SUB r13 , r13 ,# O f f s e t 1 5 R e g s ; r13 −=15∗ R e g i s t e r s
LDMDB r13 , { r0 , r 1 4 } ; [ 2 . 2 ] l o a d r 0 & r 1 4
MSR s p s r _ c x s f , r 0 ; s p s r = r 0
LDMIA r13 , { r0−r 1 4 }^ ; l o a d r 0 _ u s e r −r 1 4 _ u s e r
LDR r13 ,=PCB_IRQStack ; [ 2 . 3 ] r 1 3=IRQ s t a c k a d d r
LDR r13 , [ r 1 3 ] ; r 1 3=mem32 [ r 1 3 ] : r e s e t IRQ
MOVS pc , r 1 4 ; [ 2 . 4 ] r e t u r n t o n e x t t a s k
Rezultaty uruchomienia powyższego kodu:
I
Przełączanie kontekstu jest wykonane.
I
Rejestry kolejnego zadania są wczytywane do rejestrów w trybie użytkownika.
I
Stos IRQ jest przywrócony do stanu wejścia w obsługę przerwania.
Mariusz Naumowicz
Programowanie mikroprocesorów jednoukładowych
13 grudnia 2016
24 / 30
Device Driver Framework I
1
2
3
4
5
6
7
8
9
10
11
12
13
14
d e v i c e _ t r e e s t r ∗ host ;
UID s e r i a l ;
h o s t = e v e n t I O D e v i c e O p e n (& s e r i a l , DEVICE_SERIAL_E7T ,COM1 ) ;
i f ( h o s t ==0)
{
/∗ . . . e r r o r d e v i c e d r i v e r n o t f o u n d . . . ∗ /
}
switch ( s e r i a l )
{
c a s e DEVICE_IN_USE :
c a s e DEVICE_UNKNOWN:
/∗ . . . p r o b l e m w i t h d e v i c e . . . ∗/
}
Mariusz Naumowicz
Programowanie mikroprocesorów jednoukładowych
13 grudnia 2016
25 / 30
Device Driver Framework II
1 PRE r 0 = Event_IODeviceOpen ( u n s i g n e d i n t )
2 r 1 = & s e r i a l ( UID ∗u )
3 r 2 = DEVICE_SERIAL_E7T ( u n s i g n e d i n t m a j o r )
4 r 3 = COM1 ( u n s i g n e d i n t m i n o r )
5 SWI 5075
6 POST r 1 = The d a t a p o i n t e d t o by t h e UID p o i n t e r i s u p d a t e d
Mariusz Naumowicz
Programowanie mikroprocesorów jednoukładowych
13 grudnia 2016
26 / 30
Przełączanie kontekstu I
Mariusz Naumowicz
Programowanie mikroprocesorów jednoukładowych
13 grudnia 2016
27 / 30
Podsumowanie I
Podstawowe komponenty występujące systemach operacyjnych uruchamianych na procesorach
ARM są następujące:
I
Inicjalizacja ustawiająca wszystkie wewnętrzne zmienne, struktury danych oraz urządzenia
używane przez system operacyjny.
I
Obsługa pamięci organizuje przestrzeń dla kernela oraz innych wykonywanych aplikacji.
I
Wszystkie przerwania i wyjątki wymagają funkcji obsługujących je. Nieużywane przerwania
i wyjątki muszą posiadać zainstalowane pozorowane funkcje obsługujące.
I
Zegar okresowy jest wymagana w systemach przełączających zadania. Zegar produkuje
przerwanie wywołujące funkcje planisty.
I
Planista jest algorytmem, który określa nowe zadania mające być uruchomione.
I
Przełączanie kontekstu zapisuje stan aktualnego zadania i wczytuje stan następnego
zadania.
Powyższe komponenty są przykładowo zrealizowane w Simple Little Operating System(SLOS):
Mariusz Naumowicz
Programowanie mikroprocesorów jednoukładowych
13 grudnia 2016
28 / 30
Podsumowanie II
I
Initialization-Inicjalizacja ustawoa wszystkie funkcje systemu SLOS, włączając w to tryby
pracy stosu, proces kontroli bloków (PCB) dla każdej aplikacji, sterowniki, itd.
I
Memory model- Jądro SLOS jest umieszczone w niskiej pamięci, każda aplikacja ma swoją
własną przestrzeń pamięci oraz stos. Rejestry systemowe mikrokontrolera są umieszczone
daleko od pamięci ROM i RAM.
I
Interrupts and exceptions-SLOS korzysta tylko z trzech zdarzeń. Tymi zdarzeniami są
Reset, SWI i IRQ. Pozostałej nieużywane przerwania i wyjątki mają zainstalowane
prowizoryczne funkcje obsługi.
I
Scheduler-SLOS implenentuje prosty algorytm round-robin w planiście.
I
Context switch-Aktulany kontekst jest zapisywane w PCB, następnie kontekst następnego
zadania jest odczytywany z PCB.
I
Device driver framework-Ochrania system operacyjny przed bezpośrednim dostęp z
aplikacji do sprzętu.
Mariusz Naumowicz
Programowanie mikroprocesorów jednoukładowych
13 grudnia 2016
29 / 30
References
Andrew Sloss, Dominic Symes, and Chris Wright.
ARM System Developer’s Guide: Designing and Optimizing System Software.
Morgan Kaufmann Publishers Inc., San Francisco, CA, USA, 2004.
Mariusz Naumowicz
Programowanie mikroprocesorów jednoukładowych
13 grudnia 2016
30 / 30