Comment lire une donnée binaire sur un terminal série dans un programme C?

J'ai lu, suivi des liens et d'autres sources, mais je n'ai pas trouver réponse à ma question.

Données binaires sur le terminal série

De données est corrompu lors de leur transmission via le port série

- Je communiquer avec mon appareil embarqué par l'intermédiaire d'un port série. Par défaut, Linux embarqué utilise ce port comme un terminal. Mais je veux aussi transmettre des données binaires (paquets de service) par le port. Mon fichier /etc/inittab a un "getty" composez le:
console::respawn:/sbin/getty 115200 ttyS0

J'ai aussi fichier /etc/passwd avec de la ficelle où l'utilisateur "admin" lancer mon "cli" application après l'ouverture de session:
admin:8Mt/Jtxcyg8AY:1000:0:admin:/tmp:/tmp/cli

Par défaut de mon ttyS0 paramètres avant d'exécuter le programme est:

~ # stty -a
speed 115200 baud;stty: standard input
 line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = ^J;
eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd cs8 hupcl -cstopb cread -clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon ixoff
-iuclc -ixany -imaxbel -iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon -iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt
-echoctl echoke
~ #

Donc, dans mon programme en ligne de commande je ne les suivants:

main ()
{
    ...
    system("stty erase ^H);
    system("stty -F /dev/ttyS0 -icrnl -ixon -ixoff -opost -isig -icanon -echo");    //enter in non-canonical (raw) mode

    //What function do I need to use here to retrieve binary data (also symbols that > 0x7F) from /dev/ttyS0?

    system("stty -F /dev/ttyS0 icrnl ixon ixoff opost isig icanon echo");   //go back to canonical mode

    ...

    exit(0);
}

J'ai tenté de lire() fonction (avec unsigned char buffer) pour obtenir des données binaires, mais a échoué à recevoir des données correctes. J'ai aussi préalablement ouvrir /dev/ttyS0 de nouveau pour obtenir file_descriptor & lire() func.

Mon programme envoie 3 octets: 0xAA, 0x02, 0xFE.
Mais dans syslog, je vois toujours que l'appareil reçoit des symboles incorrects: 0x98, 0xE6, 0x18.

Quelle est la question? Comment obtenir correcte des données binaires?

Tout un code que je suis en train de tester en ce moment.

#include "cli.h"
#include "glb_vars.h"
/******************************************
*** Definitions
******************************************/
#define APPLICATION_NAME    "cli"
#define SERIALPORT_IS_CONSOLE
/******************************************
*** Constants
******************************************/
const char dev_name[] = DEV_NAME;
const char lineminstr[] = "\t--------------------------------------------------------\n";
/******************************************
*** Internal Function Declarations
******************************************/
CLI_RETVAL cliInit(void);
CLI_RETVAL cliClose(void);
void cliWorkLoop(Term_callback_t **term);
/******************************************
*** External Function Declarations
******************************************/
extern void Vectors_init(Term_callback_t **vec);
extern char** Menu_completion(const char * text, int start, int end);
/****************************************************************************/
int file_descr, max_fd;
struct termios tty, orig_tty;
fd_set work_set;
/****************************************************************************/
/*!
*  \brief  Init cli
*
*  \return  success or failure
*  \retval  CLI_SUCCESS, CLI_FAILURE
*
*  \ingroup CLI
*/
/****************************************************************************/
CLI_RETVAL cliInit(void)
{
long spd;
signal(SIGINT, SIG_IGN);
signal(SIGHUP, SIG_IGN);
signal(SIGTERM, SIG_IGN);
signal(SIGABRT, SIG_IGN);
signal(SIGQUIT, SIG_IGN);
signal(SIGILL, SIG_IGN);
// system("stty -F /dev/ttyS0 -icrnl -ixon -ixoff -opost -isig -icanon -echo");    //enter in non-canonical mode
// system("stty -a");
// sleep(1);
#ifdef SERIALPORT_IS_CONSOLE
file_descr = STDIN_FILENO;
SYS_LOG_DEBUG("SERIALPORT IS CONSOLE");
#else
SYS_LOG_DEBUG("SERIALPORT IS NOT CONSOLE");
file_descr = open("/dev/ttyS0", O_RDWR | O_ASYNC | O_NDELAY);
if (file_descr == -1) {
//Could not open the port
perror("unable to open /dev/ttyS0");
exit(1);
}
#endif
if(tcgetattr(file_descr, &tty) < 0)
{
perror("unable to get tty attributes");
exit(1);
}
//backup tty, make it raw and apply changes
orig_tty = tty;
spd = B115200;
cfsetospeed(&tty, (speed_t)spd);
cfsetispeed(&tty, (speed_t)spd);
cfmakeraw(&tty);
tty.c_cc[VMIN] = 1;
tty.c_cc[VTIME] = 10;
tty.c_cflag &= ~CSTOPB;
tty.c_cflag &= ~CRTSCTS;    /* no HW flow control? */
tty.c_cflag |= CLOCAL | CREAD;
tcsetattr(file_descr, TCSANOW, &tty);
// //update local mode flags
// tty.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
////   //renew control mode flags
////   tty.c_cflag &= ~(CBAUD | CSIZE | CSTOPB | PARENB | PARODD);
////   tty.c_cflag |= (BAUD | DATABITS | STOPBITS | PARITYON | PARITY);
// //select 'raw' output mode
// tty.c_oflag &= ~OPOST;
// //disable mapping for input mode
// tty.c_iflag &= ~(INLCR | ICRNL);
//
//
// if(tcsetattr(file_descr, TCSAFLUSH, &tty) < 0)
// {
//     perror("unable to set tty attributes");
//     exit(1);
// }
//
//Setup fd_set
FD_ZERO(&work_set);
FD_SET(file_descr, &work_set);
max_fd = file_descr + 1;
/* Readline lib init */
//Define application name for readline library
rl_readline_name = APPLICATION_NAME;
//Update Pointer to alternative function to create matches.
rl_attempted_completion_function = Menu_completion;
//Start readline with reading /etc/inputrc file
using_history();
stifle_history(CLI_MAX_HISTORY_SIZE);
//Some other initialization code
//...
//...
return CLI_SUCCESS;
}
/****************************************************************************/
/*!
*  \brief  Close cli
*
*  \return  success or failure
*  \retval  CLI_SUCCESS, CLI_FAILURE
*
*  \ingroup CLI
*/
/****************************************************************************/
CLI_RETVAL cliClose(void)
{
// system("stty -F /dev/ttyS0 icrnl ixon ixoff opost isig icanon echo");   //enter in canonical mode
tcsetattr(file_descr, TCSANOW, &orig_tty);
// if(tcsetattr(file_descr, TCSAFLUSH, &orig_tty) < 0)
// {
//     perror("unable to set orig_tty attributes");
//     exit(1);
// }
close(file_descr);
return CLI_SUCCESS;
}
/****************************************************************************/
/*!
*  \brief  Main cli processing loop
*
*  \no return
*
*  \ingroup CLI
*/
/****************************************************************************/
void cliWorkLoop(Term_callback_t **term)
{
Term_callback_t *cur_term;
int8 *commandString;
uint8 ret = CLI_REFRESH, no_prompt;
char prompt_str[20];
while (1) {
cur_term = *term;
global_cmd_compl_pointer = cur_term->cmd_list;
commandString = NULL;
sprintf(prompt_str, "%s:~> ", dev_name);
if(ret == CLI_REFRESH) {
CLEAR_SCR();
if(cur_term->out != NULL) {
cur_term->out(term, commandString, &ret);
no_prompt = ret;
}
CURSOR_DOWN();
}
int n;
struct timeval timeout;
uint8 tmpBuf[32];
while (1)
{
//Setup Timeout
timeout.tv_sec = 60;
timeout.tv_usec = 0;
//Wait for new connections
n = select(max_fd, &work_set, NULL, NULL, &timeout);
if (n < 0)
{
perror("select #2 failed");
break;
}
if (n > 0)
{
/* У нас есть ввод */
if (FD_ISSET(file_descr, &work_set))
{
if (read(file_descr, tmpBuf, 10) < 0) {
perror("cannot read");
exit(1);
}
else
{
SYS_LOG_DEBUG("READ first 4 chars: 0x%X,0x%X,0x%X,0x%X", tmpBuf[0], tmpBuf[1], tmpBuf[2], tmpBuf[3]);
}
}
break;
}
}
//
//
//     n = read(file_descr, tmpBuf, 5);
//     if (n > 0) {
//         unsigned char   *p = tmpBuf;
//
//         while (n-- > 0)
//             printf(" 0x%x", *p++);
//         printf("\r\n");
//     } else {
//         printf("failed to read: %d\r\n", n);
//     }
//
//
exit(0);
}
CLEAR_SCR();
return;
}
/****************************************************************************/
/*!
*  \brief Main cli function
*
*  \param[in]      argc - argument number.
*  \param[in,out]  argv - argument values entered by user.
*
*  \return  success or failure
*  \retval  EXIT_SUCCESS, EXIT_FAILURE
*
*
*  \ingroup CLI
*/
/****************************************************************************/
int main(int argc, char *argv[])
{
Term_callback_t *term;
char logname[16];
FILE *fp;
/* Set mask for file operation */
umask(0);
system("stty erase ^H");
openlog("cli", LOG_CONS, LOG_USER);
/* Write cli start log */
syslog(LOG_NOTICE, "Console startup. Software version: %s", VERSION);
/* Find login name */
strcpy(logname, "noname");
if ((fp = popen( "whoami", "r" )) == NULL)
{
SYS_LOG_ERR("Can't open process for \"whoami\" command.");
} else
{
fgets(logname, 16, fp);
pclose(fp);
}
SYS_LOG_INFO("Console is entered by \"%s\".", logname); //getenv("USER")
/* Console initialization */
if (cliInit() != CLI_SUCCESS) {
SYS_LOG_CRIT("CLI init failed");
return EXIT_FAILURE;
}
Vectors_init(&term);
/* Console work loop */
cliWorkLoop(&term);
cliClose();
/* Exiting from cli */
SYS_LOG_INFO("\"%s\" exited from console.", logname);
return EXIT_SUCCESS;
}

source d'informationauteur Bakir