Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Programmatic access to remote power measurements #51

Merged
merged 8 commits into from
Nov 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 50 additions & 1 deletion README
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ from sandbox/cdba/cdba-server. Available devices are read from $HOME/.cdba
= Client side
The client is invoked as:

cdba -b <board> -h <host> [-c <power-cylce-count>] boot.img
cdba -b <board> -h <host> [-c <power-cylce-count>] [-s <status-fifo>] boot.img

<host> will be connected to using ssh and <board> will be selected for
operation. As the board's fastboot interface shows up the given boot.img will
Expand All @@ -31,9 +31,23 @@ If the optional -c is given, the board will upon receiving the tilde sequence
restart the board the given number of times. Each time booting the given
boot.img.

The optional -s argument can be used to specify that a fifo should be created
lumag marked this conversation as resolved.
Show resolved Hide resolved
and opened. cdba will request the server to start sending status/measurement
updates, which will be written to this fifo.

= Server side

== Device configuration
The list of attached devices is read from $HOME/.cdba and is YAML formatted.

== Status command

The "status-cmd" property for a board specifies a command line that should be
executed to perform measurements and report status updates to the client. The
command is expected to run for the duration of the board session and should
produce a continuous stream of json-formatted lines of status updates according
to the format defined in this document.

=== Example
devices:
- board: db2k
Expand Down Expand Up @@ -110,3 +124,38 @@ devices:
fastboot: cacafada
fastboot_set_active: true
fastboot_key_timeout: 2

= Status messages

The status messages that are used by the client fifo and the server's status
command should be json-formatted, with one status update per line.

Each message should contain one timestamp member "ts", and one or more
measurement members. Like so:

{"ts":%d.%03d, "name": {["mv"|"ma"]: %u}(, "name2": {["mv"|"ma"]: %u})*}

The timestamp member ("ts"), should provide the time since first measurement in
decimal form with millisecond accuracy.

The key for the measurement members should be an identifier of the measured
resources, and the value should be an object with members for each unit
measured for the given resource and the measured value.

Valid units to report are "mv", "ma", and "mw".

Note that the cadence of measurement might differ between different items to be
measured, so not all status messages contains data for all items that can be
measured.

== Examples

Single resource "dc" measured at 20.271s, with voltage and current reported:

{"ts":20.271, "dc":{ "mv": 12165, "ma": 114}}

Multiple resources measured in a single status message, followed by single
resource measurement, all with voltage and current reported:

{"ts":38.341, "battery":{"mv":8023, "ma":725}, "vdd_cx":{"mv":750, "ma":466}}
{"ts":44.339, "battery":{"mv":8023, "ma":733}}
superna9999 marked this conversation as resolved.
Show resolved Hide resolved
45 changes: 30 additions & 15 deletions cdb_assist.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@

#include "cdba-server.h"
#include "device.h"
#include "status.h"

struct cdb_assist {
char serial[9];
Expand Down Expand Up @@ -338,23 +339,37 @@ static void cdb_gpio(struct cdb_assist *cdb, int gpio, bool on)
cdb_ctrl_write(cdb, &cmd[gpio][on], 1);
}

static void cdb_assist_print_status(struct device *dev)
static void cdb_assist_print_status(void *data)
{
struct cdb_assist *cdb = data;
struct status_value vbat[] = {
{
.unit = STATUS_MV,
.value = cdb->voltage_set,
},
{
.unit = STATUS_MA,
.value = cdb->current_actual,
},
{}
};
struct status_value vref[] = {
{
.unit = STATUS_MV,
.value = cdb->vref,
},
{}
};

status_send_values("vbat", vbat);
status_send_values("vref", vref);
}

