Git Product home page Git Product logo

ckormanyos / real-time-cpp Goto Github PK

View Code? Open in Web Editor NEW
553.0 44.0 156.0 251.19 MB

Source code for the book Real-Time C++, by Christopher Kormanyos

License: Boost Software License 1.0

Assembly 0.30% C++ 92.85% C 2.03% Batchfile 0.04% Shell 3.47% CMake 1.24% Python 0.08%
embedded-systems high-performance microcontroller realtime arduino cortex-m cpp11 embedded stm32 cpp cpp14 cpp17 cpp20 bare-metal

real-time-cpp's People

Contributors

ajneu avatar ckormanyos avatar gantzm avatar gdobato avatar imahjoub avatar jwinarske avatar lgtm-migrator avatar mark-1003 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

real-time-cpp's Issues

Review and verify the clock settings for stm32f407 and stm32f429

Hi Chris,

Note to self: Please review and verify the clock settings for stm32f407 and stm32f429. In particular, make sure that the maximum clock is properly set. Also investigate the so-called over-drive mode of the stm32f429 at 180MHz. Do we need over-drive for this target at 180MHz?

Cheers, Chris.

repository structure?

Hi Christopher,

I appreciate your book and your code, but I'm not very happy with the way this repository is organised. Could you split it and move the tools separate from the sources?

I'm using OS X and the Windows specific tools are of little use for me (not to mention the use of Git for distributing very large binaries, available anyway from their publishers).

Also, a more portable approach would be highly appreciated. For ARM projects you can use Eclipse and the GNU ARM Eclipse plug-ins.

Thank you,

Liviu

Third edition? Not an issue :)

Dear Mr. Kormanyos
I know that this is not the right place to ask questions, but I wasn't able to find your personal email.
So, I'll ask here, if there are any plans for a third edition?
Have you noticed something in the new C++ 17 standard that could warrant a new version of the book?

Thank you :)

The new Chapter09_07 source code

Hi Chris - I see that you've added this new section Chapter09_07 source code. My only question is that there isn't a Chapter 9.7 in your current edition of the book? Can you explain what this new section is for (appears to be display related)?

Thanks!

(PS. My students are enjoying the class and using your book and software....)

gnurx-elf build error

What toolchain should I use to work around this?

gcc_4.8.4.201902_gnurx-elf

/media/joel/SolidState/real-time-cpp/ref_app/src/app/benchmark/app_benchmark_crc.cpp: In function ‘bool app::benchmark::run_crc()’:
/media/joel/SolidState/real-time-cpp/ref_app/src/app/benchmark/app_benchmark_crc.cpp:13:4: error: could not convert ‘{{49u, 50u, 51u, 52u, 53u, 54u, 55u, 56u, 57u}}’ from ‘’ to ‘const mcal::memory::progmem::array<unsigned char, 9ul>’
}};
^

Handle previous suggestions from #12

Some previous suggestions from #12 were not yet fully interpreted, nor were they fully included. Somehow the PR was overlooked and forgotten.

Some suggestions are very good and should be implemented. For instance suggestions about using standard GNUmake symbols (CXXFLAGS for C++ flags, CPPFLAGS for preprocessor flags, LDFLAGS for linker flags) are still relevant.

Sometimes the argument in UINT8_C is a suffixed integer but it should be an unsuffixed integer

In this code:

    static const std::uint8_t the_lower_interrupt_vector_table_data[64U] =
    {
      UINT8_C(0x18U), UINT8_C(0xF0U), UINT8_C(0x9FU), UINT8_C(0xE5U), UINT8_C(0x18U), UINT8_C(0xF0U), UINT8_C(0x9FU), UINT8_C(0xE5U),
      UINT8_C(0x18U), UINT8_C(0xF0U), UINT8_C(0x9FU), UINT8_C(0xE5U), UINT8_C(0x18U), UINT8_C(0xF0U), UINT8_C(0x9FU), UINT8_C(0xE5U),
      UINT8_C(0x18U), UINT8_C(0xF0U), UINT8_C(0x9FU), UINT8_C(0xE5U), UINT8_C(0x18U), UINT8_C(0xF0U), UINT8_C(0x9FU), UINT8_C(0xE5U),
      UINT8_C(0x18U), UINT8_C(0xF0U), UINT8_C(0x9FU), UINT8_C(0xE5U), UINT8_C(0x18U), UINT8_C(0xF0U), UINT8_C(0x9FU), UINT8_C(0xE5U),
      UINT8_C(0x00U), UINT8_C(0x84U), UINT8_C(0x00U), UINT8_C(0x00U), UINT8_C(0x40U), UINT8_C(0x80U), UINT8_C(0x00U), UINT8_C(0x00U),
      UINT8_C(0x80U), UINT8_C(0x80U), UINT8_C(0x00U), UINT8_C(0x00U), UINT8_C(0xC0U), UINT8_C(0x80U), UINT8_C(0x00U), UINT8_C(0x00U),
      UINT8_C(0x00U), UINT8_C(0x81U), UINT8_C(0x00U), UINT8_C(0x00U), UINT8_C(0x40U), UINT8_C(0x81U), UINT8_C(0x00U), UINT8_C(0x00U),
      UINT8_C(0x80U), UINT8_C(0x81U), UINT8_C(0x00U), UINT8_C(0x00U), UINT8_C(0xC0U), UINT8_C(0x81U), UINT8_C(0x00U), UINT8_C(0x00U),
    };

the argument in UINT8_C is always a suffixed integer as the suffix 'U' is always used. However, according to 7.20.4 Macros for integer constants

The argument in any instance of these macros shall be an unsuffixed integer constant (as defined in 6.4.4.1) with a value that does not exceed the limits for the corresponding type.

Depending on how UINT8_C is defined, the compiler may or may not detect this error.

If UINT8_C is defined like this:

#define UINT8_C(x) ((uint8_t) (x##U))

the compiler will display an error something like this:

main.cxx:16:27: error: unable to find numeric literal operator 'operator""UU'
   16 | std::uint8_t ui = UINT8_C(0xffU);
      |                           ^~~~~
main.cxx:15:32: note: in definition of macro 'UINT8_C'
   15 | #define UINT8_C(x) ((uint8_t) (x##U))
      |                                ^
main.cxx:16:27: note: use '-fext-numeric-literals' to enable more built-in suffixes
   16 | std::uint8_t ui = UINT8_C(0xffU);
      |                           ^~~~~
main.cxx:15:32: note: in definition of macro 'UINT8_C'
   15 | #define UINT8_C(x) ((uint8_t) (x##U))

If UINT8_C is defined like this:

#define UINT8_C(x)      x

the compiler will not display an error.

General questions regarding real-time C++

Thank you sir for producing such an excellent book for helping hobbyists like me understand a little about building real-time systems with microcontrollers.

I looked through the book and noticed that you had timings for some of your C++ methods. How did you calculate how long those methods took to execute? How did you confirm that those methods consistently took that amount of time to execute? Did you have a special test tool or did you just add a real-time clock to your circuit and ran the same method multiple times to see if the execution times were consistent? How does one calculate the length of time for a method to execute during the architecture phase?

Building STL on Linux.

When running ./target/build/build.sh avr rebuild the build fails because there is no STL implementation built. It appears an STL implementation is provided in the src/utils/STL directory, but I can find no build files or instructions for building this implementation.

Is the src/utils/STL used, or is there a different STL dependency that needs to be downloaded and built?

Consider to use target=host for PC

Consider to use target=host for PC. At the moment, the specialized target x86_64-w64-mingw32 is used. But this does not make sense on *nix hosts.

32/64 bit portability

Can you enable switching between -m32 and -m64?

In file included from /media/joel/SolidState/real-time-cpp/ref_app/src/os/os_cfg.h:14:0,
from /media/joel/SolidState/real-time-cpp/ref_app/src/os/os.h:13,
from /media/joel/SolidState/real-time-cpp/ref_app/src/os/os.cpp:12:
/media/joel/SolidState/real-time-cpp/ref_app/src/util/utility/util_time.h: In instantiation of ‘class util::timer’:
/media/joel/SolidState/real-time-cpp/ref_app/src/os/os_cfg.h:45:23: required from here
/media/joel/SolidState/real-time-cpp/ref_app/src/util/utility/util_time.h:27:7: error: static assertion failed: The width of the timer tick_type can not exceed the width of mcal::gpt::value_type
static_assert(std::numeric_limits<tick_type>::digits <= std::numeric_limitsmcal::gpt::value_type::digits,
^~~~~~~~~~~~~

Question about the Reference Application

Chris - One of my students would like to know why the mcal_spi.h and mcal_spi.cpp are commented out in the reference application. I told them it was because you were using the reference app to benchmark the timing of the MD5 algorithm. Was I correct?

Thanks!

Explanation for Differences (between 06_01 & 01a and 17_03 & 03a)

Hi Chris - Back again teaching my course using your new Third Edition of the book. Love all the updates! Previously, you had provided an explanation of the 02_03 & 03a differences (timer blocking delay vs a tiny multi-tasking scheduler delay). Could you provide a similar explanation for the differences for the chapter06_01 and 06_01a and the chapter17_03 & 03a? I'm sure these were both updates since you published the third edition. May I suggest just added a "read.me" file in the revised directories for the "a" versions. This would help us to understand the new directories after the publishing and why you created them. Thanks again, my students really appreciate your book!

Request for a portable ARM(R) build with Eclipse / GNU ARM plug-ins

There is a request to create a portable ARM(R) build with Eclipse / GNU ARM plug-ins.

This will be useful for various targets in the ref_app including:

  • Discovery Boards like stm32f100, stm32f407, stm32f429
  • BeagleBone Black am335x bare-metal
  • Potential future support for raspi.

Cheers, Chris.

Clean up the linker scripts in the examples

The linker scripts in the examples (other than the ref_app) use input library files that do not belong there such as libg.a, libm.a, libgcc.a, etc. These should be cleaned up.

Building on Linux hangs build when printing GCC version.

In the file target/app/make/app_make_linux.gmk the section:

        @$(ECHO) GCC version...
	@$(CC) -xc++ -E -v -

hangs waiting for input because of the trailing '-'. I have removed the trailing dash and the command no longer hangs, though it does give a warning about the options.

Latest mips-mti-elf linker bug

Codescape.GNU.Tools.Package.2019.09-01.for.MIPS.MTI.Bare.Metal.CentOS-6.x86_64

mips-mti-elf-objcopy: ref_app.hex: address 0xffffffff9d000000 out of range for Intel Hex file
mips-mti-elf-objcopy:ref_app.hex: bad value

Workaround - get prior or later version of the toolchain...

CMake Targets not including toolchain files

Through examining real-time-cpp/CMakeLists.txt and real-time-cpp/ref-app/CMakeLists.txt, I do not see how the target toolchain files in ref-app/cmake are referenced.

root CMakeLists.txt calls
externalProject_add with -DCMAKE_TOOLCHAIN_FILE=${CMAKE_SOURCE_DIR}/ref_app/cmake/gcc-toolchain.cmake

Examination of gcc-toolchain.cmake shows most of the common gcc compiler, asesmbler, and linker flags are set. However I don't see any includes for the specific target chosen at cmake configure time.

Have I missed something?

Examples to be as lean and clear as possible.

Some examples contain files, in particular mcal or chip driver codes, that blur the clarity of the given example.

For instance, external chip port driver code in examples that make no use of it.

Try to identify and remove unused files 8especially even chip drivers) from examples that do not use them

This issue is intended to help make sure that the examples are lean and clear as possible.

Permission for Real-Time C++ Book Excerpts

Hi Chris - Good to chat with you again! After a one semester break, I should be teaching my course at the University of Puerto Rico - Mayaguez again in August. I've had two successful classes using your book and I was happy to see that the 2nd Edition is out now! I've order two books - one for me and one for UPRM.

Question for you (or the publisher). I would like to take snapshot copies from certain pages from your book to add to my Prezi presentations. For the first two semesters, I only referenced your book and had the students turn to those pages when needed. Very awkward especially since I'm teaching live virtually using zoom.us service. How do I get permission to use your book in this way? My presentations are not publicly available and limited to the students who are in my course and who have also purchased the book.

I want to ensure that I'm meeting all copyright restrictions with your book and any restrictions that the publisher my have.

Please let me know what I am able to do with your book during class time.

Thanks!
Ken Vaughan
Profesor
Departamento de Ingeniería Eléctrica y Computadoras
Recinto Universitario de Mayagüez
Universidad de Puerto Rico
[email protected]

Execute permission for bash scripts not set on Linux

If the repository is cloned on Linux with the command git clone https://github.com/ckormanyos/real-time-cpp.git the execute permission bit for each of the bash build scripts is not set.

For example, as can be seen in the directory listing for chapter04_04 below, the execute permission bit for build.sh is not set.

$ ls -la
total 144
drwxrwxr-x  5 brian brian  4096 Jun 12 23:39 .
drwxrwxr-x 16 brian brian  4096 Jun 12 23:39 ..
-rw-rw-r--  1 brian brian  5966 Jun 12 23:39 build.bat
-rw-rw-r--  1 brian brian  6498 Jun 12 23:39 build.sh
-rw-rw-r--  1 brian brian   949 Jun 12 23:39 chapter04_04.atsln
-rw-rw-r--  1 brian brian 21897 Jun 12 23:39 chapter04_04.cppproj
-rw-rw-r--  1 brian brian  1624 Jun 12 23:39 chapter04_04.sln
-rw-rw-r--  1 brian brian 33029 Jun 12 23:39 chapter04_04.vcxproj
-rw-rw-r--  1 brian brian 18877 Jun 12 23:39 chapter04_04.vcxproj.filters
drwxrwxr-x  2 brian brian  4096 Jun 12 23:39 images
-rw-rw-r--  1 brian brian  3604 Jun 12 23:39 readme.md
drwxrwxr-x 11 brian brian  4096 Jun 12 23:39 src
drwxrwxr-x  4 brian brian  4096 Jun 12 23:39 target
-rw-rw-r--  1 brian brian 11813 Jun 12 23:39 target.vcxproj
-rw-rw-r--  1 brian brian  2315 Jun 12 23:39 target.vcxproj.filters
$ 

Attempting to run the command ./build.sh results in an error:

$ ./build.sh
bash: ./build.sh: Permission denied
$

It's possible to resolve this issue by setting the execute permission bit for build.sh with the command chmod +x build.sh. However, it would be nice if the execute permission bits for bash scripts were already set in the GitHub repository so that this manual intervention could be avoided.

Ensure that the bash shells for examples build

Over time some of the bash files for the examples may have become broken or were migrated improperly.

  1. Ensure that the bash files for the examples all function properly
  2. Are the file lists correct?
  3. Set execution rights properly with chmod.

Textbook doesn't reference chapter02_03a

Chris - Like this textbook! Incorporating into my course on real-time embedded software. In Chapter 2.3, I don't see a reference to the companion code directory chapter02_03a. Did this companion code come later after the publishing of the book? I'm trying to determine the difference between chapter02_03 and chapter02_03a directories. chapter02_03 does not contain the led.cpp file that is shown in the book (maybe on purpose as you suggest "Try to build, flash and run the LED program with timing..."). chapter02_03a does contain the led.cpp file that is shown as an "app" namespace.

I am running on Mac OSx and can't use Visual Studio. I can't load the projects yet (may install Parallels so I can run VS).

Thanks!

Review raspi target to ensure it works, improve docs and check a newer board

It's been a while since there was confirmed use of the raspi target in the reference appliction.

Review raspi target to:

  • Ensure that it works.
  • Improve docs to provide enhanced information on the boot and running non-Linux bare metal.
  • Provide better instructions for handling SD card and boot.
  • Check with a newer board such as 4.

Library with avr-ar

Hi Christopher,

actually mcal would be great to place into a library archive.
I've given this a try with the code from chapter02_03, but think I'm doing something wrong.
Would be nice if someone could give this a try also. (perhaps someone well acquainted with gcc and/or binutils here somewhere??)

Background: I actually want to write some nice CMakeLists.txt, that then handle this nicely (library creation); but I need to know if I'm doing something wrong (or not?)
.
.
.

Anyway... I think I'm doing it wrong, since I get a really really small hex (I don't currently have AVR hardware, so I cannot test the hex.)

Here's what I've tried:

  • Create bin/libmcal.a

    • Create the objects
      bin/mcal.o bin/mcal_gcc_cxx_completion.o bin/mcal_cpu.o bin/mcal_gpt.o bin/mcal_irq.o bin/mcal_led.o
    • Combine those objects into an archive bin/libmcal.a with this command:
    avr-ar qc  bin/libmcal.a     bin/mcal.o bin/mcal_gcc_cxx_completion.o bin/mcal_cpu.o bin/mcal_gpt.o bin/mcal_irq.o bin/mcal_led.o
    • Call ranlib on the archive:
    avr-ranlib  bin/libmcal.a
  • Create bin/libstartup.a

    • Create the objects
      bin/crt0.o bin/crt0_init_ram.o bin/crt1.o bin/int_vect.o
    • Combine those objects into an archive bin/libstartup.a with this command:
    avr-ar qc  bin/libstartup.a     bin/crt0.o bin/crt0_init_ram.o bin/crt1.o bin/int_vect.o
    • Call ranlib on the archive:
    avr-ranlib  bin/libstartup.a
  • Create bin/sys_start.o (from sys_start.cpp) and link if with bin/libmcal.a and bin/libstartup.a

    • Create object bin/sys_start.o
    • Link
    avr-g++ -x none -mrelax -nostartfiles $CFLAGS $CPPFLAGS $CINCLUDES -Wl,--gc-sections -Wl,-Ttarget/micros/avr/make/avr.ld,-Map,bin/chapter02_03.map bin/sys_start.o  -o bin/chapter02_03.elf   bin/libmcal.a bin/libstartup.a

Improve the repo's readme.txt

The repo's readme.txt is out of date regarding the supported targets and partially incorrect now that the tool chains have been removed. Update the supported target list and remove the tool chain documentation.

mcal_led not MCU related

LED functions are not MCU related, this should be platform dependent functionality.
My suggestion is to create a mcal_dio for I/O abstraction and moving led macros like

define LED1 mcal_dio_1 to app or cust folder.

cap 4 led class, toogle problem

In Chapter 4 maybe have some problems

  1. In led_base class and led_port does not existe specification for type of port like existe in the second chapter
    This lines are completly missing
_reinterpret_cast(port) &= static_cast(~bval);

_reinterpret_cast(port - 1U) |= bval;

When I add this lines in constructor of led_port and compile, it don't work

Then I need to add a delete function in led_port because without it I can't compile

void operator delete(void *) {}

If the funtion not exist, this error show up

main.o: In function `led_port::~Led_port()': main.cpp:(.text._ZN8led_portD0Ev[led_port::~led_port()]+0x0): undefined reference to`operator delete(void*)' collect2: error: ld returned 1 exit status

System-tick (for AVR)

Hi Mr. Kormanyos,

I'm so glad I found your book on C++ for microcontrollers. Really great!

Being very curious as to the system-tick, I've skipped forward to Chap. 9.3

The code is mcal::gpt::value_type mcal::gpt::secure::get_time_elapsed()

What I asked myself was:
can we be (provably) certain, that this code for the system-tick is correct under all circumstances?

.
.
Here's my attempt at an explanation...
.

What do we want:

a 32-bit system-tick-counter that increments every single μs

How do we get there?
  • Use tcnt0, which is a 8-bit counter; and have it increment overy 0.5 μs (8 bit counter details in datasheet...)

  • Fire an interrupt every time tcnt0 overflows from 255 to 0 (to extend the bit-range of tcnt0, with a software-variable called system_tick)

  • Call an appropriate interrupt routine (configured in ref_app/target/micros/avr/startup/int_vect.cpp) with the following code ( void __vector_16()):

    void __vector_16()
    {
      // Increment the 32-bit system tick with 0x80, representing 128 microseconds.
      system_tick += static_cast<std::uint8_t>(0x80U);
    }

    This interrupt routine is called every 256 ticks (of tcnt0), hence every 128 μs

  • The full 32-bit system-tick-counter can thus be constructed like this:

    microsecond_tick = system_tick | (tcnt0 >> 1);       // highly unsafe
The problem of consistency

The above reading of system_tick (in the bit-or) is completely unsafe.

Why? Well system_tick is a 32 bit unsigned, and the AVR is a 8-bit microcontroller.

So the very dangerous thing, is that the microprocessor does not read the 4 bytes of system_tick in an atomic operation: while constructing the value microsecond_tick above, the processor basically needs 4 assembly instructions to access the 4 bytes of system_tick (each byte is accessed individually).
And while the these 4 bytes are being read, an interrupt may fire. And it could very well the the one that changes the very value that is still being read i.e. system_tick: this means that once the interrupt routine returns, we continue reading the bytes of a modified system_tick. It was modified "in between" it being read!! We don't end up with a consistent read.

Here's an example of this problem:
Assume that currently system_tick = 0xFFFFFF80.

Now lets say we read those 4 bytes, for example with code such as std::uint32_t my_var = system_tick;.
After reading the 2 lower bytes, it could happen that tcnt0 overflows from 255 to 0 triggering the interrupt which causes __vector_16() to be called immediately. This would then add 0x80 to system_tick causing it to become 0x00000000. Then the interrupt routine returns, and we continue constructing variable my_var by reading the remaining upper 2 bytes of system_tick.
And most problematically we end up with:

my_var == 0x0000FF80

This is completely wrong!
What would have been correct for my_var (which reads system_tick, which is a multiple of 0x80) is either: 0xFFFFFF80 OR an instant after the interrupt routine, 0x00000000.

Getting it consistent

In order to get a consistent reading, we need a way of knowing that we read the 4 bytes of system_tick, without the interrupt routine changing the value, while we are reading it.
One way to do this, is perhaps to lock interrupts. But no, that a very very bad way. That is a complete waste of resources. Much better is the way that it is implemented in the code.
The method used, is to read system_tick into variable sys_tick_1 (ref) and afterwards check if the "bad" interrupt occurred while we were reading. How to do it? Well the "bad" interrupt only occurs when tcnt0 overflows from 255 to 0. So we can just

reading system_tick (with code sys_tick_1 = system_tick); and then check the before and after value accordingly.

  • If tim0_cnt_2 >= tim0_cnt_1 we know that no overflow occurred; and our reading is good (ref "if"-branch)
  • But if an overflow occurred and tcnt0 wrapped from the high values (e.g. 255) to around 0 (then continuing with 1, 2, 3...), then we known that tim0_cnt_2 < tim0_cnt_1: and also know that an interrupt occurred. In that case we can simply do another reading of system_tick, and be certain (this-time-around) that no "bad" interrupt is upcoming (since it has just occurred an instance previously). (ref "else"-branch)
    This is exactly what is used in the code!
Remaining questions

A question that I have is
The code as it currently reads:

// Perform the consistency check.
const mcal::gpt::value_type consistent_microsecond_tick
  = ((tim0_cnt_2 >= tim0_cnt_1) ? mcal::gpt::value_type(sys_tick_1  | std::uint8_t(std::uint16_t(std::uint16_t(tim0_cnt_1) + 1U) >> 1U))
                                : mcal::gpt::value_type(system_tick | std::uint8_t(std::uint16_t(std::uint16_t(tim0_cnt_2) + 1U) >> 1U)));

could (maby) be changed to this:

// Perform the consistency check.
const mcal::gpt::value_type consistent_microsecond_tick
  = ((tim0_cnt_2 >= tim0_cnt_1) ? mcal::gpt::value_type(sys_tick_1  | std::uint8_t(tim0_cnt_1 >> 1U))
                                : mcal::gpt::value_type(system_tick | std::uint8_t(tim0_cnt_2 >> 1U)));

Spot the difference!! Yip: why is the read value of tcnt0 (either tim0_cnt_1 or tim0_cnt_2) being increased by 1 in the original?... So: Why + 1U?

Is it really necessary? As far as I can tell, the +1 is an attempt to make the return value as close as possible to the real tcnt0 value. This may be elegant... since by the time consistent_microsecond_tick is calculated and returned, some small amount of time may have passed (so adding 1 tick of tcnt0 [equiv. to 0.5 μs]) can compenstate for this.

The addition confused me at first, but it is correct.
(Edit-19.03.2015: It is not correct. There is an error in the 3rd last row below. See later post below) Here's the example I used to check the validity:

...If... 
sys_tick_1  =   0xFFFFFF80
...and...
tim0_cnt_1  = tcnt0 = 0xFF

... then

