-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add uartbone client for Linux platform
- Loading branch information
Showing
4 changed files
with
492 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
uartbone_cli: linux_cli.o uartbone.o | ||
$(CC) $(LDFLAGS) -o $@ $^ | ||
|
||
linux_cli.o: linux_cli.c | ||
|
||
uartbone.o: uartbone.c | ||
|
||
clean: | ||
rm -f linux_cli.o uartbone.o uartbone_cli |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,232 @@ | ||
#include <stdio.h> | ||
#include <unistd.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include <errno.h> | ||
#include "uartbone.h" | ||
|
||
void uart_write(struct uartbone_ctx *ctx, uint8_t data) { | ||
write(ctx->fd, &data, 1); | ||
} | ||
|
||
int uart_read(struct uartbone_ctx *ctx, uint8_t *res) { | ||
return read(ctx->fd, res, 1); | ||
} | ||
|
||
struct uart_backend ub = { | ||
.type = UNIX_UART, | ||
.readb = uart_read, | ||
.writeb = uart_write | ||
}; | ||
|
||
int get_reg_addr(FILE *csv, char *reg_name, uint32_t *res) { | ||
char *line = NULL; | ||
char *tok; | ||
size_t len = 0; | ||
bool csr_base_found = false; | ||
bool csr_reg_found = false; | ||
uint32_t csr_base = 0; | ||
uint32_t reg_addr = 0; | ||
ssize_t nread; | ||
size_t reg_name_len = strlen(reg_name); | ||
|
||
if (!reg_name) | ||
return -1; | ||
|
||
while ((nread = getline(&line, &len, csv)) != -1) { | ||
|
||
// Find the csd_base address | ||
if (strncmp(line, "csr_base", strlen("csr_base")) == 0) { | ||
strtok(line, ","); | ||
tok = strtok(NULL, ","); | ||
if (tok && (strncmp(tok, reg_name, reg_name_len) == 0)) { | ||
if (tok[reg_name_len] != '\0') | ||
continue; | ||
|
||
tok = strtok(NULL, ","); | ||
if (tok) { | ||
csr_base = strtol(tok, NULL, 0); | ||
csr_base_found = true; | ||
} | ||
} | ||
} | ||
|
||
// Find the register address | ||
if (strncmp(line, "csr_register", strlen("csr_register")) == 0) { | ||
strtok(line, ","); | ||
tok = strtok(NULL, ","); | ||
|
||
if (tok && reg_name && (strncmp(tok, reg_name, reg_name_len) == 0)) { | ||
if (tok[reg_name_len] != '\0') | ||
continue; | ||
|
||
tok = strtok(NULL, ","); | ||
if (tok) { | ||
reg_addr = strtol(tok, NULL, 0); | ||
csr_reg_found = true; | ||
} | ||
} | ||
} | ||
} | ||
|
||
if (csr_reg_found) | ||
*res = reg_addr; | ||
else if (csr_base_found) | ||
*res = csr_base; | ||
else | ||
return -1; | ||
|
||
return 0; | ||
} | ||
|
||
int main(int argc, char **argv) { | ||
struct uartbone_ctx ctx; | ||
char ident_str[256]; | ||
char c; | ||
int i = 0; | ||
int opt; | ||
bool do_read = false; | ||
bool do_write = false; | ||
bool do_print_ident = false; | ||
bool verbose = false; | ||
unsigned int baudrate = 115200; | ||
unsigned int addr_width = 4; | ||
uint32_t addr; | ||
char *addr_string = NULL; | ||
uint32_t res, val; | ||
char *prog_name = argv[0]; | ||
char *uart_port = argv[1]; | ||
char *csv_file = NULL; | ||
FILE *csv; | ||
|
||
optind = 2; | ||
|
||
while ((opt = getopt(argc, argv, ":w:r:b:a:v:c:Vi")) != -1) { | ||
switch (opt) { | ||
case 'r': | ||
char *endptr; | ||
|
||
do_read = true; | ||
addr = strtol(optarg, &endptr, 0); | ||
if (errno != 0 || endptr == optarg) | ||
addr_string = optarg; | ||
break; | ||
case 'w': | ||
|
||
do_write = true; | ||
addr = strtol(optarg, &endptr, 0); | ||
if (errno != 0 || endptr == optarg) | ||
addr_string = optarg; | ||
break; | ||
case 'i': | ||
do_print_ident = true; | ||
break; | ||
case 'b': | ||
baudrate = strtol(optarg, &endptr, 0); | ||
if (errno != 0 || endptr == optarg) | ||
goto print_usage; | ||
break; | ||
case 'a': | ||
addr_width = strtol(optarg, &endptr, 0); | ||
if (errno != 0 || endptr == optarg) | ||
goto print_usage; | ||
break; | ||
case 'c': | ||
csv_file = optarg; | ||
break; | ||
case 'V': | ||
verbose = true; | ||
break; | ||
case 'v': | ||
val = strtol(optarg, &endptr, 0); | ||
if (errno != 0 || endptr == optarg) | ||
goto print_usage; | ||
break; | ||
case '?': | ||
default: | ||
print_usage: | ||
printf("usage: %s uart_port [-V] [-b baudrate] [-r addr|reg_name] [-w addr|reg_name -v value] [-i] [-a addr_width]\n", prog_name); | ||
return -1; | ||
} | ||
} | ||
|
||
uartbone_unix_init(&ctx, uart_port, baudrate, addr_width); | ||
|
||
if (!ctx.open) { | ||
printf("opening uart failed!\n"); | ||
return ctx.error; | ||
} | ||
|
||
ctx.uart = &ub; | ||
|
||
if (verbose) { | ||
if (do_print_ident) | ||
printf("printing ident string\n"); | ||
if (do_read) | ||
printf("issuing Read\n"); | ||
if (do_write) | ||
printf("issuing Write\n"); | ||
printf("- uart: %s\n", uart_port); | ||
printf("- baudrate: %d\n", baudrate); | ||
printf("- address width: %d\n", addr_width); | ||
if (csv_file) | ||
printf("- csv: %s\n", csv_file); | ||
printf("\n"); | ||
} | ||
|
||
// Let's open the CSV file | ||
if (do_print_ident || ((do_read || do_write) && addr_string)) { | ||
if (!csv_file) { | ||
printf("You must pass -c <csv_file> argument\n"); | ||
return -1; | ||
} | ||
csv = fopen(csv_file, "r"); | ||
if (!csv) { | ||
perror("fopen"); | ||
return errno; | ||
} | ||
} | ||
|
||
if (do_print_ident) { | ||
int ret; | ||
uint32_t ident_addr; | ||
|
||
ret = get_reg_addr(csv, "identifier_mem", &ident_addr); | ||
if (ret) { | ||
printf("Could not find 'identifier_mem' in CSV file\n"); | ||
return -1; | ||
} | ||
memset(ident_str, '\0', sizeof(ident_str)); | ||
do { | ||
c = uartbone_read(&ctx, ident_addr+i*4); | ||
ident_str[i++] = c; | ||
} while (c); | ||
printf("ident: %s\n", ident_str); | ||
} else if (do_read) { | ||
int ret; | ||
|
||
if (addr_string) { | ||
ret = get_reg_addr(csv, addr_string, &addr); | ||
if (ret) { | ||
printf("Could not find register '%s'\n", addr_string); | ||
return -1; | ||
} | ||
} | ||
val = uartbone_read(&ctx, addr); | ||
printf("Read 0x%08x @ 0x%08x\n", val, addr); | ||
} else if (do_write) { | ||
int ret; | ||
|
||
if (addr_string) { | ||
ret = get_reg_addr(csv, addr_string, &addr); | ||
if (ret) { | ||
printf("Could not find register '%s'\n", addr_string); | ||
return -1; | ||
} | ||
} | ||
uartbone_write(&ctx, addr, val); | ||
printf("Written 0x%08x @ 0x%08x\n", val, addr); | ||
} | ||
|
||
return 0; | ||
} |
Oops, something went wrong.