The previous post gave a brief introduction to VELOOS design idea. VELOOS assumes that an application is decomposed on PDOs (Process Data Objects). This post describes by example features provided by VELOOS for implementing PDO.
Self-triggering PDO
Design idea: | Implement a PDO sending a message to itself. On every message received toggle a pin. |
Value: | Provides a simple example of PDO implementation. Implements a metric for measuring/estimating system throughput. |
Implementing a PDO for VELOOS requires three steps:
- Declaring a class
- Implementing message handler and initializer
- Instantiating an object
Declaring a class
Class declaration sections starts with VOS_Classes macro and ends with beginning of any other section. As with regular MP ASM sections, there is no explicit ‘section end’ therefore it is important to properly delimit class declaration sections. A source file may have only one class declaration sections (MP ASM constraints).
Within class declaration section, a class is declared VOS_mClass macro. The macro should be preceded with a class name – a valid MP ASM label. This macro generates the class’s dispatch table. It accepts two labels as parameters: message handler and initialization handler. These labels should be known in this module (e.g. defined in the same module or imported with extern directive).
VOS_Classes ; Class definitions begin
MyClass VOS_mClass MyHandler, MyInit ; MyClass implementes MyHandler and MyInit methods
code
MyInit
...
return
MyHandler
...
return
Instantiating an object
Object instantiation section begins with VOS_Objects macro and ends with beginning of any other section. It accepts two parameters – class name and object data. Object data can be any 8-bit value. System does not make any assumption on it, it just loads this value to system variable This. Class name must be a label of a previously declared class. It should be known in this module.
VOS_Objects ; Object registry begins
MyObject
VOS_mPersistentObject MyClass, 0 ; Instance of MyClass constructed with object data == 0
Objects can be instantiated in the same unit where class implemented or in a different unit. In latter case, class name should be exported with globaldirective.
Note on Class Reenterability
A reenterable class allows instantiating several objects. From the system point of view all classes are reenterable. Whether a particular class is reenterable or no depends on its design and implementation and it is up to developer to make such decision. To make a class reenterable, all resources it uses must be allocated by means of object data. PDO implemented in this example is not
reenterable.
Implementing a message handler
Message handler is a subroutine, called by the OS when it finds a message addressed to this object or a broadcast message. On handler entrance This is loaded with object data and FSR is pointing to the message ID, so that the handler may compare INDF to a (set of) message ID(s) known to PDO. A PDO should process only know messages and ignore all others. Once the message is recognized, PDO may increment FSR and access message data (if necessary). In this example message has no custom data.
Implementing an initializer
Initializer is a subroutine, called by the OS on start-up (power up and reset events). On its entrance This is loaded with object data. Initializer is called for every instantiated object, therefore Initializer should prepare all registers or periphery used by this particular instance. If there is a need of some initialization code executed for all instances PDO should implement a boot handler.
Sending a message
VELOOS provides few macros for sending messages. Each of those macro “allocates” space for a new message, places acceptor handle, message ID, sender handle (in the last location). When it completes, FSR is pointing to custom data location,
so that PDO may put message data if necessary.
Macro | Parameters | Description |
VOS_mPostMessage |
obj_to – accepter handlemsg_id – message ID |
Posts a message to a statically defined object. Both message ID and acceptor are defined at build time |
VOS_mBroadcastMsg |
msg_id – message ID |
Posts a broadcast message. Message ID defined at build time |
VOS_mPostMsgIndir |
obj_ptr file containing accepter handlemsg_id message ID |
Posts a message to an object using handle stored in a file, e.g. Acceptor is defined at run time while message ID at build time |
VOS_mPostMsgDyn |
obj_ptr file containing accepter handlemsg_file file containing message ID |
Posts a message to an object using handle stored in a file and message ID stored in another file. Both acceptor and message ID are defined at run time |
In this example only one form is used:
VOS_mPostMessage MyObject, 2 ; post message to MyObject
Implementing a boot handler
Boot handler is a fragment of code executed by the system on start-up. It is not related with any class or object. A boot handler is implemented by placing code to VOS_BootHandlers section. Since an asm file may have only one occurrence of a section name there could be only one boot handler in a source asm file. However, application that consists of many files may have many boot handlers. Order of execution is not known and not fixed, therefore the code should not relay on any particular order. When boot handler is executed objects are not initialized
VOS_BootHandlers code ; starts a section for the application boot handler
banksel ANSEL
clrf ANSEL ; Turn all pints to digital
clrf ANSELH
banksel
OSCCON ; Set Fosc = 8Mhz
movlw (.7 << IRCF0)
movwf OSCCON
; !!! NO RETURN ALLOWED !!!
Building the project
A VELOOS project, to be properly built, should include VELOOS kernel (vos.asm
) and VELOOS specific instructions in the linker script for the target device. Unfortunately, MP LAB does not support multiple lkr files (it just takes the first one) therefore changes have to be made in a copy of a standard .lkr file distributed with MP LAB.
VELOOS can be configured (fine tuned) at build time. All configurable parameters are given in a separate inc file.
A package with sources for this example can be downloaded on this link. It includes the following files:
Example1.mcp |
MP LAP project file |
main.asm |
Example1 application sources |
pic.inc |
Processor-specific primitives, macros and includes |
pic16.inc |
PIC16/PIC12 specific primitives |
vos.asm |
VELOOS kernel |
vos.inc |
VELOOS public interface |
vos_cfg.inc |
VELOOS configuration file |
16f690.lkr |
VELOOS specific linker script |
Application Source
; License: Licensed to public under the Open Software License
; http://www.opensource.org/licenses/osl-3.0.php
include "pic.inc"
include "vos.inc"
;------------------------------------------------------------------------------
__CONFIG _WDT_ON & _INTRC_OSC_NOCLKOUT & _CP_OFF & _PWRTE_ON & _MCLRE_ON & _FCMEN_OFF & _BOR_OFF & _IESO_OFF
;------------------------------------------------------------------------------
constant mask = .2 ; mask to be used for driving port (RA1)
constant msgid = 040h ; message ID
VOS_Classes ; Class definitions begin
MyClass VOS_mClass MyHandler, MyInit ; MyClass implementes MyHandler and MyInit methods
; Class definitions end with beginning of the next code section
VOS_Objects ; Object registry begins
MyObject
VOS_mPersistentObject MyClass, mask ; Instance of MyClass constructed with object data == mask
; Object registry ends with beginning of the code next section
;------------------------------------------------------------------------------
code
MyInit ; This was loaded with object data
comf This, W ; W := ~mask
banksel TRISA
movwf TRISA ; Prepare port for output
VOS_mPostMessage MyObject, msgid ; post message to itself
return
;------------------------------------------------------------------------------
MyHandler ; FSR points to message ID field, This is loaded with object data
movlw msgid
xorwf INDF, W ; if message.msg_id <> msgid
skpz
return ; return
movf This, W
banksel PORTA
xorwf PORTA, F ; Toggle port
VOS_mPostMessageMyObject, msgid ; post message to itself
return
;------------------------------------------------------------------------------
VOS_BootHandlers code ; starts a section for the application boot handler
banksel ANSEL
clrf ANSEL ; Turn all pints to digital
clrf ANSELH
banksel OSCCON ; Set Fosc = 8Mhz
movlw (.7 << IRCF0)
movwf OSCCON
; !!! NO RETURN ALLOWED !!!
;------------------------------------------------------------------------------
end
3 Comments