Code::Blocks Forums

Developer forums (C::B DEVELOPMENT STRICTLY!) => Plugins development => Topic started by: BlueHazzard on September 25, 2016, 05:28:29 pm

Title: Extend GDB plugin to communicate with other plugins
Post by: BlueHazzard on September 25, 2016, 05:28:29 pm
For embedded arm development i would like to use the gdb debugger. But the current plugin is missing some features i would like o add (like a peripheral register watch ecc.). I would like to avoid to clone the current plugin but instead create a type of cross plugin communication... The easiest would be to add a function to send Commands to the debugger and return the answer from gdb... Probably over the event system for asynchronous calls?

Are there any thoughts, counter arguments?
Title: Re: Extend GDB plugin to communicate with other plugins
Post by: oBFusCATed on September 25, 2016, 06:05:57 pm
I don't like the idea. If we do this then we need to have code that handles plugin deps and makes sure that dependant plugins are loaded before the plugin that needs them.
This is complex and error prone.

Why don't you just extend the cpu registers window with the needed functionality and the debugger api to match the needed features?
I'll be happy to guide you, review and commit the changes.
Title: Re: Extend GDB plugin to communicate with other plugins
Post by: BlueHazzard on September 25, 2016, 06:54:32 pm
I don't like the idea. If we do this then we need to have code that handles plugin deps and makes sure that dependant plugins are loaded before the plugin that needs them.
This is complex and error prone.
I see the problem here... Couldn't this be handled by using events? If the receiver plugin is not loaded the the events simply get to nirvana and the plugin detects it somehow over a timeout (wild speculations here)...

Why don't you just extend the cpu registers window with the needed functionality and the debugger api to match the needed features?
I'll be happy to guide you, review and commit the changes.
I am not happy with extending the current plugin with the features, because i would like to make something like this:
(http://www.atmel.com/Images/io_view.jpg)
and for this i need a .svd file parser and so on. This would bloat the plugin and if someone is not using the embedded stuff this is not needed...

An other possibility would be to extend the watch parsing (squirrel) with the ability to modify the controls....
Title: Re: Extend GDB plugin to communicate with other plugins
Post by: oBFusCATed on September 26, 2016, 12:50:44 am
and for this i need a .svd file parser and so on.
What is a svd file?

I am not happy with extending the current plugin with the features, because i would like to make something like this:
(http://www.atmel.com/Images/io_view.jpg)
Do you need this to be a tree ctrl?

This would bloat the plugin and if someone is not using the embedded stuff this is not needed...
It could be enabled per configuration and not on by default.

An other possibility would be to extend the watch parsing (squirrel) with the ability to modify the controls....
Don't do this, the squirrel code in the debugger plugin will be removed as soon as I finish merging the sqrat stuff.
Title: Re: Extend GDB plugin to communicate with other plugins
Post by: BlueHazzard on September 26, 2016, 01:23:46 am
What is a svd file?
for ex. http://www.keil.com/pack/doc/cmsis/svd/html/svd__example_pg.html The file describes the internal periphery register structure of arm and other µC (i know the files also for  atmega/xmega)..

Quote
Do you need this to be a tree ctrl?
i don't know the UI yet.... some kind of property grid, it should have the possibility to use drop down menus,check boxes and text fields. Custom controls like leds (red dots) would also be nice...  A search field would also be needed, because there can be ton's of register and flag names

Quote
Quote
Quote from: BlueHazzard on Yesterday at 18:54:32
This would bloat the plugin and if someone is not using the embedded stuff this is not needed...
It could be enabled per configuration and not on by default.
By bloating i mean code/ binary size... More things to maintain for the main dev team ;) Of corse it is possible to add it at the core and make it configurable, but i don't like the idea to add something to the main plugin what is not needed for the core. Because there is also potential for more logging/debugging like:
(http://www.visualmicro.com/pics/Arduino%20Debug%20Auto%20Reports%20Config%20Example%20Small.png)
I don't think this functionality should be in the core. But if you want to use codeblocks  (i think there is no really nice, cross platform and fast IDE for debugging embedded systems out there) for embedded development you "need" this things. It would simply be nice to have somehow an interface to gdb...

Quote
Quote
Quote from: BlueHazzard on Yesterday at 18:54:32
    An other possibility would be to extend the watch parsing (squirrel) with the ability to modify the controls....
Don't do this, the squirrel code in the debugger plugin will be removed as soon as I finish merging the sqrat stuff.
Sad... i think there would be a lot potential. Specially in automation of gdb things and embedded stuff (see previous image)...




Title: Re: Extend GDB plugin to communicate with other plugins
Post by: oBFusCATed on September 26, 2016, 08:40:49 pm
for ex. http://www.keil.com/pack/doc/cmsis/svd/html/svd__example_pg.html The file describes the internal periphery register structure of arm and other µC (i know the files also for  atmega/xmega)..
I think some of the embedded forks of cb has a parser for this added to the wizard.

i don't know the UI yet.... some kind of property grid, it should have the possibility to use drop down menus,check boxes and text fields. Custom controls like leds (red dots) would also be nice...  A search field would also be needed, because there can be ton's of register and flag names
Unfortunately the propgrid is the best ui for this, but I'm not sure I like this control. Especially the migration from 2.8 to 3.x. :(

By bloating i mean code/ binary size... More things to maintain for the main dev team ;) Of corse it is possible to add it at the core and make it configurable, but i don't like the idea to add something to the main plugin what is not needed for the core.
Don't worry too much about this. The cpu registers window needs improvements. If you make them general enough it might be good for all users.
And there people which will be happy to use something like cb, instead of the vendors ides.

Because there is also potential for more logging/debugging like:
(http://www.visualmicro.com/pics/Arduino%20Debug%20Auto%20Reports%20Config%20Example%20Small.png)
I don't think this functionality should be in the core. But if you want to use codeblocks  (i think there is no really nice, cross platform and fast IDE for debugging embedded systems out there) for embedded development you "need" this things. It would simply be nice to have somehow an interface to gdb...
This is totally separate topic and probably a lot more work and it is better to discuss it later, when the cpu registers problem is solved.

The problems with interfacing with the debugger from another plugin is that:
1. parsing the output is hard and is done on per command basis, so you need to do some parsing in your plugin.
2. you make a connection where your plugin starts to depend on the behaviour of one particular debugger plugin, which is not a good idea.

Sad... i think there would be a lot potential. Specially in automation of gdb things and embedded stuff (see previous image)...
Now we have python printers directly in gdb, which do better job handling the watches. Our scripts for the watches need lots of work, I'm not sure how to do even. We need a way to execute a command, wait for its output, parse it, execute another command and so on.
If you have idea where scripting might help, I'm ready to discuss them.
Title: Re: Extend GDB plugin to communicate with other plugins
Post by: oBFusCATed on September 26, 2016, 08:42:05 pm
And for the record I don't like the idea to have two separate cpu registers windows - one for host and one for embedded development.
Title: Re: Extend GDB plugin to communicate with other plugins
Post by: BlueHazzard on September 26, 2016, 11:49:55 pm
Quote
I think some of the embedded forks of cb has a parser for this added to the wizard.
I have looked into emBitz, but it is somehow closed source and won't run on linux...

Quote
Don't worry too much about this. The cpu registers window needs improvements. If you make them general enough it might be good for all users.
And there people which will be happy to use something like cb, instead of the vendors ides.
Quote
And for the record I don't like the idea to have two separate cpu registers windows - one for host and one for embedded development.
The thing is this: periphery register are not cpu registers... (like the program counter or the cpu status register) this register are read with the info registers command of gdb.
Periphery register on the other hand are located on a special memory location and read with the x command.

It is possible to merge this two register views, but i don't know if this is a wide spread opinion...
Title: Re: Extend GDB plugin to communicate with other plugins
Post by: oBFusCATed on September 27, 2016, 08:38:52 am
I have looked into emBitz, but it is somehow closed source and won't run on linux...
Does it still look like code::blocks 10.05?

It is possible to merge this two register views, but i don't know if this is a wide spread opinion...
Why not?
Title: Re: Extend GDB plugin to communicate with other plugins
Post by: BlueHazzard on September 28, 2016, 07:44:45 pm
I looks somehow like visual studio 2012 or so... And the settings ui is quite different, i had difficulties to find me around...


Quote
Why not?
Well lets try it...

Can you give me some overlook over the architecture?
What is the intention to not call (queue) the debugger commands from the DebuggerGDB class, but translate them  through the driver?
Title: Re: Extend GDB plugin to communicate with other plugins
Post by: oBFusCATed on September 28, 2016, 08:03:34 pm
There are two drivers at the moment - one for gdb and one for cdb.
This is the reason. This the original way the plugin has been coded, because there was no debugger apis in codeblocks at the time.
If it was done from scratch now - we'll have two separate plugins.
Title: Re: Extend GDB plugin to communicate with other plugins
Post by: BlueHazzard on March 01, 2017, 09:20:36 pm
So, here i am again...

I would really like to work on this, but there are some things to clear up first:
1) My final goal is to implement a svd file viewer as i described at the top. The svd file describes the internal peripheral register structure of a microprocessor (ARM, AVR, STM ecc...). This registers are located in the "RAM"-address space of the mcu (=microprocessor) and have nothing to do with the CPU core registers like the program counter or the cpu status register.
The later are read via the "reg" command in gdb. Peripheral register, on the other hand, are read by accessing the memory (x command). This means they have nothing in common. But i have seen some programs where this views are combined.

2) I don't see a urge necessity to recreate the cpu register dialog. There are all information listed and the dialog is quite simple. Of corse it could be made nicer and add some functions like reinterpreting of values and i am willing to work on this.

