circle64 | A 64-bit C bare metal environment for Raspberry Pi
kandi X-RAY | circle64 Summary
kandi X-RAY | circle64 Summary
The Circle64 project is discontinued. Please use the [Circle project] instead, which supports both 32-bit and 64-bit applications now!. Circle64 is a 64-bit C bare metal programming environment for the Raspberry Pi 3. It provides several ready-tested C classes which can be used to control different hardware features of the Raspberry Pi 3. Together with Circle there are delivered some samples which demonstrate the use of its classes.
Support
Quality
Security
License
Reuse
Top functions reviewed by kandi - BETA
Currently covering the most popular Java, JavaScript and Python libraries. See a Sample of circle64
circle64 Key Features
circle64 Examples and Code Snippets
Community Discussions
Trending Discussions on circle64
QUESTION
Admittedly I am new to C++. Unfortunately most of the code I have seen either uses the asm
call or defines an extern
function whose body is in an assembly file.
Which is why I was very exited to find the below code. I have been studying the codebase for 3 days now.
Syntactically I understand every line of the code below; except the one that counts because I don't get how it works!
- types.h defines the
u32
anduintptr
( I have seen them) - ifdef __cplusplus is needed when C and C++ code are mixed. Particularly because of the
extern C
which is C++ specific. Can be omitted if gcc has the-fno-exceptions
argument volatile
is used to prevent the compiler from doing any optimization because the address has to be bite perfect since it's writing/reading to/from registers.
All that said, I still have no idea how this code actually writes or reads from the register.
...ANSWER
Answered 2017-Dec-04 at 17:16You are looking for "memory mapped input-output".
The most common way for CPU to talk to external hardware is through memory bus - the same bus that is used to access normal memory.
First, keep in mind that CPUs interaction with memory involves not just reads and writes, but also things like bus error handling (invalid access), arbitration (multiple devices accessing the same memory) and routing (CPU might want to access multiple memory devices). To handles this, a bus protocol is used.
To write or read external memory CPU has to initiate a transaction. The exact sequence of this is defined by used bus protocol, but it usually involves steps like:
- Sending transcation address, type, length etc.
- Receiving response - allowed or declined (bus error).
- Transmitting the actual data if transaction was allowed.
The device that initiates transcation is called master or initiator, while device that is responsible for handling the transaction is called slave or target.
Device that decides what slave handles the transaction is called decoder or router. So transaction will usually go from master to decoder and then to slave device.
Bus protocol essentialy provides a way to transfer data to or from a device. This device can be a memory device or anything else. In case of memory device, its controller handles transcations by writing or reading data to or from memory cell array.
If you are familiar with Object Oriented Programming, you can think of CPU being connected to external devices via interface which allows reading and writing at specified address. Implementation of this interface can do anything. And this how memory mapped I/O is done - CPU gets connected to a bunch of devices, each receiving transactions at specific address range. Write data to one address and this data will be received by memory device which will store it to memory cell array, write data to another address and it will be received by, lets say, SD controller and will be interpreted as "send SEND_STATUS command to SD card".
If you are also familiar with modern operating systems, you can think of "everything is a file" abstraction. Some files are just plain files e.g. they act as memory. Other files are different. Just like reading /proc/cpuinfo
on Linux gives you information about your CPUs, reading at some address can provide you with information on what IRQs are currently pending or tell you how many incoming messages mailbox has at the moment.
Examples of bus protocols are AXI and AHB. AHB is simpler, AXI is more complex and faster protocol. In case of Raspberry PI it is most likely AXI protocol that is used to connect CPU to hardware.
So regarding your question, those two functions are used to access registers of external devices via memory mapped I/O. Everything else you got right:
volatile
is used to prevent compiler from removing, reordering or in any way changing those memory accesses - without this hardware will not do what we want it to do.u32
is used because many device will not even support anything but 32-bit accesses to keep hardware simple.
Community Discussions, Code Snippets contain sources that include Stack Exchange Network
Vulnerabilities
No vulnerabilities reported
Install circle64
Support
Reuse Trending Solutions
Find, review, and download reusable Libraries, Code Snippets, Cloud APIs from over 650 million Knowledge Items
Find more librariesStay Updated
Subscribe to our newsletter for trending solutions and developer bootcamps
Share this Page