|
inefetti, the translator of google is a little cmq is misfiring, you meant I want to do ie, turning on the web I found several SOLUTIONS asm that generates a charge of multitasking (which nn and multitasking, but in reality and an alternate who runs monotasking processes
in practice, and that's what I do \ \ \
There are basically two ways to implement multi-tasking: cooperative and preemptive multitasking. In the first are the programs that, naturally, give control to the system as soon as they completed the transaction in progress, the second is that the scheduler to the programs when the time allotted and transfers control from one to another.
The cooperative multitasking uses less computing resources and has (almost) switching delay for the task change, and also does not require any dedicated hardware structure, which makes it possible to implement it on any computer, on the other hand is very vulnerable to errors in programs (typically a program to crash the entire system drops) and the isolation between processes is very weak. It is the model used by Mac OS 9, Windows 3.0 and earlier. The preemptive multitasking CPU needs to implement in hardware or in the levels of privilege for the execution of code and logic specific to the context switch, changing the task performed by the scheduler. Since the program interruption is arbitrary, the task change the operating system is forced to save all or almost all the CPU registers and load them with those saved by the task that takes over, losing a lot of time. Faced with these increasing demands, the preemptive multitasking system provides enhanced security and a much larger (virtual) immunity to system crashes caused by errors in programs. It is the model used by modern operating systems. "
How to implement a management task in systems with very small resources? Cosa'è the logic of the context switch? Really need the levels of privilege? These and others are all questions that arises when we want to implement a uKernel. But to better understand what we want to achieve is perhaps easier to imagine a typical control system that we want to become multi-tasking ....
To facilitate our work better I make up an application. Let's say a client of mine asked me to develop an embedded system that plans to implement a keyboard of 11 keys and a 2x16 alphanumeric LCD display. Our client wants to display the keys pressed on the display.
We can immediately identify my two main processes. 1) Read keyboard. 2) Check LCD.
The hardware implementation at the moment we are not interested because uKernel must be released from the implementation of the card. Reading the keyboard is easy to see how a process is asynchronous to the system (asynchronous process by defining all the processes that occur in a time not determined). The asynchronous processes need to activate a triggering event in this case we can associate with the button press.
The LCD control may be interpreted as a synchronous process. (Defining a synchronous process all the processes that occur in a given time). Imagine the state of our way to update the display every 100 msec.
From these two considerations will have to implement our uKernel logic for the context switch (which still does not know what it is ...) able to manage these two events and times.
So we can imagine that the structure of our task will become more or less like this
@ EVENT TASK_ID, EVOS_KEY_PRESSED
logical management of the key
END_TASK
@ WAIT_R TIMEOS_UPDATE_LCD
update logic of the display
END_TASK
THE CORE
Before going on the application must describe the functions of the core uKernel. We must decide to implement the type of operating system first described by wikipedia. Cooperative or Preempitive? Well actually we have already answered the question by describing the task as overwritten. The type of system that will be implementing a cooperative. @ @ WAIT_R EVENT and references that are in fact the core of uKernel use to call up the process and my task will be benevolent performing their functions as soon as possible. Preempitive a system requires some features that do not have the PIC 16Cxx and then immediately forget his existence. The management of privilege levels is a beautiful feature of multitasking systems that allowed a task requiring much time as possible to the operating system. This type of request is specific preemptive systems because it is arbitrary suspension of the program and then the task remains poor not only beg the operating system to give him more time hoping that can give him, in the case of cooperative systems gives a **** to ask for once took the spring when it seems ...
Task Tables Since the task need to manage events and times my heart has need 2 tables and call Event_Table Time_Table. Each element of this table is associated with a task. If the task wants to be awakened by an event she requires with the @ EVENT type of event if it wants to be awakened in time with the task requires a time that will WAIT_R @ lsb as the operating system tick.
Switch Contest To speak of the contest is now necessary to speak of the switch we are using micro which is precisely the PIC 16C5x
THE PIC The pic is a microcontroller 16C5x would call essential. The only 33 instructions to learn is a facility that pays for itself in the internal structure of the micro cumbersome. The pages of memory is ROM and RAM hardware stack pointer (not readable) the lack of interrupts inappettibile would have made any application. Instead, the OTP can be programmed to avoid the costly and dangerous procedure of masking the micro markets have paved the way for making the fortune of Microchip's embedded. The Pic and a working register dependence, this means that all operations of the internal registers must pass through this one working register. Unlike the rich alternatives such as the Z80 instruction that had more than 150 with this solution are able to heavily reduce the number of instructions inside (... and so much expensive silicon) but in some cases creating a nagging neck bottlenecks in the implementation of functions. A bit 'of numbers to understand what we're talking about. The microcontroller is a 28-pin 2K bytes of RAM and ROM 72 at the time was a fast 20 MHz to 40 MHz increased hours
In light of the internal structure of the micro now describe exactly what action is brought typically Contest switch. The Contest is the switch function that saves the context of my tasks in memory and then restore it the next time it is invoked. The context is so supportive that the logs used in micro-processing program. The PIC, however, unlike the 8051s or indeed the z80 has no special registers (except the working register), but has only general purpouse global registers. This requires developing a micro uKernel with this, the task must be careful in the use of memory. When we see the 8051 uKernel understand this better, and so in our case does not implement it by ignoring it.
After this short description of the most savvy have already wrinkled her nose reading that the pic has a hardware stack pointer, and already understand that this is the main reason that does not allow the pic to implement uKernel preempitive. But the problem does not change in the case of the above tasks. How do I create a system that allows my uKernel to know how to draw my task? We need a new table that we call TABLE_RETURN. This new table does not lie unlike the other ram but resides in ROM.
Implementation of macro
The assembler of the microchip is very powerful and has an efficient preprocessor for the creation of macros needed for our purpose.
;------------------------------------------------- ---------------- ; @ MACRO EVENT ; COMMENT TASK is waiting to wake up events ; ENTRY ; EXIT ;------------------------------------------------- ---------------- @ MACRO EVENT TASK_N, WAKE_UP LOCAL RETURN, MEMO
BCF FSR, 5; point to bank 0 BCF FSR, 6; point to bank 0
MOVLW IND_JMP; saves the return address of an indirect MEMO MOVWF RET_ADD TASK_N +; in the table of returns ORG IND_JMP GOTO RETURN; instruction to return indirect low P. ORG MEMO +1; resume the PC from where it was IND_JMP September IND_JMP +1, I update the table pointer within MOVLW WAKE_UP; loads the wake-up mask MOVWF TASK_N + COND, COND save in the table to return
;**** The toggle mask and wake up 'reset uploading ret_add GOTO P_TASK; laugh 'control to sist. op. RETURN @ SET_BANK; sets the bench after returning to the task
ENDM
;------------------------------------------------- ---------------- ; MACRO @ WAIT_R ; COMMENT TASK is waiting for the REC TIME ; ENTRY ; EXIT ;------------------------------------------------- ---------------- @ MACRO WAIT_R TASK_N, REG LOCAL RETURN, MEMO
BCF FSR, 5; point to bank 0 BCF FSR, 6; point to bank 0
MOVLW (IND_JMP | 10000000b) ; Save the return address indirect and not the flag MEMO MOVWF RET_ADD TASK_N +; in the table of returns
ORG IND_JMP GOTO RETURN; instruction to return indirect low P. ORG MEMO +1; resume the PC from where it was
IND_JMP September IND_JMP +1, I update the table pointer within
MOVFW REG MOVWF TASK_N + COND, COND save in the table to return ; The toggle timer and 'set by loading ret_add GOTO P_TASK; laugh 'control to sist. op. RETURN @ SET_BANK; sets the bench after returning to the task
ENDM
The implementation of the core is a little more elaborate the code is, however, the comments are autoespicativi
;------------------------------------------------- ---------------- ; THE OPERATING SYSTEM!! ;------------------------------------------------- ----------------
SCHEDULER CLRWDT; clear WDOG
;------------------------------------------------- ---------------- ; AND TASK MANAGEMENT SYSTEM TIMER ;------------------------------------------------- ----------------
GEST_RTCC MOVFW RTCC; read the current state of rtcc XORWF RTCC_COPY, W, and if you look at 'the same as my copy Btfsc STATUS, Z; if they are not equal 'time spent GOTO P_TASK, then I do not update timers, I'm going to handle the I / O INCF RTCC_COPY, Same, goes one step on my watch C_TASK_0; control task 0 TASK set 0 Btfsc RET_ADD + TASK, 7; tests if events or time DECF COND + TASK, SAME, it was time, task time decreases C_TASK_1; Control Task 1 TASK 1 September Btfsc RET_ADD + TASK, 7; tests if events or time DECF COND + TASK, SAME, it was time, task time decreases C_TASK_2; Control Task 2 TASK 2 September Btfsc RET_ADD + TASK, 7; tests if events or time DECF COND + TASK, SAME, it was time, task time decreases
;------------------------------------------------- ---------------- ; START TASK ; WARNING: If you change the number of tasks also change the PART_TASK! ;------------------------------------------------- ---------------- MOVLW RET_ADD0 MOVWF FSR; point to task 0 CALL PART_TASK INCF FSR, Same, point to Task 1 CALL PART_TASK INCF FSR, Same, point to Task 2 CALL PART_TASK FINE_P_TASK P_TASK; calls SYS_OP fall here!
;------------------------------------------------- ---------------- ; Function of I / O PERFORMED BY SCHEDULER ;------------------------------------------------- ----------------
Reading the keyboard ... and updating the event OS_KEY_PRESSED
GOTO SCHEDULER
Now we implement our modules that contain our task. Recall that in our case we have a contest and then switching to the task using the internal memory of the micro to their liking ....
;------------------------------------------------- --------------- ;------------------------------------------------- --------------- TASK_0
EVENT @ 0, (1 <<OS_KEY_PRESSED)
Decoding the button pressed
GOTO TASK_0
;------------------------------------------------- --------------- ;------------------------------------------------- --------------- TASK_1
@ WAIT_R 1, 100
Display update GOTO TASK_0
Novità! Fai clic sulle parole riportate sopra per visualizzare le traduzioni alternative. Elimina
0. 0. 0. 0. 0. 0. 0. 0.
|