深入剖析esp32c3的系统底层启动

1.本文概述对于esp32的玩法,基本上定位都是做上层应用,乐鑫官方提供的esp-idf物联网开发框架已经十分的完善,做上层应用按照这套框架进行开发,完全不必了解底层的实现细节。作为一个深入研究riscv底层的爱好者来说,跳过esp-idf框架,直接像使用单片机一样去使用esp32c3更加有意思。本文的目的就是理解esp32c3的裸机开发流程,像玩单片机一样去使用这个riscv的mcu。
2.esp32c3分析对于esp32c3玩法,从玩家来看可能更加类似esp8266,相比8266,可以做如下表格对比:
8266c366
cpuxtensariscv
时钟频率160mhz160mhz
wifiieee 802.11 b/g/n;2.4ghz;ht20;up to 75 mbpsieee 802.11 b/g/n;2.4ghz;ht20;up to 150 mbps
蓝牙n/abluetooth le v5.0
sram160 kb400kb
rom0384kb
rtc rom1kb8kb
简单对比一下,不难发现esp32的还是与8266有点类似,而从目前的信息来看,esp32c3芯片的定价也是基本上和8266差不多的。
玩esp32c3,除了可以学习riscv架构,也能够对底层系统的嵌入式编程有着更加深刻的理解。
3.esp32c3系统启动流程如果按照乐鑫esp-idf正常的启动流程来看,启动过程有三个阶段
bootloader第一阶段
该阶段主要是上电后,从rom中运行,并且将bootloader第二阶段程序从flash的0x0地址偏移处搬运到ram中。
soc上电后,直接执行复位向量代码,通过检测gpio_strap_reg的寄存器的状态来确定启动模式。
一般来说,有三种启动模式:
reset from deep sleep
这种启动模式就是系统从深度睡眠中被唤醒。
power up
上电启动
看门狗复位
bootloader第二阶段
该程序开始存放在flash的0x0地址处,其中的作用是从flash中加载分区表,并且决定启动的程序位置,对于ota来说非常有用处。而且也有一些flash程序的解压或者压缩的代码,安全启动,以及 over-the-air updates(ota)等等。然后将程序的数据段放到drom,指令段放到dram中。
主程序启动
第二阶段启动后,加载主程序并且运行自己的程序的业务逻辑。主要的流程就是首先初始化c语言的执行环境,设置栈指针地址,运行freertos操作系统,然后运行main任务线程,执行app_main。用户自己在app_main中编写自己的逻辑。
4.分析esp32c3上的裸机程序目的是让esp32c3上电后直接启动我们自己编写的裸机程序,那么首先rom中的程序是不能改变的。
https://www.espressif.com/sites/default/files/documentation/esp32-c3_technical_reference_manual_cn.pdf
要写裸机代码,首先需要看懂技术手册,在芯片boot控制的这一章节,有描述esp32c3的启动一共有三个strapping管脚gpio2,gpio8,gpio9。
通过这个三个引脚的组合,可以控制boot模式。
启动模式gpio2gpio8gpio9
spi boot 模式1x1
download boot模式110
对于spi模式,又分为两种方式:
常规flash启动
这种模式支持安全启动,程序直接在ram中。
直接启动方式
不支持安全启动,程序直接运行在flash中,默认使用这种方式时,需要将程序的bin文件的前两个字节(地址:0x42000000)为0xaebd041d。
而对于download boot模式,可以将uart0或者usb下载代码到flash中或者sram中,这样可以直接在sram中运行。
而本文的实验过程采用的是直接启动方式。
在编写裸机代码之前,首先来看一下memory map。
对于数据的布局如下
程序的链接脚本可设置如下:
memory
{
irom (x): org = 0x42000000, len = 0x400000
drom (r): org = 0x3c000000, len = 0x400000
ram (rw): org = 0x3fc80000, len = 0x50000
rtc_ram (rx): org = 0x50000000, len = 0x2000
}
因为涉及到数据段和代码段的地址分离问题,当程序编译成一整个固件的时候,在flash中的存在形式就是一个elf格式的文件,通过内存的加载,将代码段,数据段分别放到iram和dram中,同时将栈指针地址,数据段,bss段指向ram中。这样就完成了裸机程序的布局。
接下来要开始构建裸机工程了。
5.esp32c3裸机工程的构建在自行构建裸机工程的时候,也参考一些国外工程师的一些代码,最后结合自己的理解,通过meson+ninja构建出属于自己的esp32c3裸机代码实验平台。
为什么不用cmake或者makefile,原因是makefile的跨平台效率不是很好,而且语法比较复杂,而cmake也比较慢,所以想到以后可能会到windows上开发,换一种高效简单的工程构建方式比较,就采用meson+ninja build。关于构建语法规则这里不做赘述。只介绍工程如何使用。
首先本文的环境只在linux上环境下做编译,并在windows平台上下载程序。整个平台后期会完全在windows上进行开发。
1.从github上下载代码
git clone git@github.com:bigmagic123/esp32c3_bare_metal.git
该工程项目主要用于研究esp32c3裸机实验平台。
2.下载riscv交叉编译工具链
首先需要下载教程编译工具链。
https://github.com/xpack-dev-tools/riscv-none-embed-gcc-xpack/releases/tag/v10.1.0-1.1/
下载对应版本的riscv最新的交叉编译工具链即可。
3.设置gcc路径
直接修改esp32c3_bare_metal/example/cross.txt中的路径即可。
替换自己的编译路径即可。
4.编译程序
meson setup _build --cross-file cross.txt
cd _build
ninja
6.esp32c3裸机代码下载与运行首先需要下载python3。可以在windows系统上进行操作。
安装好后,可以输入pip install esptool。
下载完成后,esp32c3通过串口调试助手连接到电脑。
下载完成,可以通过esptool探测芯片id。
通过下面的命令烧录并启动串口
esptool.py --port com4 --baud 921600 write_flash 0x0000 demo.bin
python -m serial.tools.miniterm com4 115200
如果退出,可以输出下面的命令
ctrl + ]
这样就可以将程序烧录到flash中了。
7.分析裸机驱动程序的编写编写裸机程序,在对于esp32c3的编程模型中,可以使用rom的里面的程序进行设计。
其原理就是rom中运行程序,每个函数都有特定的地址,只需要知道rom函数对应的地址,就可以通过访问地址,从而访问函数。
在[esp-idf](https://github.com/espressif/esp-idf)。
components/esp_rom/esp32c3/ld/esp32c3.rom.ld
其中定义了一些rom函数的地址,比如通过串口发送一个字节
uart_tx_one_char = 0x40000068;
其头文件
components/esp_rom/include/esp32c3/rom/uart.h
函数的定义
/**
* @brief output a char to printf channel, wait until fifo not full.
*
* @param none
*
* @return ok.
*/
status uart_tx_one_char(uint8_t txchar);
另外,也以通过编程手册进行操作寄存器的编程,这种难度稍微大一些。
https://www.espressif.com/sites/default/files/documentation/esp32-c3_technical_reference_manual_cn.pdf
比如在定时器组(timg)的章节
在寄存器的控制寄存器,首先timg_t0_en设置为1的时候,使能计数器。
对于esp32c3的编程,首先配置一下寄存器,使能定时器。
然后可以通过update寄存器更新寄存器的值。
当使能定时器时,其值不断在增加/减少。每次需要读取数据的时候,需要将上述的31位写0或者1,才能去读t0lo寄存器。
其定时器的值为54位。这样就可以正常通过寄存器操作esp32c3定时器了。
8.总结esp32c3裸机编程,可以清楚的理解esp32的底层启动过程,完全当作单片机来使用。
关于wifi和蓝牙部分,使用rom中提供的函数地址,通过链接脚本和头文件的方式进行函数调用,这样非常方便,而大部分驱动编程则需要自己查询datasheet,操作外设对应的寄存器进行访问。


全自动装车码垛机器人的应用优势是什么
研究人员发现:更多黑客的网络攻击针对于基于Linux的设备
智慧安防让视频服务无处不在 提升公众的安全度和安居满意度
百度AI开发者大会:首次在国内以元宇宙形式举办科技大会
太阳能半导体制冷空调控制系统设计
深入剖析esp32c3的系统底层启动
多载波MS-DPD开发平台简化基站设计
什么是氢燃料电池汽车 氢燃料电池汽车发展正面临哪些挑战
Quick-Charge IC Routes Step-Up
乐视网股权质押违约,东方证券状告贾跃亭兄长
巧妙设计声控电子门铃
苹果iPhone真的无法摆脱刘海么?
负载的电功率有功和无功的区别分析
ADC配合DMA采样规则是怎样的?
多核对嵌入式设计原则造成哪些影响
起因于RTN的SRAM误操作进行观测并模拟的方法
如今正在发生的是“物联网正在吃掉支付”
pcb板的热膨胀系数是什么意思啊?怎么测量出来的?
美日联盟形成 全球自动驾驶标准格局大变
中国机器视觉未来发展趋势及特性