3) I would create a new plugin for this functionality. But then some interface to the debugger plugin is needed.

If the outcome of this discussion is to add this functionality to the cpu register window there are some things to clear:
1) Where store the path to the SVD file. There is the need of a project settings place. Probably the "Debugger" tab of the Project options
2) What control has to be used. I think the property grid is needed!
3) Is there the will of the devs to integrate my work in the code base (this point is always valid)
4) Because the cpu register and peripheral register are called from different gdb commands there is a lot of rework in the current gdb driver
5) This will add a "huge" xml parser for svd files, that has to be maintained, to the codeblocks code base

If the outcome is that i create a new plugin a interface to the gdb plugin is needed:
1) I can think of a universal interface
1.1) like "wxString SendCommandToCurrentActiveDebugger(wxString command)" what is blocking, takes a string as command and returns a string as response
1.2) Or a cb event? Something like request debugger command... with a global answer event, for all plugins...
2) It should be future proof, if there is at some point the transmission to the mi interface it should still work
3) like on top

i would really like some thoughts about this

Why to care:
Embedded development is a big part of the today c/c++ development. The only platform Independent IDEs i know for this is Eclipse and Codeblocks. And we don't talk about Eclipse here (big, slow, bloated). And for embedded development you need to debug, and for this a svd viewer is a essential part...
Title: Re: Extend GDB plugin to communicate with other plugins
Post by: oBFusCATed on March 02, 2017, 12:24:22 am
If the outcome is that i create a new plugin a interface to the gdb plugin is needed:
1) I can think of a universal interface
1.1) like "wxString SendCommandToCurrentActiveDebugger(wxString command)" what is blocking, takes a string as command and returns a string as response
1.2) Or a cb event? Something like request debugger command... with a global answer event, for all plugins...
2) It should be future proof, if there is at some point the transmission to the mi interface it should still work
3) like on top

