I have a touchscreen controller (which is an I2C slave) that I need to enable via APCI. This should be done by calling the _PS0 ACPI method. I call this method by using AcpiEvaluateObject with no arguments and no return values.
AcpiEvaluateObject(nullptr, (ACPI_STRING)"\\_SB.I2C4._PS0", nullptr, nullptr); // returns AE_OK
AcpiEvaluateObject(nullptr, (ACPI_STRING)"\\_SB.I2C4.TCS2._PS0", nullptr, nullptr); // returns AE_AML_UNINITIALIZED_ARG
When calling this method on the parent object (I2C4), everything goes fine but calling it on the touch screen controller (TCS2), it fails. What also makes me wonder is that it returns AE_AML_UNINITIALIZED_ARG even though it doesn't take any args (according to the DSDT).
Calling the _CRS method on the same object also works without any problems. I also looked into the Linux kernel source how they change ACPI power states and they use the exact same mechanism. It boils down to the use of acpi_evaluate_object in acpi_dev_pm_explicit_set which also seems to work on the touchscreen device.
I'm not using Linux, but Genode and the Acpica library.
what am I missing to successfully enable the touchscreen device via ACPI? Is there something the Linux kernel is initializing implicitly (I couldn't find something like this)?
Related
I was looking at the docs for the WASAPI ActivateAudioInterfaceAsync() function and it mentions passing DEVINTERFACE_AUDIO_CAPTURE as deviceInterfacePath to activate the interface on the default audio capture device. That seems like a good practice since the MediaDevice::GetDefaultAudioCaptureId(AudioDeviceRole::Default) call I would otherwise make to get the deviceInterfacePath parameter (which is used in the WASAPI sample) is synchronous - even though it may take a few seconds in some cases, blocking the UI thread and potentially getting your app to be killed.
Unfortunately the docs don't show a sample, especially for how to pass the GUID as the LPCWSTR deviceInterfacePath to ActivateAudioInterfaceAsync.
How can I do it?
What I managed to code up:
Includes to add:
#include <initguid.h>
#include <mmdeviceapi.h>
Initialization:
ComPtr<IActivateAudioInterfaceAsyncOperation> asyncOp; /*needed to get ActivateCompleted callback*/
PWSTR audioCaptureGuidString;
StringFromIID(DEVINTERFACE_AUDIO_CAPTURE, &audioCaptureGuidString);
// This call must be made on the main UI thread. Async operation will call back to
// IActivateAudioInterfaceCompletionHandler::ActivateCompleted
HRESULT hr = ActivateAudioInterfaceAsync(
audioCaptureGuidString, /* deviceInterfacePath (default capture device) */
__uuidof(IAudioClient2), /*riid*/
nullptr, /*activationParams*/
this, /*completionHandler*/
&asyncOp /*createAsync*/);
CoTaskMemFree(audioCaptureGuidString);
// Windows holds a reference to the application's IActivateAudioInterfaceCompletionHandler interface
// until the operation is complete and the application releases the IActivateAudioInterfaceAsyncOperation interface
I'm using CentOS 6.6 (64-bit) and RH 1.10.2
I have a waveform that requires a FRONTEND::TUNER device that is of type RX_DIGITIZER. I also have a 1.10.2 based device that is a RX_DIGITIZER_CHANNELIZER. This device has all the functionality that the waveform needs, but the waveform will not use it because of the different tuner type.
I see that it is not picked because FrontendTunerDevice<TunerStatusStructType>::allocateCapacity() (in fe_tuner_device.cpp) that my device inherits looks for an exact match on tuner_type.
I'm not seeing any elegant ways around this. Here are the two not so elegant ways I can see around it.
I can either completely override allocateCapacity and duplicate 95% of its logic, but explicitly accept both tuner types.
Or I can override allocateCapacity and modify the capabilities before passing to the superclass method. In pseudo-code:
CORBA::Boolean MyDevice::allocateCapacity(const CF::Properties & capacities)
{
if ( capacities ask for RX_DITIGIZER ) {
CF::Properties caps = capacities;
change type to RX_DITIGIZER_CHANNELIZER
return super::allocateCapacity(caps);
} else {
return super::allocateCapacity(capacities);
}
}
Is there a better way?
The FrontEnd interfaces specification as outlined in Appendix E of the REDHAWK User Manual is a guide and has been known to be interpreted in different ways by REDHAWK device developers. In your case, the simplest solution would be to change the allocation in your waveform to an RX_DIGITIZER_CHANNELIZER and connect a listener to the device, assuming the device has the ability to output wideband data (RX_DIGITIZER). Otherwise, your suggested approach is correct while keeping in mind that the device must perform the appropriate bookkeeping should a user allocated DDCs against the CHANNELIZER portion of this device.
For more information, please refer to section E.2 on Frontend Tuner Types.
I am using a third party .dll which wraps around the DirectX d3d9.dll, modifying the original .dll's execution. A well known example of this type of setup is used by Fraps.
I am creating a Fullscreen exclusive device in multihead mode (D3DCREATE_ADAPTERGROUP_DEVICE).
I am running up against a problem where the .dll wrapper exits my program when a particular function is called from D3D9SetMode.
Here is a partial call stack generated by WinDbg from breaking when ChangeDisplaySettingsExA function is called:
0018e748 7024712d USER32!ChangeDisplaySettingsExA
0018e828 7024702e d3d9!D3D9SetMode+0xec
0018e858 70246fab d3d9!DdSetModeLH+0x83
0018e954 7024760b d3d9!CSwapChain::SetSwapChainDisplayMode+0x5ca
0018e9a4 702492b0 d3d9!CSwapChain::DoneExclusiveMode+0xc7
0018e9c8 702491fc d3d9!CEnum::DoneExclusiveMode+0x5d
0018ea18 7024904a d3d9!handleActivateApp+0x12f
0018ea40 763862fa d3d9!WindowProc+0x30f
...
I have worked out the WM_ACTIVATE is the last message to be processed before this occurs.
I have tried building against the DirectX9 February 2005 and 2007 SDK's (d3dx9_24.dll and d3dx9_32.dll respectively) - they both have the same problem.
I suspect there is a flag or setup scenario to prevent the call to ChangeDisplaySettingsExA. I have tried D3DCREATE_NOWINDOWCHANGES on device creation without any success.
Any links, information, ideas?
I am using the Aria C++ programming libs for mobile robots (http://robots.mobilerobots.com/wiki/ARIA). I am new to this API so I wanted to start with a simple action class derived from ArAction. Now I tried to develop a small test program (an ArAction) in order to
control a simulated p3dx robot via MobileSim. Development takes place under Ubuntu 10.10, using gcc 4.4.5. Making (compiling) my code works fine, without errors. I can also set the desired speed for example in my ArAction's fire() method, and the simulation is also working as desired.
But, unfortunately, I can't use the ArRobot object attached to the ArAction I am overriding. The problem is that none of the member functions of the ArRobot object seems to work. For example, calling getVel() or getCompass() always returns a zero value. And when I call the hasFrontBumpers() method the program even crashes with the error message "Aria: Received signal 'SIGSEGV'. Exiting.". As soon as I remove this method call and recompile the error is also gone again...
Here is the relevant code that leads to the crash:
ArActionDesired * forward::fire(ArActionDesired d)
{
desiredState.reset();
ArRobot *r = getRobot();
if(r == NULL)
{
printf("ArRobot = NULL\n");
deactivate();
return &desiredState;
}
printf("ok, ArRobot is not NULL, check for bumpers...\n");
r->hasFrontBumpers(); // <-- this leads to the SIGSEV-based "crash"
return &desiredState;
}
Any ideas what I am missing here -- is it a problem with my coding, or with the simulation environment? Thanks in advance for your help!
Kind regards, Matthias
ok, found it out now -- for the records: the Aria libs in version 2.7.2 are based on gcc-3 and libstdc++ 5, but Ubuntu 10.10 (which I am using) is shipped with gcc-4 and libstdc++ 6 per default. So I had to manually install the older versions of both packages, now my code is running fine...
cheers!
Calling hasFrontBumpers() for a p3dx from the fire() works fine for me on a similar Linux platform. If something is wrong, it is not in this method but in the initialization of the system. A reason for the non-moving robot could be that robot.enableMotors() hasn't been called.
I've successfully loaded a C++ plugin using a custom plugin loader class. Each plugin has an extern "C" create_instance function that returns a new instance using "new".
A plugin is an abstract class with a few non-virtual functions and several protected variables(std::vector refList being one of them).
The plugin_loader class successfully loads and even calls a virtual method on the loaded class (namely "std::string plugin::getName()".
The main function creates an instance of "host" which contains a vector of reference counted smart pointers, refptr, to the class "plugin". Then, main creates an instance of plugin_loader which actually does the dlopen/dlsym, and creates an instance of refptr passing create_instance() to it. Finally, it passes the created refptr back to host's addPlugin function. host::addPlugin successfully calls several functions on the passed plugin instance and finally adds it to a vector<refptr<plugin> >.
The main function then subscribes to several Apple events and calls RunApplicationEventLoop(). The event callback decodes the result and then calls a function in host, host::sendToPlugin, that identifies the plugin the event is intended for and then calls the handler in the plugin. It's at this point that things stop working.
host::sendToPlugin reads the result and determines the plugin to send the event off to.
I'm using an extremely basic plugin created as a debugging plugin that returns static values for every non-void function.
Any call on any virtual function in plugin in the vector causes a bad access exception. I've tried replacing the refptrs with regular pointers and also boost::shared_ptrs and I keep getting the same exception. I know that the plugin instance is valid as I can examine the instance in Xcode's debugger and even view the items in the plugin's refList.
I think it might be a threading problem because the plugins were created in the main thread while the callback is operating in a seperate thread. I think things are still running in the main thread judging by the backtrace when the program hits the error but I don't know Apple's implementation of RunApplicationEventLoop so I can't be sure.
Any ideas as to why this is happening?
class plugin
{
public:
virtual std::string getName();
protected:
std::vector<std::string> refList;
};
and the pluginLoader class:
template<typename T> class pluginLoader
{
public: pluginLoader(std::string path);
// initializes private mPath string with path to dylib
bool open();
// opens the dylib and looks up the createInstance function. Returns true if successful, false otherwise
T * create_instance();
// Returns a new instance of T, NULL if unsuccessful
};
class host
{
public:
addPlugin(int id, plugin * plug);
sendToPlugin(); // this is the problem method
static host * me;
private:
std::vector<plugin *> plugins; // or vector<shared_ptr<plugin> > or vector<refptr<plugin> >
};
apple event code from host.cpp;
host * host::me;
pascal OSErr HandleSpeechDoneAppleEvent(const AppleEvent *theAEevt, AppleEvent *reply, SRefCon refcon) {
// this is all boilerplate taken straight from an apple sample except for the host::me->ae_callback line
OSErr status = 0;
Result result = 0;
// get the result
if (!status) {
host::me->ae_callback(result);
}
return status;
}
void host::ae_callback(Result result) {
OSErr err;
// again, boilerplate apple code
// grab information from result
if (!err)
sendToPlugin();
}
void host::sendToPlugin() {
// calling *any* method in plugin results in failure regardless of what I do
}
EDIT: This is being run on OSX 10.5.8 and I'm using GCC 4.0 with Xcode. This is not designed to be a cross platform app.
EDIT: To be clear, the plugin works up until the Apple-supplied event loop calls my callback function. When the callback function calls back into host is when things stop working. This is the problem I'm having, everything else up to that point works.
Without seeing all of your code it isn't going to be easy to work out exactly what is going wrong. Some things to look at:
Make sure that the linker isn't throwing anything away. On gcc try the compile options -Wl -E -- we use this on Linux, but don't seem to have found a need for it on the Macs.
Make sure that you're not accidentally unloading the dynamic library before you've finished with it. RAII doesn't work for unloading dynamic libraries unless you also stop exceptions at the dynamic library border.
You may want to examine our plug in library which works on Linux, Macs and Windows. The dynamic loading code (along with a load of other library stuff) is available at http://svn.felspar.com/public/fost-base/trunk/
We don't use the dlsym mechanism -- it's kind of hard to use properly (and portably). Instead we create a library of plugins by name and put what are basically factories in there. You can examine how this works by looking at the way that .so's with test suites can be dynamically loaded. An example loader is at http://svn.felspar.com/public/fost-base/trunk/fost-base/Cpp/fost-ftest/ftest.cpp and the test suite registration is in http://svn.felspar.com/public/fost-base/trunk/fost-base/Cpp/fost-test/testsuite.cpp The threadsafe_store holds the factories by name and the suite constructor registers the factory.
I completely missed the fact that I was calling dlclose in my plugin_loader's dtor and for some reason the plugins were getting destructed between the RunApplicatoinEventLoop call and the call to sendToPlugin. I removed dlclose and things work now.