一份GD32完整的开发提示词 Cursor写单片机代码提示词模板rules C语言嵌入式GD32E230开发

根据你自己的情况进行修改 。可以使用大模型,帮你修改。不要完全复制。每个公司的要求不一样。

以下是具体的Cursor提示词。个人认为,适合新入门的Cursor单片机开发者。


我们主要开发的是GD32E230单片机,它是ARM M23内核的。你要精通GD32的库。

项目地址E:\EIDE\v4d5\Eide\gd32e230-quickstart
E:\EIDE\v4d5\Eide\gd32e230-quickstart\hal
E:\EIDE\v4d5\Eide\gd32e230-quickstart\src
这是重要的库

如果我让你开发的工程涉及到c语言的时候,请按照下面提示词执行。如果是其它编程语言或者脚本语言,文本等,则忽略以下规范。

C语言开发GD32 ARM单片机编程规范提示词

一、引言

本规范旨在为使用C语言开发GD32 ARM单片机的项目提供统一的编程标准,确保代码的可读性、可维护性、可靠性和高效性。规范涵盖代码风格、命名规则、语法使用、错误处理、性能优化等多个方面。开发者在编写代码时应严格遵循。
我的嵌入式代码,涉及C代码用C99标准,涉及C++代码用C++11标准 。编译器是嵌入式的ARM Compiler 6(AC6)。

二、代码风格与结构

(一)基本原则

  1. 清晰易读:代码应具有良好的可读性,优先保证清晰性,避免复杂的逻辑和晦涩的代码结构。使用适当的缩进和空白符增强代码层次感,确保结构一目了然。
  2. 简洁高效:在保证功能的前提下,代码应尽量简洁,避免冗余和不必要的复杂性。去除无用代码,提炼重复代码,提高执行效率。

(二)文件结构

  1. 源文件与头文件:每个C源文件(.c)通常应对应一个同名的头文件(.h),用于声明对外接口。头文件应只包含接口声明,如函数声明、宏定义、类型定义等,避免放置实现代码。
  2. 文件组织:合理组织源文件和头文件内容,将相关功能的代码放在同一个文件中,确保文件职责单一。例如,将与GD32 GPIO操作相关的函数和定义放在gd32_gpio.cgd32_gpio.h中。

(三)函数结构

  1. 单一职责:一个函数应只完成一项功能,避免函数功能过于复杂。例如,将GPIO初始化功能封装在一个独立函数中,而不是将GPIO初始化和数据处理功能放在同一个函数里。
  2. 避免过长函数:尽量控制函数长度,新增函数的非空非注释行数不超过50行。对于算法实现函数,若超过50行应进行合理拆分。
  3. 代码块嵌套:减少函数内代码块的嵌套深度,新增函数的代码块嵌套不超过4层,以提高代码可读性。
  4. 构造仅有一个模块或函数可以修改、创建,而其余有关模块或函数只访问的全局变量,防止多个不同模块或函数都可以修改、创建同一全局变量的现象 ,降低全局变量耦合度。
  5. 明确全局变量的初始化顺序,避免跨模块的初始化依赖
  6. 使用面向接口编程思想,通过 API 访问数据:如果本模块的数据需要对外部模块开放 ,应提供接口函数来设置、获取,同时注意全局数据的访问互斥,避免直接暴露内部数据给外部模型使用,是防止模块间耦合最简单有效的方法。定义的接口应该有比较明确的意义,比如一个风扇管理功能模块,有自动和手动工作模式,那么设置、查询工作模块就可以定义接口为Set_FanWorkMode,Get_FanWorkMode;查询转速就可以定义为Get_FanSpeed;风扇支持节能功能开关,可以定义Enable_FanSavePower等。
  7. 函数声明:.c文件中,对只在文件内部使用的函数,都采用static定义,如果是需要暴露在外部的,则无需采用static 。 另外.h文件中,只显示对外需要暴露的函数声明。 注意对外暴露的函数的参数定义,这里面应该尽可能的少参数,一些内部的成员变量,不需要从参数传递。减少对外部的依赖。 参数顺序应遵循:输入参数在前,输出参数在后 。当参数较多时(>3个),考虑封装为结构体传递 。 在.h文件中的函数声明应带有完整的参数名称和类型,便于文档生成和API理解 。 对暴露给外部的函数,应有统一的错误返回机制,如返回标准错误码 。 错误返回4000,4001…,40,等4开头的。线程安全考虑,对于可能在多线程环境中调用的外部接口,应明确标注线程安全性,必要时提供可重入版本的函数 。当需要线程安全或多实例时,应显式传递上下文参数。

内联函数使用规范:对于频繁调用的短小函数,使用inline可以减少函数调用开销 。

(四)其它细节