consistent_microsecond_tick_V2 = sys_tick_1  | (std::uint8_t(tim0_cnt_1 >> 1U);
...This yields: 
consistent_microsecond_tick_V2 = 0xFFFFFF80 | 0x7F
...therefore
consistent_microsecond_tick_V2 = 0xFFFFFFFF        // ok!

But if 1 is added:
==============
consistent_microsecond_tick = sys_tick_1  | std::uint8_t(std::uint16_t(std::uint16_t(tim0_cnt_1) + 1U) >> 1U);
...Then this yields:
consistent_microsecond_tick = 0xFFFFFF80 | (0x100 >> 1U)
...so 
consistent_microsecond_tick = 0xFFFFFF80 | 0x80
...therefore
consistent_microsecond_tick = 0x00000000          // also ok! (a bit more in the "future"... perhaps closer to the "present")
Checking the assembler code

(on linux)

cd ~/real-time-cpp/ref_app/src/mcal/avr

# create assembler code:
avr-g++ -std=c++11 -I . -I ../../util/STL -I ../.. -S -fverbose-asm -g -O2 mcal_gpt.cpp -o mcal_gpt.s

# create asm interlaced with source lines:
avr-as -alhnd mcal_gpt.s > mcal_gpt.lst

This is pretty cool since I can now verify that reading system_tick is indeed 4 assembly instructions.

 433 007c 8091 0000         lds r24,_ZN12_GLOBAL__N_111system_tickE  ;  sys_tick_1, system_tick
 434 0080 9091 0000         lds r25,_ZN12_GLOBAL__N_111system_tickE+1    ;  sys_tick_1, system_tick
 435 0084 A091 0000         lds r26,_ZN12_GLOBAL__N_111system_tickE+2    ;  sys_tick_1, system_tick
 436 0088 B091 0000         lds r27,_ZN12_GLOBAL__N_111system_tickE+3    ;  sys_tick_1, system_tick

(The instruction set can be seen here)

hmmm... ok... this ended up being a huge write-up (helping me understand the concepts better). I hope you don't mind. (I just realized that there is a wiki here. Perhaps it is better if I transfer this text to the wiki, since it is not really an "issue". Do you think that might be ok (and in your interest)?)

.
.
.
Best wishes and thanks for your book and all the code!!
A.

.
.

PS: I saw that you even have a own STL implementation for embedded. Really cool! Should be more known!
Oh... you might also enjoy browsing these: ETL, estl-teaser (also), rtcpp, Practical Guide to Bare Metal C++

Fix the header dependencies with GNU make d-files

It seems like header-only dependencies are proken in build (not rebuild) of the reference application and (potentially) the examples.

The so-called d-files for GNU make dependencies are not being used properly.

  • Reproduce the problem to verify/not-verify if there is a problem.
  • If there is a problem, fix with d-files and VPATH.

Real-Time C++ for Eclipse or Atmel Studio /.0

Hi Chris,
I'm considering to use your textbook in my university course for undergrade students.
We are using Eclipse with the Arduino plugin (Sloeber V4) for C projects. When I tried your introductionary LED-example it failed finding the . In this Arduino installation I also couldn't find the projects C/C++ Build option to add additional include paths or to select the g++ compiler version.
Alternatively I tried Atmel Studio 7.0 which resulted in almost the same problem.

As I can't expect my students to add all required paths, libraries and compilers manually as described in apendix C I'm asking if you have an installation script for either Atmel V7 or Eclipse/Arduino which adds all required features automatically.

With kind regards
Juergen

Free Toolchain for Windows

Hello, I purchased your book and look forward to working through the examples. Unfortunately, I am unable to compile even the very first LED blink example, for my Atmega 328P MCU. The error I am receiving is: "cstdint: No such file or directory". I first tried the Arduino 1.5.7 IDE , trying to pass -std=c++11 flag to the compiler through the hardware/arduino/avr/platform.txt file, which did not work. I then downloaded Atmel Studio, created an executable C++ project, added the -std=c++11 flag through my project tool chain configuration, but received the same "cstdint: No such file or directory" error. I searched the AVR8 directory and sure enough, there was no cstdint.h file. The other directories (ARM, AVR32) contained the file, but not the 8-bit AVR.

I noticed there was some discussion regarding deletion of the tools from your directories, which I do agree with. However, I'm at a loss to finding a description of the build/flash processes using the standalone Atmega 328P MCU described in your book. I can build and flash C programs to the MCU without issue. But seeing as your entire book is about C++ that does not help.

Is it possible for you to point me in the right direction? A procedure to build a working AVR8 tool chain on Windows 7? I am using a FT232 USB to serial programing interface (virtual COM) with the Atmega 328P MCU running Optiboot. Thank you.

Improve beagle bone am335x low level initialization

The beagle bone am335x low level initialization should be improved.

  • The DMTimer7 clock init polls on the wrong bits and could better use the entire range of the counter register.
  • Chip initialization optimizations like caching, branch prediction, ect. can be called *after' the bulk of the other low-level initialization.

Setting up the gnu tool chain for the ATMEL ATMega328p microcontroller

Dear Mr. Kormanyos,
I got stuck installing the GCC prerequisites. I have never worked or built such a system. In the appendix it is not very clear on how to set them up. I am using a Windows 10 (64 bit) computer and all the prerequisites have been updated from the time that you wrote the book.

Is there any help you can offer to put me in better position to build this tool chain.
Kind regards,
Gabriel

problems building the target with cmake in Linux

Hello @jwinarske , hello @ckormanyos ,

after the commit 488b7fe for adding support to clang, i can not build any more the target in linux(debian10). I get the error below by passing the same variables as I did when the first support for cmake was added:

gdobato@unix:~/Workspace/real-time-cpp/build_linux_host$ cmake ../ref_app -DTRIPLE=arm-none-eabi -DTARGET=stm32f429 -DCMAKE_TOOLCHAIN_FILE=../ref_app/cmake/gcc-toolchain.cmake
-- CMAKE_BUILD_TYPE not set, defaulting to MinSizeRel.
-- Triple ................. arm-none-eabi
-- Triple Arch ............ arm
CMake Error at cmake/gcc-toolchain.cmake:51 (get_filename_component):
get_filename_component called with incorrect number of arguments
Call Stack (most recent call first):
/usr/share/cmake-3.13/Modules/CMakeDetermineSystem.cmake:91 (include)
CMakeLists.txt:33 (project)
-- Toolchain Path .........
-- Triple ................. arm-none-eabi
-- Triple Arch ............ arm
CMake Error at cmake/gcc-toolchain.cmake:51 (get_filename_component):
get_filename_component called with incorrect number of arguments
Call Stack (most recent call first):
/home/gdobato/Workspace/real-time-cpp/build_linux_host/CMakeFiles/3.13.4/CMakeSystem.cmake:6 (include)
CMakeLists.txt:33 (project)
-- Toolchain Path .........
-- The CXX compiler identification is GNU 8.3.1
-- The ASM compiler identification is GNU
-- Found assembler: /home/gdobato/Workspace/MCUPlatform/target/tools/toolchain/LINUX/gcc-arm-none-eabi-8-2019-q3-update/bin/arm-none-eabi-gcc
-- Check for working CXX compiler: /home/gdobato/Workspace/MCUPlatform/target/tools/toolchain/LINUX/gcc-arm-none-eabi-8-2019-q3-update/bin/arm-none-eabi-g++
Illegal option -g
-- Check for working CXX compiler: /home/gdobato/Workspace/MCUPlatform/target/tools/toolchain/LINUX/gcc-arm-none-eabi-8-2019-q3-update/bin/arm-none-eabi-g++ -- works
-- Detecting CXX compiler ABI info
Illegal option -g
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
Illegal option -g
Illegal option -g
Illegal option -g
Illegal option -g
Illegal option -g
-- Detecting CXX compile features - done
-- Generator .............. Unix Makefiles
-- Build Type ............. MinSizeRel
-- Configuring incomplete, errors occurred!
See also "/home/gdobato/Workspace/real-time-cpp/build_linux_host/CMakeFiles/CMakeOutput.log".
See also "/home/gdobato/Workspace/real-time-cpp/build_linux_host/CMakeFiles/CMakeError.log".

It seems that the variable GCC_TOOLCHAIN_PREFIX is not right set in some places. E.g, by execute_process, should it not be used as ENV variable? Before investigating further, Am I passing all necessary variables to cmake? or should I pass any additional variable to cmake?

Thanks a lot,
Gabriel

Improve instructions for the GCC build

Improve the instructions for the GCC build from source in MinGW / msys. Attempt to keep the prerequisites up-to-date. Also provide command line options for building arm-none-eabi with multilib and FPU support.

PRs

Hi Chris,

I am interested in working on adding a few platforms, and adding CMake build support. Are you open to PRs on these areas?

Thanks,
Joel

[AppleClang] cmake ../ref_app -DTARGET=host

Only issue left I see building Target host on macOS gcc/AppleClang.

Scanning dependencies of target ref_app
[  3%] Building CXX object CMakeFiles/ref_app.dir/src/app/benchmark/app_benchmark.cpp.o
[  7%] Building CXX object CMakeFiles/ref_app.dir/src/app/benchmark/app_benchmark_complex.cpp.o
[ 11%] Building CXX object CMakeFiles/ref_app.dir/src/app/benchmark/app_benchmark_crc.cpp.o
In file included from /Users/joel.winarske/git/real-time-cpp/ref_app/src/app/benchmark/app_benchmark_crc.cpp:5:
/Users/joel.winarske/git/real-time-cpp/ref_app/src/math/checksums/crc/crc32.h:31:71: error: no type named 'value_type' in
      'std::__1::iterator_traits<mcal::memory::progmem::forward_iterator<const unsigned char, unsigned long> >'
    using value_type = typename std::iterator_traits<input_iterator>::value_type;
                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~
/Users/joel.winarske/git/real-time-cpp/ref_app/src/app/benchmark/app_benchmark_crc.cpp:16:27: note: in instantiation of function template specialization
      'math::checksums::crc::crc32_mpeg2<mcal::memory::progmem::forward_iterator<const unsigned char, unsigned long> >' requested here
    math::checksums::crc::crc32_mpeg2(app_benchmark_crc_data.cbegin(),
                          ^
1 error generated.
make[2]: *** [CMakeFiles/ref_app.dir/src/app/benchmark/app_benchmark_crc.cpp.o] Error 1
make[1]: *** [CMakeFiles/ref_app.dir/all] Error 2
make: *** [all] Error 2

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.