|
CodeFR Recherche
Mégaphone
hixcod, 12:10, Jan 09, 2010:
Happy New year !
MooZ, 09:41, Jan 05, 2010:
Bonne année! (erm...)
MooZ, 13:51, Jan 05, 2009:
Bonne année!
MooZ, 07:19, Jan 04, 2008:
Diantre! Je me suis fait doublé moi aussi.
Bonne année quand même (et il faut que je trouve une pinup).
Axioplase, 15:39, Jan 03, 2008:
Merde, Froggy m'a devancé sur 2008 !
Froggy, 22:21, Jan 01, 2008:
Super mega cool
MooZ, 12:34, Oct 27, 2007:
Yeah! Seven!
Seven, 16:41, Oct 18, 2007:
Prout !
MooZ, 09:47, Mars 05, 2007:
Feed the wiki comme dirait l'autre!
hixcod, 19:26, Mars 04, 2007:
et moi donc
|
On retrouve des logiciels embarqués a peu prêt dans tous les matériels électroniques; que ce soit des matériels médicaux, assistants numériques, imprimantes, four micro-ondes, téléphones portables, voitures, missiles, sondes spatiales, etc. Tous ces matériels sont spécifiques, souvent uniques, spécialisés dans un domaine particulier, et demandent parfois beaucoup de temps, de connaissances, et d’expérience pour pouvoir en tirer le meilleur parti. Les langages les plus répandus pour faire leurs logiciels embarqués sont et seront encore pour quelques temps les langages C et C++. Les systèmes embarqués existent depuis l’invention du premier microprocesseur dans les années 70 et leur nombre est en constante augmentation, ils font déjà parti de notre quotidien, sans même parfois que vous vous en aperceviez. Fort est à parier que de plus en plus de personnes travailleront dans ce domaine, peut-être vous même, qui sait… Un système embarqué est une combinaison de hardware, software, et souvent de parties mécaniques (comme pour une imprimante par exemple) créées pour réaliser une fonction spécifique et connue. C’est pour cette dernière raison que l’on ne considère pas un ordinateur personnel comme un système embarqué et ce malgré ses parties mécaniques, hardware et software. En effet l’ordinateur personnel a une utilisation générique, on ne sait pas à l’avance ce que va en faire l’utilisateur, c’est sa généricité qui le fait sortir de la catégorie. Dans un système embarqué on ne doit pas remarquer la présence de processeurs et de logiciel, le système a pour but d’être transparent et de simplifier la vie, exemple le four micro-onde ou les imprimantes. Un système embarqué n’est généralement pas seul, c’est souvent qu’une partie d’un ensemble; dans un téléphone mobile par exemple, on retrouve souvent un système embarqué applicatif, responsable des applications et contenant ou non un système d’exploitation temps réel et un système embarqué spécialisé dans la communication, les 2 parties communicants par un bus quelconque ou une zone de mémoire partagée. Notez qu’il existe 2 grandes familles de systèmes embarqués, les systèmes embarqués temps réel et ceux qui ne le sont pas. Ces systèmes sont tout simplement des systèmes sans OS temps réels, c’est à dire des systèmes qui n’ont pas de contraintes temporelles significatives. On retrouve ces systèmes dans des matériels qui ont de grosses contraintes de taille mémoire et/ou peu de nécessité de protection mémoire ou des systèmes dit non critiques comme une calculatrice, des logiciels de tests bas niveau ou certains firmwares. Ceux là ont des contraintes de temps fortes, la nécessité de répondre à un événement en un temps connu est souvent due à : • La sauvegarde de l’intégrité matérielle du système : si le temps n’est pas respecté le système est endommagé, exemple: un gestionnaire de pompe pressurisée, si l’événement qui dit que la pression doit être relâchée n’est pas traité dans les 10 secondes qui suivent la pompe peut être dégradée par la trop forte pression. • La sauvegarde des personnes dépendantes du système embarqué : comme le système ESP/ABS/airbag des voitures. (Nécessité de réaction rapide, donc due une contrainte relative à la fonctionnalité attendue du système : vous sauver la vie… on alors dit que le système à des « hard deadlines ».) • La fonctionnalité attendue : dans le cas d’un téléphone portable la nécessité de traiter rapidement les signaux GSM reçus pour pouvoir gérer une communication. Pour informations il existe plusieurs OS temps réels utilisés dans l’embarqué : VRTX, RTXC, PSOS, RTAI, RTLinux, OSEK, uCOS, Nucleus, QNX, etc. Chacun avec leurs spécificités propres et leur « footprint » (utilisation mémoire) associée. Le développeur d’un système embarqué doit donc être minutieux dans son travail et prévoir tous les cas d’utilisation possibles, un système embarqué ne se relance pas toutes les heures ou tous les mois, il peut ne pas s’arrêter pendant des années et la vie de personnes peut dépendre de la bonne exécution du programme. C’est pour ça que l’on retrouve souvent des méthodes de spécification, de développement et de tests très stricts dans le monde de l’embarqué. Contrairement a un PC, ordinateur a tout faire, un logiciel embarqué ne peut en general pas tourner sur un autre systemes embarqués sans grandes modifications, tout ca parce que le hardware sousjacent n'est jamais le même. Le hardware dans chaque systeme embarqué est adapté aux fonctions de l'application, et tout le hardware superflu est elliminé. D'un façon générale un systeme embarqué contient un processeur et un logiciel embarqué, bien sur pour faire tourner ce software on va aussi trouver de la ROM (pour garder le tout, tout le temps en memoire, l'equivalent d'un disque dur), et de la RAM (parcekilenfo), quelle soit interne au processeur ou externe selon les besoins. En plus de ces grand classiques on va retrouver tout un ensemble de peripheriques liés a la fonction que le systemes embarqué doit remplir. Ainsi on peut retrouver un ecran LCD, un keypad, un systemes GPS, un capteur de temperature, un lecteur de SD card, un bras articulé, un emeteur radio accessible via un bus SPI (Serial Peripheral Interface), etc... Chaque système embarqué est le resultat d'un ensemble de contraintes, et est donc en général unique. Une de ces contraintes peut être le coût, si le système doit avoir un coût inferieur a 50 euros alors les choix technologiques, de consommation de puissance ou encore de fiabilité peuvent en patir pour addresser ce besoin. Voici quelques elements qui peuvent aussi influer sur le design: - La puissance de calcul: La puissance nécéssaire pour que le système embarqué fonctionne comme il se doit, 8, 16 ou 32 bits, avec telle ou telle quantité de MIPS. En general une fois choisi la technologie de la decoule directement la quantité de mémoire que l'on peut inclure, si on a choisi un processeur 8 bits, et bien a premiere vue on n'aura que 256 zones memoires uniques. En general les systemés embarqués sont souvent construit avec de vieux processeurs qui sont bon marché. - Le memoire: La quantité de memoire necessaire pour contenir le logiciel embarqué et ses données. Il faut estimer le mieux possible ces quantité. La quantité de memoire necessaire peut influer sur le choix du type de processeur puisque c'est lui qui defini la limite haute de memoire accessible. - Le cout de developpement: Le coup de design du hardware et du software. C'est un coup fixe, on n'a a le faire qu'une seule fois, et il peut etre derisoire par rapport au volume de vente et/ou de fabrication. - Le nombre d'unité: Le nombre d'unité produite. Il est generalement pas necessaire de developper son propre hardware pour de petite quantité, le coup de developpement etant alors plus important que les gains. - Le temps de vie: Combien de temps va vivre le systeme ? un mois, un an, des années ? Cela affecte aussi les choix dans le design, de la selection des composants hardware a combien rique de couter le systeme a developper et produire. - La fiabilité: Quelle fiabilité doit avoir le produit ? Si c'est un pauvre jouet pour enfant, le systeme n'a pas besoin de marcher toujours parfaitement, mais si c'est pour une fusée, une voiture, c'est autre chose, le systeme a plutot interet a faire parfaitement ce qu'il est cencé faire. Forcement plus la fiabilité doit etre grande plus le cout de developpement va etre grand. Cette board ADS est orienté PDA, mais on le retrouve aussi dans des baladeurs MP3, une console (Zodiac), et moult autres bidules electroniques. Voici a quoi ressemble l'ADS iMX1 et le connecteur pour debugger: ![]() Et voici son block diagram, c'est a dire en gros un schema vu de trés haut :) Vous pouvez voir ainsi comment sont reliés les elements par rapport aux autres. Voici quelques specificités du chip : • ARM920T Microprocessor Core • AHB to IP Bus Interfaces (AIPIs) • External Interface Module (EIM) • SDRAM Controller (SDRAMC) • Clock Generation Module (CGM) and Power Control Module • Three Universal Asynchronous Receiver/Transmitters (UART 1, UART 2 and UART 3) • Two Serial Peripheral Interfaces (SPI) • Two General-Purpose? 32-bit Counters/Timers • Watchdog Timer • Real-Time? Clock/Sampling Timer (RTC) • LCD Controller (LCDC) • Pulse-Width? Modulation (PWM) Module • Universal Serial Bus (USB) Device • Multimedia Card and Secure Digital (MMC/SD) Host Controller • Memory Stick® Host Controller (MSHC) • SmartCard? Interface Module (SIM) • Direct Memory Access Controller (DMAC) • Two Synchronous Serial Interfaces and Inter-IC Sound (SSI/I2S) Module • Inter-IC (I2C) Bus Module • Video Port • General-Purpose? I/O (GPIO) Ports • Bootstrap Mode • Analog Signal Processing (ASP) Module • Bluetooth Accelerator (BTA) • Multimedia Accelerator (MMA) • Power Management Features • Operating Voltage Range: I/O voltage 1.7 V to 3.3 V, core voltage 1.7 V to 2.0 V • Packaging: 256-pin MAPBGA PBGA Pour plus d'info : http://e-www.motorola.com/webapp/sps/site/prod_summary.jsp?code=i.MX1&nodeId=018rH3ZrDR Voici le memory mapping du chip, le memory mapping est specifique a chaque chip, il permet de savoir ou sont placés en memoires les registres des peripheriques et des bus, et aussi ou est mappé la ram, la rom et la flash. Maintenant que vous avez tout compris a comment est architecturé un systeme embarqué, on peut faire un premier programme tout bête. Bon on n'a pas de stdout par defaut, ca se saurait, donc on va eviter le simple printf hello world, mais pourquoi pas afficher une image sur l'ecran LCD. ![]()
/*****************************************************************
*
* MX1 LCD Demo code for Sharp TFT 640x480 for ADS
*
* Display a 640x480 16bpp background
*
*****************************************************************/
#include <rt_misc.h>
#include <stdio.h>
/*****************/
/*****Defines*****/
/*****************/
/*****LCD Characteristics*****/
#define LCD_WIDTH 640
#define LCD_HEIGHT 480
/*****Image*****/
// Background image start location and characteristics
// the image can be created using the bmp2bin.exe or bmp24to16.exe
// utilities available on the MX1 website
#define IMAGE_ADDRESS 0x0C100000
#define IMAGE_WIDTH 640
#define IMAGE_HEIGHT 480
#define IMAGE_BPP 16
/*****Registers*****/
// System
#define CSCR (*(volatile unsigned int *)(0x0021B000))
#define PCDR (*(volatile unsigned int *)(0x0021B020))
// GPIO
#define DDIR_C (*(volatile unsigned int *)(0x0021C200))
#define DDIR_D (*(volatile unsigned int *)(0x0021C300))
#define OCR2_C (*(volatile unsigned int *)(0x0021C208))
#define DR_C (*(volatile unsigned int *)(0x0021C21C))
#define GIUS_C (*(volatile unsigned int *)(0x0021C220))
#define GIUS_D (*(volatile unsigned int *)(0x0021C320))
#define GPR_C (*(volatile unsigned int *)(0x0021C238))
#define GPR_D (*(volatile unsigned int *)(0x0021C338))
// LCDC
#define SSA (*(volatile U32 *) (0x00205000)) // Screen Start Address Register
#define SIZE (*(volatile U32 *) (0x00205004)) // Size Register
#define VPW (*(volatile U32 *) (0x00205008)) // Virtual Page Width Register
#define CPOS (*(volatile U32 *) (0x0020500C)) // LCD Cursor Position Register
#define LCWHB (*(volatile U32 *) (0x00205010)) // LCD Cursor Width Height and Blink Register
#define LCHCC (*(volatile U32 *) (0x00205014)) // LCD Color Cursor Mapping Register
#define PCR (*(volatile U32 *) (0x00205018)) // Panel Configuration Register
#define HCR (*(volatile U32 *) (0x0020501C)) // Horizontal Configuration Register
#define VCR (*(volatile U32 *) (0x00205020)) // Vertical Configuration Register
#define POS (*(volatile U32 *) (0x00205024)) // Panning Offset Register
#define LGPMR (*(volatile U32 *) (0x00205028)) // LCD Gray Palette Mapping Register
#define LSCR1 (*(volatile U32 *) (0x00205028)) // Sharp Register
#define PWMR (*(volatile U32 *) (0x0020502C)) // PWM Contrast Control Register
#define DMACR (*(volatile U32 *) (0x00205030)) // DMA Control Register
#define RMCR (*(volatile U32 *) (0x00205034)) // Refresh Mode Control Register
#define LCDICR (*(volatile U32 *) (0x00205038)) // Interrupt Configuration Register
#define LCDISR (*(volatile U32 *) (0x00205040)) // Interrupt Status Register
/*****Macros*****/
// On/Off using Port C bit 16
#define LCD_ON DR_C |= 0x00010000
#define LCD_OFF DR_C &= 0xFFFEFFFF
int main ()
{
/************************/
/*****Initialization*****/
/************************/
/*****System Clock*****/
// CSCR ### Change BCLK (CPUCLK) to 96MHz (Div = 1)
// BCLK Divider = [13:10] + 1
CSCR = 0x2F008003;
// PCDR ### Change PerCLK2 (LCDCLK) to 48MHz (Div = 2)
// PerCLK2 Divider = [7:4] + 1
PCDR = 0x000B001B;
/****************************/
/*****GPIO Configuration*****/
/****************************/
/** Set Port C bit 16 to function as on/off (set = LCD on) **/
GIUS_C = 0x00010000;
OCR2_C = 0x00000003;
DDIR_C = 0x00010000;
GPR_C = 0x00010000;
LCD_OFF;
/** Configure Port D pins [30:6] to LCD signals **/
DDIR_D |= 0x7FFFFFC0;
GIUS_D &= 0x8000003F;
GPR_D &= 0x8000003F;
/****************************/
/*****LCD Initialization*****/
/****************************/
// Disable LCDC
RMCR = 0x00000000;
// Screen Start Address Register - "top left corner" of the image
SSA = IMAGE_ADDRESS;
// Configure dimensions of panel: [23:20] = Width / 16 , [8:0] = Height
SIZE = ((LCD_WIDTH / 16) << 20)|
(LCD_HEIGHT << 0));
// Virtual Page Width: image_width * bpp / 32
VPW = IMAGE_WIDTH * IMAGE_BPP / 32;
//Cursor Controls
/*
CPOS = 0x40010001;
LCWHB = 0x1F1F0000;
LCHCC = 0x0000f800;
/**/
// Panel Control Register ### tft ,color, 16bpp, PCD = 1 (+1)
PCR = ( (1 << 31)| // TFT enable
(1 << 30)| // Color enable (set for TFT)
(3 << 28)| // Panel Bus Width, 0=1 bit,1=2,2=4,3=8 (does not matter for TFT)
(4 << 25)| // BPP, 0=1bpp,1=2,2=4,3=8,4= 12 or 16
(0 << 24)| // Pixel Polarity, 0 = Active High, 1 = Active Low
(1 << 23)| // First Line Marker Polarity, "
(1 << 22)| // Line Pulse Polarity, "
(1 << 21)| // LCD Shift Clock, 0 = Active Falling, 1 = Active Rising (reverse for TFT)
(0 << 20)| // Output Enable Polarity, 0= Active High, 1 = Active Low
(0 << 19)| // LSCLK Idle Enable (when VSYNC is idle in TFT mode)
(0 << 18)| // Endian Select, 0 = Little, 1 = Big
(0 << 17)| // Swap Select, 0 = 16bpp, 1 = else
(0 << 16)| // Reverse Vertical Scan
(0 << 8)| // ACD Stuff
(1 << 7)| // LSCLK Select, 0 = Disable OE & LSCLK when no data output in TFT mode for power savings, 1 = Always on
(1 << 6)| // Sharp Panel Signals Enable
(1 << 0)); // Pixel CLK Divider, actual divider is PCD value + 1
// HCR ### Controls HSYNC signal, for other LCDs you will need to determine these values based off of spec
// note- H_WAIT2 derived experimentally due to lack of documentation, other values taken from previous demo code
HCR = ((1 << 26)| // H_WIDTH + 1 = width of Horizontal Sync Pulse in Pixel CLK periods
(16 << 8)| // H_WAIT1 + 1 = delay in Pixel CLK periods between OE & HSYNC
(102 << 0)); // H_WAIT2 + 3 = delay between HSYNC & first data of next line
// VCR ###
VCR = ((1 << 26)| // V_WIDTH = Vertical Sync pulse width in HSYNC periods
(0 << 8)| // V_WAIT1 = delay between OE and VSYNC (in TFT)
(34 << 0)); // V_WAIT2 = delay between VSYNC and OE of the first line of next frame
/****************/
/*****LCD ON*****/
/****************/
// LCDC Enabled, self-refresh mode disabled
RMCR = ((1 << 1)| // LCDC Enable
(0 << 0)); // Self-refresh mode enable
// Power On
LCD_ON;
return;
}
Chiant ? Ca c'était que l'écran... et une image uniquement fixe. Je vais passer sur la compilation, vous savez tous ce que c'est. Le link est beaucoup plus interressant. bon le but du link c'est de resoudre les symboles, jusque la tout va bien, les addresses sont associé grace a un fichier de link, le linker file (ou scatter file) qui specifie ou se trouve les sections en memoire. Voici un exemple de linker file pour ARM:
FLASH 0x24000000 0x4000000
{
FLASH 0x24000000 0x4000000
{
init.o (Init, +First)
* (+RO)
}
32bitRAM 0x0000
{
vectors.o (Vect, +First)
* (+RW,+ZI)
}
HEAP +0 UNINIT
{
heap.o (+ZI)
}
STACKS 0x40000 UNINIT
{
stack.o (+ZI)
}
}
mais il peut y en avoir de beaucoup plus complexes:
//CodeWarrior linker command file for Rainbow MCore.
MEMORY {
ESRAM (RWX) : ORIGIN = 0x00100000 , LENGTH = 0x00000800
ERAM (RWX) : ORIGIN = 0x07800000 , LENGTH = 0x00014000
RAM (RWX) : ORIGIN = 0x08000000 , LENGTH = 0x00800000
ROM1 (RX) : ORIGIN = 0x10000000 , LENGTH = 0x00020000
ROM2 (RX) : ORIGIN = 0x10020000 , LENGTH = 0x007E0000
ROM3 (RX) : ORIGIN = AFTER(ROM2), LENGTH = 0x00000000
}
KEEP_SECTION { .INT_vectors }
SECTIONS {
_STACK_SIZE_ = 0x00004000; # 16 KB
_HEAP_SIZE_ = 0x00100000; # 1 MB
.start :
{
WRITEW _start;
WRITEW 0x00000000;
WRITEW 0x00000000;
WRITEW 0x00000000;
WRITEW 0x00000000;
} > ROM1
.text :
{
. = ALIGN(0x400);
* (.INT_vectors)
#####################
# main_app
#####################
*(.text)
_NEXT_GROUP_ADDR_ = .;
} > ROM2
.data : AT( _NEXT_GROUP_ADDR_ )
{
#####################
# main_app_data
#####################
* (.rodata)
. = ALIGN(0x4);
__data_ROM_begin = .;
* (.data)
__data_ROM_end = .;
* (.vtables)
* (.exception)
. = ALIGN(0x8);
__exception_table_start__ = .;
EXCEPTION
__exception_table_end__ = .;
___sinit__ = .;
STATICINIT
#####################
# main_app_bss
#####################
__bss_begin = .;
* (.bss)
__bss_end =.;
} > ERAM
__stack_end = .;
__stack_begin = __stack_end + _STACK_SIZE_;
__stack_begin = (__stack_begin + 7) & ~7;
__heap_addr = __stack_begin; # see MSL alloc.c
__heap_end = __heap_addr + _HEAP_SIZE_;
__heap_size = __heap_end - __heap_addr;
__data_begin = __data_ROM_begin; # set to shadow RAM address
__data_size = __data_ROM_end - __data_ROM_begin;
}
Le linker file file permet de specifier ou se trouve le stack (call, push pop and co.), ou se trouve le heap (malloc and co.) et ou sont stocké les differents données, de .text (code) a .data (donnée) en passant par .bss (static, init). Ainsi on peut faire des programmes qui tournent uniquement en ram interne, en ram externe ou pour une flash. La plupart des outils de developpement, que ca soit GNU ou autre, rajoutent lors du link ce que l'on appelle un startup code. Le startup code est un petit bout de code assembleur qui permet de preparer l'excution du programme. L'espace pour le stack doit etre alloué et initialisé avant qu'un programme en langage de plus haut niveau soit executé, de meme les copies ROM/RAM doivent etre effectué a cet endroit pour pouvoir placer le code au bon endroit en memoire avant execution. La plupart des startup code effectue les operations suivantes dans cet ordre : - Desactiver des interruptions - Copier ROM to RAM - Mettre a zero la zone uninitialized data - Allouer l'espace pour le stack - Initialiser le stack pointer - Creer et initialiser le heap - Executer les constructeurs et initialiser les variables globales - Activer les interruptions - Appeller main Voici un exemple de startup code pour DSP Starcore SC140 Un startup code peut donc etre assez complexe, et il est indispensable, la plupart du temps un exemple ou un startup code par defaut est fourni. Pour ce qui est du telechargement et du debug, lors du debug on telecharge le soft sur la board via le debugger, donc via le device de debug connecté a la board. Le moyen de connection est soit par port serie avec une interface debugger software embarqué en plus sur la board, soit directement sur un connecteur JTAG (protocole de debug) via un Multi ICE pour ARM ou un module JTAG. Lorsque l'application est fini, le seul moyen de l'envoyer sur le board est en general via un mode bootstrap sur la board c'est a dire un mode ou tout ce qui est envoyé sur l'uart est placé en memoire (moyennant un protocole de bootstrap pour placer tout ca ou on veut) ou alors on peut utiliser un programme de flashing, fourni avec la board, qui se bootstrap mais permet de stocker son programme en flash. Dans l'embarqué les environnement de developpement sont nombreux, ceux de debug un peu moins, un outils trés connu dans le monde de l'embarqué est CodeWarrior? de Metrowerks, qui fournit un environnement de developpement pour beaucoup de processeurs embarqués et de consoles. Voila, j'espere que vous avez maintenant un meilleure vision du monde l'embarqué. Ce fut un survol rapide, un exemple trés simple, et peut etre dans un prochain article je vous exposerai comment marche un OS embarqué et comment adapter/porter un OS embarqué sur une board. D'ici là, salut et bon code. Créé par: Seven dernière modification: Lundi 08 of Mars, 2004 [21:27:57 UTC] par Seven |
Connexion Utilisateurs connectés
Il y a 3 utilisateurs connectés
LinuxFR news
MAKE Hack a Day GameDev Clubic news |