-
-
Notifications
You must be signed in to change notification settings - Fork 314
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
Add support RTT for 64-bit processors #2296
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot for implementing this!
Is there a reason we want to allow more channels in 64bit archs?
I thought I didn't change the number of max channels. |
probe-rs/src/rtt.rs
Outdated
// Memory contents read in advance, starting from ptr | ||
mem_in: Option<&[u8]>, | ||
) -> Result<Option<Rtt>, Error> { | ||
let is_64bit = match core.instruction_set()? { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would be a lot nicer as if matches!(core.instruction_set()?, probe_rs_target::InstructionSet::A64)
. We only need to list the ones that are 64-bit. I realize the downside is that adding new architectures are immediately treated as 32-bit, though, so maybe instead this logic could be moved into a function like InstructionSet::width()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so maybe instead this logic could be moved into a function like InstructionSet::width()?
In this code, I want to know the size of the target integer(32bit or 64bit).
I'm checking it from the InstructioSet now, but I think there has to be a better than the current method.
Could you please tell me if you know of any good ideas?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found that Armv8a state has an is_64_bit
flag, so I changed this code to use it.
008aa3a
probe-rs/src/rtt.rs
Outdated
core.read(ptr.into(), &mut mem)?; | ||
let mut mem = vec![ | ||
0u8; | ||
if is_64bit { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you instead store the width-dependent constants in fields first, to avoid a bunch of (mostly) unnecessary if-else?
In other places, you could probably abstract away the if 64-bit { do64 } else { do32 }
code into helper functions just to clean the implementation up a bit. I'm not sure what would be the nicest, but I'm sure we can do better than an if-else everywhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm sure we can do better than an if-else everywhere.
I agree.
I am refactoring RTT codes, but it will take time to complete.
So, I would be happy if you could merge the current code first.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for waiting.
The refactor is complete now 04f918e.
Could you please review it again?
Refactor RTT
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks better, thank you for working on this. I have a few observations that I think could improve this PR slightly, please take a look.
probe-rs/src/rtt.rs
Outdated
@@ -260,7 +411,7 @@ impl Rtt { | |||
.into_iter() | |||
.filter_map(|range| { | |||
let range_len = match range.end.checked_sub(range.start) { | |||
Some(v) if v < Self::MIN_SIZE as u64 => return None, | |||
Some(v) if v < (if is_64_bit {std::mem::size_of::<RttControlBlockHeaderInner<u64>>()} else {std::mem::size_of::<RttControlBlockHeaderInner<u32>>()} as u64) => return None, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't the most elegant way,
- Complex guard conditions like this are hard to understand.
- This is the third place where you implement the
bool -> pointer width
conversion. You should probably add aRttControlBlockHeader(Inner?)::size(is_64_bit: bool)
function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for your review!
I fixed it 22e9c7c
probe-rs/src/rtt.rs
Outdated
@@ -250,8 +401,8 @@ impl Rtt { | |||
tracing::debug!("Scanning region: {:?}", region); | |||
|
|||
vec![Range { | |||
start: region.start as u64, | |||
end: region.end as u64, | |||
start: region.start, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this be a region.clone()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you!
e8741b5
probe-rs/src/rtt/channel.rs
Outdated
} | ||
|
||
pub fn flags_offset(&self) -> usize { | ||
std::mem::size_of::<Self>() - std::mem::size_of::<T>() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we use offset_of! here? Also, considering these functions are (almost?) always used to calculate some memory access offset, I think it would be better if all three of these returned u64
probe-rs/src/rtt/channel.rs
Outdated
} | ||
|
||
pub fn read_buffer_ptr_offset(&self) -> usize { | ||
std::mem::size_of::<RttChannelBufferInnerHeader<T>>() + std::mem::size_of::<T>() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is pretty hard to understand because the second size_of
points in the middle of an inner struct
. Although offset_of_nested
is not stable yet in Rust, this might still be a similarly good place to use offset_of!
, like std::mem::offset_of!(Self, buffer_offset) + std::mem::offset_of!(RttChannelBufferInnerBufferOffset<T>, read_offset)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for sharing your good method!
I rewrote *_offset
functions using offset_of!
.
0473385
Just so you're aware, that repository seems to be outdated. The latest code which you can download from the Segger website does seem to support 64-bit mode. |
Thank you for letting me know 😄 I downloaded the latest codes(SEGGER_RTT_V796c.tgz) from https://www.segger.com/downloads/jlink#J-LinkSoftwareAndDocumentationPack and I checked these codes. Could you please tell me where is the codes to support 64-bit mode? |
You might be right, I saw that they support Cortex-A and assumed that meant 64 bit. But it seems they only support ARMv7-A, which is 32-bit. Of course, the Segger C code just uses |
Thank you very much :) |
I added support RTT for 64-bit processors.
The 64-bit mode is not yet supported(TBD) by SEGGER RTT.
https://github.com/SEGGERMicro/RTT/blob/master/RTT/SEGGER_RTT.h#L216-L217
But I created a code that works with the defmt_rtt.
https://github.com/knurling-rs/defmt/blob/main/firmware/defmt-rtt/src/lib.rs#L124-L136
I checked it works on Raspberry Pi 4(64bit) and Raspberry Pi Pico(32bit).