rst
Posts: 484
Joined: Sat Apr 20, 2013 6:42 pm
Location: Germany

Re: Circle - C++ bare metal environment (with USB)

Sun Sep 15, 2019 8:35 am

To comeback on this once again:
Gavinmc42 wrote:
Thu Sep 12, 2019 1:02 am
Arduino is C++, but I use them to make apps.
There is a difference between using tools and being able to write them.
I see myself more as a baremetal tool user than a tool maker.
That's why some of my ideas are ease of user based, not maker.
It's like driving a car, not making one every time I need to go to the shops ;)
That's OK. I understand your position. There have been attempts for an Arduino integration using Circle. But I think it's not possible to develop and maintain this together with a (basically) one-man-project like Circle without a quality drop. That's why I decided myself against it. So one still need some understanding of classes for writing apps using Circle. ;)
From reading the forum you have now got Circle++ to a level that people can use for their apps.
You deserve a medal.
Thanks. But for a "correct" history I have to note, that there were already remarkable apps in 2015 using Circle. The first that I know of was an emulator for a retro computer from South Korea. In 2016 came a ArtNet-DMX gateway, which was used in real stage performances. In the meantime there are several apps.

rst
Posts: 484
Joined: Sat Apr 20, 2013 6:42 pm
Location: Germany

Re: Circle - C++ bare metal environment (with USB)

Sun Sep 15, 2019 8:45 am

MikeDB wrote:
Sat Sep 14, 2019 9:33 am
I'm aiming for Ethernet, USB & HDMI as Linux only and everything on the 40 pin extender as bare metal.
I forgot to mention, that Circle is able to do Ethernet, USB & HDMI on its own. So maybe Linux is not needed. But of course it depends on what you want to do with it. Linux and Circle together is probably not a good idea, because the startup procedure of Circle does not fit into Linux and Circle wants to take over the interrupt system and memory management for any application, which makes sense.

User avatar
MikeDB
Posts: 313
Joined: Sun Oct 12, 2014 8:27 am

Re: Circle - C++ bare metal environment (with USB)

Sun Sep 15, 2019 10:48 am

rst wrote:
Sun Sep 15, 2019 8:45 am
MikeDB wrote:
Sat Sep 14, 2019 9:33 am
I'm aiming for Ethernet, USB & HDMI as Linux only and everything on the 40 pin extender as bare metal.
I forgot to mention, that Circle is able to do Ethernet, USB & HDMI on its own. So maybe Linux is not needed. But of course it depends on what you want to do with it. Linux and Circle together is probably not a good idea, because the startup procedure of Circle does not fit into Linux and Circle wants to take over the interrupt system and memory management for any application, which makes sense.
Yes that's moreorless where I got to yesterday :-)

It's a live audio project so I need proper real-time (not pseudo-real time using large DMA buffers like ALSA) and Circle seemed to be one of the few with decent I2S drivers I could use as a base rather than a 'to be implemented' notice. But Linux gives me WiFi, USB, etc in a hassle free way. So maybe I need to just use some of the drivers from Circle without actually using Circle itself.

Altertnatively I may use a Pi Zero W for Linux and Pi4 for the audio using Circle and connect the two with SPI which would double the audio DSP available.

rst
Posts: 484
Joined: Sat Apr 20, 2013 6:42 pm
Location: Germany

Re: Circle - C++ bare metal environment (with USB)

Sun Sep 15, 2019 3:12 pm

MikeDB wrote:
Sun Sep 15, 2019 10:48 am
It's a live audio project so I need proper real-time (not pseudo-real time using large DMA buffers like ALSA) and Circle seemed to be one of the few with decent I2S drivers I could use as a base rather than a 'to be implemented' notice. But Linux gives me WiFi, USB, etc in a hassle free way. So maybe I need to just use some of the drivers from Circle without actually using Circle itself.
I heard more than once, that the audio latency in Linux was the reason to try Circle. Unfortunately I cannot offer WiFi and yes, USB in Circle has not the features and quality of the Linux drivers. The I2S driver model in Circle is relatively simple. There are two concatenated DMA buffers of configurable size, one is filled by the the application, while the other is written out to the I2S device. I guess, it's possible to adapt this in Linux.
Altertnatively I may use a Pi Zero W for Linux and Pi4 for the audio using Circle and connect the two with SPI which would double the audio DSP available.
If you are familiar with NEON programming, you will get much processing power. I programmed a virtual analog synthesizer with Circle by myself, which supports 24 polyphonic voices (6 per core), but without explicit NEON programming and probably not in a very efficient way. I heard others have reached over 100 voices.