This will work only for current GDB's debugger, switching to GDB/mi will most probably break it, because the commands and the command's output is totally different. I suppose that LLDB also has different output no matter that it supports the mi protocol. So I suggest to discard this solution.
Title: Re: Extend GDB plugin to communicate with other plugins
Post by: oBFusCATed on March 02, 2017, 12:30:40 am
If the outcome of this discussion is to add this functionality to the cpu register window there are some things to clear:
1) Where store the path to the SVD file. There is the need of a project settings place. Probably the "Debugger" tab of the Project options
2) What control has to be used. I think the property grid is needed!
3) Is there the will of the devs to integrate my work in the code base (this point is always valid)
4) Because the cpu register and peripheral register are called from different gdb commands there is a lot of rework in the current gdb driver
5) This will add a "huge" xml parser for svd files, that has to be maintained, to the codeblocks code base
1. This is fine, but this is only GDB's plugin UI. Other plugins will create separate tabs, so this is a bit grey area. I never got to make the per project UI unified. :(
2. The prop grid is a bit unstable and hard to use control, but this is the only option for wx2.8 and wx3.0. If we've switched to wx3. you could consider wxListTreeCtrl, but we have not so this is not an option
3. It depends on how it is done, the quality of the code, documentation, etc. For some of the variants I'll be reluctant to include them.
4. I don't think so, you'll have to add another cpu registers refreshing command, so I think it should be pretty straight forward
5. Why huge? It can be separated in a separate h/cpp files, so if it causes problems we could easily remove it. This should be in the gdb plugin for now
Title: Re: Extend GDB plugin to communicate with other plugins
Post by: BlueHazzard on March 03, 2017, 03:37:26 am
Ok i have started some work, and i think for the beginning it does look neat:
https://github.com/bluehazzard/codeblocks_sf

i have added a search field to quick search through the names of the registers.

only wx2.8 at the moment
Title: Re: Extend GDB plugin to communicate with other plugins
Post by: BlueHazzard on July 27, 2017, 01:50:46 pm
i continued my work and have now finished the svd file parser.
My next step is to implement the api to read the periphery register from the microcontroller.

I thought a lot about this and i think the best solution would be to implement "memory watches". They would be implemented like the current watches but instead to use the "print" gdb command they would use "x" command.

Any thoughts about this?

On a second thought, i would like to save the window, where the watch is, into the "cbWatch" class (and also into the new cbMemoryWatch class). This would enable the ability to use the same memory watch for the ExamineMemory dialogue and the  periphery register dialogue. This would also allow to add multiple memory windows and watch windows like they exist in other IDEs.

Title: Re: Extend GDB plugin to communicate with other plugins
Post by: oBFusCATed on July 27, 2017, 05:25:50 pm
Multiple watch windows aren't implemented because wxAUI doesn't support moving one pane to a random notebook, so there is no UI space left. Unfortunately I don't think wx will add this feature any time soon, so we'll have to probably think about some hacky solution. :(

For the memory watches - just add the appropriate flags in the GDBWatch class and do separate processing based on these flags.
I don't understand all the talk about the ExamineMemory dialogs...

Keep in mind that working on the current gdb plugin will most probably be a waste of your time...

Do you have some branch somewhere I can look at?
Title: Re: Extend GDB plugin to communicate with other plugins
Post by: BlueHazzard on July 28, 2017, 01:52:32 pm
Quote
Multiple watch windows aren't implemented because wxAUI doesn't support moving one pane to a random notebook, so there is no UI space left. Unfortunately I don't think wx will add this feature any time soon, so we'll have to probably think about some hacky solution. :(
Multiple tabs for the watches window? Anyway, this is not part of this discussion, i wanted only show a second use case.


For future discussion: Keep in mind that i want to implement this on codeblocks sdk level, not GDB-plugin level, because the functionality is debugger agnostic. If the debugger supports memory read out (as the most do) the debugger supports svd/register readout
Quote
For the memory watches - just add the appropriate flags in the GDBWatch class and do separate processing based on these flags.
So you think about modifying the cbWatch class? This would be ok, what about to store the owner of the watch?

Quote
I don't understand all the talk about the ExamineMemory dialogs...
on embedded development it is quite handy

Quote
Keep in mind that working on the current gdb plugin will most probably be a waste of your time...
I don't think so:
1) We are talking about to replace the gdb plugin for years now, at the plugin is still the old
2) I need this functionality quite often...
3) As i mentioned at the top this is debugger agnostic

Quote
Do you have some branch somewhere I can look at?
i have started some work here: https://github.com/bluehazzard/codeblocks_sf on the new_cpu_register_window_01 branch
[Edit:] The svd parser is not pushed yet...
Title: Re: Extend GDB plugin to communicate with other plugins
Post by: oBFusCATed on July 29, 2017, 02:46:28 pm
Let me know when you have everything published, so I can inspect it fully.

One note don't add non generic stuff to sdk classes. I can see you're adding some svd fields in the project. This is not a good idea. Add some generic storage and provide a way to define multiple parsers. As far as I can see svd is arm only and thus it is not generic.

For cbWatch, I don't know if I like the idea to be used in the cpu register ui. For sure I don't want to store pointers to windows in it. Probably you can add something like a purpose field or something like this. And definitely it is not good idea to use it in the examine memory window. This window must be made to work with arrays of bytes...

There a few subsystems of cb that are in worse state than the debugger, so they have priority in my todo at the moment.
Title: Re: Extend GDB plugin to communicate with other plugins
Post by: BlueHazzard on July 29, 2017, 03:52:53 pm
Quote
One note don't add non generic stuff to sdk classes. I can see you're adding some svd fields in the project. This is not a good idea. Add some generic storage and provide a way to define multiple parsers. As far as I can see svd is arm only and thus it is not generic.

