Ver Mensaje Individual
  #12 (permalink)  
Antiguo 26/01/2006, 04:33
Avatar de Beakdan
Beakdan
 
Fecha de Ingreso: diciembre-2001
Ubicación: Monterrey, Nuevo León
Mensajes: 433
Antigüedad: 23 años, 1 mes
Puntos: 7
En ese aspecto tienes toda la razón. Yo mismo he tenido que trabajar con un grupo de programadores expertos en drivers para desarrollar los de varios de los dispositivos que hacemos. Pero, del lado de la PC, se tiene por supuesto mucha ventaja. Puedes hacerlo todo con un lenguaje de alto nivel si lo deseas, y cumplir con todo un conjunto de reglas para asegurar la portabilidad, y otros aspectos como el reuso de código.
Sin intención de desviar el tema, del lado del Hardware que se conecta al PC por supuesto, muy pocas veces tienes oportunidad de trabajar con un procesador lo suficientemente veloz o poderoso como para seguir todas las reglas. De hecho, he recibido muchas críticas de otros programadores acerca de la gran mayoría de mi código. Aspectos como utilizar demasiadas variables globales, usar con demasiada frecuencia Inline Assembly, o tener múltiples puntos de salida para una función. Yo mismo evito hacer tales cosas programando aplicaciones para PC. Pero en algunas plataformas, las reglas estorban, o algunas cualidades de un lenguaje se vuelven la encarnación del mal. O lo que en estos procesadores genera una enorme mejora de velocidad, en un PC es irrelevante ya que, por la enorme cantidad de intrucciones que pueden procesar por segundo, un usuario no nota la diferencia entre 100 ciclos o 10,000. Por eso alguna vez te decía que muchas veces me da lo mismo el lenguaje de alto nivel que se use. Muchas veces termino optimizando sectores críticos con Assembly. Sobre todo en el manejo de interrupciones. En este mismísimo momento estoy trabajando con un procesador de Freescale de 8 bits. Te dejo dos ejemplos que en cuanto a funcionalidad, hacen exactamente lo mismo (reciben 8 bits con el protocolo I2C con un MCU funcionando a 3.2Mhz). Pero evidentemente, una de las soluciones es inaceptable.

Este ejemplo es fácil de comprender y breve...
Código:
//La variable i está declarada dentro de la función
//Y se está incrementando (esto ralentiza el bucle algunos ciclos)
//Se utilizaron BitFields
    for(i=0; i<8; i++){
        DDRA.BIT4 = 0;
        if(PTA.BIT3) TxRxSHR |= (1<<i);
        PTA.BIT4 = 0;     
        DDRA.BIT4 = 1;    
    }
Pero genera esto:
Código:
TSX   
CLR   ,X
LDA   _DDRA
AND   #-17
STA   DDRA
LDA   _PTA
AND   #8
TSTA
BEQ   +12
LDA   #1
LDX   ,X
BEQ   +3

LSLA            ;Aquí está el principal problema
DBNZX -3        ;Se retrasa (5*i) + (5*2i) + ... + (5*7i)
                ;es decir 140 ciclos
ORA   TxRxSHR
STA   TxRxSHR
LDA   _PTA
AND   #-17
STA   _PTA
LDA   _DDRA
ORA   #16
STA   _DDRA
TSX   
INC   ,X
LDA   ,X
CMP   #8
BCS   -39
Este otro código, ya no es portable definitivamente, si quiero volver a usarlo en otro procesador, tendré que reescribirlo...
Código:
//bitCount es una variable global declarada como "byte __near bitCount"
//En lugar de incrementarla, se decrementa, por lo tanto
//se compara contra cero, que es el modo más eficiente en
// un procesador. 
for(bitCount=8; bitCount>0; bitCount--){
    DDRA &= ~0x10;
    _asm{
        LDA    PTA
        AND    #0x08
        ADD    #0xF8
        ROL    TxRxSHR
    }
    PTA &= ~0x10;     
    DDRA |= 0x10;    
}
Sim embargo, genera este código que se ejecuta en ~32 ciclos:
Código:
MOV   #8,bitCount
BCLR  4,_DDRA
LDA   _PTA
AND   #8
ADD   #-8
ROL   TxRxSHR
BCLR  4,_PTA
BSET  4,_DDRA
DEC   bitCount
TST   bitCount
BNE   -20
El primer código podría ser usado, y sería portable, aún considerando que es lento, pero para esta aplicación en particular, agotaría la batería con que debe operar el procesador mucho más rápido que con el segundo código. Podría aumentar la velocidad del circuito, pero esto también acabaría con la batería. Como puedes ver, el asunto de la portabilidad ya no resulta importante. Y sigue siendo lenguaje C.

Disculpándome por desviar tanto el tema, y volviendo al rubro de los OS, alguna vez hice uno, por supuesto no un Windows, no un Linux. Simplemente se trataba de poder ejecutar varias "aplicaciones" en un MCU de 8 bits, con limitadísima memoria RAM (2K), y en lugar de disco duro, una memoria flash de 2M. Encontré un libro llamado "μC/OS, The Real-Time Kernel" de Jean J. Labrosse. Los conceptos que expone son válidos para para OS "mayores", y te guía paso a paso para que hagas uno que funcionará en un X86, ya que probablemente será el procesador que tendrás a mano. Este μC/OS ha sido portado a muchas plataformas, como los 8052, 8051, Motorola 68K, Philips 80C166... en fin, una lista interminable.

Y como ultima nota y abuso, con el incremento de aplicaciones embebidas, hay un vacío enorme de programadores que desarrollen OS o aplicaciones para estas plataformas. Desde 4 bits hasta 64 bits.

Última edición por Beakdan; 26/01/2006 a las 04:40