POSIX 这个东西,它是个标准,但它既不是 Unix 标准,也不是 Linux 标准。POSIX 就是 POSIX,可以算是“一种操作系统标准”,操作系统可以参考这个标准去实现需要的功能。
Linux/Unix 实现了部分/全部 POSIX 标准的层,而 Windows 也提供了部分 POSIX 函数。mingw 的主要贡献之一就是给 Windows 提供更完整的 POSIX 功能(有,但是不多)。
举个例子:我有个国产单片机 F1C200S。我有它的裸机开发板。它裸机里面有个内核层,这个内核层会检测你是不是“烧录/下载”模式,是的话,进行串口通信(串口通信就是一条线收 + 一条线发 + 一条线接地,钦定频率,比如我就用 115200 Hz,每个字节有个“开始 bit”+ 中间的 8 个 bit + “结尾 bit”,算下来每秒钟 11520 字节,相当于 11.25KB 每秒的传输速度。接收方也按照 115200 这个速度来检测这条线的电压高低,电压拉低表示“开始 bit”,然后连续接受 8 个 bit 后,电压升高表示“结束 bit”,以此传输每个字节)。裸机的内核层以此来实现从电脑 PC USB 串口上下载单片机的程序代码。
然后,这个单片机的程序代码是我编写的,我可以在这个基础上,按照 POSIX 的标准来提供函数,并封装函数;比如我的 stdout/stderr 接的是“串口出”,stdin 接的是“串口入”,然后我串口频率写死了是 115200 Hz;我山寨一套 C 语言标准库函数(比如 C11),让所有 printf() (本质上是 fprintf(stdout, "xxx",...) )的调用写出到“串口出”,然后“串口入”一旦有数据,我就写入到一个预先保留的 buffer 里面去,所有的 fgetc(stdin) 读取的都是这个 buffer 里面的内容。
再在这个基础上,对 fopen 的文件路径之类的做魔改,比如我就规定 /dev/stdout 是写串口出的。
类似的,有 musl 这样的东西提供类似的功能,你只需要实现 int __io_getchar() 和 void __io_putchar() 的函数行为,你就可以在你的程序代码里调用 printf() 或者使用其它的函数对 stdin/stdout 进行读写操作。
那这样一来,我就成功山寨了 Unix + 部分 POSIX 函数。只是,对于国产芯片,现在最大的问题是它依赖 gcc 而且依赖特定版本的 gcc 而且依赖 gcc 的 bug。
一旦发售 + 编译成功出 bootloader 便不再维护,然后你在例如 gcc 的版本是 gcc12 的年代去编译古代的国产芯片,你就会碰壁,因为 gcc12 修复了 gcc9 的 bug(gcc9 不能正确处理 C 语言的 static 关键字,后续版本的 gcc 新增了 -fcommon 来允许你在多个不同的 .c 文件中使用 static 关键字声明相同名字类型的未初始化全局变量),导致你无论如何也编译不出你的 bootloader 或者 buildroot。你必须想办法获取对应的 gcc 版本编译器,能直接编译/交叉编译出你需要的 bin,来编译你的源码库。
顺带一提 buildroot 基本就是山寨版 Linux 的极简版,稍微改造改造比如做个 X Server 然后走 SPI 串口输出屏显内容到一个液晶屏芯片比如 ILI9341 你就能做个带桌面的 Linux 掌上电脑。
那么这样一来,任何提供了源码的、走 X Client 协议的、能在你环境下编译为你的单片机的机器码的库(github 库)你就都支持了。
那你就可以声称:“我是小凯,我创造了凯OS(chaos)”
|