User avatar
MikeDB
Posts: 313
Joined: Sun Oct 12, 2014 8:27 am

Re: Circle - C++ bare metal environment (with USB)

Sun Sep 15, 2019 6:05 pm

rst wrote:
Sun Sep 15, 2019 3:12 pm
If you are familiar with NEON programming, you will get much processing power. I programmed a virtual analog synthesizer with Circle by myself, which supports 24 polyphonic voices (6 per core), but without explicit NEON programming and probably not in a very efficient way. I heard others have reached over 100 voices.
Interesting idea - I'll take a look at that.

User avatar
MikeDB
Posts: 313
Joined: Sun Oct 12, 2014 8:27 am

Re: Circle - C++ bare metal environment (with USB)

Mon Sep 16, 2019 10:35 am

MikeDB wrote:
Sun Sep 15, 2019 6:05 pm
rst wrote:
Sun Sep 15, 2019 3:12 pm
If you are familiar with NEON programming, you will get much processing power. I programmed a virtual analog synthesizer with Circle by myself, which supports 24 polyphonic voices (6 per core), but without explicit NEON programming and probably not in a very efficient way. I heard others have reached over 100 voices.
Interesting idea - I'll take a look at that.
Okay I had a look. Unlike Intel, it's only 128 bits so you can only do two 64 bit integer operations per cycle, and there's an overhead in moving from normal registers to the NEON ones and back. And with constantly changing multiply coefficients having to come from the main processor I suspect it won't help in the central DSP funtion, but there may be tasks I can offload to it.

rst
Posts: 484
Joined: Sat Apr 20, 2013 6:42 pm
Location: Germany

Re: Circle - C++ bare metal environment (with USB)

Mon Sep 16, 2019 11:02 am

MikeDB wrote:
Mon Sep 16, 2019 10:35 am
Okay I had a look. Unlike Intel, it's only 128 bits so you can only do two 64 bit integer operations per cycle, and there's an overhead in moving from normal registers to the NEON ones and back. And with constantly changing multiply coefficients having to come from the main processor I suspect it won't help in the central DSP funtion, but there may be tasks I can offload to it.
OK. Good to know.

kryptonaut
Posts: 3
Joined: Fri Nov 01, 2019 2:13 pm

Re: Circle - C++ bare metal environment (with USB)

Fri Nov 01, 2019 2:38 pm

Hi - I've been developing with Circle for a few months now. First off, thank you so much for providing this fantastic library! The sample projects are a great starting point, and there is clearly so much work that's gone into creating Circle.

Now, the problem. I apologise if this is the wrong forum for this, but it seemed a good place to get in contact.

I have a fairly large project, and all of a sudden I found that adding member variables to my main class was causing a 'stackdump' crash on bootup. The nature of the crash varied depending on where in my class definition I added the variable, which pointed to a memory overwrite issue. Luckily my project included a display device so I could add some debug output, and it appeared that the crash was happening in kernel.cpp within m_Logger.Initialize when it called CMachineInfo::GetMachineName

Further digging revealed that the m_MachineModel variable was being overwritten during the initialisation of one of my member variables, and on investigating this I discovered that the 'this' pointer of my member variable (which was declared as a regular object, not using 'new') overlapped the s_pThis value in machineinfo.cpp - that is to say the two objects were sharing the same memory location. Initialising my object was messing up the data in the MachineInfo object.

