OpenCores
URL https://opencores.org/ocsvn/riscv_vhdl/riscv_vhdl/trunk

Subversion Repositories riscv_vhdl

[/] [riscv_vhdl/] [trunk/] [debugger/] [src/] [libdbg64g/] [services/] [comport/] [com_linux.cpp] - Blame information for rev 2

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 sergeykhbr
/** Example:
2
* http://www.linux-tutorial.info/modules.php?name=Howto&pagename=Serial-Programming-HOWTO/x115.html#AEN125
3
*/
4
#include "api_types.h"
5
#include "api_core.h"
6
#include "attribute.h"
7
#include "comport.h"
8
 
9
#include <stdlib.h>
10
#include <dirent.h>
11
#include <stdio.h>          // standard input/output
12
#include <sys/types.h>
13
#include <sys/stat.h>
14
#include <unistd.h>         // unix standard function definition
15
#include <string.h>         // strcpy, memset, memcpy
16
#include <fcntl.h>          // file control definition
17
#include <termios.h>        // POSIX terminal control definition
18
#include <errno.h>          // error number definition
19
#include <sys/ioctl.h>
20
#include <linux/serial.h>
21
 
22
#include <iostream>
23
#include <list>
24
 
25
namespace debugger {
26
 
27
using namespace std;
28
 
29
static std::string checkDriverPresence(const std::string& tty) {
30
    struct stat st;
31
    std::string devicedir = tty;
32
 
33
    // Append '/device' to the tty-path
34
    devicedir += "/device";
35
 
36
    // Stat the devicedir and handle it if it is a symlink
37
    if (lstat(devicedir.c_str(), &st)==0 && S_ISLNK(st.st_mode)) {
38
        char buffer[1024];
39
        memset(buffer, 0, sizeof(buffer));
40
 
41
        // Append '/driver' and return basename of the target
42
        devicedir += "/driver";
43
 
44
        if (readlink(devicedir.c_str(), buffer, sizeof(buffer)) > 0)
45
            return basename(buffer);
46
    }
47
    return "";
48
}
49
 
50
/*static void register_comport(list<string>& comList,
51
                               list<string>& comList8250,
52
                               const string& dir) {
53
    // Get the driver the device is using
54
    std::string driver = checkDriverPresence(dir);
55
 
56
    // Skip devices without a driver
57
    if (driver.size() > 0) {
58
        string devfile = string("/dev/") + basename(dir.c_str());
59
 
60
        // Put serial8250-devices in a seperate list
61
        if (driver == "serial8250") {
62
            comList8250.push_back(devfile);
63
        } else
64
            comList.push_back(devfile);
65
    }
66
}
67
 
68
static void probe_serial8250_comports(list<string>& comList,
69
                                      list<string> comList8250) {
70
    struct serial_struct serinfo;
71
    list<string>::iterator it = comList8250.begin();
72
 
73
    // Iterate over all serial8250-devices
74
    while (it != comList8250.end()) {
75
 
76
        // Try to open the device
77
        int fd = open((*it).c_str(), O_RDWR | O_NONBLOCK | O_NOCTTY);
78
 
79
        if (fd >= 0) {
80
            // Get serial_info
81
            if (ioctl(fd, TIOCGSERIAL, &serinfo)==0) {
82
                // If device type is no PORT_UNKNOWN we accept the port
83
                if (serinfo.type != PORT_UNKNOWN)
84
                    comList.push_back(*it);
85
            }
86
            close(fd);
87
        }
88
        it ++;
89
    }
90
}*/
91
 
92
/*
93
 * Enumerate all files in /sys/class/tty
94
 *
95
 * For each directory /sys/class/tty/foo, check if /sys/class/tty/foo/device
96
 * exists using lstat().
97
 *
98
 * If it does not exist then you are dealing with some kind of virtual tty
99
 * device (virtual console port, ptmx, etc...) and you can discard it.
100
 * If it exists then retain serial port foo.
101
 */
102
void ComPortService::getSerialPortList(AttributeType *list) {
103
    int n;
104
    struct dirent **namelist;
105
    const char* sysdir = "/sys/class/tty/";
106
    AttributeType jsonPortInfo;
107
    list->make_list(0);
108
 
109
    // Scan through /sys/class/tty - it contains all tty-devices in the system
110
    n = scandir(sysdir, &namelist, NULL, NULL);
111
    if (n < 0) {
112
        RISCV_error("Can't scan '%s' directory", sysdir);
113
        return;
114
    }
115
    while (n--) {
116
        if (!strcmp(namelist[n]->d_name, "..")
117
         || !strcmp(namelist[n]->d_name, ".")) {
118
            free(namelist[n]);
119
            continue;
120
        }
121
 
122
        // Construct full absolute file path
123
        std::string devicedir = sysdir;
124
        devicedir += namelist[n]->d_name;
125
 
126
        // Get the driver the device is using.
127
        // Skip devices without a driver
128
        std::string driver = checkDriverPresence(devicedir);
129
        if (driver.size() <= 0) {
130
            continue;
131
        }
132
        std::string devfile = std::string("/dev/") + basename(devicedir.c_str());
133
 
134
        jsonPortInfo.make_dict();
135
        jsonPortInfo["id"] = AttributeType(devfile.c_str());
136
        list->add_to_list(&jsonPortInfo);
137
        free(namelist[n]);
138
    }
139
    free(namelist);
140
 
141
    // Only non-serial8250 has been added to comList without any further testing
142
    // serial8250-devices must be probe to check for validity
143
    //probe_serial8250_comports(comList, comList8250);
144
}
145
 
146
 
147
int ComPortService::openSerialPort(const char *port, int baud, void *hdl) {
148
    *((int *)hdl) = 0;
149
    int fd = open(port, O_RDWR | O_NOCTTY);// | O_NONBLOCK);// | O_NDELAY );
150
    //fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) & ~O_NONBLOCK);
151
    if (fd < 0) {
152
        RISCV_error("fopen() failed", NULL);
153
        return -1;
154
    }
155
 
156
    struct termios options;
157
    memset(&options, 0, sizeof(options));
158
 
159
    /**
160
     *    struct termios {
161
     *        tcflag_t  c_iflag;       // input modes
162
     *        tcflag_t  c_oflag;       // output modes
163
     *        tcflag_t  c_cflag;       // control modes
164
     *        tcflag_t  c_lflag;       // local modes
165
     *        speed_t   c_ispeed;      // input speed
166
     *        speed_t   c_ospeed;      // output speed
167
     *        cc_t      c_cc[NCCS];    // control characters
168
     *    };
169
     * Input flags c_iflags:
170
     *    ICRNL  - map CR to NL on input (NL = LF)
171
     *    IGNCR  - ignore CR
172
     *    INLCR  - map NL to CR
173
     *    IXON   - enable start/stop output control
174
     *    IXOFF  - enable start/stop input control
175
     *    IXANY  - allow any character to restart output
176
     *    ISTRIP - strip character to seven bits
177
     *    IGNPAR - ignore characters withparity error
178
     *    INPCK  - enable input parity checking
179
     *    PARMRK - mark parity error by inserting '\377', '\0'
180
     *    BRKINT - send SIGINT to the terminal when receiving break condition
181
     *    IGNBRK - ignore break condition
182
     */
183
    options.c_iflag = IGNPAR;
184
 
185
    /* Output mode c_oflag:
186
     *    OPOST  - perform output processing
187
     *    ONCLR  - transform NL to CR NL
188
     *    XTABS  - Transform TAB into spaces
189
     *    ONOEOT - discard EOT (^D) character
190
     */
191
    options.c_oflag = 0;          //
192
 
193
    /* Control modes c_cflag:
194
     *    CLOCAL - ignore modem status lines
195
     *    CREAD  - enable receiver
196
     *    CSIZE  - number of bits mask. Possible values: CS5, CS6, CS7, CS8
197
     *    CSTOPB - send 2 stop bits instead of one.
198
     *    PARENB - enable parity generation
199
     *    PARODD - generate odd parity if parity is generated
200
     *    HUPCL  - drop modem control lines on the last close of the terminal line
201
     */
202
    options.c_cflag = B115200 | CRTSCTS | CS8 | CLOCAL | CREAD;
203
 
204
    /* Local modes c_lflag:
205
     *    ECHO   - enable echoing of input characters
206
     *    ECHOE  - if ICANNON an ECHO are set then echo ERASE and KILL as one
207
     *             or more backspace-space-backspace sequences (to wipe entire
208
     *             line)
209
     *    ECHOK  - output an NL after the KILL character
210
     *    ECHONL - echo NL even if ECHO is not set
211
     *    ICANON - cannonical input. This enables line oriented input (not raw case).
212
     *    IEXTEN - enable implementation defined input extensions
213
     *    ISIG   - enable signal character INTR, QUIT, SUSP
214
     *    NOFLSH - disable flushing of the input/output queues that is normally
215
     *             done if a signal is sent
216
     *    TOSTOP - send a SIGTTOU if job control is implemented
217
     */
218
    options.c_lflag = 0;          // no signaling chars, no echo
219
 
220
    /* Available fields:
221
     *    VEOF, VEOL, VERASE, VINTR, VKILL, VMIN, VQUIT, VTIME, VSUSP, VSTART,
222
     *    VSTOP, VREPRINT, VLNEXT and VDISCARD
223
     */
224
    options.c_cc[VTIME] = 0;      // inter-character timer unesed
225
    options.c_cc[VMIN] = 0;       // blocking read until 5 chars received
226
 
227
 
228
    tcflush(fd, TCIOFLUSH);
229
    // TCSANOW   - change occurs immediatly
230
    // TCSADRAIN - change occurs after all parameters are written
231
    // TCSAFLUSH - ..
232
    if(tcsetattr(fd, TCSANOW, &options) == -1) {
233
        RISCV_error("tcsetattr() failed", NULL);
234
        return -1;
235
    }
236
 
237
    // Empty buffers
238
    tcflush(fd, TCIOFLUSH);
239
    *((int *)hdl) = fd;
240
    return 0 ;
241
}
242
 
243
void ComPortService::closeSerialPort(void *hdl) {
244
    close(*((int *)hdl));
245
}
246
 
247
int ComPortService::readSerialPort(void *hdl, char *buf, int bufsz) {
248
    return read(*((int *)hdl), buf, bufsz-1);
249
}
250
 
251
int ComPortService::writeSerialPort(void *hdl, char *buf, int bufsz) {
252
    return write(*((int *)hdl), buf, bufsz);
253
}
254
 
255
void ComPortService::cleanSerialPort(void *hdl) {
256
    tcflush(*((int *)hdl), TCIOFLUSH);
257
}
258
 
259
}  // namespace debugger

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.