Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ATmegaxxxx - generalised support #48

Merged
merged 24 commits into from
Apr 16, 2020
Merged

ATmegaxxxx - generalised support #48

merged 24 commits into from
Apr 16, 2020

Conversation

feilipu
Copy link
Contributor

@feilipu feilipu commented Apr 7, 2020

ATmegaxxxx

Port for generalised Microchip ATmega architecture

Description

This port provides a basis for supporting all modern ATmega devices using either the Enhanced Watchdog Timer, or Timer0 (an 8-bit Timer generally available across the whole range).

This initial commit contains the information required to build with System Tick being generated by either the:

  • Watchdog Timer, or
  • Timer0 - an 8-bit Timer

Further commits can add support for 16-bit Timers available on many relevant devices. The availability of these 16-bit Timers is somewhat device specific, and these complex and highly configurable Timers are often used to generate phase correct PWM timing (for example) and they would be wasted as a simple System Tick.

The port also provides support for the 3 byte program counter devices ATmega2560 and ATmega2561. Specific to these two devices the RAMPZ and EIND registers need to be preserved during a context switch. Also, due to a limitation in GCC, the scheduler needs to reside in the lower 128kB of flash for both of these devices. This is achieved by adding the .lowtext section attribute to the function prototype.

The ATmega808/809/1608/1609/3208/3209/4808/4809 megaAVR family is a substantial revision of the ATmega platform, and is currently not supported by avr-libc. Therefore the megaAVR 0-series is not supported by this port.

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@feilipu feilipu mentioned this pull request Apr 7, 2020
@feilipu
Copy link
Contributor Author

feilipu commented Apr 7, 2020

To build generic Microchip (AVR) ATmega support the similarities across the family must be considered, and differences respected. Some comments on the strategy.

System Tick

The Microchip (AVR) ATmega family has limited Timer and Pin capabilities, and is designed to be used in physical applications, controlling hardware with PWM and recognising level and edge voltage changes. It does this mainly through the use of 16-bit Timers (for generating phase correct PWM by up/down counting), and Pins attached to Interrupts. The 8-bit Timers are also attached to Pins, and they can be used for more simple timing tasks, requiring only a single counting direction.

The Timers not attached to Pins (and therefore not impacting the application of the device) are an additional 16-bit Timer (very device dependent, eg Timer3 on 1284p), and the Watch Dog Timer.

The Watch Dog Timer is configured identically across the entire range of ATmega devices. It comes in two variants. 1. Old style (eg ATmega32) which does not have an Interrupt capability, and hence on these old devices cannot be used as the System Tick. and 2. New style enhanced WDT, which can generate an Interrupt, and is available on every relevant device.

Using the Watch Dog Timer (WDT) to generate the System Tick does not impact its use as a watch dog. It can be configured to generate a System Tick interrupt, and then one period later to Reset the device if the interrupt is not serviced.

Configuration and usage of the WDT is covered in <avr/wdt.h> which was revised in avr-libc 2.0.0.

Two additional WDT functions are provided in port.c, which extend avr-libc functions to enable the WDT Interrupt without enabling Reset wdt_interrupt_enable(), and to enable both the Interrupt and the Reset wdt_interrupt_reset_enable().

3 Byte PC Devices

The ATtiny, ATmega, ATxmega families can optionally support both 3 byte PC and 3 byte RAM addresses. However, focusing on just the ATmega family only two devices have a large Flash requiring them to use 3 byte PC. These are the ATmega2560 and ATmega2561. This PR provides support for these two devices in two ways.

  • providing portSAVE_CONTEXT() and portRESTORE_CONTEXT() saving both the RAMPZ and EIND registers.
  • providing a portTASK_FUNCTION_PROTO() with the linker attribute .lowtext which is used to ensure that the scheduler and relevant functions remain in the lower 128kB of Flash.

Interrupt Nesting

The ATmega family does not support interrupt nesting, having only one interrupt priority. This means that when the Scheduler is running, interrupts are normally disabled.

When a very time critical process is running, based on microsecond timing generated by one of the Timers, it is important to re-enable interrupts as early as possible in processing a Yield. Fortunately, this is supported through the use of the NO_BLOCK decorator when defining the Interrupt Service Routine.

The NO_BLOCK decorator will enable the global interrupt early in the handling of an ISR (in this case for the Scheduler), and enable interrupts to be nested. Using this method, I've been able to successfully implement an Audio Synthesiser with less than 83 microseconds for each cycle, whilst still running the Scheduler to handle display and input.

Using NO_BLOCK is optional, and should only be done if a critical Timer should interrupt the Scheduler.

Extension proposals for PR

From the basis of this PR, following further commits could be made. But, before doing this work I'd like confirmation to proceed.

  • Identify which "in production" ATmega devices are "old style" devices without WDT Interrupt capability, and configure them to automatically use the 8-bit Timer0 as the System Tick. EDIT identification done, below.

  • Add option to use a number of alternate 16-bit Timers with further configuration. As already noted, these 16-bit Timers are not configured consistently across all devices (or even across different Timers within one device) so providing them as a generalised solution is challenging.

Please comment and provide direction as needed.

@feilipu
Copy link
Contributor Author

feilipu commented Apr 7, 2020

Heap Management

Most users of FreeRTOS will choose to manage their own heap using one of the pre-allocated heap management algorithms, but for those that choose to use heap_3.c, the wrappered malloc() method, there is an issue that needs to be addressed.

The avr-libc library assumes that the stack will always be above the heap, and does a check for this when responding to a malloc() request. This is not the case when Tasks are running, as their stack is located in the early allocated heap address ranges which will be below free heap memory, and so the malloc() request will fail even though heap space is available.

To avoid this issue causing pvPort_Malloc() to fail, the user needs to issue this tuning statement BEFORE they use the heap, or use the xTaskCreate() API.

if( __malloc_heap_end == 0 )
    __malloc_heap_end = (char *)(RAMEND - __malloc_margin);

Unfortunately in the repository there is nowhere sensible to include this statement, as it should be included early in the main() function.

@feilipu
Copy link
Contributor Author

feilipu commented Apr 8, 2020

ATmega devices with ENHANCED WDT Interrupt capability - will use WDT.

  • ATmega8U2/16U2/32U2 -> 2kB RAM
  • ATmega16U4/32U4 - Arduino Leonardo -> 2.5kB RAM
  • ATmega48PB/88PB/168PB/328PB - Arduino Uno -> 2kB RAM
  • ATmega164PA/324PA/644PA/1284P - Goldilocks -> 16kB RAM
  • ATmega324PB -> 2kB RAM
  • ATmega640/1280/2560/1281/2561 - Arduino Mega -> 8kB RAM + XRAM

ATmega devices without enhanced WDT Interrupt capability - will use Timer0.

  • ATmega8A/16A/32A/64A/128A -> 4kB RAM
  • ATmega165A/165PA/325A/325PA/3250A/3250PA/645A/645P/6450A/6450P -> 4kB RAM
  • ATmega169A/169PA/329A/329PA/3290A/3290PA/649A/649P/6490A/6490P -> 4kB RAM

ATmega devices without avr-libc support - unsupported at this stage.

  • ATmega808/809/1608/1609/3208/3209/4808/4809 - megaAVR 0-Series -> 6kB RAM

Copy link
Contributor

@yuhui-zheng yuhui-zheng left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did not finish review, sending preliminary feedback.

A couple details I would like to check after this round of review:

  • watchdog timer related code path.
  • timer setup. (It visually looks different since we are using 8-bit timer. I'd like to double check.)
  • register names etc.

And, internal discussion is also going on in parallel. Will keep posting review feedback.

portable/GCC/ATmegaxxxx/portmacro.h Show resolved Hide resolved
#if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__)
/* Task function macros as described on the FreeRTOS.org WEB site. */
// Add .lowtext tag for the linker for ATmega2560 and ATmega2561. To make sure they are loaded in low memory.
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) __attribute__ ((section (".lowtext")))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I saw you have something in readme.md, about .lowtext --

Also, due to a limitation in GCC, the scheduler needs to reside in the lower 128kB of flash for both of these devices. This is achieved by adding the .lowtext section attribute to the function prototype.

Would like to get some more details on the "limitation of GCC" just to help understanding.

Copy link
Contributor Author

@feilipu feilipu Apr 9, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The original conversation was in 2008, by stu_san on AVR Freaks. I won't paraphrase the details here.

My comment from 2012 showed I addressed the issue by adding a new section into the avr6.x linker script called .task. And more discussion here on my post from 2011 and specifically to the ATmega2560 here.

From avrlibc 1.8.0 (January 2014) there was a .lowtext section that was implemented in avr6.x, so I adjusted my repository to use that new section name, which also made modifying the default linker script unnecessary.

#define portSCHEDULER_ISR WDT_vect

#elif defined( portUSE_TIMER0 )
/* Hardware constants for Timer0. */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll add TIMSK0 register bit map to this section. As per a former Microchip engineer, bit map may change on newer devices. Not a blocker for this PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you would like to add 16-bit Timer capability into this PR, I can do that too.

But, I'm not totally sure how to do it generally for all ATmega devices.
My experience is limited to these devices.

  • ATmega8U2/16U2/32U2 -> 2kB RAM
  • ATmega16U4/32U4 - Arduino Leonardo -> 2.5kB RAM
  • ATmega48PB/88PB/168PB/328PB - Arduino Uno -> 2kB RAM
  • ATmega164PA/324PA/644PA/1284P - Goldilocks -> 16kB RAM
  • ATmega640/1280/2560/1281/2561 - Arduino Mega -> 8kB RAM + XRAM

But, let's get the WDT and 8-bit Timer0 done first.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. And I think 8-bit is sufficient for tick clock. Will check other's opinion on this.

portable/GCC/ATmegaxxxx/port.c Show resolved Hide resolved
Copy link
Contributor

@RichardBarry RichardBarry left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This port has needed a refresh for a long time! Some comments in the header file also apply to the C file.

portable/GCC/ATmegaxxxx/portmacro.h Outdated Show resolved Hide resolved
// System Tick - Scheduler timer
// Prefer to use the enhanced Watchdog Timer, but also Timer0 is ok.

#if defined(WDIE) && defined(WDIF) // Enhanced WDT with interrupt capability
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple of things that would be great here:

  1. To provide a timer implementation that will work on all chips.
  2. To have a backward compatibility option that uses the 16-bit timer as per the legacy port (to prevent breaking existing projects).
  3. To enable users to use any clock they like by, for example, making prvSetupTimerInterrupt() a weakly defined symbol vPortSetupTimerInterrupt() allowing it to be instead be defined as part of the application (this is done in other FreeRTOS kernel ports for maximum flexibility and would bring this port up to date with the latest conventions).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To 1. that is exactly the purpose of this path. The Enhanced Watchdog Timer (WDT) is available on all commonly used ATmega devices. It is configured simply and can be detected by the availability of the Watchdog Interrupt Enable (WDIE), and Watchdog Interrupt Flag (WDIF) provided by avr-libc. These flags are also configured consistently across all MCUs.

