Prima cosa da sapere prima di iniziare è che le periferiche nei processori arm sono [http://it.wikipedia.org/wiki/Metodi_di_input/output#Memory-mapped_I.2FO memory mapped] quindi per accedere alle periferiche (come le digitali) basta leggere ad un indirizzo prefissato in memoria. Per conoscere l'indirizzo di memoria corretto basta leggere il datasheet del processore. Leggendo i datasheet del processore in questione si può notare che le periferiche di I/O sono suddivise in 8 porte differenti da 8 bit ciascuno (chiamate con le lettere dalla A alla H). Alcune uscite sono assegnate a piu' device tramite multiplexer, e quindi configurabili scrivendo in un'apposita area di memoria di 32 bit chiamata device_config. Inoltre per ogni digitale si deve settare un'altra area di memoria che indica se quella digitale sara' usata come input o come output. Avevo letto in giro gente che usava push e pop scritte in assembler per scrivere e leggere in memoria, e io non capivo il perché, quindi ho provato a fare di testa mia e ad usare i puntatori, e tutto funziona a meraviglia ed il codice risulta IMHO molto piu' leggibile: {{{ #!C // Dichiaro i puntatori che dovranno puntare all'indirizzo di memoria // in cui sono mappate le digitali static volatile uint8_t* port[8], *portd[8]; // Apro /dev/mem int devmem = open("/dev/mem", O_RDWR|O_SYNC); assert(devmem != -1); // Prendo la pagina di memoria relativa alle digitali data_page = (unsigned long)mmap(0, getpagesize(), PROT_READ|PROT_WRITE, MAP_SHARED, devmem, DATA_PAGE); assert (&data_page != MAP_FAILED); // Prendo la pagina di memoria relativa alle configurazioni syscon_page = (unsigned long)mmap(0, getpagesize(), PROT_READ|PROT_WRITE , MAP_SHARED, devmem, SYSCON_PAGE); assert(&syscon_page != MAP_FAILED); // Prendo l'area di memoria relativa ai device config uint32_t* deviceCfg = (uint32_t*) (syscon_page + DEVICECFG); // Abilito la scrittura in memoria. uint32_t* syscon_unlock = (uint32_t*) (syscon_page + SYSCON_UNLOCK); *syscon_unlock = UNLOCK_VAL; //Associo ai puntatori l'area di memoria relativa alle porte digitali port[0] = (uint8_t*) (data_page + PADR); //[...] port[7] = (uint8_t*) (data_page + PHDR); //Associo ai puntatori l'area di memoria relativa alla direzione delle porte digitali portd[0] = (uint8_t*) (data_page + PADDR); //[...] portd[7] = (uint8_t*) (data_page + PHDDR); }}} E adesso non serve altro che leggere e scrivere nelle aree di memoria: {{{ #!C inline void set_bit(bool src, uint8_t *dst, uint8_t bit) { int value = 1 << bit; if(src) *dst |= value; else *dst &= ~value; } inline void get_bit(uint8_t src, bool *dst, uint8_t bit) { int value = 1 << bit; *dst = (src & value) >> bit; } int set_port_bit (uint8_t nport, bool value, uint8_t pos) { if(nport < 8 && pos < 8) { set_bit(value, port[nport], pos); return 0; } return -1; } int get_port_bit (uint8_t nport, bool* value, uint8_t pos) { if(nport < 8 && pos < 8) { get_bit(*port[nport], value, pos); return 0; } return -1; } int set_port_dir_bit (uint8_t nport, bool value, uint8_t pos) { if(nport < 8 && pos < 8) { set_bit(value, portd[nport], pos); return 0; } return -1; } }}} PS: Se vi servono maggiori informazioni basta chiedere vi email: me (at) mancausoft (dot) org