MSP430Target.cpp
Go to the documentation of this file.
1 #include "stdafx.h"
2 #include "MSP430Target.h"
3 #include "MSP430Util.h"
4 
5 using namespace GDBServerFoundation;
6 using namespace MSP430Proxy;
7 
8 #define REPORT_AND_RETURN(msg, result) { ReportLastMSP430Error(msg); return result; }
9 #define MAIN_SEGMENT_SIZE 512
10 
12 {
13  if (m_bClosePending)
14  return m_bValid;
15 
16  LONG version = 0;
17  if (MSP430_Initialize((char *)settings.PortName, &version) != STATUS_OK)
18  REPORT_AND_RETURN("Cannot initialize MSP430.DLL", false);
19  m_bClosePending = true;
20 
21  if (MSP430_VCC(settings.Voltage) != STATUS_OK)
22  REPORT_AND_RETURN("Cannot enable Vcc", false);
23 
24  if (MSP430_Identify((char *)&m_DeviceInfo, sizeof(m_DeviceInfo), DEVICE_UNKNOWN) != STATUS_OK)
25  REPORT_AND_RETURN("Cannot identify the MSP430 device", false);
26 
27  if (MSP430_Reset(ALL_RESETS, FALSE, FALSE) != STATUS_OK)
28  REPORT_AND_RETURN("Cannot reset the MSP430 device", false);
29 
30  if (settings.AutoErase)
31  {
32  printf("Erasing FLASH...\n");
33  if (MSP430_Erase(ERASE_MAIN, m_DeviceInfo.mainStart, m_DeviceInfo.mainEnd - m_DeviceInfo.mainStart) != STATUS_OK)
34  printf("Warning: cannot erase FLASH: %s\n", GetLastMSP430Error());
35  else
36  m_bFLASHErased = true;
37  }
38 
39  m_DeviceInfo.string[__countof(m_DeviceInfo.string) - 1] = 0;
40  printf("Found a device: %s\n", m_DeviceInfo.string);
41  printf("Number of hardware breakpoints: %d\n", m_DeviceInfo.nBreakpoints);
42  printf("%d bytes of FLASH memory (0x%04x-0x%04x)\n", m_DeviceInfo.mainEnd - m_DeviceInfo.mainStart + 1, m_DeviceInfo.mainStart, m_DeviceInfo.mainEnd);
43  printf("%d bytes of RAM (0x%04x-0x%04x)\n", m_DeviceInfo.ramEnd - m_DeviceInfo.ramStart + 1, m_DeviceInfo.ramStart, m_DeviceInfo.ramEnd);
44  if (m_DeviceInfo.ram2End || m_DeviceInfo.ram2Start)
45  printf("%d bytes of RAM2 (0x%04x-0x%04x)\n", m_DeviceInfo.ram2End - m_DeviceInfo.ram2Start + 1, m_DeviceInfo.ram2Start, m_DeviceInfo.ram2End);
46  printf("%d bytes of INFO memory (0x%04x-0x%04x)\n", m_DeviceInfo.infoEnd - m_DeviceInfo.infoStart + 1, m_DeviceInfo.infoStart, m_DeviceInfo.infoEnd);
47 
48  m_UsedBreakpoints.resize(m_DeviceInfo.nBreakpoints);
49 
50  m_bValid = true;
51  return true;
52 }
53 
54 #include "GlobalSessionMonitor.h"
55 
57 {
58  if (m_bClosePending)
59  {
60  printf("GDB Disconnected. Releasing MSP430 interface.\n");
61  MSP430_Close(FALSE);
62  }
63 
65 }
66 
68 {
69  for (;;)
70  {
71  LONG state = 0;
72  if (MSP430_State(&state, m_BreakInPending, NULL) != STATUS_OK)
73  REPORT_AND_RETURN("Cannot query device state", false);
74  if (state != RUNNING)
75  {
76  m_BreakInPending = false;
77  return true;
78  }
79  }
80 }
81 
82 GDBServerFoundation::GDBStatus MSP430Proxy::MSP430GDBTarget::ExecuteRemoteCommand( const std::string &command, std::string &output )
83 {
84  if (command == "help")
85  {
86  output = "Supported stub commands:\n\
87 \tmon help - Display this message\n\
88 \tmon erase - Erase the FLASH memory\n";
89  return kGDBSuccess;
90  }
91  else if (command == "erase")
92  {
93  if (MSP430_Erase(ERASE_MAIN, m_DeviceInfo.mainStart, m_DeviceInfo.mainEnd - m_DeviceInfo.mainStart) != STATUS_OK)
94  {
95  output = "Cannot erase FLASH: ";
96  output += GetLastMSP430Error();
97  output += "\n";
98  }
99  else
100  {
101  output = "Flash memory erased. Run \"load\" to program your binary.\n";
102  m_bFLASHErased = true;
103  }
104 
105  return kGDBSuccess;
106  }
107  else
108  return kGDBNotSupported;
109 }
110 
111 GDBServerFoundation::GDBStatus MSP430Proxy::MSP430GDBTarget::GetEmbeddedMemoryRegions( std::vector<EmbeddedMemoryRegion> &regions )
112 {
113  if (m_DeviceInfo.mainStart || m_DeviceInfo.mainEnd)
114  regions.push_back(EmbeddedMemoryRegion(mtFLASH, m_DeviceInfo.mainStart, m_DeviceInfo.mainEnd - m_DeviceInfo.mainStart + 1, MAIN_SEGMENT_SIZE));
115  if (m_DeviceInfo.ramStart || m_DeviceInfo.ramEnd)
116  regions.push_back(EmbeddedMemoryRegion(mtRAM, m_DeviceInfo.ramStart, m_DeviceInfo.ramEnd- m_DeviceInfo.ramStart + 1));
117  if (m_DeviceInfo.ram2Start || m_DeviceInfo.ram2End)
118  regions.push_back(EmbeddedMemoryRegion(mtRAM, m_DeviceInfo.ram2Start, m_DeviceInfo.ram2End- m_DeviceInfo.ram2Start + 1));
119  return kGDBSuccess;
120 }
121 
122 GDBServerFoundation::GDBStatus MSP430GDBTarget::GetLastStopRecord( TargetStopRecord *pRec )
123 {
124  pRec->Reason = kSignalReceived;
125  pRec->Extension.SignalNumber = SIGTRAP;
126  return kGDBSuccess;
127 }
128 
129 GDBServerFoundation::GDBStatus MSP430GDBTarget::ResumeAndWait( int threadID )
130 {
131  if (!DoResumeTarget(RUN_TO_BREAKPOINT))
132  return kGDBUnknownError;
133 
134  if (!WaitForJTAGEvent())
135  return kGDBUnknownError;
136  return kGDBSuccess;
137 }
138 
139 GDBServerFoundation::GDBStatus MSP430GDBTarget::Step( int threadID )
140 {
141  if (!DoResumeTarget(SINGLE_STEP))
142  return kGDBUnknownError;
143 
144  if (!WaitForJTAGEvent())
145  return kGDBUnknownError;
146 
147  return kGDBSuccess;
148 }
149 
150 GDBServerFoundation::GDBStatus MSP430GDBTarget::SendBreakInRequestAsync()
151 {
152  m_BreakInPending = true;
153  return kGDBSuccess;
154 }
155 
156 GDBServerFoundation::GDBStatus MSP430GDBTarget::ReadFrameRelatedRegisters( int threadID, RegisterSetContainer &registers )
157 {
158  LONG rawRegs[16] = {0,};
159  if (MSP430_Read_Registers(rawRegs, MASKREG(PC) | MASKREG(SP)) != STATUS_OK)
160  REPORT_AND_RETURN("Cannot read frame-related registers", kGDBUnknownError);
161 
162  registers[PC] = RegisterValue(rawRegs[PC], 2);
163  registers[SP] = RegisterValue(rawRegs[SP], 2);
164 
165  return kGDBSuccess;
166 }
167 
168 GDBServerFoundation::GDBStatus MSP430GDBTarget::ReadTargetRegisters( int threadID, RegisterSetContainer &registers )
169 {
170  LONG rawRegs[16] = {0,};
171  if (MSP430_Read_Registers(rawRegs, ALL_REGS) != STATUS_OK)
172  REPORT_AND_RETURN("Cannot read device registers", kGDBUnknownError);
173 
174  for (size_t i = 0; i < __countof(rawRegs); i++)
175  registers[i] = RegisterValue(rawRegs[i], 16);
176 
177  return kGDBSuccess;
178 }
179 
180 GDBServerFoundation::GDBStatus MSP430GDBTarget::WriteTargetRegisters( int threadID, const RegisterSetContainer &registers )
181 {
182  LONG rawRegs[16] = {0,};
183  int mask = 0;
184 
185  for (size_t i = 0; i < 16; i++)
186  if (registers[i].Valid)
187  {
188  mask |= MASKREG(i);
189  rawRegs[i] = registers[i].ToUInt16();
190  }
191 
192  if (MSP430_Write_Registers(rawRegs, mask) != STATUS_OK)
193  REPORT_AND_RETURN("Cannot write device registers", kGDBUnknownError);
194 
195  return kGDBSuccess;
196 }
197 
198 GDBServerFoundation::GDBStatus MSP430GDBTarget::ReadTargetMemory( ULONGLONG Address, void *pBuffer, size_t *pSizeInBytes )
199 {
200  if (MSP430_Read_Memory((LONG)Address, (char *)pBuffer, *pSizeInBytes) != STATUS_OK)
201  REPORT_AND_RETURN("Cannot read device memory", kGDBUnknownError);
202  return kGDBSuccess;
203 }
204 
205 GDBServerFoundation::GDBStatus MSP430GDBTarget::WriteTargetMemory( ULONGLONG Address, const void *pBuffer, size_t sizeInBytes )
206 {
207  if (Address >= m_DeviceInfo.mainStart && Address <= m_DeviceInfo.mainEnd)
208  {
209  if (!m_bFLASHErased)
210  {
211  printf("Error: FLASH needs to be erased before programming.\nPlease either use gdb with XML support, or execute \"mon erase\" command in GDB.");
212  return kGDBUnknownError;
213  }
214  }
215 
216  if (MSP430_Write_Memory((LONG)Address, (char *)pBuffer, sizeInBytes) != STATUS_OK)
217  REPORT_AND_RETURN("Cannot write device memory", kGDBUnknownError);
218  return kGDBSuccess;
219 }
220 
221 GDBServerFoundation::GDBStatus MSP430GDBTarget::GetDynamicLibraryList( std::vector<DynamicLibraryRecord> &libraries )
222 {
223  return kGDBNotSupported;
224 }
225 
226 GDBServerFoundation::GDBStatus MSP430GDBTarget::GetThreadList( std::vector<ThreadRecord> &threads )
227 {
228  return kGDBNotSupported;
229 }
230 
231 GDBServerFoundation::GDBStatus MSP430GDBTarget::SetThreadModeForNextCont( int threadID, DebugThreadMode mode, OUT bool *pNeedRestoreCall, IN OUT INT_PTR *pRestoreCookie )
232 {
233  return kGDBNotSupported;
234 }
235 
236 GDBServerFoundation::GDBStatus MSP430GDBTarget::Terminate()
237 {
238  return kGDBNotSupported;
239 }
240 
241 GDBServerFoundation::GDBStatus MSP430GDBTarget::CreateBreakpoint( BreakpointType type, ULONGLONG Address, unsigned kind, OUT INT_PTR *pCookie )
242 {
243  if ((type == bptHardwareBreakpoint) || (type == bptSoftwareBreakpoint))
244  {
245  for (size_t i = 0; i < m_UsedBreakpoints.size(); i++)
246  {
247  if (!m_UsedBreakpoints[i])
248  {
249  if (MSP430_Breakpoint(i, (LONG)Address) != STATUS_OK)
250  REPORT_AND_RETURN("Cannot set a hardware breakpoint", kGDBUnknownError);
251  m_UsedBreakpoints[i] = true;
252  *pCookie = i;
253  return kGDBSuccess;
254  }
255  }
256  printf("Warning! Out of hardware breakpoints. Please use the EEM mode for software breakpoint support.\n");
257  return kGDBUnknownError;
258  }
259  return kGDBNotSupported;
260 }
261 
262 GDBServerFoundation::GDBStatus MSP430GDBTarget::RemoveBreakpoint( BreakpointType type, ULONGLONG Address, INT_PTR Cookie )
263 {
264  if ((type == bptHardwareBreakpoint) || (type == bptSoftwareBreakpoint))
265  {
266  size_t i = (size_t)Cookie;
267  MSP430_Clear_Breakpoint(i);
268  m_UsedBreakpoints[i] = false;
269 
270  return kGDBSuccess;
271  }
272  return kGDBNotSupported;
273 }
274 
275 GDBServerFoundation::GDBStatus MSP430Proxy::MSP430GDBTarget::EraseFLASH( ULONGLONG addr, size_t length )
276 {
277  m_bFLASHCommandsUsed = true;
278  if (MSP430_Erase(ERASE_MAIN, (LONG)addr, length) != STATUS_OK)
279  REPORT_AND_RETURN("Cannot erase FLASH memory", kGDBUnknownError);
280  m_bFLASHErased = true;
281  return kGDBSuccess;
282 }
283 
284 GDBServerFoundation::GDBStatus MSP430Proxy::MSP430GDBTarget::WriteFLASH( ULONGLONG addr, const void *pBuffer, size_t length )
285 {
286  m_bFLASHCommandsUsed = true;
287  if (MSP430_Write_Memory((LONG)addr, (char *)pBuffer, length) != STATUS_OK)
288  REPORT_AND_RETURN("Cannot program FLASH memory", kGDBUnknownError);
289  return kGDBSuccess;
290 }
291 
292 GDBServerFoundation::GDBStatus MSP430Proxy::MSP430GDBTarget::CommitFLASHWrite()
293 {
294  m_bFLASHCommandsUsed = true;
295  return kGDBSuccess;
296 }
297 
299 {
300  if (pHint)
301  printf("%s: %s\n", pHint, GetLastMSP430Error());
302  else
303  printf("%s\n", GetLastMSP430Error());
304 }
305 
307 {
308  if (MSP430_Run(mode, FALSE) != STATUS_OK)
309  REPORT_AND_RETURN("Cannot resume device", false);
310 
311  return true;
312 }
313