Code Monkey home page Code Monkey logo

circle's Introduction

Circle

Overview

Circle is a C++ bare metal programming environment for the Raspberry Pi. It should be usable on all existing models (tested on model A+, B, B+, on Raspberry Pi 2, 3, 4, 400, 5 and on Raspberry Pi Zero), except on the Raspberry Pi Pico, which is not supported. Circle provides several ready-tested C++ classes and add-on libraries, which can be used to control different hardware features of the Raspberry Pi. Together with Circle there are delivered several sample programs, which demonstrate the use of its classes. Circle can be used to create 32-bit or 64-bit bare metal applications.

Circle includes bigger (optional) third-party C-libraries for specific purposes in addon/ now. This is the reason why GitHub rates the project as a C-language-project. The main Circle libraries are written in C++ using classes instead. That's why it is called a C++ programming environment.

The 46th Step

With this release Circle initially supports the Raspberry Pi 5. There are many features, which are not available yet, but important features like USB and networking are supported. Please see the Circle documentation for more information on Raspberry Pi 5 support!

Circle comes with an USB serial CDC gadget now, which allows to communicate with a Circle application from a host computer via a serial interface without an USB serial adapter. This can be tested with the test/usb-serial-cdc-gadget.

The properties file library in addon/Properties supports section headers now.

A possible race condition in CTimer has been fixed, which could only occur with the KY-040 rotary encoder module driver.

Features

Only the features with a "x" or other info are currently supported on the Raspberry Pi 5.

Circle supports the following features:

Group Features Raspberry Pi 5
C++ build environment AArch32 and AArch64 support AArch64 only
Basic library functions (e.g. new and delete) x
Enables all CPU caches using the MMU x
Interrupt support (IRQ and FIQ) IRQ only
Multi-core support (Raspberry Pi 2, 3 and 4) x
Cooperative non-preemtive scheduler x
CPU clock rate management x
Clang/LLVM support (experimental) x
Debug support Kernel logging to screen, UART and/or syslog server screen / UART
C-assertions with stack trace x
Hardware exception handler with stack trace x
GDB support using rpi_stub (Raspberry Pi 2 and 3)
Serial bootloader (by David Welch) included x
Software profiling support (single-core) x
QEMU support
SoC devices GPIO pins (with interrupt, Act LED) and clocks no clocks
Frame buffer (screen driver with escape sequences) limited
UART(s) (Polling and interrupt driver) x
System timer (with kernel timers) x
Platform DMA controller memcopy only
EMMC SD card interface driver x
SDHOST SD card interface driver (Raspberry Pi 1-3)
PWM output (2 channels)
PWM sound output (on headphone jack)
I2C master(s) and slave masters only
SPI0 master (Polling and DMA driver)
SPI1 auxiliary master (Polling)
SPI3-6 masters of Raspberry Pi 4 (Polling)
SMI master (experimental)
I2S sound output and input
HDMI sound output (without VCHIQ)
Hardware random number generator x
Watchdog device x
Official Raspberry Pi touch screen
VCHIQ interface and audio service drivers
BCM54213PE Gigabit Ethernet NIC of Raspberry Pi 4
MACB / GEM Gigabit Ethernet NIC of Raspberry Pi 5 x
Wireless LAN access x
USB Host controller interface (HCI) drivers x
Standard hub driver (USB 2.0 only) x
HID class device drivers (keyboard, mouse, gamepad) x
Driver for on-board Ethernet device (SMSC951x)
Driver for on-board Ethernet device (LAN7800)
Driver for USB mass storage devices (bulk only) x
Driver for USB audio streaming devices (RPi 4 only) x
Drivers for different USB serial devices x
Audio class MIDI input support x
Touchscreen driver (digitizer mode) x
Printer driver x
MIDI gadget driver
Serial CDC gadget driver (experimental)
File systems Internal FAT driver (limited function) x
FatFs driver (full function, by ChaN) x
TCP/IP networking Protocols: ARP, IP, ICMP, UDP, TCP x
Clients: DHCP, DNS, NTP, HTTP, Syslog, MQTT x
Servers: HTTP, TFTP x
BSD-like C++ socket API x
Graphics OpenGL ES 1.1 and 2.0, OpenVG 1.1, EGL 1.4
(not on Raspberry Pi 4)
uGUI (by Achim Doebler)
LVGL (by LVGL Kft) x
2D graphics class in base library
Not supported Bluetooth

Building

For building 64-bit applications (AArch64) see the next section.

Circle does not support 32-bit applications on the Raspberry Pi 5.

This describes building on PC Linux. See the file doc/windows-build.txt for information about building on Windows. If building for the Raspberry Pi 1 you need a toolchain for the ARM1176JZF core (with EABI support). For Raspberry Pi 2/3/4 you need a toolchain with Cortex-A7/-A53/-A72 support. A toolchain, which works for all of these, can be downloaded here. Circle has been tested with the version 12.2.Rel1 (arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-eabi.tar.xz) from this website.

First edit the file Rules.mk and set the Raspberry Pi version (RASPPI, 1, 2, 3 or 4) and the PREFIX of your toolchain commands. Alternatively you can create a Config.mk file (which is ignored by git) and set the Raspberry Pi version and the PREFIX variable to the prefix of your compiler like this (don't forget the dash at the end):

RASPPI = 1
PREFIX = arm-none-eabi-

The following table gives support for selecting the right RASPPI value:

RASPPI Target Models Optimized for
1 kernel.img A, B, A+, B+, Zero, (CM) ARM1176JZF-S
2 kernel7.img 2, 3, Zero 2, (CM3) Cortex-A7
3 kernel8-32.img 3, Zero 2, (CM3) Cortex-A53
4 kernel7l.img 4B, 400, CM4 Cortex-A72

For a binary distribution you should do one build with RASPPI = 1, one with RASPPI = 2 and one build with RASPPI = 4 and include the created files kernel.img, kernel7.img and kernel7l.img. Optionally you can do a build with RASPPI = 3 and add the created file kernel8-32.img to provide an optimized version for the Raspberry Pi 3.

The configuration file Config.mk can be created using the configure tool too. Please enter ./configure -h for help on using it!

There are a number of configurable system options in the file include/circle/sysconfig.h. Please have a look into this file to learn, how you can configure Circle for your purposes. Some hardware configurations may require modifications to these options (e.g. using USB on the CM4).

Then go to the build root of Circle and do:

./makeall clean
./makeall

By default only the Circle libraries are built. To build a sample program after makeall go to its subdirectory and do make.

You can also build Circle on the Raspberry Pi itself (set PREFIX = (empty)) on Raspbian but you need some method to put the kernel.img file onto the SD(HC) card. With an external USB card reader on model B+ or Raspberry Pi 2/3/4 model B (4 USB ports) this should be no problem.

AArch64

Circle supports building 64-bit applications, which can be run on the Raspberry Pi 3, 4 or 5. There are also Raspberry Pi 2 versions and the Raspberry Pi Zero 2, which are based on the BCM2837 SoC. These Raspberry Pi versions can be used too (with RASPPI = 3).

The recommended toolchain to build 64-bit applications with Circle can be downloaded here. Circle has been tested with the version 12.2.Rel1 (arm-gnu-toolchain-12.2.rel1-x86_64-aarch64-none-elf.tar.xz) from this website.

There are distro-provided toolchains on certain Linux platforms (e.g. g++-aarch64-linux-gnu on Ubuntu or gcc-c++-aarch64-linux-gnu on Fedora), which may work with Circle and can be a quick way to use it, but you have to test this by yourself. If you encounter problems (e.g. no reaction at all, link failure with external library) using a distro-provided toolchain, please try the recommended toolchain (see above) first, before reporting an issue.

First edit the file Rules.mk and set the Raspberry Pi architecture (AARCH, 32 or 64) and the PREFIX64 of your toolchain commands. The RASPPI variable has to be set to 3, 4 or 5 for AARCH = 64. Alternatively you can create a Config.mk file (which is ignored by git) and set the Raspberry Pi architecture and the PREFIX64 variable to the prefix of your compiler like this (don't forget the dash at the end):

AARCH = 64
RASPPI = 3
PREFIX64 = aarch64-none-elf-

The configuration file Config.mk can be created using the configure tool too. Please enter ./configure -h for help on using it!

Then go to the build root of Circle and do:

./makeall clean
./makeall

By default only the Circle libraries are built. To build a sample program after makeall go to its subdirectory and do make.

Installation

Copy the Raspberry Pi firmware (from boot/ directory, do make there to get them) files along with the kernel*.img (from sample/ subdirectory) to a SD(HC) card with FAT file system.

It is now always recommended to copy the file config32.txt (for 32-bit mode) or config64.txt (for 64-bit mode) from the boot/ directory to the SD(HC) card and to rename it to config.txt there. These files are especially required to enable FIQ use on the Raspberry Pi 4. Furthermore the additional file armstub7-rpi4.bin (for 32-bit mode) or armstub8-rpi4.bin (for 64-bit mode) is required on the SD card then. Please see boot/README for information on how to build these files.

Finally put the SD(HC) card into the Raspberry Pi.

Directories

  • include: The common header files, most class headers are in the include/circle/ subdirectory.
  • lib: The Circle class implementation and support files (other libraries are in subdirectories of lib/).
  • sample: Several sample applications using Circle in different subdirectories. The main function is implemented in the CKernel class.
  • addon: Contains contributed libraries and samples (has to be build manually).
  • app: Place your own applications here. If you have own libraries put them into app/lib/.
  • boot: Do make in this directory to get the Raspberry Pi firmware files required to boot.
  • doc: Additional documentation files.
  • test: Several test programs, which test different features of Circle.
  • tools: Tools for building Circle and for using Circle more comfortable (e.g. a serial bootloader).

Classes

The following C++ classes were added to Circle:

Base library

  • CMACBDevice: Driver for MACB/GEM Ethernet NIC of Raspberry Pi 5
  • CSouthbridge: Driver for the RP1 multi-function device of the Raspberry Pi 5

USB library

  • CUSBSerialHostDevice: Generic host driver for USB serial devices (was: CUSBSerialDevice)
  • CUSBSubSystem: USB sub-system of the Raspberry Pi 5

USB gadget library

  • CUSBCDCGadget: USB serial CDC gadget
  • CUSBCDCGadgetEndpoint: Endpoint of the USB serial CDC gadget

The available Circle classes are listed in the file doc/classes.txt. If you have Doxygen installed on your computer you can build a class documentation in doc/html/ using:

./makedoc

At the moment there are only a few classes described in detail for Doxygen.

Additional Topics

Trademarks

Raspberry Pi is a trademark of Raspberry Pi Ltd.

Linux is a trademark of Linus Torvalds.

PS3 and PS4 are registered trademarks of Sony Computer Entertainment Inc.

Windows, Xbox 360 and Xbox One are trademarks of the Microsoft group of companies.

Nintendo Switch is a trademark of Nintendo.

Khronos and OpenVG are trademarks of The Khronos Group Inc.

OpenGL ES is a trademark of Silicon Graphics Inc.

The micro:bit brand belongs to the Micro:bit Educational Foundation.

HDMI is a registered trademark of HDMI Licensing Administrator, Inc.

circle's People

Contributors

aterialdawn avatar bcs1234 avatar diyelectromusic avatar dwhinham avatar elmfrain avatar ericfont avatar flabbergast avatar hinxx avatar hpingel avatar kevinboone avatar konistehrad avatar matemaciek avatar mitsuji avatar mjrgh avatar rsta2 avatar seba1978 avatar smuehlst avatar stdrc avatar thexxturboxx avatar timgates42 avatar xalior avatar yomboprime avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

circle's Issues

sample/31-webclient does not work any more (HTTP error 301)

eLinux.org does not support HTTP any more and uses HTTPS instead, which is not supported by Circle. Because this sample tries to fetch a page using HTTP from this server, a HTTP error 301 (Moved permanently) will be reported. Unfortunately there is currently no solution on this.

Raspberry pi 3 hanging on serial print

Hello, I'm having a problem while testing with raspberry pi 3.
The blink example works and i can see the led blinking, but as soon i insert a serial code, the rasp hangs, also if i try to run other examples i receive nothing at the serial. Could it be a different bootcode problem? If so, could you post the boot binaries tou used to perform test with raspberry pi 3? Thanks

//
// kernel.cpp
//
// Circle - A C++ bare metal environment for Raspberry Pi
// Copyright (C) 2014-2016  R. Stange <[email protected]>
// 
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//
#include "kernel.h"
#include <circle/gpiopin.h>
#include <circle/timer.h>

CKernel::CKernel (void)
{
}

CKernel::~CKernel (void)
{
}

boolean CKernel::Initialize (void)
{
	return TRUE;
}

TShutdownMode CKernel::Run (void)
{
	CGPIOPin AudioLeft (41, GPIOModeOutput);
	CGPIOPin AudioRight (40, GPIOModeOutput);

	// flash the Act LED 10 times and click on audio (3.5mm headphone jack)
	for (unsigned i = 1; i <= 10; i++)
	{
		m_ActLED.On ();
		AudioLeft.Invert ();
		AudioRight.Invert ();
		CTimer::SimpleMsDelay (200);

		m_ActLED.Off ();
		CTimer::SimpleMsDelay (500);
	}

	return ShutdownReboot;
}

CDeviceNameService - list devices

Hi. I'm trying to run file access example. It keeps saying that "partition not found". I wonder why there is no ListDevices method in CDeviceNameService. It could help me to find correct device name.

Andrzej

Raspberry zero - speed settings

Hi. As you probably know the default speed settings for raspberry zero are slightly higher than settings for raspberry 1. Since you use fixed values for both raspberry 1 and zero i had to make some modifications in circle core to change speed settings:

  1. make CCPUThrottle::SetClockRate public accessible
	CCPUThrottle::SetClockRate(CLOCK_ID_CORE, 340 * 1000 * 1000, true);
	CCPUThrottle::SetClockRate(CLOCK_ID_ARM, 1000 * 1000 * 1000, true);

#define CLOCK_ID_SDRAM		8

	CCPUThrottle::SetClockRate(CLOCK_ID_SDRAM, 450 * 1000 * 1000, true);
  1. add voltage related tag to property tags:
#define PROPTAG_GET_VOLTAGE	    	0x00030003
#define PROPTAG_SET_VOLTAGE	    	0x00038003

struct TPropertyTagVoltage
{
	TPropertyTag	Tag;
	u32		nVoltageId;
	#define VOLTAGE_ID_CORE		1
	#define VOLTAGE_ID_SDRAM_C	2
	#define VOLTAGE_ID_SDRAM_P	3
	#define VOLTAGE_ID_SDRAM_I	4
	u32		value;
};

struct TPropertyTagSetVoltage
{
	TPropertyTag	Tag;
	u32		nVoltageId;
	u32		value;
};

TagVoltage.nVoltageId = VOLTAGE_ID_CORE;
TagVoltage.value = 1350000; //1,35V
if (Tags.GetTag(PROPTAG_SET_VOLTAGE, &TagVoltage, sizeof TagVoltage, 4))
{
	Message.Format ("CORE Voltage %d %d\r\n", TagVoltage.nVoltageId, TagVoltage.value);
	m_Screen.Write ((const char *) Message, Message.GetLength ());		//return 0;
}

Are you planning to implement such routines in nearest future?

Connecting GPIO pin to interrupt rising edge gives continuous sequence of interrupt handler calls

I'm trying to attach an interrupt handler to the rising edge of a GPIO pin. My current test setup is a push button with a pulldown resistor attached to GPIO pin 26 of a Raspberry Pi Zero. Pushing the button toggles the pin from LOW to HIGH, which I can verify with a multimeter and a logic analyzer.

The problem ist that the interrupt handler is being called all the time. Even if I connect GPIO 26 directly to GND, this behavior doesn't change. The symptom is a continuous stream of "Interrupt rising edge" messages on the console.

The code is derived from the code in softserial.cpp. The following is the relevant portion of a minimal test example (full project available if necessary). Is there a problem with the code, or do I have a hardware problem?

CKernel::CKernel (void)
:	m_Screen (m_Options.GetWidth (), m_Options.GetHeight ()),
	m_Timer (&m_Interrupt),
	m_Logger (m_Options.GetLogLevel (), &m_Timer),
	m_GPIOManager (&m_Interrupt)
{
}

CKernel::~CKernel (void)
{
}

bool CKernel::Initialize (void)
{
	bool bOK = true;

	if (bOK)
	{
		bOK = m_Screen.Initialize ();
	}

	if (bOK)
	{
		CDevice *pTarget = m_DeviceNameService.GetDevice (m_Options.GetLogDevice (), FALSE);
		if (pTarget == 0)
		{
			pTarget = &m_Screen;
		}

		bOK = m_Logger.Initialize (pTarget);
	}

	if (bOK)
	{
		bOK = m_Interrupt.Initialize ();
	}

	if (bOK)
	{
		bOK = m_Timer.Initialize ();
	}

	if (bOK)
	{
		bOK = m_GPIOManager.Initialize ();
	}

	return bOK;
}

void CKernel::InterruptHandler (void)
{
	m_Logger.Write("CKernel::InterruptHandler", LogNotice, "Interrupt rising edge");
}

void CKernel::InterruptStub (void *pParam)
{
	CKernel *pThis = (CKernel *) pParam;
	assert (pThis != 0);

	pThis->InterruptHandler ();
}

TShutdownMode CKernel::Run (void)
{
	m_Logger.Write (FromKernel, LogNotice, "Compile time: " __DATE__ " " __TIME__);

	CGPIOPin clockPin(26, GPIOModeInput, &m_GPIOManager);

	clockPin.ConnectInterrupt (InterruptStub, this);
	clockPin.EnableInterrupt (GPIOInterruptOnRisingEdge);

	while (true);

	return ShutdownReboot;
}

Delayed status report from HP USB Smart Card Keyboard

Keyboard is recognized as standard int3-1-1 device, but the key presses aren't taken correctly. Sometimes, when a modifier key is pressed, the event pair press/release are shown seconds later from the real key press.

Reported by JosΓ© Luis SΓ‘nchez

QEMU

Can Circle be used with QEMU?

p_thread semantic scheduler?

Hi, I studied your implementation of scheduler.
Compare to the usual fork-and-join approach, your scheduler is kind of an polling based approach that the scheduler is activated on yield and run the next possible task.

Does my statement correctly describe your scheduler's behavior?

One limitation for this event based approach does not use multicores to explore true parallelism?

Notable clang warning regarding comparison that is always true

I have submitted pull request #19 to fix some minor code issues reported by clang. An additional notable warning reported by clang which probably should be investigated is the following:

bcmframebuffer.cpp:93:36: warning: comparison of constant 256 with expression of type 'u8' (aka 'unsigned char') is always true [-Wtautological-constant-out-of-range-compare]
    if (m_pInfo->Depth <= 8 && nIndex < 256)
                               ~~~~~~ ^ ~~~

As nIndex is declared as u8 in the parameter list of CBcmFrameBuffer::SetPalette, the comparison nIndex < 256 is always true.

Samples fails when are loaded using u-boot

When a sample that uses timers is loaded using u-boot, the execution fails. The reason is that u-boot changes the CP15 register VBAR (section 3.2.43, p.253 from ARM1176JZF-S TRM). I'm using a PI B+, but the same register is at ARMv7 & ARMv8.
Setting this CP15 register to zero, resolves the problem.

Btw, u-boot modifies too the bit-1 "Strict Alignment Fault Checking" in CP15 register c1,c0, 0 (section 3.2.7, p.176 from ARM1176JZF-S TRM) setting to "enabled". I can't say now how impact this in Circle.

Best regards ;)

Raspberry Pi 2 support

Is there any plan to support lastest Raspbeery Pi 2? It will be worthy if it is possible.

PWM audio on the RPI Zero

I would like to use the PWMSounddevice with the RPI Zero but this requires the standard pins (40,etc) to be changed because the Zero doesn't have those audio pins available. I did see you had a quick solution to this in the Oct 1, 2017 commit, but this does not seem to work (anymore).

Any pointers on how this can be done currently?

Cross toolchain on Windows needs modification slightly of CFLAGS in Rules.mk

Windows 8.1 Mingw environment,

Rules.mk CFLAGS may cause an compile error like the following.

arm-none-eabi-g++ -march=armv5 -mtune=arm1176jzf-s -Wall -Wno-psabi -fsigned-char -fno-builtin -nostdinc -nostdlib -undef -D__circle__ -I ../include -I ../addon -O -fno-exceptions -fno-rtti -std=c++0x -c -o synchronize.o synchronize.cpp
C:\Users\Miso\AppData\Local\Temp\ccBIvGL4.s: Assembler messages:
C:\Users\Miso\AppData\Local\Temp\ccBIvGL4.s:27: Error: selected processor does not support ARM mode cpsid i' C:\Users\Miso\AppData\Local\Temp\ccBIvGL4.s:79: Error: selected processor does not support ARM modecpsie i'
make: *** [synchronize.o] Error 1

I could fix the compile error with change of CFLAGS as the following.

CFLAGS += -march=armv6j -mfloat-abi=hard -mtune=arm1176jzf-s -Wall -Wno-psabi -fsigned-char -fno-builtin -nostdinc -nostdlib
-undef -D__circle__ -I $(CIRCLEHOME)/include -I $(CIRCLEHOME)/addon -O #-DNDEBUG

There will be no more compile error on Windows.

Why do we need a Barrier on GPIO-Output?

In CGPIOPin::Write you use PeripheralEntry and PeripheralExit to protect the memory-write that toggles the GPIO-Pin.
Is that really necessary? Because on "Real-Linux" one can change the GPIO state with a simple memory write without needing any special barriers? Or are the barriers provided by the Linux kernel in that case and hidden away from the C code running on Linux? (I would be quite surprised about that, though.)

VC4 port

Hi,

Is there any interest in porting (some of) these bits to the even-more-bare-metal VC4 side? Some things might be pretty useful there, I think, and could probably be made to work (i.e. "blobless") maybe almost just by tweaking base addresses and recompiling.

Disable Prefetching.

Hello and thank you for your project. I am using your library to characterize the power/energy behavior of the raspPI3b. I am trying to disable the prefetching unit of the CPU. According to the arm manual I need to set a value to CPUACTLR when processor is idle. I tried to add code in startup.S which reads CPUACTLR and then writes back the same value to the register. However the booting freezes. The code is added after the VBAR is reseted in startup.S and looks like :

mrrc    p15, 0, r2, r3, c15 
mcrr    p15, 0, r2, r3, c15  

Could u please provide me some guidance on how to do it?

26-cpustress

Hello and congratulations for your awesome project. I am testing the 26-cpustress sample on a raspberry Pi 3b. I am setting all the compilation options for this platform and I compile successfully the 26th sample. The single threaded/CPU version is executing correctly. Afterwards I follow the instructions and i define ARM_ALLOW_MULTI_CORE in include/circle/sysconfig.h. I re-complie all the libraries and re-execute the sample. I am not sure, but i think that everything is executed on top of CPU 0. Am I missing something? Is there any implementation in which all 4 cores of my PI simultaneously execute a part of the computation (Simillar to the POSIX pthreads)? Thank you.

Minor problem with CString.Format

Hi,

The CString::Format method don't add the needed '0' with a format as "%04d". With "%04u" the zero filler is formatted as expected.

Both Circle and Circle64 are missing CursorLeft support

Both Circle and Circle64 have the code for CursorLeft missing in lib/screen.cpp

lib/screen.cpp

void CScreenDevice::Write (char chChar)
{
...
        case ScreenStateBracket:
...
                case 'C':
                        CursorRight ();
                        m_nState = ScreenStateStart;
                        break;

                case 'D': // Added by AMR, missing in original
                        CursorLeft ();
                        m_nState = ScreenStateStart;
                        break;

                case 'H':
                        CursorHome ();
                        m_nState = ScreenStateStart;
                        break;
...
}

USB Device Implementation?

This is more a question than a bug report: I wonder if you tried to use the board as USB-device (but not as host like in your examples) in order to e.g. let it appear as serial interface on a connected host PC (USB CDC device implementation).

Anyway: well done, this is a lot of useful code!

Other Languages Support

Hello
First Of all, thanks for this awesome codes, I would Like to Display Farsi Text On the Screen.
I found a Font.h file, I converted a farsi Font Like "B nazanin" to the bitmap hex file, and replaced it, but it did not work, Do you have any Idea or solution for this?

Thank You so much
Niloofar

TLB dirty after loading image with u-boot and PI B+

When a bare image is loaded using u-boot the TLB cache maintains contents that generate problems when MMU is reenabled by Circle. This can be tested using sample 03-screentext, that shows strange lines over the text at random places, and last lines completely shattered when the screen resolution is low, as 640x480. When the MMU is disabled (calling memory(FALSE) in kernel.cpp constructor) all screen is showed correctly.

As specified in ARM Cortex-A Series Programmer's Guide (DEN0013D), section 8.8, after disable MMU is needed to invalidate L1-Cache, TLB and branch predictor (point 2 from sample code). For this issue the relevant action is invalidate TLB, that resolves the problem.

I've modified the file startup.S as:

mov r0, #0
mcr p15, 0, r0, c12, c0, 0 /* reset VBAR (if changed by u-boot) /
mcr p15, 0, r0, c7, c5, 0 /
Invalidate Instruction Cache /
mcr p15, 0, r0, c7, c5, 6 /
Invalidate branch prediction array /
mcr p15, 0, r0, c8, c7, 0 /
Invalidate entire Unified Main TLB /
mcr p15, 0, r0, c7, c5, 4 /
need to be changed for ISB instruction on PI-2/3 */

Establish a list of priority tasks to encourage contributions

Hi,

While it's freshly new, this project seems really active. I think he could be a game changer in the Raspberry Pi's bare-metal world because it is more concrete than other projects I found.

dwelch67 opened the way with all these great "how-to" examples but circle is more about making all theses peripherals work together rather than one by one, right ?

I think encouraging the open source community to contribute is a must, 'cause I would to, but I don't want to mess up your plans. That's the reason why I think doing a list of priority features in your README (or through issues?) is important. I don't want to fork to make my own version, but rather contribute to make this one it more useful.

BTW, keep it up, this repository is full of interesting things for everyone (And I strongly consider myself part of "everyone" πŸ˜„)

POSIX socket compatibility possible?

I'm just curious: Would it be possible to make the circle socket api look like normal sockets, so one can use a default C library that uses sockets and it would work out of the box?

Probably a lot of work, though.

Compiler IRQ/FIQ-Optimization

When doing my research on FIQ interrupt handlers i found some information, that one can use an __attribute__ ((interrupt ("FIQ"))) or __attribute__ ((interrupt ("IRQ"))) to tell the compiler that a function should be used as an interrupt handler.
I don't see any information or usage of this in circle. Is there a special reason for this?

Is it realistic trying to process a 1 MHz signal with a Raspberry Pi Zero and circle?

This is more a question than an issue.

I'm trying to process signals that have a 1 MHz clock. My ultimate goal is to simulate a device that is attached to the bus of a 6502 processor.

At the moment I'm trying to mirror the 1 MHz clock signal from one input GPIO pin to an output GPIO pin with the following code:

kernel.h:

#ifndef _kernel_h
#define _kernel_h

#include <circle/memory.h>
#include <circle/actled.h>
#include <circle/koptions.h>
#include <circle/devicenameservice.h>
#include <circle/screen.h>
#include <circle/serial.h>
#include <circle/exceptionhandler.h>
#include <circle/interrupt.h>
#include <circle/timer.h>
#include <circle/logger.h>
#include <circle/types.h>
#include <circle/gpiomanager.h>

enum TShutdownMode
{
	ShutdownNone,
	ShutdownHalt,
	ShutdownReboot
};

class CKernel
{
public:
	CKernel (void);
	~CKernel (void);

	bool Initialize (void);

	TShutdownMode Run (void);

private:
	// do not change this order
	CMemorySystem		m_Memory;
	CKernelOptions		m_Options;
	CDeviceNameService	m_DeviceNameService;
	CScreenDevice		m_Screen;
	CExceptionHandler	m_ExceptionHandler;
	CInterruptSystem	m_Interrupt;
	CTimer				m_Timer;
	CLogger				m_Logger;
	CGPIOManager		m_GPIOManager;

	void InterruptHandler (void);
	static void InterruptStub (void *pParam);

	CGPIOPin clockPin;

	bool volatile state;
};

#endif

kernel.cpp:

#include "kernel.h"

#include <assert.h>

static const char FromKernel[] = "kernel";

CKernel::CKernel (void)
:	m_Screen (m_Options.GetWidth (), m_Options.GetHeight ()),
	m_Timer (&m_Interrupt),
	m_Logger (m_Options.GetLogLevel (), &m_Timer),
	m_GPIOManager (&m_Interrupt),
	clockPin(26, GPIOModeInput, &m_GPIOManager),
	state(false)
{
}

CKernel::~CKernel (void)
{
}

bool CKernel::Initialize (void)
{
	bool bOK = true;

	if (bOK)
	{
		bOK = m_Screen.Initialize ();
	}

	if (bOK)
	{
		CDevice *pTarget = m_DeviceNameService.GetDevice (m_Options.GetLogDevice (), FALSE);
		if (pTarget == 0)
		{
			pTarget = &m_Screen;
		}

		bOK = m_Logger.Initialize (pTarget);
	}

	if (bOK)
	{
		bOK = m_Interrupt.Initialize ();
	}

	if (bOK)
	{
		bOK = m_Timer.Initialize ();
	}

	if (bOK)
	{
		bOK = m_GPIOManager.Initialize ();
	}

	return bOK;
}

void CKernel::InterruptHandler (void)
{
	state = clockPin.Read();
}

void CKernel::InterruptStub (void *pParam)
{
	CKernel *pThis = (CKernel *) pParam;
	assert (pThis != 0);

	pThis->InterruptHandler ();
}

TShutdownMode CKernel::Run (void)
{
	m_Logger.Write (FromKernel, LogNotice, "Compile time: " __DATE__ " " __TIME__);
	m_Logger.Write (FromKernel, LogNotice, "Connecting interrupts to clock pin");

	clockPin.ConnectInterrupt (InterruptStub, this);
	clockPin.EnableInterrupt (GPIOInterruptOnRisingEdge);
	clockPin.EnableInterrupt2 (GPIOInterruptOnFallingEdge);

	unsigned const clockMirrorPin = 10;
	m_Logger.Write (FromKernel, LogNotice, "Mirroring clock input to GPIO pin %u", clockMirrorPin);
	CGPIOPin clockOutPin(clockMirrorPin, GPIOModeOutput);

	m_Logger.Write (FromKernel, LogNotice, "Looping...");

	bool oldState = state;
	while (true) {
		bool const newState = state;

		if (newState != oldState) {
			if (newState) {
				clockOutPin.Write(HIGH);
			}
			else {
				clockOutPin.Write(LOW);
			}
			oldState = newState;
		}
	}

	return ShutdownReboot;
}

I use a logic analyzer to compare the input and the output signal, and the output signal does not keep up with the input signal, e.g. it misses arbitrary transitions of the input clock signal.

I also have version of the code that switches the output pin directly from the interrupt handling routine, and that bypasses the search for the right interrupt callback in CGPIOManager::InterruptHandler(), because I know that only one specific pin triggers an interrupt, but that is not much better, and the code is too large to post here.

So my question is, is it realistic trying to implement this with circle at all, or should I bury this idea?

Thank you

../sample/15_files/ β€” umsd1-1 Partion not mounting (Possibly user error)

Hi,

I forked your repository and have been compiling with the arm-none-eabi- toolchain to put the circle bare metal OS on my Raspberry Pi. I have been trying to experiment with writing to a 1 GB USB (FAT 32) drive plugged directly into the USB port on my Pi. After using make in the ../sample/15_files/ directory, the code successfully boots on the Pi, but hangs after the "Compile time" line that is printed to the monitor. I added an "else" to the "if" statement in kernel.cpp that checks to see if the partition is found and it is successfully being found. It seems that the partition is not being mounted properly. Do you have any idea why the code does not get past the mounting "if" statement? Should I be modifying the defined name of the partition at the beginning of kernel.cpp?

I've attached a screen shot of the modified code (2 else statements added). The code never reaches the second if statement. Any suggestions would be greatly appreciated!

screen shot 2015-04-22 at 4 04 00 pm

Raspberry Pi 2 v1.2 (aka RPi2+) currently not supported

According to this there is a new revision 1.2 of the Raspberry Pi 2 out which is based on the BCM2837 SoC (not on BCM2836 any more). The BCM2837 was previously used on the Raspberry Pi 3 only.

The Raspberry Pi 2 v1.2 is currently not supported by Circle. Because I do not own such device I cannot test it with Circle and cannot get it working.

Connect a GPIO pin to rising and falling edge interrupts

Do I understand it correctly that currently it is not possible to connect a GPIO pin via class CGPIOPin to both a falling-edge and rising-edge interrupt? I looked at the "BCM2835 ARM Peripherals" document, and I think it should be possible technically to do that.

Buffer Size being ignored in CSocket::Receive?

To me it looks like the buffer size is pretty much ignored when calling CSocket::Receive. The only thing it does is overwrite the number of received bytes in case less than nLength bytes were received?

So i cannot really trust the number of received bytes and also cannot trust receive to not write beyond the provided pBuffer-Pointer?

Is this intentional? Am I missing something here?

Sound makes erorr after USB module initialized

Pwmsound works fine. But USB module and Pwmsound makes confilct. It is very easy to dectect. Adding pwnsound function into USB sample code. Sound makes tick noise recursively to the end of play.

USB Registers

Hello,

I am dong some baremetal development for the Raspberry Pi and could find as good as no documentation in the public domain about the USB core except for the base address. I see that you have implemented USB support so I have a few questions:

  1. Is there a standard register structure for USB devices or is it specific to implementations?
  2. Where can I find the usb register descriptions for the BCM2835?
  3. I am trying to develop a very basic usb driver which does not have to be generic at all. Let us just say that I want to use a keyboard as a fancy keypad connected over USB. Are there enough Infos available (I mean without having to reverse engineer code myself) in the public domain for me to even attempt this or should I just drop the idea?

Many thanks,
Szoshi

Using math.h with Circle

I want to use math.h in Circle.
So I tried to add the library but "No such file or directory" error is occured.
How I add more libraries in the sources?

Gamepad support?

Hi, awesome work! Tested Mouse and Keyboard and it works great.
There is no support for gamepads ?
Thanks for sharing!

TFTP serve not working

hi
i try:

C:\Users\test>tftp -i 169.254.0.111 GET kernel.img kernel.img

I see on circle serial console:
00:12:25.68 tftpd: Transfer timed out
00:12:52.97 tftpd: Incoming read request from 169.254.229.229
00:13:37.98 tftpd: Transfer timed out
00:13:37.98 tftpd: Incoming write request from 169.254.229.229
00:13:43.04 tftpd: Transfer timed out
00:13:43.21 tftpd: Incoming write request from 169.254.229.229
00:13:48.22 tftpd: Transfer timed out

Disable Prefetch.

Hello and thank you for your project. I am using your library to characterize the power/energy behavior of the raspPI3b. I am trying to disable the prefetching unit of the CPU. According to the arm manual I need to set a value to CPUACTLR when processor is idle. I tried to add code in startup.S which reads CPUACTLR and then writes back another value to the register. However when i read and print the register the resutls are the same.

mrrc    p15, 0, r2, r3, c15 
bic r2, r2, #28672
orr r2, r2, #253755392
mcrr    p15, 0, r2, r3, c15  

Could u please provide me some guidance on how to do it?

Problem with multicore support and last firmware

Hi Rene,

From last firmware update, the secondary CPUs don't start correctly. The reason is this change:

raspberrypi/tools#76

I've applied this small modification to multicore.cpp:

write32 (ARM_LOCAL_MAILBOX3_SET0 + 0x10 * nCore, (u32) &_start_secondary);
asm volatile ("sev");

So, the CPUs are starting again.

Best regards

webserver memory leak

Hi!

I've come across some memory leak problem in web server implementation.
I can reproduce problem on example 21-webserver, on raspberry pi2.
I first tried with ARM_ALLOW_MULTI_CORE + REALTIME settings in sysconfig.h,
then with ARM_ALLOW_MULTI_CORE only setting, then with default settings, problem remain the same.
What I do is flooding webserver with following command from my pc:
curl -s "http://192.168.1.118?[1-10000]"
What happens is that always after 457 successful replies raspberry hangs.

I did some rough debugging, found that:

  • with mem_info() I see that things get allocated but never freed, it looks like any connection is taking about 1 block of 262144, 2 blocks of 4096, 1 block of 1024;

  • with TCP_DEBUG I've seen that connections stay stuck in FIN-WAIT-1 state, as if TCPTimerTimeWait never get called, so state never goes further to CLOSING and tcpconnection never get deleted;

  • what is strange is that this happens only if I continuously do "fast" writing on screen (without scrolling): I continuously call "\b[H" sequence to go home with screen cursor, then call mem_info(); this results in seeing very fast update of memory consumption; in this conditions, example 21 hangs with even 1 connection, and connection last seen state is FIN-WAIT-1;

  • if I remove the mem_info() thing, but keep the TCP_DEBUG thing, I see from the tcp log that 1 connection correctly terminates (goes to CLOSED state, and then I see "Deleted TCB" message); a connection flood anyway terminates with some not-well defined hang;

That's what I've seen so far, hope it is useful :)
I may try some further debugging next days...

