|
I'm working on a project that would benefit from having a good function call trace system, after reading up on stuff around the internet it seems like this is a format that can do the job:code:
code:
|
# ¿ Nov 1, 2023 02:34 |
|
|
# ¿ May 2, 2024 20:38 |
|
Thanks much for the excellent and detailed explanation! You wrap your code in do{}while(0) so that it works syntactically as you want with semicolons, but since that structure doesn't do anything useful it gets optimized out to nothing in the actual output. Other constructs like if statements don't work the same way with semicolons so it has to be do-while. pseudorandom name posted:Well, you screwed up your examples, it should be do { } while (0) True, I was typing it out from memory and auto-included the semicolon by force of habit. I didn't understand the importance of it not being there so it didn't jump out at me. I get why you don't want it there now.
|
# ¿ Nov 1, 2023 16:23 |
|
Weird question: does the first function called in a C++ program absolutely have to be called main, or can we rename it to something else? The reason I ask is because I just started some work on an embedded microcontroller with an asymmetric dual core, one is a (relatively) beefy Cortex M7 and the other is a weaker Cortex M4 on the same silicon. When kickstarting the chip from power on and doing all of the stuff to init the processors before handing off fully to the software side I end up with two functions, both called main(), when a more natural naming might be main_m7() and main_m4(). My IDE absolutely rejects me naming them that, but having two different things with the same name is mildly confusing in the code. I suppose I can just make each main() call a pass-thru function to main_m7 and main_m4, but it's just an interesting thought experiment to consider naming them something else natively.
|
# ¿ Dec 12, 2023 05:55 |
|
Thanks everyone who commented, I appreciate the info and advice!Foxfire_ posted:Do you have an operating system with concepts like 'programs', or are you just using the chip directly? Nope, this is bare metal register-flippy stuff. The power comes on and the hardware knows the first four bytes are the starting value of the stack pointer, then the next four bytes are the reset vector aka the starting value of the program counter. Those get loaded and then you pop into the reset vector code where I do all the setup stuff you described, then call main. So yeah, I didn't think the name main was going to be special in that context, it's just a thing I call once the chip is ready to go. But I think the IDE is throwing a fit because, as Dijkstracula pointed out, the name main is standardized as special in most cases. Anyway I think I hit on a solution that meets my needs without getting into doing anything too strange. The function name main may be special but the file name that main is located in is not. So I should be able to call one file main_m4.cpp and the other main_m7.cpp, put each of the respective main() calls in each one which keeps the compiler happy, but now I'm also happy because I don't have two tabs open in the IDE labeled main.cpp but containing different contents causing me to swear under my breath as I open the wrong one for the hundredth time that day.
|
# ¿ Dec 13, 2023 00:42 |
|
StumblyWumbly posted:How are you building this? I'd think you'd need 2 separate projects and linkers, but it sounds like your IDE is putting it all into one? Or is it mainly that you don't like having 2 similar projects open at once? This is in Visual Studio with the VisualGDB extension for working on embedded microcontrollers. I'm in the learning phase of how to do dual core processors but as I understand it now you make one VS solution with two projects inside it, one for each processor. Then each project gets its own linker/startup/chip header/code that can be compiled and downloaded to the target independently. The two project thing is what leads to having two main.cpp files which gets slightly confusing since both can be open in the IDE at once. I think I can resolve that by naming the files main_m7.cpp and main_m4.cpp, and let each contain a main() call without doing anything super weird. Next up on the list is figuring out how to assign different hardware peripherals to each processor and how to run a hardware debugger with two processors since apparently you can set it up so that a breakpoint in one stops only that processor or both.
|
# ¿ Dec 13, 2023 04:54 |
|
Is there any way to tell a linker script to put a data structure at a specific location in memory? My situation is that I'm working on an embedded microcontroller with two processors and I want to set up some FIFO queues to pass messages between them. Each processor has its own project with its own linker script, but they need to agree exactly on where the FIFOs are located so they can take turns reading/writing data. What I am doing now, which works but feels sub-optimal, is manually declaring a variable in each linker script that contains the base address of a section of memory that both processors can access. Then there is a code file that is common to both processors that reads that address variable and assigns it to a struct pointer that defines my FIFOs. That makes both processors access the FIFO structs at the same memory location which basically works. But there is nothing stopping some other code from also declaring a variable in that location which would lead to a real fun bug. Is there a better way to do this?
|
# ¿ Apr 13, 2024 02:41 |
|
|
# ¿ May 2, 2024 20:38 |
|
Thanks for the replys!rjmccall posted:Casting an integer to a pointer to your struct is by far the easiest and most portable way. Qwertycoatl posted:I agree with this. OK, that sounds pretty much like what I was doing, just with the extra step of getting the value out of the linker script because I was thinking that that is the place memory architecture should be described. I like the idea of getting the memory address out of the chip header file though, I'll take a look and see if it's defined in there. Jabor posted:Your linker scripts should define two separate memory segments: That's kind of the setup I started with, but then had the paranoid thought that if future-me ever forgot about the details and allocated another bit of memory in this shared bank to be used by only one processor, that' processors linker might stack things in memory from the base address as (new item, FIFOs) while the second processor's linker would just have (FIFOs) and they wouldn't agree on the FIFOs address. This makes me think that maybe it would be a good idea to comment out references to the shared memory entirely from the linker scripts while adding a note stating why I did that. Then future me can't would not be able to put anything else there by just giving it an attribute, I'd have to open up the linker script and (hopefully) run across my old warning comments.
|
# ¿ Apr 13, 2024 17:03 |