-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathtarget_mb_freertos.h
170 lines (140 loc) · 3.8 KB
/
target_mb_freertos.h
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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#pragma once
#include "target.h"
#include "proxy-conn.hpp"
#include "gdb_packets.h"
#include "threadid.h"
namespace freertos {
enum symbols_values
{
Symbol_start,
Symbol_pxCurrentTCB,
Symbol_pxReadyTasksLists,
Symbol_xDelayedTaskList1,
Symbol_xDelayedTaskList2,
Symbol_pxDelayedTaskList,
Symbol_pxOverflowDelayedTaskList,
Symbol_xPendingReadyList,
Symbol_xTasksWaitingTermination,
Symbol_xSuspendedTaskList,
Symbol_uxCurrentNumberOfTasks,
Symbol_uxTopUsedPriority,
Symbol_xTopReadyPriority,
Symbol_Count
};
} // ::freertos
// Internal
static constexpr address_t THREAD_ID_CURRENT_EXECUTION = 1;
// Stacking constants
enum class stack_growth {
down = -1,
up = 1,
def = down,
};
enum : ssize_t {
register_unused = -1,
register_sp = -2,
register_unavail = -3,
};
struct register_stack_offset
{
// offset in bytes, -1 - register unstacked, -2 - SP register
ssize_t offset;
//
unsigned width_bits;
};
struct register_stacking
{
size_t context_size;
stack_growth growth_direction;
const register_stack_offset* registers;
const size_t registers_count;
};
class target_mb_freertos : public target
{
public:
// MicroBlaze FreeRTOS 32bit system
using tid_t = threadid<uint32_t>;
target_mb_freertos(connection &conn, const std::vector<char *> &options);
// target interface
public:
bool process_request(const gdb_packet &pkt) override;
private:
// Handlers
bool handle_query_packet(const gdb_packet& pkt);
bool handle_stop_reply_packets(const gdb_packet& pkt);
// Processors
void request_symbol();
tid_t make_threadid(address_t tcb, address_t pid = 1) const noexcept;
tid_t get_threadid(address_t tcb, bool update = true);
//
// Thread update sequence
//
void update_threads(std::function<void()> done_cb);
void get_threads_count(int idx = 0);
void get_current_thread();
void get_thread_lists_count();
void get_thread_list_data();
// thread list data processing
void get_list_threads_count();
void get_list_elem_ptr();
// list elements
void get_list_elem_thread_id();
void get_list_elem_thread_name();
void get_list_elem_next();
// done
void update_threads_done();
void make_empty_threading();
void add_current_execution();
//
// Thread retrivie registers list
//
bool get_thread_reg_list(address_t thread_id);
void get_thread_stack_ptr(address_t thread_id);
void get_thread_registers();
void get_thread_reg_list_done();
private:
connection& m_conn;
bool m_process_symbols = false;
size_t m_current_symbol = 0;
bool m_rtos_avail = false;
std::array<address_t, freertos::Symbol_Count> m_symbols;
// Threading
struct thread_info
{
address_t thread_tcb = 0;
tid_t thread_id;
bool exists = false;
std::string name;
std::string extra;
};
struct thread_list
{
thread_list(address_t address)
: address(address) {}
address_t address = 0;
size_t count = 0;
address_t list_elem_ptr = 0;
address_t list_elem_ptr_prev = address_t(-1);
};
struct threading
{
size_t threads_count = 0;
address_t current_thread_tcb = 0;
tid_t current_thread_id;
std::deque<thread_info> info;
std::vector<thread_list> lists;
decltype (lists)::iterator list_it;
std::function<void()> done_cb;
};
threading m_threading;
tid_t m_current_thread_id;
std::map<address_t, int32_t> m_threads_map;
bool m_multiprocess = false;
gdb_packet m_stop_reply_response;
struct registers
{
const register_stacking* stacking = nullptr;
address_t stack_ptr = 0;
};
registers m_registers;
};