You know, exactly this is the point i wanted to state on the top of this discussion. This should not be part of the sdk or the debugger plugin, but you said me that it is ok to implement this kind of stuff into the sdk. I don't like this idea, so i will go one step back and try some other approach:

1) Extend the SDK with a class called cbMemoryWatch (pseudocode):
Code
class cbMemoryWatch 
{
  uint64_t m_address;  // start address of the memory watch
  uint64_t m_count;      // count of bytes
  vector<uint8_t> m_data; // The actual data

  bool IsChanged() const;
  const std::vector<uint8_t>& GetData()
}
This class will hold a watch on a continuous memory (RAM) area with m_count size. (so for example 256 Bytes form address 0x331E34 )

Extend the cbDebuggerPlugin class with this API functions:
Code
virtual cb::shared_ptr<cbMemoryWatch> AddMemoryWatch(const uint64_t address, const uint64_t count) = 0;
virtual void DeleteMemoryWatch(cb::shared_ptr<cbMemoryWatch> watch) = 0;
virtual bool HasMemoryWatch(cb::shared_ptr<cbMemoryWatch> watch) = 0;
virtual bool SetMemoryWatchValue(cb::shared_ptr<cbMemoryWatch> watch, const std::vector<uint8_t>& value) = 0;
virtual void UpdateMemoryWatch(cb::shared_ptr<cbMemoryWatch> watch) = 0;
the MemoryWatches will get updated like the normal watches on every hold of the debugger, but with the "x" gdb command and not with "print" like the watches.

With this API it should be possible to implement a SVD (or any other) view as a plugin.
Title: Re: Extend GDB plugin to communicate with other plugins
Post by: oBFusCATed on July 29, 2017, 05:03:26 pm
I guess, I'm not getting the idea of svds.
In the beginning you wanted to plug them in the cpu register's window, now you want to plug them in the examine memory or make new window.
I'm totally confused.

p.s. m_count doesn't make sense when m_data is a vector...
Title: Re: Extend GDB plugin to communicate with other plugins
Post by: BlueHazzard on July 29, 2017, 05:56:45 pm
i never wanted to put them in the cpu register window, that was your idea... Ok from the beginning:

1) Microcontroller have special function register (SFR), where the functionality of the periphery is controlled. This register are mostly stored in a RAM block, or at least accessible over a RAM instruction, so they can be read out with the debugger with the "x" command. They are called register, but have nothing to do with the CPU internal register like the EIP or the PC (program counter) found in the CPU.

2) SVD files are special files (from ARM) that describe the location and the value of this special function register. They describe that on location 0x123413 is the SFR called UART_CTRL and if this register has the value 0x44 then the UART is activated, but if it has the value 0x33 it is deactivated. The SVD file describes also how you create header files to control this registers and many more things. This files are provided by the hardware manufacturers of the microcontroller. SVD is some file standard mostly used for ARM, but similar files exist for other microcontroller

3) So I want a window (property grid tree) that displays me the status of this SFR. For this the debugger reads some part of the RAM and interprets the data in it with the help of the svd file

4) What is needed: A interface to the debugger that lets you read , not necessarily connected, parts of the RAM (1). Where can this be found: In the memory window, so my thoughts were to connect this two things.

The interpreting and displaying of the SFR is a microcontroller specific task, so i personally think it should be put in a plugin. The needed functionality to the debugger is only read pieces of memory, what every debugger should be possible, but the plugin needs a interface for this. My idea is to introduce the concept of "memory watches" as described above, so any plugin can add watches to the current running debugger and keep track of them with a shared_ptr (probably not the best way, but hey this is how it is made with the watches)

(1) for example 12 Bytes starting from 0xAA1234, 4 Bytes starting from 0xAA1223 ecc.
Title: Re: Extend GDB plugin to communicate with other plugins
Post by: oBFusCATed on July 29, 2017, 06:32:17 pm
Are these things always read using the x command? For all controllers or this is stored in the svd?
The term memory watches is not a good one. It is close to data watches.
Is it possible for these things to have sub-fields? Or do they store just a single value?
Do we need to display them in the UI like we display a C/C++ struct?

The cbMemoryWatch proposal is not a good one because it expands the API too much.
Lets see if we can reuse the watches functionality for these things.

edit: What is the cheapest way I can get one such controller+jtag debugger for experimentation?
Title: Re: Extend GDB plugin to communicate with other plugins
Post by: BlueHazzard on July 29, 2017, 07:43:07 pm
Quote
Are these things always read using the x command? For all controllers or this is stored in the svd?
As far as i can tell all big microcontroller map their periphery register to ram, so it should always be possible to read them from ram with x.

Quote
Is it possible for these things to have sub-fields? Or do they store just a single value?
Do we need to display them in the UI like we display a C/C++ struct?
I can not find any nice image but you can get a idea from here: http://www.forward.com.au/BluetoothLedDriver/PINB_PB2.JPG for AVR

PORTB is a periphery with the register PINB (at address 0x36 with the value 0x04), DDRB (at address 0x37 with the value 0x00) and PORTB  (at address 0x38 with the value 0x04)
Now if i would use the memory watch idea, i would create a watch with the address 0x36 and the count of 3. This would return me {0x04, 0x00, 0x04} and the plugin would interpret  it and fill the property grid..

This image is not ideal, because one register can be divided in more Bit fields (from different size) and every bit field can have multiple values, selected by a drop down list.  Each bitfield can have different attributes like: read only, write only, write only once ecc...
Also one register can be multiple bytes large (AVR 8Bit register vs ARM 32 or 64bit register), this is described in the svd file.

Quote
Lets see if we can reuse the watches functionality for these things.
i am open for ideas, but keep in mind that it should be fast and the data should be as raw as possible...

Quote
The cbMemoryWatch proposal is not a good one because it expands the API too much.
I can understand this point to some extend if there are a lot external plugins, but codeblocks, at the moment, is not a application with tons of external plugins (at least i am not aware of them), so breaking the API should not be a big deal.

