msp430-gdbproxy.cpp
Go to the documentation of this file.
1 // msp430-gdbproxy.cpp : Defines the entry point for the console application.
2 //
3 
4 #include "stdafx.h"
5 
6 // VBoxGDB.cpp : Defines the entry point for the console application.
7 //
8 
9 #include "stdafx.h"
10 #include <stdio.h>
11 #include "MSP430EEMTarget.h"
12 #include "GlobalSessionMonitor.h"
13 
14 using namespace BazisLib;
15 using namespace GDBServerFoundation;
16 
17 /*class StubWithLogging : public GDBStub
18 {
19  FILE *pLogFile;
20 
21  virtual StubResponse HandleRequest(const BazisLib::TempStringA &requestType, char splitterChar, const BazisLib::TempStringA &requestData)
22  {
23  printf(">> %s%c%s\n", DynamicStringA(requestType).c_str(), splitterChar, DynamicStringA(requestData).c_str());
24  fprintf(pLogFile, ">> %s%c%s\n", DynamicStringA(requestType).c_str(), splitterChar, DynamicStringA(requestData).c_str());
25  StubResponse response = __super::HandleRequest(requestType, splitterChar, requestData);
26  printf("<< %s\n", std::string(response.GetData(), response.GetSize()).c_str());
27  fprintf(pLogFile, "<< %s\n", std::string(response.GetData(), response.GetSize()).c_str());
28  fflush(pLogFile);
29  return response;
30  }
31 
32 public:
33  StubWithLogging(ISyncGDBTarget *pTarget)
34  : GDBStub(pTarget, true)
35  {
36  pLogFile = fopen("gdbserver.log", "w");
37  }
38 
39  ~StubWithLogging()
40  {
41  fclose(pLogFile);
42  }
43 };*/
44 
45 using namespace MSP430Proxy;
46 
47 typedef GDBStub StubImpl;
48 
49 class MSP430StubFactory : public IGDBStubFactory
50 {
51 private:
52  GlobalSettings m_Settings;
53 
54 public:
56  : m_Settings(settings)
57  {
58  }
59 
60  virtual IGDBStub *CreateStub(GDBServer *pServer)
61  {
62  MSP430GDBTarget *pTarget;
63  if (m_Settings.EnableEEMMode)
64  pTarget = new MSP430EEMTarget();
65  else
66  pTarget = new MSP430GDBTarget();
67 
68  if (!g_SessionMonitor.RegisterSession(pTarget))
69  {
70  printf("Cannot start a new debugging session before the old session ends.\n");
71  return NULL;
72  }
73 
74  if (!pTarget->Initialize(m_Settings))
75  {
76  printf("Failed to initialize MSP430 debugging engine. Aborting.\n");
77  delete pTarget;
78  return NULL;
79  }
80  printf("New GDB debugging session started.\n");
81 
82  if (m_Settings.SingleSessionOnly)
83  pServer->StopListening();
84 
85  return new StubImpl(pTarget);
86  }
87 
88  virtual void OnProtocolError(const TCHAR *errorDescription)
89  {
90  _tprintf(_T("Protocol error: %s\n"), errorDescription);
91  }
92 };
93 
94 #include <msp430.h>
95 #include "MSP430Util.h"
96 
98 {
99  printf("Usage: msp430-gdbproxy [options]\n\
100 All options are optional:\n\
101  --noeem - Disable EEM mode (required for advanced breakpoints)\n\
102  --keepbp - Keep software breakpoints in FLASH (reduces erase cycles)\n\
103  --bp_insn=0xNNNN - Override software breakpoint instruction (default 0x4343)\n\
104  --bpmode=<mode> - Specifies how to create breakpoints with \"break\" command:\n\
105  soft - always create software breakpoints (run \"hbreak\" to override)\n\
106  hard - always create hardware breakpoints, fail when out of them\n\
107  auto - create hardware breakpoints while available, then software\n\
108  --progport=<port> - Specify port for TI FET (default is \"USB\")\n\
109  --voltage=<nnnn> - Specify Vcc voltage in mV (default = 3333)\n\
110  --tcpport=<n> - Listen on TCP port n (default 2000)\n\
111  --keepalive - Keep running after GDB disconnects, wait for next connection\n\
112  --autoerase - Erase FLASH when debugging is started\n\
113 ");
114 }
115 
116 void ParseOptions(int argc, char* argv[], GlobalSettings &settings)
117 {
118  for (int i = 1; i < argc; i++)
119  {
120  std::string arg;
121  char *sep = strchr(argv[i], '=');
122  char *val = NULL;
123  if (sep)
124  arg = std::string(argv[i], sep - argv[i]), val = sep + 1;
125  else
126  arg = argv[i];
127 
128  if (arg.length() < 2 || arg[0] != '-' || arg[1] != '-')
129  {
130  printf("Warning: unknown option: %s\n", arg.c_str());
131  continue;
132  }
133 
134  arg = arg.substr(2);
135 
136  if (arg == "noeem")
137  settings.EnableEEMMode = false;
138  else if (arg == "keepbp")
139  settings.InstantBreakpointCleanup = false;
140  else if (arg == "bp_insn")
141  {
142  if (strlen(val) < 3 || _memicmp(val, "0x", 2))
143  {
144  printf("Warning: wrong bp_insn format\n");
145  continue;
146  }
147  int insn = 0;
148  sscanf(val, "%x", &insn);
149  settings.BreakpointInstruction = insn;
150  }
151  else if (arg =="bpmode")
152  {
153  if (!val)
154  continue;
155  if (!strcmp(val, "soft"))
156  settings.SoftBreakPolicy = SoftwareOnly;
157  else if (!strcmp(val, "hard"))
158  settings.SoftBreakPolicy = HardwareOnly;
159  else if (!strcmp(val, "auto"))
161  }
162  else if (arg == "progport")
163  settings.PortName = val;
164  else if (arg == "tcpport")
165  settings.ListenPort = atoi(val);
166  else if (arg == "voltage")
167  settings.Voltage = atoi(val);
168  else if (arg == "keepalive")
169  settings.SingleSessionOnly = false;
170  else if (arg == "autoerase")
171  settings.AutoErase = true;
172  }
173 }
174 
175 int main(int argc, char* argv[])
176 {
177  GlobalSettings settings;
178 
179  if (argc >= 2 && !strcmp(argv[1], "--help"))
180  {
181  ShowHelpScreen();
182  return 0;
183  }
184 
185  ParseOptions(argc, argv, settings);
186 
187  LONG version = 0;
188  STATUS_T status = MSP430_Initialize((char *)settings.PortName, &version);
189  if (status != STATUS_OK)
190  {
191  printf("Cannot initalize MSP430.DLL on port %s: %s\n", settings.PortName, GetLastMSP430Error());
192  printf("\nRun msp430-gdbproxy --help for usage instructions.\n");
193  return 1;
194  }
195  MSP430_Close(FALSE);
196 
197  GDBServer srv(new MSP430StubFactory(settings));
198  ActionStatus st = srv.Start(settings.ListenPort);
199  if (!st.Successful())
200  {
201  _tprintf(_T("Cannot start listening on port %d: %s\n"), settings.ListenPort, st.GetMostInformativeText().c_str());
202  return 1;
203  }
204 
205  printf("msp430-gdbproxy++ v1.0 [http://gnutoolchains.com/msp430/gdbproxy]\n\
206 Run \"msp430-gdbproxy --help\" to get help.\n\
207 Listening on port %d.\nTo start debugging:\n\
208 \t1. Start \"msp430-gdb <yourfile.elf>\"\n\
209 \t2. Run the \"target remote :%d\" command in GDB.\n\
210 \t3. Run \"load\" to program the FLASH memory.\n\
211 \t4. In case of GDB errors, see this window for more info.\n", settings.ListenPort, settings.ListenPort);
212 
213  printf("If you don't have msp430-gdb, visit http://gnutoolchains.com/msp430 to get it.\n\n");
214 
215  srv.WaitForTermination();
216  return 0;
217 }