libxr 0.2.2__tar.gz → 0.2.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {libxr-0.2.2 → libxr-0.2.4}/PKG-INFO +68 -2
- {libxr-0.2.2 → libxr-0.2.4}/README.md +67 -1
- {libxr-0.2.2 → libxr-0.2.4}/pyproject.toml +2 -1
- {libxr-0.2.2 → libxr-0.2.4}/src/libxr/GeneratorCodeSTM32.py +74 -5
- libxr-0.2.4/src/libxr/STM32FlashGenerator.py +185 -0
- {libxr-0.2.2 → libxr-0.2.4}/src/libxr.egg-info/PKG-INFO +68 -2
- {libxr-0.2.2 → libxr-0.2.4}/src/libxr.egg-info/SOURCES.txt +1 -0
- {libxr-0.2.2 → libxr-0.2.4}/src/libxr.egg-info/entry_points.txt +1 -0
- {libxr-0.2.2 → libxr-0.2.4}/LICENSE +0 -0
- {libxr-0.2.2 → libxr-0.2.4}/setup.cfg +0 -0
- {libxr-0.2.2 → libxr-0.2.4}/src/libxr/ConfigCubemxProject.py +0 -0
- {libxr-0.2.2 → libxr-0.2.4}/src/libxr/GeneratorCode.py +0 -0
- {libxr-0.2.2 → libxr-0.2.4}/src/libxr/GeneratorSTM32CMake.py +0 -0
- {libxr-0.2.2 → libxr-0.2.4}/src/libxr/GeneratorSTM32CMakeClang.py +0 -0
- {libxr-0.2.2 → libxr-0.2.4}/src/libxr/GeneratorSTM32IT.py +0 -0
- {libxr-0.2.2 → libxr-0.2.4}/src/libxr/PeripheralAnalyzer.py +0 -0
- {libxr-0.2.2 → libxr-0.2.4}/src/libxr/PeripheralAnalyzerSTM32.py +0 -0
- {libxr-0.2.2 → libxr-0.2.4}/src/libxr/__init__.py +0 -0
- {libxr-0.2.2 → libxr-0.2.4}/src/libxr.egg-info/dependency_links.txt +0 -0
- {libxr-0.2.2 → libxr-0.2.4}/src/libxr.egg-info/requires.txt +0 -0
- {libxr-0.2.2 → libxr-0.2.4}/src/libxr.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: libxr
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.4
|
|
4
4
|
Summary: C++ code generator for LibXR-based embedded systems, supporting STM32 and modular robotics applications.
|
|
5
5
|
Author-email: Xiao <2592509183@qq.com>
|
|
6
6
|
Maintainer-email: Xiao <2592509183@qq.com>
|
|
@@ -57,6 +57,27 @@ Dynamic: license-file
|
|
|
57
57
|
|
|
58
58
|
## 📥 Installation 安装
|
|
59
59
|
|
|
60
|
+
### 使用pipx安装 (Install via `pipx`)
|
|
61
|
+
|
|
62
|
+
windows
|
|
63
|
+
|
|
64
|
+
```ps
|
|
65
|
+
python -m pip install --user pipx
|
|
66
|
+
python -m pipx ensurepath
|
|
67
|
+
pipx install libxr
|
|
68
|
+
pipx ensurepath
|
|
69
|
+
# Restart your terminal
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
linux
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
sudo apt install pipx
|
|
76
|
+
pipx install libxr
|
|
77
|
+
pipx ensurepath
|
|
78
|
+
# Restart your terminal
|
|
79
|
+
```
|
|
80
|
+
|
|
60
81
|
### 使用 pip 安装 (Install via `pip`)
|
|
61
82
|
|
|
62
83
|
```bash
|
|
@@ -233,9 +254,54 @@ usage: xr_gen_code_stm32 [-h] -i INPUT -o OUTPUT [--xrobot] [--libxr-config LIBX
|
|
|
233
254
|
Main entry point with all initialization logic
|
|
234
255
|
|
|
235
256
|
- `libxr_config.yaml`:
|
|
236
|
-
运行时配置文件,可自定义缓冲区大小、队列等参数
|
|
257
|
+
运行时配置文件,可自定义缓冲区大小、队列等参数
|
|
237
258
|
Runtime config YAML, can be customized with buffer size, queue, etc.
|
|
238
259
|
|
|
260
|
+
- `flash_map.hpp`:
|
|
261
|
+
自动生成的 Flash 扇区表,供 Flash 抽象层使用
|
|
262
|
+
Auto-generated flash sector layout for use with Flash abstraction layer
|
|
263
|
+
|
|
264
|
+
---
|
|
265
|
+
|
|
266
|
+
### `xr_stm32_flash`
|
|
267
|
+
|
|
268
|
+
解析 STM32 型号,生成 Flash 扇区信息表(YAML 格式输出)。
|
|
269
|
+
Parses STM32 model name and generates flash layout info (YAML output).
|
|
270
|
+
|
|
271
|
+
```bash
|
|
272
|
+
usage: xr_stm32_flash <STM32_MODEL>
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
### 🧠 功能说明 (Functionality)
|
|
276
|
+
|
|
277
|
+
- 根据 STM32 型号名称自动推导 Flash 大小
|
|
278
|
+
Automatically infers flash size from the STM32 model string
|
|
279
|
+
|
|
280
|
+
- 根据芯片系列(如 F1/F4/H7/U5 等)生成对应的扇区布局
|
|
281
|
+
Generates sector layout depending on the chip series (e.g., F1/F4/H7/U5)
|
|
282
|
+
|
|
283
|
+
- 输出包括每个扇区的地址、大小和索引
|
|
284
|
+
Output includes address, size, and index of each sector
|
|
285
|
+
|
|
286
|
+
### 📦 输出内容 (Outputs)
|
|
287
|
+
|
|
288
|
+
- YAML 格式的 Flash 信息
|
|
289
|
+
Flash info in YAML format:
|
|
290
|
+
|
|
291
|
+
```yaml
|
|
292
|
+
model: STM32F103C8
|
|
293
|
+
flash_base: '0x08000000'
|
|
294
|
+
flash_size_kb: 64
|
|
295
|
+
sectors:
|
|
296
|
+
- index: 0
|
|
297
|
+
address: '0x08000000'
|
|
298
|
+
size_kb: 1.0
|
|
299
|
+
- index: 1
|
|
300
|
+
address: '0x08000400'
|
|
301
|
+
size_kb: 1.0
|
|
302
|
+
...
|
|
303
|
+
```
|
|
304
|
+
|
|
239
305
|
---
|
|
240
306
|
|
|
241
307
|
### `xr_stm32_it`
|
|
@@ -29,6 +29,27 @@
|
|
|
29
29
|
|
|
30
30
|
## 📥 Installation 安装
|
|
31
31
|
|
|
32
|
+
### 使用pipx安装 (Install via `pipx`)
|
|
33
|
+
|
|
34
|
+
windows
|
|
35
|
+
|
|
36
|
+
```ps
|
|
37
|
+
python -m pip install --user pipx
|
|
38
|
+
python -m pipx ensurepath
|
|
39
|
+
pipx install libxr
|
|
40
|
+
pipx ensurepath
|
|
41
|
+
# Restart your terminal
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
linux
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
sudo apt install pipx
|
|
48
|
+
pipx install libxr
|
|
49
|
+
pipx ensurepath
|
|
50
|
+
# Restart your terminal
|
|
51
|
+
```
|
|
52
|
+
|
|
32
53
|
### 使用 pip 安装 (Install via `pip`)
|
|
33
54
|
|
|
34
55
|
```bash
|
|
@@ -205,9 +226,54 @@ usage: xr_gen_code_stm32 [-h] -i INPUT -o OUTPUT [--xrobot] [--libxr-config LIBX
|
|
|
205
226
|
Main entry point with all initialization logic
|
|
206
227
|
|
|
207
228
|
- `libxr_config.yaml`:
|
|
208
|
-
运行时配置文件,可自定义缓冲区大小、队列等参数
|
|
229
|
+
运行时配置文件,可自定义缓冲区大小、队列等参数
|
|
209
230
|
Runtime config YAML, can be customized with buffer size, queue, etc.
|
|
210
231
|
|
|
232
|
+
- `flash_map.hpp`:
|
|
233
|
+
自动生成的 Flash 扇区表,供 Flash 抽象层使用
|
|
234
|
+
Auto-generated flash sector layout for use with Flash abstraction layer
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
### `xr_stm32_flash`
|
|
239
|
+
|
|
240
|
+
解析 STM32 型号,生成 Flash 扇区信息表(YAML 格式输出)。
|
|
241
|
+
Parses STM32 model name and generates flash layout info (YAML output).
|
|
242
|
+
|
|
243
|
+
```bash
|
|
244
|
+
usage: xr_stm32_flash <STM32_MODEL>
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### 🧠 功能说明 (Functionality)
|
|
248
|
+
|
|
249
|
+
- 根据 STM32 型号名称自动推导 Flash 大小
|
|
250
|
+
Automatically infers flash size from the STM32 model string
|
|
251
|
+
|
|
252
|
+
- 根据芯片系列(如 F1/F4/H7/U5 等)生成对应的扇区布局
|
|
253
|
+
Generates sector layout depending on the chip series (e.g., F1/F4/H7/U5)
|
|
254
|
+
|
|
255
|
+
- 输出包括每个扇区的地址、大小和索引
|
|
256
|
+
Output includes address, size, and index of each sector
|
|
257
|
+
|
|
258
|
+
### 📦 输出内容 (Outputs)
|
|
259
|
+
|
|
260
|
+
- YAML 格式的 Flash 信息
|
|
261
|
+
Flash info in YAML format:
|
|
262
|
+
|
|
263
|
+
```yaml
|
|
264
|
+
model: STM32F103C8
|
|
265
|
+
flash_base: '0x08000000'
|
|
266
|
+
flash_size_kb: 64
|
|
267
|
+
sectors:
|
|
268
|
+
- index: 0
|
|
269
|
+
address: '0x08000000'
|
|
270
|
+
size_kb: 1.0
|
|
271
|
+
- index: 1
|
|
272
|
+
address: '0x08000400'
|
|
273
|
+
size_kb: 1.0
|
|
274
|
+
...
|
|
275
|
+
```
|
|
276
|
+
|
|
211
277
|
---
|
|
212
278
|
|
|
213
279
|
### `xr_stm32_it`
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "libxr"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.4"
|
|
8
8
|
description = "C++ code generator for LibXR-based embedded systems, supporting STM32 and modular robotics applications."
|
|
9
9
|
requires-python = ">=3.8"
|
|
10
10
|
authors = [
|
|
@@ -46,6 +46,7 @@ xr_gen_code = "libxr.GeneratorCode:main"
|
|
|
46
46
|
xr_stm32_it = "libxr.GeneratorSTM32IT:main"
|
|
47
47
|
xr_stm32_cmake = "libxr.GeneratorSTM32CMake:main"
|
|
48
48
|
xr_stm32_clang = "libxr.GeneratorSTM32CMakeClang:main"
|
|
49
|
+
xr_stm32_flash = "libxr.STM32FlashGenerator:main"
|
|
49
50
|
xr_cubemx_cfg = "libxr.ConfigCubemxProject:main"
|
|
50
51
|
|
|
51
52
|
[tool.setuptools.packages.find]
|
|
@@ -348,8 +348,10 @@ def generate_dma_resources(project_data: dict) -> str:
|
|
|
348
348
|
"buffer_size",
|
|
349
349
|
DMA_DEFAULT_SIZES[p_type_base]["buffer"]
|
|
350
350
|
)
|
|
351
|
-
|
|
352
|
-
|
|
351
|
+
if p_type_base in ["ADC"]:
|
|
352
|
+
dma_code.append(f"static uint16_t {instance_lower}_buf[{int(buf_size/2)}];")
|
|
353
|
+
else:
|
|
354
|
+
dma_code.append(f"static uint8_t {instance_lower}_buf[{buf_size}];")
|
|
353
355
|
|
|
354
356
|
return "/* DMA Resources */\n" + "\n".join(dma_code) if dma_code else ""
|
|
355
357
|
|
|
@@ -472,7 +474,7 @@ class PeripheralFactory:
|
|
|
472
474
|
def _generate_header_includes(use_xrobot: bool = False) -> str:
|
|
473
475
|
"""Generate essential header inclusions with optional XRobot components."""
|
|
474
476
|
headers = [
|
|
475
|
-
'#include "app_main.h"',
|
|
477
|
+
'#include "app_main.h"\n',
|
|
476
478
|
'#include "libxr.hpp"',
|
|
477
479
|
'#include "main.h"',
|
|
478
480
|
'#include "stm32_adc.hpp"',
|
|
@@ -485,13 +487,14 @@ def _generate_header_includes(use_xrobot: bool = False) -> str:
|
|
|
485
487
|
'#include "stm32_spi.hpp"',
|
|
486
488
|
'#include "stm32_timebase.hpp"',
|
|
487
489
|
'#include "stm32_uart.hpp"',
|
|
488
|
-
'#include "stm32_usb.hpp"'
|
|
490
|
+
'#include "stm32_usb.hpp"',
|
|
491
|
+
'#include "flash_map.hpp"'
|
|
489
492
|
]
|
|
490
493
|
|
|
491
494
|
if use_xrobot:
|
|
492
495
|
headers.extend([
|
|
493
496
|
'#include "app_framework.hpp"\n'
|
|
494
|
-
'#include "xrobot_main.hpp"'
|
|
497
|
+
'#include "xrobot_main.hpp"\n'
|
|
495
498
|
])
|
|
496
499
|
|
|
497
500
|
return '\n'.join(headers) + '\n\nusing namespace LibXR;\n'
|
|
@@ -764,6 +767,70 @@ void app_main(void);
|
|
|
764
767
|
logging.info(f"Generated header: {header_path}")
|
|
765
768
|
|
|
766
769
|
|
|
770
|
+
def generate_flash_map_cpp(flash_info: dict) -> str:
|
|
771
|
+
"""
|
|
772
|
+
Convert flash_info dictionary to a C++ constexpr struct array.
|
|
773
|
+
|
|
774
|
+
:param flash_info: Output from flash_info_to_dict
|
|
775
|
+
|
|
776
|
+
:return: C++ code as a string
|
|
777
|
+
"""
|
|
778
|
+
lines = [
|
|
779
|
+
"#include \"stm32_flash.hpp\"",
|
|
780
|
+
"",
|
|
781
|
+
"constexpr LibXR::FlashSector FLASH_SECTORS[] = {",
|
|
782
|
+
]
|
|
783
|
+
|
|
784
|
+
for s in flash_info["sectors"]:
|
|
785
|
+
index = s["index"]
|
|
786
|
+
address = int(s["address"], 16)
|
|
787
|
+
size_kb = int(s["size_kb"])
|
|
788
|
+
lines.append(f" {{0x{address:08X}, 0x{(size_kb * 1024):08X}}},")
|
|
789
|
+
|
|
790
|
+
lines.append("};\n")
|
|
791
|
+
lines.append("constexpr size_t FLASH_SECTOR_NUMBER = sizeof(FLASH_SECTORS) / sizeof(LibXR::FlashSector);")
|
|
792
|
+
return "\n".join(lines)
|
|
793
|
+
|
|
794
|
+
def inject_flash_layout(project_data: dict, output_dir: str) -> None:
|
|
795
|
+
"""
|
|
796
|
+
Automatically generate FlashLayout from project_data['Mcu']['Type']
|
|
797
|
+
and inject it into libxr_settings. Also generates flash_map.hpp.
|
|
798
|
+
|
|
799
|
+
:param project_data: Project configuration containing MCU type
|
|
800
|
+
|
|
801
|
+
:param output_dir: Output directory for generated flash_map.hpp
|
|
802
|
+
"""
|
|
803
|
+
try:
|
|
804
|
+
from libxr.STM32FlashGenerator import layout_flash, flash_info_to_dict
|
|
805
|
+
mcu_model = project_data.get("Mcu", {}).get("Type", "").strip()
|
|
806
|
+
if not mcu_model:
|
|
807
|
+
logging.warning("Cannot find MCU name, skipping FlashLayout generation")
|
|
808
|
+
return
|
|
809
|
+
|
|
810
|
+
flash_info = layout_flash(mcu_model)
|
|
811
|
+
flash_dict = flash_info_to_dict(flash_info)
|
|
812
|
+
libxr_settings["FlashLayout"] = flash_dict
|
|
813
|
+
logging.info(f"FlashLayout is generated and injected, MCU: {mcu_model}")
|
|
814
|
+
|
|
815
|
+
cpp_code = generate_flash_map_cpp(flash_dict)
|
|
816
|
+
if output_dir:
|
|
817
|
+
hpp_path = os.path.join(output_dir, "flash_map.hpp")
|
|
818
|
+
with open(hpp_path, "w", encoding="utf-8") as f:
|
|
819
|
+
f.write(f"""#pragma once
|
|
820
|
+
// Auto-generated Flash Layout Map
|
|
821
|
+
// MCU: {mcu_model}
|
|
822
|
+
|
|
823
|
+
#include "main.h"
|
|
824
|
+
|
|
825
|
+
""")
|
|
826
|
+
f.write(cpp_code)
|
|
827
|
+
logging.info(f"Flash layout map written to: {hpp_path}")
|
|
828
|
+
except ImportError as e:
|
|
829
|
+
logging.warning(f"Cannot import FlashLayout generator: {e}")
|
|
830
|
+
except Exception as e:
|
|
831
|
+
logging.warning(f"Cannot generate FlashLayout: {e}")
|
|
832
|
+
|
|
833
|
+
|
|
767
834
|
def main():
|
|
768
835
|
try:
|
|
769
836
|
args = parse_arguments()
|
|
@@ -788,6 +855,8 @@ def main():
|
|
|
788
855
|
with open(args.output, "w", encoding="utf-8") as f:
|
|
789
856
|
f.write(output_code)
|
|
790
857
|
|
|
858
|
+
inject_flash_layout(project_data, output_dir)
|
|
859
|
+
|
|
791
860
|
config_path = os.path.join(output_dir, "libxr_config.yaml")
|
|
792
861
|
|
|
793
862
|
with open(config_path, "w", encoding="utf-8") as f:
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import re
|
|
2
|
+
from dataclasses import dataclass
|
|
3
|
+
from typing import Optional, List
|
|
4
|
+
import sys
|
|
5
|
+
import traceback
|
|
6
|
+
import yaml
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@dataclass
|
|
10
|
+
class FlashSector:
|
|
11
|
+
"""Flash memory sector information"""
|
|
12
|
+
index: int
|
|
13
|
+
address: int
|
|
14
|
+
size: int
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@dataclass
|
|
18
|
+
class FlashInfo:
|
|
19
|
+
"""Complete flash memory configuration"""
|
|
20
|
+
model: str
|
|
21
|
+
flash_base: int
|
|
22
|
+
flash_sectors: List[FlashSector]
|
|
23
|
+
flash_size_kb: Optional[int] = None
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
FLASH_SIZE_CODES = {
|
|
27
|
+
'4': 16, '6': 32, '8': 64, 'B': 128, 'C': 256, 'D': 384,
|
|
28
|
+
'E': 512, 'F': 768, 'G': 1024, 'H': 1536, 'I': 2048,
|
|
29
|
+
'J': 3072, 'K': 4096, 'L': 6144, 'M': 8192, 'N': 12288,
|
|
30
|
+
'P': 16384, 'Q': 512, 'R': 640, 'S': 768, 'T': 1024, 'Z': 512,
|
|
31
|
+
'5': 512, '7': 2048, 'A': 1024, 'V': 1024, 'W': 512, 'X': 1024, 'Y': 2048,
|
|
32
|
+
'1': 256, '3': 8,
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def get_flash_kb(model: str) -> int:
|
|
37
|
+
"""Get flash size from STM32 model number (original logic preserved)"""
|
|
38
|
+
model = model.strip().upper()
|
|
39
|
+
|
|
40
|
+
# Original condition chain preserved
|
|
41
|
+
if model.startswith("STM32WL"):
|
|
42
|
+
if "X" in model:
|
|
43
|
+
return 1024
|
|
44
|
+
if any(code in model for code in ['55', '54', '53', '52']):
|
|
45
|
+
return 512
|
|
46
|
+
return 512
|
|
47
|
+
if model.startswith("STM32WBA"):
|
|
48
|
+
code = model[11]
|
|
49
|
+
return FLASH_SIZE_CODES.get(code, 512)
|
|
50
|
+
if model.startswith("STM32WB"):
|
|
51
|
+
if "7" in model:
|
|
52
|
+
return 2048
|
|
53
|
+
if "V" in model:
|
|
54
|
+
return 1024
|
|
55
|
+
return 512
|
|
56
|
+
if model.startswith("STM32U5"):
|
|
57
|
+
if "A" in model:
|
|
58
|
+
return 1024
|
|
59
|
+
code = model[10]
|
|
60
|
+
return FLASH_SIZE_CODES.get(code, None)
|
|
61
|
+
|
|
62
|
+
# Original fallback logic
|
|
63
|
+
try:
|
|
64
|
+
return FLASH_SIZE_CODES[model[10]]
|
|
65
|
+
except (KeyError, IndexError):
|
|
66
|
+
raise ValueError(f"Unrecognized capacity code for {model}")
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def layout_flash(model: str) -> FlashInfo:
|
|
70
|
+
"""Flash layout generator (original logic fully preserved)"""
|
|
71
|
+
model = model.upper()
|
|
72
|
+
flash_kb = get_flash_kb(model)
|
|
73
|
+
flash_base = 0x08000000
|
|
74
|
+
layout = []
|
|
75
|
+
|
|
76
|
+
# Original condition chain
|
|
77
|
+
if "F1" in model:
|
|
78
|
+
page_size = 1024 if flash_kb <= 128 else 2048
|
|
79
|
+
layout = [((flash_kb * 1024) // page_size, page_size)]
|
|
80
|
+
elif "F2" in model or "F4" in model:
|
|
81
|
+
sector_sizes = [16, 16, 16, 16, 64] + [128] * 12
|
|
82
|
+
layout = []
|
|
83
|
+
remaining = flash_kb
|
|
84
|
+
for size in sector_sizes:
|
|
85
|
+
if remaining >= size:
|
|
86
|
+
layout.append((1, size * 1024))
|
|
87
|
+
remaining -= size
|
|
88
|
+
else:
|
|
89
|
+
break
|
|
90
|
+
elif "U5" in model:
|
|
91
|
+
layout = [(1, 128 * 1024)] * (flash_kb // 128)
|
|
92
|
+
elif any(x in model for x in ["WL", "L4", "G0", "G4", "C0", "U0"]):
|
|
93
|
+
layout = [((flash_kb * 1024) // 2048, 2048)]
|
|
94
|
+
elif "L0" in model:
|
|
95
|
+
layout = [((flash_kb * 1024) // 128, 128)]
|
|
96
|
+
elif "WB" in model:
|
|
97
|
+
layout = [((flash_kb * 1024) // 4096, 4096)]
|
|
98
|
+
elif "WBA" in model:
|
|
99
|
+
layout = [(1, 32 * 1024)] * (flash_kb // 32)
|
|
100
|
+
elif "H7" in model:
|
|
101
|
+
layout = [((flash_kb * 1024) // (128 * 1024), 128 * 1024)]
|
|
102
|
+
elif any(x in model for x in ["F7", "F3", "F0"]):
|
|
103
|
+
layout = [((flash_kb * 1024) // 2048, 2048)]
|
|
104
|
+
elif "L1" in model:
|
|
105
|
+
layout = [((flash_kb * 1024) // 256, 256)]
|
|
106
|
+
else:
|
|
107
|
+
layout = [((flash_kb * 1024) // 1024, 1024)]
|
|
108
|
+
|
|
109
|
+
# Original sector generation
|
|
110
|
+
sectors = []
|
|
111
|
+
addr = flash_base
|
|
112
|
+
for count, size in layout:
|
|
113
|
+
for _ in range(count):
|
|
114
|
+
sectors.append(FlashSector(
|
|
115
|
+
index=len(sectors),
|
|
116
|
+
address=addr,
|
|
117
|
+
size=size
|
|
118
|
+
))
|
|
119
|
+
addr += size
|
|
120
|
+
|
|
121
|
+
return FlashInfo(
|
|
122
|
+
model=model,
|
|
123
|
+
flash_base=flash_base,
|
|
124
|
+
flash_sectors=sectors,
|
|
125
|
+
flash_size_kb=flash_kb
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def flash_info_to_dict(info: FlashInfo) -> dict:
|
|
130
|
+
"""Original serialization logic preserved"""
|
|
131
|
+
return {
|
|
132
|
+
"model": info.model,
|
|
133
|
+
"flash_base": f"0x{info.flash_base:08X}",
|
|
134
|
+
"flash_size_kb": info.flash_size_kb,
|
|
135
|
+
"sectors": [
|
|
136
|
+
{"index": s.index, "address": f"0x{s.address:08X}", "size_kb": round(s.size / 1024, 3)}
|
|
137
|
+
for s in info.flash_sectors
|
|
138
|
+
]
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def main():
|
|
143
|
+
"""Command line interface for STM32 flash information tool"""
|
|
144
|
+
|
|
145
|
+
def validate_model(model: str) -> bool:
|
|
146
|
+
"""Validate STM32 model number format"""
|
|
147
|
+
return (
|
|
148
|
+
'-' not in model and
|
|
149
|
+
model.upper().startswith("STM32") and
|
|
150
|
+
len(model) > 8
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
if len(sys.argv) != 2:
|
|
154
|
+
print("STM32 Flash Information Tool")
|
|
155
|
+
print("Usage:")
|
|
156
|
+
print(f" xr_stm32_flash <STM32_MODEL>")
|
|
157
|
+
print("\nExamples:")
|
|
158
|
+
print(f" xr_stm32_flash STM32F103C8T6")
|
|
159
|
+
print(f" xr_stm32_flash STM32L476RG")
|
|
160
|
+
sys.exit(1)
|
|
161
|
+
|
|
162
|
+
model = sys.argv[1].strip().upper()
|
|
163
|
+
|
|
164
|
+
try:
|
|
165
|
+
if not validate_model(model):
|
|
166
|
+
raise ValueError(f"Invalid STM32 model format: {model}")
|
|
167
|
+
|
|
168
|
+
info = layout_flash(model)
|
|
169
|
+
print(yaml.safe_dump(
|
|
170
|
+
flash_info_to_dict(info),
|
|
171
|
+
sort_keys=False,
|
|
172
|
+
allow_unicode=True,
|
|
173
|
+
default_flow_style=False
|
|
174
|
+
))
|
|
175
|
+
|
|
176
|
+
except Exception as e:
|
|
177
|
+
print(f"\nERROR: Failed to process model {model}")
|
|
178
|
+
print(f"Reason: {str(e)}")
|
|
179
|
+
print("\nStack trace:")
|
|
180
|
+
traceback.print_exc()
|
|
181
|
+
sys.exit(2)
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
if __name__ == '__main__':
|
|
185
|
+
main()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: libxr
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.4
|
|
4
4
|
Summary: C++ code generator for LibXR-based embedded systems, supporting STM32 and modular robotics applications.
|
|
5
5
|
Author-email: Xiao <2592509183@qq.com>
|
|
6
6
|
Maintainer-email: Xiao <2592509183@qq.com>
|
|
@@ -57,6 +57,27 @@ Dynamic: license-file
|
|
|
57
57
|
|
|
58
58
|
## 📥 Installation 安装
|
|
59
59
|
|
|
60
|
+
### 使用pipx安装 (Install via `pipx`)
|
|
61
|
+
|
|
62
|
+
windows
|
|
63
|
+
|
|
64
|
+
```ps
|
|
65
|
+
python -m pip install --user pipx
|
|
66
|
+
python -m pipx ensurepath
|
|
67
|
+
pipx install libxr
|
|
68
|
+
pipx ensurepath
|
|
69
|
+
# Restart your terminal
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
linux
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
sudo apt install pipx
|
|
76
|
+
pipx install libxr
|
|
77
|
+
pipx ensurepath
|
|
78
|
+
# Restart your terminal
|
|
79
|
+
```
|
|
80
|
+
|
|
60
81
|
### 使用 pip 安装 (Install via `pip`)
|
|
61
82
|
|
|
62
83
|
```bash
|
|
@@ -233,9 +254,54 @@ usage: xr_gen_code_stm32 [-h] -i INPUT -o OUTPUT [--xrobot] [--libxr-config LIBX
|
|
|
233
254
|
Main entry point with all initialization logic
|
|
234
255
|
|
|
235
256
|
- `libxr_config.yaml`:
|
|
236
|
-
运行时配置文件,可自定义缓冲区大小、队列等参数
|
|
257
|
+
运行时配置文件,可自定义缓冲区大小、队列等参数
|
|
237
258
|
Runtime config YAML, can be customized with buffer size, queue, etc.
|
|
238
259
|
|
|
260
|
+
- `flash_map.hpp`:
|
|
261
|
+
自动生成的 Flash 扇区表,供 Flash 抽象层使用
|
|
262
|
+
Auto-generated flash sector layout for use with Flash abstraction layer
|
|
263
|
+
|
|
264
|
+
---
|
|
265
|
+
|
|
266
|
+
### `xr_stm32_flash`
|
|
267
|
+
|
|
268
|
+
解析 STM32 型号,生成 Flash 扇区信息表(YAML 格式输出)。
|
|
269
|
+
Parses STM32 model name and generates flash layout info (YAML output).
|
|
270
|
+
|
|
271
|
+
```bash
|
|
272
|
+
usage: xr_stm32_flash <STM32_MODEL>
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
### 🧠 功能说明 (Functionality)
|
|
276
|
+
|
|
277
|
+
- 根据 STM32 型号名称自动推导 Flash 大小
|
|
278
|
+
Automatically infers flash size from the STM32 model string
|
|
279
|
+
|
|
280
|
+
- 根据芯片系列(如 F1/F4/H7/U5 等)生成对应的扇区布局
|
|
281
|
+
Generates sector layout depending on the chip series (e.g., F1/F4/H7/U5)
|
|
282
|
+
|
|
283
|
+
- 输出包括每个扇区的地址、大小和索引
|
|
284
|
+
Output includes address, size, and index of each sector
|
|
285
|
+
|
|
286
|
+
### 📦 输出内容 (Outputs)
|
|
287
|
+
|
|
288
|
+
- YAML 格式的 Flash 信息
|
|
289
|
+
Flash info in YAML format:
|
|
290
|
+
|
|
291
|
+
```yaml
|
|
292
|
+
model: STM32F103C8
|
|
293
|
+
flash_base: '0x08000000'
|
|
294
|
+
flash_size_kb: 64
|
|
295
|
+
sectors:
|
|
296
|
+
- index: 0
|
|
297
|
+
address: '0x08000000'
|
|
298
|
+
size_kb: 1.0
|
|
299
|
+
- index: 1
|
|
300
|
+
address: '0x08000400'
|
|
301
|
+
size_kb: 1.0
|
|
302
|
+
...
|
|
303
|
+
```
|
|
304
|
+
|
|
239
305
|
---
|
|
240
306
|
|
|
241
307
|
### `xr_stm32_it`
|
|
@@ -9,6 +9,7 @@ src/libxr/GeneratorSTM32CMakeClang.py
|
|
|
9
9
|
src/libxr/GeneratorSTM32IT.py
|
|
10
10
|
src/libxr/PeripheralAnalyzer.py
|
|
11
11
|
src/libxr/PeripheralAnalyzerSTM32.py
|
|
12
|
+
src/libxr/STM32FlashGenerator.py
|
|
12
13
|
src/libxr/__init__.py
|
|
13
14
|
src/libxr.egg-info/PKG-INFO
|
|
14
15
|
src/libxr.egg-info/SOURCES.txt
|
|
@@ -6,4 +6,5 @@ xr_parse = libxr.PeripheralAnalyzer:main
|
|
|
6
6
|
xr_parse_ioc = libxr.PeripheralAnalyzerSTM32:main
|
|
7
7
|
xr_stm32_clang = libxr.GeneratorSTM32CMakeClang:main
|
|
8
8
|
xr_stm32_cmake = libxr.GeneratorSTM32CMake:main
|
|
9
|
+
xr_stm32_flash = libxr.STM32FlashGenerator:main
|
|
9
10
|
xr_stm32_it = libxr.GeneratorSTM32IT:main
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|