Table des matières

FIFOs et Programmation Orientée Objet

Récupérer le sujet: https://bvdp.inetdoc.net/files/iut/td_fifo/TD1_com_2020.pdf

Programme à base de variables globales

main.cpp
#include <stdio.h>
 
#include <iostream>
using namespace std;
 
#include <QCoreApplication>
 
//initialisation faite directement
#define FIFO_SIZE 3
unsigned int fifo_size = FIFO_SIZE ;
unsigned int write_index = 0 ;
unsigned int read_index = 0 ;
unsigned int nb_available = 0 ;
char data[FIFO_SIZE] ;
 
//////////////////////////////////////////////////
////
/// \brief write_char_fifo
/// \param token : jeton a écrire dans la FIFO
/// \return 1 si valeur écrite dans la FIFO, 0 sinon
///
char write_char_fifo(const char token){
    if(nb_available >= fifo_size)
        return 0 ;  //FIFO PLEINE
    data[write_index] = token ;
    write_index++;
    if( write_index >= fifo_size)
        write_index = 0 ;
    nb_available++;
    return 1; //OK
}
//////////////////////////////////////////////////
///
/// \brief read_char_fifo
/// \param ptr_token : pointeur vers la zone mémoire dans laquelle ranger le jeton lu depuis la FIFO
/// \return  1 si valeur lue dans la FIFO, 0 sinon
///
char read_char_fifo( char * ptr_token){
    if( nb_available == 0)
        return 0; //FIFO VIDE
    *ptr_token=data[read_index];
    read_index ++;
    if( read_index >=  fifo_size)
        read_index = 0 ;
    nb_available--;
    return 1; //OK
}
//////////////////////////////////////////////////
int main(int argc, char *argv[])
{
 
    printf("salut les APP\r\n");
 
    cout << "Hello World!" << endl;
    /*write_char_fifo(5);
    write_char_fifo(1);
    write_char_fifo(7);*/
    for (int i=0;i<10;i++)
        if (write_char_fifo(i)==0)
           cout << "fifo pleine "<< endl;
 
    for (int i=0;i<10;i++){
        //rien n'empêche un utilisateur d'écrire
        //nb_available=5; //grosse bétise!
 
        char c;
        if (read_char_fifo(&c)!=0)
            cout << "donnée lue dans la fifo: " << +c << endl;
        else
            cout << "fifo vide "<< endl;
    }
    printf("fin\r\n");
}

Programme à base de structures

main2.cpp
#include <stdio.h>
 
#include <iostream>
using namespace std;
 
#include <QCoreApplication>
 
//initialisation faite directement
 
 
struct charFifo{
  char * data ;
  unsigned int fifo_size ;
  unsigned int write_index ;
  unsigned int read_index ;
  unsigned int nb_available ;
};
 
#define FIFO_SIZE1 3
char FifoBuffer[FIFO_SIZE1];
struct charFifo myFifo;    // la variable FIFO à utiliser
 
#define FIFO_SIZE2 4
char FifoBuffer2[FIFO_SIZE2];
struct charFifo myFifo2;
////////////////////////////////////////
////
/// \brief init_char_fifo
/// \param pf
/// \param buf
/// \param f_size
///
void init_char_fifo(struct charFifo * ptr_fif, char * buf, unsigned int f_size){
//(*ptr_fif).fifo_size=f_size;
ptr_fif->fifo_size=f_size;
ptr_fif->nb_available=0;
ptr_fif->write_index=0;
ptr_fif->read_index=0;
ptr_fif->data=buf;
 
}
 
//////////////////////////////////////////////////
////
/// \brief write_char_fifo
/// \ptr_fif : pointeur vers la fifo dans laquelle écrire
/// \param token : jeton a écrire dans la FIFO
/// \return 1 si valeur écrite dans la FIFO, 0 sinon
///
char write_char_fifo(struct charFifo * ptr_fif, const char token){
    if(ptr_fif->nb_available >= ptr_fif->fifo_size)
        return 0 ;  //FIFO PLEINE
    ptr_fif->data[ptr_fif->write_index] = token ;
    (ptr_fif->write_index)++;
    if( ptr_fif->write_index >= ptr_fif->fifo_size)
        ptr_fif->write_index = 0 ;
    ptr_fif->nb_available++;
    return 1; //OK
}
 
