Programmare su Raspberry PI: programmiamo in COBOL

cobol per PI

Oggi vedremo cosa occorre per programmare in COBOL con un Raspberry PI: dal software di compilazione al codice di hello world, egestione GPIO.

Nella scorsa settimana abbiamo pubbllicato un articolo dedicato al retrocomputing con il Raspberry PI, mostrando come installare ed utilizzare un ambiente Fortran. Abbiamo quindi presentato alcuni esempi di codice Fortran, mostrando come fosse semplice ricompilarli per ARM. Dobbiamo ammettere che l’articolo ha suscitato l’interesse di diversi lettori, tra i quali i miei “vecchi” colleghi di programmazione Attilio e Paolo. Con loro il sottoscritto ha condiviso il periodo di sviluppo su mainframe in COBOL, e più scherzando che seriamente, entrambi mi han chiesto se fosse possibile programmare in COBOL sul Raspberry PI.

La risposta breve è , è possibile. Anche se il COBOL era noto per la sua farraginosità, pedanteria e prolissità nella descrizione del codice, l’esatto contrario, quindi, del C, siamo riusciti a trovare un compilatore COBOL per ARM che fa al caso nostro.

Ma andiamo con ordine…

Struttura di un programma COBOL

Chi ha lavorato sui mainframe ricorderà che la struttura di un programma COBOL è strictly typed, e definita nel seguente modo:

  • IDENTIFICATION DIVISION. – Una sezione in cui appaiono gli identificatori obbligatori
    • IDENTIFICATION DIVISION. serve ad identificare il programma, in essa infatti sono inseriti il nome del programma, l’autore, le date ed altre documentazioni.
    • PROGRAM-ID. nomeprog. Il nome programma deve avere una lunghezza massima di 8 caratteri, il primo deve essere alfabetico, non deve contenere spazi e non può contenere caratteri speciali tranne il trattino (-), che però non può essere nè in prima né in ultima posizione.
    • Altri identificatori non obbligatori, ma utili per tracciare l’autore del modulo, la data di scrittura, di compilazione e di installazione
  • ENVIRONMENT DIVISION. Contiene informazioni sulla configurazione che sarà utilizzata dal programma.
    • CONFIGURATION SECTION. La CONFIGURATION SECTION nella quale si definisce il tipo di macchina sulla quale si lavora e si specificano le sezioni che dichiarano particolari funzioni, il periodo DECIMAL-POINT IS COMMA ad esempio, serve per indicare al compilatore che desideriamo sostituire  il punto decimale con una virgola in modo che l’interpretazione delle cifre decimali e cifre superiori a 999 unità ci sia più chiara; i  compilatori COBOL adottano la notazione anglo-americana e quindi 1.000,00 lo scriverebbero 1,000.00.
    • INPUT-OUTPUT SECTION. in cui si definiscono le unità logiche  che puntano ai files elaborati dal programma, e soprattutto serve per definire il tipo di file, della modalità d’accesso, delle eventuali chiavi, del FILE STATUS (codice di ritorno che a seconda del valore contenuto ci comunica l’esito dell’operazione eseguita) e del LOCK MODE (modalità di controllo dei files in ambienti multiutente). L’organizzazione dei files (SEQUENTIAL, LINE-SEQUENTIAL, INDEX, RELATIVE), cioè il posizionamento dei records all’interno del file, viene scelta in funzione del modo con cui i records dovranno essere elaborati, mentre L’ACCESSO (SEQUENTIAL, RANDOM, DYNAMIC) varia in funzione del tipo di elaborazione che sarà svolta sul file.
  • DATA DIVISION. Descrive i files e le aree di lavoro che saranno utilizzati. La DATA DIVISION si compone di due SECTION obbligatorie e due facoltative:
    • FILE SECTION. cui si descrivono i record che costituiscono i file utilizzati dal programma dichiarati nella ENVIRONMENT DIVISION
    • WORKING-STORAGE SECTION, nella quale si dichiarano le aree di lavoro
    • LINKAGE SECTION necessaria per la dichiarazione delle aree comuni al programma chiamante
    • SCREEN SECTION nella quale si dichiarano le aree dello schermo.
  • PROCEDURE DIVISION. Contiene le istruzioni ed i comandi che l’elaboratore dovrà eseguire.

Il tutto va codificato secondo una strategia particolare, seguendo un incolonnamento prefissato  (ad esempio i commenti vanno preceduti da un asterisco in colonna 7, le righe hanno una lunghezza di 72 colonne, è possibile andare a capo ma solo mediante operatori particolari…)

cobol raspberry
Esempio di intestazione di programma COBOL

Per darvi un’idea di cosa fosse scrivere un programma in COBOL, ecco il listato di un programma che esegue la semplice lettura di un file sequenziale a linee:

Impressionante, non è vero? E non abbiamo ancora toccato CICS o DB2…

Perché farsi del male in questo modo?