Quote
edit: What is the cheapest way I can get one such controller+jtag debugger for experimentation?
probably a NUCLEO-F103RB, nucleo-f091rc or a other stm discovery board (ARM controller from STMicroelectronics ) with around 15€. The debugger (SWD) is included and you get the possibility to make a full j-link ( https://www.segger.com/products/debug-probes/j-link/models/other-j-links/st-link-on-board/ ) out of it. Note: i have yet to try to use the stm controller to work in codeblocks. At the moment i use an arduino due and a j-link from segger (Atmel ARM controller)
Title: Re: Extend GDB plugin to communicate with other plugins
Post by: oBFusCATed on July 29, 2017, 10:54:46 pm
API Breakage is not problematic. I just don't want to make the API big. I prefer if we could re-use as much as possible.

Do you expect to add "watches" for all supported "registers" from the file at once or do you add them one by one (the ones you need at the moment)?

Can you find some example svd file and then show the UI we should generate? So we can have something more concrete example we could discuss.
If you read every register with a single x command then the performance will be rather bad (similarly bad as if you add many watches).
The commands are executed synchronously, if you want asynchronous execution then gdb/mi protocol should be used.
Title: Re: Extend GDB plugin to communicate with other plugins
Post by: BlueHazzard on July 30, 2017, 02:19:38 am
Quote
API Breakage is not problematic. I just don't want to make the API big. I prefer if we could re-use as much as possible.
But you have to give people a possibility to work with it.
With the current implementation of the watches, every watch saved in the interna of the debugger is mirrored to the watches window. For this purpose this is not wanted...

Quote
Do you expect to add "watches" for all supported "registers" from the file at once or do you add them one by one (the ones you need at the moment)?
Probably as needed. It would be nice to make the first read out to read all registers but this can be a lot data (11kByte) and so it is probably better to read only the current open registers. This should be as fast as possible...

Quote
Can you find some example svd file and then show the UI we should generate? So we can have something more concrete example we could discuss.
If you read every register with a single x command then the performance will be rather bad (similarly bad as if you add many watches).
I updated my test app to populate a property grid. This is by far not complete (1), but you will get a idea (img is attached)
The corresponding part of the svd file (only the uart/MR register is shown:
Code
   <name>UART</name>
      <version>6418H</version>
      <description>Universal Asynchronous Receiver Transmitter</description>
      <prependToName>UART_</prependToName>
      <baseAddress>0x400E0800</baseAddress>
      <addressBlock>
        <offset>0</offset>
        <size>0x128</size>
        <usage>registers</usage>
      </addressBlock>
      <interrupt>
        <name>UART</name>
        <value>8</value>
      </interrupt>
      <registers>
          <name>CR</name>
          <description>Control Register</description>
          <addressOffset>0x00000000</addressOffset>
          <size>32</size>
          <access>write-only</access>
          <fields>
            <field>
              <name>RSTRX</name>
              <description>Reset Receiver</description>
              <bitOffset>2</bitOffset>
              <bitWidth>1</bitWidth>
              <access>write-only</access>
            </field>
            <field>
              <name>RSTTX</name>
              <description>Reset Transmitter</description>
              <bitOffset>3</bitOffset>
              <bitWidth>1</bitWidth>
              <access>write-only</access>
            </field>
            <field>
              <name>RXEN</name>
              <description>Receiver Enable</description>
              <bitOffset>4</bitOffset>
              <bitWidth>1</bitWidth>
              <access>write-only</access>
            </field>
            <field>
              <name>RXDIS</name>
              <description>Receiver Disable</description>
              <bitOffset>5</bitOffset>
              <bitWidth>1</bitWidth>
              <access>write-only</access>
            </field>
            <field>
              <name>TXEN</name>
              <description>Transmitter Enable</description>
              <bitOffset>6</bitOffset>
              <bitWidth>1</bitWidth>
              <access>write-only</access>
            </field>
            <field>
              <name>TXDIS</name>
              <description>Transmitter Disable</description>
              <bitOffset>7</bitOffset>
              <bitWidth>1</bitWidth>
              <access>write-only</access>
            </field>
            <field>
              <name>RSTSTA</name>
              <description>Reset Status Bits</description>
              <bitOffset>8</bitOffset>
              <bitWidth>1</bitWidth>
              <access>write-only</access>
            </field>
          </fields>
        </register>
        <register>
          <name>MR</name>
          <description>Mode Register</description>
          <addressOffset>0x00000004</addressOffset>
          <size>32</size>
          <access>read-write</access>
          <resetValue>0x00000000</resetValue>
          <fields>
            <field>
              <name>PAR</name>
              <description>Parity Type</description>
              <bitOffset>9</bitOffset>
              <bitWidth>3</bitWidth>
              <access>read-write</access>
              <enumeratedValues>
                <enumeratedValue>
                  <name>EVEN</name>
                  <description>Even Parity</description>
                  <value>0x0</value>
                </enumeratedValue>
                <enumeratedValue>
                  <name>ODD</name>
                  <description>Odd Parity</description>
                  <value>0x1</value>
                </enumeratedValue>
                <enumeratedValue>
                  <name>SPACE</name>
                  <description>Space: parity forced to 0</description>
                  <value>0x2</value>
                </enumeratedValue>
                <enumeratedValue>
                  <name>MARK</name>
                  <description>Mark: parity forced to 1</description>
                  <value>0x3</value>
                </enumeratedValue>
                <enumeratedValue>
                  <name>NO</name>
                  <description>No Parity</description>
                  <value>0x4</value>
                </enumeratedValue>
              </enumeratedValues>
            </field>
            <field>
              <name>CHMODE</name>
              <description>Channel Mode</description>
              <bitOffset>14</bitOffset>
              <bitWidth>2</bitWidth>
              <access>read-write</access>
              <enumeratedValues>
                <enumeratedValue>
                  <name>NORMAL</name>
                  <description>Normal Mode</description>
                  <value>0x0</value>
                </enumeratedValue>
                <enumeratedValue>
                  <name>AUTOMATIC</name>
                  <description>Automatic Echo</description>
                  <value>0x1</value>
                </enumeratedValue>
                <enumeratedValue>
                  <name>LOCAL_LOOPBACK</name>
                  <description>Local Loopback</description>
                  <value>0x2</value>
                </enumeratedValue>
                <enumeratedValue>
                  <name>REMOTE_LOOPBACK</name>
                  <description>Remote Loopback</description>
                  <value>0x3</value>
                </enumeratedValue>
              </enumeratedValues>
            </field>
          </fields>
        </register>

(1) For example i would like to post the value of the current slected enumeration in the 3. column of the property gird, but was not able to do it... Also some icons would be nice. Make custom controls for only boolean register, display the bit field width in the 4. column and so on...
Title: Re: Extend GDB plugin to communicate with other plugins
Post by: oBFusCATed on July 30, 2017, 02:52:51 am
With the current implementation of the watches, every watch saved in the interna of the debugger is mirrored to the watches window. For this purpose this is not wanted...
Do you mean that there are GDBWatch and WatchesProperties objects? The cbWatch objects are managed by the debugger, because it knows best what additional data it needs for them to keep them up-to-date.

For this new cbWatch type we could add something like:
Code
cbWatch* cbDebuggerPlugin::AddPeripheralRegister(uint64_t address, uint64_t size, const wxString &id (or fullname) )

Probably as needed. It would be nice to make the first read out to read all registers but this can be a lot data (11kByte) and so it is probably better to read only the current open registers. This should be as fast as possible...
There is no way to be notified of changes in the memory locations (hw watch points are too limited for this purpose).
So if you want all "registers" to be updated at every "next line" or "step into" command then this will be massively slow.
In the watches window there is functionality that makes it possible to mark that you want only certain watches to be auto updated. And there is manual update command per watch. Similar mechanism should be use here, too.
Title: Re: Extend GDB plugin to communicate with other plugins
Post by: BlueHazzard on July 31, 2017, 01:49:34 pm
Quote
Quote from: BlueHazzard on Yesterday at 02:19:38

    With the current implementation of the watches, every watch saved in the interna of the debugger is mirrored to the watches window. For this purpose this is not wanted...

Do you mean that there are GDBWatch and WatchesProperties objects? The cbWatch objects are managed by the debugger, because it knows best what additional data it needs for them to keep them up-to-date.
i looked again in the code and now i think i understand what is going on:
1) Watches window creates a new watch with Manager::Get()->GetDebuggerManager()->AddWatch() and stores the returned value as a shared pointer in a list
2) If the watches window needs to update its state it reads the data from the shared pointer what contains the actual data, updated by the debugger plugin.
so you use shared pointer to share data between the plugin and the interface