//////////////////////////////////////////////////
///
/// \brief read_char_fifo
/// \ptr_fif : pointeur vers la fifo dans laquelle écrire
/// \param ptr_token : pointeur vers la zone mémoire dans laquelle ranger le jeton lu depuis la FIFO
/// \return  1 si valeur lue dans la FIFO, 0 sinon
///
char read_char_fifo(struct charFifo * ptr_fif, char * ptr_token){
    if( ptr_fif->nb_available == 0)
        return 0; //FIFO VIDE
    *ptr_token=ptr_fif->data[ptr_fif->read_index];
    (ptr_fif->read_index )++;
    if( ptr_fif->read_index >=  ptr_fif->fifo_size)
        ptr_fif->read_index = 0 ;
    ptr_fif->nb_available--;
    return 1; //OK
}
//////////////////////////////////////////////////
int main(int argc, char *argv[])
{
 
    printf("salut les APP\r\n");
 
    char lu;
    init_char_fifo(&myFifo, FifoBuffer,  FIFO_SIZE1);
    read_char_fifo(&myFifo, &lu) ;
    write_char_fifo(&myFifo, 5) ;
    write_char_fifo(&myFifo, 8) ;
    read_char_fifo(&myFifo, &lu) ;
    write_char_fifo(&myFifo, 12) ;
    write_char_fifo(&myFifo, 1) ;
    write_char_fifo(&myFifo, 7) ;
    read_char_fifo(&myFifo, &lu) ;
    read_char_fifo(&myFifo, &lu) ;
    read_char_fifo(&myFifo, &lu) ;
    read_char_fifo(&myFifo, &lu) ;
 
}

Solution Question 2.5 du TD:

Programme avec approche objet

testapp.pro
QT += core
QT -= gui
 
TARGET = testapp
CONFIG += console
CONFIG -= app_bundle
 
TEMPLATE = app
 
SOURCES += main.cpp
SOURCES += fifo.cpp
SOURCES += fifoavecreinit.cpp
 
HEADERS+= fifo.h
HEADERS+= fifoavecreinit.h
fifo.h
#ifndef FIFO_H
#define FIFO_H
#include <iostream>
class Fifo
{
public:
    Fifo(unsigned int f_size=15); //paramètre par défaut
    ~Fifo();
    char write_char(const char token);
    char read_char(char * token);
    int get_nb_available();
    //les méthodes templates sont inlinées, on met le code dans le .h
    friend std::ostream &operator<<( std::ostream &output,Fifo &F )
    { char car;
        if (F.read_char(&car)==1)
            output <<  car ;
        else
            output <<  "FIFO VIDE" ;
        return output;
    }
    friend std::istream &operator>>( std::istream  &input, Fifo &F )
    {
        char car;
        input >> car;
        F.write_char(car); //pas de vérification de place disponible dans la fifo, hic
        return input;
    }
    //ces attributs sont rendus privés pour éviter qu'un utilisateur de la classe puisse les modifier
private:
    char * data ;
    unsigned int fifo_size ;
    //les attributs suivants seront modifiables par les classes filles
protected:
    unsigned int write_index ;
    unsigned int read_index ;
    unsigned int nb_available ;
 
};
#endif // FIFO_H
fifo.cpp
#include "fifo.h"
 
using namespace std;
 
//#define DEBUGFIFO
 
////////////////////////////////////////////
Fifo::Fifo(unsigned int f_size)
{
    cout << "construction d'une fifo" << endl;
    this->data=new char(f_size);    //allocation de data
    this->fifo_size = f_size ;
    this->write_index = 0 ;
    this->read_index = 0 ;
    this->nb_available = 0 ;
}
////////////////////////////////////////////
Fifo::~Fifo()
{
    delete(this->data);    //libération de data
}
////////////////////////////////////////////
char Fifo::write_char(const char token){
    if(this->nb_available >= this->fifo_size) return 0 ;
    this->data[this->write_index] = token ;
    this->write_index = this->write_index + 1;
    if(this->write_index >= this->fifo_size) this->write_index = 0 ;
    this->nb_available = this->nb_available + 1 ;
    return 1 ;
}
////////////////////////////////////////////
char Fifo::read_char(char * token){
    if(this->nb_available == 0) return 0;
    *token = this->data[this->read_index]  ;
    this->read_index = this->read_index + 1;
    if(this->read_index >= this->fifo_size) this->read_index = 0 ;
    this->nb_available = this->nb_available -1 ;
    return 1 ;
}
////////////////////////////////////////////
int Fifo::get_nb_available() {
#ifdef DEBUGFIFO
    cout <<" get_nb_available() a été invoquée"<<endl;
#endif
    return  this->nb_available;
}
fifoavecreinit.h
#ifndef FIFOAVECREINIT_H
#define FIFOAVECREINIT_H
#include "fifo.h"
class FifoAvecReinit : public Fifo
{
public:
    FifoAvecReinit();
    void reinit();
};
 
#endif // FIFOAVECREINIT_H
fifoavecreinit.cpp
#include "fifoavecreinit.h"
#include <iostream>
using namespace std;
////////////////////////////////////////////
FifoAvecReinit::FifoAvecReinit()
{
    cout << "construction d'une fifoAvecReinit" << endl;
}
////////////////////////////////////////////
void FifoAvecReinit::reinit()
{
    this->nb_available=0;
    this->read_index=0;
    this->write_index=0;
}
main.cpp
#include <stdio.h>
 
#include <iostream>
using namespace std;
 
#include "fifo.h"
 
#include "fifoavecreinit.h"
 
Fifo fifo1(3); //initialisation de la FIFO
// init_char_fifo(&myFifo, FifoBuffer,  FIFO_SIZE1);
 
 
//////////////////////////////////////////////////
int main(int argc, char *argv[])
{
 
    printf("salut les APP\r\n");
    cout << "Hello World!" << endl;
 
 
    Fifo * ptr_fifo5;
 
    ptr_fifo5=new Fifo(100000000);
    ptr_fifo5->write_char(1);
    ptr_fifo5->write_char(2);
    ptr_fifo5->write_char(3);
    delete(ptr_fifo5);
 
 
 
    Fifo * tab_ptr_fifo[100];
    for (int i=0;i<100;i++)
        tab_ptr_fifo[i]=new Fifo(1000);
 
    tab_ptr_fifo[12]->write_char(6);
 
 
    //init_char_fifo(&myFifo, (char*)4,3);
 
    char lu;
 
    //fifo1.nb_available=8; //interdit grace à l'encapsulation
    fifo1.read_char(&lu);
    fifo1.write_char(5);
    fifo1.write_char(8);
    fifo1.read_char(&lu);
    fifo1.write_char(12);
    fifo1.write_char(1);
 
    cout << "données disponibles dans la fifo: " << +fifo1.get_nb_available() << endl;
 
 
    fifo1.write_char(7);
    fifo1.read_char(&lu);
    fifo1.read_char(&lu);
    fifo1.read_char(&lu);
    fifo1.read_char(&lu);
 
/*
    Fifo fifo2(20); //une autre FIFO, de taille 20, qui n'est pas la taille par défaut
    fifo2.write_char('3');
    cout << "Il y a " <<  fifo2.get_nb_available()  <<" données dans la fifo 3" << endl;
    cout << "entrer 3 valeurs à ranger dans la fifo" <<endl;
    cin >> fifo2;
    cin >> fifo2;
    cin >> fifo2;
 
    cout << "Il y a " <<  fifo2.get_nb_available()  <<" données dans la fifo 3" << endl;
    cout << fifo2 << " " << fifo2 <<  " " << fifo2 << " " << fifo2 << " " << fifo2 <<   endl;
*/
 
 
    FifoAvecReinit fifo3;
    fifo3.write_char(1);
    fifo3.write_char(2);
    fifo3.write_char(3);
    fifo3.write_char(4);
    fifo3.read_char(&lu);
    fifo3.reinit();
    fifo3.read_char(&lu);
 
 
 
 
 
    /*write_char_fifo(5);
    write_char_fifo(1);
    write_char_fifo(7);*/
  /*  for (int i=0;i<10;i++)
        if (write_char_fifo(i)==0)
           cout << "fifo pleine "<< endl;
 
    for (int i=0;i<10;i++){
        //rien n'empêche un utilisateur d'écrire
        //nb_available=5; //grosse bétise!
 
        char c;
        if (read_char_fifo(&c)!=0)
            cout << "donnée lue dans la fifo: " << +c << endl;
        else
            cout << "fifo vide "<< endl;
    }
 
 
    data[2]=5 ;
 
    *(data+2)=6;
*/
    printf("fin\r\n");
}

Procédure d'installation de QTcreator 5

télécharger et lancer l'installer: http://mirrors.ukfast.co.uk/sites/qt.io/archive/online_installers/3.2/qt-unified-windows-x86-3.2.2-online.exe

La version 5.14.1 n'est plus disponible, choisir la 5.14.2 et bien cocher MinGW 7.3.0 64bits:

Wireshark pour Windows 10

Télécharger les 2 fichiers suivants:

Wireshark: https://bvdp.inetdoc.net/files/iut/td_fifo/install_qt5_windows/WiresharkPortable_3.2.2.paf.exe

WinPcap: https://bvdp.inetdoc.net/files/iut/td_fifo/install_qt5_windows/WinPcap_4_1_3.exe

Puis suivre les étapes “méthodes 1 et 2” de: https://www.outlookappins.com/windows-10/wireshark-no-interfaces-found/

Récupération des sources pour compiler les applications de démo

https://bvdp.inetdoc.net/files/iut/td_fifo/install_qt5_windows/sources-pour-binaire.zip

Editer les 2 fichiers .bat pour modifier le PATH afin qu'il indique le dossier ou vous avez installé QT.

Effacer les fichiers portant l'extension .pro.users… avant d'ouvrir qtcreator en double cliquant sur le fichier portant l'extension .pro