question: what is the difference between rpi2 and rpi3?

I've found the following code (at https://github.com/rsta2/circle/blob/master/lib/bcmpropertytags.cpp#L94):

    u32 *pEndTag = (u32 *) (pBuffer->Tags + nTagSize);
    *pEndTag = PROPTAG_END;

#if RASPPI != 3
    CleanDataCache ();
    DataSyncBarrier ();
#endif

    u32 nBufferAddress = GPU_MEM_BASE + (u32) pBuffer;
    if (m_MailBox.WriteRead (nBufferAddress) != nBufferAddress)
    {
        return FALSE;
    }

#if RASPPI != 3
    InvalidateDataCache ();
    DataSyncBarrier ();
#else
    DataMemBarrier ();
#endif

I understand why you clear the data-cache and what the barriers are for, what I don't understand is why you don't clear the datacache and do the dsb when it's a rpi3 and after the writeread there's also a difference between the models. I think it's because of the different arm-cores, but what is the important point to know about the difference between the models regarding dmb, dsb and cachebehavior?

Problems with keyboard USB 1.1

Hello RenΓ©,

I'm testing the new code in develop branch. I've found as issue with the LED handling with a keyb Logitech K120 keyboard that not exist when I use a HP keyb (USB 2.0).

I've found another problem with new gamepad code while using a Sony DualShock Sixaxis for PS3 (original, not clone). Both errors are shown at boot:

00:00:00.71 usbdev0-1: Device ven424-9514, dev9-0-2 found
00:00:00.72 usbdev0-1: Interface int9-0-1 found
00:00:00.72 usbdev0-1: Function is not supported
00:00:00.73 usbdev0-1: Interface int9-0-2 found
00:00:00.73 usbdev0-1: Using device/interface int9-0-2
00:00:02.94 usbdev0-1: Device ven424-ec00 found
00:00:02.94 usbdev0-1: Using device/interface ven424-ec00
00:00:03.11 usbdev1-2: Device ven46d-c31c found
00:00:03.12 usbdev1-2: Interface int3-1-1 found
00:00:03.12 usbdev1-2: Using device/interface int3-1-1
00:00:03.13 usbdev1-2: Interface int3-0-0 found
00:00:03.13 usbdev1-2: Using device/interface int3-0-0
00:00:03.30 usbdev1-3: Device ven46d-c03e found
00:00:03.30 usbdev1-3: Interface int3-1-2 found
00:00:03.31 usbdev1-3: Using device/interface int3-1-2
00:00:03.49 usbdev1-5: Device ven54c-268 found
00:00:03.49 usbdev1-5: Interface int3-0-0 found
00:00:03.50 usbdev1-5: Using device/interface int3-0-0
00:00:03.55 smsc951x: MAC address is B8:27:EB:F6:EA:B3
00:00:03.56 usbhub: Port 1: Device configured
00:00:03.62 dwhci: Transaction failed (status 0xA)
00:00:03.63 usbpad: Cannot get HID report descriptor
00:00:03.63 usbhub: Port 2: Device configured
00:00:03.69 usbhub: Port 3: Device configured
00:00:03.75 dwhci: Transaction failed (status 0xA)
00:00:03.75 usbpad: Cannot get HID report descriptor
00:00:03.76 usbhub: Port 5: Cannot configure device
00:00:03.76 dwroot: Device configured