I discovered where the single CMachineInfo object was created in sysinit.cpp - but unfortunately I don't have a clear understanding of how the memory allocation and initialisation works. However, moving the definition of the MachineInfo object to the end of the file, outside the sysinit() function, seemed to resolve the problem. At least the CMachineInfo::s_pThis now contains a much lower address which does not clash with my object.

Can you confirm whether this solution seems reasonable?

Sorry for the complicated explanation, but I wanted to give as much info as possible!

rst
Posts: 484
Joined: Sat Apr 20, 2013 6:42 pm
Location: Germany

Re: Circle - C++ bare metal environment (with USB)

Fri Nov 01, 2019 8:25 pm

@kryptonaut Thanks for using and appreciating Circle.

The problem, you have described, seems to be a strange one to me and I guess, the solution to define the CMachineInfo object in lib/sysinit.cpp static (outside of a function) does only work by luck.

Unfortunately it's difficult to imagine, what happens there. Is it possible to provide some (maybe reduced) version of your source code, which shows this problem, so that I can have a look at it and maybe debug it? You can also write a personal Email to me, if you want. My Email address is noted in the header of most Circle source code files.

kryptonaut
Posts: 3
Joined: Fri Nov 01, 2019 2:13 pm

Re: Circle - C++ bare metal environment (with USB)

Sat Nov 02, 2019 11:29 am

@rst Thanks for your reply - I will try to create a simple demonstration of the issue and then I'll get in touch by email.

kryptonaut
Posts: 3
Joined: Fri Nov 01, 2019 2:13 pm

Re: Circle - C++ bare metal environment (with USB)

Mon Nov 04, 2019 4:14 pm

For the record, the bug of course turned out to be my fault - I should have been doing a 'make clean' when changing my header file. Doing a simple 'make' resulted in the kernel having an incorrect size for my class definition, which was the reason for memory being overwritten.

Many thanks to Rene for the quick response pointing this out to me.

styro
Posts: 8
Joined: Tue Nov 10, 2015 8:37 pm

Re: Circle - C++ bare metal environment (with USB)

Mon Nov 18, 2019 9:18 pm

Hello,
As i mentioned in an other post i am porting the PreenFM2-Synth to baremetal RaspberryPi with the Circle-Framework,
and so far it seems to work! its really ugly but if anybody wants to try it out: https://github.com/styro2000/RasPreenFM2/

Now am am trying to optimize things to get an better latency and was lowering the CHUNKSIZE to 32 @ 48k for the CI2SSoundBaseDevice and then it seems that the GetChunk doesent get called anymore... What could be the problem?
CHUNKSIZE 64 @ 96k works great for low latency but uses unnecessary power.

Anyway, many thanks for this great Framework!
btw I have the impression that many users of Circle are interested in synthesizerstuff, perhaps it would be nice to have
a sort of meetingpoint.

pik33
Posts: 195
Joined: Thu Sep 10, 2015 4:26 pm

Re: Circle - C++ bare metal environment (with USB)

Tue Nov 19, 2019 7:35 am

styro wrote:
Mon Nov 18, 2019 9:18 pm
Hello,
As i mentioned in an other post i am porting the PreenFM2-Synth to baremetal RaspberryPi with the Circle-Framework,
and so far it seems to work! its really ugly but if anybody wants to try it out: https://github.com/styro2000/RasPreenFM2/

Now am am trying to optimize things to get an better latency and was lowering the CHUNKSIZE to 32 @ 48k for the CI2SSoundBaseDevice and then it seems that the GetChunk doesent get called anymore... What could be the problem?
CHUNKSIZE 64 @ 96k works great for low latency but uses unnecessary power.

Anyway, many thanks for this great Framework!
btw I have the impression that many users of Circle are interested in synthesizerstuff, perhaps it would be nice to have
a sort of meetingpoint.
I am not using (yet) the Circle but it seems to be only baremetal environment running on RPi4, so... if there will be no Ultibo for RPi4 in a near future, maybe I will start to use it - I am interested in audio synthesis using baremetal RPi and RPi 3 is too slow for the thing I started some time ago on PC: https://github.com/pik33/20180824-retro-fm.

