2Fermer4
squalylLe 20/02/2017 à 15:15
Godzil: le probleme c'est que le protocole TI ne gère pas le broadcast, donc faut bitbanger un protocole a la main (ils l'ont fait sur cemetech)


fais un truc genre HDLC (half duplex chais plus quoi)

un octet sépare les trames (en général 0x7E)

et la présence de 0x7E dans un paquet est échappée par 0x7D 0x5E

la présence d'escape est elle même escapée par 0x7D 0x5D

ca peut être géré au moment de l'envoi/réception d'un caractère.

L'avantage c'est que c'est auto-sychronisant contrairement a header/len/payload

si tu tombes au milieu, tu jettes tous les octets jusqu'a recevoir 7E et paf t'as le début de la trame. La longueur devient également implicite.

Le dernier octet transmis peut être un checksum

en gros
enum {packet_pending, packet_done, protocol_error}
enum {waitsync,start,receiving,escape}
char state
char checksum
void receive(char input)
si state == waitsync:
  si input = 7E : start->state
  else: return

si state == start:
  si input != 7E : receiving->state, INIT_VALUE->checksum goto rx
  else: return packet_pending

rx:
si state == receiving:
  si input = 7D: escape ->state
  si input = 7E: if CHECKSUM_OK: return packet_done else: return protocol_error
  sinon: if len<maxlen: input->buf[len++], UPDATE_CHECKSUM, else: rx overflow

si state == escape:
  receiving->state
  if input == 5E or 5D: input == input xor 0x20, if len<maxlen: input->buf[len++], UPDATE_CHECKSUM, else: rx overflow
  else: waitsync->state, return protocol_error

Déja utilisé des tonnes de fois ici.

chaque station écoute tout, donc un seul peut effectivement parler a la fois.
la dedans tu peux définir que le premier octet est l'adresse de la machine (par ex 00h = broadcast) comme ca tu peux adresser un paquet a une seule machine.

l'émission est triviale, je te la laisse en exercice.

autre avantage, le buffer n'a besoin que de stocker la payload, mais les octets de départ/escape ne le sont jamais.

je te laissse digérer grin