I have connected Logitech keyb, a mouse and PS3 DualShock.

how to use CSPIMaster together with CSPIMasterDMA

Hi. Sorry for my bad english.

I would like to use CSPIMaster together with CSPIMasterDMA. I want to send few bytes synchronously (CSPIMaster) than much more bytes asynchronously (CSPIMasterDMA). I manager to do this by changing

	write32 (ARM_SPI0_CS,   (read32 (ARM_SPI0_CS) & ~CS_CS)
			      | (nChipSelect << CS_CS__SHIFT)
			      | CS_CLEAR_RX | CS_CLEAR_TX
			      | CS_TA);

to

	write32 (ARM_SPI0_CS,   (read32 (ARM_SPI0_CS) & ~CS_CS **& ~CS_DMAEN & ~CS_ADCS**)
			      | (nChipSelect << CS_CS__SHIFT)
			      | CS_CLEAR_RX | CS_CLEAR_TX
			      | CS_TA);

Do you think it's correct way to do this? Using DMA and callbacks for sending 1 or 2 bytes is very inconvienent. Should i expect any issues caused by switching between DMA and synchronous mode ?

Thank you.

How can I wait for vertical blank?

Hi,

I hope this is the correct way to ask a question like this.

I am making games using this library and I would like to be able to have the game wait for the vertical sync, to avoid tearing. I've read up a bit on the subject and found two potential ways to do this.

  1. Use the Set virtual offset tag, as discussed here. < https://www.raspberrypi.org/forums/viewtopic.php?t=19073 > So I've tried calling CBcmFrameBuffer::SetVirtualOffset and it returns with no error (TRUE) but the game is still not waiting for VSync.

