Skip to content

Commit

Permalink
Runtime logging configuration; asynchronous USB requests; helper tool…
Browse files Browse the repository at this point in the history
…s for acceptance testing
  • Loading branch information
sergeuz committed Oct 29, 2016
1 parent 7d404a8 commit cbda226
Show file tree
Hide file tree
Showing 42 changed files with 3,429 additions and 663 deletions.
8 changes: 6 additions & 2 deletions services/inc/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,13 @@
#undef DEBUG_BUILD
#endif

#if defined(DEBUG_BUILD) && !defined(LOG_INCLUDE_SOURCE_INFO)
#define LOG_INCLUDE_SOURCE_INFO
#ifndef LOG_INCLUDE_SOURCE_INFO
#ifdef DEBUG_BUILD
#define LOG_INCLUDE_SOURCE_INFO 1
#else
#define LOG_INCLUDE_SOURCE_INFO 0
#endif
#endif // !defined(LOG_INCLUDE_SOURCE_INFO)

#define MAX_SEC_WAIT_CONNECT 8 // Number of second a TCP, spark will wait
#define MAX_FAILED_CONNECTS 2 // Number of time a connect can fail
Expand Down
10 changes: 7 additions & 3 deletions services/inc/logging.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,8 @@
Following macros configure logging module at compile time:
LOG_INCLUDE_SOURCE_INFO - allows to include source info (file name, function name, line number)
into messages generated by the logging macros. By default, this macro is defined only for debug
builds (see config.h).
into messages generated by the logging macros. Default value is 0 for release builds and 1 for
debug builds (see config.h).
LOG_COMPILE_TIME_LEVEL - allows to strip any logging output that is below of certain logging level
at compile time. Default value is LOG_LEVEL_ALL meaning that no compile-time filtering is applied.
Expand Down Expand Up @@ -236,6 +236,10 @@ extern void HAL_Delay_Microseconds(uint32_t delay);
#define LOG_MAX_STRING_LENGTH 160
#endif

#ifndef LOG_INCLUDE_SOURCE_INFO
#define LOG_INCLUDE_SOURCE_INFO 0
#endif

