# CSharp_Board_Doc
**Repository Path**: ICS_PUBLIC/csharp_-board_-doc
## Basic Information
- **Project Name**: CSharp_Board_Doc
- **Description**: 文档仓库
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 2
- **Forks**: 0
- **Created**: 2025-07-01
- **Last Updated**: 2025-12-12
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# 硬件要求
* ICS C#开发板一快
* JLINK一台
# 1.首先安装环境(windows下)
* 1.1 克隆工具链https://gitee.com/ICS_PUBLIC/arm-none-eabi-gcc-for-csharp.git
* 1.2 工具链仓库下,有安装我编译版本的arm-none-eabi-gcc工具链,是的,你没有看错,普通的arm-none-eabi-gcc工具链虽然可以编译,但是运行C#代码一定会崩。所以吧工具链仓库下的gcc解压,解压后,找到arm-none-eabi-gcc.exe所在的目录加入环境变量.
* 1.3 安装cmake 无脑下一步。按道理安装时会自动加入环境变量,如果没有,则你需要手动添加CMake.exe所在的目录加到环境变量。
## 注意,这里一定将CMAKE.exe 设置为管理员运行,详见:https://blog.csdn.net/snikeguo/article/details/149667825
* 1.3 解压Ninja 同样加入环境变量
* 1.4 python, python我就不打包到仓库了,自行网上下载,3.X的就行,我的是3.13.2
* 安装windows下的kconfig后端:
```
pip install windows-curses
```
1.5 修复kconfig的bug,是的,他在windows下有个bug,修复BUG:`C:\Users\Administrator\AppData\Local\Programs\Python\Python313\Lib\site-packages\guiconfig.py`中增加一行import re即可 我的用户名是Administrator 用户自行替换
# 2.克隆仓库
2.1 新建一个nuttx的工作目录,比如E:/nuttx_workspace,后续称之为$nuttx_root
2.2 克隆nuttx到$nuttx_root/nuttx目录下
2.3 克隆apps到$nuttx_root/apps目录下
目录结构应该如下所示:
```
shell>ls
nuttx
apps
```
# 3.编译仓库
* 工程为两部分,BOOT和APP。
* 其中BOOT工程编译出来,烧录在单片机芯片内部,在芯片内部FLASH运行,BOOT上电先读KEY1状态,如果KEY1被按下,BOOT不会跳转到APP,会停在BOOT,此时PC会出现一个U盘。这时候把你的APP的nuttx.bin复制到/ics目录下,重新上电,他就自动把SD卡的/ics/nuttx.bin搬运到SDRAM上跑了。我们打算把编译产物放到build_boot文件夹中。
* 其中APP工程,是用户工程,由底层OS+native runtime+用户C#代码一起编译生成的固件。我们打算把编译产物放到build_nativeaot_publish文件夹中。
## 3.1 BOOT配置和编译
* 初始化BOOT配置 在$nuttx_root/nuttx目录下打开终端,键入:
```
cmake -B build_boot -DBOARD_CONFIG=ics-stm32h723zg:boot -GNinja
```
* 这就算吧这个我板子的配置作为编译目标了,编译到build_root目录下,如果你想更改配置,则:
```
cmake --build build_boot -t menuconfig
```
* 就会出现配置界面,配置完毕后,编译工程:
```
cmake --build build_boot
```
编译完了就会在build_boot里面有对应的编译产物。
## 3.2 APP配置但不编译(注意这我们不编译,因为缺少C#的.o文件)
* 初始化APP, 在$nuttx_root/nuttx目录下打开终端,键入:
```
cmake -B build_nativeaot_publish -DBOARD_CONFIG=ics-stm32h723zg:nativeaot_publish -GNinja
```
* 如果想配置
```
cmake --build build_nativeaot_publish -t menuconfig
```
# 4.开发C#程序并编译APP
* 下载.net10 sdk https://dotnet.microsoft.com/zh-cn/download/dotnet/10.0
* 新建C#工程(比如$nuttx_root/CSharpProject,也可以直接用我的Ics.Nativeaot.Sample仓库) 咱们这里用 Ics.Nativeaot.Sample仓库InterfaceDispatchTest的例子
* 修改C#工程文件:
```
Exe
net10.0
enable
enable
F:\ICS_CSharpWorkSpace\nuttx_workspace\apps\ics\NativeAot\dotnet_toolchain\net10_linux_arm_runtime\Debug\native
F:\ICS_CSharpWorkSpace\nuttx_workspace\apps\ics\NativeAot\dotnet_toolchain\net10_linux_arm_runtime\Debug\lib
$(IlcFrameworkNativePath)
F:\ICS_CSharpWorkSpace\nuttx_workspace\apps\ics\NativeAot\dotnet_toolchain\compiler
F:\ICS_CSharpWorkSpace\nuttx_workspace\apps\ics\NativeAot\CSharpObjectFile
F:\ICS_CSharpWorkSpace\nuttx_workspace\nuttx
cmake --build build_nativeaot_publish
true
true
```
记得修改你的这几个路径改成你的哦
* 然后再VS里编译程序没问题后,我们就打算编译成单片机程序了,在C#工程路径下,输入如下命令:
```
dotnet publish "InterfaceDispatchTest.csproj" -c Debug -r linux-arm /p:PublishAot=true #这里咱们用的InterfaceDispatchTest项目
```
* #### 这次会失败,不用管他,接下来要覆盖文件!注意,覆盖文件只有你电脑第一次部署这个方案的时候才会出现。
* 覆盖文件:
##### 将Microsoft.NET.Publish.targets 覆盖到 C:\Program Files\dotnet\sdk\10.0.100\Sdks\Microsoft.NET.Sdk\targets
##### 将Microsoft.NETCore.Native.targets,
##### Microsoft.NETCore.Native.Publish.targets,
##### Microsoft.NETCore.Native.Unix.targets,
##### 覆盖到C:\Users\Administrator\.nuget\packages\microsoft.dotnet.ilcompiler\10.0.0\build
* 这时候理论上C#从dll到.o文件已经OK了,我们需要再次执行 dotnet publish命令,这个命令会将dll变成.o文件,然后复制到$CSharpObjectFilePath路径下,最后调用BuildNuttxCommand,详见C#工程文件。
```
dotnet publish "InterfaceDispatchTest.csproj" -c Debug -r linux-arm /p:PublishAot=true #这里咱们用的InterfaceDispatchTest项目
```
* 假如说你修改了C语言层面的代码,但是没有修改C#那边代码,你现在需要编译一次。那么可以用这个命令
```
cmake --build build_nativeaot_publish
```
* 其实dotnet publish最后一步也是调用的上述cmake命令来编译.编译完了,此时按道理你的$NuttxRootPath/build_nativeaot_publish目录下的elf文件就更新了。如果你只想编译C#程序,不链接成elf ,请将工程文件中的:
```
F:\ICS_CSharpWorkSpace\nuttx_workspace\nuttx
cmake --build build_nativeaot_publish
```
这两行 去掉即可。后续你在$nuttx_root目录里执行cmake --build build_nativeaot_publish即可。
# 4.制作TF卡映像
* BOOT和APP编译完了,接下来就要烧录BOOT了。BOOT烧录用JLINK。芯片是STM32H723ZGT6,自行烧录。
* 假设你的SD卡是空的,或者刚买回来板子,那你就把按住KEY1,电脑出现U盘了,你就新建一个ICS文件夹,把build_nativeaot_publish文件夹下的nuttx.bin复制进去。这样就好了
# 5.运行
BOOT也下载好了,APP也放到SD卡的指定文件夹了,上电跑吧~~
# 6.停留在BOOT
上电时,按住KEY1,BOOT不会跳转到APP,会停在BOOT,此时PC会出现一个U盘。把你的build_app/nuttx.bin复制到/ics目录下,重新上电
# 7.调试
使用ozone软件打开$nuttx_root\nuttx\OZoneDebugProject\Boot下的工程即可调试BOOT,APP:$nuttx_root\nuttx\OZoneDebugProject\NativeAOT_Publish也同理。
## 7.1调试原理
JLINK加载当前工程目录下的init_pll550mhz_sdram133_for_stm32h723_osc8mhz_csb1.bin,先执行这个bin文件,初始化PLL和SDRAM,然后在将ELF的机器码部分拷贝到SDRAM,最后停在入口。SEGGER公司几乎所有旗下的产品都提供了如何调用JLINK API初始化芯片,但是前提是你知道如何操作寄存器。我不熟寄存器,就直接生成一个STM32CUBEMX工程,作为这部分代替。缺点就是每次点击复位很慢。