Here I go with another question 🙂

How to upload firmware via JTAG to BL702 with some command line tool?
Bouffalo Lab Dev Cube is working pretty nice, but it's GUI-based and not so "developer-friendly".
Was the bflb_mcu_tool supposed to work with openocd?
It seems like it was a backend for Bouffalo Lab Dev Cube
(actually both are written in Python, both support same interfaces and even has same latest version 1.6.8)
but even so I couldn't set it up to succesfully load the firmware.

Under Windows, I tried:

Run openOCD:

C:\Users\jatsekku\Desktop\dev\utils\openocd>openocd.exe -f openocd-usb-sipeed.cfg                                                                                                                                                    
Open On-Chip Debugger 0.11.0 (2021-05-19) [https://github.com/sysprogs/openocd]                                                                                                                                                      
Licensed under GNU GPL v2                                                                                                                                                                                                            
libusb1 09e75e98b4d9ea7909e8837b7a3f00dda4589dc3                                                                                                                                                                                     
For bug reports, read                                                                                                                                                                                                                        
http://openocd.org/doc/doxygen/bugs.html                                                                                                                                                                                     
SiPEED USB-JTAG/TTL Ready for Remote Connections                                                                                                                                                                                     
Info : Listening on port 6666 for tcl connections                                                                                                                                                                                    
Info : Listening on port 4444 for telnet connections                                                                                                                                                                                 
Error: libusb_open() failed with LIBUSB_ERROR_NOT_SUPPORTED                                                                                                                                                                          
Info : clock speed 8000 kHz                                                                                                                                                                                                          
Info : JTAG tap: riscv.cpu tap/device found: 0x20000e05 (mfg: 0x702 (<unknown>), part: 0x0000, ver: 0x2)                                                                                                                             
Info : datacount=1 progbufsize=2                                                                                                                                                                                                     
Info : Disabling abstract command reads from CSRs.                                                                                                                                                                                   
Info : Examined RISC-V core; found 1 harts                                                                                                                                                                                           
Info :  hart 0: XLEN=32, misa=0x40801125                                                                                                                                                                                             
Info : starting gdb server for riscv.cpu.0 on 3333                                                                                                                                                                                   
Info : Listening on port 3333 for gdb connections          

and from Eclipse I invoked "download" action with configuration like this:

make INTERFACE=openocd

In result, openOCD reported:
https://pastebin.com/8m8T2YSz

    Downloading firmware with openocd need too many cmds and the process is complicated, also its speed is very low, so suggests to use uart to download.

      Okay, but openocd (jtag) can manage entering to the bootloader and reseting MCU after programming, which is very handy in case of remote development.

        a month later

        In short, we know of only one working flash loader for 602 and the situation is even more dire for 70[246]. :-(

        I evaluated seven different programs that included a CLI to test BL60[24] specifically, and consulted with experts on the Bouffalo parts. We all three agreed that the "draw an owl" part between generating a .bin and seeing it appear on the device is frustrating and during development, can be a huge time sink (did I move the jumper too soon? Oh, I just debugged the executable that was left in flash because the upload failed?) and needlessly frustrates developers.

        We had all three tried various JTAG tools (on BL602) and knew that none board/software combination (which often included OpenOCD) from the likes of Segger, Sipeed, FT232H, others could successfully write to flash, even when they could halt the processor, introspect registers, RAM, and bus devices, and restart the device.

        Of those seven, only one could be reasonably considered "working" on the the three major OSes. We found blflash from Spacemeowx2 to be the best tool for programming BL602, BL604 on MacOS, Windows, and Linux. We all agreed to center our collective recommendations, like writings, and effort behind that one.

        BLDevCube offers lots of functionality we (I) don't need, but the absence of a command line is a deal-breaker. I'd hope that breaking out the minimal "send argv[1] to the device" main(), using defaults for clock speeds and all those other strange knobs to turn, should be easy to abstract out. Also, DevCube has basic functions broken and I've had the engineering teams stumped for months on that one. At one time, I was able to link my program and shoot it into the 706EVB and run trivial code from RAM that way using GDB. It's from memory and I don't recall if OpenOCD was involved or not.

        We just don't have a working solution for BL706 yet and we're designing a new product that's outgrown the BL604 and needs more GPIO.

        Also, ahem, one direct competitor to the 706-class chip emulates a USB CDC mode in their boot rom and uses DTR and RTS for their equivalent of reset and PIN 8/PIN 28 boot mode and offers a second /dev that's used for JTAG. Power, console, jtag all over the same single commodity cable - they probably don't even need the 24-pin versions. No jumpers. It's pretty sweet...except that it has about the same GPIO cont as the BL604, so that's not really a useful alternative for us anyway.

          18 days later
          12 days later

          Indeed, I had some success in flashing BL702. I'm actively working on that tool in my spare time.
          Important thing to mention is that it's not standalone solution. I still need to use bootinfo.bin generated by bouffalolab tool. I figured out most of bootheader and how to generate it on my own, but I would like to understand it better.

          One thing which wonder me the most at this point is https://github.com/bouffalolab/bl_mcu_sdk/blob/c9a587c430b2036c655cd9708c7ca5fd139f4f64/drivers/bl702_driver/std_drv/src/bl702_sf_cfg.c

          Why there is so many serial flash ICs config there?
          Is it provided to support external memory?
          Which one of silicon design is embeded into BL702?

            I'm also curious how is it possible to load eflasher_image to the BL702 using ... well load_eflasher's commands and protocol?
            What is primarly used to flash BL702?
            Can I brick it if I mess up with it?
            How boot2 is corelated with eflash_loader?_

            So many questions 🙂

              8 days later

              Hi @jatsekku ,

              Why there is so many serial flash ICs config there?
              Is it provided to support external memory?

              Correct.

              I'm also curious how is it possible to load eflasher_image to the BL702 using ... well load_eflasher's commands and protocol?

              When you hold BOOT pin on BL70X, BootROM enables ISP interface. This interface is almost same as eflash_loader one (only less commands, of course, you can't write to flash, since only eflash_loader initializes it), but else it's same.

              Can I brick it if I mess up with it?

              No, the BootROM is of course, Read Only, so whatever you will do, you will still be able to get into BootROM mode and flash eflash_loader, and then write to flash.

              How boot2 is corelated with eflash_loader?

              boot2 is secondary bootloader, and it has nothing to do with eflash_loader at all. boot2 is mostly used with IOT SDK, it's purpose is to manage OTA stuff (A/B firmware switching), loading some things as partition table into RAM before main application runs, can manage encryption etc. This secondary bootloader is optional, when you use bfl_mcu_tool, boot2 is not needed, and your app is directly executed by BootROM.

              > @jatsekku#569 I'm actively working on that tool i

              That's embarrassing. I just offered you a helpful tip on a tool I'd found on the internet...not realizing that it was yours. Sorry. :-)

              In discussions with others on the 18 JEDEC flash types present, the two prevailing theories were that the tables were machine generated from/for related parts and it was just easier to carry them along than to weed them out OR that Bouffalo could potentially be making these chips with the RISC-V/SoC "magic" in one section of the wafer and using Commodity/Off The Shelf flash parts for storage and they wanted the tools to be able to easily handle any potential swap of flash. This theory had some weight because the GD32V parts do something similar and Gigadevice was "A NOR flash company that made some MCUs" instead of being a MCU company and they may want the flexibility to swap flash unceremoniously.

              It is indeed annoying that you can't seem to just squirt one binary but instead have go glue together a couple of programs that you have to carry as resources or something. It opens doors for problems when binary, loader, and these sidecar files get out of sync.lkkfThere is some configuration for things like security keys, clock config, partition information. BL602 stashes Wifi auth, which I suppose isn't needed on 702. Some of the bytes are code to be literally copied and some are synthesized from external bits.

              I'm not sure all the twiddly bits in this area have been documented/reversed, but it's been a while since I've worked in this area. Folks like you, Gamelaster, and Lup have each made big strides, but it seems there are still secrets in this area to reveal.

              I don't know if chip companies work to make this hard or if they just don't consider boot/flash/load/debug as important as other systems to make easy. :-)

              6 days later

              robert That's embarrassing. I just offered you a helpful tip on a tool I'd found on the internet...not realizing that it was yours. Sorry. :-)

              No problem, I'm glad that people can find it, hope it will be usefull in the near future 🙂

              robert I'm not sure all the twiddly bits in this area have been documented/reversed, but it's been a while since I've worked in this area. Folks like you, Gamelaster, and Lup have each made big strides, but it seems there are still secrets in this area to reveal.

              Yeah, I've seen some of it, I really appreciate your work guys!

              Actually, we could set-up some discord server or something like this to exchange our expirience.
              I think this chips are quite big thing, because it's cheap, powerfull in term of classic MCU and RF SoC as well,
              the only drawback at this point is that it's no really ready to be used in mainstream due to it's poor documentation, a bit messy SDK and tools/ecosystem.

              Toogether with my teammates, we are trying to provide flasher for remote development,
              we also started to work on simple eflash protocol analyzer to provide better reverse engineering experience.
              We hope to port OpenThread to these beasts at some point.

              jatsekku @gamelaster is the master of Discord. I defer completely to him. I run warm and cold with it. I don't like the implication of being "on call" and find something block oriented like email (groups.io?) preferable because it makes people take moment to compose a thought and ask a coherent question instead of "ne1 there?" <typing> ya, u? <typing> stuff. But don't let my grumpiness discourage you. :-) There is a reddit /r/bl602, but it has essentially no subscribers; r/riscv seems to have more expertise on tap and a good s:n ratio.

              I like the BL60x chips, but I share your concern about doc, perceived market share (ESP32-C3 has entered the room) and that awful developer experience of screwing with custom up-loaders, being unable to flash from JTAG, and more dirty laundry that I've aired for 2 years. I started a stepping-stone project tonight (need a 32-bit SiFive core...) and chose ESP32-C3 because I can get programming, power, console, and JTAG all from one USB cable and not have to dink with IO8. (Now picking the part was a far as I've gotten, but here we are... I've used idf and their SDK before on other projects and it's pretty sweet.)

              BL702 has mindshare only from SiPeed's JTAG board and BL706 is totally non-existent on even Aliexpress. So that whole product line doesn't seem to be lifting developer mindshare much. There's just not the $[color]Pill level of recognition. As an English (only) speaker, it seems that Lup authored most of the original English literature on these devices. Every bbs, forum, tweet conversation, github trail or whatever else leads back to his work on the Bouffalo line. :-) There aren't articles, tech tips, tweets, or anything else to raise developer footprint that I've seen. I don't know if it's cultural or an an intentional thing (maybe they're amazingly successful inside China) or what, but it does take more than interesting chips to make an interesting chip family of products.

              TIL that OpenThread exists. I knew of its predecessor by name only as it was discussed once inside Google at a tech talk I attended. Good luck with it!

                6 days later

                Hey guys!
                I was a little offtopic, but I would like to ask if someone knows what is goin on here:

                ###[ CheckImage ]### 
                  id        = 0x19
                  rsvd      = 0x0
                  len       = 0
                
                ###[ MemoryWrite ]### 
                  id        = 0x50
                  rsvd      = 0x0
                  len       = 8
                ###[ Raw ]### 
                     load      = '\x00\\xf1\x00@EHBN'
                
                ###[ MemoryWrite ]### 
                  id        = 0x50
                  rsvd      = 0x0
                  len       = 8
                ###[ Raw ]### 
                     load      = '\x04\\xf1\x00@\x00\x00\x01"'
                
                ###[ MemoryWrite ]### 
                  id        = 0x50
                  rsvd      = 0x0
                  len       = 8
                ###[ Raw ]### 
                     load      = '\x18\x00\x00@\x00\x00\x00\x00'
                
                ###[ MemoryWrite ]### 
                  id        = 0x50
                  rsvd      = 0x0
                  len       = 8
                ###[ Raw ]### 
                     load      = '\x18\x00\x00@\x02\x00\x00\x00'
                
                ###[ Handshake ]###
                  id        = 0x55
                  count     = 150

                As you can see some strange MemoryWrite occurs right after CheckImage (after loading eflash_loader).

                At this point I hardcoded that, but I would like to know what is the purpose of that chunk

                    bl_flasher.flash_efloader('chips/bl702/image/eflash_loader/eflash_loader_32m.bin')
                
                    #Unknown operation - these commands are not waiting for response
                    bl_proto.memory_write(b'\x00\xf1\x00\x40\x45\x48\x42\x4e')
                    bl_proto.memory_write(b'\x04\xf1\x00\x40\x00\x00\x01\x22')
                    bl_proto.memory_write(b'\x18\x00\x00\x40\x00\x00\x00\x00')
                    bl_proto.memory_write(b'\x18\x00\x00\x40\x02\x00\x00\x00')
                    time.sleep(0.35)
                
                    bl_proto.handshake()

                  Hi @jatsekku ,
                  this is only for BL70X series, and I think this is errata workaround of BootROM or silicon bug.
                  After translating the commands, it writes to those registers:

                  0x4000F100 0x4E424845 // Setting HBN_RSV0 (Status Flag) to HBN_STATUS_ENTER_FLAG
                  0x4000F104 0x22010000 // Setting HBN_RSV1 (Wake-up Address) to 0x22010000
                  0x40000018 0x00000002 // writes bit reg_ctrl_cpu_reset in swrst_cfg2

                  From my deduction, this uses two unused registers in HBN (Deep sleep control (Hibernate) core), which are persistent even after CPU reset, to know where to jump after reset. If you don't do this, USB Serial CDC will not work on Windows 11 in eflash_loader.

                  #Unknown operation - these commands are not waiting for response

                  This is false. You should wait for the OK response, it sends it. If you will not wait for it, the "OK" responses from the BootROM will be stuck in the RX buffer, and it will confuse your app.

                  BTW. If you will have any other questions, I recommend you to join #nutcracker channel on PINE64 platforms as Matrix, Telegram, Discord or IRC. You can find links here: https://wiki.pine64.org/wiki/Main_Page#Chat_Platforms

                  -gamiee

                  4 months later
                  Write a Reply...
                  @ 2025 Bouffalo Lab (Nanjing) Co., Ltd. All rights reserved.