So then I found this.

  1. Enable fake_vsync_irq in config.txt and listen to IRQ 48, as discussed here < raspberrypi/firmware#67 > So I tried connecting an IRQ handler like so:
    m_Interrupt.ConnectIRQ( ARM_IRQ_SMI, IRQParty, (void*)0 );
    But for some reason that function never returns. If I add logging before and after that function call I see that the log message before the call is printed but not the message after.

My IRQ handler looks like this:

volatile uint32 testValue;

void IRQParty( void* _pData )
{
	testValue++;
	write32( 0x20600000, 0 );
}

Soooooo I guess my question is, how can I wait for vsync using the Circle library?

Thank you very much for an awesome library. Super easy to use and very lightweight! My game is running within a second after the power switch is flipped, rather than first having to wait for ages for Raspbian to boot up. That is fantastic!

CPU Frequency

Hi.

I am executing a cpu heavy application which uses circle. The application iteratively performs some logistics ( reading inputs, allocating memory) and then it turns into a computative intensive benchmark. I want to boot raspberry PI with a low frequency ( 600Mhz ) perform all the logistics in the low frequency ( 600Mhz) and then turn frequency on the Max ( 1200 Mhz).
On a pseudo code this looks like :

Boot....
Application:
while ( True ){
setFreqToLow(600)
PerformLogistics()
setFreqToHight(1200)
PerformComputations()
}