In realtà spesso il diavolo è meno brutto di quanto lo si dipinga. Questo sistema di programmazione era necessario per interfacciarsi con hardware particolari (mainframe) su sistemi operativi particolari (MVS) attraverso processori di comando (JCL) che assumevano il controllo e la gestione di periferiche (initiators, channels. control units, tapes, disks) ciascuna delle quali era gestita da un sistema di controllo autonomo, in modo da evitare collisioni durante le fasi di multiprogrammazione. Eravamo al termine degli Anni Settanta del secolo scorso.

Poco più tardi inizio la rivoluzione informatica, il “personal computer” fece capolino sulle nostre scrivanie, la la Xerox Palo Alto Research Center (PARC) presentò la metafora della scrivania, apparvero i primi sistemi operativi multithread per PC (IBM OS/2) e tutto iniziò a sembrare più semplice.

Tant’è vero che oggi il classico programma hello world in COBOL assume la forma seguente:

cobol raspberry pi

Fa quasi tenerezza…

Installiamo il COBOL sul PI

Per installare il compilatore COBOL sul nostro Raspberry, la procedura è semplice.

Innanzi tutto il classico aggiornamento di sistema:

Al termine dell’aggiornamento installiamo il nostro compilatore:

e controlliamo che tutto sia a posto:

E’ giunto il momento di scrivere il nostro primo programma in COBOL sul PI.

Inseriamo il seguente codice nel nostro editor preferito:

facendo ben attenzione a posizionare ogni inizio riga a colonna 7, pena la mancata compilazione del codice… Quindi salviamo il programma con hello.cbl, compiliamo con il comando

e lanciamo il file eseguibile con

Voila: abbiamo creato il nostro primo programma in COBOL!

In realtà, se leggiamo l’ultima riga della risposta al flag –version, ci rendiamo conto di trovarci dietro ad un preprocessore per il C. In altri termini, non abbiamo un vero compilatore, bensì un traduttore da COBOL in C… ma tant’è.

Interfacciarsi con il mondo reale

Ovviamente non sarà sempre così facile… Cosa occorre fare, ad esempio, per gestire il GPIO del PI da COBOL?

Ecco un programma di esempio. Caricate nell editor il sorgente e salvatelo come RPiwithCOBOL.cobol, quindi compilate come al solito.

L’effetto sul monitor dovrebbe essere il seguente:

RPiCOBOL

mentre il LED collegato sul pin 21 inizierà a lampeggiare.

In realtà, chi programma in COBOL si sarà accorto di un potenziale problema: ogni riga di codice del linguaggio inizia a colonna 8 e termiina con un punto misurando al massimo 72 caratteri. Sarà quindi necessario rimaneggiare il nostro programma nel seguente modo:

Come è facile notare, è sufficiente spezzare le righe che vanno oltre colonna 80, andare a capo, partire dalla riga successiva a colonna 7, inserire il codice di continuazione  ‘-‘, lasciare uno spazio, reinserire il codice stringa ‘ e terminare la nostra riga. QUesto per ciascuna delle righe che superano colonna 80, pena un errore in compilazione.

Salviamo il nuovo sorgente ma per compilarlo ci occorre un ulteriore escamotage: dal momento che l’accesso al GPIO (o per essere più specifici, l’accesso alle directory contenenti i system files dei devices necessari per colloquiare con il GPIO) richiede privilegi di root, occorre compilare lanciando sia il compilatore che l’eseguibile creato utilizzando sudo:

Ora il sistema è pronto e il programma è compilato correttamente: il programma accederà al PIN 21 esportandolo come system file,  determinerà la directory di azione, chiamerà (PERFORM) tre volte la routine FLASH-LITE e chiuderà la sessione con la chiamata di sistema definita in WS-GPIO-CLR. La procedura FLASH-LITE non farà altro che definire un path per i device del GPIO, inviare un valore di on ed uno di off con uno sleep di 1 secondo. Ora avrete un’idea del perché il COBOL viene definito un linguaggio “prolisso”…

Considerazioni finali

Niente male, vero? Certo, in C è più rapido, e in Python più veloce, ma il fascino di gestire il GPIO di un PI via COBOL non ha prezzo!

E anche per oggi abbiamo terminato. Ne è venuta fuori una puntata sostanziosa… Se ne volete altre del genere, scrivete!

Definire ciò che si è non risulta mai semplice o intuitivo, in specie quando nella vita si cerca costantemente di migliorarsi, di crescere tanto professionalmente quanto emotivamente. Lavoro per contribuire al mutamento dei settori cardine della computer science e per offrire sintesi ragionate e consulenza ad aziende e pubblicazioni ICT, ma anche perche’ ciò che riesco a portare a termine mi dà soddisfazione, piacere. Così come mi piace suonare (sax, tastiere, chitarra), cantare, scrivere (ho pubblicato 350 articoli scientfici e 3 libri sinora, ma non ho concluso ciò che ho da dire), leggere, Adoro la matematica, la logica, la filosofia, la scienza e la tecnologia, ed inseguo quel concetto di homo novus rinascimentale, cercando di completare quelle sezioni della mia vita che ancora appaiono poco ricche.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.