ELT048 – Embedded Operational
Systems
Rodrigo Maximiano Antunes de
Almeida
rmaalmeida@[Link]
@rmaalmeida
Universidade Federal de Itajubá
Review
Exercise
• Implement priority selection inside the kernel
Lower number -> lower priority
Must keep (soft) real time scheduling
• Processes (with priorities)
4 – keypad debounce
3 – increment/decrement clock
2 – display update
1 – clock count (ssdDigit)
U
UNN II F
FEE II
Void pointers
Void pointers
• Points to a memory region without specifying the
type.
• Can not be used without casting.
• Abstraction that allows the programmer to pass the
parameter of different types to the same function.
• A function that receives how to know how to handle
each type.
U
UNN II F
FEE II
Void pointers
char *name = "Paulo";
double weight = 87.5;
unsigned int children = 3;
void main (void){
//não confundir com printf
print(0, name);
print(1, &weight);
print(2, &children);
}
Void pointers
void print(int option; void *parameter){
switch(option){
case 0:
printf("%s",(char*)parameter);
break;
case 1:
printf("%f",*((double*)parameter));
break;
case 2:
printf("%d",*((unsigned int*)parameter));
break;
}
}
Driver
Driver
• What is a driver?
An interface layer that translate hardware to software
• It have two requirements
First: It is dependent on the microcontroller, the attached
peripherals and the connections between them.
Second: Need to comply with the built-in standard from
the operational system
U
UNN II F
FEE II
How can I develop my driver?
• First: know your hardware
Which features from the microcontroller are needed?
How the external peripheral is connected?
Are there any software/communication routines
required?
U
UNN II F
FEE II
Developing my driver (1)
• Example:
LCD Display:
• 16 columns X 2 lines
• Compatible with HD44780 (Hitachi)
NEO201
• 8 bit connection (data)
• Direct access to EN, RS e RW (control)
PIC18F4520
• Using both port D (data) and port E (control)
Initialization routines
U
UNN II F
FEE II
LCD initialization routine
U
UNN II F
FEE II
Schematics LCD - PIC
U
UNN II F
FEE II
Basic communication
void lcdData(unsigned char valor){
BitSet(PORTE,RS); //data
BitClr(PORTE,RW); //write
PORTD = valor;
BitSet(PORTE,EN); //enable pulse
BitClr(PORTE,EN);
BitClr(PORTE,RS); //avoid problems with 7 seg disp
Delay40us();
}
Basic communication
void lcdInit(void){
// lcd init 10ms
Delay2ms();
Delay2ms();
Delay2ms();
Delay2ms();
Delay2ms();
//pin directions
BitClr(TRISE,RS); //RS
BitClr(TRISE,EN); //EN
BitClr(TRISE,RW); //RW
TRISD = 0x00; //data
ADCON1 = 0b00001110; //Analog/digital config
lcdCommand(0x38); //8bits, 2 lines, 5x8
lcdCommand(0x06); //incremental mode
lcdCommand(0x0F); //display, cursor , blink on
}
How can I develop my driver?
• Second: know your operational system
Is there any standard on function parameters?
Which structures and information do I need to provide to
the operational system
How the OS will pass information for me?
U
UNN II F
FEE II
Talking with any type of driver
• Parameters problem
The kernel must be able to communicate in the same
way with all drivers
Each function in each driver have different types and
quantities of parameters
• Solution
Pointer to void
U
UNN II F
FEE II
Void pointers
• Points to a memory region without specifying the
type.
• Can not be used without casting.
• Abstraction that allows the programmer to pass
parameters of different types to the same function.
• The function that receives them must know how to
handle each type.
U
UNN II F
FEE II
Void pointers
char *name = "Paulo";
double weight = 87.5;
unsigned int children = 3;
void main (void){
//it is not printf!!!!
print(0, name);
print(1, &weight);
print(2, &children);
}
Void pointers
void print(int option; void *parameter){
switch(option){
case 0:
printf("%s",(char*)parameter);
break;
case 1:
printf("%f",*((double*)parameter));
break;
case 2:
printf("%d",*((unsigned int*)parameter));
break;
}
}
The standard
#ifndef DD_TYPES_H
#define DD_TYPES_H
//Device Drivers Types (dd_types.h)
//ptr. de func. para uma função do driver
typedef char(*ptrFuncDrv)(void *parameters);
//estrutura do driver
typedef struct {
char id;
ptrFuncDrv *funcoes;
ptrFuncDrv initFunc;
} driver;
//função de retorno do driver
typedef driver* (*ptrGetDrv)(void);
#endif /* DD_TYPES_H */
Driver example
Generic Device Driver
drvGeneric
-thisDriver: driver
driver
-this_functions: ptrFuncDrv[ ]
-callbackProcess: process* +drv_id: char
+availableFunctions: enum = {GEN_FUNC_1, GEN_FUNC_2 } +functions: ptrFuncDrv[ ]
-init(parameters:void*): char +drv_init: ptrFuncDrv
-genericDrvFunction(parameters:void*): char
-genericIsrSetup(parameters:void*): char
+getDriver(): driver*
U
UNN II F
FEE II
#ifndef drvGeneric_h
#define drvGeneric_h
#include "dd_types.h"
//lista de funções do driver
enum {
LED_SET,LED_FLIP, LED_END
};
//função de acesso ao driver
driver* getGenericDriver(void);
#endif // drvGenerico_h
#include "kernel.h"
#include "pic18f4520.h"
#include "drvGeneric.h"
static driver myself;
static ptrFuncDrv my_funcs[LED_END];
char changePORTD(void *parameters) {
PORTD = (char) parameters;
return SUCCESS;
}
char inverte(void * parameters){
PORTD = ~PORTD;
}
char initGenerico(void *parameters) {
TRISD = 0x00;
[Link] = (char) parameters;
return SUCCESS;
}
driver* getGenericDriver(void) {
[Link] = initGenerico;
my_funcs[LED_SET] = changePORTD;
my_funcs[LED_FLIP] = inverte;
[Link] = my_funcs;
return &myself;
}