Android kernel : How to create /dev/video0 before ueventd daemon gets started? - android-kernel

I want to access /dev/video0 from a kernel module after camera is initialized.
For that I want to create /dev/video0 node before the ueventd daemon gets started.

Looking more deeply the kernel handling of /dev/video0 node whenever an
application tries to open this file it gets a FILE *fp pointer ,
the linux kernel virtual file system checks whether this is a regular file or
device file, and if it is a device file it checks it's major number to track
the driver which registered it and saves the minor number in i_rdev field of
struct inode *inode which is again embedded in struct file *fp and
passed to that driver.
So for every FILE *fp opened by application there is struct file *fp in
registered driver i.e v4l2 driver in our case. This file pointer is passed on
to kernel ioctl API v4l2_ioctl.
Now internally v4l2 driver maintains an array of pointers to all the
registered video devices
as seen below :
static struct video_device *video_device[VIDEO_NUM_DEVICES];
Now if we see the implementation of main ioctl call.
static long v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
struct video_device *vdev = video_devdata(filp);
...
}
This video device structure is extracted from file pointer which is the key by which we can control the video device i.e. our camera from within the kernel as it contains function pointers to all the registered v4l2 ioctls. So our target is to access the video device structure from within the kernel.
Now again looking at how kernel accesses the video device when it gets a request from application.
struct video_device *video_devdata(struct file *file)
{
return video_device[iminor(file->f_path.dentry->d_inode)];
}
EXPORT_SYMBOL(video_devdata);
static inline unsigned iminor(const struct inode *inode)
{
return MINOR(inode->i_rdev);
}
As seen above it uses i_rdev field for getting the minor number passed from struct file *fp through VFS.
To summarise if we want to access ioctl from within the kernel we need to fill
a dummy file *fp pointer containing minor number in
file->f_path.dentry->d_inode.i_rdev field, v4l2 subsystem will get
video_device structure using this field and will be able to drive further the
ioctl operations from video_device structure by using video_device->ioctl_ops
field as seen below.
struct video_device
{
#if defined(CONFIG_MEDIA_CONTROLLER)
struct media_entity entity;
#endif
/* device ops */
const struct v4l2_file_operations *fops;
const struct v4l2_ioctl_ops *ioctl_ops;
...
}
To set file->f_path.dentry->d_inode.i_rdev we need to add references to inode and dentry structure inside file structure as per below pseudocode:
static int enumerate_camera()
{
inode.i_rdev = cam_minor_number ;// Saved when camera device registered;
dentry.d_inode = inode;
file.f_path.dentry = dentry;
file.f_dentry->d_inode = inode;
....
}

Related

How to fix 'avr-g++: error: device-specs/specs-atmega328p: No such file or directory' error in Arduino IDE

I am programming my arduino uno on the new raspberry pi 4. I have installed arduino IDE v1.8.9 and I am having issues in compiling the code.
I am getting an error.
avr-g++: error: device-specs/specs-atmega328p: No such file or directory
Please Help.
I am running Rasbian Os
/*
AnalogReadSerial
Reads an analog input on pin 0, prints the result to the Serial Monitor.
Graphical representation is available using Serial Plotter (Tools > Serial Plotter menu).
Attach the center pin of a potentiometer to pin A0, and the outside pins to +5V and ground.
This example code is in the public domain.
http://www.arduino.cc/en/Tutorial/AnalogReadSerial
*/
// the setup routine runs once when you press reset:
void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
}
// the loop routine runs over and over again forever:
void loop() {
// read the input on analog pin 0:
int sensorValue = analogRead(A0);
// print out the value you read:
Serial.println(sensorValue);
delay(1); // delay in between reads for stability
}
This is the -tools option for arduino-builder missing the location avr.
A setting like
-tools /home/owner/arduino-1.8.10/hardware/tools/avr
is needed so as to find the spec files. Set your compile output to verbose to see the compile command that is issued, and verify above line is present.
More info: https://github.com/arduino/arduino-builder/issues/263

How to use the standard output by Flash Air?

I want to make a command line tool by Flash Air, but there is not any api of AS3 to output content to standard output.
Then, I try to use ANE to solve my problem(By making a windows ane and use C's printf function to output content), but it doesn't work.
Is there any methods to use the standard output by Flash air, or to make a command line tool by Flash Air?
The code of dll written by c++ is:
FREObject add(FREContext ctx, void* functionData, uint32_t argc, FREObject argv[])
{
int32_t x,y;
FREGetObjectAsInt32(argv[0], &x);
FREGetObjectAsInt32(argv[1], &y);
int32_t result = x + y;
FREObject resObj;
FRENewObjectFromInt32(result, &resObj);
//I want to use the "printf" to print content to the console
printf("print by dll: the result is %d\n", result);
return resObj;
}
but there is not any api of AS3 to output content to standard output.
Only a running OS process can give back Standard Output (also called stdio in C).
The best you can do is create an app that looks like commandline tool but in reality it just runs & passes data to the actual (native) OS commandline tool. Meaning in your tool you capture the user command to a string and then run a nativeProcess involving that (parsed) string as your process arguments.
Example in your app user types : calc. Your AIR runs: c:\Windows\System32\calc.exe
Anyways, on to your real question...
I try to use C's printf function to output content, but it doesn't
work.
If you mean you made some test.exe with C and when you get AIR to run it you want to capture the printf output then you can try:
process.addEventListener(ProgressEvent.STANDARD_OUTPUT_DATA, CTest_OutputData);
or
process.addEventListener(ProgressEvent.STANDARD_ERROR_DATA, CTest_ErrorData);
To catch the output (it will be sent as bytes) make sure you have some public byteArray and String created. Here's an example for STANDARD_ERROR_DATA (it's likely the output goes here too, since you claim that STANDARD_OUTPUT_DATA is not working).
The code shown below inside that function works same whichever type of progressEvent you choose. Just put in the "right" one. temp_BA is the byteArray variable you setup earlier.
public function CTest_ErrorData (event:ProgressEvent):void
{
process.standardOutput.readBytes( temp_BA, temp_BA.length, process.standardOutput.bytesAvailable );
if ( temp_BA.length > 0 )
{
temp_String = temp_BA.readUTFBytes(temp_BA.length);
trace( "temp_String is : " + temp_String ); //if you want to check it
}
}
Final TIP: You can get traces inside Flash IDE by disabling "desktop" and keeping "extended desktop" ticked. Both must be ticked later when you make installing app.

How to get NV12 file in the Nvidia CUDA 5.0 SDK's project cudaDecodeGL?