To 2. it becomes more challenging, as the numbering for the 16-bit Timers changes from MCU to MCU, as does their configuration and availability. It would be possible to provide a configuration for the ATmega32 (a legacy product), but this wouldn't be applicable to modern ATmega MCU. I've built a matrix of Timers vs MCU for a number of the common MCU types, but it is relatively complex and, as @yuhui-zheng pointed out, reserved bits are masked differently depending on the MCU too.

Happy to add 16-bit Timers as an example, but probably best to be left to the user to do final configuration.

To 3. I'd seek advice on how to best achieve that outcome. Perhaps reviewer edits?

#define portYIELD() vPortYield()
/*-----------------------------------------------------------*/

#if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I presume these parts are singled out (doubled out?) because they have larger memory space. In general preference is not to have chip (as opposed to architecture) specifics in a port layer, especially if it puts a burden on the user to get the compile time options right, or the target chip family is likely to change in the future. So a couple of questions - is there a catch-all definition that can be use for all devices for which this special use case applies, or alternatively, can we just have this special use case apply to all chips no matter if they need it or not? [either way, the code as you have it now is better than the legacy code, which was very chip family specific.]

Is .lowtext something that always exists, or something the user will potentially trip up on if they don't have the correct linker script. If the latter is true then please update the comment to tell users how to fix any potential linker errors. (can just be a link to a forum post somewhere that tells people how to fix).

Copy link
Contributor Author

@feilipu feilipu Apr 11, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The two parts ATmega2560 and ATmega2561 are the only two parts in common usage (and for the past 12 years at least) that need the 3 Byte PC solution.

Potentially they could also be differentiated by architecture by using the these options and providing the below.

#if defined(__AVR_3_BYTE_PC__)

This is more generic, so I'll fix it. EDIT fixed.

The .lowtext section is provided by the linker script in avr6.x. If the user has correctly nominated their device type in the compile line -mmcu=atmegaxxxx, then the correct linker script will be selected. It is automatic.

Copy link
Contributor Author

@feilipu feilipu Apr 11, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is an additional twist to this story in that two devices have both 256kB of Flash and needs __AVR_3_BYTE_PC__ and can address XRAM beyond 64kB and so has the __AVR_HAVE_RAMPZ__ register. These devices are the ATmega2560 and Atmega2561.

To cater for the ATmega1280 and ATmega1281, which have XRAM capability and the __AVR_HAVE_RAMPZ__ register, but don't have a 3 Byte PC, another option for portSAVE_CONTEXT() needs to be provided.

EDIT done.

portable/GCC/ATmegaxxxx/port.c Outdated Show resolved Hide resolved
portable/GCC/ATmegaxxxx/port.c Outdated Show resolved Hide resolved
portable/GCC/ATmegaxxxx/port.c Show resolved Hide resolved
ATmega devices without enhanced __WDT__ Interrupt capability - will use Timer0.

- ATmega8A/16A/32A/64A/128A -> 4kB RAM
- ATmega808/809/1608/1609/3208/3209/4808/4809 -> 6kB RAM

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ATmega808/809/1608/1609/3208/3209/4808/4809 series is comparatively new.
It doesn't have a dedicated 8 bit timer Timer0. It has only 16 bit timers named TCA and TCB. These can be used in split-mode to create 8 bit timers if required. Also, TCA and TCB have completely different set of registers and bitmaps than that of legacy mega devices such as mega48PB/mega328PB. I think, with Timer0, this PR can't serve ATmega808/809/1608/1609/3208/3209/4808/4809. What do you think?

Copy link
Contributor Author

@feilipu feilipu Apr 11, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Grrr. Yes. It is a totally different beast from the Timer point of view.

Looking at the data sheet, the best option seems to use the RTC with the internal 32kHz Oscillator in the Periodic Interrupt Timer (PIT) mode as the System Tick.

Using the same clock source as the RTC function, the PIT can request an interrupt or trigger an output event on every nth clock period. n can be selected from {4, 8, 16,.. 32768} for interrupts, and from {64, 128, 256,... 8192} for events.

The ATmega808/809/1608/1609/3208/3209/4808/4809 WDT doesn't have any interrupt capability, and I'd picked up that it couldn't be used. But I hadn't noticed the completely reimagined Timer solution.

I don't have any of ATmega808/809/1608/1609/3208/3209/4808/4809 that I can experiment with, so I'd suggest to work this out later. The initial datasheet was published in 2018, so it is very new.

Copy link
Contributor Author

@feilipu feilipu Apr 11, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Further, I'm quite sure that avr-libc doesn't support this series of devices, as 2.0.0 was released in 2016. Without avr-libc, everything here is irrelevant.

The only option is to make a note that the megaAVR 0-series is unsupported.

EDIT checked that it is only the Timer architecture that is different, so support can be added in (provided the user configures their own prvSetupTimerInterrupt() function). So, now the megaAVR 0-series is supported.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think, megaAVR-0 series is of architecture avr8x - which is the same as xmega and few tiny devices. This is supported by avr-libc since the architecture was already existing.
I have one 4808. May be I can try after this got merged.

Copy link
Contributor Author

@feilipu feilipu Apr 11, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. That makes sense. I've not seen that avr8x architecture before.

Then it would be best to handle support as part of an ATxmega port.

Something to add later, or separately.

EDIT Searching for avr8x produces this interesting conversation. There be dragons.🐲

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another solution I could think of is probably making prvSetupTimerInterrupt() in port.c external. We could provide example implementations in various projects, e.g. 8-bit/16-bit timer (as default probably), watchdog as a second clock source (for security initiatives), and RTC (for use cases concerning about clock skew). Users could determine which one(s) to use in their application scenario.

This may make sense, since all the timers we are talking about here are not part of the MCU core but rather peripheral. (In contrast to ARM, SysTick is provided in MCU core.) This will also make port cleaner...

Copy link
Contributor Author

@feilipu feilipu Apr 13, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. As noted in another comment, putting the TimerN configuration into a separate file is what I do in practice. I usually hold all the timer configurations in a separate file called FreeRTOSBoardDefs.h, or FreeRTOSVariant.h for Arduino_FreeRTOS.

But, this is unrelated to the OP comment. Support for this new ATmega808/809/1608/1609/3208/3209/4808/4809 avr8x family is going to be difficult as the tool set required is not yet fully developed. Something that can be looked at as a future addition, imho.

Copy link

@TintuVayalattu TintuVayalattu Apr 14, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I know, these devices(EDIT: megaAVR-0) are supported using a device spec file from DFP.
These devices are supproted in Atmel START and MCC for public. In fact, few IoT examples are also available in 4808 which consumes almost 90% of memory resources. Anyway, I can check and confirm if there is any limitation.

Copy link
Contributor Author

@feilipu feilipu Apr 14, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have checked the portmacro.h and port.c file from the v10.0.0 files included in an ATmega4809 example using FreeRTOS 10.0.0.

  • portmacro.h - no relevant differences, but uses some depreciated gcc grammar.
  • port.c - removed optional debugging bytes in pxPortInitialiseStack, only standard 2-byte stack management, and some depreciated gcc grammar.

I think, if the prvSetupTimerInterrupt() is kept as an external or weak, along with the portSCHEDULER_ISR definition being weak, there are is nothing preventing support for these megaAVR 0-series devices working.

I can add the small differences if desired.

EDIT @yuhui-zheng since it was only a few small things, I'm doing it anyway.
Sorry it breaks your review approval (again).

EDIT Done.

@yuhui-zheng
Copy link
Contributor

A standalone comment -- I setup a project which runs with Atmel Studio simulator. https://github.com/yuhui-zheng/FreeRTOS/tree/atmega_port_demo/FreeRTOS/Demo/AVR_ATMega_AtmelStudio_simulator

I'll use this one to verify build at least. And if you are interested, could play with it as well. AVR_ATMega_AtmelStudio_simulator/README.md has included some details regarding to setup. (The project is configured to use ATmega2560, one 8-bit timer, one 16-bit timer, one WDT, and etc. And if to play with RTC, could reconfigure the project. But you'll notice, RTC is not so common in ATmega family.)

yuhui-zheng
yuhui-zheng previously approved these changes Apr 13, 2020
Copy link
Contributor

@yuhui-zheng yuhui-zheng left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per internal discussion, we'd like to make this an ongoing effort to improve the port. Thus planning to merge this first before further changes. A couple of things we may consider:

  • Putting this port temporarily under ./portable/ThirdParty/GCC. This port may get mature there, and be moved back. (We've done this with a couple of ports for licensing/quality control/other reasons. Mentioning, to not surprise you. If we decide to do so, I'll put things in a single PR so that rebase may be easier.)

  • Either weak linkage or external linkage for prvSetupTimerInterrupt. We have existing examples for using weak linkage for functions implemented in porting layer. (This is assuming we have a good default implementation for target MCUs.) External linkage is also in consideration, since finding a default for all devices may be hard. (If using 16-bit timer is a good default for all ATmega devices, that's perfect.)

  • Formatting. We'll do it in a separate PR.

I'll approve without merging for a little bit.


#if defined(WDIE) && defined(WDIF) /* If Enhanced WDT with interrupt capability is available */

#define portUSE_WDTO WDTO_15MS /* use the Watchdog Timer for xTaskIncrementTick */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we are missing #include <avr/wdt.h> in this file. In the simulator project I linked, WDTO_15MS is not recognized without #include <avr/wdt.h>

Also, if you try the simulator project, the tick count after vTaskDelay is off. The attached snapshot is from running with 8-bit timer. And in the FreeRTOS Viewer window you'll see every 100 ticks, the breakpoint at line 82 is triggered. (Since mainCHECK_PERIOD is configured to 100.) But when using WDT0_15MS, this is not the case anymore. (The fix may be simply using a matching WDT period setting. Prefer to be consistent... )

Screen Shot 2020-04-12 at 11 47 57 PM

.

Copy link
Contributor Author

@feilipu feilipu Apr 13, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we are missing #include <avr/wdt.h> in portmacro.h file.

Agreed. I usually hold all the timer configurations in a separate file called FreeRTOSBoardDefs.h, or FreeRTOSVariant.h, and forgot to move it over too.

This relates to your question about using a separate layer, for individual timer configuration, and in practice that is what I do.

EDIT added.

* Prefer to use the enhanced Watchdog Timer, but also Timer0 is ok.
*/

#if defined(WDIE) && defined(WDIF) /* If Enhanced WDT with interrupt capability is available */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd propose to use counter as default clock source. It's more aligned with other ports.

(But considering all the differences between various ATmega MCUs, maybe we should move tick timer initialization into application layer. No change request for now, let's decide where to put tick timer initialization.)

Copy link
Contributor Author

@feilipu feilipu Apr 13, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using the TimerN for the tick is normal practice. But the issue is that every MCU has different timers available, and each of these have different reserved bits. It gets very complex, as you've pointed out.

My personal preference is to use the RTC related timer (usually Timer2), which ensures that there no drift. But this relies on having an external 32kHz watch crystal implemented. Not a general solution.

The advantage of the WDT is simple and repeatable configuration across all the common "hobbyist" MCU versions (Arduino).

* instead of 2 for the other ATmega* chips.
*
* Store 0 as the top byte since we force all task routines to the bottom 128K
* of flash. We do this by using the .lowtext label in the linker script.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the linker script provided by START or sample projects? Checking since we are relying on .lowtext section for behavioral correctness, though I'm not seeing this "populated" when playing with Atmel Studio. If no, we may want to consider explicitly document this...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The linker script is provided by binutils-avr used with gcc. This PR is based on solely using the Open Source tools available for AVR. Nothing to do with Atmel Studio (although it would be doing the same thing under the covers, since it uses avr-libc too).

Look for /usr/lib/avr/lib/ldscripts/avr6.x in the binutils-avr package.

yuhui-zheng
yuhui-zheng previously approved these changes Apr 13, 2020
@feilipu
Copy link
Contributor Author

feilipu commented Apr 15, 2020

Ok. I think I'm done here. @yuhui-zheng for review, etc.

@yuhui-zheng
Copy link
Contributor

yuhui-zheng commented Apr 16, 2020

@feilipu Thanks. The change for reti and ret makes sense -- the return from vPortYieldFromTick() preserves SREG I bit, and the second return from ISR sets SREG I bit to reenable interrupt. I'll see if my simulator effort can better capture this in a test maybe.

Let's merge this PR, and make incremental changes to the port. I'll immediate follow up with a PR to move port to thirdparty directory per previous comment.

@yuhui-zheng yuhui-zheng merged commit 1abca83 into FreeRTOS:master Apr 16, 2020
Dazza0 pushed a commit to Dazza0/FreeRTOS-Kernel that referenced this pull request Mar 20, 2023
* Rename configNUM_CORES to configNUMBER_OF_CORES
chinglee-iot added a commit that referenced this pull request Jul 24, 2023
FreeRTOS SMP feature is developed in a separate SMP branch. This commit merges the SMP branch to main along with some fixes. User of SMP branch needs to apply the following changes in the port:

* Rename configNUM_CORES to configNUMBER_OF_CORES
* Define portSET/CLEAR_INTERRUPT_MASK for SMP
* Define portENTER/EXIT_CRITICAL_FROM_ISR for SMP. vTaskEnterCriticalFromISR and vTaskExitCriticalFromISR should be used for these port macros
* Update portSET/CLEAR_INTERRUPT_MASK_FROM_ISR implementation to mask interrupt only Call xTaskIncrementTick in critical section in port

History of the development branch:
* Add vTaskYieldWithinAPI for taskYIELD_IF_USING_PREEMPTION

* Add configNUM_CORES config for SMP
* Add portGET_CORE_ID porting config and default return 0 to compatible
  with single core demos
* Replace xYieldPending with xYieldPendings for multiple cores
* Add vTaskYieldWithinAPI function for yield pending if the task is in
  criticial section. This check are enabled only when portCRITICAL_NESTING_IN_TCB
  is enabled
* taskYIELD_IF_USING_PREEMPTION use vTaskYieldWithinAPI when
  configUSE_PREEMPTION is set to 1

The following sections will be updated in other commits
* taskYIELD_IF_USING_PREEMPTION usage in multiple cores
* xYieldPendings usage in multiple cores

* Use portYIELD_WITHIN_API for portYIELD_WITHIN_API for single core

* Add xTaskRunState and xIsIdle in TCB

* Add xTaskRunState and xIsIdle in TCB
* Use xTaskAttribute to replace the xIsIdle in SMP TCB

* Add pxCurrentTCBs for multiple cores

* Keep pxCurrentTCB for single core
* Add pxCurrentTCBs for SMP
* Add xTaskGetCurrentTaskHandle for SMP
* Replace taskSELECT_HIGHEST_PRIORITY_TASK with temporary prvSelectHighestPriorityTask

* Add SMP critical section functions

* Update vTaskEnterCritical and vTaskExitCritical functions for SMP
* Add vTaskEnterCriticalFromISR and vTaskExitCriticalFromISR for SMP

* Add SMP prvYieldCore and prvYieldForTask

* Add idle tasks for SMP

* Add minimal idle task function declaration
* Align to use 0x00 for null terminator

* Merge vTaskSuspendAll and xTaskResumeAll from SMP branch

* Merge vTaskResume and xTaskResumeFromISR from SMP

* Merge xTaskIncrementTick from SMP

* Update prvYieldForTask usage in kernel APIs

* Merge prvAddNewTaskToReadyList from SMP

* Merge vTaskSwitchContext from SMP

* Add vTaskSwitchContextForCore APIs to switch context for specific core
* vTaskSwitchContext will switch context for current core

* Merge vTaskDelete from SMP

* Add prvYeildCore for single core to reduce multicore macros
* Add taskTASK_IS_RUNNING for single core
* Add taskTASK_IS_YIELDING

* Merge vTaskSuspend from SMP

* Set minimal idle task idle attribute

* Set minimal idle task idle attribute in prvInitialiseNewTask

* Move prvCreateIdleTasks forward and check return value

* Add minimal idle hook config check

* Fix xTaskResumeAll in SMP

* xTaskRusmeAll do nothing when scheduler not running in SMP

* check scheduler suspended when scheduler is running

* Move suspend scheduler inside critical section

* Update comment for uxSchedulerSuspended

* Add back xPendingReadyList for single core

* Use critical section for SMP

* Add in ISR check in prvCheckForRunStateChange function

* Add critical section protect for context switch

* Add vTaskSwitchContextForCore declaration

* Fix missing macro and check for single core

* Fix task delete condition

* Latest kernel move out the prvDeleteTask and the check condition should be
  TASK_IS_RUNNING

* Use critical section to protect more in SMP for vTaskDelete

* The condition task is running is not thread safe in SMP
* Once we add the task to termination the task is still running and may
  add it back to other list. Which cause memory corruption.

* Merge SMP prvSelectHighestPriorityTask to main

* Merge prvCheckTasksWaitingTermination from SMP branch

* Move prvDeleteTCB outside of critical section

* Add NULL pointer check in prvCheckTasksWaitingTermination

* Update for performance

* Remove prvSelectHighestPriorityTask and vTaskSwitchContextForCore for
  -O0 performance in single core

* Update prvSelectHighestPriorityTask

* Merge vTaskYieldWithinAPI from SMP

Update vTaskYieldWithinAPI from SMP
* xTaskDelayUntil
* xTaskDelay
* ulTaskGenericNotifyTake
* xTaskGenericNotifyWait
* event_groups.c
* queue.c
* timers.c

Add critical section protection
* xTaskGetSchedulerState

Update state check macro
* vTaskGetInfo
* eTaskGetState

* Merge vTaskPrioritySet from SMP branch

* Void prvYieldForTask return value in vTaskPrioritySet

* Yield for SMP when set priority

* Move vTaskDelay check uxSchedulerSuspended

* Update code logic for performance

* Fix yield for task in single core

* Merge timer change from SMP branch

* Split xTimerGenericCommand into xTimerGenericCommandFromTask and
  xTimerGenericCommandFromISR to remove the recursion path when called from ISRs.
* Add portTIMER_CALLBACK_ATTRIBUTE for timer callback function

* Add RP2040 SMP porting support

* Seperate task state for SMP and single core

* Merge configRUN_MULTIPLE_PRIORITIES from SMP branch

* Merge configUSE_TASK_PREEMPTION_DISABLE from SMP

* Merge configUSE_CORE_AFFINITY from SMP

* Update pxYieldSpinLocks to per-cpu variable in SMP

* Remove TODO log

* Add suppport for ARM CM55 (#494)

* Add supposrt for ARM CM55

* Fix file header

* Remove duplicate code

* Refactor portmacro.h

1. portmacro.h is re-factored into 2 parts - portmacrocommon.h which is
   common to all ARMv8-M ports and portmacro.h which is different for
   different compiler and architecture. This enables us to provide
   Cortex-M55 ports without code duplication.
2. Update copy_files.py so that it copies Cortex-M55 ports correctly -
   all files except portmacro.h are used from Cortex-M33 ports.

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>

Co-authored-by: Gaurav Aggarwal <aggarg@amazon.com>

* add extra check for compiler time (#499)

minor change to add extra check for compiler time to prevent bad config

Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com>

* Update feature_request.md (#500)

* Update feature_request.md

* Remove trailing spaces

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>

Co-authored-by: Gaurav Aggarwal <aggarg@amazon.com>

* Add callback overrides for stream buffer and message buffers (#437)

* Let each stream/message can use its own sbSEND_COMPLETED

In FreeRTOS.h, set the default value of configUSE_SB_COMPLETED_CALLBACK
to zero, and add additional space for the function pointer when
the buffer created statically.

In stream_buffer.c, modify the macro of sbSEND_COMPLETED which let
the stream buffer to use its own implementation, and then add an
pointer to the stream buffer's structure, and modify the
implementation of the buffer creating and initializing

Co-authored-by: eddie9712 <qw1562435@gmail.com>

* Add configUSE_MUTEXES to function declarations in header (#504)

This commit adds the configUSE_MUTEXES guard to the function
declarations in semphr.h which are only available when configUSE_MUTEXES
is set to 1.

It was reported here - https://forums.freertos.org/t/mutex-missing-reference-to-configuse-mutexes-on-the-online-documentation/15231

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>

* RP2040: Remove incorrect assertion (#508)

After the xEventGroupWaitBits in vProtLockInternalSpinUnlockWithWait there was an assertion about
pxYiledSpinLock being NULL, however when xEventGroupWaitBits returns, IRQs have been re-enabled
and so it is no longer safe to assert on the state which is protected by IRQs being disabled.

Co-authored-by: graham sanderson <graham.sanderson@raspeberryi.com>

* Ensure that xTaskGetCurrentTaskHandle is included (#507)

This commits adds a check that INCLUDE_xTaskGetCurrentTaskHandle is
set to 1. A compile time error message is produced if it is not set to
1. This is needed because stream_buffer.c uses xTaskGetCurrentTaskHandle.

This was reported here - https://forums.freertos.org/t/xstreambufferreceive-include-xtaskgetcur/15283

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>

* RP2040: Allow FreeRTOS to be added to the parent CMake project post initialization of the Pico SDK (#497)

Co-authored-by: graham sanderson <graham.sanderson@raspeberryi.com>

* Update to TF-M version TF-Mv1.6.0 (#517)

Signed-off-by: Xinyu Zhang <xinyu.zhang@arm.com>
Change-Id: I0c15564b342873f9bd7a8240822e770950a0563e

* Update submodule pointer of Community Supported Ports (#486)

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>

Co-authored-by: Paul Bartell <pbartell@amazon.com>
Co-authored-by: Joseph Julicher <jjulicher@mac.com>

* Add Cortex M7 r0p1 Errata 837070 workaround to CM4_MPU ports (#513)

* Clarify Cortex M7 r0p1 errata number in r0p1 specific port.

* Add ARM Cortex M7 r0p0 / r0p1 Errata 837070 workaround to CM4 MPU ports.

Optionally, enable the errata workaround by defining configTARGET_ARM_CM7_r0p0 or configTARGET_ARM_CM7_r0p1 in FreeRTOSConfig.h.

* Add r0p1 errata support to IAR port as well

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>

* Change macro name to configENABLE_ERRATA_837070_WORKAROUND

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>

Co-authored-by: Gaurav Aggarwal <aggarg@amazon.com>

* RP2040: Use indirect reference for pxCurrentTCB (#525)

* Posix: Removed unused signal set from port (#528)

Co-authored-by: Jakob Hasse <0xjakob@users.noreply.github.com>

* Add SBOM Generation in auto_release.yml (#524)

* add portDONT_DISCARD to pxCurrentTCB (#479)

This fixes link failures with LTO:

/tmp/ccJbaKaD.ltrans0.ltrans.o: in function `pxCurrentTCBConst2':
/root/project/FreeRTOS/portable/GCC/ARM_CM4F/port.c:249: undefined reference to `pxCurrentTCB'
/usr/lib/gcc/arm-none-eabi/11.2.0/../../../../arm-none-eabi/bin/ld: /tmp/ccJbaKaD.ltrans0.ltrans.o: in function `pxCurrentTCBConst':
/root/project/FreeRTOS/portable/GCC/ARM_CM4F/port.c:443: undefined reference to `pxCurrentTCB'

* Implement MicroBlazeV9 stack protection (#523)

* Implement stack protection for MicroBlaze (without MPU wrappers)

* Update codecov action to v3.1.0

* Add vPortRemoveInterruptHandler API (#533)

* Add xPortRemoveInterruptHandler API

This API is added to the MicroBlazeV9 port. It enables the application
writer to remove an interrupt handler.

This was originally contributed in this PR - https://github.com/FreeRTOS/FreeRTOS-Kernel/pull/523

* Change API signature to return void

This makes the API similar to vPortDisableInterrupt.

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>

Co-authored-by: Gavin Lambert <uecasm@users.noreply.github.com>

* Fix NULL pointer dereference in vPortGetHeapStats

When the heap is exhausted (no free block), start and end markers are
the only blocks present in the free block list:

     +---------------+     +-----------> NULL
     |               |     |
     |               V     |
+ ----- +            + ----- +
|   |   |            |   |   |
|   |   |            |   |   |
+ ----- +            + ----- +
  xStart               pxEnd

The code block which traverses the list of free blocks to calculate heap
stats used a do..while loop that moved past the end marker when the heap
had no free block resulting in a NULL pointer dereference. This commit
changes the do..while loop to while loop thereby ensuring that we never
move past the end marker.

This was reported here - https://github.com/FreeRTOS/FreeRTOS-Kernel/issues/534

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>

* Change type of message buffer handle (#537)

* Block SIG_RESUME in the main thread of the Posix port so that sigwait works as expected (#532)

Co-authored-by: alfred gedeon <28123637+alfred2g@users.noreply.github.com>

* Update History.txt (#535)

* Update History.txt

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>

* Add .syntax unified to GCC assembly functions (#538)

This fixes the compilation issue with XC32 compiler.

It was reported here - https://forums.freertos.org/t/xc32-v4-00-error-with-building-freertos-portasm-c/14357/4

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>

Co-authored-by: Paul Bartell <pbartell@amazon.com>

* Generalize Thread Local Storage (TLS) support (#540)

* Generalize Thread Local Storage (TLS) support

FreeRTOS's Thread Local Storage (TLS) support used variables and
functions from newlib, thereby making the TLS support specific to
newlib. This commit generalizes the TLS support so that it can be used
with other c-runtime libraries also. The default behavior for newlib
support is still kept same for backward compatibility.

The application writer would need to set configUSE_C_RUNTIME_TLS_SUPPORT
to 1 in their FreeRTOSConfig.h and define the following macros to
support TLS for a c-runtime library:

1. configTLS_BLOCK_TYPE - Type used to define the TLS block in TCB.
2. configINIT_TLS_BLOCK( xTLSBlock ) - Allocate and initialize memory
   block for the task's TLS Block.
3. configSET_TLS_BLOCK( xTLSBlock ) - Switch C-Runtime's TLS Block to
   point to xTLSBlock.
4. configDEINIT_TLS_BLOCK( xTLSBlock ) - Free up the memory allocated
   for the task's TLS Block.

The following is an example to support TLS for picolibc:

 #define configUSE_C_RUNTIME_TLS_SUPPORT        1
 #define configTLS_BLOCK_TYPE                   void*
 #define configINIT_TLS_BLOCK( xTLSBlock )      _init_tls( xTLSBlock )
 #define configSET_TLS_BLOCK( xTLSBlock )       _set_tls( xTLSBlock )
 #define configDEINIT_TLS_BLOCK( xTLSBlock )

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>

* Change default value of INCLUDE_xTaskGetCurrentTaskHandle (#542)

* Include string.h at the top of portable/GCC/ARM_CA9/port.c to prevent memset() generating a warning. (#430)

Co-authored-by: none <unknown>

* Move some of the complex pre-processor guards on prvWriteNameToBuffer() to compile time checks in FreeRTOS.h.

Co-authored-by: Paul Bartell <pbartell@amazon.com>

* Fix formatting of FreeRTOS.h

* correct grammar in include/FreeRTOS.h

Co-authored-by: Aniruddha Kanhere <60444055+AniruddhaKanhere@users.noreply.github.com>

* Fix warnings in posix port (#544)

Fixes warnings about unused parameters and variables when built with
`-Wall -Wextra`.

* Add support for MISRA rule 20.7 (#546)

Misra rule 20.7 requires parenthesis to all parameter names
in macro definitions.

The issue was reported here : https://forums.freertos.org/t/misra-20-7-compatibility/15385

* Add FreeRTOS config directory to include dirs (#548)

This allows the application write to set FREERTOS_CONFIG_FILE_DIRECTORY
to whichever directory the FreeRTOSConfig.h file exists in.

This was reported here - https://github.com/FreeRTOS/FreeRTOS-Kernel/issues/545

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>

* [Fix] Type for pointers operations (#550)

* fix type for pointers operations in some places: size_t -> portPOINTER_SIZE_TYPE

* fix pointer arithmetics

* fix xAddress type

* RISC-V: Add support for RV32E extension in GCC port (#543)

Co-authored-by: Joseph Julicher <jjulicher@mac.com>

* Added checks for index in ThreadLocalStorage APIs (#552)

Added checks for ( xIndex >= 0 ) in ThreadLocalStorage APIs

* Update of three badly terminated macro definitions (#555)

* Update of three badly terminated macro definitions
- vTaskDelayUntil() to conform to usual pattern do { ... } while(0)
- vTaskNotifyGiveFromISR() and
- vTaskGenericNotifyGiveFromISR() to remove extra terminating semicolons
- This PR addresses issues #553 and #554

* Adjust formatting of task.h

Co-authored-by: Paul Bartell <pbartell@amazon.com>

* M85 support (#556)

* Extend support to Arm Cortex-M85

Signed-off-by: Gabor Toth <gabor.toth@arm.com>
Change-Id: I679ba8e193638126b683b651513f08df445f9fe6

* Add generated Cortex-M85 support files

Signed-off-by: Gabor Toth <gabor.toth@arm.com>
Change-Id: Ib329d88623c2936ffe3e9a24f5d6e07655e4e5c8

* Extend Trusted Firmware M port

Extend Trusted Firmware M port to Cortex-M23,
Cortex-M55 and Cortex-M85.

Signed-off-by: Gabor Toth <gabor.toth@arm.com>
Change-Id: If8f1081acfd04e547b3227579e70e355a6adffe3

* Re-run copy_files.py script

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>

Signed-off-by: Gabor Toth <gabor.toth@arm.com>
Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>
Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com>
Co-authored-by: Gaurav Aggarwal <aggarg@amazon.com>

* portable-RP2040: Fix typo in README.md (#559)

Replace "import" with "include" in cmake code sample.

* Update CMakeLists.txt for Cortex-M55 and Cortex-M85 ports (#560)

* Annotate ports CMakeLists.txt with port details

* CMake: Add Cortex-M55 and Cortex-M85 ports

* Use highest numbered MPU regions for kernel

ARMv7-M allows overlapping MPU regions. When 2 MPU regions overlap, the
MPU configuration of the higher numbered MPU region is applied. For
example, if a memory area is covered by 2 MPU regions 0 and 1, the
memory permissions for MPU region 1 are applied.

We use 5 MPU regions for kernel code and kernel data protections and
leave the remaining for the application writer. We were using lowest
numbered MPU regions (0-4) for kernel protections and leaving the
remaining for the application writer. The application writer could
configure those higher numbered MPU regions to override kernel
protections.

This commit changes the code to use highest numbered MPU regions for
kernel protections and leave the remaining for the application writer.
This ensures that the application writer cannot override kernel
protections.

We thank the SecLab team at Northeastern University for reporting this
issue.

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>

* Make RAM regions non-executable

This commit makes the privileged RAM and stack regions non-executable.

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>

* Remove local stack variable form MPU wrappers

It was possible for a third party that had already independently gained
the ability to execute injected code to achieve further privilege
escalation by branching directly inside a FreeRTOS MPU API wrapper
function with a manually crafted stack frame. This commit removes the
local stack variable `xRunningPrivileged` so that a manually crafted
stack frame cannot be used for privilege escalation by branching
directly inside a FreeRTOS MPU API wrapper.

We thank Certibit Consulting, LLC, Huazhong University of Science and
Technology and the SecLab team at Northeastern University for reporting
this issue.

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>

* Restrict unpriv task to invoke code with privilege

It was possible for an unprivileged task to invoke any function with
privilege by passing it as a parameter to MPU_xTaskCreate,
MPU_xTaskCreateStatic, MPU_xTimerCreate, MPU_xTimerCreateStatic, or
MPU_xTimerPendFunctionCall.

This commit ensures that MPU_xTaskCreate and MPU_xTaskCreateStatic can
only create unprivileged tasks. It also removes the following APIs:
1. MPU_xTimerCreate
2. MPU_xTimerCreateStatic
3. MPU_xTimerPendFunctionCall

We thank Huazhong University of Science and Technology for reporting
this issue.

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>

* Update History.txt

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>

* Update History.txt as per the PR feedback

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>

* Update RISC-V IAR port to support vector mode. (#458)

* Update RISC-V IAR port to support vector mode.

* uncrustify

Co-authored-by: David Chalco <david@chalco.io>
Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com>
Co-authored-by: alfred gedeon <28123637+alfred2g@users.noreply.github.com>

* Added better pointer declaration readability (#567)

* Add better pointer declaration readability

I revised the declaration of single-line pointers by splitting it into
multiple lines. Now, every pointer is declared (and initialized
accordingly) on its own line. This refactoring should enhance
readability and decrease the probability of error when a new pointer is
added/removed or a current one has its initialization value modified.

Signed-off-by: Cristian Cristea <cristiancristea00@gmail.com>

* Remove unnecessary whitespace characters and lines

It removes whitespace characters at the end of lines (empty or
othwerwise) and clear lines at the end of the file (only one remains).
It is an automatic operation done by git.

Signed-off-by: Cristian Cristea <cristiancristea00@gmail.com>

Signed-off-by: Cristian Cristea <cristiancristea00@gmail.com>

* Update doc comments in task.h (#570)

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>

* Tickless idle fixes/improvement (#59)

* Fix tickless idle when stopping systick on zero...

...and don't stop SysTick at all in the eAbortSleep case.

Prior to this commit, if vPortSuppressTicksAndSleep() happens to stop
the SysTick on zero, then after tickless idle ends, xTickCount advances
one full tick more than the time that actually elapsed as measured by
the SysTick.  See "bug 1" in this forum post:
https://forums.freertos.org/t/ultasknotifytake-timeout-accuracy/9629/40

SysTick
-------
The SysTick is the hardware timer that provides the OS tick interrupt
in the official ports for Cortex M.  SysTick starts counting down from
the value stored in its reload register.  When SysTick reaches zero, it
requests an interrupt.  On the next SysTick clock cycle, it loads the
counter again from the reload register.  To get periodic interrupts
every N SysTick clock cycles, the reload register must be N - 1.

Bug Example
-----------
- Idle task calls vPortSuppressTicksAndSleep(xExpectedIdleTime = 2).
  [Doesn't have to be "2" -- could be any number.]
- vPortSuppressTicksAndSleep() stops SysTick, and the current-count
  register happens to stop on zero.
- SysTick ISR executes, setting xPendedTicks = 1
- vPortSuppressTicksAndSleep() masks interrupts and calls
  eTaskConfirmSleepModeStatus() which confirms the sleep operation. ***
- vPortSuppressTicksAndSleep() configures SysTick for 1 full tick
  (xExpectedIdleTime - 1) plus the current-count register (which is 0)
- One tick period elapses in sleep.
- SysTick wakes CPU, ISR executes and increments xPendedTicks to 2.
- vPortSuppressTicksAndSleep() calls vTaskStepTick(1), then returns.
- Idle task resumes scheduler, which increments xTickCount twice (for
  xPendedTicks = 2)

In the end, two ticks elapsed as measured by SysTick, but the code
increments xTickCount three times.  The root cause is that the code
assumes the SysTick current-count register always contains the number of
SysTick counts remaining in the current tick period.  However, when the
current-count register is zero, there are ulTimerCountsForOneTick
counts remaining, not zero.  This error is not the kind of time slippage
normally associated with tickless idle.

*** Note that a recent commit https://github.com/FreeRTOS/FreeRTOS-Kernel/commit/e1b98f0
results in eAbortSleep in this case, due to xPendedTicks != 0.  That
commit does mostly resolve this bug without specifically mentioning
it, and without this commit.  But that resolution allows the code in
port.c not to directly address the special case of stopping SysTick on
zero in any code or comments.  That commit also generates additional
instances of eAbortSleep, and a second purpose of this commit is to
optimize how vPortSuppressTicksAndSleep() behaves for eAbortSleep, as
noted below.

This commit also includes an optimization to avoid stopping the SysTick
when eTaskConfirmSleepModeStatus() returns eAbortSleep.  This
optimization belongs with this fix because the method of handling the
SysTick being stopped on zero changes with this optimization.

* Fix imminent tick rescheduled after tickless idle

Prior to this commit, if something other than systick wakes the CPU from
tickless idle, vPortSuppressTicksAndSleep() might cause xTickCount to
increment once too many times.  See "bug 2" in this forum post:
https://forums.freertos.org/t/ultasknotifytake-timeout-accuracy/9629/40

SysTick
-------
The SysTick is the hardware timer that provides the OS tick interrupt
in the official ports for Cortex M.  SysTick starts counting down from
the value stored in its reload register.  When SysTick reaches zero, it
requests an interrupt.  On the next SysTick clock cycle, it loads the
counter again from the reload register.  To get periodic interrupts
every N SysTick clock cycles, the reload register must be N - 1.

Bug Example
-----------
- CPU is sleeping in vPortSuppressTicksAndSleep()
- Something other than the SysTick wakes the CPU.
- vPortSuppressTicksAndSleep() calculates the number of SysTick counts
  until the next tick.  The bug occurs only if this number is small.
- vPortSuppressTicksAndSleep() puts this small number into the SysTick
  reload register, and starts SysTick.
- vPortSuppressTicksAndSleep() calls vTaskStepTick()
- While vTaskStepTick() executes, the SysTick expires.  The ISR pends
  because interrupts are masked, and SysTick starts a 2nd period still
  based on the small number of counts in its reload register.  This 2nd
  period is undesirable and is likely to cause the error noted below.
- vPortSuppressTicksAndSleep() puts the normal tick duration into the
  SysTick's reload register.
- vPortSuppressTicksAndSleep() unmasks interrupts before the SysTick
  starts a new period based on the new value in the reload register.
  [This is a race condition that can go either way, but for the bug
  to occur, the race must play out this way.]
- The pending SysTick ISR executes and increments xPendedTicks.
- The SysTick expires again, finishing the second very small period, and
  starts a new period this time based on the full tick duration.
- The SysTick ISR increments xPendedTicks (or xTickCount) even though
  only a tiny fraction of a tick period has elapsed since the previous
  tick.

The bug occurs when *two* consecutive small periods of the SysTick are
both counted as ticks.  The root cause is a race caused by the small
SysTick period.  If vPortSuppressTicksAndSleep() unmasks interrupts
*after* the small period expires but *before* the SysTick starts a
period based on the full tick period, then two small periods are
counted as ticks when only one should be counted.

The end result is xTickCount advancing nearly one full tick more than
time actually elapsed as measured by the SysTick.  This is not the kind
of time slippage normally associated with tickless idle.

After this commit the code starts the SysTick and then immediately
modifies the reload register to ensure the very short cycle (if any) is
conducted only once.  This strategy requires special consideration for
the build option that configures SysTick to use a divided clock.  To
avoid waiting around for the SysTick to load value from the reload
register, the new code temporarily configures the SysTick to use the
undivided clock.  The resulting timing error is typical for tickless
idle.  The error (commonly known as drift or slippage in kernel time)
caused by this strategy is equivalent to one or two counts in
ulStoppedTimerCompensation.

This commit also updates comments and #define symbols related to the
SysTick clock option.  The SysTick can optionally be clocked by a
divided version of the CPU clock (commonly divide-by-8).  The new code
in this commit adjusts these comments and symbols to make them clearer
and more useful in configurations that use the divided clock.  The fix
made in this commit requires the use of these symbols, as noted in the
code comments.

* Fix tickless idle with alternate systick clocking

Prior to this commit, in configurations using the alternate SysTick
clocking, vPortSuppressTicksAndSleep() might cause xTickCount to jump
ahead as much as the entire expected idle time or fall behind as much
as one full tick compared to time as measured by the SysTick.

SysTick
-------
The SysTick is the hardware timer that provides the OS tick interrupt
in the official ports for Cortex M. SysTick starts counting down from
the value stored in its reload register. When SysTick reaches zero, it
requests an interrupt. On the next SysTick clock cycle, it loads the
counter again from the reload register. The SysTick has a configuration
option to be clocked by an alternate clock besides the core clock.
This alternate clock is MCU dependent.

Scenarios Fixed
---------------
The new code in this commit handles the following scenarios that were
not handled correctly prior to this commit.

1. Before the sleep, vPortSuppressTicksAndSleep() stops the SysTick on
zero, long after SysTick reached zero.  Prior to this commit, this
scenario caused xTickCount to jump ahead one full tick for the same
reason documented here: https://github.com/FreeRTOS/FreeRTOS-Kernel/pull/59/commits/0c7b04bd3a745c52151abebc882eed3f811c4c81

2. After the sleep, vPortSuppressTicksAndSleep() stops the SysTick
before it loads the counter from the reload register.  Prior to this
commit, this scenario caused xTickCount to jump ahead by the entire
expected idle time (xExpectedIdleTime) because the current-count
register is zero before it loads from the reload register.

3. Prior to return, vPortSuppressTicksAndSleep() attempts to start a
short SysTick period when the current SysTick clock cycle has a lot of
time remaining.  Prior to this commit, this scenario could cause
xTickCount to fall behind by as much as nearly one full tick because the
short SysTick cycle never started.

Note that #3 is partially fixed by https://github.com/FreeRTOS/FreeRTOS-Kernel/pull/59/commits/967acc9b200d3d4beeb289d9da9e88798074b431
even though that commit addresses a different issue.  So this commit
completes the partial fix.

* Improve comments and name of preprocessor symbol

Add a note in the code comments that SysTick requests an interrupt when
decrementing from 1 to 0, so that's why stopping SysTick on zero is a
special case.  Readers might unknowingly assume that SysTick requests
an interrupt when wrapping from 0 back to the load-register value.

Reconsider new "_SETTING" suffix since "_CONFIG" suffix seems more
descriptive.  The code relies on *both* of these preprocessor symbols:

portNVIC_SYSTICK_CLK_BIT
portNVIC_SYSTICK_CLK_BIT_CONFIG  **new**

A meaningful suffix is really helpful to distinguish the two symbols.

* Revert introduction of 2nd name for NVIC register

When I added portNVIC_ICSR_REG I didn't realize there was already a
portNVIC_INT_CTRL_REG, which identifies the same register.  Not good
to have both.  Note that portNVIC_INT_CTRL_REG is defined in portmacro.h
and is already used in this file (port.c).

* Replicate to other Cortex M ports

Also set a new fiddle factor based on tests with a CM4F.  I used gcc,
optimizing at -O1.  Users can fine-tune as needed.

Also add configSYSTICK_CLOCK_HZ to the CM0 ports to be just like the
other Cortex M ports.  This change allowed uniformity in the default
tickless implementations across all Cortex M ports.  And CM0 is likely
to benefit from configSYSTICK_CLOCK_HZ, especially considering new CM0
devices with very fast CPU clock speeds.

* Revert changes to IAR-CM0-portmacro.h

portNVIC_INT_CTRL_REG was already defined in port.c.  No need to define
it in portmacro.h.

* Handle edge cases with slow SysTick clock

Co-authored-by: Cobus van Eeden <35851496+cobusve@users.noreply.github.com>
Co-authored-by: abhidixi11 <44424462+abhidixi11@users.noreply.github.com>
Co-authored-by: Joseph Julicher <jjulicher@mac.com>
Co-authored-by: alfred gedeon <28123637+alfred2g@users.noreply.github.com>

* Merge SMP commit 45dd83a8e

* 45dd83a8e | 2022-06-09 | Fix RP2040 assertion due to yield spin lock info being wrongly shared between multiple cores (#501)

* Merge SMP b87dfa3e9

* b87dfa3e9 | 2022-06-04 | RP2040: Allow FreeRTOS to be added to the parent CMake project post initialization of the Pico SDK

* Merge SMP 13f034eb7

* 13f034eb7 | 2022-06-24 | RP2040: Fix compiler warning and comment (#509)

* Fix compiler warning and spelling

* Fix Add new task for single core when scheduler not running

* Fix priority set when task is not in ready list for single core

* Fix vTaskResume when task is not running

* Fix uncrustify formating warning

* Add portCHECK_IF_IN_ISR for SMP

* Format vTaskSwitchContext

* Fix vTaskSwitchContextForCore bug due to uncrustify

* First review - did not build yet

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>

* Corresponding changes in FreeRTOS.h and task.h

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>

* Fix the single core compilation

* vTaskSwtichContextForCore rename vTaskSwitchContext
* vTaskYieldWithinAPI for single core
* pxCurrentTCBs for single core in xTaskIncrementTick

* Fix compilation warning

* Update xTaskGetCurrentTaskHandleCPU API

* Use BaseType_t instead of UBaseType_t

* Make the list traverse loop more readable

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>

* Remove unnecessary loop in xTaskIncrementTick for single core

* Update uxSchedulerSuspended with ISR lock in prvCheckForRunStateChange

* Updated ESP32 port-layer to ESP-IDF `v4.4.2` (#572)

* Xtensa_ESP32: Added esp-idf v4.4.2 specific changes

* Xtensa_ESP32: Updated SPDX license identifiers

* Add warning message to ensure min stack size (#575)

Co-authored-by: alfred gedeon <28123637+alfred2g@users.noreply.github.com>

* Removed the 'configASSERT( xInheritanceOccurred == pdFALSE )' assertion from xQueueSemaphoreTake as the reasoning behind it is wrong; it can trigger on wrongly on highly-contested semaphores on multicore systems. See https://forums.freertos.org/t/15967 (#576)

Co-authored-by: Niklas Gürtler <niklas.guertler@tacterion.com>

* Update the NIOSII port to enable longer jumps (#578)

Update the NIOSII port so it works on systems with more RAM as
per https://forums.freertos.org/t/nios-ii-r-nios2-call26-noat-linker-error/16028

* Update Cortex-M55 and Cortex-M85 ports (#579)

These were missed when PR #59 was merged.

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>

* Fix context switch when time slicing is off (#568)

* Fix context switch when time slicing is off

When time slicing is off, context switch should only happen when a
task with priority higher than the currently executing one is unblocked.
Earlier the code was invoking a context switch even when a task with
priority equal the currently executing task was unblocked. This commit
fixes the code to only do a context switch when a higher priority
task is unblocked.

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>

* Merge commit "Add support for retrieving a task's uxCoreAffinityMask
with the vTaskGetInfo() API"

* Merge commit 8128208bdee1f997f83cae631b861f36aeea9b1f

* Use taskENTER/EXIT_CRITICAL_FROM_ISR (#38)

* Enter critical section from is implemented differently for single core
  and smp. Use taskENTER/EXIT_CRITICAL_FROM_ISR in source.

* Improve single core unit test coverage (#42)

* prvCreateIldeTask use configNUM_CORES
* First time yield in idle task in SMP only
* prvCheckTasksWaitingTermination check pxTCB NULL pointer for SMP only.
  Single core won't have to check the pxTCB

* Yield for task when core affinity changed (#41)

* Yield for task when the task is linked to new allowed cores

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>
Co-authored-by: Gaurav Aggarwal <aggarg@amazon.com>

* Remove builtin clz in prvSelectHighestPriorityTask (#37)

* Remove builtin clz in prvSelectHighestPriorityTask

* Move critical nesting count to port (#47)

* Move the critical nesting management to port layer

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>

* Move critical nesting in TCB macro to tasks.c

* Add RP2040 support maintain critical nesting count in TCB

* Fix formatting

* RP2040 maintain critical nesting count in port

* Fix constant type

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>
Co-authored-by: Gaurav Aggarwal <aggarg@amazon.com>

* Rename config num cores (#48)

* Rename configNUM_CORES to configNUMBER_OF_CORES

* Fix the task selection when task yields (#54)

* Move xTaskIncrementTick critical section to port (#55)

* Port should use taskENTER/EXIT_CRITICAL_FROM_ISR

* Not preempt equal priority task in the following functions (#56)

Not to preempt equal priority task in the following functions
* vTaskResume
* vTaskResumeFromISR
* vTaskPrioritySet
* vTaskCoreAffinitySet

* Remove implicit test (#49)

* Remove taskTASK_IS_RUNNING implicit test
* Remove portCHECK_IF_IN_ISR implicit test
* Fix taskVALID_CORE_ID implicit test
* Remove configASSERT implicit test

* Fix preempt equal priority task in xTaskIncrementTick (#58)

* Not preempt equal priority when a task is removed from delay list.
  Process time sharing is handle in the logic below.
* Remove the xPreemptEqualPriority parameter of prvYieldForTask

* Remove prvSelectHighestPriorityTask call in vTaskSuspend (#59)

* Every core starts with an idle task in SMP implementation and
  taskTASK_IS_RUNNING only return ture when the task is idle task before
  scheduler started. So prvSelectHighestPriorityTask won't be called in
  vTaskSuspend before scheduler started.
* Update prvSelectHighestPriorityTask to ensure that this function is
  called only when scheduler started.

* Adding portIDLE_TASK_TEST_MOCK in idle task function (#66)

* Adding configIDLE_TASK_HOOK in idle task function

* Add INFINITE_LOOP macro to test idle task function (#67)

* Remove configIDLE_TASK_HOOK
* Add INFINIT_LOOP. Unit test can redefine this macro to mock the
function.

* portYield is not called when exit critical section from ISR (#60)

* Reference SMP branch

* Fix list index is moved in prvSearchForNameWithinSingleList (#61)

* index pointer should not be moved in SMP

* Yield for priority inherit and disinherit (#64)

* Yield the core runs the task with prority changed when priority
  inheritance and disinheritance.

* fix performance counting for SMP (#65)

* performance counting: ulTaskSwitchedInTime and ulTotalRunTime must be (#618)

arrays, index is core number

---------

Co-authored-by: Hardy Griech <ntbox@gmx.net>

* Remomve unreachable assert in prvCheckForRunStateChange (#68)

* Previous assert already ensure this assert won't be triggered

* Remove unreachable code in preYieldForTask (#69)

* xLowestPriorityCore index can't be greater than configNUMBER_OF_CORES

* Add first version of XCOREAI port (#63)

* xTaskIncrementTick need to be called in critical section
* Rename configNUM_CORES to configNUMBER_OF_CORES
* Define portENTER/EXIT_CRITICAL_FROM_ISR for SMP
* portSET/CLEAR_INTERRUPT_MASK_FROM_ISR is not used in SMP

* Fix configDEINIT_TLS_BLOCK (#73)

configDEINIT_TLS_BLOCK() should deinit the TLS block of the task to being
deleted instead of the currently running task.

* Sync with main branch (#71)

* Fix array-bounds compiler warning on gcc11+ in list.h (#580)

listGET_OWNER_OF_NEXT_ENTRY computes `( pxConstList )->pxIndex->pxNext` after
verifying that `( pxConstList )->pxIndex` points to `xListEnd`, which due to
being a MiniListItem_t, can be shorter than a ListItem_t. Thus,
`( pxConstList )->pxIndex` is a `ListItem_t *` that extends past the end of the
`List_t` whose `xListEnd` it points to. This is fixed by accessing `pxNext`
through a `MiniListItem_t` instead.

* move the prototype for vApplicationIdleHook to task.h. (#600)

Co-authored-by: pluess <pluess@faulhorn.mw.iap.unibe.ch>
Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com>

* Update equal priority task preemption (#603)

* vTaskResume and vTaskPrioritySet don't preempt equal priority task

* Update vTaskResumeAll not to preempt task with equal priority

* Fix in xTaskResumeFromISR

* Update FreeRTOS/FreeRTOS build checks (#613)

This is needed to be compatible with the refactoring done in this
PR - https://github.com/FreeRTOS/FreeRTOS/pull/889

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>

* Add ulTaskGetRunTimeCounter and ulTaskGetRunTimePercent (#611)

Allow ulTaskGetIdleRunTimeCounter and ulTaskGetIdleRunTimePercent to be
used whenever configGENERATE_RUN_TIME_STATS is enabled, as this is the
only requirement for these functions to work.

* Fix some CMake documentation typos (#616)

The quick start instructions for CMake mention the "master"
git branch which has been replaced by "main" in the current
repo.

The main CMakeLists.txt documents how to integrate a
custom port. Fix a typo in the suggested CMake code.

* Added support of 64bit events. (#597)

* Added support of 64bit even

Signed-off-by: Cervenka Dusan <cervenka@acrios.com>

* Added missing brackets

Signed-off-by: Cervenka Dusan <cervenka@acrios.com>

* Made proper name for tick macro.

Signed-off-by: Cervenka Dusan <cervenka@acrios.com>

* Improved macro evaluation

Signed-off-by: Cervenka Dusan <cervenka@acrios.com>

* Fixed missed port files  + documentation

Signed-off-by: Cervenka Dusan <cervenka@acrios.com>

* Changes made on PR

Signed-off-by: Cervenka Dusan <cervenka@acrios.com>

* Fix macro definition.

Signed-off-by: Cervenka Dusan <cervenka@acrios.com>

* Formatted code with uncrustify

Signed-off-by: Cervenka Dusan <cervenka@acrios.com>

---------

Signed-off-by: Cervenka Dusan <cervenka@acrios.com>

* Introduce portMEMORY_BARRIER for Microblaze port. (#621)

The introduction of `portMEMORY_BARRIER` will ensure
the places in the kernel use a barrier will work.
For example, `xTaskResumeAll` has a memory barrier
to ensure its correctness when compiled with optimization
enabled. Without the barrier `xTaskResumeAll` can fail
(e.g. start reading and writing to address 0 and/or
infinite looping) when `xPendingReadyList` contains more
than one task to restore.

In `xTaskResumeAll` the compiler chooses to cache the
`pxTCB` the first time through the loop for use
in every subsequent loop. This is incorrect as the
removal of `pxTCB->xEventListItem` will actually
change the value of `pxTCB` if it was read again
at the top of the loop. The barrier forces the compiler
to read `pxTCB` again at the top of the loop.

The compiler is operating correctly. The removal
`pxTCB->xEventListItem` executes on a `List_t *`
and `ListItem_t *`.  This means that the compiler
can assume that any `MiniListItem_t` values are
unchanged by the loop (i.e. "strict-aliasing").
This allows the compiler to cache `pxTCB` as it
is obtained via a `MiniListItem_t`. This is incorrect
in this case because it is possible for a `ListItem_t *`
to actually alias a `MiniListItem_t`. This is technically
a "violation of aliasing rules" so we use the the barrier
to disable the strict-aliasing optimization in this loop.

* Do not call exit() on MSVC Port when calling vPortEndScheduler (#624)

* make port exitable

* correctly set xPortRunning to False

* add suggestions from Review

Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com>

* add suggestions from Review

Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com>

---------

Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com>

* Update PR template to include checkbox for Unit Test related changes (#627)

* Fix build failure introduced in PR #597 (#629)

The PR #597 introduced a new config option configTICK_TYPE_WIDTH_IN_BITS
which can be defined to one of the following:
* TICK_TYPE_WIDTH_16_BITS - Tick type is 16 bit wide.
* TICK_TYPE_WIDTH_32_BITS - Tick type is 32 bit wide.
* TICK_TYPE_WIDTH_64_BITS - Tick type is 64 bit wide.

Earlier we supported 16 and 32 bit width for tick type which was
controlled using the config option configUSE_16_BIT_TICKS. The PR
tried to maintain backward compatibility by honoring
configUSE_16_BIT_TICKS. The backward compatibility did not work as
expected though, as the macro configTICK_TYPE_WIDTH_IN_BITS was used
before it was defined. This PR addresses it by ensuring that the macro
configTICK_TYPE_WIDTH_IN_BITS is defined before it is used.

Testing
1. configUSE_16_BIT_TICKS is defined to 0.

Source (function xTaskIncrementTick in tasks.c):
```
const TickType_t xConstTickCount = xTickCount + ( TickType_t ) 1;
```

Assembly:
```
109e:       4b50            ldr     r3, [pc, #320]  ; (11e0 <xTaskIncrementTick+0x150>)
10a0:       f8d3 4134       ldr.w   r4, [r3, #308]  ; 0x134
10a4:       3401            adds    r4, #1
10a6:       f8c3 4134       str.w   r4, [r3, #308]  ; 0x134
```

It is clear from assembly that the tick type is 32 bit.

2. configUSE_16_BIT_TICKS is defined to 1.

Source (function xTaskIncrementTick in tasks.c):
```
const TickType_t xConstTickCount = xTickCount + ( TickType_t ) 1;
```

Assembly:
```
10e2:       4b53            ldr     r3, [pc, #332]  ; (1230 <xTaskIncrementTick+0x15c>)
10e4:       f8b3 4134       ldrh.w  r4, [r3, #308]  ; 0x134
10e8:       b2a4            uxth    r4, r4
10ea:       3401            adds    r4, #1
10ec:       b2a4            uxth    r4, r4
10ee:       f8a3 4134       strh.w  r4, [r3, #308]  ; 0x134
```

It is clear from assembly that the tick type is 16 bit.

3. configTICK_TYPE_WIDTH_IN_BITS is defined to TICK_TYPE_WIDTH_16_BITS.

Source (function xTaskIncrementTick in tasks.c):
```
const TickType_t xConstTickCount = xTickCount + ( TickType_t ) 1;
```

Assembly:
```
10e2:       4b53            ldr     r3, [pc, #332]  ; (1230 <xTaskIncrementTick+0x15c>)
10e4:       f8b3 4134       ldrh.w  r4, [r3, #308]  ; 0x134
10e8:       b2a4            uxth    r4, r4
10ea:       3401            adds    r4, #1
10ec:       b2a4            uxth    r4, r4
10ee:       f8a3 4134       strh.w  r4, [r3, #308]  ; 0x134
```

It is clear from assembly that the tick type is 16 bit.

4. configTICK_TYPE_WIDTH_IN_BITS is defined to TICK_TYPE_WIDTH_32_BITS.

Source (function xTaskIncrementTick in tasks.c):
```
const TickType_t xConstTickCount = xTickCount + ( TickType_t ) 1;
```

Assembly:
```
109e:       4b50            ldr     r3, [pc, #320]  ; (11e0 <xTaskIncrementTick+0x150>)
10a0:       f8d3 4134       ldr.w   r4, [r3, #308]  ; 0x134
10a4:       3401            adds    r4, #1
10a6:       f8c3 4134       str.w   r4, [r3, #308]  ; 0x134
```

It is clear from assembly that the tick type is 32 bit.

5. configTICK_TYPE_WIDTH_IN_BITS is defined to TICK_TYPE_WIDTH_64_BITS.

```
 #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
```

The testing was done for GCC/ARM_CM3 port which does not support 64 bit
tick type.

6. Neither configUSE_16_BIT_TICKS nor configTICK_TYPE_WIDTH_IN_BITS
defined.

```
 #error Missing definition:  One of configUSE_16_BIT_TICKS and
 configTICK_TYPE_WIDTH_IN_BITS must be defined in FreeRTOSConfig.h.
 See the Configuration section of the FreeRTOS API documentation for
 details.
```

7. Both configUSE_16_BIT_TICKS and configTICK_TYPE_WIDTH_IN_BITS defined.

```
 #error Only one of configUSE_16_BIT_TICKS and
 configTICK_TYPE_WIDTH_IN_BITS must be defined in FreeRTOSConfig.h.
 See the Configuration section of the FreeRTOS API documentation for
 details.
```

Related issue - https://github.com/FreeRTOS/FreeRTOS-Kernel/issues/628

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>

* Feature/fixing clang gnu compiler warnings (#620)

* Adding in ability to support a library for freertos_config and a custom freertos_kernel_port (#558)

* Using single name definition for libraries everywhere. (#558)

* Supporting backwards compatibility with FREERTOS_CONFIG_FILE_DIRECTORY (#571)

* Removing compiler warnings for GNU and Clang. (#571)

* Added in documentation on how to consume from a main project. Added default PORT selection for native POSIX and MINGW platforms.

* Only adding freertos_config if it exists. Removing auto generation of it from a FREERTOS_CONFIG_FILE_DIRECTORY.

* Fixing clang and gnu compiler warnings.

* Adding in project information and how to compile for GNU/clang

* Fixing compiler issue with unused variable - no need to declare variable.

* Adding in compile warnings for linux builds that kernel is okay with using.

* Fixing more extra-semi-stmt clang warnings.

* Moving definition of hooks into header files if features are enabled.

* Fixing formatting with uncrustify.

* Fixing merge conflicts with main merge.

* Fixing compiler errors due to merge issues and formatting.

* Fixing Line feeds.

* Adding 'portNORETURN' into portmacros.h. Other Updates based on PR request

* Further clean-up of clang and clang-tidy issues.

* Removing compiler specific pragmas from common c files.

* Fixing missing lexicon entry and uncrustify formatting changes.

* Resolving merge issue multiple defnitions of proto for prvIdleTask

* Fixing formatting issues that are not covered by uncrustify. Use clang-tidy instead if you want this level of control.

* More uncrustify formatting issues.

* Fixing extra bracket in #if statement.

---------

Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com>

* POSIX port fixes (#626)

* Fix types in POSIX port

Use TaskFunction_t and StackType_t as other ports do.

* Fix portTICK_RATE_MICROSECONDS in POSIX port

---------

Co-authored-by: Jacques GUILLOU <jacques.guillou.job@gmail.com>
Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com>

* Cortex-M35P: Add Cortex-M35P port (#631)

* Cortex-M35P: Add Cortex-M35P port

The Cortex-M35P support added to kernel. The port hasn't been
validated yet with TF-M. Hence TF-M support is not included in this
port.

Signed-off-by: Devaraj Ranganna <devaraj.ranganna@arm.com>

* Add portNORETURN to the newly added portmacro.h

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>

---------

Signed-off-by: Devaraj Ranganna <devaraj.ranganna@arm.com>
Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>
Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com>
Co-authored-by: Gaurav Aggarwal <aggarg@amazon.com>
Co-authored-by: kar-rahul-aws <118818625+kar-rahul-aws@users.noreply.github.com>

* Introduced Github Status Badge for Unit Tests (#634)

* Introduced Github Status Badge for Unit Tests

* Github status badge to point to latest run

* Github status badge UT points to latest results

* Fixed URL for Github Status badge

---------

Co-authored-by: kar-rahul-aws <118818625+kar-rahul-aws@users.noreply.github.com>

* Remove C99 requirement from CMake file (#633)

* Remove C99 requirement from CMake file

The kernel source is C89 compliant and does not need C99.

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>

* Explicitly set C89 requirement for kernel

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>

---------

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>

* Add Thread Local Storage (TLS) support using Picolibc functions (#343)

* Pass top of stack to configINIT_TLS_BLOCK

Picolibc wants to allocate the per-task TLS block within the stack
segment, so it will need to modify the top of stack value. Pass the
pxTopOfStack variable to make this explicit.

Signed-off-by: Keith Packard <keithpac@amazon.com>

* Move newlib-specific definitions to separate file

This reduces the clutter in FreeRTOS.h caused by having newlib-specific
macros present there.

Signed-off-by: Keith Packard <keithpac@amazon.com>

* Make TLS code depend only on configUSE_C_RUNTIME_TLS_SUPPORT

Remove reference to configUSE_NEWLIB_REENTRANT as that only works
when using newlib. configUSE_C_RUNTIME_TLS_SUPPORT is always
set when configUSE_NEWLIB_REENTRANT is set, so using both was
redundant in that case.

Signed-off-by: Keith Packard <keithpac@amazon.com>

* portable-ARC: Adapt ARC support to use generalized TLS support

With generalized thread local storage (TLS) support present in the
core, the two ARC ports need to have the changes to the TCB mirrored
to them.

Signed-off-by: Keith Packard <keithpac@amazon.com>

* Add Thread Local Storage (TLS) support using Picolibc functions

This patch provides definitions of the general TLS support macros in
terms of the Picolibc TLS support functions.

Picolibc is normally configured to use TLS internally for all
variables that are intended to be task-local, so these changes are
necessary for picolibc to work correctly with FreeRTOS.

The picolibc helper functions rely on elements within the linker
script to arrange the TLS data in memory and define some symbols.
Applications wanting to use this mechanism will need changes in their
linker script when migrating to picolibc.

Signed-off-by: Keith Packard <keithpac@amazon.com>

---------

Signed-off-by: Keith Packard <keithpac@amazon.com>
Co-authored-by: Keith Packard <keithpac@amazon.com>
Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com>

* Interrupt priority assert improvements for CM3/4/7 (#602)

* Interrupt priority assert improvements for CM3/4/7

In the ARM_CM3, ARM_CM4, and ARM_CM7 ports, change the assertion that
`configMAX_SYSCALL_INTERRUPT_PRIORITY` is nonzero to account for the
number of priority bits implemented by the hardware.

Change these ports to also use the lowest priority for PendSV and
SysTick, ignoring `configKERNEL_INTERRUPT_PRIORITY`.

* Remove not needed configKERNEL_INTERRUPT_PRIORITY define

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>

---------

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>
Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com>
Co-authored-by: Gaurav Aggarwal <aggarg@amazon.com>

* Introduced code coverage status badge (#635)

* Introduced code coverage status badge

* Trying to fix the URL checker issue

* Fix URL check

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>

---------

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>
Co-authored-by: Gaurav Aggarwal <aggarg@amazon.com>
Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com>

* added portPOINTER_SIZE_TYPE and SIZE_MAX definition to PIC24/dsPIC port (#636)

* added portPOINTER_SIZE_TYPE definition to PIC24/dsPIC port

* Added SIZE_MAX definition to PIC24/dsPIC33

* Fix TLS and stack alignment when using picolibc (#637)

Both the TLS block and stack must be correctly aligned when using
picolibc. The architecture stack alignment is represented by the
portBYTE_ALIGNMENT_MASK and the TLS block alignment is provided by the
Picolibc _tls_align() inline function for Picolibc version 1.8 and
above. For older versions of Picolibc, we'll assume that the TLS block
requires the same alignment as the stack.

For downward growing stacks, this requires aligning the start of the
TLS block to the maximum of the stack alignment and the TLS
alignment. With this, both the TLS block and stack will now be
correctly aligned.

For upward growing stacks, the two areas must be aligned
independently; the TLS block is aligned from the start of the stack,
then the tls space is allocated, and then the stack is aligned above
that.

It's probably useful to know here that the linker ensures that
variables within the TLS block are assigned offsets that match their
alignment requirements. If the TLS block itself is correctly aligned,
then everything within will also be.

I have only tested the downward growing stack branch of this patch.

Signed-off-by: Keith Packard <keithpac@amazon.com>
Co-authored-by: Keith Packard <keithpac@amazon.com>
Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com>

* Enable building the GCC Cortex-R5 port without an FPU (#586)

* Ensure configUSE_TASK_FPU_SUPPORT option is set correctly

If one does enable the FPU of the Cortex-R5 processor, then the GCC
compiler will define the macro __ARM_FP. This can be used to ensure,
that the configUSE_TASK_FPU_SUPPORT is set accordingly.

* Enable the implementation of vPortTaskUsesFPU only if configUSE_TASK_FPU_SUPPORT is set to 1

* Remove error case in pxPortInitialiseStack

The case of configUSE_TASK_FPU_SUPPORT is 0 is now handled

* Enable access to FPU registers only if FPU is enabled

* Make minor formating changes

* Format ARM Cortex-R5 port

* Address review comments from @ChristosZosi

* Minor code review suggestions

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>

---------

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>
Co-authored-by: Christos Zosimidis <christos.zosimidis@gmail.com>
Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com>
Co-authored-by: Gaurav Aggarwal <aggarg@amazon.com>

* Fix freertos_kernel cmake property, Posix Port (#640)

* Fix freertos_kernel cmake property, Posix Port

* Moves the `set_property()` call below the target definition in top level CMakeLists file
* Corrects billion value from `ULL` suffix (not C90 compliant) to `UL` suffix with cast to uint64_t

* Add blank line to CMakeLists.txt

* Add missing FreeRTOS+ defines

* Run kernel demos and unit tests for PR changes (#645)

* Run kernel demos and unit tests for PR changes

Kernel demos check builds multiple demos from FreeRTOS/FreeRTOS and
unit tests check runs unit tests in FreeRTOS/FreeRTOS. Both of these
checks currently use main branch of FreeRTOS-Kernel. This commits
updates these checks to use the changes in the PR.

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>

* Do not specify PR SHA explicitly as that is default

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>

* Remove explicit PR SHA from kernel checks

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>

---------

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>

* Add functions to get the buffers of statically created objects (#641)

Added various ...GetStaticBuffer() functions to get the buffers of statically
created objects.
---------
Co-authored-by: Paul Bartell <pbartell@amazon.com>
Co-authored-by: Nikhil Kamath <110539926+amazonKamath@users.noreply.github.com>
Co-authored-by: Gaurav Aggarwal <aggarg@amazon.com>

* Cortex-M Assert when NVIC implements 8 PRIO bits (#639)

* Cortex-M Assert when NVIC implements 8 PRIO bits

* Fix CM3 ports

* Fix ARM_CM3_MPU

* Fix ARM CM3

* Fix ARM_CM4_MPU

* Fix ARM_CM4

* Fix GCC ARM_CM7

* Fix IAR ARM ports

* Uncrustify changes

* Fix MikroC_ARM_CM4F port

* Fix MikroC_ARM_CM4F port-(2)

* Fix RVDS ARM ports

* Revert changes for Tasking/ARM_CM4F port

* Revert changes for Tasking/ARM_CM4F port-(2)

* Update port.c

Fix GCC/ARM_CM4F port

* Update port.c

* update GCC\ARM_CM4F port

* update port.c

* Assert to check configMAX_SYSCALL_INTERRUPT_PRIORITY is set to higher priority

* Fix merge error: remove duplicate code

* Fix typos

---------

Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com>
Co-authored-by: Ubuntu <ubuntu@ip-172-31-17-174.ec2.internal>

* Remove C90 requirement from CMakeLists (#649)

This is needed as it is breaking projects - https://forums.freertos.org/t/freertos-gcc-cmake/16984

We will re-evaluate and accordingly add this later.

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>

* Only add alignment padding when needed (#650)

Heap 4 and Heap 5 add some padding to ensure that the allocated blocks
are always aligned to portBYTE_ALIGNMENT bytes. The code until now was
adding padding always even if the resulting block was already aligned.
This commits updates the code to only add padding if the resulting block
is not aligned.

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>

* add a missing comma (#651)

* fix conversion warning (#658)

FreeRTOS-Kernel/portable/GCC/ARM_CM4F/port.c:399:41: error: conversion from 'uint32_t' {aka 'long unsigned int'} to 'uint8_t' {aka 'unsigned char'} may change value [-Werror=conversion]

Signed-off-by: Vo Trung Chi <chi.votrung@vn.bosch.com>

---------

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>
Signed-off-by: Cervenka Dusan <cervenka@acrios.com>
Signed-off-by: Devaraj Ranganna <devaraj.ranganna@arm.com>
Signed-off-by: Keith Packard <keithpac@amazon.com>
Signed-off-by: Vo Trung Chi <chi.votrung@vn.bosch.com>
Co-authored-by: Archit Gupta <71798289+archigup@users.noreply.github.com>
Co-authored-by: tcpluess <tpluess@ieee.org>
Co-authored-by: pluess <pluess@faulhorn.mw.iap.unibe.ch>
Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com>
Co-authored-by: Chris Copeland <chris@chrisnc.net>
Co-authored-by: David J. Fiddes <35607151+davefiddes@users.noreply.github.com>
Co-authored-by: Dusan Cervenka <cervenka@acrios.com>
Co-authored-by: bbain <16752579+bbain@users.noreply.github.com>
Co-authored-by: Ju1He1 <93189163+Ju1He1@users.noreply.github.com>
Co-authored-by: Aniruddha Kanhere <60444055+AniruddhaKanhere@users.noreply.github.com>
Co-authored-by: phelter <paulheltera@gmail.com>
Co-authored-by: jacky309 <jacques.guillou@gmail.com>
Co-authored-by: Jacques GUILLOU <jacques.guillou.job@gmail.com>
Co-authored-by: Devaraj Ranganna <devaraj.ranganna@arm.com>
Co-authored-by: Gaurav Aggarwal <aggarg@amazon.com>
Co-authored-by: kar-rahul-aws <118818625+kar-rahul-aws@users.noreply.github.com>
Co-authored-by: Nikhil Kamath <110539926+amazonKamath@users.noreply.github.com>
Co-authored-by: Keith Packard <keithp@keithp.com>
Co-authored-by: Keith Packard <keithpac@amazon.com>
Co-authored-by: Joseph Julicher <jjulicher@mac.com>
Co-authored-by: Paul Bartell <pbartell@amazon.com>
Co-authored-by: Christos Zosimidis <christos.zosimidis@gmail.com>
Co-authored-by: Kody Stribrny <89810515+kstribrnAmzn@users.noreply.github.com>
Co-authored-by: Holden <holden-zenithaerotech.com>
Co-authored-by: Darian <32921628+Dazza0@users.noreply.github.com>
Co-authored-by: Ubuntu <ubuntu@ip-172-31-17-174.ec2.internal>
Co-authored-by: Nicolas <nicolas.brunner@heig-vd.ch>
Co-authored-by: Vo Trung Chi <chi.votrung@vn.bosch.com>

* Smp dev merge main 20230410 (#74)

* Fix array-bounds compiler warning on gcc11+ in list.h (#580)

listGET_OWNER_OF_NEXT_ENTRY computes `( pxConstList )->pxIndex->pxNext` after
verifying that `( pxConstList )->pxIndex` points to `xListEnd`, which due to
being a MiniListItem_t, can be shorter than a ListItem_t. Thus,
`( pxConstList )->pxIndex` is a `ListItem_t *` that extends past the end of the
`List_t` whose `xListEnd` it points to. This is fixed by accessing `pxNext`
through a `MiniListItem_t` instead.

* move the prototype for vApplicationIdleHook to task.h. (#600)

Co-authored-by: pluess <pluess@faulhorn.mw.iap.unibe.ch>
Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com>

* Update equal priority task preemption (#603)

* vTaskResume and vTaskPrioritySet don't preempt equal priority task

* Update vTaskResumeAll not to preempt task with equal priority

* Fix in xTaskResumeFromISR

* Update FreeRTOS/FreeRTOS build checks (#613)

This is needed to be compatible with the refactoring done in this
PR - https://github.com/FreeRTOS/FreeRTOS/pull/889

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>

* Add ulTaskGetRunTimeCounter and ulTaskGetRunTimePercent (#611)

Allow ulTaskGetIdleRunTimeCounter and ulTaskGetIdleRunTimePercent to be
used whenever configGENERATE_RUN_TIME_STATS is enabled, as this is the
only requirement for these functions to work.

* Fix some CMake documentation typos (#616)

The quick start instructions for CMake mention the "master"
git branch which has been replaced by "main" in the current
repo.

The main CMakeLists.txt documents how to integrate a
custom port. Fix a typo in the suggested CMake code.

* Added support of 64bit events. (#597)

* Added support of 64bit even

Signed-off-by: Cervenka Dusan <cervenka@acrios.com>

* Added missing brackets

Signed-off-by: Cervenka Dusan <cervenka@acrios.com>

* Made proper name for tick macro.

Signed-off-by: Cervenka Dusan <cervenka@acrios.com>

* Improved macro evaluation

Signed-off-by: Cervenka Dusan <cervenka@acrios.com>

* Fixed missed port files  + documentation

Signed-of…
AhmedIsmail02 pushed a commit to AhmedIsmail02/FreeRTOS-Kernel that referenced this pull request Jun 12, 2024
* ml-eval-kit: Make ETHOSU_ARCH configurable in TensorFlow CMake

This patch removes the hardcoded value of u55 in tesorflow.cmake.
It now uses ETHOS_U_NPU_ID as input and convert it to the format
needed by TensorFlow build.
This also means the ETHOS_U_NPU_ID variable preserve workaround is
no longer needed in SetupMlEmbeddedEvaluationKitLibraries.cmake as
it is no longer overwritten in tensorflow.cmake.

Signed-off-by: Gabor Abonyi <gabor.abonyi@arm.com>

* ml-eval-kit: Move NPU config from app to bsp

These settings are independent from the applications, to reduce
duplication, configuration of NPU is moved to bsp layer.
Added U65 option and checks for config validity.

Signed-off-by: Gabor Abonyi <gabor.abonyi@arm.com>

* ml-eval-kit: Move activation_buf_dram to .bss.NoInit region

This is needed to place activation_buf_dram in a no init region, so
it does not require space in flash.

Signed-off-by: Gabor Abonyi <gabor.abonyi@arm.com>

* build-run: Add support for Ethos NPU ID and MAC cycle configuration

* Add option to the build/run scripts to select different Ethos NPU
* Add option to the buld script to select number of Ethos NPU MAC
  unit per cycle

Signed-off-by: Gabor Abonyi <gabor.abonyi@arm.com>

* build-run: Use a shell variable to gather CMake arguments

This is so some CMake arguments can be excluded more easily
depending on the build configuration. It will remove the need
to set default values for CMake cache variables from the scripts
as CMake cache variables already have default values.

This change allows a standard overriding of CMake cache variable
in CMake scripts without a check to see if the user input a value
for the cache variable.

Signed-off-by: Gabor Abonyi <gabor.abonyi@arm.com>

* build: Unify error report format in build.sh

Signed-off-by: Gabor Abonyi <gabor.abonyi@arm.com>

---------

Signed-off-by: Gabor Abonyi <gabor.abonyi@arm.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants