diff --git a/CHANGELOG.md b/CHANGELOG.md
index 42c6126..c913175 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -13,6 +13,7 @@ and this project adheres to
* `flags` can be specified at map file as well
* `size` property at root level to modify the document size
* `labels` property can go on the left side as well
+* Friendly name field (`name`) for sections at the yaml map file to be used instead of ID
## [0.2.0] - 2023-12-14
diff --git a/README.md b/README.md
index 542f0e3..0546dc3 100644
--- a/README.md
+++ b/README.md
@@ -50,7 +50,7 @@ an `id`, an `address` and a `size`.
While these three are needed, there are other possible attributes that are optional:
- `name`: Friendly text name that would be used instead of the `id`
-- `type`: Section type, which can be used for different purposes. Possibilities are `section` (default) and `area`.
+- `type`: Section type, which can be used for different purposes. Current possibilities are `section` (default) and `area`.
The input file should contain the `map` keyword whose value is an array of sections. Below an example
of how an input file should look like:
@@ -67,7 +67,7 @@ of how an input file should look like:
- ...
```
-In order to use this file, invoke Linkerscope and specify the yaml map file as input:
+In order to use this file, invoke LinkerScope and specify the yaml map file as input:
```bash
./linkerscope.py -i memory_map.yaml -o memory_map.svg -c config.yaml
@@ -78,7 +78,7 @@ In order to use this file, invoke Linkerscope and specify the yaml map file as i
For a complex diagram that fully represents the memory map of a given program, handcrafting the memory map can be
time-consuming. In the case that the intended diagram is related to a program, the necessary information is already
available at the generated GNU Linker map files.
-Linkerscope conveniently provides the possibility to parse these files and generate diagram from those. For that, simply
+LinkerScope conveniently provides the possibility to parse these files and generate diagram from those. For that, simply
specify the `.map` file as an input.
```bash
@@ -87,93 +87,45 @@ specify the `.map` file as an input.
### Creating a configuration file
-The configuration file is a `.yaml` file containing all the required information to tell LinkerScope what and how to draw the maps.
-All information there is optional.
+The configuration file is a `.yaml` file containing all the required information to tell LinkerScope what and how to draw the memory map.
+All information there is optional, including the file itself. If this information is not provided, the default values will be used.
-Normally, a configuration file contains style information, memory areas, and links.
+Normally, a configuration file contains **areas**, **links** and **style** information.
+
+**Areas** provides a list of memory areas to be displayed, with information regarding its position and size on the map, memory range to include or specific drawing style.
+Additionally, it can contain a **sections** sub-property where specific sections can be added to modify desired properties
+
+**Links** provides a simple way of graphically relating same memory addresses across different areas
+
+**Style** defines the parent drawing style properties that will be used at the document. Additionally, each area can override specific style properties at its style section.
+Lastly, sections can override parent (area) style as well
```yaml
style:
- ...
+ background: '#99B898'
+ stroke: 'black'
+ # ...
areas:
- area:
style:
- ...
-
- address:
- lowest: 0x0
- highest: 0x200000000
-
- size:
- ...
+ # ...
+ title: Register Map
+ range: [0x0, 0x100000000]
+ sections:
+ - names: [USART1, USART2]
+ style:
+ hide-name: true
+ # ...
- area:
- ...
+ # ...
links:
- addresses: [ 0x80045d4, ...]
- sections: [__malloc_av_, ...]
-
-
-```
-#### Styles
-
-The style can be defined at map level, where it will be applied to all areas, but also at area or even at section level.
-Specifying a style at are level will override the specified configuration for the whole map where it was defined.
-Specifying it at section level, it will override style information from map and area.
+ addresses: [0x80045d4]
+ sections: [__malloc_av_, [TIM2, TIM3]]
-```yaml
-style:
- # RGB colors or english plain text color names can be used
- box_fill_color: '#CCE5FF'
- label_color: 'blue'
- box_stroke_color: '#3399FF'
- box_stroke_width: 2
- link_stroke_width: 2
- link_stroke_color: 'grey'
- label_font: 'Helvetica Bold'
- label_size: '16px'
- label_stroke_width: 0.5px
- area_fill_color: 'lightgrey'
```
-- Window:
- - `background_color`
-- Area background
- - `area_background_color`
-- Memory section rectangle
- - `box_fill_color`
- - `box_stroke_color`
- - `box_stroke_width`
-- Section name, address and size
- - `label_color`
- - `label_font`
- - `label_size`
- - `label_stroke_width`
-- Link lines between addresses at different maps
- - `link_stroke_width`
- - `link_stroke_color`
-
-If the style at specific sections needs to be defined/overridden, it will be specified under `style -> overrides -> sections` property at
-area level, by specifying the names of the regions whose properties want to be overridden, followed by the properties to override:
-```yaml
-- area:
- ...
- address:
- ...
- style:
- # Area style definition
- link_stroke_color: 'grey'
- link_stroke_width: 1
- section_stroke_width: 0
- section_fill_color: 'blue'
- # Area style overrides for specified sections
- overrrides:
- - sections: [ ROM Table, Peripheral, External RAM ]
- section_fill_color: '#99B898'
- - sections: [ External PPB ]
- section_fill_color: '#FECEA8'
-```
#### Areas
The diagram can have one or multiple areas. When multiple areas are declared,
@@ -283,7 +235,7 @@ areas:
flags: break
```
-##### `grows-up` / `grows-down`
+##### Growths
These flags specify the section as growing section, for instance, if the section is meant to grow into one direction, such as the stack.
When flagging a section with `grows-down`, an arrow pointing downwards will be appended to the bottom of the section indicating that the section is growing into that direction:
@@ -326,9 +278,56 @@ links:
```
+#### Styles
+
+The style can be defined at document level, where it will be applied to all areas, but also at area or even at section level.
+Specifying a style at area level will override the specified properties for the whole area where it was defined.
+Specifying it at section level, it will override style only for the specified section or group of sections.
+
+```yaml
+style:
+ # This is a style defined at document level
+ text-fill: 'lightgrey'
+ background: 'black'
+ stroke: '#99B898'
+ stroke-width: 1
+ font-type: 'Helvetica'
+
+areas:
+- area:
+ title: 'Internal Memory'
+ pos: [30, 50]
+ style:
+ # This is a style defined at area level, which will override fill property only applied at Main Memory area
+ fill: 'blue'
+ sections:
+ - names: [ SRAM, Flash ]
+ style:
+ # This is a style defined at section level, and will be applied only to SRAM and Flash sections
+ fill: 'green'
+ hide-address: true
+- area:
+ title: 'External Memory'
+ # ...
+```
+
+Below a list of style properties with general use and specific for sections:
+##### General
+ - `background`, `fill`, `font-size`, `font-type`, `opacity`, `size`, `stroke`, `stroke_dasharray`, `stroke-width`, `text-stroke`,`text-fill`,`text-stroke-width`, `weigth`
+
+##### Section properties:
+ - `break-type`: specify memory break type. See [`break`](#break) section
+ - `break-size`: specify memory break size in pixels. See [`break`](#break) section
+ - `growth-arrow-size`: size of the direction growth arrow. See [`Growths`](#growths) section
+ - `growth-arrow-fill`: color for the direction growth arrow. See [`Growths`](#growths) section
+ - `growth-arrow-stroke`: stroke color for the direction growth arrow. See [`Growths`](#growths) section
+ - `hide-size`: hides the size label of a section
+ - `hide-name`: hides the name label of a section
+ - `hide-address`: hides the address label of a section
+
#### Other properties
-##### Document size
+_Document size_
The generated SVG document has a fixed size. If you want to adjust it, use the `size` property at root level to pass
desired document width and height in pixels.
diff --git a/examples/link_example_config.yaml b/examples/link_example_config.yaml
index ab46946..d1378b1 100755
--- a/examples/link_example_config.yaml
+++ b/examples/link_example_config.yaml
@@ -15,7 +15,7 @@ style:
stroke-width: 1
text-stroke: 'black'
text-stroke-width: 0
- font_type: 'Helvetica'
+ font-type: 'Helvetica'
areas:
- area:
diff --git a/examples/link_example_map.svg b/examples/link_example_map.svg
index 04212b8..79caa9f 100644
--- a/examples/link_example_map.svg
+++ b/examples/link_example_map.svg
@@ -1,2 +1,2 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/examples/stm32f103_config.yaml b/examples/stm32f103_config.yaml
new file mode 100644
index 0000000..a186454
--- /dev/null
+++ b/examples/stm32f103_config.yaml
@@ -0,0 +1,58 @@
+size: [800,900]
+variables:
+ graphite: &graphite '#2A363B'
+ pastel_green: &pastel_green '#99B898'
+ pastel_yellow: &pastel_yellow '#FECEA8'
+ pastel_orange: &pastel_orange '#FF847C'
+ pastel_red: &pastel_red '#E84A5F'
+
+style:
+ text-fill: 'lightgrey'
+ break-size: 60
+ break-type: '~'
+ growth-arrow-size: 2
+ growth-arrow-fill: 'white'
+ growth-arrow-stroke: 'black'
+ background: *graphite
+ fill: '#99B898'
+
+ stroke: *graphite
+ stroke-width: 1
+ text-stroke: 'black'
+ text-stroke-width: 0
+ font_type: 'Helvetica'
+
+areas:
+# total area area
+- area:
+ range: [0x0, 0x100000000]
+ size: [200, 700]
+ style:
+ fill: *pastel_green
+ hide-size: true
+ sections:
+ - names: [none]
+ style:
+ hide-name: true
+ fill: grey
+
+- area:
+ range: [0x40000000, 0x40030000]
+ pos: [500]
+ size: [200, 700]
+ style:
+ fill: *pastel_green
+ background: grey
+ hide-size: true
+ sections:
+ - names: [none]
+ style:
+ hide-name: true
+ fill: grey
+
+links:
+ style:
+ fill: grey
+ sections: [[TIM2, CRC]]
+
+
diff --git a/examples/stm32f103_map.yaml b/examples/stm32f103_map.yaml
new file mode 100644
index 0000000..469f8c2
--- /dev/null
+++ b/examples/stm32f103_map.yaml
@@ -0,0 +1,186 @@
+map:
+ - id: none
+ address: 0x00000000
+ size: 0x20000000
+ type: area
+ - id: none
+ address: 0x20000000
+ size: 0x20000000
+ type: area
+ - id: none
+ address: 0x40000000
+ size: 0x20000000
+ type: area
+ - id: none
+ address: 0x60000000
+ size: 0x20000000
+ type: area
+ - id: none
+ address: 0x80000000
+ size: 0x20000000
+ type: area
+ - id: none
+ address: 0xA0000000
+ size: 0x20000000
+ type: area
+ - id: none
+ address: 0xC0000000
+ size: 0x20000000
+ type: area
+
+
+
+ - id: none
+ address: 0xE0100000
+ size: 0x0FE00000
+ type: area
+
+ - id: SRAM
+ address: 0x20000000
+ size: 0x08000000
+ type: area
+
+ - id: Peripherals
+ address: 0x40000000
+ size: 0x08000000
+ type: area
+
+ - id: M3 Cortex Internal Peripherals
+ address: 0xE0000000
+ size: 0x01000000
+ type: area
+
+ - id: TIM2
+ address: 0x40000000
+ size: 0x00000400
+ type: area
+ - id: TIM3
+ address: 0x40000400
+ size: 0x00000400
+ type: area
+ - id: TIM4
+ address: 0x40000800
+ size: 0x00000400
+ type: area
+ - id: RTC
+ address: 0x40002800
+ size: 0x00000400
+ type: area
+ - id: WWDG
+ address: 0x40002C00
+ size: 0x00000400
+ type: area
+ - id: IWDG
+ address: 0x40003000
+ size: 0x00000400
+ type: area
+ - id: SPI2
+ address: 0x40003800
+ size: 0x00000400
+ type: area
+ - id: USART2
+ address: 0x40004400
+ size: 0x00000400
+ type: area
+ - id: USART3
+ address: 0x40004800
+ size: 0x00000400
+ type: area
+ - id: I2C1
+ address: 0x40005400
+ size: 0x00000400
+ type: area
+ - id: I2C2
+ address: 0x40005800
+ size: 0x00000400
+ type: area
+ - id: USB Registers
+ address: 0x40005C00
+ size: 0x00000400
+ type: area
+ - id: USB/CAN SRAM
+ address: 0x40006000
+ size: 0x00000400
+ type: area
+ - id: BXCAN
+ address: 0x40006400
+ size: 0x00000400
+ type: area
+ - id: BKP
+ address: 0x40006C00
+ size: 0x00000400
+ type: area
+ - id: POWER
+ address: 0x40007000
+ size: 0x00000400
+ type: area
+ - id: AFIO
+ address: 0x40010000
+ size: 0x00000400
+ type: area
+ - id: EXTI
+ address: 0x40010400
+ size: 0x00000400
+ type: area
+ - id: PORT A
+ address: 0x40010800
+ size: 0x00000400
+ type: area
+ - id: PORT B
+ address: 0x40010C00
+ size: 0x00000400
+ type: area
+ - id: PORT C
+ address: 0x40011000
+ size: 0x00000400
+ type: area
+ - id: PORT D
+ address: 0x40011400
+ size: 0x00000400
+ type: area
+ - id: PORT E
+ address: 0x40011800
+ size: 0x00000400
+ type: area
+ - id: ADC1
+ address: 0x40012400
+ size: 0x00000400
+ type: area
+ - id: ADC2
+ address: 0x40012800
+ size: 0x00000400
+ type: area
+ - id: TIM1
+ address: 0x40012C00
+ size: 0x00000400
+ type: area
+ - id: SPI1
+ address: 0x40013000
+ size: 0x00000400
+ type: area
+ - id:
+ address: 0x40010000
+ size: 0x00000400
+ type: area
+ - id: USART1
+ address: 0x40013800
+ size: 0x00000400
+ type: area
+ - id: DMA
+ address: 0x40020000
+ size: 0x00000400
+ type: area
+ - id: RCC
+ address: 0x40021000
+ size: 0x00000400
+ type: area
+ - id: Flash Interface
+ address: 0x40022000
+ size: 0x00000400
+ type: area
+ - id: CRC
+ address: 0x40023000
+ size: 0x00000400
+ type: area
+
+
diff --git a/map_drawer.py b/map_drawer.py
index e39b80e..609f9ec 100755
--- a/map_drawer.py
+++ b/map_drawer.py
@@ -427,7 +427,8 @@ def _make_text(self,
)
def _make_name(self, section):
- return self._make_text(section.id,
+ name = section.name if section.name is not None else section.id
+ return self._make_text(name,
(section.name_label_pos_x,section.name_label_pos_y),
style=section.style,
anchor='middle',
diff --git a/map_file_loader.py b/map_file_loader.py
index d0988c8..fe5ccf2 100644
--- a/map_file_loader.py
+++ b/map_file_loader.py
@@ -37,9 +37,11 @@ def parse_yaml(filename):
y = yaml.safe_load(file)
for element in y['map']:
+ print(element)
sections.append(Section(address=element['address'],
size=element['size'],
id=element['id'],
+ name=element.get('name'),
parent=element.get('parent', 'none'),
_type=element.get('type', 'area'),
flags=element.get('flags', '')
diff --git a/map_parser.py b/map_parser.py
index 0750835..162325c 100644
--- a/map_parser.py
+++ b/map_parser.py
@@ -9,8 +9,8 @@ class MapParser:
Parse a linker map file and convert it to a yaml file for further processing
"""
def __init__(self, input_filename, output_filename):
- self.areas = []
self.sections = []
+ self.subsections = []
self.input_filename = input_filename
self.output_filename = output_filename
@@ -26,22 +26,23 @@ def parse(self):
prev_line = line
my_dict = {'map': []}
- for area in self.areas:
+ for section in self.sections:
my_dict['map'].append({
'type': 'area',
- 'address': area.address,
- 'size': area.size,
- 'name': area.name,
+ 'address': section.address,
+ 'size': section.size,
+ 'id': section.id,
+ 'flags': section.flags
})
- for section in self.sections:
+ for subsection in self.subsections:
my_dict['map'].append({
'type': 'section',
- 'parent': section.filter_parent,
- 'address': section.address,
- 'size': section.size,
- 'name': section.id,
- 'flags': section.flags
+ 'parent': subsection.parent,
+ 'address': subsection.address,
+ 'size': subsection.size,
+ 'id': subsection.id,
+ 'flags': subsection.flags
})
with open(self.output_filename, 'w', encoding='utf8') as file:
@@ -55,13 +56,13 @@ def process_areas(self, line):
result = p.search(line)
if result is not None:
- self.areas.append(Section(parent=None,
- id=result.group(1),
- address=int(result.group(2), 0),
- size=int(result.group(3), 0),
- _type='area'
- )
- )
+ self.sections.append(Section(parent=None,
+ id=result.group(1),
+ address=int(result.group(2), 0),
+ size=int(result.group(3), 0),
+ _type='area'
+ )
+ )
def process_sections(self, line):
pattern = r'\s(.[^.]+).([^. \n]+)[\n\r]\s+(0x[0-9a-fA-F]{16})\s+' \
@@ -71,10 +72,10 @@ def process_sections(self, line):
result = p.search(line)
if result is not None:
- self.sections.append(Section(parent=result.group(1),
- id=result.group(2),
- address=int(result.group(3), 0),
- size=int(result.group(4), 0),
- _type='section'
- )
- )
+ self.subsections.append(Section(parent=result.group(1),
+ id=result.group(2),
+ address=int(result.group(3), 0),
+ size=int(result.group(4), 0),
+ _type='section'
+ )
+ )
diff --git a/section.py b/section.py
index 74c60be..14061ec 100755
--- a/section.py
+++ b/section.py
@@ -16,12 +16,13 @@ class Section:
label_offset: int = 10
style: Style
- def __init__(self, size, address, id, _type, parent, flags=[]):
+ def __init__(self, size, address, id, _type, parent, flags=[], name=None):
self.type = _type
self.parent = parent
self.size = size
self.address = address
self.id = id
+ self.name = name
self.size_y = 0
self.size_x = 0
self.style = Style()
diff --git a/style.py b/style.py
index 32c685e..2e62fe5 100644
--- a/style.py
+++ b/style.py
@@ -33,7 +33,7 @@ class Style:
def __init__(self, style=None):
if style is not None:
for key, value in style.items():
- setattr(self, key.replace('-','_'), style.get(key, value))
+ setattr(self, key.replace('-', '_'), style.get(key, value))
def override_properties_from(self, style):
"""
@@ -66,7 +66,6 @@ def get_default():
default_style.growth_arrow_size = 1
default_style.background = 'white'
- default_style.fill = '#CCE5FF'
default_style.stroke = 'black'
default_style.stroke_width = 1
default_style.size = 2