For bare metal RPi3 programming I use Ultibo which has no audio driver so I had to write one. The driver is simple enough to be converted to C/C++ and has no dependencies so it can be used outside of Ultibo environment. The source is here: https://github.com/pik33/SimpleAudio
This driver uses 8-bit PWM at 960 kHz sample rate and it has a noise shaper, which gives very good audio quality. The sample rate can be seet freely (quantized, 250 MHz divided by a const) from 8 to 960 kHz
This is low latency driver: as it uses simplified DMA, the maximum buffer length for 44100 Hz sample rate is 384 samples which is about 8 ms of audio data

rst
Posts: 484
Joined: Sat Apr 20, 2013 6:42 pm
Location: Germany

Re: Circle - C++ bare metal environment (with USB)

Tue Nov 19, 2019 9:08 am

Thanks, @styro! Good to see you are making progress with your PreenFM2-Synth port.

I did not test CI2SSoundBaseDevice with that small chunk sizes, but I guess, if you want to use a chunk size of 32 for small latency, you have to decrease the "TX Request Level" in the "DREQ_A" register of the PCM / I2S block like that:

Code: Select all

diff --git a/lib/i2ssoundbasedevice.cpp b/lib/i2ssoundbasedevice.cpp
index 75114ae..43bc78a 100644
--- a/lib/i2ssoundbasedevice.cpp
+++ b/lib/i2ssoundbasedevice.cpp
@@ -71,6 +71,9 @@
 #define TXC_A_CH2POS__SHIFT	4
 #define TXC_A_CH2WID__SHIFT	0
 
+#define DREQ_A_TX__SHIFT	8
+#define DREQ_A_TX__MASK		(0x7F << 8)
+
 //
 // DMA controller
 //
@@ -263,6 +266,8 @@ boolean CI2SSoundBaseDevice::Start (void)
 
 	// enable I2S DMA operation
 	PeripheralEntry ();
+	write32 (ARM_PCM_DREQ_A,   (read32 (ARM_PCM_DREQ_A) & ~DREQ_A_TX__MASK)
+				 | (0x18 << DREQ_A_TX__SHIFT));
 	write32 (ARM_PCM_CS_A, read32 (ARM_PCM_CS_A) | CS_A_DMAEN);
 	PeripheralExit ();
 
See page 134 of this document for a description of the "DREQ_A" register.

I think, the current meeting point for Circle stuff is in this forum. The message frequency has been relatively low so far, so I'm not sure, if a separate discussion platform does make sense.

BTW. Circle issues should be reported here.

styro
Posts: 8
Joined: Tue Nov 10, 2015 8:37 pm

Re: Circle - C++ bare metal environment (with USB)

Tue Nov 19, 2019 7:00 pm

Hallo rst!
Many thanks, it worked, CHUNKSIZE 32 @ 48kHz!
the calculation of 8Voices with 6 Operators take about 47uS and so it seems that there are even some cycles left for more fun stuff! :-)

Many thanks for Your Work & Help!
all the best
styro2000

rst
Posts: 484
Joined: Sat Apr 20, 2013 6:42 pm
Location: Germany

Re: Circle - C++ bare metal environment (with USB)

Fri Nov 22, 2019 7:54 pm

styro wrote:
Tue Nov 19, 2019 7:00 pm
Many thanks, it worked, CHUNKSIZE 32 @ 48kHz!
the calculation of 8Voices with 6 Operators take about 47uS and so it seems that there are even some cycles left for more fun stuff! :-)
Sounds good. :) I have updated the "develop" branch, so that chunk size 32 will work with the next Circle release without patching. Thanks for testing and info!

dpotop
Posts: 86
Joined: Mon Nov 24, 2014 2:14 pm

RPi4 and USB3 performance questions

Mon Dec 09, 2019 10:57 am

Hello,

I'm considering interfacing with a high-speed device in bare metal on the RPi4.
Circle seems to be the only bare metal library currently doing RPi4 and USB.
However, I'd need more than that (and of course I'm quite willing to
program it). I'd like to have your opinion on the feasibility of this project, and
more specifically:
- Does Circle already support USB3 on the RPi4?
- Can it be configured to provide high transfer speeds?

