# 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工程,作为这部分代替。缺点就是每次点击复位很慢。