目录
引子
前几天有人拿个word文档,问我怎么实现,概括一下就是用c实现数码管显示。
但是咱们肯定不做这么简单这么点,我打算做个开源的项目,可以一直更新底层软件库,和上层显示库,目标就是所有的硬件都能模拟。今天主要是搭建个框架,视频在B站。
我给他放到码云上了,录视频的时候开源协议没选,加上git命令太久没用生疏了,commit没推上去,现在好啦。等他初步可以用的时候我在开源。
代码风格约束
今天没想好,后面会逐步更新,暂时只有三点要求
1.注释必须使用/**/,且注释中不能包含注释
2.所有的缩进必须使用空格
3.每个文件要按照样例文件创建
4.==判断时常量在左变量在右
5.函数明变量名等长度不可以超过32个
6.宏定义必须大写
7.宏定义要用()
8.复杂宏定义需要使用do{}while(0)
为什么要这样要求呢,首先注释用//的话,如果你的编辑器宽度不够,换个环境你的一行长注释可能会变成两行,这样编译时会报错的。
缩进用空格则是因为tab不是在所有环境中都是四个空格的,会导致代码外观上很奇怪,另外有些文本工具可能没有tab解析。咱们为了体现专业性,所有的缩进都必须使用空格。
文件样理后面解释
我们有时在做等于判断时可能会漏下一个等号导致变成赋值操作,这样很不好。为了防止这种问题出现,可以把常量写左面。这样漏写时一编译就会检查出来。
函数名变量名不超过32个其实也是为了优化效率,因为这个名字在程序执行阶段是会被用到的。名字过长就会影响效率,严重还会导致程序执行不了,超过硬件能访问的宽度了他可能会没法成功匹配正确的函数和变量。当然这个不是一一对应的,不是32个字符就对应32位。不是这样的。但是也右一定关系,所以最好别太长了。
宏定义大写就是一个规范,这样你用的时候一下就知道他是个宏。
宏定义必须用括号这个就比较有意思了举个例子
cpp
#define A(a) a*a
int b = A(1+1);
当你没用括号时
b的值是1+1*1+1=3
但是其实你真正想的是4对吧
那就要这样
cpp
#define A(a) (a)*(a)
但是这样还是有问题,比如我要拿这个去计算时
cpp
#define a 1 + 1
int b = a;
会只拿一个1,所以也要加括号
cpp
#define a (1 + 1)
int b = a;
当然我只是举个例子。正常不会这么简单
还有就是这种
cpp
#define INIT (0)
#define RES (1)
经常会看到很多寄存器会这样写,这个我不清楚为什么可能是为了统一代码风格,要是有知道的兄弟欢迎评论区来说说哈。
然后就是do while这种就是因为有些宏要定义的比较复杂。
cpp
#include <stdio.h>
#define INT_TO_CHARS(n) do{ \
((n) >> 24 & 0xFF);\
((n) >> 16 & 0xFF);\
((n) >> 8 & 0xFF);\
((n) & 0xFF);\
}while(0);
int main() {
int num = 12345;
char chars[4];
// 使用宏将整型数拆分为四个char
chars[0] = INT_TO_CHARS(num)[0];
chars[1] = INT_TO_CHARS(num)[1];
chars[2] = INT_TO_CHARS(num)[2];
chars[3] = INT_TO_CHARS(num)[3];
printf("Chars: %c%c%c%c\n", chars[0], chars[1], chars[2], chars[3]);
return 0;
}
为了保证定义的宏后面内容是个整体所以还要用\保证他们是一行的。
代码结构和模板
暂时就是这样一个简单结构后面在继续丰富,我目前分三层,底层hardware,应用层APP和显示层show。
cpp
/*FILENAME: main.c
*DESC : program entry
*AUTHOR : tianyu.xin
**/
文件头每个文件都要有,这个后面继续补充描述项
cpp
/*FILENAME: template.c
*DESC : template Head file
*AUTHOR : tianyu.xin
**/
/* 62* */
/**************************************************************
***************************EXTERN******************************
**************************************************************/
/**************************************************************
***************************LOCAL******************************
**************************************************************/
cpp
#ifndef __TEMPLATE_H__
#define __TEMPLATE_H__
/*FILENAME: template.c
*DESC : template Head file
*AUTHOR : tianyu.xin
**/
/**************************************************************
***************************DEFINE******************************
**************************************************************/
/**************************************************************
***************************EXTERN******************************
**************************************************************/
/**************************************************************
***************************LOCAL******************************
**************************************************************/
#endif /*template.h*/
local区存放本地函数,extern区存放针对本文件以外的对外接口
DEFINE是宏定义的区域
目前build还有很多问题,先用make后面用python做build过程。
目前python脚本支持清除工作。
python
import subprocess
import sys
import os
import glob
# 获取当前目录的绝对路径
current_directory = os.getcwd()
output = current_directory+"/OUTPUT/"
# 打印当前目录的路径
print("当前目录的路径是:", current_directory)
def compile_makefile():
"""编译Makefile"""
subprocess.run(["make"])
# def clean():
# """清除Makefile编译的产物"""
# subprocess.run(["rm", output+"*"], shell=True)
def clean():
"""清除Makefile编译的产物"""
files_to_delete = glob.glob(output + "*")
for file in files_to_delete:
os.remove(file)
if __name__ == "__main__":
if len(sys.argv) < 2:
pass
#print("请输入命令参数:make 或 clean")
elif sys.argv[1] == "make":
compile_makefile()
elif sys.argv[1] == "clean":
clean()
else:
print("无效的命令参数")