Question

J'écris une application qui utilise openNetcf.io.serial (open source, Voir le code de série ici) pour sa communication en série sur un appareil Windows CE 6.0. Cette application est codée en C # dans le Framework compact 2.0. Je ne crois pas que le problème que je suis sur le point de décrire est spécifiquement lié à ces détails, mais je peux être prouvé comme étant faux à cet égard.

Le problème que j'ai, c'est que, apparemment Au hasard (lire comme: problème intermittent que je ne peux pas encore dupliquer de manière fiable), les données ne parviendront pas à transmettre ou à être reçues jusqu'à ce que le périphérique lui-même soit redémarré. Le périphérique Windows CE communique avec un système qui exécute une application entièrement différente. Le redémarrage de ce autre système et la déconnexion / reconnexion des câbles de communication ne semblent pas résoudre ce problème, redémarrant uniquement le périphérique Windows CE.

Le seul signe de ce problème qui se produit est l'absence d'un événement TxDone à partir de la mise à feu OpenNETCF (recherchez "TxDone ();" dans OpenNetCF.io.Serial Class), et aucune donnée n'est reçue, quand je sais pertinemment que la connexion est connectée Le système envoie des données.

Toute valeur de caractère de 1 à 255 (0x01 - 0xff) peut être envoyée et reçu dans notre communication série. Les valeurs nulles sont jetées.

Mes paramètres série sont 38400 bauds, 8 bits de données, pas de parité, 1 bit d'arrêt (38400, 8n1). J'ai défini les tailles de tampon d'entrée et de sortie sur 256 octets. L'événement de données se produit chaque fois que nous recevons 1 ou plusieurs caractères, et la transmission se produit lorsqu'il y a 1 ou plus d'octets dans le tampon de sortie, car les messages sont de longueur variable.

Aucune étouffement n'est utilisé. Comme il s'agit de RS422, seuls 4 signaux sont utilisés: Rx +, Rx-, Tx +, Tx-.

Je reçois un événement "DataReceived", je lis toutes les données du tampon d'entrée et fais mon propre tampon dans mon code pour l'analyser à travers mon guide en dehors de l'événement DataCeceived. Lorsque je reçois un message de commande, j'enverrai un message de reconnaissance rapide. Lorsque l'autre système reçoit un message de commande du périphérique Windows CE, il renverra un message d'accusé de réception rapide. Les messages de reconnaissance n'obtiennent aucune autre réponse car ils sont destinés à un simple "oui, je l'ai obtenu". Dans mon code, je reçois / transmet à travers plusieurs threads, donc j'utilise le mot clé de verrouillage, donc je ne transmets pas plusieurs messages simultanément sur plusieurs threads. La double vérification via le code a montré que je ne suis pas raccroché aux verrous.

À ce stade, je me demande si je manque en permanence quelque chose d'évident sur le fonctionnement de la communication en série, comme si je dois définir une variable ou une propriété, plutôt que de simplement lire à partir d'un tampon d'entrée lorsqu'il n'est pas vide et d'écrire dans un tampon de transmission.

Toutes les informations, les options à vérifier, les suggestions, les idées, etc. sont les bienvenues. C'est quelque chose avec lequel je lutte par moi-même depuis des mois, j'espère que les réponses ou les commentaires que je reçois ici peuvent aider à déterminer ce problème. Merci en avance.

Edit, 24/02/2011:
(1) Je ne peux que sembler recréer l'erreur sur le démarrage du système avec lequel le périphérique Windows CE communique, et pas chaque démarrage. J'ai également regardé les signaux, la tension de mode commune fluctue, mais l'amplitude du bruit qui se produit au démarrage du système ne semble pas lié si le problème se produit ou non, j'ai vu 25 V pic à crête ne pas problème, lorsque le pic de 5V -PECT le problème réapparu).
Le problème continue de sonner de plus en plus de matériel, mais j'essaie de comprendre ce qui peut provoquer les symptômes que je vois, car aucun matériel ne semble réellement échouer ou s'arrêter, du moins où j'ai pu atteindre pour Mesurer les signaux. Mes excuses, mais je ne pourrai pas donner de nombres de pièces de matériel, alors ne demandez pas aux composants utilisés.

(2) Selon la suggestion de @ ctacke, j'ai assuré que tous les transmits passaient par le même emplacement pour la maintenabilité, la sécurité du fil que je mets est essentiellement comme suit:

lock(transmitLockObj)
{
    try
    {
        comPort.Output = data;
    }
    [various catches and error handling for each]
}

(3) Obtenir des erreurs de dépassement UART, dans un test où <10 octets ont été envoyés et reçus sur un intervalle de temps d'environ 300 msc à 38400 bauds. Une fois qu'il a obtenu une erreur, il passe à l'itération de la boucle suivante et n'exécute pas ReadFile, et n'exécute pas l'événement TXDone (ou toute autre procédure de vérification de ligne). De plus, non seulement la fermeture et la réouverture du port ne font rien pour résoudre ce problème, mais redémarrer le logiciel alors que l'appareil est toujours en cours d'exécution non plus. Seul un redémarrage matériel.

Mon événement de données est le suivant:

try
{
    byte[] input = comPort.Input; //set so Input gets FULL RX buffer

    lock(bufferLockObj)
    {
        for (int i = 0; i < input.Length; i++)
        {
            _rxRawBuffer.Enqueue(input[i]);
            //timer regularly checks this buffer and parses data elsewhere
            //there, it is "lock(bufferLockObj){dataByte = _rxRawBuffer.Dequeue();}"
            //so wait is kept short in DataReceived, while remaining safe
        }
    }
}
catch (Exception exc)
{
    //[exception logging and handling]
    //hasn't gotten here, so no point in showing
}

Cependant, instantanément après l'appel de WriteFile a chronométré la première fois du test, c'était lorsque j'ai commencé à obtenir des erreurs de dépassement UART. Honnêtement, je ne vois pas mon code provoquer une condition de dépassement UART.

Les pensées? Matériel ou logiciel lié, je vérifie tout ce que je peux penser pour vérifier.

Pas de solution correcte

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top