Best,
Dpotop
dpotop

rst
Posts: 484
Joined: Sat Apr 20, 2013 6:42 pm
Location: Germany

Re: Circle - C++ bare metal environment (with USB)

Mon Dec 09, 2019 12:02 pm

@dpotop Yes, Circle does support USB 3.0 on the RPi 4, but this is not an optimized high-speed driver. Its transfer rate is not comparable with that of the Linux driver. Also USB 3.0 hubs are currently not supported.

rdpdo
Posts: 7
Joined: Tue Oct 29, 2019 8:38 pm

Re: Circle - C++ bare metal environment (with USB)

Fri Dec 13, 2019 5:57 pm

Hello All,

I am using circle for few week now and it is really great ! Thanks you VERY MUCH for it ! And the examples are excellent too.

I just got some interrupt disturb. (it IS the ONLY reason why I was not able to use linux) when initialize SD-CARD acces (but with linux even when I was not using SD-CARD I was getting disturb ) at the kernel constructor so I needed to initialize it only when needed, after my real-time measurements (for storing data).

Now I would like to use the 2Gbyte of my raspberry to extend my measurement data acquisition.

Does someone here have extended the memory acces on raspberry pi 4 to 2GBytes or more ?

I am thinking of modifying code in the malloc function, do you think it is a good start ?

Thanks for your help and THANKS YOU again !

rst
Posts: 484
Joined: Sat Apr 20, 2013 6:42 pm
Location: Germany

Re: Circle - C++ bare metal environment (with USB)

Sat Dec 14, 2019 12:32 pm

@rdpdo Thanks! High memory above 1 GByte is currently not supported in Circle and is planned for a future version. If you want to use it in spite of it, you have to consider the following:
  • The MMU page table initializes the high memory as "device memory" (not cached) at the moment. To get full speed access this has to be modified to "normal memory".
  • There may be hardware devices, which do not support physical addresses above 1 GByte for direct memory access. I have seen some bounce buffering mechanism in some Linux drivers, which handles this. This is not implemented in the Circle drivers yet. So it's not clear, if you can use a buffer in high memory for instance as socket buffer or for a USB transfer.

dpotop
Posts: 86
Joined: Mon Nov 24, 2014 2:14 pm

Re: Circle - C++ bare metal environment (with USB)

Sun Dec 15, 2019 2:48 pm

Hello,

First of all, I'd like to thank all contributors for this library. It's the first time I look into it, and it looks very clean. I even pushed optimization to -O3 and the code still works!

I'm considering using it as a basis for my future bare metal work (I'm currently re-coding everything starting from code in other libraries). What still holds me back is my lack of experience with C++ on bare metal (constructors, destructors, etc.), and the lack of support for more complex MMU configuration, which I need (and, of course, an urge to control everything, but I guess all bare metal programmers are a bit like this). Is there some way I could educate myself on C++ on bare metal? The MMU code I could contribute, if someone wants it...

That said, I have two questions concerning the USB driver, which I'm currently trying to use as such.
1. What kind of max throughput I should expect on a RPi3B+ and on a RPi4 ? Someone told me this is not a high-perf driver. Can you explain me why, and what would be needed to make it so?
2. I try to reduce the amount of code around the USB driver, in order to incorporate it. Is it correct to say that the driver is event-driven (as opposed to sampling the device on a fixed period)? And that everything happens on the IRQ interrupt (as opposed to FIQ)?

Best regards,
Dpotop
dpotop

rst
Posts: 484
Joined: Sat Apr 20, 2013 6:42 pm
Location: Germany

Re: Circle - C++ bare metal environment (with USB)

Mon Dec 16, 2019 7:40 am

