summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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 */