static void cdb_assist_status_enable(struct device *dev)
lumag marked this conversation as resolved.
Show resolved Hide resolved
{
struct cdb_assist *cdb = dev->cdb;
char buf[128];
int n;

n = sprintf(buf, "%umV %umA%s%s%s%s%s ref: %umV",
cdb->voltage_set,
cdb->current_actual,
cdb->vbat ? " vbat" : "",
cdb->vbus ? " vbus" : "",
cdb->btn[0] ? " btn1" : "",
cdb->btn[1] ? " btn2" : "",
cdb->btn[2] ? " btn3" : "",
cdb->vref);

cdba_send_buf(MSG_STATUS_UPDATE, n, buf);
watch_timer_add(1000, cdb_assist_print_status, cdb);
}

static void cdb_set_voltage(struct cdb_assist *cdb, unsigned mV)
Expand Down Expand Up @@ -384,7 +399,7 @@ const struct control_ops cdb_assist_ops = {
.open = cdb_assist_open,
.close = cdb_assist_close,
.power = cdb_assist_power,
.print_status = cdb_assist_print_status,
.status_enable = cdb_assist_status_enable,
.usb = cdb_assist_usb,
.key = cdb_assist_key,
};
2 changes: 1 addition & 1 deletion cdba-server.c
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ static int handle_stdin(int fd, void *buf)
// fprintf(stderr, "fastboot boot\n");
break;
case MSG_STATUS_UPDATE:
device_print_status(selected_device);
device_status_enable(selected_device);
break;
case MSG_VBUS_ON:
device_usb(selected_device, true);
Expand Down
47 changes: 42 additions & 5 deletions cdba.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ static bool quit;
static bool fastboot_repeat;
static bool fastboot_done;

static int status_fd = -1;

static const char *fastboot_file;

static struct termios *tty_unbuffer(void)
Expand Down Expand Up @@ -398,12 +400,40 @@ static void request_fastboot_files(void)

static void handle_status_update(const void *data, size_t len)
{
char *str = alloca(len + 1);
if (status_fd < 0)
return;

write(status_fd, data, len);
}

static void status_enable_fn(struct work *work, int ssh_stdin)
{
cdba_send(ssh_stdin, MSG_STATUS_UPDATE);

free(work);
}

static void status_pipe_open(const char *path)
{
struct work *work;
int ret;
int fd;

ret = mkfifo(path, 0600);
if (ret < 0 && errno != EEXIST)
err(1, "failed to create fifo %s", path);

fd = open(path, O_RDWR | O_NONBLOCK);
if (fd < 0)
err(1, "failed to open fifo %s", path);

memcpy(str, data, len);
str[len] = '\n';
status_fd = fd;

write(STDOUT_FILENO, str, len + 1);
/* Queue a MSG_STATUS_UPDATE request */
work = malloc(sizeof(*work));
work->fn = status_enable_fn;

list_add(&work_items, &work->node);
}

static void handle_list_devices(const void *data, size_t len)
Expand Down Expand Up @@ -577,6 +607,7 @@ int main(int argc, char **argv)
struct timeval timeout_total_tv;
struct termios *orig_tios;
const char *server_binary = "cdba-server";
const char *status_pipe = NULL;
int timeout_inactivity = 0;
int timeout_total = 600;
struct work *next;
Expand All @@ -597,7 +628,7 @@ int main(int argc, char **argv)
int opt;
int ret;

