Compare commits
8 Commits
master
...
imraa_impr
Author | SHA1 | Date | |
---|---|---|---|
|
b8d73738bd | ||
|
39c9187f6d | ||
|
0397d8399e | ||
|
ab4e0cc0a1 | ||
|
1a1fa776fd | ||
|
1d13668a26 | ||
|
884afe7820 | ||
|
15b053b484 |
@@ -30,7 +30,6 @@ make
|
||||
After you've built mraa you can install using `make install`.
|
||||
|
||||
## Running Imraa
|
||||
|
||||
Before being able to use mraa to program the Arduino101 you will need to run
|
||||
imraa to flash the sketch file onto the board. The sketch file that imraa will
|
||||
look for is located here: [Arduino101 Sketch](http://iotdk.intel.com/misc/ConfigurableFirmataCurieImu.ino.bin).
|
||||
|
@@ -56,7 +56,7 @@ main()
|
||||
|
||||
mraa_firmata_response(firm, interrupt);
|
||||
|
||||
uint8_t* buffer = calloc(4, 0);
|
||||
char* buffer = calloc(4, 0);
|
||||
if (buffer == NULL) {
|
||||
free(firm);
|
||||
return EXIT_FAILURE;
|
||||
|
@@ -1,10 +1,11 @@
|
||||
add_executable (imraa imraa.c)
|
||||
add_executable (imraa imraa.c imraa_arduino.c imraa_io.c imraa_lock.c)
|
||||
|
||||
include_directories (${PROJECT_SOURCE_DIR}/api)
|
||||
include_directories (${PROJECT_SOURCE_DIR}/include)
|
||||
include_directories (${PROJECT_SOURCE_DIR}/api/mraa)
|
||||
include_directories (${PROJECT_SOURCE_DIR}/imraa)
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DIMRAA=1")
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DIMRAA=1")
|
||||
|
||||
find_package (JSON-C REQUIRED)
|
||||
include_directories (${JSON-C_INCLUDE_DIR})
|
||||
|
525
imraa/imraa.c
525
imraa/imraa.c
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Author: Brendan Le Foll <brendan.le.foll@intel.com>
|
||||
* Author: Longwei Su <lsu@ics.com>
|
||||
* Copyright (c) 2015 Intel Corporation.
|
||||
* Copyright (c) 2015-2016 Intel Corporation.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
@@ -29,395 +29,23 @@
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <unistd.h>
|
||||
#include <json-c/json.h>
|
||||
#include <libudev.h>
|
||||
#include <error.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <mraa/uart.h>
|
||||
#include <mraa/gpio.h>
|
||||
#include <mraa/i2c.h>
|
||||
#include <mraa/pwm.h>
|
||||
#include <json-c/json.h>
|
||||
|
||||
#include <argp.h>
|
||||
|
||||
#include <mraa_internal.h>
|
||||
|
||||
#include <imraa_arduino.h>
|
||||
#include <imraa_io.h>
|
||||
#include <imraa_lock.h>
|
||||
|
||||
#define IMRAA_CONF_FILE "/etc/imraa.conf"
|
||||
|
||||
typedef struct mraa_io_objects_t {
|
||||
const char* type;
|
||||
int index;
|
||||
bool raw;
|
||||
const char* label;
|
||||
} mraa_io_objects_t;
|
||||
|
||||
const char*
|
||||
imraa_list_serialport()
|
||||
{
|
||||
struct udev* udev;
|
||||
struct udev_enumerate* enumerate;
|
||||
struct udev_list_entry *devices, *dev_list_entry;
|
||||
struct udev_device* dev;
|
||||
const char* ret = NULL;
|
||||
udev = udev_new();
|
||||
if (!udev) {
|
||||
printf("Can't create udev, check libudev\n");
|
||||
exit(1);
|
||||
}
|
||||
enumerate = udev_enumerate_new(udev);
|
||||
udev_enumerate_add_match_subsystem(enumerate, "tty");
|
||||
udev_enumerate_add_match_property(enumerate, "ID_VENDOR_ID", "8087");
|
||||
udev_enumerate_add_match_property(enumerate, "ID_MODEL_ID", "0ab6");
|
||||
// udev_enumerate_add_match_property(enumerate, "ID_SERIAL",
|
||||
// "Intel_ARDUINO_101_AE6642SQ55000RS");
|
||||
udev_enumerate_scan_devices(enumerate);
|
||||
devices = udev_enumerate_get_list_entry(enumerate);
|
||||
|
||||
udev_list_entry_foreach(dev_list_entry, devices)
|
||||
{
|
||||
const char* path;
|
||||
path = udev_list_entry_get_name(dev_list_entry);
|
||||
dev = udev_device_new_from_syspath(udev, path);
|
||||
ret = udev_device_get_devnode(dev);
|
||||
}
|
||||
udev_enumerate_unref(enumerate);
|
||||
udev_unref(udev);
|
||||
|
||||
if (ret) {
|
||||
printf("Ardunio 101 Device Node Path: %s\n", ret);
|
||||
} else {
|
||||
printf("Can't detect any Ardunio 101 Device on tty\n");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
mraa_result_t
|
||||
imraa_reset_arduino(const char* modem)
|
||||
{
|
||||
mraa_uart_context uart;
|
||||
uart = mraa_uart_init_raw(modem);
|
||||
mraa_uart_set_baudrate(uart, 1200);
|
||||
|
||||
if (uart == NULL) {
|
||||
fprintf(stderr, "UART failed to setup\n");
|
||||
return MRAA_ERROR_UNSPECIFIED;
|
||||
}
|
||||
mraa_uart_stop(uart);
|
||||
mraa_deinit();
|
||||
return MRAA_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
imraa_flash_101(const char* bin_path, const char* bin_file_name, const char* tty)
|
||||
{
|
||||
if (imraa_reset_arduino(tty) != MRAA_SUCCESS) {
|
||||
fprintf(stderr, "Failed to reset arduino on %s for unknown reason, carrying on...\n", tty);
|
||||
}
|
||||
|
||||
char* ln = NULL;
|
||||
size_t len = 0;
|
||||
bool board_found = false;
|
||||
const char* dfu_list = "/dfu-util -d ,8087:0ABA -l";
|
||||
size_t bin_path_len = strlen(bin_path);
|
||||
|
||||
char* full_dfu_list = (char*) calloc((bin_path_len + strlen(dfu_list) + 1), sizeof(char));
|
||||
if (!full_dfu_list) {
|
||||
printf("imraa_flash_101 can't allocate string buffer for dfu list\n");
|
||||
exit(1);
|
||||
}
|
||||
strncat(full_dfu_list, bin_path, strlen(bin_path));
|
||||
strncat(full_dfu_list, dfu_list, strlen(dfu_list));
|
||||
|
||||
int i;
|
||||
// dfu list is still needed, as the time for reset and recognized is varies from platform to
|
||||
// platform.
|
||||
// once dfu able to query available devices, then it is ready to flash
|
||||
for (i = 0; i < 10 && board_found == false; i++) {
|
||||
printf("Waiting for device...\n");
|
||||
// dfu-util -d,8087:0ABA -l
|
||||
FILE* dfu_result = popen(full_dfu_list, "r");
|
||||
if (dfu_result == NULL) {
|
||||
printf("Failed to run command\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (i == 4) {
|
||||
printf("Flashing is taking longer than expected\n");
|
||||
printf("Try pressing MASTER_RESET button\n");
|
||||
}
|
||||
|
||||
while (getline(&ln, &len, dfu_result) != -1) {
|
||||
if (strstr(ln, "sensor_core")) {
|
||||
board_found = true;
|
||||
printf("Device found!\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
sleep(1);
|
||||
if (pclose(dfu_result) != 0) {
|
||||
printf("Failed to close command\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
free(ln);
|
||||
|
||||
if (board_found == false) {
|
||||
printf("ERROR: Device is not responding.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
const char* dfu_upload = "/dfu-util -d ,8087:0ABA -D ";
|
||||
const char* dfu_option = " -v -a 7 -R";
|
||||
int buffersize = bin_path_len + strlen(dfu_upload) + strlen(bin_file_name) + strlen(dfu_option) + 1;
|
||||
char* full_dfu_upload = calloc(buffersize, sizeof(char));
|
||||
if (!full_dfu_upload) {
|
||||
printf("imraa_flash_101 can't allocate string buffer for dfu flash\n");
|
||||
exit(1);
|
||||
}
|
||||
strncat(full_dfu_upload, bin_path, strlen(bin_path));
|
||||
strncat(full_dfu_upload, dfu_upload, strlen(dfu_upload));
|
||||
strncat(full_dfu_upload, bin_file_name, strlen(bin_file_name));
|
||||
strncat(full_dfu_upload, dfu_option, strlen(dfu_option));
|
||||
printf("flash cmd: %s\n", full_dfu_upload);
|
||||
int status = system(full_dfu_upload);
|
||||
if (status != 0) {
|
||||
printf("ERROR: Upload failed on %s\n", tty);
|
||||
exit(1);
|
||||
}
|
||||
printf("SUCCESS: Sketch will execute in about 5 seconds.\n");
|
||||
free(full_dfu_list);
|
||||
free(full_dfu_upload);
|
||||
sleep(5);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
imraa_write_lockfile(const char* lock_file_location, const char* serialport)
|
||||
{
|
||||
FILE* fh;
|
||||
char str[10];
|
||||
json_object* platform1 = json_object_new_object();
|
||||
snprintf(str, 10, "%d", MRAA_NULL_PLATFORM);
|
||||
json_object_object_add(platform1, "id", json_object_new_string(str));
|
||||
|
||||
json_object* platform2 = json_object_new_object();
|
||||
snprintf(str, 10, "%d", MRAA_GENERIC_FIRMATA);
|
||||
json_object_object_add(platform2, "id", json_object_new_string(str));
|
||||
json_object_object_add(platform2, "uart", json_object_new_string(serialport));
|
||||
|
||||
json_object* platfroms = json_object_new_array();
|
||||
json_object_array_add(platfroms, platform1);
|
||||
json_object_array_add(platfroms, platform2);
|
||||
json_object* lock_file = json_object_new_object();
|
||||
json_object_object_add(lock_file, "Platform", platfroms);
|
||||
fh = fopen(lock_file_location, "w");
|
||||
if (fh != NULL) {
|
||||
fputs(json_object_to_json_string_ext(lock_file, JSON_C_TO_STRING_PRETTY), fh);
|
||||
fclose(fh);
|
||||
} else {
|
||||
fprintf(stderr, "can't write to lock file\n");
|
||||
}
|
||||
json_object_put(lock_file);
|
||||
}
|
||||
|
||||
void
|
||||
imraa_handle_subplatform(struct json_object* jobj, bool force_update)
|
||||
{
|
||||
struct json_object* platform;
|
||||
int i, ionum;
|
||||
const char* dfu_loc = NULL;
|
||||
const char* lockfile_loc = NULL;
|
||||
const char* flash_loc = NULL;
|
||||
const char* usbserial = NULL;
|
||||
|
||||
struct json_object* dfu_location;
|
||||
if (json_object_object_get_ex(jobj, "dfu-utils-location", &dfu_location) == true) {
|
||||
if (json_object_is_type(dfu_location, json_type_string)) {
|
||||
printf("dfu location: %s\n", json_object_get_string(dfu_location));
|
||||
dfu_loc = json_object_get_string(dfu_location);
|
||||
} else {
|
||||
fprintf(stderr, "dfu location string incorrectly parsed\n");
|
||||
}
|
||||
}
|
||||
|
||||
struct json_object* lockfile_location;
|
||||
if (json_object_object_get_ex(jobj, "lockfile-location", &lockfile_location) == true) {
|
||||
if (json_object_is_type(lockfile_location, json_type_string)) {
|
||||
printf("lock file location: %s\n", json_object_get_string(lockfile_location));
|
||||
lockfile_loc = json_object_get_string(lockfile_location);
|
||||
} else {
|
||||
fprintf(stderr, "lock file string incorrectly parsed\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (json_object_object_get_ex(jobj, "Platform", &platform) == true) {
|
||||
if (json_object_is_type(platform, json_type_array)) {
|
||||
ionum = json_object_array_length(platform);
|
||||
for (i = 0; i < ionum; i++) {
|
||||
struct json_object* ioobj = json_object_array_get_idx(platform, i);
|
||||
json_object_object_foreach(ioobj, key, val)
|
||||
{
|
||||
if (strcmp(key, "flash") == 0) {
|
||||
flash_loc = json_object_get_string(val);
|
||||
}
|
||||
if (strcmp(key, "usbserial") == 0) {
|
||||
usbserial = json_object_get_string(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "platform string incorrectly parsed\n");
|
||||
}
|
||||
}
|
||||
if (flash_loc == NULL || usbserial == NULL ) {
|
||||
printf("conf didn't give image location or usb serial, skip flashing\n");
|
||||
return;
|
||||
}
|
||||
if (!dfu_loc) {
|
||||
dfu_loc = "/usr/bin";
|
||||
printf("No dfu path found, using default path /usr/bin instead");
|
||||
}
|
||||
if (!lockfile_loc) {
|
||||
lockfile_loc = "/tmp/imraa.lock";
|
||||
printf("No lock path found, using default lock file /tmp/imraa.lock instead");
|
||||
}
|
||||
|
||||
// got flash? do flash
|
||||
if (access(lockfile_loc, F_OK) != -1 && force_update == false) {
|
||||
printf("already exist a lock file, skip flashing\n");
|
||||
printf("force upgrade? remove the lockfile or run with force\n");
|
||||
return;
|
||||
} else {
|
||||
fprintf(stdout, "Starting to flash board\n");
|
||||
if (force_update) {
|
||||
fprintf(stdout, "**Caution: force update mode**\n");
|
||||
}
|
||||
|
||||
// TODO flash img checksum, and serialport validation?
|
||||
const char* detected_serialport = imraa_list_serialport();
|
||||
if (detected_serialport == NULL) {
|
||||
printf("No subplatform detected, check USB connection, skip flashing\n");
|
||||
return;
|
||||
}
|
||||
if (strcmp(usbserial, "auto") != 0 && strcmp(usbserial, detected_serialport) != 0) {
|
||||
printf("given serial port didn't match detected serial port, skip flashing\n");
|
||||
return;
|
||||
}
|
||||
if (imraa_flash_101(dfu_loc, flash_loc, detected_serialport) == 0) {
|
||||
imraa_write_lockfile(lockfile_loc, detected_serialport);
|
||||
} else {
|
||||
fprintf(stderr, "invalid flashing paramenters, please check agian\n");
|
||||
fprintf(stderr, "DFU Util location: %s\n", dfu_loc);
|
||||
fprintf(stderr, "Flash Img location: %s\n", dfu_loc);
|
||||
fprintf(stderr, "USB Serial: %s\n", usbserial);
|
||||
fprintf(stderr, "Flash failed, push master reset and try again\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
imraa_handle_IO(struct json_object* jobj)
|
||||
{
|
||||
struct mraa_io_objects_t* mraa_io_obj;
|
||||
struct json_object* ioarray;
|
||||
int ionum = 0;
|
||||
int i;
|
||||
if (json_object_object_get_ex(jobj, "IO", &ioarray) == true) {
|
||||
ionum = json_object_array_length(ioarray);
|
||||
printf("Length of IO array is %d\n", ionum);
|
||||
mraa_io_obj = (mraa_io_objects_t*) malloc(ionum * sizeof(mraa_io_objects_t));
|
||||
if (!mraa_io_obj) {
|
||||
printf("imraa_handle_IO malloc failed\n");
|
||||
exit(1);
|
||||
}
|
||||
int index2 = -1;
|
||||
; // optional index for io configuration;
|
||||
if (json_object_is_type(ioarray, json_type_array)) {
|
||||
for (i = 0; i < ionum; i++) {
|
||||
struct json_object* ioobj = json_object_array_get_idx(ioarray, i);
|
||||
struct json_object* x;
|
||||
if (json_object_object_get_ex(ioobj, "type", &x) == true) {
|
||||
mraa_io_obj[i].type = json_object_get_string(x);
|
||||
}
|
||||
if (json_object_object_get_ex(ioobj, "index", &x) == true) {
|
||||
mraa_io_obj[i].index = json_object_get_int(x);
|
||||
}
|
||||
if (json_object_object_get_ex(ioobj, "raw", &x) == true) {
|
||||
mraa_io_obj[i].raw = json_object_get_boolean(x);
|
||||
}
|
||||
if (json_object_object_get_ex(ioobj, "label", &x) == true) {
|
||||
mraa_io_obj[i].label = json_object_get_string(x);
|
||||
}
|
||||
if (json_object_object_get_ex(ioobj, "index2", &x) == true) {
|
||||
index2 = json_object_get_int(x);
|
||||
}
|
||||
// starting io configuration
|
||||
if (strcmp(mraa_io_obj[i].type, "gpio") == 0) {
|
||||
mraa_gpio_context gpio = NULL;
|
||||
if (mraa_io_obj[i].raw) {
|
||||
gpio = mraa_gpio_init_raw(mraa_io_obj[i].index);
|
||||
} else {
|
||||
gpio = mraa_gpio_init(mraa_io_obj[i].index);
|
||||
}
|
||||
if (gpio != NULL) {
|
||||
mraa_result_t r = mraa_gpio_owner(gpio, 0);
|
||||
if (r != MRAA_SUCCESS) {
|
||||
mraa_result_print(r);
|
||||
}
|
||||
mraa_gpio_close(gpio);
|
||||
}
|
||||
} else if (strcmp(mraa_io_obj[i].type, "i2c") == 0) {
|
||||
mraa_i2c_context i2c = NULL;
|
||||
if (mraa_io_obj[i].raw) {
|
||||
i2c = mraa_i2c_init_raw(mraa_io_obj[i].index);
|
||||
} else {
|
||||
i2c = mraa_i2c_init(mraa_io_obj[i].index);
|
||||
}
|
||||
if (i2c != NULL) {
|
||||
mraa_i2c_stop(i2c);
|
||||
}
|
||||
} else if (strcmp(mraa_io_obj[i].type, "pwm") == 0) {
|
||||
mraa_pwm_context pwm = NULL;
|
||||
if (mraa_io_obj[i].raw) {
|
||||
pwm = mraa_pwm_init_raw(index2, mraa_io_obj[i].index);
|
||||
} else {
|
||||
pwm = mraa_pwm_init(mraa_io_obj[i].index);
|
||||
}
|
||||
if (pwm != NULL) {
|
||||
mraa_result_t r = mraa_pwm_owner(pwm, 0);
|
||||
if (r != MRAA_SUCCESS) {
|
||||
mraa_result_print(r);
|
||||
}
|
||||
mraa_pwm_close(pwm);
|
||||
}
|
||||
} else if (strcmp(mraa_io_obj[i].type, "spi") == 0) {
|
||||
mraa_spi_context spi = NULL;
|
||||
if (mraa_io_obj[i].raw) {
|
||||
spi = mraa_spi_init_raw(mraa_io_obj[i].index, index2);
|
||||
} else {
|
||||
spi = mraa_spi_init(mraa_io_obj[i].index);
|
||||
}
|
||||
if (spi != NULL) {
|
||||
mraa_spi_stop(spi);
|
||||
}
|
||||
} else if (strcmp(mraa_io_obj[i].type, "uart") == 0) {
|
||||
mraa_uart_context uart = NULL;
|
||||
if (mraa_io_obj[i].raw) {
|
||||
uart = mraa_uart_init_raw(mraa_io_obj[i].label);
|
||||
} else {
|
||||
uart = mraa_uart_init(mraa_io_obj[i].index);
|
||||
}
|
||||
if (uart != NULL) {
|
||||
mraa_uart_stop(uart);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "IO array incorrectly parsed\n");
|
||||
}
|
||||
free(mraa_io_obj);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
check_version(struct json_object* jobj)
|
||||
imraa_check_version(struct json_object* jobj)
|
||||
{
|
||||
struct json_object* imraa_version;
|
||||
if (json_object_object_get_ex(jobj, "version", &imraa_version) == true) {
|
||||
@@ -434,56 +62,90 @@ check_version(struct json_object* jobj)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
print_version()
|
||||
const char *argp_program_version = "imraa version 2.0";
|
||||
const char *argp_program_bug_address = "http://github.com/intel-iot-devkit/mraa/issues";
|
||||
|
||||
static char doc[] = "somestuff";
|
||||
|
||||
static char args_doc[] = "-i imraa.conf";
|
||||
|
||||
static struct argp_option options[] = {
|
||||
{"verbose", 'v', 0, 0, "Produce verbose output" },
|
||||
{"quiet", 'q', 0, 0, "Don't produce any output" },
|
||||
{"silent", 's', 0, OPTION_ALIAS },
|
||||
{"force", 'f', 0, 0, "Force update" },
|
||||
{"arduino", 'a', 0, 0, "Arduino detection" },
|
||||
{"input", 'i', "FILE", 0,
|
||||
"configuration file" },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
struct arguments
|
||||
{
|
||||
fprintf(stdout, "Version %s on %s\n", mraa_get_version(), mraa_get_platform_name());
|
||||
char *args[2];
|
||||
int silent, verbose, force, arduino;
|
||||
char *input_file;
|
||||
};
|
||||
|
||||
static error_t
|
||||
parse_opt(int key, char *arg, struct argp_state *state)
|
||||
{
|
||||
|
||||
/* Get the input argument from argp_parse, which we
|
||||
know is a pointer to our arguments structure. */
|
||||
struct arguments *arguments = state->input;
|
||||
|
||||
switch(key) {
|
||||
case 'q': case 's':
|
||||
arguments->silent = 1;
|
||||
break;
|
||||
case 'v':
|
||||
arguments->verbose = 1;
|
||||
break;
|
||||
case 'a':
|
||||
arguments->arduino = 1;
|
||||
break;
|
||||
case 'f':
|
||||
arguments->force = 1;
|
||||
break;
|
||||
case 'i':
|
||||
arguments->input_file = arg;
|
||||
break;
|
||||
case ARGP_KEY_ARG:
|
||||
if (state->arg_num >= 2) {
|
||||
argp_usage(state);
|
||||
}
|
||||
arguments->args[state->arg_num] = arg;
|
||||
break;
|
||||
case ARGP_KEY_END:
|
||||
if (state->arg_num < 0) {
|
||||
/* Not enough arguments. */
|
||||
argp_usage (state);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return ARGP_ERR_UNKNOWN;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
print_help()
|
||||
{
|
||||
fprintf(stdout, "version Get mraa version and board name\n");
|
||||
fprintf(stdout, "force Force update subplatform\n");
|
||||
fprintf(stdout, "conf_path Force update with override configuration\n");
|
||||
}
|
||||
|
||||
void
|
||||
print_command_error()
|
||||
{
|
||||
fprintf(stdout, "Invalid command, options are:\n");
|
||||
print_help();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
static struct argp argp = { options, parse_opt, args_doc, doc};
|
||||
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
char* buffer = NULL;
|
||||
char* imraa_conf_file = IMRAA_CONF_FILE;
|
||||
long fsize;
|
||||
bool force_update = false;
|
||||
struct arguments arguments;
|
||||
|
||||
if (argc > 2) {
|
||||
print_command_error();
|
||||
}
|
||||
arguments.silent = 0;
|
||||
arguments.verbose = 0;
|
||||
arguments.force = 0;
|
||||
arguments.input_file = IMRAA_CONF_FILE;
|
||||
|
||||
if (argc > 1) {
|
||||
if (strcmp(argv[1], "help") == 0) {
|
||||
print_help();
|
||||
return EXIT_SUCCESS;
|
||||
} else if (strcmp(argv[1], "version") == 0) {
|
||||
print_version();
|
||||
return EXIT_SUCCESS;
|
||||
} else if (strcmp(argv[1], "force") == 0) {
|
||||
force_update = true;
|
||||
} else {
|
||||
imraa_conf_file = argv[1];
|
||||
force_update = true;
|
||||
}
|
||||
}
|
||||
argp_parse(&argp, argc, argv, 0, 0, &arguments);
|
||||
|
||||
FILE* fh = fopen(imraa_conf_file, "r");
|
||||
FILE* fh = fopen(arguments.input_file, "r");
|
||||
if (fh == NULL) {
|
||||
fprintf(stderr, "Failed to open configuration file\n");
|
||||
return EXIT_FAILURE;
|
||||
@@ -495,28 +157,33 @@ main(int argc, char** argv)
|
||||
buffer = calloc(fsize, sizeof(char));
|
||||
if (buffer != NULL) {
|
||||
int result = fread(buffer, sizeof(char), fsize, fh);
|
||||
if (result != fsize) {
|
||||
printf("imraa conf reading error");
|
||||
if (result != (fsize - 1)) {
|
||||
printf("imraa conf reading error\n");
|
||||
}
|
||||
} else {
|
||||
printf("imraa read_conf buffer can't allocated\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// call reduced imraa_init (not that mraa_init) will already have been called
|
||||
imraa_init();
|
||||
|
||||
json_object* jobj = json_tokener_parse(buffer);
|
||||
if (check_version(jobj) != 0) {
|
||||
if (imraa_check_version(jobj) != 0) {
|
||||
printf("version of configuration file is not compatible, please check again\n");
|
||||
} else {
|
||||
mraa_platform_t type = mraa_get_platform_type();
|
||||
imraa_handle_subplatform(jobj, force_update);
|
||||
if (type == MRAA_NULL_PLATFORM || type == MRAA_UNKNOWN_PLATFORM) {
|
||||
printf("imraa: Failed to do IO pinmuxing on null/unkown platform\n");
|
||||
} else {
|
||||
imraa_handle_IO(jobj);
|
||||
|
||||
if (arguments.arduino) {
|
||||
imraa_handle_subplatform(jobj, arguments.force);
|
||||
}
|
||||
|
||||
if (type == MRAA_NULL_PLATFORM || type == MRAA_UNKNOWN_PLATFORM) {
|
||||
printf("imraa: attempting to do IO pinmuxing on null/unkown platform\n");
|
||||
}
|
||||
imraa_handle_IO(jobj);
|
||||
}
|
||||
|
||||
fclose(fh);
|
||||
json_object_put(jobj);
|
||||
free(buffer);
|
||||
|
@@ -1,12 +1,8 @@
|
||||
{
|
||||
"version": "0.9.6",
|
||||
"version": "1.4.0",
|
||||
"lockfile-location": "/tmp/imraa.lock",
|
||||
"dfu-utils-location": "/usr/bin",
|
||||
"Platform" :[
|
||||
{"id":"1280", "flash":"/usr/share/mraa/firmata101.ino.bin", "usbserial": "auto"}
|
||||
],
|
||||
"IO": [
|
||||
{"type":"gpio", "index":0, "raw": false, "label": "none"},
|
||||
{"type":"i2c", "index":0, "raw": false, "label": "i2c-0"}
|
||||
]
|
||||
}
|
||||
|
12
imraa/imraa.io.conf
Normal file
12
imraa/imraa.io.conf
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"version": "1.4.0",
|
||||
"lockfile-location": "/tmp/imraa.lock",
|
||||
"dfu-utils-location": "/usr/bin",
|
||||
"Platform" :[
|
||||
{"id":"1280", "flash":"/usr/share/mraa/firmata101.ino.bin", "usbserial": "auto"}
|
||||
],
|
||||
"IO": [
|
||||
{"type":"gpio", "index":0, "raw": false, "label": "none", "user": "brendan", "group": "brendan"},
|
||||
{"type":"i2c", "index":0, "raw": false, "label": "i2c-0", "user": "brendan", "group": "user"}
|
||||
]
|
||||
}
|
279
imraa/imraa_arduino.c
Normal file
279
imraa/imraa_arduino.c
Normal file
@@ -0,0 +1,279 @@
|
||||
/*
|
||||
* Author: Brendan Le Foll <brendan.le.foll@intel.com>
|
||||
* Author: Longwei Su <lsu@ics.com>
|
||||
* Copyright (c) 2015-2016 Intel Corporation.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <unistd.h>
|
||||
#include <json-c/json.h>
|
||||
#include <libudev.h>
|
||||
|
||||
#include <argp.h>
|
||||
#include <error.h>
|
||||
|
||||
#include <mraa/uart.h>
|
||||
#include <mraa/gpio.h>
|
||||
#include <mraa/i2c.h>
|
||||
#include <mraa/pwm.h>
|
||||
|
||||
#include <mraa_internal.h>
|
||||
#include <imraa_lock.h>
|
||||
|
||||
const char*
|
||||
imraa_list_serialport()
|
||||
{
|
||||
struct udev* udev;
|
||||
struct udev_enumerate* enumerate;
|
||||
struct udev_list_entry *devices, *dev_list_entry;
|
||||
struct udev_device* dev;
|
||||
const char* ret = NULL;
|
||||
udev = udev_new();
|
||||
if (!udev) {
|
||||
printf("Can't create udev, check libudev\n");
|
||||
exit(1);
|
||||
}
|
||||
enumerate = udev_enumerate_new(udev);
|
||||
udev_enumerate_add_match_subsystem(enumerate, "tty");
|
||||
udev_enumerate_add_match_property(enumerate, "ID_VENDOR_ID", "8087");
|
||||
udev_enumerate_add_match_property(enumerate, "ID_MODEL_ID", "0ab6");
|
||||
// udev_enumerate_add_match_property(enumerate, "ID_SERIAL",
|
||||
// "Intel_ARDUINO_101_AE6642SQ55000RS");
|
||||
udev_enumerate_scan_devices(enumerate);
|
||||
devices = udev_enumerate_get_list_entry(enumerate);
|
||||
|
||||
udev_list_entry_foreach(dev_list_entry, devices)
|
||||
{
|
||||
const char* path;
|
||||
path = udev_list_entry_get_name(dev_list_entry);
|
||||
dev = udev_device_new_from_syspath(udev, path);
|
||||
ret = udev_device_get_devnode(dev);
|
||||
}
|
||||
udev_enumerate_unref(enumerate);
|
||||
udev_unref(udev);
|
||||
|
||||
if (ret) {
|
||||
printf("Ardunio 101 Device Node Path: %s\n", ret);
|
||||
} else {
|
||||
printf("Can't detect any Ardunio 101 Device on tty\n");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
mraa_result_t
|
||||
imraa_reset_arduino(const char* modem)
|
||||
{
|
||||
mraa_uart_context uart;
|
||||
uart = mraa_uart_init_raw(modem);
|
||||
mraa_uart_set_baudrate(uart, 1200);
|
||||
|
||||
if (uart == NULL) {
|
||||
fprintf(stderr, "UART failed to setup\n");
|
||||
return MRAA_ERROR_UNSPECIFIED;
|
||||
}
|
||||
mraa_uart_stop(uart);
|
||||
mraa_deinit();
|
||||
return MRAA_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
imraa_flash_101(const char* bin_path, const char* bin_file_name, const char* tty)
|
||||
{
|
||||
if (imraa_reset_arduino(tty) != MRAA_SUCCESS) {
|
||||
fprintf(stderr, "Failed to reset arduino on %s for unknown reason, carrying on...\n", tty);
|
||||
}
|
||||
|
||||
char* ln = NULL;
|
||||
size_t len = 0;
|
||||
bool board_found = false;
|
||||
const char* dfu_list = "/dfu-util -d ,8087:0ABA -l";
|
||||
size_t bin_path_len = strlen(bin_path);
|
||||
|
||||
char* full_dfu_list = (char*) calloc((bin_path_len + strlen(dfu_list) + 1), sizeof(char));
|
||||
if (!full_dfu_list) {
|
||||
printf("imraa_flash_101 can't allocate string buffer for dfu list\n");
|
||||
exit(1);
|
||||
}
|
||||
strncat(full_dfu_list, bin_path, strlen(bin_path));
|
||||
strncat(full_dfu_list, dfu_list, strlen(dfu_list));
|
||||
|
||||
int i;
|
||||
// dfu list is still needed, as the time for reset and recognized is varies from platform to
|
||||
// platform.
|
||||
// once dfu able to query available devices, then it is ready to flash
|
||||
for (i = 0; i < 10 && board_found == false; i++) {
|
||||
printf("Waiting for device...\n");
|
||||
// dfu-util -d,8087:0ABA -l
|
||||
FILE* dfu_result = popen(full_dfu_list, "r");
|
||||
if (dfu_result == NULL) {
|
||||
printf("Failed to run command\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (i == 4) {
|
||||
printf("Flashing is taking longer than expected\n");
|
||||
printf("Try pressing MASTER_RESET button\n");
|
||||
}
|
||||
|
||||
while (getline(&ln, &len, dfu_result) != -1) {
|
||||
if (strstr(ln, "sensor_core")) {
|
||||
board_found = true;
|
||||
printf("Device found!\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
sleep(1);
|
||||
if (pclose(dfu_result) != 0) {
|
||||
printf("Failed to close command\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
free(ln);
|
||||
|
||||
if (board_found == false) {
|
||||
printf("ERROR: Device is not responding.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
const char* dfu_upload = "/dfu-util -d ,8087:0ABA -D ";
|
||||
const char* dfu_option = " -v -a 7 -R";
|
||||
int buffersize = bin_path_len + strlen(dfu_upload) + strlen(bin_file_name) + strlen(dfu_option) + 1;
|
||||
char* full_dfu_upload = calloc(buffersize, sizeof(char));
|
||||
if (!full_dfu_upload) {
|
||||
printf("imraa_flash_101 can't allocate string buffer for dfu flash\n");
|
||||
exit(1);
|
||||
}
|
||||
strncat(full_dfu_upload, bin_path, strlen(bin_path));
|
||||
strncat(full_dfu_upload, dfu_upload, strlen(dfu_upload));
|
||||
strncat(full_dfu_upload, bin_file_name, strlen(bin_file_name));
|
||||
strncat(full_dfu_upload, dfu_option, strlen(dfu_option));
|
||||
printf("flash cmd: %s\n", full_dfu_upload);
|
||||
int status = system(full_dfu_upload);
|
||||
if (status != 0) {
|
||||
printf("ERROR: Upload failed on %s\n", tty);
|
||||
exit(1);
|
||||
}
|
||||
printf("SUCCESS: Sketch will execute in about 5 seconds.\n");
|
||||
free(full_dfu_list);
|
||||
free(full_dfu_upload);
|
||||
sleep(5);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
imraa_handle_subplatform(struct json_object* jobj, bool force_update)
|
||||
{
|
||||
struct json_object* platform;
|
||||
int i, ionum;
|
||||
const char* dfu_loc = NULL;
|
||||
const char* lockfile_loc = NULL;
|
||||
const char* flash_loc = NULL;
|
||||
const char* usbserial = NULL;
|
||||
|
||||
struct json_object* dfu_location;
|
||||
if (json_object_object_get_ex(jobj, "dfu-utils-location", &dfu_location) == true) {
|
||||
if (json_object_is_type(dfu_location, json_type_string)) {
|
||||
printf("dfu location: %s\n", json_object_get_string(dfu_location));
|
||||
dfu_loc = json_object_get_string(dfu_location);
|
||||
} else {
|
||||
fprintf(stderr, "dfu location string incorrectly parsed\n");
|
||||
}
|
||||
}
|
||||
|
||||
struct json_object* lockfile_location;
|
||||
if (json_object_object_get_ex(jobj, "lockfile-location", &lockfile_location) == true) {
|
||||
if (json_object_is_type(lockfile_location, json_type_string)) {
|
||||
printf("lock file location: %s\n", json_object_get_string(lockfile_location));
|
||||
lockfile_loc = json_object_get_string(lockfile_location);
|
||||
} else {
|
||||
fprintf(stderr, "lock file string incorrectly parsed\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (json_object_object_get_ex(jobj, "Platform", &platform) == true) {
|
||||
if (json_object_is_type(platform, json_type_array)) {
|
||||
ionum = json_object_array_length(platform);
|
||||
for (i = 0; i < ionum; i++) {
|
||||
struct json_object* ioobj = json_object_array_get_idx(platform, i);
|
||||
json_object_object_foreach(ioobj, key, val)
|
||||
{
|
||||
if (strcmp(key, "flash") == 0) {
|
||||
flash_loc = json_object_get_string(val);
|
||||
}
|
||||
if (strcmp(key, "usbserial") == 0) {
|
||||
usbserial = json_object_get_string(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "platform string incorrectly parsed\n");
|
||||
}
|
||||
}
|
||||
if (flash_loc == NULL || usbserial == NULL ) {
|
||||
printf("conf didn't give image location or usb serial, skip flashing\n");
|
||||
return;
|
||||
}
|
||||
if (!dfu_loc) {
|
||||
dfu_loc = "/usr/bin";
|
||||
printf("No dfu path found, using default path /usr/bin instead");
|
||||
}
|
||||
if (!lockfile_loc) {
|
||||
lockfile_loc = "/tmp/imraa.lock";
|
||||
printf("No lock path found, using default lock file /tmp/imraa.lock instead");
|
||||
}
|
||||
|
||||
// got flash? do flash
|
||||
if (access(lockfile_loc, F_OK) != -1 && force_update == false) {
|
||||
printf("already exist a lock file, skip flashing\n");
|
||||
printf("force upgrade? remove the lockfile or run with force\n");
|
||||
return;
|
||||
} else {
|
||||
fprintf(stdout, "Starting to flash board\n");
|
||||
if (force_update) {
|
||||
fprintf(stdout, "**Caution: force update mode**\n");
|
||||
}
|
||||
|
||||
// TODO flash img checksum, and serialport validation?
|
||||
const char* detected_serialport = imraa_list_serialport();
|
||||
if (detected_serialport == NULL) {
|
||||
printf("No subplatform detected, check USB connection, skip flashing\n");
|
||||
return;
|
||||
}
|
||||
if (strcmp(usbserial, "auto") != 0 && strcmp(usbserial, detected_serialport) != 0) {
|
||||
printf("given serial port didn't match detected serial port, skip flashing\n");
|
||||
return;
|
||||
}
|
||||
if (imraa_flash_101(dfu_loc, flash_loc, detected_serialport) == 0) {
|
||||
imraa_write_lockfile(lockfile_loc, detected_serialport);
|
||||
} else {
|
||||
fprintf(stderr, "invalid flashing paramenters, please check agian\n");
|
||||
fprintf(stderr, "DFU Util location: %s\n", dfu_loc);
|
||||
fprintf(stderr, "Flash Img location: %s\n", dfu_loc);
|
||||
fprintf(stderr, "USB Serial: %s\n", usbserial);
|
||||
fprintf(stderr, "Flash failed, push master reset and try again\n");
|
||||
}
|
||||
}
|
||||
}
|
29
imraa/imraa_arduino.h
Normal file
29
imraa/imraa_arduino.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Author: Brendan Le Foll <brendan.le.folL@intel.com>
|
||||
* Copyright (c) 2016 Intel Corporation.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
void imraa_handle_subplatform(struct json_object* jobj, bool force_update);
|
||||
|
||||
|
178
imraa/imraa_io.c
Normal file
178
imraa/imraa_io.c
Normal file
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Author: Brendan Le Foll <brendan.le.foll@intel.com>
|
||||
* Copyright (c) 2015-2016 Intel Corporation.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <unistd.h>
|
||||
#include <error.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <json-c/json.h>
|
||||
|
||||
#include <pwd.h>
|
||||
|
||||
#include <mraa/uart.h>
|
||||
#include <mraa/gpio.h>
|
||||
#include <mraa/i2c.h>
|
||||
#include <mraa/pwm.h>
|
||||
|
||||
#include <mraa_internal.h>
|
||||
|
||||
#include <imraa_arduino.h>
|
||||
|
||||
#define SYSFS_CLASS_GPIO "/sys/class/gpio"
|
||||
#define MAX_SIZE 64
|
||||
|
||||
typedef struct mraa_io_objects_t {
|
||||
const char* type;
|
||||
int index;
|
||||
bool raw;
|
||||
const char* label;
|
||||
const char* user;
|
||||
} mraa_io_objects_t;
|
||||
|
||||
void
|
||||
imraa_handle_IO(struct json_object* jobj)
|
||||
{
|
||||
struct mraa_io_objects_t* mraa_io_obj;
|
||||
struct json_object* ioarray;
|
||||
int ionum = 0;
|
||||
int i;
|
||||
if (json_object_object_get_ex(jobj, "IO", &ioarray) == true) {
|
||||
ionum = json_object_array_length(ioarray);
|
||||
printf("Length of IO array is %d\n", ionum);
|
||||
mraa_io_obj = (mraa_io_objects_t*) calloc(ionum, sizeof(mraa_io_objects_t));
|
||||
if (!mraa_io_obj) {
|
||||
printf("imraa_handle_IO malloc failed\n");
|
||||
exit(1);
|
||||
}
|
||||
int index2 = -1;
|
||||
// optional index for io configuration;
|
||||
if (json_object_is_type(ioarray, json_type_array)) {
|
||||
for (i = 0; i < ionum; i++) {
|
||||
struct json_object* ioobj = json_object_array_get_idx(ioarray, i);
|
||||
struct json_object* x;
|
||||
if (json_object_object_get_ex(ioobj, "type", &x) == true) {
|
||||
mraa_io_obj[i].type = json_object_get_string(x);
|
||||
}
|
||||
if (json_object_object_get_ex(ioobj, "index", &x) == true) {
|
||||
mraa_io_obj[i].index = json_object_get_int(x);
|
||||
}
|
||||
if (json_object_object_get_ex(ioobj, "raw", &x) == true) {
|
||||
mraa_io_obj[i].raw = json_object_get_boolean(x);
|
||||
}
|
||||
if (json_object_object_get_ex(ioobj, "label", &x) == true) {
|
||||
mraa_io_obj[i].label = json_object_get_string(x);
|
||||
}
|
||||
if (json_object_object_get_ex(ioobj, "index2", &x) == true) {
|
||||
index2 = json_object_get_int(x);
|
||||
}
|
||||
if (json_object_object_get_ex(ioobj, "user", &x) == true) {
|
||||
mraa_io_obj[i].user = json_object_get_string(x);
|
||||
}
|
||||
// starting io configuration
|
||||
if (strcmp(mraa_io_obj[i].type, "gpio") == 0) {
|
||||
mraa_gpio_context gpio = NULL;
|
||||
if (mraa_io_obj[i].raw) {
|
||||
gpio = mraa_gpio_init_raw(mraa_io_obj[i].index);
|
||||
} else {
|
||||
gpio = mraa_gpio_init(mraa_io_obj[i].index);
|
||||
}
|
||||
if (gpio != NULL) {
|
||||
if (mraa_io_obj[i].user != NULL) {
|
||||
int sysfs_gpio_pin = mraa_gpio_get_pin_raw(gpio);
|
||||
if (sysfs_gpio_pin >= 0) {
|
||||
char bu[MAX_SIZE];
|
||||
snprintf(bu, MAX_SIZE, SYSFS_CLASS_GPIO "/gpio%d/value", sysfs_gpio_pin);
|
||||
struct passwd* user = getpwnam(mraa_io_obj[i].user);
|
||||
if (user != NULL) {
|
||||
if (chown(bu, user->pw_uid, user->pw_gid) == -1) {
|
||||
fprintf(stderr, "Couldn't change ownership of file %s to %d:%d\n", bu, user->pw_uid, user->pw_gid);
|
||||
} else {
|
||||
fprintf(stderr, "Invalid user %s\n", mraa_io_obj[i].user);
|
||||
}
|
||||
}
|
||||
}
|
||||
mraa_result_t r = mraa_gpio_owner(gpio, 0);
|
||||
if (r != MRAA_SUCCESS) {
|
||||
mraa_result_print(r);
|
||||
}
|
||||
mraa_gpio_close(gpio);
|
||||
}
|
||||
} else if (strcmp(mraa_io_obj[i].type, "i2c") == 0) {
|
||||
mraa_i2c_context i2c = NULL;
|
||||
if (mraa_io_obj[i].raw) {
|
||||
i2c = mraa_i2c_init_raw(mraa_io_obj[i].index);
|
||||
} else {
|
||||
i2c = mraa_i2c_init(mraa_io_obj[i].index);
|
||||
}
|
||||
if (i2c != NULL) {
|
||||
mraa_i2c_stop(i2c);
|
||||
}
|
||||
} else if (strcmp(mraa_io_obj[i].type, "pwm") == 0) {
|
||||
mraa_pwm_context pwm = NULL;
|
||||
if (mraa_io_obj[i].raw) {
|
||||
pwm = mraa_pwm_init_raw(index2, mraa_io_obj[i].index);
|
||||
} else {
|
||||
pwm = mraa_pwm_init(mraa_io_obj[i].index);
|
||||
}
|
||||
if (pwm != NULL) {
|
||||
mraa_result_t r = mraa_pwm_owner(pwm, 0);
|
||||
if (r != MRAA_SUCCESS) {
|
||||
mraa_result_print(r);
|
||||
}
|
||||
mraa_pwm_close(pwm);
|
||||
}
|
||||
} else if (strcmp(mraa_io_obj[i].type, "spi") == 0) {
|
||||
mraa_spi_context spi = NULL;
|
||||
if (mraa_io_obj[i].raw) {
|
||||
spi = mraa_spi_init_raw(mraa_io_obj[i].index, index2);
|
||||
} else {
|
||||
spi = mraa_spi_init(mraa_io_obj[i].index);
|
||||
}
|
||||
if (spi != NULL) {
|
||||
mraa_spi_stop(spi);
|
||||
}
|
||||
} else if (strcmp(mraa_io_obj[i].type, "uart") == 0) {
|
||||
mraa_uart_context uart = NULL;
|
||||
if (mraa_io_obj[i].raw) {
|
||||
uart = mraa_uart_init_raw(mraa_io_obj[i].label);
|
||||
} else {
|
||||
uart = mraa_uart_init(mraa_io_obj[i].index);
|
||||
}
|
||||
if (uart != NULL) {
|
||||
mraa_uart_stop(uart);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "IO array incorrectly parsed\n");
|
||||
}
|
||||
free(mraa_io_obj);
|
||||
}
|
||||
}
|
28
imraa/imraa_io.h
Normal file
28
imraa/imraa_io.h
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Author: Brendan Le Foll <brendan.le.folL@intel.com>
|
||||
* Copyright (c) 2016 Intel Corporation.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
void imraa_handle_IO(struct json_object* jobj);
|
||||
|
71
imraa/imraa_lock.c
Normal file
71
imraa/imraa_lock.c
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Author: Brendan Le Foll <brendan.le.foll@intel.com>
|
||||
* Copyright (c) 2016 Intel Corporation.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <unistd.h>
|
||||
#include <json-c/json.h>
|
||||
#include <libudev.h>
|
||||
|
||||
#include <argp.h>
|
||||
#include <error.h>
|
||||
|
||||
#include <mraa/uart.h>
|
||||
#include <mraa/gpio.h>
|
||||
#include <mraa/i2c.h>
|
||||
#include <mraa/pwm.h>
|
||||
|
||||
#include <mraa_internal.h>
|
||||
|
||||
void
|
||||
imraa_write_lockfile(const char* lock_file_location, const char* serialport)
|
||||
{
|
||||
FILE* fh;
|
||||
char str[10];
|
||||
json_object* platform1 = json_object_new_object();
|
||||
snprintf(str, 10, "%d", MRAA_NULL_PLATFORM);
|
||||
json_object_object_add(platform1, "id", json_object_new_string(str));
|
||||
|
||||
json_object* platform2 = json_object_new_object();
|
||||
snprintf(str, 10, "%d", MRAA_GENERIC_FIRMATA);
|
||||
json_object_object_add(platform2, "id", json_object_new_string(str));
|
||||
json_object_object_add(platform2, "uart", json_object_new_string(serialport));
|
||||
|
||||
json_object* platfroms = json_object_new_array();
|
||||
json_object_array_add(platfroms, platform1);
|
||||
json_object_array_add(platfroms, platform2);
|
||||
json_object* lock_file = json_object_new_object();
|
||||
json_object_object_add(lock_file, "Platform", platfroms);
|
||||
fh = fopen(lock_file_location, "w");
|
||||
if (fh != NULL) {
|
||||
fputs(json_object_to_json_string_ext(lock_file, JSON_C_TO_STRING_PRETTY), fh);
|
||||
fclose(fh);
|
||||
} else {
|
||||
fprintf(stderr, "can't write to lock file\n");
|
||||
}
|
||||
json_object_put(lock_file);
|
||||
}
|
28
imraa/imraa_lock.h
Normal file
28
imraa/imraa_lock.h
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Author: Brendan Le Foll <brendan.le.folL@intel.com>
|
||||
* Copyright (c) 2016 Intel Corporation.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
void imraa_write_lockfile(const char* lock_file_location, const char* serialport);
|
||||
|
@@ -24,6 +24,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#include "uart.h"
|
||||
|
||||
#define MODE_INPUT 0x00
|
||||
@@ -99,6 +101,7 @@ typedef struct s_firmata {
|
||||
char firmware[140];
|
||||
uint8_t dev_count;
|
||||
struct _firmata** devs;
|
||||
pthread_spinlock_t lock;
|
||||
} t_firmata;
|
||||
|
||||
t_firmata* firmata_new(const char* name);
|
||||
|
@@ -39,6 +39,13 @@ firmata_new(const char* name)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int ret = pthread_spin_init(&res->lock, PTHREAD_PROCESS_SHARED);
|
||||
if (ret != 0) {
|
||||
syslog(LOG_ERR, "firmata; could not init locking");
|
||||
free(res);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
res->uart = mraa_uart_init_raw(name);
|
||||
if (res->uart == NULL) {
|
||||
syslog(LOG_ERR, "firmata: UART failed to setup");
|
||||
@@ -133,7 +140,9 @@ firmata_endParse(t_firmata* firmata)
|
||||
int analog_val = firmata->parse_buff[1] | (firmata->parse_buff[2] << 7);
|
||||
for (pin = 0; pin < 128; pin++) {
|
||||
if (firmata->pins[pin].analog_channel == analog_ch) {
|
||||
pthread_spin_lock(&firmata->lock);
|
||||
firmata->pins[pin].value = analog_val;
|
||||
pthread_spin_unlock(&firmata->lock);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -147,7 +156,9 @@ firmata_endParse(t_firmata* firmata)
|
||||
for (mask = 1; mask & 0xFF; mask <<= 1, pin++) {
|
||||
if (firmata->pins[pin].mode == MODE_INPUT) {
|
||||
uint32_t val = (port_val & mask) ? 1 : 0;
|
||||
pthread_spin_lock(&firmata->lock);
|
||||
firmata->pins[pin].value = val;
|
||||
pthread_spin_unlock(&firmata->lock);
|
||||
}
|
||||
}
|
||||
return;
|
||||
@@ -240,10 +251,12 @@ firmata_endParse(t_firmata* firmata)
|
||||
int reg = (firmata->parse_buff[4] & 0x7f) | ((firmata->parse_buff[5] & 0x7f) << 7);
|
||||
int i = 6;
|
||||
int ii = 0;
|
||||
pthread_spin_lock(&firmata->lock);
|
||||
for (; ii < (firmata->parse_count - 7) / 2; ii++) {
|
||||
firmata->i2cmsg[addr][reg+ii] = (firmata->parse_buff[i] & 0x7f) | ((firmata->parse_buff[i+1] & 0x7f) << 7);
|
||||
i = i+2;
|
||||
}
|
||||
pthread_spin_unlock(&firmata->lock);
|
||||
} else {
|
||||
if (firmata->devs != NULL) {
|
||||
struct _firmata* devs = firmata->devs[0];
|
||||
|
@@ -84,6 +84,7 @@ mraa_result_t
|
||||
mraa_firmata_close(mraa_firmata_context dev)
|
||||
{
|
||||
mraa_firmata_response_stop(dev);
|
||||
pthread_spin_destroy(&firmata_dev->lock);
|
||||
free(dev);
|
||||
return MRAA_SUCCESS;
|
||||
}
|
||||
@@ -182,11 +183,17 @@ static mraa_result_t
|
||||
mraa_firmata_i2c_wait(int addr, int reg)
|
||||
{
|
||||
int i = 0;
|
||||
for (; firmata_dev->i2cmsg[addr][reg] == -1; i++) {
|
||||
pthread_spin_lock(&firmata_dev->lock);
|
||||
int res = firmata_dev->i2cmsg[addr][reg];
|
||||
pthread_spin_unlock(&firmata_dev->lock);
|
||||
for (; res == -1; i++) {
|
||||
if (i > 50) {
|
||||
return MRAA_ERROR_UNSPECIFIED;
|
||||
}
|
||||
usleep(500);
|
||||
pthread_spin_lock(&firmata_dev->lock);
|
||||
res = firmata_dev->i2cmsg[addr][reg];
|
||||
pthread_spin_unlock(&firmata_dev->lock);
|
||||
}
|
||||
return MRAA_SUCCESS;
|
||||
}
|
||||
@@ -345,7 +352,10 @@ mraa_firmata_aio_read(mraa_aio_context dev)
|
||||
{
|
||||
// careful, whilst you need to enable '0' for A0 you then need to read 14
|
||||
// in t_firmata because well that makes sense doesn't it...
|
||||
return (int) firmata_dev->pins[dev->channel].value;
|
||||
pthread_spin_lock(&firmata_dev->lock);
|
||||
int ret = (int) firmata_dev->pins[dev->channel].value;
|
||||
pthread_spin_unlock(&firmata_dev->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static mraa_result_t
|
||||
@@ -380,7 +390,10 @@ mraa_firmata_gpio_mode_replace(mraa_gpio_context dev, mraa_gpio_mode_t mode)
|
||||
static int
|
||||
mraa_firmata_gpio_read_replace(mraa_gpio_context dev)
|
||||
{
|
||||
return firmata_dev->pins[dev->pin].value;
|
||||
pthread_spin_lock(&firmata_dev->lock);
|
||||
int res = firmata_dev->pins[dev->pin].value;
|
||||
pthread_spin_unlock(&firmata_dev->lock);
|
||||
return res;
|
||||
}
|
||||
|
||||
static mraa_result_t
|
||||
|
@@ -44,7 +44,7 @@ static mraa_result_t
|
||||
mraa_gpio_get_valfp(mraa_gpio_context dev)
|
||||
{
|
||||
char bu[MAX_SIZE];
|
||||
sprintf(bu, SYSFS_CLASS_GPIO "/gpio%d/value", dev->pin);
|
||||
snprintf(bu, MAX_SIZE, SYSFS_CLASS_GPIO "/gpio%d/value", dev->pin);
|
||||
dev->value_fp = open(bu, O_RDWR);
|
||||
if (dev->value_fp == -1) {
|
||||
syslog(LOG_ERR, "gpio%i: Failed to open 'value': %s", dev->pin, strerror(errno));
|
||||
|
14
src/mraa.c
14
src/mraa.c
@@ -1039,6 +1039,10 @@ mraa_add_subplatform(mraa_platform_t subplatformtype, const char* uart_dev)
|
||||
return MRAA_SUCCESS;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (subplatformtype == MRAA_GENERIC_FIRMATA) {
|
||||
syslog(LOG_NOTICE, "mraa: Cannot add Firmata platform as support not compiled in");
|
||||
}
|
||||
#endif
|
||||
|
||||
return MRAA_ERROR_INVALID_PARAMETER;
|
||||
@@ -1112,7 +1116,15 @@ mraa_add_from_lockfile(const char* imraa_lock_file)
|
||||
uartdev = NULL;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (json_object_object_get_ex(jobj_lock, "IO", &ioarray) == true &&
|
||||
json_object_is_type(ioarray, json_type_array)) {
|
||||
/* assume we have declared IO so we are preinitialised and wipe the
|
||||
* advance func array
|
||||
*/
|
||||
memset(plat->adv_func, 0, sizeof(mraa_adv_func_t));
|
||||
}
|
||||
}
|
||||
else {
|
||||
ret = MRAA_ERROR_INVALID_RESOURCE;
|
||||
}
|
||||
json_object_put(jobj_lock);
|
||||
|
@@ -208,11 +208,14 @@ mraa_intel_edison_gpio_init_post(mraa_gpio_context dev)
|
||||
mraa_result_t
|
||||
mraa_intel_edison_gpio_close_pre(mraa_gpio_context dev)
|
||||
{
|
||||
if (dev->phy_pin >= 0) {
|
||||
int pin = dev->phy_pin;
|
||||
if (agpioOutputen[pin]) {
|
||||
mraa_gpio_close(agpioOutputen[pin]);
|
||||
agpioOutputen[pin] = NULL;
|
||||
// check if we own it
|
||||
if (dev->owner != 0) {
|
||||
if (dev->phy_pin >= 0) {
|
||||
int pin = dev->phy_pin;
|
||||
if (agpioOutputen[pin]) {
|
||||
mraa_gpio_close(agpioOutputen[pin]);
|
||||
agpioOutputen[pin] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
return MRAA_SUCCESS;
|
||||
|
Reference in New Issue
Block a user