Doug Howard
Posts: 9
Joined: Mon Feb 27, 2017 12:18 pm

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

Tue Jul 18, 2017 11:47 pm

I searched for"BCM2837 PWM"
What pins can be used on a RPI3 for PWM? Why is this so had to fine?
I would like to flash more than one LED.
thanks in advance,
Doug Howard

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

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

Tue Aug 15, 2017 7:58 pm

Doug Howard wrote: I searched for"BCM2837 PWM"
What pins can be used on a RPI3 for PWM? Why is this so had to fine?
I would like to flash more than one LED.
thanks in advance,
Doug Howard
Have a look at sample/13-pwmoutput. This sample program drives two LEDs at GPIO 18 and 19 (BCM numbering) using hardware PWM. Circle supports these two channels on the RPi 3 for PWM output. The PWM interface has not changed since BCM2835.

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

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

Wed Sep 27, 2017 6:22 am

Because it was speculated about the network capabilities of Circle in another topic, I want to inform about this.

Circle has a TCP/IP network stack which was written from scratch in C++. It implements the following protocols: ARP, IP, ICMP, UDP, TCP, DHCP, DNS, HTTP, TFTP, NTP. The application interface is a self defined C++ interface. Basic connection and transfer functions are oriented on the BSD socket interface also known from Linux.

Circle networking does work with the internal SMSC951x Ethernet NIC only. The USB driver for this NIC supports the basic transfer functions "send frame" and "receive frame".

Because some protocol implementations are partial and Circle has not the audience for testing like other systems, I call this implementation as experimental. Nevertheless there is an application of Circle networking for stage light environments (UDP-based ArtNet) which seems to work well.

Vanfanel
Posts: 419
Joined: Sat Aug 18, 2012 5:58 pm

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

Wed Oct 04, 2017 11:03 pm

SDL2 running on Circle would be AWESOME. Or libretro/retroarch.
Just imagine all the software automatically available as baremetal by porting those!!

@rst: after how FAR you have taken this enviroment, have you thought about adding a simple commanline interface (single-process of course) where one could build and run Circle projects on Circle itself?

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

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

Thu Oct 05, 2017 1:12 pm

Vanfanel wrote: have you thought about adding a simple commanline interface (single-process of course) where one could build and run Circle projects on Circle itself?
Honestly not. This would require to run a C++ compiler on Circle and would blow it up very much. I prefer Circle being a lightweight system, relatively easy to be understood. A console class with a command line editor may come, but only to be used inside user applications.
SDL2 running on Circle would be AWESOME. Or libretro/retroarch.
Just imagine all the software automatically available as baremetal by porting those!!
Would be awesome, but probably a huge task! ;)

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

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

Wed Mar 21, 2018 9:40 pm

Support for the new Raspberry Pi 3 Model B+ has been added to Circle at the develop branch on GitHub including a driver for the LAN7800 Gigabit Ethernet device. I did some tests with several sample programs and everything seems to work well.

msx80
Posts: 10
Joined: Sun Feb 11, 2018 4:36 am

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

Fri Apr 13, 2018 2:05 pm

Hi, just discovered this project, looks awesome! Thanks for mantaining it! I'm looking forward to try it this weekend on my RPI Zero
I was wondering about graphics performances.. Has anybody tested how fast you can draw the screen? Like, how many FPS could we reasonably get with some simple 2d graphics?

I've peeked into the CScreenDevice class but it looks like the only available primitive is SetPixel.Is there some other class that support blitting of images or such?

Also, if i understood correctly, the screen class uses the framebuffer facility, is this the fastest way to get graphics on the screen?

Thanks

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

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

Fri Apr 13, 2018 4:09 pm

Hi, thanks for being interested in Circle. Circle does not support accelerated graphics using the GPU. I know of the Circle-based ZX Spectrum emulator ZXBaremulator, which reaches at least 50 to 60 FPS with a PAL screen resolution, while doing sound at the same time. So for retro graphics it can be a choice.

The default CScreenDevice class is mainly intended for writing text to the screen. Other screen classes are not available yet, but you can use the CBcmFrameBuffer class to easily initialise the frame buffer hardware to be used in your own class. There is also a port of the µGUI module.

EDIT: Screen size was wrong.

msx80
Posts: 10
Joined: Sun Feb 11, 2018 4:36 am

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

Sun Apr 15, 2018 5:08 pm

Indeed i'm interested in some retro graphics :) Tested circle finally, works great even on a Zero :) I tried to use a low resolution, like 320x240 or something similar but it wouldn't work. i changed the screen and framebuffer classes but seems like such resolutions are not supported (640x480 is the smallest reported by tvservice). I wasn't able to use virtual screen resolution for some reasons.
It's a pity not being possible to use such res as upscaling complicates drawing on the screen and wastes time. I wonder how the spectrum emulator does it? (is it closed source iiuc)

