Bus I2C linux
Répondre à la discussion
Affichage des résultats 1 à 11 sur 11

Bus I2C linux



  1. #1
    sandrecarpe

    Bus I2C linux


    ------

    Bonjour à tous,

    J'ai un programme C++ sur Raspberry chargé de communiquer avec un pic en I2C pour récupérer des données issues de capteurs.
    J'ai un thread qui lance périodiquement (toutes les quelques secondes) une requête pour communiquer avec le PIC.
    Dans un second thread, je lance une autre requête I2C, au même esclave, mais 2 fois par jour.

    Que se passe t-il si les deux requêtes sont demandées en même temps ? Est-ce que Linux met une des requêtes en file d'attente ou est-ce qu'une erreur est levée ? Je dois gérer ça par soft ?

    Merci pour vos réponses !

    -----
    Dernière modification par sandrecarpe ; 22/09/2018 à 12h38.

  2. #2
    Jack
    Modérateur

    Re : Bus I2C linux

    Accès concurrent à des ressources communes => mutex.

    De toutes manières, testes-tu la réussite de l'ouverture du fichier permettant l'accès à l'I2C? Parce qu'à mon avis, tant que le fichier est ouvert par un thread, il ne doit pas être possible de l'ouvrir dans l'autre.

  3. #3
    sandrecarpe

    Re : Bus I2C linux

    Bien sûr ! Je ne sais pas pourquoi je n'y avais pas pensé alors que je le fais déjà pour communiquer avec l'autre esclave...
    Mais du coup, deux threads peuvent t-ils communiquer sans problème sur le bus I2C à deux esclaves différents ?
    Autrement dit, j'ai deux "file descriptor" : un pour communiquer à chaque esclave sur le bus I2C. Y a t-il partage des ressources ?
    D'un côté, je dirais oui parce que c'est le même bus. Mais d'un autre, je dirais non parce que ce n'est pas le même "file descriptor"

  4. #4
    Jack
    Modérateur

    Re : Bus I2C linux

    Le file descriptor doit être attaché à une seule ressource matérielle. A mon avis, le système devrait te "jeter" si tu essaies d'en attacher un autre.

    Les 2 thread doivent donc pouvoir communiquer avec le même bus et le même file descriptor, mais pas en même temps. La section critique doit donc correspondre aux moments où tu va envoyer et recevoir les trames. A ta place je la protègerais par un mutex.

    Quelle librairie utilises-tu pour gérer l'I2C?

  5. A voir en vidéo sur Futura
  6. #5
    sandrecarpe

    Re : Bus I2C linux

    Ok merci pour les informations, je vais protéger tout ça pour des mutex

    J'utilise WiringPi pour gérer l'I2C

  7. #6
    sandrecarpe

    Re : Bus I2C linux

    Apparemment il est tout à fait possible d'avoir deux file descriptor qui pointent sur la même ressource :
    https://stackoverflow.com/questions/...-the-same-file

  8. #7
    Jack
    Modérateur

    Re : Bus I2C linux

    Il faudrait essayer avec un bus I2C au lieu d'un fichier disque.
    Quoiqu'il en soit, ça ne coûte rien de verrouiller l'accès avec un mutex

  9. #8
    Jack
    Modérateur

    Re : Bus I2C linux

    Citation Envoyé par sandrecarpe Voir le message
    J'utilise WiringPi pour gérer l'I2C
    Je trouve que la librairie pigpio et meilleure que wiringpi, en particulier pour la gestion de l'I2C car elle permet de gérer plus finement l'I2C et surtout de transférer des blocs de données.

  10. #9
    sandrecarpe

    Re : Bus I2C linux

    Je connaissais pas, merci pour l'info, je vais regarder ça de près !

  11. #10
    sandrecarpe

    Re : Bus I2C linux

    J'ai fais un premier test avec mon seul esclave :

    Code:
    #include "LcdDisplay.h"
    
    
    LcdDisplay::LcdDisplay(unsigned char szAddres) : _backlightEtat(true)
    {
    	m_szAddres = szAddres;
    	m_isDeviceInitialized = false;
    }
    
    LcdDisplay::~LcdDisplay()
    {
    
    }
    
    void LcdDisplay::init()
    {
    	std::lock_guard<std::mutex> lock(_mutex);
    
    }
    
    void LcdDisplay::cls()
    {
    	std::lock_guard<std::mutex> lock(_mutex);
    }
    
    //---------------------------------------------------
    /**
      * displayStringAtPosition : display a string at the given position
      *
      * @param pData is the pointer the data to write
      * @param szLine is the line number
      * @param szCol is the colum number
      *
    */
    //---------------------------------------------------
    
    void LcdDisplay::setBacklight(const bool etat)
    {
    	std::lock_guard<std::mutex> lock(_mutex);
    
    }
    
    bool LcdDisplay::getBacklight()
    {
    	return _backlightEtat;
    }
    
    
    
    void LcdDisplay::displayStringAtPosition(const char* pData, char szLine, char szCol)
    {
    	std::lock_guard<std::mutex> lock(_mutex);
    
    	
    }
    
    //---------------------------------------------------
    /**
      * setCursorAtPosition : setCursor
      *
      * @param szLine is the line number
      * @param szCol is the colum number
      * @param isVisible if true, enable the cursor
      * @param isBlinking if true, enable cursor blinking
      *
    */
    //---------------------------------------------------
    void LcdDisplay::setCursorAtPosition(char szLine, char szCol,bool isVisible, bool isBlinking)
    {
    	std::lock_guard<std::mutex> lock(_mutex);
    }
    
    void LcdDisplay::createChar(const unsigned char pattern[8], unsigned char adresse)
    {
    	std::lock_guard<std::mutex> lock(_mutex);
    }
    
    
    //************* PRIVATE SECTION *************************
    //**************LOW LEVEL FUNCTION **********************
    
    //---------------------------------------------------
    /**
      * write : write a command to lcd
      *
      * @param szData is the command/data to write
      * @param szMode is the mode
      *
    */
    //---------------------------------------------------
    void LcdDisplay::write(char szData, char szMode)
    {
    
    }
    
    void LcdDisplay::writeNibble(char szData){
    
    }
    
    void LcdDisplay::strobe(char szData){
    
    }
    
    
    void LcdDisplay::setLinePosition(char szLine)
    {
    
    }
    void LcdDisplay::displayString(const char* pData)
    {
    
    }
    
    //---------------------------------------------------
    /**
      * writei2c : write at low level
      *
      * @param szData is the data to write
      *
    */
    void LcdDisplay::writei2c(unsigned char szData)
    {
    		
    	int nRes = wiringPiI2CWrite(m_nDeviceFD,szData);
    }
    Comme vous pouvez voir, il s'agit d'un écran LCD. Le problème est que lorsque qu'on utilise une instance de cette classe, il ne faut pas que l'enchainement de deux méthodes soit interrompu par un autre thread, sinon l'affichage des données sur l'écran se fait n'importe comment. Du coup j'ai du mettre les mutex en dehors de la classe pour avoir un bon comportement, chose que je ne trouve vraiment pas terrible !

  12. #11
    Jack
    Modérateur

    Re : Bus I2C linux

    De toutes manières, le mutex étant commun à tous les thread, tu n'as pas intérêt à le déclarer dans la classe LcdDisplay.

Discussions similaires

  1. linux 64 ou 32
    Par invitee75a2d43 dans le forum Logiciel - Software - Open Source
    Réponses: 6
    Dernier message: 23/04/2012, 19h35
  2. linux cmd
    Par invite97743677 dans le forum Logiciel - Software - Open Source
    Réponses: 3
    Dernier message: 19/02/2009, 08h26
  3. Linux et USB
    Par invitef2671992 dans le forum Logiciel - Software - Open Source
    Réponses: 3
    Dernier message: 20/01/2006, 16h27
  4. Linux
    Par invitef2671992 dans le forum Logiciel - Software - Open Source
    Réponses: 10
    Dernier message: 22/08/2005, 16h04
  5. Linux > Windows ou Windows > Linux et la pomme dans to
    Par invite37693cfc dans le forum Logiciel - Software - Open Source
    Réponses: 4
    Dernier message: 09/05/2003, 11h35