/* SPDX-License-Identifier: GPL-2.0-or-later */ /* * Copyright (C) 2016-2020 by Marc Schink */ #ifndef OPENOCD_RTT_RTT_H #define OPENOCD_RTT_RTT_H #include #include #include #include /** * Control block ID length in bytes, including the trailing null-terminator. */ #define RTT_CB_MAX_ID_LENGTH 16 /* Control block size in bytes. */ #define RTT_CB_SIZE (RTT_CB_MAX_ID_LENGTH + 2 * sizeof(uint32_t)) /* Channel structure size in bytes. */ #define RTT_CHANNEL_SIZE 24 /* Minimal channel buffer size in bytes. */ #define RTT_CHANNEL_BUFFER_MIN_SIZE 2 /** RTT control block. */ struct rtt_control { /** Control block address on the target. */ target_addr_t address; /** Control block identifier, including trailing null-terminator. */ char id[RTT_CB_MAX_ID_LENGTH]; /** Maximum number of up-channels. */ uint32_t num_up_channels; /** Maximum number of down-channels. */ uint32_t num_down_channels; }; /** RTT channel. */ struct rtt_channel { /** Channel structure address on the target. */ target_addr_t address; /** Channel name address on the target. */ uint32_t name_addr; /** Buffer address on the target. */ uint32_t buffer_addr; /** Channel buffer size in bytes. */ uint32_t size; /** Write position within the buffer in bytes. */ uint32_t write_pos; /** Read position within the buffer in bytes. */ uint32_t read_pos; /** * Buffer flags. * * @note: Not used at the moment. */ uint32_t flags; }; /** RTT channel information. */ struct rtt_channel_info { /** Channel name. */ char *name; /** Length of the name in bytes, including the trailing null-terminator. */ size_t name_length; /** Buffer size in bytes. */ uint32_t size; /** * Buffer flags. * * @note: Not used at the moment. */ uint32_t flags; }; typedef int (*rtt_sink_read)(unsigned int channel, const uint8_t *buffer, size_t length, void *user_data); struct rtt_sink_list { rtt_sink_read read; void *user_data; struct rtt_sink_list *next; }; /** Channel type. */ enum rtt_channel_type { /** Up channel (target to host). */ RTT_CHANNEL_TYPE_UP, /** Down channel (host to target). */ RTT_CHANNEL_TYPE_DOWN }; typedef int (*rtt_source_find_ctrl_block)(struct target *target, target_addr_t *address, size_t size, const char *id, bool *found, void *user_data); typedef int (*rtt_source_read_ctrl_block)(struct target *target, target_addr_t address, struct rtt_control *ctrl_block, void *user_data); typedef int (*rtt_source_read_channel_info)(struct target *target, const struct rtt_control *ctrl, unsigned int channel, enum rtt_channel_type type, struct rtt_channel_info *info, void *user_data); typedef int (*rtt_source_start)(struct target *target, const struct rtt_control *ctrl, void *user_data); typedef int (*rtt_source_stop)(struct target *target, void *user_data); typedef int (*rtt_source_read)(struct target *target, const struct rtt_control *ctrl, struct rtt_sink_list **sinks, size_t num_channels, void *user_data); typedef int (*rtt_source_write)(struct target *target, struct rtt_control *ctrl, unsigned int channel, const uint8_t *buffer, size_t *length, void *user_data); /** RTT source. */ struct rtt_source { rtt_source_find_ctrl_block find_cb; rtt_source_read_ctrl_block read_cb; rtt_source_read_channel_info read_channel_info; rtt_source_start start; rtt_source_stop stop; rtt_source_read read; rtt_source_write write; }; /** * Initialize Real-Time Transfer (RTT). * * @returns ERROR_OK on success, an error code on failure. */ int rtt_init(void); /** * Shutdown Real-Time Transfer (RTT). * * @returns ERROR_OK on success, an error code on failure. */ int rtt_exit(void); /** * Register an RTT source for a target. * * @param[in] source RTT source. * @param[in,out] target Target. * * @returns ERROR_OK on success, an error code on failure. */ int rtt_register_source(const struct rtt_source source, struct target *target); /** * Setup RTT. * * @param[in] address Start address to search for the control block. * @param[in] size Size of the control block search area. * @param[in] id Identifier of the control block. Must be null-terminated. * * @returns ERROR_OK on success, an error code on failure. */ int rtt_setup(target_addr_t address, size_t size, const char *id); /** * Start Real-Time Transfer (RTT). * * @returns ERROR_OK on success, an error code on failure. */ int rtt_start(void); /** * Stop Real-Time Transfer (RTT). * * @returns ERROR_OK on success, an error code on failure. */ int rtt_stop(void); /** * Get the polling interval. * * @param[out] interval Polling interval in milliseconds. * * @returns ERROR_OK on success, an error code on failure. */ int rtt_get_polling_interval(unsigned int *interval); /** * Set the polling interval. * * @param[in] interval Polling interval in milliseconds. * * @returns ERROR_OK on success, an error code on failure. */ int rtt_set_polling_interval(unsigned int interval); /** * Get whether RTT is started. * * @returns Whether RTT is started. */ bool rtt_started(void); /** * Get whether RTT is configured. * * @returns Whether RTT is configured. */ bool rtt_configured(void); /** * Get whether RTT control block was found. * * @returns Whether RTT was found. */ bool rtt_found_cb(void); /** * Get the RTT control block. * * @returns The RTT control block. */ const struct rtt_control *rtt_get_control(void); /** * Read channel information. * * @param[in] channel_index Channel index. * @param[in] type Channel type. * @param[out] info Channel information. * * @returns ERROR_OK on success, an error code on failure. */ int rtt_read_channel_info(unsigned int channel_index, enum rtt_channel_type type, struct rtt_channel_info *info); /** * Register an RTT sink. * * @param[in] channel_index Channel index. * @param[in] read Read callback function. * @param[in,out] user_data User data to be passed to the callback function. * * @returns ERROR_OK on success, an error code on failure. */ int rtt_register_sink(unsigned int channel_index, rtt_sink_read read, void *user_data); /** * Unregister an RTT sink. * * @param[in] channel_index Channel index. * @param[in] read Read callback function. * @param[in,out] user_data User data to be passed to the callback function. * * @returns ERROR_OK on success, an error code on failure. */ int rtt_unregister_sink(unsigned int channel_index, rtt_sink_read read, void *user_data); /** * Write to an RTT channel. * * @param[in] channel_index Channel index. * @param[in] buffer Buffer with data that should be written to the channel. * @param[in,out] length Number of bytes to write. On success, the argument gets * updated with the actual number of written bytes. * * @returns ERROR_OK on success, an error code on failure. */ int rtt_write_channel(unsigned int channel_index, const uint8_t *buffer, size_t *length); extern const struct command_registration rtt_target_command_handlers[]; #endif /* OPENOCD_RTT_RTT_H */