Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | /*
* Copyright (c) 2015 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Event logger support.
*/
#include <logging/event_logger.h>
#include <misc/ring_buffer.h>
void sys_event_logger_init(struct event_logger *logger,
u32_t *logger_buffer, u32_t buffer_size)
{
sys_ring_buf_init(&logger->ring_buf, buffer_size, logger_buffer);
k_sem_init(&(logger->sync_sema), 0, UINT_MAX);
}
static void event_logger_put(struct event_logger *logger, u16_t event_id,
u32_t *event_data, u8_t data_size,
void (*sem_give_fn)(struct k_sem *))
{
int ret;
unsigned int key;
key = irq_lock();
ret = sys_ring_buf_put(&logger->ring_buf, event_id,
logger->ring_buf.dropped_put_count, event_data,
data_size);
if (ret == 0) {
logger->ring_buf.dropped_put_count = 0;
/* inform that there is event data available on the buffer */
sem_give_fn(&(logger->sync_sema));
}
irq_unlock(key);
}
void sys_event_logger_put(struct event_logger *logger, u16_t event_id,
u32_t *event_data, u8_t data_size)
{
event_logger_put(logger, event_id, event_data, data_size, k_sem_give);
}
/**
* @brief Send an event message to the logger with a non preemptible
* behavior.
*
* @details Add an event message to the ring buffer and signal the sync
* semaphore using the internal function _sem_give_non_preemptible to inform
* that there are event messages available, avoiding the preemptible
* behavior when the function is called from a task. This function
* should be only used for special cases where the sys_event_logger_put
* does not satisfy the needs.
*
* @param logger Pointer to the event logger used.
* @param event_id The identification of the profiler event.
* @param data Pointer to the data of the message.
* @param data_size Size of the buffer in 32-bit words.
*
* @return No return value.
*/
void _sys_event_logger_put_non_preemptible(struct event_logger *logger,
u16_t event_id, u32_t *event_data, u8_t data_size)
{
extern void _sem_give_non_preemptible(struct k_sem *sem);
event_logger_put(logger, event_id, event_data, data_size,
_sem_give_non_preemptible);
}
static int event_logger_get(struct event_logger *logger,
u16_t *event_id, u8_t *dropped_event_count,
u32_t *buffer, u8_t *buffer_size)
{
int ret;
ret = sys_ring_buf_get(&logger->ring_buf, event_id, dropped_event_count,
buffer, buffer_size);
if (likely(!ret)) {
return *buffer_size;
}
switch (ret) {
case -EMSGSIZE:
/* if the user can not retrieve the message, we increase the
* semaphore to indicate that the message remains in the buffer
*/
k_sem_give(&(logger->sync_sema));
return -EMSGSIZE;
case -EAGAIN:
return 0;
default:
return ret;
}
}
int sys_event_logger_get(struct event_logger *logger, u16_t *event_id,
u8_t *dropped_event_count, u32_t *buffer,
u8_t *buffer_size)
{
if (k_sem_take(&(logger->sync_sema), K_NO_WAIT) == 0) {
return event_logger_get(logger, event_id, dropped_event_count,
buffer, buffer_size);
}
return 0;
}
int sys_event_logger_get_wait(struct event_logger *logger, u16_t *event_id,
u8_t *dropped_event_count, u32_t *buffer,
u8_t *buffer_size)
{
k_sem_take(&(logger->sync_sema), K_FOREVER);
return event_logger_get(logger, event_id, dropped_event_count, buffer,
buffer_size);
}
#ifdef CONFIG_SYS_CLOCK_EXISTS
int sys_event_logger_get_wait_timeout(struct event_logger *logger,
u16_t *event_id,
u8_t *dropped_event_count,
u32_t *buffer, u8_t *buffer_size,
u32_t timeout)
{
if (k_sem_take(&(logger->sync_sema), __ticks_to_ms(timeout))) {
return event_logger_get(logger, event_id, dropped_event_count,
buffer, buffer_size);
}
return 0;
}
#endif /* CONFIG_SYS_CLOCK_EXISTS */
|