Skip to content

Name the memory section of stack and TCB of timer task - #798

Closed
aymenjebalibmw wants to merge 1 commit into
eclipse-threadx:masterfrom
aymenjebalibmw:protect_timer_task-1
Closed

aymenjebalibmw wants to merge 1 commit into
eclipse-threadx:masterfrom
aymenjebalibmw:protect_timer_task-1

Conversation

@aymenjebalibmw

Copy link
Copy Markdown

This allows to link the named memory section to a dedicated partition of the RAM. For example for performance reasons, we can link the stack region into a low latency RAM memory. This feature is also useful to protect Task Stacks from overflowing each others, considering that we protect by MPU each stack.

PR checklist

  • Updated function header with a short description and version number
  • Added test case for bug fix or new feature
  • Validated on real hardware

This allows to link the named memory section to a dedicated
partition of the RAM. For example for performance reasons, we
can link the stack region into a low latency RAM memory.
This feature is also useful to protect Task Stacks from overflowing
each others, considering that we protect by MPU each stack.
@blanchardj-dev

Copy link
Copy Markdown

This would introduce compiler dependent code into the code ThreadX sources. Wouldn't it be better to perform the placement directly in the linker script instead?

@aymenjebalibmw

Copy link
Copy Markdown
Author

This would introduce compiler dependent code into the code ThreadX sources. Wouldn't it be better to perform the placement directly in the linker script instead?

Linker regular expression on LLVM didn't work to catch the required symbol.

I can change it to something like this, so in tx_user.h the proper compiler pragma/attribute can be specified:

tx_timer_thread_stack_area[(((UINT) TX_TIMER_THREAD_STACK_SIZE)+((sizeof(ULONG))- ((UINT) 1)))/(sizeof(ULONG))] TX_TIMER_STACK_SECTION_NAME;

@blanchardj-dev

Copy link
Copy Markdown

You might need to compile with the -fdata-sections flags to get each symbol into a different section. Then, I think you should be able to isolate it directly in the linker script.

As for the section name macro this would not be fully portable sadly since some compilers using pragmas instead of variable attributes require the pragma to be before the symbol definition.

@aymenjebalibmw

Copy link
Copy Markdown
Author

You might need to compile with the -fdata-sections flags to get each symbol into a different section. Then, I think you should be able to isolate it directly in the linker script.

As for the section name macro this would not be fully portable sadly since some compilers using pragmas instead of variable attributes require the pragma to be before the symbol definition.

yes we do use -fdata-sections, my bad now re-ordering the linker script we catch this properly.
thanks for the advice.

@aymenjebalibmw

Copy link
Copy Markdown
Author

not needed,

@aymenjebalibmw

aymenjebalibmw commented Oct 6, 2026 •

Copy link
Copy Markdown
Author

Shit!!! closing was too quick. there is no way arround the named memory section for the feature I need.
Otherwise I will mess up the linker script.

The issue as afollowing, we would like to have contiguous address space with no gaps for the TCBs and place them into one unique MPU region, the stacks are all together inside one other region.
now If I don't have named sections, I will have to catch symbol by symbol in the linker, that is not maintainable if add more tasks. meaning that I need to catch all stacks and then all TCBs and If I want to place these at the end of the memory, I will have to partition the RAM memory to even smaller chuncks and fill with the size manually.
Whille all can be resolved with named sections.

@fdesbiens

Copy link
Copy Markdown
Contributor

Hi @aymenjebalibmw

Thanks for working this through on hardware, and no harm done on the quick close — @blanchardj-dev's call is right, and the linker script is the answer here.

The set of symbols you cannot reach from your own code is closed: your application's TCBs and stacks are your own variables, so you place those yourself and match them with a wildcard. ThreadX adds exactly two, _tx_timer_thread and _tx_timer_thread_stack_area, and those names are stable across releases. Adding a task costs you nothing; this is two lines, once.

Grouping them with your own sections, gap-free, is what the script is for:

    .tcbs   : ALIGN(64) { *(.tcb)   *(.bss._tx_timer_thread) }            > LLRAM
    .stacks : ALIGN(64) { *(.stack) *(.bss._tx_timer_thread_stack_area) } > LLRAM

The order you write is the order you get, so there is no RAM sub-partitioning and no manual sizing. If you would rather have no kernel-owned stack in the MPU map at all, TX_TIMER_PROCESS_IN_ISR removes the timer thread and both symbols outright, at the cost of running timer callbacks in interrupt context.

@aymenjebalibmw

Copy link
Copy Markdown
Author

Hi @fdesbiens

Thanks for your feedback.

The TX_TIMER_PROCESS_IN_ISR configuration is not recommended for safety critical applications.

There are good reasons that compilers support named memory sections. When you look into memap concept of AUTOSAR, you will see enough good reasons for that.
Handcrafting linker script with symbol list or objects, is not an option for us. that is manual work we would like to avoid.

We apply the patch for our project.

@fdesbiens

Copy link
Copy Markdown
Contributor

Thanks @aymenjebalibmw.

Fair on TX_TIMER_PROCESS_IN_ISR — that was an option to be aware of, not a recommendation for a safety-critical context.

For safety-critical, there may be a better fit than section placement. If you are on Cortex-R52, the module manager port shipped in v6.5.2.202603_rel, and there is a protection-boundary example for an S32Z280 EVB in the tree at ports_module/cortex_r52/gnu/example_build/s32z280_evb. The manager keeps the kernel's MPU regions permanently and reprograms only the module's regions on a switch, so the timer thread's TCB and stack sit outside every module's reach by construction — the property you were building toward. Module thread stacks are allocated from the module's own memory and fall inside its data region, so there is no section placement to maintain at all. You also get a fault handler and txm_module_manager_memory_fault_notify, and the manager rejects a module thread whose stack overlaps another's.

The honest limit: isolation is per module, not per thread. Two threads in one module share a data region and can still overwrite each other's stacks. One task per module restores per-task isolation, at the cost of reprogramming regions on every context switch. If your freedom-from-interference argument is at partition level, modules are the right tool; if you need one MPU region per task stack, no ThreadX port offers that today and that part is yours to write either way.

If you stay non-module, TX_ENABLE_STACK_CHECKING with tx_thread_stack_error_notify is a cheap backstop — a fill-pattern check at context switch rather than a hardware guard.

Separately, and not an answer to this: ZoneX, the suite's Armv8-R partitioning hypervisor, declares partitions from a manifest rather than assembling them in a linker script, which is the instinct behind your MemMap point. It is at v0.1.0 and explicitly not production software, but if that direction interests you, feedback at this stage is worth a lot.

Either way, carrying your patch locally is fine. The licence is MIT, and it is two symbols in one file whose names do not move between releases.

Thanks for raising it, and for the hardware validation.

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.

3 participants