// Sets log message attribute
#define LOG_ATTR_SET(_attr, _name, _val) \
do { \
Expand Down Expand Up @@ -308,7 +312,7 @@ static const char* const _log_category = NULL;

#endif // !defined(__cplusplus)

#ifdef LOG_INCLUDE_SOURCE_INFO
#if LOG_INCLUDE_SOURCE_INFO
#define _LOG_ATTR_SET_SOURCE_INFO(_attr) \
LOG_ATTR_SET(_attr, file, __FILE__); \
LOG_ATTR_SET(_attr, line, __LINE__); \
Expand Down
35 changes: 20 additions & 15 deletions services/src/logging.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,20 +78,21 @@ void log_set_callbacks(log_message_callback_type log_msg, log_write_callback_typ
}

void log_message_v(int level, const char *category, LogAttributes *attr, void *reserved, const char *fmt, va_list args) {
if (!log_msg_callback && (!log_compat_callback || level < log_compat_level)) {
const log_message_callback_type msg_callback = log_msg_callback;
if (!msg_callback && (!log_compat_callback || level < log_compat_level)) {
return;
}
// Set default attributes
if (!attr->has_time) {
LOG_ATTR_SET(*attr, time, HAL_Timer_Get_Milli_Seconds());
}
char buf[LOG_MAX_STRING_LENGTH];
if (log_msg_callback) {
if (msg_callback) {
const int n = vsnprintf(buf, sizeof(buf), fmt, args);
if (n > (int)sizeof(buf) - 1) {
buf[sizeof(buf) - 2] = '~';
}
log_msg_callback(buf, level, category, attr, 0);
msg_callback(buf, level, category, attr, 0);
} else {
// Using compatibility callback
const char* const levelName = log_level_name(level, 0);
Expand Down Expand Up @@ -127,8 +128,9 @@ void log_write(int level, const char *category, const char *data, size_t size, v
if (!size) {
return;
}
if (log_write_callback) {
log_write_callback(data, size, level, category, 0);
const log_write_callback_type write_callback = log_write_callback;
if (write_callback) {
write_callback(data, size, level, category, 0);
} else if (log_compat_callback && level >= log_compat_level) {
// Compatibility callback expects null-terminated strings
if (!data[size - 1]) {
Expand All @@ -148,7 +150,8 @@ void log_write(int level, const char *category, const char *data, size_t size, v
}

void log_printf_v(int level, const char *category, void *reserved, const char *fmt, va_list args) {
if (!log_write_callback && (!log_compat_callback || level < log_compat_level)) {
const log_write_callback_type write_callback = log_write_callback;
if (!write_callback && (!log_compat_callback || level < log_compat_level)) {
return;
}
char buf[LOG_MAX_STRING_LENGTH];
Expand All @@ -157,8 +160,8 @@ void log_printf_v(int level, const char *category, void *reserved, const char *f
buf[sizeof(buf) - 2] = '~';
n = sizeof(buf) - 1;
}
if (log_write_callback) {
log_write_callback(buf, n, level, category, 0);
if (write_callback) {
write_callback(buf, n, level, category, 0);
} else {
log_compat_callback(buf); // Compatibility callback
}
Expand All @@ -172,7 +175,8 @@ void log_printf(int level, const char *category, void *reserved, const char *fmt
}

void log_dump(int level, const char *category, const void *data, size_t size, int flags, void *reserved) {
if (!size || (!log_write_callback && (!log_compat_callback || level < log_compat_level))) {
const log_write_callback_type write_callback = log_write_callback;
if (!size || (!write_callback && (!log_compat_callback || level < log_compat_level))) {
return;
}
static const char hex[] = "0123456789abcdef";
Expand All @@ -184,17 +188,17 @@ void log_dump(int level, const char *category, const void *data, size_t size, in
buf[offs++] = hex[b >> 4];
buf[offs++] = hex[b & 0x0f];
if (offs == sizeof(buf) - 1) {
if (log_write_callback) {
log_write_callback(buf, sizeof(buf) - 1, level, category, 0);
if (write_callback) {
write_callback(buf, sizeof(buf) - 1, level, category, 0);
} else {
log_compat_callback(buf);
}
offs = 0;
}
}
if (offs) {
if (log_write_callback) {
log_write_callback(buf, offs, level, category, 0);
if (write_callback) {
write_callback(buf, offs, level, category, 0);
} else {
buf[offs] = 0;
log_compat_callback(buf);
Expand All @@ -203,8 +207,9 @@ void log_dump(int level, const char *category, const void *data, size_t size, in
}

int log_enabled(int level, const char *category, void *reserved) {
if (log_enabled_callback) {
return log_enabled_callback(level, category, 0);
const log_enabled_callback_type enabled_callback = log_enabled_callback;
if (enabled_callback) {
return enabled_callback(level, category, 0);
}
if (log_compat_callback && level >= log_compat_level) { // Compatibility callback
return 1;
Expand Down
2 changes: 1 addition & 1 deletion system-dynalib/makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ SYSTEM_DYNALIB_MODULE_PATH=.

TARGET_TYPE = a
BUILD_PATH_EXT = $(SYSTEM_DYNALIB_BUILD_PATH_EXT)
DEPENDENCIES = system dynalib
DEPENDENCIES = system dynalib hal

include ../build/arm-tlm.mk
32 changes: 31 additions & 1 deletion system/inc/active_object.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,15 @@

#pragma once

#include <cstddef>

#if PLATFORM_THREADING

#include <functional>
#include <mutex>
#include <thread>
#include <future>

#include "channel.h"
#include "concurrent_hal.h"

Expand Down Expand Up @@ -435,4 +438,31 @@ class ActiveObjectThreadQueue : public ActiveObjectQueue



#endif
#endif // PLATFORM_THREADING

/**
* This class implements a queue of asynchronous calls that can be scheduled from an ISR and then
* invoked from an event loop running in a regular thread.
*/
class ISRTaskQueue {
public:
typedef void(*TaskFunc)(void*);

explicit ISRTaskQueue(size_t size);
~ISRTaskQueue();

bool enqueue(TaskFunc func, void* data = nullptr); // Called from an ISR
bool process(); // Called from the primary thread

private:
struct Task {
TaskFunc func;
void* data;
Task* next;
};

Task* tasks_;
Task* availTask_; // Task pool
Task* firstTask_; // Task queue
Task* lastTask_;
};
85 changes: 82 additions & 3 deletions system/inc/system_control.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,99 @@
#ifndef SYSTEM_CONTROL_H_
#define SYSTEM_CONTROL_H_

#include <stddef.h>

#include "usb_hal.h"

typedef enum DataFormat { // TODO: Move to appropriate header
DATA_FORMAT_INVALID = 0,
DATA_FORMAT_BINARY = 10, // Generic binary format
DATA_FORMAT_TEXT = 20, // Generic text format
DATA_FORMAT_JSON = 30
} DataFormat;

#ifdef USB_VENDOR_REQUEST_ENABLE

// Maximum supported size of USB request/reply data
#define USB_REQUEST_BUFFER_SIZE 512

#ifdef __cplusplus
extern "C" {
#endif

typedef enum USBRequestType {
USB_REQUEST_INVALID = 0,
USB_REQUEST_CUSTOM = 10, // Customizable request processed in application thread
USB_REQUEST_DEVICE_ID = 20,
USB_REQUEST_SYSTEM_VERSION = 30,
USB_REQUEST_RESET = 40,
USB_REQUEST_DFU_MODE = 50,
USB_REQUEST_SAFE_MODE = 60,
USB_REQUEST_LISTENING_MODE = 70,
USB_REQUEST_LOG_CONFIG = 80
} USBRequestType;

typedef enum USBRequestResult {
USB_REQUEST_RESULT_OK = 0,
USB_REQUEST_RESULT_ERROR = 10
} USBRequestResult;

typedef struct USBRequest {
size_t size; // Structure size
int type; // Request type (as defined by USBRequestType enum)
char* data; // Data buffer
size_t request_size; // Request size
size_t reply_size; // Reply size (initialized to 0)
int format; // Data format (as defined by DataFormat enum)
} USBRequest;

// Callback invoked for USB requests that should be processed at application side
typedef bool(*usb_request_app_handler_type)(USBRequest* req, void* reserved);

// Sets application callback for USB requests
void system_set_usb_request_app_handler(usb_request_app_handler_type handler, void* reserved);

// Signals that processing of the USB request has finished
void system_set_usb_request_result(USBRequest* req, int result, void* reserved);

#ifdef __cplusplus
} // extern "C"

class SystemControlInterface {
public:
SystemControlInterface();
~SystemControlInterface();
uint8_t handleVendorRequest(HAL_USB_SetupRequest* req);

static void setRequestResult(USBRequest* req, USBRequestResult result);

private:
static uint8_t vendorRequestCallback(HAL_USB_SetupRequest* req, void* ptr);
struct USBRequestData {
USBRequest req; // Externally accessible part of the request data
USBRequestResult result;
bool active;
volatile bool ready;

USBRequestData();
~USBRequestData();
};

USBRequestData usbReq_;

uint8_t handleVendorRequest(HAL_USB_SetupRequest* req);

uint8_t enqueueRequest(HAL_USB_SetupRequest* req, DataFormat fmt = DATA_FORMAT_BINARY);
uint8_t fetchRequestResult(HAL_USB_SetupRequest* req);

static void processSystemRequest(void* data); // Called by SystemThread
static void processAppRequest(void* data); // Called by ApplicationThread

static uint8_t vendorRequestCallback(HAL_USB_SetupRequest* req, void* data); // Called by HAL

static bool setRequestResult(USBRequest* req, const char* data, size_t size);
};

#endif // __cplusplus

#endif // USB_VENDOR_REQUEST_ENABLE

#endif // SYSTEM_CONTROL_H_
#endif // SYSTEM_CONTROL_H_
12 changes: 11 additions & 1 deletion system/inc/system_dynalib.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#define SYSTEM_DYNALIB_H

#include "dynalib.h"
#include "usb_hal.h"

#ifdef DYNALIB_EXPORT
#include "system_mode.h"
Expand All @@ -33,6 +34,7 @@
#include "system_update.h"
#include "system_event.h"
#include "system_version.h"
#include "system_control.h"
#endif

DYNALIB_BEGIN(system)
Expand Down Expand Up @@ -62,8 +64,16 @@ DYNALIB_FN(18, system, Spark_Finish_Firmware_Update, int(FileTransfer::Descripto
DYNALIB_FN(19, system, application_thread_current, uint8_t(void*))
DYNALIB_FN(20, system, system_thread_current, uint8_t(void*))

#ifdef USB_VENDOR_REQUEST_ENABLE
DYNALIB_FN(21, system, system_set_usb_request_app_handler, void(usb_request_app_handler_type, void*))
DYNALIB_FN(22, system, system_set_usb_request_result, void(USBRequest*, int, void*))
#define BASE_IDX 23
#else
#define BASE_IDX 21
#endif // USB_VENDOR_REQUEST_ENABLE

DYNALIB_END(system)

#undef BASE_IDX

#endif /* SYSTEM_DYNALIB_H */

3 changes: 3 additions & 0 deletions system/inc/system_task.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@
#include "socket_hal.h"
#include "system_cloud.h"
#include "wlan_hal.h"
#include "active_object.h"

extern ISRTaskQueue SystemISRTaskQueue;

#ifdef __cplusplus
extern "C" {
Expand Down
Loading

0 comments on commit cbda226

Please sign in to comment.