Also, switching the sd card in and out for each test is terrible :P any chance we'll see wifi working? i know it's probably much harder than ethernet..

Anyway, great project!

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

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

Sun Apr 15, 2018 7:45 pm

You can use a resolution of 320x240, if you directly choose it in the constructor of CKernel in kernel.cpp of any sample:

Code: Select all

CKernel::CKernel (void)
:	m_Screen (320, 240),
...

It does not work with the cmdline.txt settings, because there are some checks in CKernelOptions, which do not allow a resolution below 640x480. Even if the display does not support these smaller sizes, the firmware is able to upscale it. The Spectrum emulator has its own screen management class based on CBcmFrameBuffer and selects a resolution of 720x576 AFAIK, because it is able to show the border areas of the screen as the original Spectrum was doing. I think, the source of it is still not available because of some rumours about other planned commercial Spectrum emulators, but the author promised me, it will be available later.

There will be serial bootloader support soon in Circle. If you have an USB serial adapter, you can simply do "make flash" in your project's directory and the kernel image will automatically be build, downloaded and started on your Raspberry Pi. With a serial baud rate of about 1 Mbps this works reasonable quick.

WiFi support is unfortunately not in sight. I know, it would be great to have it, but if it would be easy, I had already done it. :)

Thanks!

msx80
Posts: 10
Joined: Sun Feb 11, 2018 4:36 am

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

Tue Apr 17, 2018 11:58 am

ok tested again and was able to make it run at 320x240! I noticed the constraints the first time around but probably made some mistakes (i'm not good with C/C++ ).
A serial bootloader would be awesome, and i'm sure i have some ftdi board or something laying around. Looking forward to try it!

I also gave a try on integrating lua, i couldn't make it run but made some progress :P I crosscompiled lua successfully but the linker gives me some errors, even if i use circle-stdlib. I guess there's some mismatch in the standard library. I'll give another try later

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

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

Tue Apr 17, 2018 3:26 pm

Great, that it's working now. The serial bootloader can be already tested, if you checkout the develop branch. We have used Dwelch67's bootloader. Have a look into the file doc/eclipse-support.txt for infos on how to use it with Circle. It can be used with or without the Eclipse IDE.

Running Lua on Circle would be awesome. If the linker errors remain, we need to know to names of the affected symbols. The standard library support for Circle is relatively new and there may be issues with the circle-stdlib project or with Circle itself. Please note that the order of the libraries given to the linker sometimes causes such problems.

msx80
Posts: 10
Joined: Sun Feb 11, 2018 4:36 am

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

Tue Apr 17, 2018 5:12 pm

Yeah, running Lua would be awesome. I'm interested in retrocoding and fantasy consoles (like TIC-80 or Pico 8). A PI zero would be an awesome platform to make a physical retro computer. With graphics, sound, gamepads, keyboards etc, already supported, it wouldn't need much more. Lua would be a great language for it. Also, i think it's one of the simplest, lightest environment to port around.

Anyway, for compiling it, first i hacked the Makefile to use the the arm toolkit and added some switches copied from circle (-march=armv6k -mtune=arm1176jzf-s -marm -mfpu=vfp -mfloat-abi=hard -fsigned-char). I ended up with the following errors.

Code: Select all

/home/nicola/gcc-arm-none-eabi-6-2017-q1-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/hard/libc.a(lib_a-exit.o): In function `exit':
exit.c:(.text.exit+0x2c): undefined reference to `_exit'
/home/nicola/gcc-arm-none-eabi-6-2017-q1-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/hard/libc.a(lib_a-abort.o): In function `abort':
abort.c:(.text.abort+0x10): undefined reference to `_exit'
....
....
Googling around, i found someone on stackoverflow suggesting to add "-specs=nosys.specs". I tried blindly as i have no idea what it means, so copypasted like the worst of programmers and the errors actually went away.
So now i have liblua.a which is the thing to link.
On a circle-stdlib sample i added:

Code: Select all

#define LUA_32BITS
#include "lua-5.3.4/src/lua.hpp"
and a couple of line to initialize a Lua state. Then i added liblua.a in the Makefile and ran make. The code compiles but the linker breaks, this is the final output i have:

Code: Select all

[nicola@hal testlua]$ make
arm-none-eabi-ld -o kernel.elf -Map kernel.map -T ../../libs/circle/circle.ld ../../libs/circle/lib/startup.o main.o kernel.o /home/nicola/gcc-arm-none-eabi-6-2017-q1-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/hard/libstdc++.a /home/nicola/gcc-arm-none-eabi-6-2017-q1-update/bin/../lib/gcc/arm-none-eabi/6.3.1/hard/libgcc.a "../../install/arm-none-circle/lib/libm.a" "../../install/arm-none-circle/lib/libc.a" "../../install/arm-none-circle/lib/libcirclenewlib.a" liblua.a ../../libs/circle/addon/SDCard/libsdcard.a ../../libs/circle/lib/usb/libusb.a ../../libs/circle/lib/input/libinput.a ../../libs/circle/lib/fs/fat/libfatfs.a ../../libs/circle/lib/fs/libfs.a ../../libs/circle/lib/net/libnet.a ../../libs/circle/lib/sched/libsched.a ../../libs/circle/lib/libcircle.a  /home/nicola/gcc-arm-none-eabi-6-2017-q1-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib/hard/libstdc++.a /home/nicola/gcc-arm-none-eabi-6-2017-q1-update/bin/../lib/gcc/arm-none-eabi/6.3.1/hard/libgcc.a
liblua.a(lstate.o): In function `lua_newstate':
lstate.c:(.text+0x340): undefined reference to `time'
liblua.a(ltable.o): In function `mainposition.isra.3':
ltable.c:(.text+0xe8): undefined reference to `frexp'
liblua.a(lvm.o): In function `l_strcmp':
lvm.c:(.text+0x50): undefined reference to `strcoll'
liblua.a(lvm.o): In function `luaV_tointeger':
lvm.c:(.text+0x1fc): undefined reference to `floor'
liblua.a(lvm.o): In function `luaV_execute':
lvm.c:(.text+0x234c): undefined reference to `pow'
lvm.c:(.text+0x23cc): undefined reference to `fmod'
lvm.c:(.text+0x24f8): undefined reference to `floor'
liblua.a(lauxlib.o): In function `errfile':
lauxlib.c:(.text+0x22c): undefined reference to `__errno'
liblua.a(lauxlib.o): In function `getF':
lauxlib.c:(.text+0x2dc): undefined reference to `fread'
liblua.a(lauxlib.o): In function `skipBOM':
lauxlib.c:(.text+0x368): undefined reference to `__srget_r'
lauxlib.c:(.text+0x3b4): undefined reference to `__srget_r'
liblua.a(lauxlib.o): In function `skipcomment.part.0':
lauxlib.c:(.text+0x47c): undefined reference to `__srget_r'
lauxlib.c:(.text+0x4c8): undefined reference to `__srget_r'
liblua.a(lauxlib.o): In function `luaL_fileresult':
lauxlib.c:(.text+0x754): undefined reference to `__errno'
liblua.a(lauxlib.o): In function `luaL_loadfilex':
lauxlib.c:(.text+0x1104): undefined reference to `fopen'
lauxlib.c:(.text+0x1158): undefined reference to `freopen'
liblua.a(lauxlib.o): In function `luaL_gsub':
lauxlib.c:(.text+0x1d84): undefined reference to `strstr'
liblua.a(ldebug.o): In function `lua_getinfo':
ldebug.c:(.text+0x9d4): undefined reference to `strchr'
ldebug.c:(.text+0xa04): undefined reference to `strchr'
liblua.a(ldo.o): In function `luaD_throw':
ldo.c:(.text+0xd0): undefined reference to `longjmp'
liblua.a(ldo.o): In function `checkmode':
ldo.c:(.text+0x168): undefined reference to `strchr'
liblua.a(ldo.o): In function `luaD_rawrunprotected':
ldo.c:(.text+0x2ac): undefined reference to `setjmp'
liblua.a(lgc.o): In function `propagatemark':
lgc.c:(.text+0xccc): undefined reference to `strchr'
lgc.c:(.text+0xcdc): undefined reference to `strchr'
liblua.a(lobject.o): In function `l_str2dloc':
lobject.c:(.text+0x128): undefined reference to `strtod'
liblua.a(lobject.o): In function `numarith.isra.0':
lobject.c:(.text+0x234): undefined reference to `fmod'
lobject.c:(.text+0x25c): undefined reference to `pow'
lobject.c:(.text+0x270): undefined reference to `floor'
liblua.a(lobject.o): In function `luaO_str2num':
lobject.c:(.text+0x65c): undefined reference to `strpbrk'
lobject.c:(.text+0x788): undefined reference to `strchr'
liblua.a(lobject.o): In function `luaO_tostring':
lobject.c:(.text+0x890): undefined reference to `snprintf'
lobject.c:(.text+0x8a0): undefined reference to `strspn'
lobject.c:(.text+0x92c): undefined reference to `snprintf'
liblua.a(lobject.o): In function `luaO_pushvfstring':
lobject.c:(.text+0x9a0): undefined reference to `strchr'
lobject.c:(.text+0xb50): undefined reference to `snprintf'
liblua.a(lobject.o): In function `luaO_chunkid':
lobject.c:(.text+0xd54): undefined reference to `strchr'
make: *** [../../libs/circle/Rules.mk:96: kernel.img] Error 1
All missing stuff looks like it's from the stdlib, which i get should be on circle-stdlib, but i don't know where to go from here.
The Makefile is (i also tried to move liblua.a around):

Code: Select all

#
# Makefile
#

CIRCLEHOME = ../../libs/circle
NEWLIBDIR = ../../install/arm-none-circle

OBJS    = main.o kernel.o

include $(CIRCLEHOME)/Rules.mk

CFLAGS += -I "$(NEWLIBDIR)/include" -I $(STDDEF_INCPATH) -I ../../include
LIBS := "$(NEWLIBDIR)/lib/libm.a" "$(NEWLIBDIR)/lib/libc.a" "$(NEWLIBDIR)/lib/libcirclenewlib.a" \
        liblua.a \
        $(CIRCLEHOME)/addon/SDCard/libsdcard.a \
        $(CIRCLEHOME)/lib/usb/libusb.a \[list][/list]
        $(CIRCLEHOME)/lib/input/libinput.a \
        $(CIRCLEHOME)/lib/fs/fat/libfatfs.a \
        $(CIRCLEHOME)/lib/fs/libfs.a \
        $(CIRCLEHOME)/lib/net/libnet.a \
        $(CIRCLEHOME)/lib/sched/libsched.a \
        $(CIRCLEHOME)/lib/libcircle.a \
Also, Lua has some compilation flavour, namely: aix bsd c89 freebsd generic linux macosx mingw posix solaris. I tried "generic" as it looks like the most adapt, but perhaps posix would do better? Do we have posix on circle(-stdlib)?

As i said i'm quite bad at C/C++, so i did mostly trial and error.

Thanks for your support :)

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

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

Tue Apr 17, 2018 6:40 pm

I think, you already did a good job. What I can see is, that liblua.a must be moved to the first position in LIBS. There are some functions, which are not implemented yet by the circle-stdlib project. We have to find out, which functions are affected. I don't think, this is fully POSIX compatible, but I'm not the circle-stdlib author. I can ask him. Can you please write me an email to the address noted in most source code headers of Circle. I think this is too specific, to discuss it here.

msx80
Posts: 10
Joined: Sun Feb 11, 2018 4:36 am

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

Tue Apr 17, 2018 8:41 pm

rst wrote:
Tue Apr 17, 2018 6:40 pm
What I can see is, that liblua.a must be moved to the first position in LIBS.
I can't believe it, that was it, it works now! Here's circle loading an external Lua file and executing it:

Image

code is standard from a lua example:

Code: Select all

#include "kernel.h"

#include <stdio.h>
#include <math.h>
#include <stdlib.h>

void print_error(lua_State* state) {
  // The error message is on top of the stack.
  // Fetch it, print it and then pop it off the stack.
  const char* message = lua_tostring(state, -1);
  puts(message);
  lua_pop(state, 1);
}

void execute(const char* filename)
{
  lua_State *state = luaL_newstate();
  printf("Lua state is %p\n", state);  

  // Make standard libraries available in the Lua object
  luaL_openlibs(state);

  int result;

  // Load the program; this supports both source code and bytecode files.
  result = luaL_loadfile(state, filename);

  if ( result != LUA_OK ) {
    print_error(state);
    return;
  }

  // Finally, execute the program by calling into it.
  // Change the arguments if you're not running vanilla Lua code.

  result = lua_pcall(state, 0, LUA_MULTRET, 0);

  if ( result != LUA_OK ) {
    print_error(state);
    return;
  }
}


CKernel::CKernel (void)
:	CStdlibAppStdio ("02-stdio-hello")
{
	mActLED.Blink (5);	// show we are alive
}

CStdlibApp::TShutdownMode CKernel::Run (void)
{
	mLogger.Write (GetKernelName (), LogNotice, "C Standard Library stdin/stdout/stderr Demo");

	mLogger.Write (GetKernelName (), LogNotice, "stdio test...");

	printf("Hello world!\n");
	fprintf(stderr, "Hello world on stderr!\n");

	execute("prog.lua");
	
	printf("Ended lua\n");
	

	printf("Type some characters and hit <RETURN>\n");

	char line[200];
	if (fgets(line, sizeof(line), stdin) != nullptr)
	{
		printf("Read '%s' from stdin...\n", line);
	}
	else
	{
		perror("fgets returned NULL");
	}
	mLogger.Write (GetKernelName (), LogNotice, "C Standard Library Demo finished");

	return ShutdownHalt;
}

I'll write you tomorrow, maybe i try some more involved test first! thanks again

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

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

Wed Apr 18, 2018 8:04 am

Great, that it's working now!

Return to “Bare metal”

Who is online

Users browsing this forum: No registered users and 3 guests