1.常量建议使用 const 定义代替宏
2.指针与const的结合 ,引用C99标准能够帮助我们更精确地理解const的语义,并编写出更加健壮和易维护的代码。总之,使用const定义常量和指针不仅能提升代码的可读性,还能充分利用编译器的类型检查机制,减少潜在的错误。

三、命名规则

(一)通用命名规则

  1. 清晰明了:标识符命名要清晰、有明确含义,使用完整单词或通用缩写,避免产生误解。
    变量名字要短小,使用驼峰形式,例如,使用pinNumber表示GPIO引脚编号,而不是使用模糊的缩写。

  2. 统一风格:函数,功能的长名字用中间_下划线形式。传参数采用驼峰式命名,传参可以以_开头定义就局部参数变量。

  3. 特殊情况:极特殊的情况下,比较长的变量名,可以用中间下滑线形式命名,这通常由人类程序员确定。

(二)文件命名规则

  1. 小写字母:源文件和头文件命名统一采用小写字母,不同单词间用下划线分隔,如gd32_timer.cgd32_timer.h
  2. 体现功能:文件名应能清晰体现文件的功能,便于识别和管理。

(三)变量命名规则

  1. 前缀标识:全局变量加_g后缀,后缀_s 表示静态局部变量,便于区分变量作用域。这个命名规则看起来很清晰,能够明确区分不同类型的变量:
  • _g 表示全局变量,提醒开发人员注意它们的全局作用域。
  • _s 表示静态局部变量,作用域限于函数,但其生命周期贯穿整个程序运行。

这样的一致性命名有助于代码的可读性和维护性。只要团队成员都遵循这个规则,它将能有效提高代码的可理解性。

函数内的局部变量名用缩写,越短越好。不要和全局变量重名。也不要和其它结构体里的成员名重名。

volatile限定符的使用指导:对于可能被中断修改的变量,添加volatile确实是必要的。

  1. 避免单字节命名:禁止使用单字节命名变量,循环变量ijk除外。
  2. 描述性命名:变量命名应能描述其用途,使用名词或形容词加名词的方式,如buttonPressFlag表示。
  3. 常用缩写
    argument 可缩写为 arg
    buffer 可缩写为 buff
    clock 可缩写为 clk
    command 可缩写为 cmd
    compare 可缩写为 cmp
    configuration 可缩写为 cfg
    device 可缩写为 dev
    error 可缩写为 err
    hexadecimal 可缩写为 hex
    increment 可缩写为 inc
    initialize 可缩写为 init
    maximum 可缩写为 max
    message 可缩写为 msg
    minimum 可缩写为 min
    parameter 可缩写为 para
    previous 可缩写为 prev
    register 可缩写为 reg
    semaphore 可缩写为 sem
    statistic 可缩写为 stat
    synchronize 可缩写为 sync
    temp 可缩写为 tmp

不在以上举例的常用缩写范围内的单词,尽量要用缩写。避免看不懂。
5. 指针型变量:可以用 xxxPtr来命名指针变量。

(四)函数命名规则

  1. 动词开头:函数命名应以动词开头,体现函数执行的动作,采用动词加名词的结构,函数名以用下划线形式_,如read_gpio_pin表示读取GPIO引脚的函数。
  2. 清晰准确:函数名应准确反映其功能,避免使用模糊或歧义的名称。
  3. 函数名功能分类要统一: 函数一般有get_, read_, set_, init_, do_ , calc_, update_, fresh_,load_,save_, turn_, turnOn_, toggle_,test_,config_,init_Struct_ ,erase_,reset_, init_dev,…等等你可以将同类函数,以相似的动词开头。分析每个函数的作用,以其动作开头。
  4. 参数名规则:函数传参的参数名字,命名尽量简短,参数名字可以不使用中间_下划线的命名方式,多字节可使用驼峰命名,或以_开头。如果参数是指针,xxxx_StructType_t *xxxPtr ; 则最推荐用Ptr作为指针变量结尾。 例如在传参过程中,Function(uint32_t *xxxPtr); Function(uint8_t *xxxBufPtr, uint16_t size)

(五)宏命名规则

  1. 全大写加下划线:宏定义采用全大写字母,单词间加下划线,如GPIO_PIN_0TIMER_CLOCK_FREQ
  2. 避免冲突:宏名应避免与其他标识符冲突,且不能使用下划线开头和结尾(特殊标识定义除外)。

(六)枚举类型类型定义规则

枚举类型名称使用_enumType_t后缀定义枚举类型。
xxxx_enumType_t;
xxx_xxx_enumType_t;

typedef enum {
ENUM_VALUE1,
ENUM_VALUE2,
ENUM_VALUE3,
} xxxx_enumType_t;

枚举变量,的话
xxxx_enumType_t var1Enum;
xxxx_enumType_t var2Enum;

枚举的类型声明,放在.h文件中,枚举变量放在.c文件中定义
如果需要外部引用,就在.h文件用extern。

(七)结构体定义规则

typedef struct xxx_struct xxx_t;

结构体定义规则如下
struct xxx_struct {

};

xxx_t var1;
xxx_t var2;

如果定义的结构体,仅在.c文件内部使用,则无需把定义结构体类型放在.h文件中。暴露给其它地方。
如果结构体需要在别的文件中用,那么可以将结构体类型的定义放在.h文件中,同时typedef struct xxx_struct xxx_t;这个也放在.h文件中 。 具体的结构体全局变量则定义在.c文件中。 然后在.h文件中,用extern来声明。这样外部文件就可以使用了。

四、语法与格式

(一)语法使用

  1. 遵循标准:严格遵循C语言标准,确保代码的兼容性和可移植性。
  2. 避免隐式转换:尽量减少数据类型的隐式转换,必要时进行显式转换,并确保转换的正确性。例如,将float类型转换为int类型时,要注意数据精度的丢失。

(二)格式规范

  1. 缩进与空白符:程序块采用缩进风格编写,每级缩进为4个空格。相对独立的程序块之间、变量说明之后必须加空行,增强代码的可读性。
  2. 语句长度:一条语句不宜过长,若不能拆分需分行写。换行时增加一级缩进,在低优先级操作符处划分新行,操作符放在新行首,确保一个完整语句放在一行。
  3. 操作符空格:在两个以上的关键字、变量、常量进行对等操作时,操作符前后加空格;非对等操作时,关系密切的立即操作符(如->)后不加空格。

五、错误处理与验证

(一)错误处理

  1. 合理使用异常:虽然C语言没有异常机制,但可通过返回错误码等方式处理异常情况。函数应返回明确的错误码,调用者需对错误码进行检查和处理。
  2. 错误日志记录:在关键代码段添加错误日志记录功能,便于定位和排查问题。可使用自定义的日志函数记录错误信息,包括错误发生的位置、错误码等。

(二)输入验证

  1. 参数验证:对函数的输入参数进行有效性验证,确保参数在合理范围内。例如,对于GPIO引脚编号参数,应检查其是否在有效引脚范围内。
  2. 数据范围检查:对输入数据进行范围检查,防止数据溢出或越界。如对定时器计数值进行检查,确保其不超过定时器的最大计数值。

六、性能优化

(一)算法优化

  1. 选择合适算法:根据实际需求选择高效的算法,避免使用复杂低效的算法。例如,在排序算法中,对于小规模数据可使用插入排序,大规模数据可使用快速排序。
  2. 优化算法实现:对算法实现进行优化,减少不必要的计算和操作。如在循环中避免重复计算不变量,将其移到循环体外。

(二)资源管理

  1. 内存管理:合理分配和释放内存,避免内存泄漏和内存碎片。使用动态内存分配函数(如mallocfree)时,要确保内存的正确释放,可通过封装内存管理函数来增强内存管理的安全性。
  2. 外设资源管理:合理使用GD32单片机的外设资源,避免资源冲突和浪费。例如,在使用定时器时,确保定时器的配置符合需求,避免过度占用系统资源。

七、关键规范

(一)模块化编程

  1. 功能模块化:将项目功能划分为多个独立的模块,每个模块负责特定的功能,提高代码的可维护性和可扩展性。例如,将GD32的ADC功能封装成一个独立模块,便于其他模块调用和维护。
  2. 模块接口设计:设计清晰的模块接口,模块间通过接口进行通信,降低模块间的耦合度。模块接口应提供必要的函数和数据结构,确保模块的独立性和可复用性。

(二)寄存器操作规范

  1. 寄存器映射:使用标准的寄存器映射方式,确保对GD32单片机寄存器的正确访问。可通过定义结构体或宏来映射寄存器地址和位域,提高代码的可读性和可维护性。
  2. 寄存器操作函数:封装寄存器操作函数,避免在代码中直接对寄存器进行复杂操作。例如,编写set_Gpio_Pin函数来设置GPIO引脚状态,而不是直接操作GPIO寄存器。

八、测试

(一)测试策略

  1. 单元测试:编写单元测试用例对各个模块进行测试,确保模块功能的正确性。单元测试应关注模块的行为,而不是具体实现细节。
  2. 集成测试:进行集成测试,验证各个模块之间的协同工作是否正常,确保系统整体功能的正确性。

(二)测试工具

  1. 选择合适工具:根据项目需求选择合适的测试工具,如基于硬件调试器的测试工具或软件模拟测试工具。
  2. 测试框架:可使用开源的测试框架(如Check)来组织和运行测试用例,提高测试效率和可管理性。

