2017-02-13 6 views
10

Je suis en train de lire un registre à partir d'un adaptateur RS485 en utilisant une connexion UART sur une carte ARM sans succèsARM: la lecture des données modbus par UART échoue

Machines

Connecteurs

dispositif esclave connecté au bord ARM

puissance Compteur d'énergie < --rx/tx câble -> SENA Adaptateur RS485 < --serial mâle/adaptateur mâle + série de mini-câble série -> ARM carte mini-port série

voir les images de la configuration:

arbre de l'appareil utilisé: am335x-sbc-t335.dts

ressources forestières de l'appareil:http://get-album.com/dts/

dispositif esclave connecté au PC

puissance Compteur d'énergie < --2 fil rx/tx -> SENA Adaptateur RS485 < -> PC

Note: Le port mini-série sur la carte est le même port qui est utilisé pour la communication série-console (sur baud 115200) - et cela fonctionne sans problème

ci-dessous est un code alternatif qui lit le premier registre du dispositif esclave connecté à l'utilisation de la bibliothèque de libmodbus

libmodbus_test.c - la lecture et l'impression de la première reigster du dispositif:

#include <sys/types.h> 
#include <string.h> 
#include <modbus.h> 
#include <stdlib.h> 
#include <stdio.h> 
#include <errno.h> 

#define MODBUS_DEVICE "/dev/ttyS2" 
#define MODBUS_STOP_BIT 1 
#define MODBUS_DATA_BIT 8 
#define MODBUS_START_BIT 1 
#define MODBUS_PARITY 'N' 

int main(int argc, char *argv[]) { 

    const char *dev_path = MODBUS_DEVICE; 
    uint16_t result[2]; 
    int slave_nr = 31, baud = 9600; 
    modbus_t *mb; 

    if (argc == 2) { 
     dev_path=argv[1]; 
    } 

    mb = modbus_new_rtu(dev_path, baud, MODBUS_PARITY, MODBUS_DATA_BIT, MODBUS_STOP_BIT); 
    if (mb == NULL) { 
     printf("error creating libmodbus rtu\n"); 
     return -1; 
    } 
    printf("created new rtu...\n"); 
    modbus_set_debug(mb, 1); 
    if (modbus_connect(mb) < 0){ 
     printf("modbus error: %s\n", modbus_strerror(errno)); 
     modbus_close(mb); 
     modbus_free(mb); 
     return -1; 
    } 

    modbus_set_slave(mb, slave_nr); 

    printf("ModBus connected !\n"); 

    if (modbus_read_registers(mb, 0x1, 2, result) < 0) { 
     printf("error reading bits: %s\n", modbus_strerror(errno)); 
     modbus_close(mb); 
     modbus_free(mb); 
     return -1; 
    } 

    printf("successfully red integer: %d: %X (hex)\n", result[0], result[0]); 

    modbus_free(mb); 
    return 0; 
} 

[sortie de l'exécution libmodbus_test sur PC]

[email protected]:~/new# modbus gcc -I /usr/local/include/modbus libmodbus_test.c -o libmodbus_test -lmodbus 
[email protected]:~/new# ./libmodbus_test /dev/ttyS2 
created new rtu... 
Opening /dev/ttyS2 at 9600 bauds (N, 8, 1) 
ModBus connected ! 
[1F][03][00][01][00][02][96][75] 
Waiting for a confirmation... 
<1F><03><04><00><DD><00><DD><54><51> 
successfully red integer: 221: DD (hex) 

[sortie de l'exécution libmodbus_test sur la carte ARM]

[email protected]:~/new# gcc -I /usr/include/modbus/ libmodbus_test.c -o libmodbus_test -lmodbus 
[email protected]:~/new# ./libmodbus_test /dev/ttyO0 
created new rtu... 
Opening /dev/ttyO0 at 9600 bauds (N, 8, 1) 
ModBus connected ! 
[1F][03][00][01][00][02][96][75] 
Waiting for a confirmation... 
ERROR Connection timed out: select 

lors de l'exécution de libmodbus_test à partir de la carte ARM, select() renvoie toujours 0 lors de l'exécution du même programme sur PC, cela fonctionne très bien => l'appareil esclave renvoie des données.

Une tentative en utilisant termios a également échoué avec des résultats similaires

de termios_test.c

#include <sys/select.h> 
#include <termios.h> 
#include <stdio.h> 
#include <fcntl.h> 
#include <unistd.h> 
#include <sys/time.h> 
#include <sys/types.h> 
#include <string.h> 
#include <stdint.h> 
#include <linux/serial.h> 
#include <sys/ioctl.h> 

static const uint8_t table_crc_hi[] = { 
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 
    0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 
    0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 
    0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 
    0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 
    0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 
    0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 
    0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 
    0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 
    0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 
    0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 
    0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 
    0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 
    0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 
    0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 
    0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 
    0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 
    0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 
    0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 
    0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 
}; 


/* Table of CRC values for low-order byte */ 
static const uint8_t table_crc_lo[] = { 
    0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 
    0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 
    0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 
    0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 
    0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4, 
    0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3, 
    0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 
    0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 
    0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 
    0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, 
    0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED, 
    0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26, 
    0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 
    0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 
    0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 
    0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, 
    0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E, 
    0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5, 
    0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 
    0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 
    0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, 
    0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, 
    0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B, 
    0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C, 
    0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 
    0x43, 0x83, 0x41, 0x81, 0x80, 0x40 
}; 


void calc_crc(uint8_t *buffer, ssize_t length, uint8_t *crc_hi_arg, uint8_t *crc_lo_arg) { 

    uint8_t crc_hi = 0xff; 
    uint8_t crc_lo = 0xff; 
    unsigned int i; 

    while (length--) { 
     i = crc_hi^*buffer++; 
     crc_hi = crc_lo^table_crc_hi[i]; 
     crc_lo = table_crc_lo[i]; 
    } 

    *crc_hi_arg = crc_hi; 
    *crc_lo_arg = crc_lo; 

} 

int main(int argc, char **argv){ 

    char *dev_path = "/dev/ttyS2"; 
    if (argc == 2) { 
     dev_path = argv[1]; 
    } 
    uint8_t write_data[8]; 
    int fd,write_len,select_ret, bytes_avail, status; 
    struct termios config; 
    char c; 
    uint8_t crc_hi, crc_lo; 
    fd_set activefs, tmpfs;; 
    struct timeval timeout; 

    timeout.tv_sec = 0; 
    timeout.tv_usec= 500000; 

    fd = open(dev_path, O_RDWR | O_NOCTTY | O_NDELAY | O_EXCL); 

    if (fd == -1){ 
     perror("open"); 
     return 1; 
    } 

    FD_ZERO(&tmpfs); 
    FD_SET(fd, &tmpfs); 

    printf("opened device\n"); 
    if (tcgetattr(fd, &config) < 0) { close(fd); return -1 } 

    if (cfsetispeed(&config, B9600) < 0 || cfsetospeed(&config, B9600) < 0) { 
     printf("cant setting speed!\n"); 
     close(fd); 
     return 1; 
    } 


    config.c_cflag |= (CREAD | CLOCAL); 
    config.c_cflag &=~ CSIZE; 
    config.c_cflag &=~ CSTOPB; 
    config.c_cflag &=~ PARENB; 
    config.c_cflag |= CS8; 

    config.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); 

    config.c_iflag &= ~INPCK; 
    config.c_iflag &= ~(IXON | IXOFF| IXANY); 

    config.c_oflag &= ~OPOST; 


    config.c_cc[VMIN] = 0; 
    config.c_cc[VTIME] = 0; 

    if (tcsetattr(fd, TCSANOW, &config) < 0) { 
     printf("cant apply config!\n"); 
     close(fd); 
     return 1; 
    } 


    write_data[0] = 0x1f; // slave addr 
    write_data[1] = 0x03; // function 
    write_data[2] = 0x00; // data address of first coil (8b) 
    write_data[3] = 0x01; // data address of first coil (8b) 
    write_data[4] = 0x00; // num of coils requested 
    write_data[5] = 0x01; // num of coils requested 
    calc_crc(write_data, 6, &crc_hi, &crc_lo); 
    write_data[6] = crc_hi; 
    write_data[7] = crc_lo; 

    printf("data: [0x%x][0x%x][0x%x][0x%x][0x%x][0x%x][0x%x][0x%x]", write_data[0], write_data[1], write_data[2], write_data[3], write_data[4], write_data[5], write_data[6], write_data[7]); 

    while (1) { 

     sleep(1); 
     write_len= write(fd, write_data, 8); 
     activefs = tmpfs; 
     select_ret = select(1, &activefs, NULL, NULL, &timeout); 
     if (select_ret < 0) { 
      perror("select"); 
      return 1; 
     } 

     if (select_ret > 0) { 
      printf("select returned %d\n", select_ret); 
      if (read(fd, &c, 1) < 0) { 
       perror("read"); 
      } else { 
       printf("received: %d\n", c); 
      } 
     } 

    } 


} 

[de sortie de termios.c sur la carte ARM]

[email protected]:~/new# ./termios /dev/ttyO0 
opened device 

... select continue de revenir 0

[Sortie termios.c sur PC]

$ gcc -o termios_test termios_test.c 
$ ./termios_test /dev/ttyS2 
opened device 
data: [0x1f][0x3][0x0][0x1][0x0][0x1][0xd6][0x74]select returned 1 
received: 31 
select returned 1 

Peu importe les valeurs, il y a un échange de données et c'est ce que je veux réaliser en utilisant la carte

J'ai essayé attributs passer RS485 via pcntl, mais le mêmes résultats se sont passées termios_rs485_test.c: http://pastebin.com/RWtHtjLF

la connexion entre la carte et le PC se fait par l'ultra mini-série au câble DB9 et je peux lire avec succès les données/écriture depuis et vers le conseil d'administration. Comment se fait-il que la lecture des données de l'adaptateur RS485 ne réussisse jamais? Où devrais-je chercher afin de me rapprocher d'une solution?

Voici quelques informations au sujet du conseil/drivers/etc

[email protected]:~/modbus# uname -a 
Linux cm-debian 4.4.0-cm-t335-5.1 #98 SMP Thu Sep 1 15:12:31 IDT 2016 armv7l GNU/Linux 

[email protected]:~/new# dmesg | grep -i --color '\(serial\|tty\|uart\)' 
[ 0.000000] Kernel command line: console=ttyO0,115200n8 root=ubi0:rootfs rw rootfstype=ubifs ubi.mtd=rootfs 
[ 0.771007] Serial: 8250/16550 driver, 4 ports, IRQ sharing enabled 
[ 0.780286] omap_uart 44e09000.serial: no wakeirq for uart0 
[ 0.780329] of_get_named_gpiod_flags: can't parse 'rts-gpio' property of node '/ocp/[email protected][0]' 
[ 0.780960] 44e09000.serial: ttyO0 at MMIO 0x44e09000 (irq = 155, base_baud = 3000000) is a OMAP UART0 
[ 1.543031] console [ttyO0] enabled 
[ 1.550036] omap_uart 48022000.serial: no wakeirq for uart1 
[ 1.556099] of_get_named_gpiod_flags: can't parse 'rts-gpio' property of node '/ocp/[email protected][0]' 
[ 1.556764] 48022000.serial: ttyO1 at MMIO 0x48022000 (irq = 156, base_baud = 3000000) is a OMAP UART1 
[ 2.953486] usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1 
[ 2.973176] usb usb1: SerialNumber: musb-hdrc.0.auto 
[ 3.572722] usb 1-1: New USB device strings: Mfr=0, Product=0, SerialNumber=0 
[ 6.689030] systemd[1]: Expecting device dev-ttyO0.device... 
[ 7.210727] systemd[1]: Starting system-getty.slice. 
[ 7.235407] systemd[1]: Created slice system-getty.slice. 
[ 7.241302] systemd[1]: Starting system-serial\x2dgetty.slice. 
[ 7.265277] systemd[1]: Created slice system-serial\x2dgetty.slice. 
[ 7.925632] systemd[1]: Starting LSB: controls configuration of serial ports... 
[ 8.485680] systemd[1]: Started LSB: controls configuration of serial ports. 
[ 14.840532] pinctrl-single 44e10800.pinmux: pin 44e10978.0 already requested by 48022000.serial; cannot claim for 481cc000.can 
[ 14.895866] pinctrl-single 44e10800.pinmux: pin 44e10980.0 already requested by 48022000.serial; cannot claim for 481d0000.can 


[email protected]:~/modbus# setserial -a /dev/ttyO0 
/dev/ttyO0, Line 0, UART: undefined, Port: 0x0000, IRQ: 155 
     Baud_base: 3000000, close_delay: 50, divisor: 0 
     closing_wait: 3000 
     Flags: spd_normal 

[email protected]:~/new# setserial -a /dev/ttyS2 
/dev/ttyS2, Line 2, UART: unknown, Port: 0x0000, IRQ: 0 
     Baud_base: 0, close_delay: 50, divisor: 0 
     closing_wait: 3000 
     Flags: spd_normal 

[email protected]:~/new# setserial -a /dev/ttyS1 
/dev/ttyS1, Line 1, UART: unknown, Port: 0x0000, IRQ: 0 
     Baud_base: 0, close_delay: 50, divisor: 0 
     closing_wait: 3000 
     Flags: spd_normal 

[email protected]:~/new# setserial -a /dev/ttyS0 
/dev/ttyS0, Line 0, UART: unknown, Port: 0x0000, IRQ: 0 
     Baud_base: 0, close_delay: 50, divisor: 0 
     closing_wait: 3000 
     Flags: spd_normal 


[email protected]:~/modbus# lsmod 
Module     Size Used by 
sha256_generic   9731 1 
hmac     2866 1 
drbg     13731 1 
ctr      3673 2 
ccm      7928 2 
arc4     2000 2 
wl12xx     57190 0 
wlcore    180594 1 wl12xx 
mac80211    605465 2 wl12xx,wlcore 
cfg80211    492985 2 mac80211,wlcore 
snd_soc_davinci_mcasp 15953 2 
snd_soc_tlv320aic23_i2c  2092 1 
snd_soc_simple_card  7474 0 
snd_soc_tlv320aic23 10191 1 snd_soc_tlv320aic23_i2c 
snd_soc_edma   1309 1 snd_soc_davinci_mcasp 
snd_soc_core   158330 5 snd_soc_davinci_mcasp,snd_soc_edma,snd_soc_tlv320aic23_i2c,snd_soc_tlv320aic23,snd_soc_simple_card 
snd_pcm_dmaengine  5548 1 snd_soc_core 
snd_pcm    92743 4 snd_soc_davinci_mcasp,snd_soc_core,snd_soc_tlv320aic23,snd_pcm_dmaengine 
c_can_platform   6650 0 
c_can     9638 1 c_can_platform 
wlcore_spi    5086 0 
can_dev    12315 1 c_can 
ti_am335x_adc   5635 0 
snd_timer    21413 1 snd_pcm 
kfifo_buf    3452 1 ti_am335x_adc 
snd     55936 3 snd_soc_core,snd_timer,snd_pcm 
industrialio   40286 2 ti_am335x_adc,kfifo_buf 
evdev     13187 0 
omap_wdt    5293 0 
soundcore    1339 1 snd 


[email protected]:~/new# cat /proc/cpuinfo 
processor  : 0 
model name  : ARMv7 Processor rev 2 (v7l) 
BogoMIPS  : 597.60 
Features  : half thumb fastmult vfp edsp thumbee neon vfpv3 tls vfpd32 
CPU implementer : 0x41 
CPU architecture: 7 
CPU variant  : 0x3 
CPU part  : 0xc08 
CPU revision : 2 

Hardware  : Generic AM33XX (Flattened Device Tree) 
Revision  : 0000 
Serial   : 0000000000000000 

[email protected]:~/new# cat /proc/consoles 
ttyO0    -W- (EC p ) 250:0 

[email protected]:/etc# cat debian_version 
8.2 

Toute aide est très appréciée Merci

MISE À JOUR

Alors que le ultra mini-série au câble DB9 est connecté au tableau, j'ai couru termios_test.c et en courant, j'ai inséré un morceau de métal dans la broche du milieu du câble (le TX) et je pouvais voir les données de déchets affichées sur l'écran (parfois !). J'ai branché l'adaptateur mâle-mâle sur le câble et j'ai de nouveau touché la broche du milieu, et j'ai pu voir à nouveau les données d'ordures.

Une autre chose que j'ai fait est de connecter l'appareil esclave à l'adaptateur SENA RS485, et utiliser la pièce métallique sur les broches, la broche du milieu de l'adaptateur, lorsque le métal touche, allume la led TX. aucune broche n'allume la led RX. Lors de la connexion de cet adaptateur RS485 au port COM du PC, l'envoi de données à ce port ferait clignoter le voyant RX. Je commence à soupçonner que la carte n'écrit pas correctement sur l'adaptateur RS485 ou que les broches ne sont pas correctement mappées. Où devrais-je aller d'ici? cela pourrait-il vraiment être un problème logiciel?

+1

Il semble que systemd lance également getty sur/dev/ttyO0. Et il y a des paramètres du noyau qui utilisent ttyO0 comme console du noyau. Essayez de vous débarrasser de cette configuration – nos

+0

Supprimé/dev/ttyO0 de bootargs mais cela n'a pas fonctionné non plus, mêmes résultats – Smokie

+2

Pouvez-vous pointer vers un fichier d'arborescence de périphérique en cours d'utilisation? Il semble que vous ayez «CAN» en cours d'exécution sur la carte ARM (je suppose pas sur le PC) et ces différents protocoles peuvent prétendre à l'UART. Un test de base est de connecter un câble de bouclage (ou de se connecter directement à un PC avec cross over) et d'exécuter mini-com, etc juste pour voir que vous pouvez utiliser ce port. Avez-vous fait cela? Ceci élimine tout problème avec votre code, les tensions avec les périphériques, la configuration linux/init, etc. Diviser et conquérir est toujours bon. Il y a beaucoup de couches où les choses peuvent mal tourner, alors les gens ne peuvent que deviner. –

Répondre

7

Deux problèmes logiciels se trouvent dans termios_test.c.Le premier numéro était lié à tcgetattr() manqué. Le second est ce que le premier paramètre à sélectionner() doit être 1, pas fd + 1. Maintenant, ils ont corrigé et le code ne fonctionne toujours pas avec SENA RS485.

Artless Noise a suggéré de connecter la carte ARM au PC et de vérifier si la carte UART sur ARM est correctement configurée. Smokie connecté ARM à PC en utilisant un câble série ultra mini DB9 et a confirmé que termios_test.c peut envoyer et recevoir des données à Windows PC.

Pour l'instant, j'ai supposé que le problème est avec la connexion physique de ARM à SENA. Ultra mini série à DB9 câble utilisé pour connecter ARM au PC est un crosscable. Il connecte la broche ARM RX à la broche PC TX et vice versa. L'adaptateur SENA RS485 est conçu pour être connecté directement au PC sans câble. Il a une connexion directe: broche PC TX connectée à la broche SENA TX et broche PC RX à la broche SENA RX. ARM est connecté à SENA à l'aide d'un câble série ultra-mini DB9 et d'un adaptateur COM mâle-mâle. L'adaptateur COM mâle/mâle ne modifie pas l'ordre des broches, donc la broche TX est devenue broche TX. Ainsi, dans la connexion, la broche ARM TX est devenue erronée, connectée à la broche SENA RX. Pour effectuer un travail schématique, le câble COM null modem doit être utilisé à la place de l'adaptateur COM mâle-mâle. Il Brochage de base pourrait être la suivante:

ARM side        SENA side 
TXT pin 3      <--> RXD pin 2 
RXD pin 2      <--> TXT pin 3 
GND        <--> GND 
RTS pin 7 (leave unconnected)  +-> RTS pin 7 
            | 
CTS pin 8 (leave unconnected)  +-> CTS pin 8 
            | 
DTR pin 4 (leave unconnected)  +--> DTR pin 4 (to emulate the same behavior as PC does) 
DCD pin 1 (leave unconnected)  (leave unconnected) DCD pin 1 
DSR pin 6 (leave unconnected)  (leave unconnected) DSR pin 6 

Si SENA utilisation de flux matériel, puis les entrées RTS et DTR doivent être connectés à la sortie CTS. Sinon, ils pourraient être laissés déconnectés. Je suggère de connecter d'abord les signaux RXD, TXD et GND, et si cela ne fonctionne pas, connectez les broches RTS, CTS et DTR.

Il est possible de connecter des broches RTS et CTS à ARM pour implémenter le contrôle de flux matériel, mais cela ne fait rien. Parce que la vitesse SENA RS485 TX/RX est la même que la vitesse UART. Quoi qu'il en soit, les modifications suivantes doivent être effectuées: installer R44 et R45 (qui n'est pas installé sur la carte ARM) et modifier les broches RTS/CTS dans le fichier DTS de la carte ARM (maintenant utilisées comme broches I2C1) et configurer UART dans le logiciel pour utiliser le flux contrôle. Dans le cas où quelqu'un prétend UART sur ARM vous verrez des caractères inattendus dans le flux de données (par exemple, vous verrez l'épingle SENA TX clignote pendant le démarrage ARM, si ARM utilisant UART0 comme console). Ou vous verrez 'login:' ou 'login incorrect' dans le flux de données si getty utilisant UART. De plus, la ROM de démarrage ARM peut imprimer certaines chaînes sur UART et vous ne pouvez pas désactiver ce comportement. U-boot peut utiliser UART comme console et comme chaîne de sortie. Soyez prêt à ce que ces données vont dans RS485 et d'une manière ou d'une autre affectent son travail.

+0

Vous avez raison, mais ce n'était pas le problème. – Smokie

+2

Vous passez également un paramètre invalide à sélectionner. Le premier paramètre doit être 1, pas fd + 1. Et merci pour downvote. – alexander

+0

downvoted puisque cela appartient vraiment à la section des commentaires, il n'a pas contribué à trouver une solution ... – Smokie