while ((opt = getopt(argc, argv, "b:c:C:h:ilRt:S:T:")) != -1) {
while ((opt = getopt(argc, argv, "b:c:C:h:ilRt:S:s:T:")) != -1) {
switch (opt) {
case 'b':
board = optarg;
Expand All @@ -623,6 +654,9 @@ int main(int argc, char **argv)
case 'S':
server_binary = optarg;
break;
case 's':
status_pipe = optarg;
break;
case 't':
timeout_total = atoi(optarg);
break;
Expand Down Expand Up @@ -661,6 +695,9 @@ int main(int argc, char **argv)
break;
}

if (status_pipe)
status_pipe_open(status_pipe);

ret = fork_ssh(host, server_binary, ssh_fds);
if (ret)
err(1, "failed to connect to \"%s\"", host);
Expand Down
8 changes: 8 additions & 0 deletions config-samples/sample11.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
devices:
- board: myboard
name: "My Board"
alpaca: /dev/ttyACM0
console: /dev/ttyUSB0
fastboot: cacafada
status-cmd: /usr/bin/sample-measure-app --sample-rate 100 /dev/measure0
20 changes: 17 additions & 3 deletions device.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
#include "fastboot.h"
#include "list.h"
#include "ppps.h"
#include "status-cmd.h"

#define ARRAY_SIZE(x) ((sizeof(x)/sizeof((x)[0])))

Expand Down Expand Up @@ -260,10 +261,18 @@ int device_power(struct device *device, bool on)
return device_power_off(device);
}

void device_print_status(struct device *device)
void device_status_enable(struct device *device)
{
if (device_has_control(device, print_status))
device_control(device, print_status);
if (device->status_enabled)
return;

if (device_has_control(device, status_enable))
device_control(device, status_enable);

if (device->status_cmd)
status_cmd_open(device);

device->status_enabled = true;
}

void device_usb(struct device *device, bool on)
Expand Down Expand Up @@ -300,6 +309,11 @@ void device_boot(struct device *device, const void *data, size_t len)
fastboot_set_active(device->fastboot, device->set_active);
fastboot_download(device->fastboot, data, len);
device->boot(device);

if (device->status_enabled && !device->usb_always_on) {
warnx("disabling USB, use ^A V to enable");
device_usb(device, false);
}
}

void device_send_break(struct device *device)
Expand Down
8 changes: 6 additions & 2 deletions device.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ struct control_ops {
int (*power)(struct device *dev, bool on);
void (*usb)(struct device *dev, bool on);
void (*key)(struct device *device, int key, bool asserted);
void (*print_status)(struct device *dev);
void (*status_enable)(struct device *dev);
};

struct console_ops {
Expand Down Expand Up @@ -46,6 +46,8 @@ struct device {
int state;
bool has_power_key;

bool status_enabled;

void (*boot)(struct device *);

const struct control_ops *control_ops;
Expand All @@ -56,6 +58,8 @@ struct device {
void *cdb;
void *console;

char *status_cmd;

struct list_head node;
};

Expand All @@ -73,7 +77,7 @@ struct device *device_open(const char *board,
void device_close(struct device *dev);
int device_power(struct device *device, bool on);

void device_print_status(struct device *device);
void device_status_enable(struct device *device);
void device_usb(struct device *device, bool on);
int device_write(struct device *device, const void *buf, size_t len);

Expand Down
2 changes: 2 additions & 0 deletions device_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,8 @@ static void parse_board(struct device_parser *dp)
dev->ppps_path = strdup(value);
} else if (!strcmp(key, "ppps3_path")) {
dev->ppps3_path = strdup(value);
} else if (!strcmp(key, "status-cmd")) {
dev->status_cmd = strdup(value);
} else {
fprintf(stderr, "device parser: unknown key \"%s\"\n", key);
exit(1);
Expand Down
11 changes: 10 additions & 1 deletion meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,13 @@ server_deps = [dependency('libudev', required: server_opt),
dependency('yaml-0.1', required: server_opt),
gpiod_dep,
ftdi_dep]

# E.g. Debian reuires -lutil for forkpty
if not compiler.has_function('forkpty')
util_dep = compiler.find_library('util')
server_deps += util_dep
endif

server_srcs = ['cdba-server.c',
'cdb_assist.c',
'circ_buf.c',
Expand All @@ -71,7 +78,9 @@ server_srcs = ['cdba-server.c',
'local-gpio.c',
'console.c',
'qcomlt_dbg.c',
'ppps.c']
'ppps.c',
'status.c',
'status-cmd.c']
superna9999 marked this conversation as resolved.
Show resolved Hide resolved

if gpiod_dep.version().version_compare('>=2.0')
server_srcs += ['local-gpio-v2.c']
Expand Down
Loading