九、安全性

(一)数据安全

  1. 防止溢出:在进行数据处理时,防止数据溢出和越界,确保数据的安全性和正确性。例如,在对数组进行操作时,检查数组下标是否越界。
  2. 数据加密:对于敏感数据,可考虑进行加密处理,提高数据的安全性。如对通信数据进行加密传输,防止数据泄露。

(二)代码安全

  1. 避免危险函数:避免使用危险的C函数(如strcpygets等),使用相对安全的函数(如strncpyfgets等)代替,防止缓冲区溢出等安全问题。
  2. 代码审查:进行代码审查,及时发现和修复潜在的安全漏洞,确保代码的安全性。

十、文档

(一)代码注释

  1. 注释内容:注释应清晰明了,解释代码的功能、意图和关键算法。避免重复描述代码,对代码中巧妙、晦涩、重要的地方加以注释。
  2. 注释位置:注释应放在代码上方相邻位置或右方,不可放在下方。文件头部、函数声明处、全局变量等应添加详细注释。
  3. 注释位置: 如果某个计算相除的结果可能=0,或者函数return后面的值可能是0,请用在后面备注 // maybe 0

(二)项目文档

  1. 功能描述:编写项目文档,详细描述项目的功能、架构、模块设计等内容,便于团队成员理解和维护项目。
  2. 使用说明:提供项目的使用说明,包括硬件连接、软件配置、操作流程等,方便用户使用和部署项目。

十一、其它应该注意的编译报错问题

为了减少编译器编译出错和警告,应该严格按照规范写代码。还请注意以下常见编译报错问题:

1、使用 static 限定符:对于仅在当前文件内部使用的函数或变量,建议加上 static。
2、修正隐式声明:在使用函数之前提供正确的声明或包含相应的头文件。
3、明确 switch-case 的控制流:根据需要添加 break; 或 fallthrough 注解,避免意外的执行流程。
4、 结构体填充(-Wpadded) , 编译器提示在结构体中自动插入了填充字节(padding),以满足内存对齐要求。
构体成员 ,将较大数据类型放前面,较小的放后面,可以减少编译器自动插入的填充字节,从而减少内存浪费。最后如果需要填充几个字节,可以用1~2个固定的占位符变量,来显式的填充。
5、 注意隐式类型转换问题,检查所有隐式转换,确保不会因类型大小、符号(有符号 vs. 无符号)或精度问题导致数据丢失。必要时使用显式转换并验证数据范围。
6、 函数原型和声明缺失(-Wmissing-prototypes、-Wmissing-variable-declarations)
7、 未使用的参数 不要出现在代码里(-Wunused-parameter),如果某个函数参数在实现中没有用到,可以通过删除参数或者使用特定的宏(如 UNUSED)来标记,避免产生无用代码的警告。
8、 投射(-Wcast-qual)问题,当你从一个具有 volatile 或 const 限定符的指针转换为不带这些限定符的指针时,可能会丢失原本的数据保护特性,编译器会警告你这种转换可能带来的问题。
9、 switch 语句中不能缺失对所有枚举值的显式处理(-Wcovered-switch-default、-Wswitch-enum)
10、 文件格式问题 “no newline at end of file” 表示文件末尾缺少换行符,这在某些编码规范中被视为不规范。
11 、其他问题 如未使用的变量(-Wunused-variable)、旧式函数定义风格(-Wstrict-prototypes)等,对于未使用的变量,可以考虑删除或注释掉;对于旧式函数定义,建议尽量更新为标准的函数原型声明,以确保代码在现代编译器下无警告、无隐患。

总的来说,严格按照编码规范编写代码,不仅可以减少编译器的警告和错误,还能提高代码的可读性、可维护性和可靠性。

十二、针对嵌入式单片机的一些具体补充

  1. 命名规则遵循ARM标准(模块名_IRQHandler);
  2. 强调了中断处理时间限制(<10μs),
  3. 使用标志位模式而不是在中断中执行耗时操作,
  4. 正确使用了GD32的中断清除函数,
  5. 关闭非必要外设时钟,
  6. 硬件抽象层规范,提出的函数指针结构体方式是嵌入式系统中常用的硬件抽象方法,可以方便地实现设备驱动的可替换性,提高代码的可移植性。
  7. 强调通过官方库函数操作寄存器而非直接访问,可以提高代码可移植性和可维护性。

如果项目中,如果明确告诉你要求做检查,那应该按照checklist检查的结果生成完整的报告.md文件,对提示词中,或者checklist文件中提到的关键点逐个检查。统计问题数量,按重要性排序写在.md报告文件中。

以上是C语言相关的要求。如果涉及到C语言请严格执行。

代码检查清单checklist

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值