ether2ser 0.1.0
Ethernet <-> synchronous V.24 bridge firmware for RP2040 + W5500
Loading...
Searching...
No Matches
event_loop.c File Reference
#include "system/event_loop.h"
#include <inttypes.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "hardware/watchdog.h"
#include "pico/time.h"
#include "pico/types.h"
#include "drivers/pio_tx_rx_driver.h"
#include "drivers/tx_queue.h"
#include "drivers/w5500_driver.h"
#include "protocol/hdlc_common.h"
#include "protocol/hdlc_decoder.h"
#include "protocol/hdlc_sync.h"
#include "system/app_context.h"
#include "system/cli_usb_cdc.h"
#include "system/common.h"
#include "system/error.h"
#include "system/event_dispatch.h"
#include "system/event_queue.h"
Include dependency graph for event_loop.c:

Go to the source code of this file.

Data Structures

struct  event_loop_runtime_t
 

Macros

#define MAIN_LOOP_SLEEP_MS   1
 
#define MAIN_LOOP_SLEEP_US   50
 
#define TX_QUEUE_DRAIN_CHUNK_SIZE   32U
 
#define TX_QUEUE_HIGH_WM   48U
 
#define TX_QUEUE_LOW_WM   12U
 
#define EVENT_LOOP_MAX_EVENTS_AT_ONCE   20
 
#define EVENT_LOOP_MAX_EVENTS_WHILE_TX_ACTIVE   2
 
#define HDLC_DECODE_FAIL_STREAK_LIMIT   4U
 
#define HDLC_SYNC_IDLE_TIMEOUT_US   20000U
 
#define HDLC_SYNC_NO_PROGRESS_MAX_BYTES   2048U
 
#define HDLC_SYNC_NO_PROGRESS_MAX_BYTES_EXTERNAL   12288
 

Functions

static void print_prompt (app_ctx_t *app)
 
static bool event_loop_should_drop_hunt_idle_byte (app_ctx_t *app, uint8_t rx_byte, uint32_t *idle_run_length)
 
static void drain_rx_until_empty (app_ctx_t *app, event_loop_runtime_t *runtime, size_t *rx_drained)
 
static void update_rx_drain_stats (app_ctx_t *app, event_loop_runtime_t *event_loop_runtime, const size_t rx_drained_early, const uint64_t now_us)
 
static void poll_and_enqueue_udp_rx (app_ctx_t *app, event_loop_runtime_t *event_loop_runtime)
 
static size_t poll_tx_pipeline (app_ctx_t *app, event_loop_runtime_t *event_loop_runtime)
 
static void poll_hdlc_idle_timeout (app_ctx_t *app, event_loop_runtime_t *event_loop_runtime, const uint64_t now_us)
 
static void decode_hdlc_to_udp_tx (app_ctx_t *app, event_loop_runtime_t *event_loop_runtime)
 
static void drain_hdlc_frames_to_udp (app_ctx_t *app, event_loop_runtime_t *event_loop_runtime)
 
static void poll_hdlc_no_progress (app_ctx_t *app, event_loop_runtime_t *event_loop_runtime)
 
static void update_statistics (app_ctx_t *app)
 
static void poll_and_dispatch_events (app_ctx_t *app)
 
static void update_udp_rx_throttle_state (app_ctx_t *app, event_loop_runtime_t *runtime)
 
void event_loop (app_ctx_t *app)
 Run the main application polling loop.
 

Macro Definition Documentation

◆ EVENT_LOOP_MAX_EVENTS_AT_ONCE

#define EVENT_LOOP_MAX_EVENTS_AT_ONCE   20

Definition at line 49 of file event_loop.c.

◆ EVENT_LOOP_MAX_EVENTS_WHILE_TX_ACTIVE

#define EVENT_LOOP_MAX_EVENTS_WHILE_TX_ACTIVE   2

Definition at line 50 of file event_loop.c.

◆ HDLC_DECODE_FAIL_STREAK_LIMIT

#define HDLC_DECODE_FAIL_STREAK_LIMIT   4U

Definition at line 51 of file event_loop.c.

◆ HDLC_SYNC_IDLE_TIMEOUT_US

