OpenOCD中flash编程算法的实现
如何自己设计一个基于openocd调试架构的芯片下载算法,作为一个嵌入式er, 如果做MCU的开发是必须要了解的,因为各个芯片公司都有自己的芯片,而flash驱动各家有不同,所以往往需要自家的工程师去支持,今天就来介绍下基于OpenOCD的flash编程算法的设计方法~~
本文以riscv的flash算法为例,来说明flash编程算法在openocd中的实现,代码git路径:
https://gitee.com/riscv-mcu/riscv-openocd.git
openocd 源码中flash编程算法的实现是在src/flash下,openocd把编程算法称作flash dirver, 如下driver.c就是各个芯片的flash driver的汇总。
在driver.c中例化自己设计的driver对象, 本次介绍的是GD32VF的flash driver, 注册如下:
driver中的各个方法如下:
做flash driver其实就是要实现erase、protect、write、read、probe、info这几个函数,目前是这样理解,其他函数没看。
flash编程的话主要就是write的实现了,这里看下GD32V的代码,这里的实现它是借助了STM32的驱动写的,所以函数名称有stm32,这个函数里面首先会判断目标设备是否处于halt状态,也就是是否暂停,因为接下来其实是需要debug模块通过JTAG写flash,然后就是配置flash key寄存器,猜测这里的key寄存器和gd32f1的是同一个地址和key值,所以可以直接使用stm32的配置。
果然看数值都能对上。然后就是使能编程PG位,最后就是主要的编程函数,stm32x_write_block:
stm32x_write_block这里面上来会判断以下target是arm的还是riscv, 分别调用是不同的编程函数,这里就是GD公司设置的驱动区分方法,我们直接看stm32x_write_block_riscv:
这个函数上来会开辟一个work_area空间用来存放flash编程函数,这个函数是单独在contrib/loaders/flash/gd32vf103/gd32vf103.c中实现的,这个函数其实很简单,就是一个一个halfword的编程,直到编程到指定的数目,退出,代码如下:
写入一次flash,就等一次bsy位,然后再进行下一次的编程。
接下来,开辟一个空间存放要写入的数据:
接下来就是设置编程函数调用的时候的入参,因为上面的编程函数其实是单独编译成一个代码段,然后在需要编程的时候把这段代码放在work_area中,所以调用时需要设置入参,否则运行出错。
riscv的a0-a4是可以作为函数调用的入参寄存器的,所以在这里设置;
接下来就是一个循环调用target_run_algorithm这个接口,对flash编程了,编程之前就是设置4个入参寄存器的值,然后编程,然后等待bsy完成,继续下一次编程,因为一次编程的数据有限,如果一次没写完那就循环下一次。
target_run_algorithm这个函数就是openocd 提供的编程算法的接口了:
到此,一次编程写入操作流程完成,其他的函数后面再分享~~
喜欢的朋友可以关注公众号,有更多嵌入式软件的分享,也可以私信交流: