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

Tickless mode fixes #13

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open

Tickless mode fixes #13

wants to merge 3 commits into from

Conversation

diggit
Copy link
Contributor

@diggit diggit commented Apr 16, 2020

This is initial effort to fix timing issues in Argon, more info in #11. I am open open to suggestions.

@flit
Copy link
Owner

flit commented Apr 19, 2020

Started reviewing… Thanks! 😄

@@ -290,7 +259,8 @@ bool ar_kernel_increment_tick_count(unsigned ticks)
ar_list_node_t * next = node->m_next;

// Is it time to wake this thread?
if (g_ar.tickCount >= thread->m_wakeupTime)
//TODO: would it be safe to cache tick_count?
Copy link
Owner

Choose a reason for hiding this comment

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

I was wondering about that too. It's probably safe to cache it within a single function like this one, or ar_kernel_scheduler().

return g_ar.tickCount * ar_get_milliseconds_per_tick();
#endif // AR_ENABLE_TICKLESS_IDLE
return ar_port_get_time_absolute_ms();
// return ar_port_get_time_absolute_ticks() * kSchedulerQuanta_ms; //do we have to limit resolution?
Copy link
Owner

Choose a reason for hiding this comment

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

Imo, it's better if resolution is not limited.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, I was not sure about consequences. Will Fix.

Comment on lines 562 to +590
uint32_t ar_get_tick_count(void)
{
#if AR_ENABLE_TICKLESS_IDLE
uint32_t elapsed_ticks = ar_port_get_timer_elapsed_us() / (kSchedulerQuanta_ms * 1000);
return g_ar.tickCount + elapsed_ticks;
#else
return g_ar.tickCount;
#endif // AR_ENABLE_TICKLESS_IDLE
return ar_port_get_time_absolute_ticks();
}

// See ar_kernel.h for documentation of this function.
uint32_t ar_get_millisecond_count(void)
{
#if AR_ENABLE_TICKLESS_IDLE
uint32_t elapsed_ms = ar_port_get_timer_elapsed_us() / 1000;
return g_ar.tickCount * ar_get_milliseconds_per_tick() + elapsed_ms;
#else
return g_ar.tickCount * ar_get_milliseconds_per_tick();
#endif // AR_ENABLE_TICKLESS_IDLE
return ar_port_get_time_absolute_ms();
// return ar_port_get_time_absolute_ticks() * kSchedulerQuanta_ms; //do we have to limit resolution?
Copy link
Owner

@flit flit Apr 19, 2020

Choose a reason for hiding this comment

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

ar_get_tick_count() and ar_get_millisecond_count() should probably be inline. That does mean exposing some port APIs publicly…

Or can we just completely remove them? Is there any reason to not directly call ar_port_get_time_absolute_<x>()? (Renamed?)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, forgot to inline them. Even though, compiler would probably inline them anyway.
Well, I think that application should have access to system time. Also application should not have access to port functions.

}

//TODO: is return type sufficient?
uint32_t ar_port_get_time_absolute_ms()
Copy link
Owner

Choose a reason for hiding this comment

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

Probably not, need uint64_t here.

Comment on lines +384 to 385
//TODO: move ar_get_microseconds() somewhere else and redirect to ar_port_get_time_absolute_us() ?
WEAK uint64_t ar_get_microseconds()
Copy link
Owner

Choose a reason for hiding this comment

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

Yeah, move it next to the other get-time APIs.

Copy link
Owner

@flit flit left a comment

Choose a reason for hiding this comment

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

I like the changes! Thanks again. 👍

The only thing I see that really needs to be done is to split the timer-porting code from the rest of the Cortex-M porting code, so we don't have duplicates.

@diggit
Copy link
Contributor Author

diggit commented Apr 27, 2020

I see no problem i splitting them. Any idea about port sources structure? Should there be some automation in what is compiled (eg through ar_config) or leave it up to user, which sources to compile and link?

What about:

  • port/
    • port.hpp (common header defining interface to port functions)
    • arch/
      • cortex/
        • cm0.cpp
        • cm3_4_7.cpp (split if needed)
    • target/
      • stm32/
        • f303.cpp
        • f446.cpp
        • 103.cpp
      • nxp/
        • kinetis_??.cpp

diggit added 3 commits May 3, 2020 00:26
This change allows to utilize HW timers more easily.
(default ar_port.cpp using systick needs updating)
*Single* uses only one timer as microsecond counter between ticks.
*Chained* uses two chained timer s (on hardware level) to count
microseconds between tics and ticks themselves.
Most precise timing with this solution.
- some f303 port cleanups
- add port using generic ARM SysTick with explained limitations

only lightly tested!
@flit
Copy link
Owner

flit commented Jul 6, 2020

My sincerest apologies for being quiet for too long! 🙏

For the port sources, I guess I'm not sure what the best solution is. One of the goals I had for the Argon repo was for it to be usable as a git submodule, without including too much ancillary code you don't need. (I've used it like this in projects; it's nice.)

Options:

  1. Your proposal with device support in the core repo.
  2. The ideal solution would be dependency-managed packages, but I think the C/C++ package manager space is too messy (certainly compared to Rust, for instance).
  3. Separate each device-specific port into its own repo that you would submodule next to the core Argon repo.
  4. Have device support grouped into another repo from which users can just pick out the file(s) they need and copy into their project. Or you could submodule it if you don't care about extra files.

For now I'm leaning towards your proposal. 😄 I can live with a relatively small number of device-support files in the core repo. And it can always be changed if needed.

As for builds, I've never been a fan of using macros to include/exclude files in the build. So I'd rather leave it up to the user.

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.

2 participants