The CiA 301 CANopen protocol specification defines two objects that a device may implement to save and restore parameters:
Object 1010h - Store Parameters
When a device implements this object, the CANopen master writes the value "save" to one of the subentries of the object to cause the corresponding set of parameters to be written to non-volatile memory.
Object 1011h - Restore Default Parameters
When a device implements this object, the CANopen master writes the value "load" to one of the subentries of the object to restore the corresponding default parameters to be restored.
Device Reset
The CiA 301 specification says that "default values shall be set valid after the CANopen device is reset" - by way of a power cycle, NMT reset node (sub-index 01h to 7Fh) or NMT reset communication (sub-index 02h).
What are 'the default values'?
Does "the default values" mean:
The values set by the Store Parameters object? In which case, how can the device be reset to the original factory default settings?
The original factory default settings? If so, when should the saved parameters be restored?
A combination of the above, whereby the factory default settings are restored by a device reset, and the Store Parameters values are restored by the Restore Default Parameters object?
Some other definition?
I understand the mechanisms for reading from the objects to obtain the device capabilities and writing the guard pattern to them to trigger the required action. I also know which values to save and which subsets to save for the different sub-indeces.
The thing I do not understand is when should the factory default values be used (if at all) rather than the saved values, and vice versa?
Object 1010h - Store Parameters
This does exactly what you'd expect: it causes the specified parameters to be stored.
Object 1011h - Restore Default Parameters
This causes and parameters that were previously saved by the Store Parameters to be no longer saved so that the original default values are used when the device resets. It is not equivalent to 'Load Parameters' (there is no such object), as this operation occurs automatically when the device resets, rather it could be thought of as 'Delete Stored Parameters'.
Summary
Object 1010h causes parameters to be saved.
Object 1011h causes saved parameters to be deleted.
On reset, parameters will be loaded from their saved values, if they have been stored, or set to their default values if the default values have been restored.
Related
When calling vkCmdBindDescriptorSets, I have to pass the number of the first set and an array of descriptor sets that I would like bound. I then get to use whichever set I like in my shader using layout(set = X, binding = 0).
My question is the following. The descriptor set layout for the set was only specified at descriptor set creation. Yet when I bind, I can bind any descriptor set to any set number using the above function. Is it up to my to keep my shader layout and binding consistent with the layout specified amongst pipeline creation? Otherwise, how does the pipeline/shader "know" which layout my specific set is using?
In Vulkan, unless otherwise noted, it's always "up to you". This is no exception.
If you attempt to render/dispatch with a pipeline and bound descriptor sets that do not have matching layouts, undefined behavior results.
The pipeline "knows" which layout you're using by fiat. The whole point of a layout is that it "lays out" the arrangement of the internal data representing how those descriptors are organized. So where "binding 2" is within whatever internal data structure the implementation uses for defining that is determined solely by the layout.
A layout is therefore kind of like a struct in C or C++. You can't pass a pointer to a struct of type B to a function that expects a pointer to a struct of type A. Well, you can if you do a bunch of casts, but when the function accesses that pointer, undefined behavior results.
The same goes for pipelines and bound descriptor sets: they must use compatible layouts, or undefined behavior results.
I have a custom FuelTank object, anylogic tank but with some extra logic. It has a parameter SimTank of type "storageTank". The anylogic "tank" block (inside the FuelTank object) has its "StorageTank" set to this parameter.
I now have a TankFarm object which in turn incorporates a number of these FuelTank objects. And a Collection - FuelTanks to reference each of the tanks. It has a parameter SimTanks, which is a one-dimensional array of type Other, storageTank[].
So now.
If I configure the TankFarm object, select each tank in the object and one by one set each tank's SimTank parameter to "SimTanks[0]", "SimTanks[1]", etc. then populate SimTanks with the list of storageTanks I want to use in my visual representation, everything works fine. EXCEPT if I have less "storageTanks" in my SimTanks array than there are tanks in my TankFarm object. (which is understandable. If I only have 4 storageTanks, but 5 tanks in my tankfarm, then tank 5 will have its "SimTank" parameter set to "SimTanks[4]" which of course does not exist in the "SimTanks" array and correspondingly gives an error)
To get around this problem, I use a function and run it when the simulation starts:
for (int s=0; s<=(TankFarm.SimTanks.length-1); s++)
TankFarm.FuelTanks.get(s).SimTank = SimTanks[s];
So now if the user only added 4 "storageTank objects" to his visual simulation, only the first four tanks in the "TankFarm" are assigned a storageTank the last one is "null".
Code works (does not give an error), but when you run the model there is ZERO simulation, none, nothing happens with the StorageTank objects in the visual representation, they don't show anything; it is as if the AnyLogic tanks (inside the individual FuelTank objects), are not linked with the StorageTanks?
How do I fix this please"? How do I dynamically assign the StorageTank objects dropped on the main window and added to the SimTanks array to the tanks in my FuelTank object?
(To clarify, if I do it manually, one by one, it works - but then if I have less storageTanks than Tanks in my farm it gives an error. If I do exactly the same dynamically, through code, it does not give an error, but the simulation does not work, the storageTanks does not show anything??)
This issue has been resolved thank you. I created a function inside the library object that returns a StorageTank. Then added a parameter that the user configures to use the object's animation or add "his own" animation. Each tank object in the library then calls the function which returns a StorageTank object - either the built-in object (built into the library object) or the one the user added manually. The method works perfectly - user may drop the library object (which includes its own animation) but then configure it to not use that animation, in which case user has to build and assign his own animation.
I'm working on a project using Redis cache with cachingFramework.redis.
I already have working the get function with Redis (using FetchObject)
but I need to update the Save function to save in DB and override/update the key/value in Redis.
Should I use SetObject? or I need to call first Remove(key)
It really depends on the when parameter, but by default the SET operation on redis overrides the current value, regardless of its type. Here is the documentation.
So you don't need to call the Remove method.
You can check here how StackExchange.Redis library choose between different SET commands (SET, SETNX, SETEX) depending on the parameters.
I have two method: METHOD_A() and METHOD_B().
In METHOD_A() I use another method METHOD_A_A which returns me an internal table et_entityset with some data.
I want to export et_entityset to memory and import it from memory in METHOD_B(), but when I import et_entityset it's always blank.
My minimal reproducible example:
In method METHOD_A():
DATA et_entityset TYPE some_type.
lo_camp->METHOD_A_A(
EXPORTING
it_order = SOMETHING
IMPORTING
et_entityset = et_entityset
).
IF et_entityset IS NOT INITIAL.
EXPORT lt_mem_content FROM et_entityset TO MEMORY ID 'lt_memory_content'.
ENDIF.
In METHOD_B():
DATA lt_mem_content TYPE some_type.
IMPORT lt_mem_content TO lt_mem_content FROM MEMORY ID 'lt_memory_content'.
READ TABLE lt_mem_content INTO DATA(ls_mem_content) INDEX 1.
DATA(lv_content_id) = ls_mem_content-id.
Export to memory / Import to memory is valid only within a session.
So assuming you have not made a typo / upper lowercase error with the export and memory commands, then I can only assume you are no longer with the call sequence within a session.
Eg new calls to stateless services, new rfc calls not reusing a session .
A cross Workprocess cross session option.
Export ... to SHARED BUFFER
HOWEVER, there is NO guarantee the value will be there, as there is an automatic free as required algorithm that will discard entries to make room for new entries.
So if you plan to use this, make sure sufficient memory is allocated to the shared memory buffer. in AL12 you can monitor the entries.
The "ABAP memory", which is used by Export to memory and Import to memory, is accessible only by programs running in the same "ABAP session" (explanation of different types of memories and types of sessions in ABAP-based systems).
Two programs may run in the same ABAP session if they call each other, directly or indirectly, via statements like SUBMIT, CALL TRANSACTION, procedure call, etc.
For example:
If there are two HTTP calls, that will be two different ABAP sessions. There is one exception for BSP, which is an old SAP technology, there is a "stateful" flag at BSP level which retains and reuses the ABAP sessions.
If a user logs in once (one user session), and opens a new window (Ctrl+N), all programs executed in that window run in a second "ABAP session", i.e. two programs running in each session cannot communicate via the "ABAP memory".
Example to make two programs exchange some data via the ABAP memory:
REPORT zprogram1.
DATA variable TYPE string.
EXPORT memory_name_1 = `A` TO MEMORY ID 'my Z memory 1'.
SUBMIT zprogram2 AND RETURN.
IMPORT memory_name_2 = variable FROM MEMORY ID 'my Z memory 2'.
ASSERT variable = `AB`. " <=== proof that data was transferred via ABAP memory
REPORT zprogram2.
DATA variable TYPE string.
IMPORT memory_name_1 = variable FROM MEMORY ID 'my Z memory 1'.
variable = variable && `B`.
EXPORT memory_name_2 = variable TO MEMORY ID 'my Z memory 2'.
PS: an "ABAP session" may be better known as the old name "external session".
How can i retrieve the is_sfparam-content, either using query or function module.
then will be passed as a parameter to cl_recp_data_cn_general=>get_contract.
do you have any idea? Where can I get that is_sfparam-content?
Thanks
CALL METHOD cl_recp_data_cn_general=>get_contract
EXPORTING
id_guid = is_sfparam-content
IMPORTING
es_contract = contract
CHANGING
cf_error = lf_error.
This guid paramater brings no sense as it is generated in runtime. You can check this yourself by putting breakpoint at the first line (e.g. line 102) of method cl_recp_data_cn_general=>get_contract and checking id_guid var in debugger. It will be different with each run of preview in RECN tcode.
Check also line 11 of CONSTRUCTOR method of CL_RECP_SF_DOC class, it is executed during each form generation.
The real contract object lays in variable go_busobj of program SAPLRECA_BDT_APPL_TOOL which brings RECN functionality and it is global i.e. it is loaded into memory constantly while RECN is running, just passing doc object into called methods thru the call stack, which you can follow in debugger.
Where really form generation takes place is CL_RECP_SF_JOB class, for preview it is _FP_PREVIEW method, for print it is _FP_PRINT. For example, in preview method form FM is called in that place
What you need to do if you want to call arbitrary contract print-form, which is what I assume you want to do by asking this question:
Find out smartform FM name by putting breakpoint in the above line
Build parameters for this FM calling. The only obligatory parameter is LS_SFPARAM-CONTENT which is the GUID.
You can generate this GUID manually by creating CL_RECP_SF_DOC object, let it be io_doc var. The constructor of this object has input parameter is_doc which should be filled according to the attributes of contract which you want to print, and which are stored in VIBDRO and VICNCN tables.
After creating this object pass its attribute io_doc->md_guid to ls_sfparam-content, generate other parameters with CL_RECP_SF_JOB->_sf_get_form_param and
Run the smartform FM /1BCDWB/SF000000XX found at step 1 with these parameters
I didn't check all these steps by myself but I believe it should work.