Lately, I've been reading the cudaDecodeGL project of Nvidia cuda5.0 SDK.This project convert a MPEG2 file to NV12 file, then the NV12 file is converted to ARGB file in the kernel function, finally this ARGB file will be rendered and displayed in the OpenGL window. Actually, the middle-produced NV12 file is not output, while I want to get the NV12 file.
I would be so appreciated if someone could tell me what to do.
Referring to the whitepaper:
Post processing on a frame is done by mapping the frame through cudaPostProcessFrame(). This returns a pointer to a NV12 decoded frame.
This function is contained (and used) in the source file videoDecodeGL.cpp which is contained in the sample project.
There is only one actual use (function call) for this function. It is called out of the copyDecodedFrameToTexture function. The decoded frame in this function is what you want. If you look through this function prior to the call to cudaPostProcessFrame you'll see the following code:
// If streams are enabled, we can perform the readback to the host while the kernel is executing
if (g_bReadback && g_ReadbackSID)
{
CUresult result = cuMemcpyDtoHAsync(g_bFrameData[active_field], pDecodedFrame[active_field], (nDecodedPitch * nHeight * 3 / 2), g_ReadbackSID);
This shows how/where/when to grab the decoded frame back to the host if you want to. At that point you will have to queue up the frames and save to a file if that is what you want to do.

How to define a global memory array at device code and pass the value to host after execution?

I try to create a device global memory array in the kernel code and after the exection is finished, pass the array content to host memory. Is it possible to create a global memory array at device code scope dynamically, or do I need to define the array out side if the device code score as global array.
__global__ void kernel_code(...,int array_size){
__device__ int array_data[size];
// fill the array_data
...
}
int main(){
//pass data from array_data to host array
}
is it possible to do that, if it is not what is the most likely practice?
The allocation of the array must be able to be performed statically by the compiler. So you cannot declare the size of it to be a parameter that you pass to a kernel.
Furthermore, a __device__ variable declaration is not allowed inside a function body. So it has to be at global scope in your module, not at function scope.
Apart from that, you can pass data between a statically declared device array and a host array. The __device__ variable has the following characteristics:
Resides in global memory space,
Has the lifetime of an application,
Is accessible from all the threads within the grid and from the host
through the runtime library (cudaGetSymbolAddress() /
cudaGetSymbolSize() / cudaMemcpyToSymbol() / cudaMemcpyFromSymbol()).
So in your host code, you would use cudaMemcpyToSymbol to transfer data to from your host array to the device array, and cudaMemcpyFromSymbol to transfer data from the device array to the host array.
For dynamically sized device arrays, the most common practice would be to allocate them using ordinary host runtime API functions like cudaMalloc and transfer data from a host array to a device array or vice-versa using cudaMemcpy
Normal practice is to manipulate device memory only in kernels (it's much faster). Simply use cudaMemcpy(dst, src, cudaMemcpyDeviceToHost) to copy the data into host memory (in main()).

CUDA plugin dlopen

I've written a cuda plugin (dynamic library), and I have a program written in C which uses dlopen() to load this plugin. I am using dlsym() to get the functions from this plugin. For my application it is very important that any time of loading plugin the program gets a new handle with dlopen() calling (the library file may modified subsequently).
Therefore after the using of functions from my plugin I invoke the dlclose(). The invocations dlopen() - dlsym() - dlclose() are occur during my program execution (in the loop).
If I working on the computer with NVIDIA driver 256.35 (CUDA 3.0 or 3.1) I have a memory leak (I use in my plugin cudaMemGetInfo() calling for the diagnostics).
If I working on the computer with NVIDIA driver 195.36.15 (CUDA 3.0) I have an error after some time of the program execution: “NVIDIA: could not open the device file /dev/nvidia0 (Too many open files).”
If I don't use the dlclose() invocation the program is working fine, but in this case I can't replace the plugin on a new one's during my program execution.
Anyone encountered this problem?
Thanks.
Nobody wrote plugins on CUDA?
I've found the similar example on CUDA SDK: matrixMulDynlinkJIT. I've done small correction in the code. In particular, in the file cuda_drvapi_dynlink.c I've corrected cuInit() function:
CUDADRIVER CudaDrvLib = NULL;
CUresult CUDAAPI cuInit(unsigned int Flags)
{
//CUDADRIVER CudaDrvLib;
CUresult result;
int driverVer;
if (CudaDrvLib != NULL) {
dlclose (CudaDrvLib);
CudaDrvLib = NULL;
}
.......
}
And in the file matrixMulDynlinkJIT.cpp I've added loop in the main() function:
int main(int argc, char** argv)
{
printf("[ %s ]\n", sSDKsample);
while (1) {
// initialize CUDA
CUfunction matrixMul = NULL;
cutilDrvSafeCallNoSync(initCUDA(&matrixMul, argc, argv));
.....
}//while (1)
cutilExit();
}
So, I have the same problem like in my program (after some time execution): “NVIDIA: could not open the device file /dev/nvidia0 (Too many open files).”
But when I comment out the dlclose() in the cuda_drvapi_dynlink.c file – all works fine
I can't understand this behavior...
Any ideas?