When I boot PI using the fast option it boots with the high frequency ( 1200 ) and then it toggles between 600Mhz-1200 Mhz normally. When I dont use the "fast" option the PI boots on the low (600Mhz ) frequency but it cannot set the high frequency afterwards. The CCPUThrottle::SetSpeed(CPUSpeedMaximum,True) returns "0".

Any idea why this happens? Thank you very much in advance.

Socket: Connection closed in the middle of file transfer

I am currently using the socket api by Circle.

On the Raspi side, I opened a socket and created a TCP connection with a server that is running the "SimpleHTTPServer" module in Python.
I was able to make a HTTP GET request to ask for a file from this server, and receive it completely.

This works for files smaller than ~2MB.

When I try to receive a file that is 4MB, it will pause after receiving 1408 blocks of the file (each block is 1460 bytes). I have a loop that keeps calling receive() and the ending condition is whether or not its return value is 0.

When I check on the server side, it says that the connection is closed by the remote host. Therefore the connection was closed by the Raspi side.

Do you have any clue why this is happening?

Thanks in advance.

Open questions about CPWMSoundDevice class

Hi Rene,

I'm working again with Circle and have some questions that I want comment with you.

I'm using the CPWMSoundDevice class and, examining his code, you say that supports 12 bit samples at 44.1 sampling frequency. But in code I can see:

assert (nBitsPerSample == 8 || nBitsPerSample == 16);

so, the accepted sizes are 8 & 16. I would prefer to send 12-bit samples and the driver don't need resample on-the-fly. If I'm not wrong, the sampling freq. is configured with:

write32 (ARM_PWM_RNG1, PWM_RANGE);
write32 (ARM_PWM_RNG2, PWM_RANGE);

at the Run method. PWM_RANGE is defined as:

#define PWM_RANGE (CLOCK_FREQ / CLOCK_DIVIDER / SAMPLE_RATE)

so, the PWM_RANGE for 44.1 kHz is programmed with value 5668 because the result is truncated to lower integer. With this number as divisor, the resulting freq is 44107.26888 kHz. With 5669 could be 44099.48845, near from the intended sampling freq than 44107.

Anyway, would it be possible to change the sampling freq without recompiling the library?

My problem is that I need to generate the samples on-the-fly, and a frequency as 44099.48 is a problem to generate the samples. Trying different numbers, I've found two divisors interesting to me, that generates freqs. of 25 kHz and 31.25 kHz. I don't know when is possible to change the #define and expect the generated freq. would be the desired. I don't understand very well the MASH filters principle, and I depend of a correct freq to synchronize another things.

At another hand, could exist a method to know the PWM state without polling the driver? (using a callback from DMACompletionRoutine when nTransferSize = 0?, i.e.). I'm calling repeatedly to Playback method but that's very sensible to USB transfers (I guess) and it's easy to hear clicks!, pops!, and all sort of dirty sounds. The worst part is with a PI B+, that can't copes with all the work to be done.

It's very important to my app that can be a reliable method to generate the sound samples and, probably, use the PWM as a fine clock.

Best regards

Arithmetic operations of global variables

First of all thanks for providing this huge set of examples.

I'm facing problem while doing floating point arithmetic operations on global variables. The error log is given below,
kernel.o: In function std::sin(float)': /usr/arm-none-eabi/include/c++/6.3.1/cmath:449: undefined reference to sinf'
kernel.o: In function std::tan(float)': /usr/arm-none-eabi/include/c++/6.3.1/cmath:506: undefined reference to tanf'
kernel.o: In function std::sqrt(float)': /usr/arm-none-eabi/include/c++/6.3.1/cmath:487: undefined reference to sqrtf'
../../Rules.mk:74: recipe for target 'kernel7.img' failed
make: *** [kernel7.img] Error 1

If I declare the variables in local scope or as static in global scope then the bare metal program compiles properly.
Do you have any idea why this linker issue are persisting?

Circle not working?

Hi, I'm trying to use circle with my raspberry 3.
I could compile the 01 sample (arm-none-eabi- as PREFIX, RASPPI=3 in Rules.mk).
I have copied the boot files in the sd, and the kernel.img generated by gcc.
Unfortunately I can't see anything happening (if I understand correctly, the ACT led is the one near the power led, green).
Am I doing something wrong? How can I know?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.