So your proposal should be ok.

Quote
For this new cbWatch type we could add something like:
Code: [Select]
cbWatch* cbDebuggerPlugin::AddPeripheralRegister(uint64_t address, uint64_t size, const wxString &id (or fullname) )
Again, i would not make this (the name AddPeripheralRegister) so special... Just lets read a count of bytes from some memory location. This would allow us to make this way more flexible...

Quote
There is no way to be notified of changes in the memory locations (hw watch points are too limited for this purpose).
So if you want all "registers" to be updated at every "next line" or "step into" command then this will be massively slow.
In the watches window there is functionality that makes it possible to mark that you want only certain watches to be auto updated. And there is manual update command per watch. Similar mechanism should be use here, too.
Let me describe the procedure:
1) Start the debugger
2) Open the "System peripheral window". This window lists all registers from the svd file in a property grid-tree. All nodes are closed.
3) The target is halted for the first time (on the main entry point, this is some default behavior if you are debugging in embedded systems. The debugger stops after a reset/start and whaits for the user to run the target)
4) Optional: All registers are read for after reset state ( i don't think this is needed)
5) The user expands one or more peripheral nodes from the "System peripheral window". The debugger updates this elements from the target
6) User hits "run"
7) Target runs until breakpoint
8) debugger halts and updates all expanded registers from the "System peripheral window"
9) The user changes one value from a register
10) The debugger writes the new value to memory
11) The debugger updates the register view (to check if the write was successful)
11) User hits run
12) Loop to 6)

Title: Re: Extend GDB plugin to communicate with other plugins
Post by: oBFusCATed on July 31, 2017, 08:21:05 pm
Again, i would not make this (the name AddPeripheralRegister) so special... Just lets read a count of bytes from some memory location. This would allow us to make this way more flexible...
What do you mean by flexible here? I don't care much about the exact name, but I don't like MemoryWatch, because it is too similar to data breakpoint and tracepoints. Which are different things.

