SOC是啥?System on Chip. 一个芯片,但是片上有好多东西的意思。市面上的AI芯片、包括你知道的麒麟xxx,骁龙xxx等等一些列手机芯片都是SOC。对于SOC设计者来讲,显然要知道码农们码出来的一行行代码是如何在SOC上跑起来的。
本文是科普向的,只介绍重要的步骤,省略了大量细节,希望用尽量非专业的词汇介绍概念。如果要真的研究这些东西,还需要大量阅读文档。
0.概览
一段C代码要在SOC上跑起来,一般需要6个步骤。
这是一个总图。包括了最简单的编译流程以及一个SOC可以跑的最小系统。左面绿框里的东西是在PC机上进行的,主要就是把你写的C代码变成二进制的机器码。
右面紫框里是PCB板,红框就是一颗芯片。只有红框里的芯片显然是不可能运行的。你至少要有电源,FLASH,晶振啥的啊。
- FLASH是存储你写的程序的二进制文件的。
- 电源是干啥的你应当很清楚?
- 晶振是给芯片提供时钟(Clock)的。当然芯片内部会有PLL来接收晶振的时钟。
- Reset是个按钮。重置芯片的。你可以理解为上电后自动按一下。你手动也可以按一下。
- UART是输出信息用的。毕竟你要知道你的helloworld到底跑了没有,需要把结果通过某个东西输出来。
红框里就是芯片内的东西。此处画了一个最最最简单的AI芯片SOC。此处介绍一个最最最小的SOC架构。稍微复杂一点的设计见桔里猫:AI SOC芯片里面有什么。
- ARM-M3是个CPU。你可以换成RISC-V或者其他系列的CPU。都没问题。
- AXI是个总线。你要想知道具体怎么连接的看这篇文章桔里猫:SOC中AXI总线是如何连接的。你要是想进一步了解一下AXI协议看这篇文章桔里猫:AXI总线你需要知道的事儿。
- SRAM是片上的存储器。用来存储堆栈啊什么的。速度很快。
- NPU是个神经网络加速单元。这个东西现在市面上一堆一堆。比如寒武纪最原始就是给华为提供这个IP。(当然,后来华为把寒武纪踹了开始自己写这个NPU)
- APB。AXI是高速总线,但总有好多外设其实不需要那么快的速度。为了防止AXI太忙,所以一般有个慢速的总线,APB。挂一些慢的东西。例如UART。
STEP1 准备启动文件
此处我们先要写好一个叫startup.s文件的。这个文件直接是用汇编写的。这个文件主要完成三个工作。。。堆栈的初始化,定位中断向量表,调用启动函数。
1.1 堆栈初始化
上图是中startup.s里面栈的初始化。。。主要就是分配一下大小。重置一下指针。堆原理一样。
1.2 定义中断向量表
上图就是定义的中断向量表。其实你可以理解为这个就是个各个小函数的地址。要放在Flash的0位置处。例如你要运行Reset_Handler这个小程序,PC就会先先访问这个中断向量表,得知Resethandler在哪个地址,然后PC跳到相应的位置开始执行Resethandler. 里面定义了各种中断发生后CPU要做的事儿(小程序)。
1.3 调用ResetHandler
这个小程序就是默认的初始化操作。其实就干了两件事儿,把你写的二进制代码文件从FLASH里搬到SRAM里,然后开始运行(bl main).
STEP2 编写业务代码
这一步应该你比较熟。就是你的c文件。一般来讲学c语言写的第一个程序就是这个。
printf("Hello Word!\n");
STEP3 编译生成机器码
第三步是把写的代码变成机器可以认识的二进制文件。一般用到的工具是GCC。包括了链接啊编译等等一大堆东西。此处为了简单解释,你可以理解为把startup.s翻译成二进制,把hellowolrd.c翻译成二进制。然后把两段二进制拼起来。最终生成code.bin。里面的东西如下图所示。
生成这个code.bin以后。基本上电脑编译这一步就算完成了。下一步就是下载到开发板了。
STEP4 烧写FLASH
第三步生成的code.bin总归是个文件。在你的PC机上呢。如何让它跑在SOC上呢?这需要一个媒介。就是FLASH,这是个小的存储芯片。至于怎么烧写进去。。。用这个烧写器。。。其实一般来讲接口都会设计的很优雅,比如用个micro usb啥的。不会让你抱着砖写FLASH的。
总之,第四步结束以后code.bin就到flash里面了。
STEP5 RESET
第五步是要复位一下芯片系统。为什么要复位一下这个你可能要对数字芯片有一定的了解。让芯片里的各个寄存器恢复到初始状态。大体解释一下的话,CPU里存在一个寄存器叫PC。例如PC=2,就从存储2位置处取出指令来执行。这个复位就是让PC恢复到0,开始跑。
STEP6 CPU开始执行
emmm 到这一步,CPU开始跑程序。先跑startup.s, 再跑 helloworld.c。
STEP7 输出计算结果
等计算结束以后,要输出结果(结果也是一串二进制数)。这是后数据先从ARM写到AXI总线,然后通过AXI-APB纵线桥写到APB,然后写到UART串口。最后你用串口线就能把结果在PC机上看到。
总结
emmm 感觉上述就是如何设计一个最小SOC系统并在系统上跑一个helloworld. 实际上里面涉及到的细节非常多。比如UART如何用起来的, FLASH怎么接进去的。复位信号也不时一个RESET这么简单。往往有power-on reset, system reset等等一堆。但是原理上就是上面讲的这些。写的时候好多东西我比较熟悉了所以想当然的给省略了,如果有什么不清楚的可以讨论。往后有机会再令写文章补充比较细节的步骤。