dpotop wrote:
Sun Dec 15, 2019 2:48 pm
That said, I have two questions concerning the USB driver, which I'm currently trying to use as such.
1. What kind of max throughput I should expect on a RPi3B+ and on a RPi4 ? Someone told me this is not a high-perf driver. Can you explain me why, and what would be needed to make it so?
2. I try to reduce the amount of code around the USB driver, in order to incorporate it. Is it correct to say that the driver is event-driven (as opposed to sampling the device on a fixed period)? And that everything happens on the IRQ interrupt (as opposed to FIQ)?
  1. I think, this is only of importance for USB mass-storage devices. I did not make measurements on that, but I suppose one won't get a transfer rate of more than some MBytes/s. The xHCI driver does handle only one Transfer Request Block (TRB) at a time. One has to use multiple TRBs to speed it up. This would cause a different driver design. The Linux xHCI driver has 5 times the number of source code lines compared to the Circle driver.
  2. Yes, the Circle driver is event-driven and uses the IRQ.

kawa-yoiko
Posts: 6
Joined: Wed Dec 04, 2019 2:42 am

Re: Circle - C++ bare metal environment (with USB)

Mon Dec 16, 2019 5:30 pm

dpotop wrote:
Sun Dec 15, 2019 2:48 pm
Is there some way I could educate myself on C++ on bare metal?
Many language features come without manual work — ctors/dtors are called automatically for variables on function entry/exit and new/delete, templates are expanded into plain functions etc. The major parts differing from C care are global constructors, the "new" operator, and library linkage, and Circle itself can be a great educational source for these. Circle's sysinit.cpp and circle.ld (look at symbols __init_start and __init_end that mark global constructors), new.cpp, and Rules.mk handle these things respectively, and are quite easy to follow. (Hopefully I have not left something out :))

Btw, maybe take a look at USPi if you are incorporating the USB driver only.

rst
Posts: 484
Joined: Sat Apr 20, 2013 6:42 pm
Location: Germany

Re: Circle - C++ bare metal environment (with USB)

Thu Feb 06, 2020 2:52 pm

rdpdo wrote:
Fri Dec 13, 2019 5:57 pm
Now I would like to use the 2Gbyte of my raspberry to extend my measurement data acquisition.

Does someone here have extended the memory acces on raspberry pi 4 to 2GBytes or more ?
There is a new release of Circle available, which supports using the (extended) high memory over 1 GB on the Raspberry Pi 4, like that:

Code: Select all

#include <circle/new.h>

unsigned char *p = new (HEAP_HIGH) unsigned char[1024];
With HEAP_ANY given instead, both memory regions (high or low) will be used for allocation. If the system option HEAP_DEFAULT_NEW is defined as HEAP_ANY, this can also be set as the default allocation method (if no HEAP_* selector is given).

blippy
Posts: 72
Joined: Fri Nov 03, 2017 3:07 pm

Re: Circle - C++ bare metal environment (with USB)

Sun Feb 23, 2020 4:08 pm

QEMU?

I compiled compiled the 03-screentext example from Circle. My Rules.mk reads as follows:

Code: Select all

AARCH    ?= 32
RASPPI   ?= 2
PREFIX   ?= arm-none-eabi-
PREFIX64 ?= aarch64-none-elf-
I build the project, transfer it to a SD card, boot, and it works!

Now I'm trying to get it to work via qemu. I did fallocate to create a disk, and formatted it:

Code: Select all

file circle.fs
circle.fs: DOS/MBR boot sector, code offset 0x3c+2, OEM-ID "mkfs.fat", sectors/cluster 4, reserved sectors 4, root entries 512, Media descriptor 0xf8, sectors/FAT 68, sectors/track 32, heads 64, sectors 69632 (volumes > 32 MB), serial number 0x5d3c1921, unlabeled, FAT (16 bit)
I add all the files that I have for the SD card. I launch qemu via the command line:

Code: Select all

qemu-system-arm -M raspi2 -cpu cortex-a7 -m 256M -drive file=circle.fs,if=sd,format=raw -kernel circle.fs
QEMU launches, but the output screen is blank. I'm expecting it to print stuff to the window, but I don't see anything. I've tried a variety of settings, but to no avail.

Can anyone suggest what's going wrong?

Return to “Bare metal, Assembly language”