About step 1: How do you select the svd file? The user selects it every time the window is being opened? It is stored in a project/target/the window and the window resets it every time new debug session is started?
About Step 5: linking the expanding of the property and updating the values is not a good idea. At least for the watches it is a terrible idea, but I guess it might work for these fixed set of "registers" kind of window.
Step 8 will definitely be supper slow in the current implementation. I'm not sure if it will be fast in a gdb/mi implementation, too. The gdb/mi performance depends more on the gdb's performance than the integration.
Title: Re: Extend GDB plugin to communicate with other plugins
Post by: BlueHazzard on July 31, 2017, 09:50:38 pm
Quote
What do you mean by flexible here? I don't care much about the exact name, but I don't like MemoryWatch, because it is too similar to data breakpoint and tracepoints. Which are different things.
It would be possible for other plugins to read out memory from the microcontroller and use it for own things (for example https://www.segger.com/products/debug-probes/j-link/technology/real-time-transfer/general-information/#tab-15668-1 this is only a general idea, there are countless other things, like generating memory maps from MMU and DMA and so on) In general, if you can read the ram from a microcontroller you can do a hell lot of things. With this kind of watch it would be possible to do all this things from a plugin.

Quote
About step 1: How do you select the svd file? The user selects it every time the window is being opened? It is stored in a project/target/the window and the window resets it every time new debug session is started?
Of course it should be saved at project or target level. But this can be done from the plugin and codeblocks provides a api for this, so no problems here ( as far as i know a plugin can add notebooks to the Project->Settings dialog, at least the gdb plugin does it and so there is also a place for the setting entry). The svd file is parsed on load of the project (and when the file is changed in the options of corse). The window is populated at the opening of the debugger, with all elements. The window provides a search control so the user can find the needed register pretty fast. The update of the data is then a other problem, but there is the possibility to optimize, for example find the best size between count of watches and size of a singe watch.
At the moment i would like to implement it and for this i need to know what api the devs would support. For optimization is later time, if the bottleneck is found.

Quote
About Step 5: linking the expanding of the property and updating the values is not a good idea. At least for the watches it is a terrible idea,
Why is this a bad idea? Only get the data from the debugger as you need it, because from my experience the problem is codeblocks<->gdb and not gdb or codeblocks at program level. I think the mi gdb plugin does this and it is fast and reliable. You can cache the values and only update if the debugger was running in the mean time... In any way it is faster then updating the whole register map (if the map is 11kByte big, on smaller targets it may be a possibility. Don't optimize until you know where the problem is...)


Title: Re: Extend GDB plugin to communicate with other plugins
Post by: oBFusCATed on August 01, 2017, 01:14:38 am
With this kind of watch it would be possible to do all this things from a plugin.
I really doubt it. Especially if you want to transfer tons of data.

At the moment i would like to implement it and for this i need to know what api the devs would support.
It will be good if you could try the minimal version of the watch idea. In order to see if it is worth pursuing. Nothing fancy and complex on the UI part. Get adding (use some hardcoded path to a svd file for example) and updating watches to work. My original thought was to put the register watches in the watches window, because it will make it easier to experiment with it.

For optimization is later time, if the bottleneck is found.
The problem with api design is that you should design for performance up front. It is very hard to make a system really performant if the api is not optimal.

Why is this a bad idea?
It creates delays for the user when you need the data. I guess here it won't be that bad and it could be disabled if it creates too many ux problems. I'm not sure I like the similar implementation in the gdb/mi plugin.

...because from my experience the problem is codeblocks<->gdb and not gdb or codeblocks at program level.
Sometimes gdb is slow, because it has tons of data to process and produces small amount of data.

In any way it is faster then updating the whole register map (if the map is 11kByte big, on smaller targets it may be a possibility...)
This could be done in the gdb plugin. Because it is its job to iterate the register-watches and decide what commands to issue. It might be possible to merge different memory ranges. If they overlap or next to each other.
Title: Re: Extend GDB plugin to communicate with other plugins
Post by: BlueHazzard on August 06, 2017, 05:07:33 pm
I tried to implement the way you suggested. We need to distinguish between a "symbol" watch and a "memory" watch, because the gdb command for asking a symbol is "output" and for a memory region it is "x". Now my first try is to make the distinguish within the watch. For this is have to:
1) Extend the cbWatch class with
Code

        enum cbWatchType
        {
            cbWatchType_SYMBOL,
            cbWatchType_MEMORY
        };

        virtual void AddMemoryRange(uint64_t address, uint64_t size, const wxString &id ) = 0;
        cbWatchType  GetWatchType()     {return m_watchType;};

        private:
            cbWatchType m_watchType;

2) Modify the GDBWatch class:
Code
void GDBWatch::AddMemoryRange(uint64_t address, uint64_t size, const wxString &id )
{
    m_symbol = wxString::Format(wxT("/%ulub %lx"), size, address);
    m_watchType = cbWatchType_MEMORY;
}

void GDBWatch::SetSymbol(const wxString& symbol)
{
    m_symbol = symbol;
    m_watchType = cbWatchType_SYMBOL;
}
now my plan was to modify the class GdbCmd_Watch to distinguish between memory and symbol watch
Code
        GdbCmd_Watch(DebuggerDriver* driver, cb::shared_ptr<GDBWatch> watch) :
            DebuggerCmd(driver),
            m_watch(watch)
        {
            wxString type;
            wxString symbol;

            m_watch->GetSymbol(symbol);
            m_watch->GetType(type);

            if(m_watch->GetWatchType == cbWatchType_MEMORY)
            {
                m_Cmd << "x " << symbol;
                return;
            }
// old code from here on

            type.Trim(true);
            type.Trim(false);
            m_Cmd = static_cast<GDB_driver*>(m_pDriver)->GetScriptedTypeCommand(type, m_ParseFunc);
            if (m_Cmd.IsEmpty())
            {
Now i wanted to modify the
Code
ParseGDBWatchValue
function to parse a memory and symbol watch differently. But it is not that easy....
There is also the GdbCmd_FindWatchType command. I have discovered that the process for updating a watch is to
1) Queue a GdbCmd_FindWatchType command.
2) After successful action this command queues a GdbCmd_Watch
Now the GdbCmd_FindWatchType is useless for the memory watch. So i have to insert even more logic, or modify it future up...

Is this really the way you want to go?
Title: Re: Extend GDB plugin to communicate with other plugins
Post by: oBFusCATed on August 06, 2017, 05:25:12 pm
Why do you want to reuse the watch parsing and querying in the gdb plugin?
When adding memory watches you can add them to a separate array of objects and treat them differently inside the plugin.
The idea is to reuse the interface of cbWatch, but not the implementation inside the plugin.

