summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSaya Sugiura <ssugiura@jp.adit-jv.com>2021-03-26 02:52:13 +0000
committerSaya Sugiura <39760799+ssugiura@users.noreply.github.com>2021-10-05 11:19:26 +0900
commit3c3ead84aa51abc8d95c5ee974182194949f63c9 (patch)
tree116153d8ccb8ef32dedb1bc3cc6a808c14c6c0da
parentcf79abb110c7ff8b5b75c6f48beeddd9d92dfbd3 (diff)
downloadDLT-daemon-3c3ead84aa51abc8d95c5ee974182194949f63c9.tar.gz
lib: Add new interfaces with given buffer
This commit adds new interfaces: - dlt_user_log_write_start_w_given_buffer(): accepts a log buffer as an input. - dlt_user_log_write_finish_w_given_buffer(): finalizes logging and send the message to corresponding output This is to reduce DLT API calls in DLT application as much as possible and avoid allocating dynamic memory within DLT library. The log buffer has to be prepared in DLT application in order to use these interfaces. Signed-off-by: Saya Sugiura <ssugiura@jp.adit-jv.com>
-rw-r--r--doc/dlt_for_developers.md70
-rw-r--r--include/dlt/dlt_user.h.in34
-rw-r--r--src/lib/dlt_user.c122
3 files changed, 195 insertions, 31 deletions
diff --git a/doc/dlt_for_developers.md b/doc/dlt_for_developers.md
index 09e2b87..d664ab8 100644
--- a/doc/dlt_for_developers.md
+++ b/doc/dlt_for_developers.md
@@ -262,7 +262,7 @@ DLT\_LOG\_INFO | Informational, providing high level understanding
DLT\_LOG\_DEBUG | Detailed debug information for programmers
DLT\_LOG\_VERBOSE | Verbose debug information for programmers
-Please be aware the the default Log Level is set to INFO; this means message
+Please be aware the default Log Level is set to INFO; this means message
which are logged in INFO, WARN, ERROR and FATAL will logged. Hint: The default
Log Level can be changed by setting an environment variable (see DLT Library -
runtime configuration).
@@ -734,6 +734,74 @@ if (dlt_user_log_write_start(&ctx, &ctxdata, DLT_LOG_INFO) > 0) {
}
```
+#### Send log message with given buffer
+
+DLT applications can prepare a log message buffer by themselves instead
+of calling logging parameters. There are two benefits; the applications
+can reduce API calls to DLT library as much as possible so that the
+APIs won't block the application's sequence, and dynamic allocation can
+be avoided in DLT library during runtime.
+
+The applications should prepare following values in order to use this
+functionality:
+
+- *char buffer[DLT_USER_BUF_MAX_SIZE]*: Buffer which contains one log message payload
+- *size_t size*: Buffer size
+- *int32_t args_num*: Number of arguments
+
+One argument in the buffer consists of following:
+| Length(byte) | Description |
+|----------------|--------------|
+| 4 | Type Info |
+| x | Data Payload |
+
+DLT Applications need to simulate what are done in logging parameters to
+store data to the buffer (type info given to the buffer, etc.),
+otherwise the behavior is undefined.
+
+Also important note here is that the functionality works properly only
+with these function combination:
+
+- *Start logging*: dlt\_user\_log\_write\_start\_w\_given\_buffer
+- *Finish logging*: dlt\_user\_log\_write\_finish\_w\_given\_buffer
+
+Since the function does not allocate memory dynamically, it could lead
+to segmentation fault or memory leak with different APIs. It is mandatory
+to check if dlt_user_is_logLevel_enabled is returning DLT_RETURN_TRUE before
+calling dlt_user_log_write_start_w_given_buffer (see below code example).
+
+##### Macro
+
+No macro interface is available as of now.
+
+##### Function
+
+```
+/* Example: Prepare one log message with uint16 */
+char buffer[DLT_USER_BUF_MAX_SIZE] = {0};
+size_t size = 0;
+int32_t args_num = 0;
+
+uint32_t type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_16BIT;
+memcpy(buffer + size, &(type_info), sizeof(uint32_t));
+size += sizeof(uint32_t);
+
+uint16_t data = 1234;
+memcpy(buffer + size, &data, sizeof(uint16_t));
+size += sizeof(uint16_t);
+
+args_num++;
+
+/* Give the buffer to DLT library */
+if (dlt_user_is_logLevel_enabled(&ctx,DLT_LOG_INFO) == DLT_RETURN_TRUE)
+{
+ if (dlt_user_log_write_start_w_given_buffer(&ctx, &ctxdata, DLT_LOG_INFO, buffersize, args_num) > 0)
+ {
+ dlt_user_log_write_finish_w_given_buffer(&ctxdata);
+ }
+}
+```
+
#### Attributes
In verbose mode, log message arguments can contain attributes. A "name" attribute
diff --git a/include/dlt/dlt_user.h.in b/include/dlt/dlt_user.h.in
index 30eb234..7a2d35e 100644
--- a/include/dlt/dlt_user.h.in
+++ b/include/dlt/dlt_user.h.in
@@ -298,6 +298,30 @@ DltReturnValue dlt_user_log_write_start_id(DltContext *handle,
uint32_t messageid);
/**
+ * Initialize the generation of a DLT log message with given buffer from DLT application.
+ * This can be considered as replacement of dlt_user_log_write_start/dlt_user_log_write_start_id
+ * and other data functions like dlt_user_log_write_string. The fourth, fifth, and sixth arguments
+ * shall be prepared by DLT application; this function is only responsible for checking log
+ * level and setting the given values to context data. This function has to be called first,
+ * when an application is ready to send a new log message with given buffer. This function only
+ * works with combination of dlt_user_log_write_finish_w_given_buffer and the function must only be
+ * called, when return value is bigger than zero. The function only supports verbose mode as of now.
+ * @param handle pointer to an object containing information about one special logging context
+ * @param log pointer to an object containing information about logging context data
+ * @param loglevel this is the current log level of the log message to be sent
+ * @param buffer data with log message
+ * @param size buffer size
+ * @param args_num number of arguments in buffer
+ * @return Value from DltReturnValue enum, DLT_RETURN_TRUE if log level is matching
+ */
+DltReturnValue dlt_user_log_write_start_w_given_buffer(DltContext *handle,
+ DltContextData *log,
+ DltLogLevelType loglevel,
+ char *buffer,
+ size_t size,
+ int32_t args_num);
+
+/**
* Finishing the generation of a DLT log message and sending it to the DLT daemon.
* This function has to be called after writing all the log attributes of a log message.
* @param log pointer to an object containing information about logging context data
@@ -306,6 +330,16 @@ DltReturnValue dlt_user_log_write_start_id(DltContext *handle,
DltReturnValue dlt_user_log_write_finish(DltContextData *log);
/**
+ * Finishing the generation of a DLT log message and sending it to the DLT daemon without
+ * freeing log buffer. This function only works with combination of
+ * dlt_user_log_write_start_w_given_buffer. This function has to be called after writing all
+ * the log attributes of a log message.
+ * @param log pointer to an object containing information about logging context data
+ * @return Value from DltReturnValue enum
+ */
+DltReturnValue dlt_user_log_write_finish_w_given_buffer(DltContextData *log);
+
+/**
* Write a boolean parameter into a DLT log message.
* dlt_user_log_write_start has to be called before adding any attributes to the log message.
* Finish sending log message by calling dlt_user_log_write_finish.
diff --git a/src/lib/dlt_user.c b/src/lib/dlt_user.c
index d2ef613..d29a7a0 100644
--- a/src/lib/dlt_user.c
+++ b/src/lib/dlt_user.c
@@ -1719,6 +1719,26 @@ int dlt_set_resend_timeout_atexit(uint32_t timeout_in_milliseconds)
/* ********************************************************************************************* */
+DltReturnValue dlt_user_log_write_start_init(DltContext *handle,
+ DltContextData *log,
+ DltLogLevelType loglevel,
+ bool is_verbose)
+{
+ DLT_LOG_FATAL_RESET_TRAP(loglevel);
+
+ /* initialize values */
+ if ((dlt_user_log_init(handle, log) < DLT_RETURN_OK) || (dlt_user.dlt_ll_ts == NULL))
+ return DLT_RETURN_ERROR;
+
+ log->args_num = 0;
+ log->log_level = loglevel;
+ log->size = 0;
+ log->use_timestamp = DLT_AUTO_TIMESTAMP;
+ log->verbose_mode = is_verbose;
+
+ return DLT_RETURN_TRUE;
+}
+
static DltReturnValue dlt_user_log_write_start_internal(DltContext *handle,
DltContextData *log,
DltLogLevelType loglevel,
@@ -1744,8 +1764,7 @@ DltReturnValue dlt_user_log_write_start_internal(DltContext *handle,
uint32_t messageid,
bool is_verbose)
{
- DLT_LOG_FATAL_RESET_TRAP(loglevel);
- DltReturnValue ret = DLT_RETURN_OK;
+ int ret = DLT_RETURN_TRUE;
/* check nullpointer */
if ((handle == NULL) || (log == NULL))
@@ -1758,47 +1777,78 @@ DltReturnValue dlt_user_log_write_start_internal(DltContext *handle,
/* check log levels */
ret = dlt_user_is_logLevel_enabled(handle, loglevel);
- if (ret == DLT_RETURN_WRONG_PARAMETER)
+ if (ret == DLT_RETURN_WRONG_PARAMETER) {
return DLT_RETURN_WRONG_PARAMETER;
- else if (ret == DLT_RETURN_LOGGING_DISABLED)
+ } else if (ret == DLT_RETURN_LOGGING_DISABLED) {
+ log->handle = NULL;
return DLT_RETURN_OK;
+ }
- /* initialize values */
- if ((dlt_user_log_init(handle, log) < DLT_RETURN_OK) || (dlt_user.dlt_ll_ts == NULL))
- return DLT_RETURN_ERROR;
+ ret = dlt_user_log_write_start_init(handle, log, loglevel, is_verbose);
+ if (ret == DLT_RETURN_TRUE) {
+ /* initialize values */
+ if (log->buffer == NULL) {
+ log->buffer = calloc(sizeof(unsigned char), dlt_user.log_buf_len);
- /* initialize values */
- if (log->buffer == NULL) {
- log->buffer = calloc(sizeof(unsigned char), dlt_user.log_buf_len);
+ if (log->buffer == NULL) {
+ dlt_vlog(LOG_ERR, "Cannot allocate buffer for DLT Log message\n");
+ return DLT_RETURN_ERROR;
+ }
+ }
- if (log->buffer == NULL) {
- dlt_vlog(LOG_ERR, "Cannot allocate buffer for DLT Log message\n");
- return DLT_RETURN_ERROR;
+ /* In non-verbose mode, insert message id */
+ if (!is_verbose_mode(dlt_user.verbose_mode, log)) {
+ if ((sizeof(uint32_t)) > dlt_user.log_buf_len) {
+ return DLT_RETURN_USER_BUFFER_FULL;
+ }
+
+ /* Write message id */
+ memcpy(log->buffer, &(messageid), sizeof(uint32_t));
+ log->size = sizeof(uint32_t);
+
+ /* as the message id is part of each message in non-verbose mode,
+ * it doesn't increment the argument counter in extended header (if used) */
}
}
- log->args_num = 0;
- log->log_level = loglevel;
- log->size = 0;
- log->use_timestamp = DLT_AUTO_TIMESTAMP;
- log->verbose_mode = is_verbose;
+ return ret;
+}
- /* In non-verbose mode, insert message id */
- if (!is_verbose_mode(dlt_user.verbose_mode, log)) {
- if ((sizeof(uint32_t)) > dlt_user.log_buf_len)
- return DLT_RETURN_USER_BUFFER_FULL;
+DltReturnValue dlt_user_log_write_start_w_given_buffer(DltContext *handle,
+ DltContextData *log,
+ DltLogLevelType loglevel,
+ char *buffer,
+ size_t size,
+ int32_t args_num)
+{
+ int ret = DLT_RETURN_TRUE;
- /* Write message id */
- memcpy(log->buffer, &(messageid), sizeof(uint32_t));
- log->size = sizeof(uint32_t);
+ /* check nullpointer */
+ if ((handle == NULL) || (log == NULL) || (buffer == NULL))
+ return DLT_RETURN_WRONG_PARAMETER;
- /* as the message id is part of each message in non-verbose mode,
- * it doesn't increment the argument counter in extended header (if used) */
- }
+ /* discard unexpected parameters */
+ if ((size <= 0) || (size > dlt_user.log_buf_len) || (args_num <= 0))
+ return DLT_RETURN_WRONG_PARAMETER;
- return DLT_RETURN_TRUE;
-}
+ /* forbid dlt usage in child after fork */
+ if (g_dlt_is_child)
+ return DLT_RETURN_ERROR;
+
+ /* discard non-verbose mode */
+ if (dlt_user.verbose_mode == 0)
+ return DLT_RETURN_ERROR;
+
+ ret = dlt_user_log_write_start_init(handle, log, loglevel, true);
+ if (ret == DLT_RETURN_TRUE) {
+ log->buffer = (unsigned char *)buffer;
+ log->size = size;
+ log->args_num = args_num;
+ }
+ return ret;
+ }
+
DltReturnValue dlt_user_log_write_finish(DltContextData *log)
{
int ret = DLT_RETURN_ERROR;
@@ -1813,6 +1863,18 @@ DltReturnValue dlt_user_log_write_finish(DltContextData *log)
return ret;
}
+DltReturnValue dlt_user_log_write_finish_w_given_buffer(DltContextData *log)
+{
+ int ret = DLT_RETURN_ERROR;
+
+ if (log == NULL)
+ return DLT_RETURN_WRONG_PARAMETER;
+
+ ret = dlt_user_log_send_log(log, DLT_TYPE_LOG);
+
+ return ret;
+}
+
static DltReturnValue dlt_user_log_write_raw_internal(DltContextData *log, const void *data, uint16_t length, DltFormatType type, const char *name, bool with_var_info)
{
/* check nullpointer */