Posts

Blackmagic + gdbgui

Image
 Sometimes it really helps to have a nice GUI for GDB Finding an IDE that supports *correctly* remote gdb debugging as used with Arm or RiscV boards is difficult. There is one option that seems to work ok :  gdbgui The principle is that the UI is actually your favorite browser How to start it easily with the backmagic ? 1- create a blackmagic gdb init script target extended-remote /dev/ttyBmpGdb monitor connect_srst enable monitor swdp_scan attach 1 load compare-sections set mem inaccessible-by-default off set confirm off 2- start gdbgui through a small shell script #!/bin/bash export F=$PWD/$@ echo "Loading $F" gdbgui -g "/home/fx/Arduino_stm32/arm-gcc-2020q4/bin/arm-none-eabi-gdb-py3 -x /home/fx/blackmagic.gdb ${F}" (you'll need to adapt those 2 scripts for your configuration : path to gdb, path to blackmagic.gdb, device to use etc...) then bash ~/gdbgui.sh myelf.elf and it starts.  A small warning, i have to go to the output panel and press enter or else it...

GD32F1, GD32VF103 why should i bother ?

Image
It's not secret, i rather like the GD32xx chips. They work fine, the doc is ok (not great but ok) and they have a riscv based one that works very well. So i started writing lnArduino, i.e. running an Arduino style API on the riscv GD32VF103 chip as found on the Longan Nano. And then i wondered : Why should i care if it is an arm core or a riscv core ? The peripherals are mostly the same between the GD32F1/F3 and the GD32VF1 So i started adding support for Arm core (only GD32F1, GD32F3, and to some extend STM32F1) It is surprisingly simple to do, once you get through the base ones (boot, interrupts, freeRTOS) that are nasty. So for the features that are done, i can build the *same* code on a longan nano and on bluepill with a GD32F1 chip.  Only one line to change to select the MCU/Architecture in the CMakelist and that's it. "But i can do that with the Arduino API" you might think Sure thing, but you dont have the code & drivers written with FreeRTOS available out ...

Longan nano simple signal generator : Demo

Image
It's just a toy but it works : sine, triangle, square from 10 hz to 100 khz The aim is mainly to use the lnArduino framework and makes sure it works (it does!) Youtube demo   Source code : https://github.com/mean00/longan_nano_signal_generator

Longan Nano : Making a simple signal generator

Image
  The Goal here is to make a simple signal generator with the longan nano. We'll just add a rotary encoder and that's it. It must be able to output sine, square and triangle sine up to ~ 100 kHz. So first thing first : How ? Using the internal DAC(s) to generate the signal. Let's have a look at it. DAC The  dual DAC is a 8Bits/12 bits digital to analog converter connected to PA4/PA5.  It seems the pins used are hardwired and cannot be changed. That could be a problem as they are shared with 2 SPI0 signals, connected to the screen. The DAC will do a conversion each time a trigger event happens. That event can either be software (i.e. you write a register) or a timer. A DMA can be scheduled using said timer too. What does it mean for us ? It means we prepare the data to send, a sine wave for example in a buffer, setup a DMA transfer and program the timer so that a new sample is sent to the DAC at the proper time. Each time the timer rolls over, the DMA will send the next sa...

Longan nano : a new gcc weird behaviour

Image
  This is a known quirk of recent compiler.  It began with Arm, then appeared in apple llvm and now everywhere. Can you see the error in the following code ? (answer at the end [1]) bool        myMcp23017::dumpRegisters() { uint8_t reg=0; for(int i=0;i<27;i++)    Logger("Reg 0x%x : 0x%x\n  ",i,reg); } The usual bug is there is a crash at returns because the return address is mixed-up. On riscV, the generated code is as follows : Dump of assembler code for function _ZN10myMcp2301713dumpRegistersEv: 0x08007f3e <+0>:     addi    sp,sp,-16 0x08007f40 <+2>:     sw      ra,12(sp) 0x08007f42 <+4>:     sw      s0,8(sp) 0x08007f44 <+6>:     sw      s1,4(sp) 0x08007f46 <+8>:     sw      s2,0(sp) 0x08007f48 <+10>:    li      s2,0 0x08007f4a <+12...

Longan Nano : FreeRTOS Thread support within GDB

Image
  This is a common need: Be able to see and navigate among threads from gdb. There are 2 ways to do that : It is built-in at  low level. That means either inside gdb or openOcd or blackmagic probe etc.... Using external scripts One gotcha to make things more difficult : Depending on the FreeRTOS port, the way the registers are pushed on the stack differs and may confuse gdb. As far as option 1 is concerned,  i did not manage to make it work with riscv-openOCD, in addition i'm pretty sure the FreeRTOS port i'm using will cause problem So let's go for option 2. GDB Python support  We'll use some python3 scripts within gdb to deal with thread awareness In order to do that, we'll need a python3 enabled riscv gdb Let's download the vanilla gdb 10.2 from gnu.org  (*not* the riscv version) and configure it that way export PATH=/opt/gd32/toolchain/bin/:$PATH echo /usr/bin/python3-config --includes echo /usr/bin/python3-config --libs export PYVER=3.8 export LIBS=`/usr...

Longan Nano : I2C Master

Image
 After SPI, serial and Gpio, the next building block is I2C/Master. That one is a bit peculiar. Overview/DMA It is actually a finite state machine.  Each transition of a I2C transmission is associated with  an event, with a corresponding "event" interrupt. The sequence is StartSent-AddressSent-DataDataData-BTC-Stop Simple enough. Where it becomes tricky is when you want to use DMA with it. You have to manage two interrupts source in parallel. It ends up as  :  1- Do the beginning as usual, using  plain I2C interrupt events. 2- When reaching the "data" stage, start a DMA transfer + disable I2C event interrupt (we trigger the DMA transfer only if the # of data is > 2, else we do it using basic interrupts) 3- When the DMA stage is done, re-enable the I2C event interrupts  to finish the transfer To give an example:  to refresh the SSD1306 screen in one step (1024 bytes), we only need ~ 6 interrupts ( 5 I2C + 1 DMA) rather than ~ 1030 interrupts in ...