PHP in Elphel cameras

From ElphelWiki
Revision as of 18:55, 14 December 2007 by Andrey.filippov (talk | contribs) (''elphel'' extension functions)
Jump to: navigation, search

Why PHP?

One of the main objectives of Elphel products is to make them developer-friendly. Just opening of the camera internals (including source code, FPGA code, hardware schematics) is not enough without providing means to modify the cameras easily, and here PHP comes to the rescue. It is powerful and efficient and is well known by many developers including those who may have problems to modify FPGA code or kernel drivers. It is much easier to try your custom applications written in PHP - just transfer the files to the camera (i.e. with ftp) and open them in the web browser.

PHP supports custom extensions written in C and we'll work (and I hope not just we at Elphel) to provide more custom function to combine flexibility and ease of use of the PHP with efficiency of native compiled code.

PHP in Elphel cameras (models 353/363)

Current version of PHP in Elphel cameras is 5.2.1, we will try to keep it (almost) current. As of now ( Elphel software version 7.1.6) there are two copies of PHP in the camera - one is working through Boa web server (traditional for Axis ETRAX based products) in CGI mode (port 80) and the other one in Fast CGI mode through Lighttpd on port 81. Fast CGI mode does not restart applications (like traditional CGI does) for each HTTP request but rather keeps them alive to serve multiple requests. In the case of large application like PHP itself it makes a big performance difference and allows usage of the PHP scripts in the camera without the penalty of slow responses - something really undesirable for AJAX applications.


How to use PHP in the camera

It is very simple. It is the same as to try your HTML/JavaScript pages. You just need to ftp you script to one of the two locations (or their subdirectories) in the camera. Examples below assume you have the default camera IP=192.168.0.9:

  • /var/html (visible as http://192.168.0.9:81/var/ in the web browser) - recommended for experiments, if something goes wrong you can just power-cycle the camera and all your changes will be gone
  • /usr/html' (visible as http://192.168.0.9:81/ in the web browser) - permanent (until next full firmware upgrade ) storage in the camera flash memory. This second location is more dangerous as you can change the installed files and rebooting will not restore the default behaviour. Flash memory has limited number of write cycles and can develop additional bad blocks during usage, so this location is recommended for "final" files, already tested in /var/html.

You may also edit small text files with web-based editor. It does not allow to open non-existent file, but has an option to "Save As" - http://192.168.0.9:81/admin-bin/editcgi.cgi So you can try opening http://192.168.0.09:81/admin-bin/editcgi.cgi?file=/usr/html/phpinfo.php and then (modify and) save it to /var/html/test.php . When done - just open the following URL and watch the results of the script processing by in-camera PHP:

http://192.168.0.9:81/var/test.php  - run
http://192.168.0.9:81/admin-bin/editcgi.cgi?file=/var/html/test.php - edit

It is also possible to execute PHP scripts without the browser - camera startup scripts already use it for various initialization of the hardware. You can (silently) execute the same program in telnet session:

php /var/html/test.php >/dev/null

Elphel PHP extension in the camera

Since Elphel software version 7.1.6 there is a custom extension module for PHP installed in the camera, you may also create your own extension as described below. The existent extension exports several functions and defines constants.

Constants, defined in elphel PHP extension

see: Elphel_PHP_constants

elphel extension functions

Note: Currently arguments (and array values) are supposed to be numbers, not strings - you may want to use $value+0 (instead of just $value) if $value may be a string (i.e. passed from _GET[])--Andrey.filippov 19:55, 14 December 2007 (CST)


elphel_get_P_value

long elphel_get_P_value (long $address)

This function returns value of one of internal camera parameters, as defined in c313a.h and documented in Elphel_PHP_constants. It is strongly recommended to use symbolic names as the numeric values may change in the future (as they already did multiple times). The values are maintained by the camera driver(s), usually they are updated when the driver programs the acquisition process.

Example:

echo elphel_get_P_value(ELPHEL_FP100S)/100; // will return current camera sensor frame rate in (frames per second);



elphel_set_P_value

void elphel_set_P_value (long $address, long $data) Set camera parameters to be used when the camera will be "programmed" (see below). Example:

elphel_set_P_value(ELPHEL_QUALITY,100); // set JPEG compression quality to 100% - virtually lossless

The elphel_get_P_value and elphel_set_P_value deal with different variables. Those that are read are validated to match the allowed values and may differ from those written (and they are only updated when sensor/compressor are programmed). You may read the parameters values that were written to the camera by adding ELPHEL_NUMBER to the parameter address, i.e

echo elphel_get_P_value(ELPHEL_QUALITY+ELPHEL_NUMBER); // will output the compression quality as written



elphel_get_P_arr

array elphel_get_P_arr (array $template) Read multiple camera parameters as an associative array, according to $template. $template should have elements with the key names matching the camera parameters names, same as defined Elphel_PHP_constants, but without "ELPHEL_" prefix (all the elements with the other keys will be ignored). elphel_get_P_arr returns array, where element keys are the same as in $template (after removing of any unknown ones), and values are long values read from the camera.

Example:

$arr=array("foo"=>"", "WOI_LEFT" => "",  "WOI_TOP" => "", "1", 3, "WOI_WIDTH" => 0, "WOI_HEIGHT" => 0);
print_r ($arr);

will return (5MPix sensor, full window):

Array
(
   [WOI_LEFT] => 0
   [WOI_TOP] => 0
   [WOI_WIDTH] => 2592
   [WOI_HEIGHT] => 1936
)



elphel_set_P_arr

long elphel_set_P_arr (array $input)

Write multiple camera parameters, provided as an associative array, where keys are parameter names same as defined Elphel_PHP_constants, but without "ELPHEL_" prefix. Values should be numeric and integer, all other types are ignored.

Return value - number of successfully processed elements.

Example:

echo elphel_set_P_arr(array("WOI_LEFT" => 896,  "WOI_TOP" => 672, "WOI_WIDTH" => 800, "WOI_HEIGHT" => 600));

Will print 4 and set 800x600 window in the center of the 5Mpix sensor.



elphel_get_state

long elphel_get_state (void) There are multiple states defined in the camera, some are obsolete, the following are most common (no symbolic constants in PHP yet)

  • 0 - "reset" (i.e. no images yet acquired after power up)
  • 7 - "stopped" - sensor is constantly acquiring images (used for autoexposure), but compressor is stopped and no frames get to the circbuf
  • 8 - "running" - compressor is acquiring images to circbuf
  • 9 - "stopping" - compressor is compressing the last frame (transition from "running" to "stopped"
  • 10 - "single_buffer" - compressor is acquiring full circbuf (plus one frame as it will notice the buffer is full after overrunning the original starting point) and then will stop



elphel_reset_sensor

void elphel_reset_sensor (void) Reset the sensor settings, stop compressor (if it was running) and force sensor re-initialization.

Example:

elphel_reset_sensor();



elphel_program_sensor

void elphel_program_sensor (long $nonstop) Applies written earlier (see elphel_set_P_value, elphel_set_P_arr) parameters to the cameras sensor and FPGA compressor. $nonstop determines if the acquisition should be restarted ($nonstop==0) ot updated without stopping ($nonstop==1).

Example:

elphel_program_sensor(0);



elphel_compressor_run

void elphel_compressor_run (void) Turn the FPGA compressor on. Sensor should be already programmed ([[PHP_in_Elphel_cameras#|elphel_get_state] should return 7 (or higher) if tested prior to issuing elphel_compressor_run() command.

Example:

elphel_compressor_run();



elphel_compressor_stop

void elphel_compressor_stop (void)

Stop camera compressor (will stop transferring more frames to the circular buffer. This command does not to be synchronized - compressor will finish current frame before stopping.

Example:

elphel_compressor_stop();



elphel_compressor_frame

void elphel_compressor_frame (void) Acquire one frame to the buffer (will apply written JPEG quality). Sensor should be already programmed ([[PHP_in_Elphel_cameras#|elphel_get_state] should return 7 (or higher) if tested prior to issuing elphel_compressor_frame() command.

Example:

elphel_compressor_frame();




elphel_set_fpga_time

double elphel_set_fpga_time (double seconds) Set FPGA internal timer that is used for time-stamping images and video frames. Internal counter has a 32-bit seconds counter and 12 bit microsecond one, so you may specify epoch - seconds since 01/01/1970.

Returns time set as a double - it should match the input parameter after rounding to microseconds (resolution of the FPGA timer).

Example:

elphel_set_fpga_time(0x47565ad3);

elphel_get_fpga_time

double elphel_get_fpga_time (void)

Copies current value of the FPGA timer registers to the global array (maybe read with several functions described above) and returns the the time as a double value, combining second as microseconds. The readout process guaranties that seconds and microseconds are sample simultaneously.

Example:

echo elphel_get_fpga_time();



elphel_flush_cache

void elphel_flush_cache (void)

This function is included to fight (hardware) cache coherency problems in mmap implementation for ETRAX FS processor. I'm not sure it will be really needed here - it needs some testing. If it will be proven it is needed - we'll incorporate it into appropriate functions that depend on it, if not it will just be removed.

This function may be needed before elphel_get_P_value, elphel_get_P_arr to read data updated by the driver and/or before elphel_program_sensor, PHP_in_Elphel_cameras#elphel_compressor_run\elphel_compressor_run, elphel_compressor_frame (if any of the parameters were changed with elphel_set_P_value, elphel_set_P_arr after the last call to elphel_flush_cache

Example:

elphel_flush_cache();

Update: confirmed, elphel_flush_cache() is needed, without it I've seen GAINR and GAING updated, while GAINB, GAINGB - not. They have addresses 46,47 and 48,49 so belong to different cache lines (are written to system memory at different times)

Creating custom PHP extensions for Elphel cameras

... You may also want to try your scripts from the command line - in that case the stdout will be visible and you and PHP+your module will be able to complain about Segmentation faults (when invoked from the browser it you will get Error 500 at best if that happens). And you'll have to manually restart web server + PHP after module changes (remember - Fast CGI does not kill PHP after end of HTTP request?)