#define HDLC_SYNC_IDLE_TIMEOUT_US   20000U

Definition at line 52 of file event_loop.c.

◆ HDLC_SYNC_NO_PROGRESS_MAX_BYTES

#define HDLC_SYNC_NO_PROGRESS_MAX_BYTES   2048U

Definition at line 53 of file event_loop.c.

◆ HDLC_SYNC_NO_PROGRESS_MAX_BYTES_EXTERNAL

#define HDLC_SYNC_NO_PROGRESS_MAX_BYTES_EXTERNAL   12288

Definition at line 54 of file event_loop.c.

◆ MAIN_LOOP_SLEEP_MS

#define MAIN_LOOP_SLEEP_MS   1

Definition at line 42 of file event_loop.c.

◆ MAIN_LOOP_SLEEP_US

#define MAIN_LOOP_SLEEP_US   50

Definition at line 43 of file event_loop.c.

◆ TX_QUEUE_DRAIN_CHUNK_SIZE

#define TX_QUEUE_DRAIN_CHUNK_SIZE   32U

Definition at line 45 of file event_loop.c.

◆ TX_QUEUE_HIGH_WM

#define TX_QUEUE_HIGH_WM   48U

Definition at line 46 of file event_loop.c.

◆ TX_QUEUE_LOW_WM

#define TX_QUEUE_LOW_WM   12U

Definition at line 47 of file event_loop.c.

Function Documentation

◆ decode_hdlc_to_udp_tx()

◆ drain_hdlc_frames_to_udp()

static void drain_hdlc_frames_to_udp ( app_ctx_t app,
event_loop_runtime_t event_loop_runtime 
)
static

Definition at line 257 of file event_loop.c.

References app_ctx_t::accumulator, decode_hdlc_to_udp_tx(), E2S_ERR_HDLC_ACC_FRAME_READY, E2S_OK, HDLC_FLAG_BYTE, hdlc_sync_acc_init(), hdlc_sync_acc_poll(), HDLC_FRAME_T::length, and app_ctx_t::reconstructed_frame.

Referenced by event_loop().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ drain_rx_until_empty()

static void drain_rx_until_empty ( app_ctx_t app,
event_loop_runtime_t runtime,
size_t *  rx_drained 
)
static

◆ event_loop()

void event_loop ( app_ctx_t app)

Run the main application polling loop.

Parameters
appApplication context.

TODO: Its not good that the event loop pokes around in hdlc state. We should add a helper like hdlc_sync_acc_reset_frame that hides these details and just call that from here. This shall be refactored in the next iteration.

Definition at line 383 of file event_loop.c.

References cli_poll(), drain_hdlc_frames_to_udp(), drain_rx_until_empty(), log_take_emitted_flag(), MAIN_LOOP_SLEEP_US, app_ctx_t::need_prompt, poll_and_dispatch_events(), poll_and_enqueue_udp_rx(), poll_hdlc_idle_timeout(), poll_hdlc_no_progress(), poll_tx_pipeline(), print_prompt(), event_loop_runtime_t::rx_byte, rx_clock_poll_stall(), payload_statistics_t::rx_fifo_stall_events, app_ctx_t::stats, payload_statistics_t::udp_rx_buffer_full_counts, payload_statistics_t::udp_rx_throttle_skips, event_loop_runtime_t::udp_rx_throttled, payload_statistics_t::udp_tx_buffer_full_counts, update_rx_drain_stats(), update_statistics(), update_udp_rx_throttle_state(), w5500_poll_udp_buffer_full_events(), and event_loop_runtime_t::work_done.

Referenced by main().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ event_loop_should_drop_hunt_idle_byte()

static bool event_loop_should_drop_hunt_idle_byte ( app_ctx_t app,
uint8_t  rx_byte,
uint32_t *  idle_run_length 
)
static

Definition at line 65 of file event_loop.c.

References app_ctx_t::accumulator, V24_CONFIG_T::external_clock, HDLC_SYNC_STATE_HUNTING, HDLC_SYNC_ACCUMULATOR_T::state, and app_ctx_t::v24_config.

Referenced by drain_rx_until_empty().

Here is the caller graph for this function:

◆ poll_and_dispatch_events()

