Is a const array automatically loaded to flash? - memory

I am using an IAR IDE with a Cortex M4 based MCU. When I declare an array to be const does it automatically assign it to flash memory rather than RAM?

By experiment, using a global array marked as const, it get loaded to flash. If const is omitted it gets mapped into RAM

This is determined by your linker configuration. You can configure your linker to not touch flash at all, but it won't be very useful, since at power-on, your processor won't contain the code or initialization data to initialize memory. Typically, code (not defined as ramfunc), read only data, and initialization values for read/write data will end up in flash, and I believe IAR's linker scripts are setup to map this way by default.
In your experiment, using const puts the variable directly into flash. If you had an initialized value (presumably you did, since it was const), then removing const means it will be placed in read/write data section, but there will be a copy in flash (if using the default script) to initialize the RAM copy from.

Related

Get lua state inside lua

I would like to get the lua state from inside lua so I can pass it too an external program that cannot be hooked up using ffi or dll. I just need a pointer to it and the ability to share it(shared memory across program boundaries.
That or I can create a lua state in my program and then pass that so I would simply need to set the lua state to it inside lua(and it would have to work with shared memory).
I've thought about sharing data using json but ideally I would like to directly access objects.
Lua is pretty good about avoiding heap allocation and global pointers to allocated memory. lua_newstate takes an allocator function as a parameter. The provided function will be used to allocate/deallocate all memory associated with the lua_State object. Including the pointer returned by lua_newstate.
So hypothetically, you could provide an allocator function that allocates/deallocates interprocess shared memory. And then, you can just pass the lua_State to some other process and access it.
First, you clearly cannot do this "from inside lua"; that kind of low-level thing just ain't happening. You cannot access the lua_State object from within Lua. You must be in control of the lua_State creation process for that to be a possibility. So we're talking about C (equivalent) code here, not in-Lua code.
Now, you can expose a C function to Lua which returns a light userdata that just so happens to be the exact lua_State* in question. But Lua can't really do much with light userdata other than pass it to other C function APIs.
Second, while the Lua system provides a guarantee that it will only allocate memory through the allocator, the system does not provide a guarantee that what you're trying to do will work. It is entirely possible that the Lua implementation does use process global memory, so long as it does it in such a way that different threads can access that global memory without breaking threading guarantees.
Obviously, you can inspect the Lua implementation to see if it does anything of the kind. But my point is that the guarantees are that each independent lua_State will be thread-isolated from each other and that each lua_State will only allocate memory through the given allocator. There is no guarantee that Lua's implementation doesn't have some global storage that it uses for some purpose.
So simply sharing the memory allocated by the Lua state may not be enough.
Also, even if this works, the two processes cannot access the same lua_State object at the same time, just like two threads in the same process cannot access the lua_State at the same time.
The lua state is not designed to leave the program / thread it is executing in.
Doing a query on a running lua_state could result in a crash, because it is only notionally consistent when a lua call returns, or a C api function is called. During execution, some un-locked modifications could cause uninitialized memory access, or ininite loops due to lists being inconsistent.

Questions about passing strings and other data from UI to LV2 plugin

I need to pass a string from the UI to the plugin. From the eg-sample, it appears that an LV2 atom should be written to a atom port.
If I understand it correctly
First allocate a LV2_Atom_Forge. May that object be on the stack or does it have to survive after the UI event callback has returned?
Call lv2_atom_forge_set_buffer. How do I know the required size of the buffer? The example sets it to 1024 bytes for no reason. May the buffer be allocated on the stack or does it have to survive the UI after the UI event callback has returned?
The forge is just a utility for writing atoms. The buffer it writes to is provided by the code that uses it, so the lifetime of the forge itself is irrelevant. Allocating it on the stack is fine, though it may be more convenient to keep one around in your UI struct for use in various places.
You can estimate the space required by knowing the format of atoms as described in the documentation, or simply implementing everything with a massive buffer at first and checking the size field of the top-level atom in your output. Keep in mind that this will change if you have variable-sized elements like strings in there. The data passed to the UI callback(s) is const and only valid during the call, it must be copied by the receiver if it needs to be available later.

How to return a struct from an imported DLL-function in MQL4?

Is there a way to return a struct from an imported function in MQL4, without having to pass it as a parameter and making a memcpy?
Be cautious with any kind of DLL-interfacing, MQL4 Documentation states:
Passing ParametersAll parameters of simple types are passed by values unless it is explicitly indicated that they are passed by reference. When a string is passed, the address of the buffer of the copied string is passed; if a string is passed by reference, the address of the buffer of this string without copying it is passed to the function imported from DLL.Structures that contain dynamic arrays[], strings, classes, other complex structures, as well as static or dynamic arrays[] of the enumerated objects, can't be passed as a parameter to an imported function.When passing an array to DLL, the address of the beginning of the data buffer is always passed (irrespective of the AS_SERIES flag). A function inside a DLL knows nothing about the AS_SERIES flag, the passed array is a static array of an undefined length; an additional parameter should be used for specifying the array size.
More glitches apply... Then how to make it work?
Maybe a straight, heterogeneous multi-party distributed processing, which communicates rather results than function calls, independent of all nightmares of maintaining just DLL-imported functions API changes, is a way safer way to go. Using this approach for the last few years and since than have no problems with New-MQL4.56789 string-s that seized to remain string-s and silently started to become struct-s etc.
Worth to know about.
Anyway, welcome and enjoy the Wild Worlds of MQL4 -- may enjoy to click and read other posts on issues in MQL4/DLL integration and/or signalling/messaging in MQL4 domains. Feel free to ask more

How does Lua handle storing something it created into userdata it did not?

So I am exposing complicated data objects that are both created entirely within a C++ environment but more recently I have made it so Lua can also create an instances of these objects. I use the UserData to track where the allocation happened so when __gc is called it knows what it is supposed to do.
Is Lua smart enough to know a reference to a user data it created is stored in a user data block that it did not create?
Code Sample
function AddNewSubjObject(containerId, subObjectType)
local containerObject = meta_ContainerObject:getContainer(containerId)
local newSubObject = meta_SubObject:CreateNew(subObjectType)
containerObject.AddChild(newSubObject)
return containerObject;
end
We get a local variable to the userdata object that can contain other objects. We then create a new object that its only tracking is in Lua. Finally we call a method that will store the sub object in the container object.
When this function returns, to me it looks like it has removed all references to the newSubObject so I fear it will delete the memory allocated for it even though it is still being referenced..
Will this either leak memory by not cleaning up the objects properly or will it corrupt memory by deleting it when it is still be potentially used? Basically I am wondering if this is a situation that has to be considered and handled when exposing userdata via Lua.
The Lua garbage collector does not look inside userdata.
Lua provides weak tables to manage these kinds of references. See PiL Chapter 17. You can use a table with weak keys of subObjects and values of the container of the subObject. When the container is collected so will the subObjects.

OpenCL 1.2 Mem Object flags

So reading through the OpenCL 1.2 reference pages, I noticed a difference in clCreateBuffer.
There are three new cl_mem_flags that pretain to the host usage: CL_MEM_HOST_READ_ONLY, CL_MEM_HOST_WRITE_ONLY, and CL_MEM_HOST_NO_ACCESS. I was just a bit confused how these differ from the cl_mem_flags from earlier versions? Wouldn't CL_MEM_READ_ONLY AND CL_MEM_WRITE_ONLY accomplish the same thing?
Also, do these flags affect how you call functions such as clEnqueueRead/Write/Map/UnmapBuffer ?
These new flags are basically the "host-counterparts" of the original flags.
For example, consider the CL_MEM_READ_ONLY flag:
This flag specifies that the memory object is a read-only memory object when used inside a kernel.
In contrast to that, for CL_MEM_HOST_READ_ONLY:
This flag specifies that the host will only read the memory object
(from the clCreateBuffer documentation, emphasis by me)
They thus allow a more fine-grained specification of what you will do with the memory:
Host read, Kernel write
Host write, Kernel write
Host read+write, Kernel read
....
This enables the OpenCL implementation to perform optimizations under the hood, quoting from the above mentioned documentation:
This flag specifies that the host will only write to the memory object (using OpenCL APIs that enqueue a write or a map for write). This can be used to optimize write access from the host (e.g. enable write combined allocations for memory objects for devices that communicate with the host over a system bus such as PCIe).
Of course this will affect how the buffer may be used. For example, when you create a host-read-only buffer with CL_MEM_HOST_READ_ONLY, then an attempt to write to this buffer with clEnqueueWriteBuffer will fail - again, refering to the documentation:
Errors
clEnqueueWriteBuffer returns CL_SUCCESS if the function is executed successfully. Otherwise, it returns one of the following errors:
...
CL_INVALID_OPERATION if clEnqueueWriteBuffer is called on buffer which has been created with CL_MEM_HOST_READ_ONLY

Resources