Sistemas Embedded con FPGA's y Linux


Tarjeta con FPGA + controladora Puente H motores

Implementando la electronica y el software de una CNC de motores de continua

Los sistemas embedded (tambien llamados sistemas embebidos o empotrados), son sistemas altamente integrados.
Suelen ocupar muy poco espacio y tener un consumo muy reducido.
Con la entrada al mercado de las FPGA's los sistemas embedded aun se pueden reducir mas, y ya podemos hablar de sistemas SoC (system on chip, o sistema en chip), es decir todo un sistema compuesto de procesador,memoria, y circuitos de apoyo personalizados pueden entrar en un solo microchip.
Las FPGA's a groso modo podemos decir que son chips virgenes, es decir, chips que se pueden transformar
en circuitos que nosotros queramos. Estos circuitos se suelen crear describiendolos con lenguajes especiales hardware, los mas utilizados son VHDL y Verilog.

El sistema que voy a tratar en este articulo esta compuesto de una placa con una FPGA Spartan3 y memoria.
Su finalidad sera la de controlar una CNC con 3 motores de tension continua, es decir va a ser un sistema microprocesado donde vamos a necesitar 3 salidas PWM, 3 entradas para encoders opticos y otras salidas y entradas auxiliares para dar apoyo a sensores de final de carrera,botones,etc..

Para estas funciones le crearemos unos circuitos dedicados, por lo cual este sistema se comportara de una manera mucho mas veloz que lo que pudiera realizar un PC de ultima hornada por muchos megahertzios que dispusiera.

Finalmente en el apartado del software, a este sistema le pondre un sistema operativo ucLinux, con lo cual el desarrollo del programa que gestionara la CNC sera muy parecido a la que desarrollo normalmente para ordenadores de sobremesa.

El sistema operativo ucLinux es un kernel derivado de Linux pero parcheado para que funcione en procesadores que carecen de MMU (memory management unit), digamos que todos los procesos comparten el direccionamiento de memoria por lo que cualquier programa que estuviera mal diseñado puede tirar todo el sistema abajo. Afortunadamente el Linux siempre se ha caracterizado por su estabilidad y ucLinux se muestra muy muy robusto.
Para completar nuestro sistema tenemos que cumplir varios objetivos:

  • Conseguir que linux arranque en nuestro sistema.
  • Configurar los drivers standard del sistema (memoria mtd,ethernet,teclado etc..)
  • Crear unos drivers en el kernel que gestionen los circuitos creados por nosotros (pwm,encoders,botones,vga)
  • Crear el programa de modo usuario. En nuestro caso portaremos el programa EMC2 de linuxcnc a nuestro sistema.

    Hardware

    A esta FPGA le voy a crear multiples circuitos que son:

  • Procesador PowerPC Microblaze 32 bits
  • Entrada teclado PS/2
  • Mac Ethernet 10/100
  • Controlador de memoria DDR
  • Memoria Cache de datos e instrucciones (8ks)
  • Salida Display
  • Salida VGA
  • Salida PWM de multiples canales para etapa de potencia de los motores (puente H)
  • Entrada para multiples Encoders opticos

    La placa ademas debera tener algo de memoria RAM DDR para el uso del procesador y memoria flash para configurar la fpga y para albergar el kernel uclinux, y los programas.

  • Memoria DDR 32 Megabytes
  • Memoria Flash Serie 16 Megabytes

    Software

  • U-boot para arrancar el kernel
  • kernel UcLinux 2.4.32 con soporte IP, sistemas fat, memorias SD, etc...
  • Software nivel usuario uclinuxdist con busybox, etc...
  • Drivers de kernel para circuitos pwm y encoders opticos.
  • EMC2 de linuxcnc

    Configuraciones avanzadas

    Necesidades especiales, tiempos de respuesta.
    Linux no esta pensado para gestionar eventos en tiempo real, esta pensado para ser muy eficiente haciendo muchas tareas a la vez, y para esto, tener que responder en tiempo real a ciertas situaciones crea un impacto negativo en el rendimiento general del sistema. En los sistemas embedded los objetivos son muy distintos, a veces se necesita que el sistema reaccione con tiempos de respuesta muy pequeños y deterministas.El kernel 2.6 ha realizado muchas mejoras en este aspecto, pero cuando se requiere un tiempo real hard, lo mejor es parchear el kernel con los parches de rtlinux o rtai.
    Estos hacen que el cerebro del sistema sea un microkernel de tiempo real, y el linux se convierte en un proceso mas.
    De esta manera puedes programar un proceso realtime que se encargue por ejemplo de alguna interrupcion, y el resto de tareas tipicas de linux, gestion de la pila ip, dispositivos,etc..se ejecuta con una prioridad mas baja.

    Bootlog de Uclinux arrancando en la tarjeta con softprocessor Microblaze

    Linux version 2.4.32-uc0 (root@trastu) (gcc version 3.4.1 ( Xilinx EDK 8.1.01 Build EDK_I.19.4 080506 )) #15 Wed Mar 28 12:49:45 CEST 2007
    On node 0 totalpages: 8192
    zone(0): 8192 pages.
    zone(1): 0 pages.
    zone(2): 0 pages.
    CPU: MICROBLAZE
    Kernel command line: mtdparts=physmap_auto:256K(boot),256K(bootenv),256K(config), 4M(image),11M(spare) macaddr=00:0a:35:00:22:01
    Console: xmbserial on UARTLite
    Calibrating delay loop... 32.97 BogoMIPS
    Memory: 32MB = 32MB total
    Memory: 29692KB available (624K code, 2090K data, 36K init)
    Dentry cache hash table entries: 4096 (order: 3, 32768 bytes)
    Inode cache hash table entries: 2048 (order: 2, 16384 bytes)
    Mount cache hash table entries: 512 (order: 0, 4096 bytes)
    Buffer cache hash table entries: 1024 (order: 0, 4096 bytes)
    Page-cache hash table entries: 8192 (order: 3, 32768 bytes)
    POSIX conformance testing by UNIFIX
    Linux NET4.0 for Linux 2.4
    Based upon Swansea University Computer Society NET3.039
    Microblaze UARTlite serial driver version 1.00
    ttyS0 at 0x40600000 (irq = 2) is a Microblaze UARTlite
    Starting kswapd
    RAMDISK driver initialized: 16 RAM disks of 4096K size 1024 blocksize
    physmap_auto flash device: 1000000 at 21000000
    physmap_auto probing buswidth 1
    cfi_cmdset_0001: Erase suspend on write enabled
    0: offset=0x0,size=0x20000,blocks=128
    Using buffer write method
    physmap_auto: Using Command Line partition definition
    Creating 5 MTD partitions on "Physically mapped flash":
    0x00000000-0x00040000 : "boot"
    0x00040000-0x00080000 : "bootenv"
    0x00080000-0x000c0000 : "config"
    0x000c0000-0x004c0000 : "image"
    0x004c0000-0x00fc0000 : "spare"
    uclinux[mtd]: RAM probe address=0x220d3a3c size=0x1d3000
    uclinux[mtd]: root filesystem index=6
    MicroBlaze auto-config flash probe(0x21000000,8388608,4): 800000 at 21000000
    CFI: Found no Flash device at location zero
    Search for id:(1818 00) interleave(2) type(2)
    Search for id:(1818 00) interleave(2) type(2)
    Search for id:(1818 00) interleave(2) type(2)
    Search for id:(18 18) interleave(2) type(1)
    Search for id:(18 18) interleave(2) type(1)
    Search for id:(18 18) interleave(2) type(1)
    Search for id:(1818 00) interleave(4) type(2)
    Search for id:(1818 00) interleave(4) type(2)
    Search for id:(1818 00) interleave(4) type(2)
    Search for id:(18 00) interleave(4) type(1)
    Search for id:(18 00) interleave(4) type(1)
    Search for id:(18 00) interleave(4) type(1)
    JEDEC: Found no Flash device at location zero
    MicroBlaze auto-config ram probe(0x220d3a3c,1912832,4): 1d3000 at 220d3a3c
    Creating 1 MTD partitions on "RAM":
    0x00000000-0x001d3000 : "Romfs"
    VFS: Mounted root (cramfs filesystem) readonly.
    Freeing init memory: 36K
    Mounting proc:
    Mounting var:
    Populating /var:
    Running local start scripts.
    Mounting /etc/config:
    Populating /etc/config:
    flatfsd: invalid header magic
    flatfsd: Nonexistent or bad flatfs (-183), creating new one...
    flatfsd: Wrote 232 bytes to flash in 2 seconds
    flatfsd: Created 4 configuration files (124 bytes)
    Setting hostname:

    Embedded login: root
    Password:
    # ls
    bin dev etc home lib mnt proc sbin tmp usr var
    #

    Links:

    Empresas de FPGA

    Xilinx
    Altera

    Linux en microblaze

    Petalinux

    Cores libres

    OpenCores