static void poll_and_dispatch_events ( app_ctx_t app)
static

Definition at line 348 of file event_loop.c.

References event_dispatch(), EVENT_LOOP_MAX_EVENTS_AT_ONCE, EVENT_LOOP_MAX_EVENTS_WHILE_TX_ACTIVE, event_queue_pop(), app_ctx_t::tx_queue, and tx_queue_is_empty().

Referenced by event_loop().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ poll_and_enqueue_udp_rx()

◆ poll_hdlc_idle_timeout()

◆ poll_hdlc_no_progress()

◆ poll_tx_pipeline()

static size_t poll_tx_pipeline ( app_ctx_t app,
event_loop_runtime_t event_loop_runtime 
)
static

Definition at line 166 of file event_loop.c.

References E2S_OK, LOG_ERROR, poll_queue_stats(), tx_poll(), app_ctx_t::tx_queue, tx_queue_drain(), TX_QUEUE_DRAIN_CHUNK_SIZE, tx_queue_is_empty(), and event_loop_runtime_t::work_done.

Referenced by event_loop().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ print_prompt()

static void print_prompt ( app_ctx_t app)
static

Definition at line 56 of file event_loop.c.

References LOG_PLAIN, and app_ctx_t::need_prompt.

Referenced by event_loop().

Here is the caller graph for this function:

◆ update_rx_drain_stats()

static void update_rx_drain_stats ( app_ctx_t app,
event_loop_runtime_t event_loop_runtime,
const size_t  rx_drained_early,
const uint64_t  now_us 
)
static

◆ update_statistics()

static void update_statistics ( app_ctx_t app)
static

Definition at line 312 of file event_loop.c.

References app_ctx_t::accumulator, HDLC_SYNC_ACCUMULATOR_T::consume_count, hdlc_decode_stats_t::crc_mismatch, payload_statistics_t::decode_fail_crc_mismatch, payload_statistics_t::decode_fail_invalid_frame, payload_statistics_t::decode_fail_payload_too_long, payload_statistics_t::decode_fail_too_short, payload_statistics_t::decode_fail_unstuff_error, payload_statistics_t::event_queue_drop_events, event_queue_get_count(), event_queue_get_high_water_mark(), event_queue_get_push_drop_count(), payload_statistics_t::event_queue_used_max, HDLC_SYNC_ACCUMULATOR_T::hardcap_drop_bytes, HDLC_SYNC_ACCUMULATOR_T::hardcap_drop_events, hdlc_decode_stats_snapshot(), hdlc_decode_stats_t::invalid_frame, payload_statistics_t::log_drop_lines, log_get_high_water_mark(), payload_statistics_t::log_queue_used_max, log_take_dropped_count(), HDLC_SYNC_ACCUMULATOR_T::lookahead_wait_synced, HDLC_SYNC_ACCUMULATOR_T::lookahead_wait_syncing, hdlc_decode_stats_t::payload_too_long, app_ctx_t::stats, payload_statistics_t::sync_candidate_consume, payload_statistics_t::sync_hardcap_drop_bytes, payload_statistics_t::sync_hardcap_drop_events, payload_statistics_t::sync_lookahead_wait_synced, payload_statistics_t::sync_lookahead_wait_syncing, hdlc_decode_stats_t::too_short, app_ctx_t::tx_queue, tx_queue_get_count(), payload_statistics_t::tx_queue_used_max, and hdlc_decode_stats_t::unstuff_error.

Referenced by event_loop().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ update_udp_rx_throttle_state()

static void update_udp_rx_throttle_state ( app_ctx_t app,
event_loop_runtime_t runtime 
)
static

TODO: This curerntly only schedules tx_drain with rx_udp. Ideally we should add a simple scheduler to the event loop.

Definition at line 365 of file event_loop.c.

References app_ctx_t::stats, app_ctx_t::tx_queue, tx_queue_get_count(), TX_QUEUE_HIGH_WM, TX_QUEUE_LOW_WM, payload_statistics_t::udp_rx_throttle_enter, and event_loop_runtime_t::udp_rx_throttled.

Referenced by event_loop().

Here is the call graph for this function:
Here is the caller graph for this function: