PHP in Elphel cameras
Contents
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
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 return 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_program_sensor
void elphel_program_sensor (long nonstop)
elphel_compressor_run
void elphel_compressor_run (void)
elphel_compressor_stop
void elphel_compressor_stop (void)
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?)