I don't see why the cbWatch needs to have a type at this point in time of development.
Probably when you start to do the UI you'll have to add some field that is used to specify the widget and some what to get the data for the widget, but you are not at this step yet.

p.p. C::B is using C++11 now, so you can take advantage of the better enums and don't have to explicitly add namespace.
Title: Re: Extend GDB plugin to communicate with other plugins
Post by: BlueHazzard on August 07, 2017, 02:12:47 am
ok, i have now implemented a first version of the whole thing:
https://youtu.be/ELOoFKLemmQ

i will upload the source code to github as soon as possible...
Title: Re: Extend GDB plugin to communicate with other plugins
Post by: BlueHazzard on August 07, 2017, 02:39:44 am
Ok, codeblocks code is here:
https://github.com/bluehazzard/codeblocks_sf/tree/debugger/memory_range_watch

for the plugin code i need more time. I have to clean up a bit...
Title: Re: Extend GDB plugin to communicate with other plugins
Post by: oBFusCATed on August 07, 2017, 09:42:36 am
DeleteMemoryRange and HasMemoryRange seem redundant...
Also I'm not sure it is a good idea to use GDBWatch as a class and to store the command in the symbol field or the result as a string in the value.
Title: Re: Extend GDB plugin to communicate with other plugins
Post by: BlueHazzard on August 08, 2017, 10:28:48 am
Quote
DeleteMemoryRange and HasMemoryRange seem redundant...
i agree with that.. This popped up my mind as soon as i pushed the code

Quote
Also I'm not sure it is a good idea to use GDBWatch as a class and to store the command in the symbol field or the result as a string in the value.
This could easily be made, and honestly i would prefer it. But the result has to be stored in the value member as string, because otherwise the cbWatch has to be modified, or how do you think to get the result from outside of the gdb plugin? One possibility would be to add a function
Code
bool GetMemoryRangeValue(cb:shared_ptr<cbWatch> watch, std::vector<char> &data) 
to cbDebuggerPlugin, but this seems not intuitive if the normal use of cbWatch is GetValue().
Title: Re: Extend GDB plugin to communicate with other plugins
Post by: oBFusCATed on August 08, 2017, 02:21:28 pm
This could easily be made, and honestly i would prefer it. But the result has to be stored in the value member as string, because otherwise the cbWatch has to be modified, or how do you think to get the result from outside of the gdb plugin?
It depends what you want to do with the data. Do you know what operations you want to do?

One possibility would be to add a function
Code
bool GetMemoryRangeValue(cb:shared_ptr<cbWatch> watch, std::vector<char> &data) 
to cbDebuggerPlugin, but this seems not intuitive if the normal use of cbWatch is GetValue().
Do not go this route, please.
Title: Re: Extend GDB plugin to communicate with other plugins
Post by: BlueHazzard on August 30, 2017, 08:18:29 pm
Hi,
i reworked the implementation: https://github.com/bluehazzard/codeblocks_sf/tree/debugger/memory_range_watch

The interface to all plugins is only one function:
Code
cb::shared_ptr<cbWatch>  cbDebuggerPlugin::AddMemoryRange(uint64_t address, uint64_t size, const wxString &id ) = 0;
This function returns a cbWatch object that represents a memory range. The value of the Watch (the memory raw data directly from ram) can be get with (pseudo code):
Code
cb::shared_ptr<cbWatch> m_watch = dbg_plugin->AddMemoryRange(0x400000, 16, wxEmtyString );
// Run the debugger
wxString tmp;
m_watch->GetValue(tmp);
size_t lengthOfData = tmp.size();
char* memoryContetn = new char[ lengthOfData ];
memcpy(memoryContent, tmp.To8BitData(), 16);
// yay: ram content in memoryContent for your free use and interpretation
// i know there is a uint16_t @ 0x400002
uint16_t myNeededValue = 0;
memcpy(&myNeededValue, memoryContent+2, 2);

At plugin level there is a internal watch class: GDBMemoryRangeWatch that represents a memory range. It derives from cbWatch and stores the address and size of the range.
All the memory range watches are stored in
Code
std::vector<cb::shared_ptr<GDBMemoryRangeWatch> > m_memoryRange;
and the following functions are transparent for normal and memory range watches:
Code
void DebuggerGDB::DeleteWatch(cb::shared_ptr<cbWatch> watch)
bool DebuggerGDB::HasWatch(cb::shared_ptr<cbWatch> watch)
there is an additional function (at the moment only for GDBPlugin but it can be added to cbDebuggerPlugin) to check if the watch is a memory range watch
Code
bool DebuggerGDB::IsMemoryRangeWatch(cb::shared_ptr<cbWatch> watch)

The actual reading of the memory from gdb is implemented like the normal watches with a
Code
class GdbCmd_MemoryRangeWatch : public DebuggerCmd

This implementation works nice and transparent. It is relatively fast and i use it in the new plugin i showed with the video above. I will post the link to the source later tody...

conclusion:
To add a interface for other plugins to read random ram content from the debugger, only one new function has to be added to cbDebuggerPlugin. The data is exchanged through wxString::To8BitData() so the cbWatch class has not to be altered.

@oBFusCATed: Is this interface somehow acceptable for you?
Title: Re: Extend GDB plugin to communicate with other plugins
Post by: BlueHazzard on October 11, 2017, 02:07:12 am
Ok, this is my suggestion for a pull request. I think the commits are not to large and quite obvious...

https://github.com/bluehazzard/codeblocks_sf/tree/debugger/pull_candidate/memory_range_watch/1

any thoughts on this?
Title: Re: Extend GDB plugin to communicate with other plugins
Post by: oBFusCATed on February 10, 2019, 12:17:15 am
Posting here just for reference: http://forums.codeblocks.org/index.php/topic,22207.msg157208.html#msg157208