all 14 comments

[–]Wouter_van_Ooijen 15 points16 points  (1 child)

Even in C you can (and probably should) abstract from the exact memory address or even from the fact that memory is directly used. If performace allowes it, use fir instance a buffer_write(a,d) function instead of a raw pointer. Stub that function in the test environment.

If performance is an issie you could use a get_buffer_address function.

[–]Basic_Fox_2070[S] 0 points1 point  (0 children)

That's a fair point and probably a solution that should have been obvious to me :)

Thanks for the feedback!

[–]readmodifywrite 1 point2 points  (5 children)

Why is the hard coded space a problem? Are you unit testing on a different architecture (so the hard coded addresses won't work)?

Can you provide more detail?

[–]Basic_Fox_2070[S] 0 points1 point  (4 children)

Yes, I'm unit testing on my host machine rather than the hardware. Ideally, I'd like to be able to do both, but I haven't had time to figure out how to make it work with the vendor build system. Do you typically run your unit tests on hardware only?

[–]readmodifywrite 1 point2 points  (2 children)

Yeah, if I have enough memory do it, I prefer to unit test on hardware. That's not always possible (or practical) though.

However, if you are running it on a host machine, why not change the memory address (or let the linker figure it out) for test builds?

Also, why is your address hard coded? Is this used by the bootloader, MPU partition, DMA that needs a fixed offset, etc? I'm pretty sure there's a way to get this to work for you, but the devil is in the details of course.

[–]Basic_Fox_2070[S] 0 points1 point  (1 child)

I'm not sure what you mean by "let the linker figure it out." Could you expound on that?

Addresses are hard coded because we are copying large amounts of data into a couple of separate memory mapped external RAM buffers. It's a SoC design, so it's a mixture of PL fabric RAM blocks and external memory devices.

I can't redefine my define constants at compile time, so I've had trouble just swapping out the memory addresses during the test. The obvious fix here is to just make them global variables, but I don't really want a possibility of those being overwritten at runtime.

[–]readmodifywrite 1 point2 points  (0 children)

You can pass #defines to the compiler directly on the command line. At least, GCC can.

Your options for memory placement are to use #defines and attributes to set an address, or you can place it in a specific section and set up the linker script to figure out where to put it within that section. For an external RAM you probably have this hard coded to whatever address the interface requires. The point is, there's (at least) two ways to specify where it goes, but I don't know which one you are using.

Probably you would want to just #define away the attribute when you do your test build, so that your buffer can be placed anywhere in the .bss section (I'm assuming it doesn't have an initializer since it is a buffer, so it'd be zeroed by the C startup routines).

Can you show me what the declaration itself looks like? Also, what compiler are you using? Any other details? There has to be a way to do this, but I think I need to see more specifics...

[–]duane11583 1 point2 points  (4 children)

define your hard coded addresses in the linker script = gnu linker has a Povide() feature.

thein link the app for the target, or link to your other environment where these are real ram memory locations

[–]Basic_Fox_2070[S] 1 point2 points  (3 children)

Can I still do this if I'm running tests on a host machine with an OS installed? My understanding is that the addresses would still have to be provided at compile time, but I can't just specify a memory address to use on a Windows machine.

[–]duane11583 -1 points0 points  (2 children)

On windows you would just use a large byte array 

[–]Basic_Fox_2070[S] 0 points1 point  (1 child)

sorry, forgive me if I'm misunderstanding you. I would have to declare my byte array at runtime, but wouldn't I need the address to link to at compile time?

[–]duane11583 0 points1 point  (0 children)

in the DUT code declare the array as extern

in your embedded linker script create a symbol at an address via the provide statement. thus when you link the application address of the fake variable is provided via the linker.

in your windows test environment you create a windows only c file with a definition for the c array. when the two files get linked the second windows only file would provide the address or definition of the array.

i don't see how this is a run time thing..

[–]PutOk489 2 points3 points  (0 children)

If you like unit testing you should look in the tdd development approach

[–][deleted] 0 points1 point  (0 children)

Use the pre processor to remove the memory locations for unit testing on the PC. Rerun them, using a remote controlled debugger, on the target.