Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
E
elphel-apps-camogm
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Elphel
elphel-apps-camogm
Commits
03fde964
Commit
03fde964
authored
Dec 10, 2016
by
Mikhail Karpenko
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add disk test program
The program sequentionally writes counter value to disk
parent
ec1f0c4e
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
672 additions
and
2 deletions
+672
-2
Makefile
src/Makefile
+7
-2
camogm_test.c
src/camogm_test.c
+665
-0
No files found.
src/Makefile
View file @
03fde964
GUIDIR
=
camogmgui
GUIDIR
=
camogmgui
PROGS
=
camogm
PROGS
=
camogm
TEST_PROG
=
camogm_test
PHPSCRIPTS
=
camogmstate.php
$(GUIDIR)
/camogmgui.php
$(GUIDIR)
/camogmgui.css
$(GUIDIR)
/camogmgui.js
$(GUIDIR)
/camogm_interface.php
\
PHPSCRIPTS
=
camogmstate.php
$(GUIDIR)
/camogmgui.php
$(GUIDIR)
/camogmgui.css
$(GUIDIR)
/camogmgui.js
$(GUIDIR)
/camogm_interface.php
\
$(GUIDIR)
/SpryTabbedPanels.css
$(GUIDIR)
/SpryTabbedPanels.js
$(GUIDIR)
/xml_simple.php
$(GUIDIR)
/SpryCollapsiblePanel.css
\
$(GUIDIR)
/SpryTabbedPanels.css
$(GUIDIR)
/SpryTabbedPanels.js
$(GUIDIR)
/xml_simple.php
$(GUIDIR)
/SpryCollapsiblePanel.css
\
$(GUIDIR)
/SpryCollapsiblePanel.js
$(GUIDIR)
/SpryCollapsiblePanel.js
...
@@ -11,6 +12,7 @@ IMAGES = $(GUIDIR)/images/filebrowser-01.gif $(GUIDIR)/images/filebrowser-bo
...
@@ -11,6 +12,7 @@ IMAGES = $(GUIDIR)/images/filebrowser-01.gif $(GUIDIR)/images/filebrowser-bo
SRCS
=
camogm.c camogm_ogm.c camogm_jpeg.c camogm_mov.c camogm_kml.c camogm_read.c index_list.c
SRCS
=
camogm.c camogm_ogm.c camogm_jpeg.c camogm_mov.c camogm_kml.c camogm_read.c index_list.c
TEST_SRC
=
camogm_test.c
OBJS
=
$
(
SRCS:.c
=
.o
)
OBJS
=
$
(
SRCS:.c
=
.o
)
CFLAGS
+=
-Wall
-I
$(STAGING_DIR_HOST)
/usr/include-uapi
CFLAGS
+=
-Wall
-I
$(STAGING_DIR_HOST)
/usr/include-uapi
...
@@ -26,14 +28,17 @@ BINDIR = /usr/bin/
...
@@ -26,14 +28,17 @@ BINDIR = /usr/bin/
WWW_PAGES
=
/www/pages
WWW_PAGES
=
/www/pages
IMAGEDIR
=
$(WWW_PAGES)
/images
IMAGEDIR
=
$(WWW_PAGES)
/images
all
:
$(PROGS)
all
:
$(PROGS)
$(TEST_PROG)
$(PROGS)
:
$(OBJS)
$(PROGS)
:
$(OBJS)
$(CC)
$(LDFLAGS)
$^
$(LDLIBS)
-o
$@
$(CC)
$(LDFLAGS)
$^
$(LDLIBS)
-o
$@
$(TEST_PROG)
:
$(TEST_SRC:.c=.o)
install
:
$(PROGS) $(PHPSCRIPTS) $(CONFIGS)
install
:
$(PROGS) $(PHPSCRIPTS) $(CONFIGS)
$(INSTALL)
$(OWN)
-d
$(DESTDIR)$(BINDIR)
$(INSTALL)
$(OWN)
-d
$(DESTDIR)$(BINDIR)
$(INSTALL)
$(OWN)
-m
$(INSTMODE)
$(PROGS)
$(DESTDIR)$(BINDIR)
$(INSTALL)
$(OWN)
-m
$(INSTMODE)
$(PROGS)
$(DESTDIR)$(BINDIR)
$(INSTALL)
$(OWN)
-m
$(INSTMODE)
$(TEST_PROG)
$(DESTDIR)$(BINDIR)
$(INSTALL)
$(OWN)
-d
$(DESTDIR)$(SYSCONFDIR)
$(INSTALL)
$(OWN)
-d
$(DESTDIR)$(SYSCONFDIR)
$(INSTALL)
$(OWN)
-m
$(INSTDOCS)
$(CONFIGS)
$(DESTDIR)$(SYSCONFDIR)
$(INSTALL)
$(OWN)
-m
$(INSTDOCS)
$(CONFIGS)
$(DESTDIR)$(SYSCONFDIR)
$(INSTALL)
$(OWN)
-d
$(DESTDIR)$(WWW_PAGES)
$(INSTALL)
$(OWN)
-d
$(DESTDIR)$(WWW_PAGES)
...
@@ -47,7 +52,7 @@ clean:
...
@@ -47,7 +52,7 @@ clean:
depend
:
.depend
depend
:
.depend
.depend
:
$(SRCS)
.depend
:
$(SRCS)
$(TEST_SRCS)
rm
-f
./.depend
rm
-f
./.depend
$(CC)
$(CFLAGS)
-MM
$^
>
./.depend
;
$(CC)
$(CFLAGS)
-MM
$^
>
./.depend
;
...
...
src/camogm_test.c
0 → 100644
View file @
03fde964
/** @brief This define is needed to use lseek64 and should be set before includes */
#define _LARGEFILE64_SOURCE
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <linux/fs.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <sys/uio.h>
#include <sys/stat.h>
#include <string.h>
#include <getopt.h>
#include <ctype.h>
#include <elphel/ahci_cmd.h>
#include "camogm.h"
#include "camogm_read.h"
#define DEFAULT_DEBUG_LVL 6
#define DEFAULT_EXIF 0
#define COMMAND_LOOP_DELAY 500000
#define MMAP_BUFF_SIZE 0x4000000
#define SENSOR_PORTS 4
#define SMALL_BUFF_LEN 32
/** State file record format. It includes device path in /dev, starting, current and ending LBAs */
#define STATE_FILE_FORMAT "%s\t%llu\t%llu\t%llu\n"
// redefine debug macros define in camogm.h
#undef D
#undef D0
#undef D1
#undef D2
#undef D3
#undef D4
#undef D5
#undef D6
#define D(x) { if (debug_file && debug_level) { x; fflush(debug_file); } }
#define D0(x) { if (debug_file) { x; fflush(debug_file); } }
#define D1(x) { if (debug_file && (debug_level > 0)) { x; fflush(debug_file); } }
#define D2(x) { if (debug_file && (debug_level > 1)) { x; fflush(debug_file); } }
#define D3(x) { if (debug_file && (debug_level > 2)) { x; fflush(debug_file); } }
#define D4(x) { if (debug_file && (debug_level > 3)) { x; fflush(debug_file); } }
#define D5(x) { if (debug_file && (debug_level > 4)) { x; fflush(debug_file); } }
#define D6(x) { if (debug_file && (debug_level > 5)) { x; fflush(debug_file); } }
struct
dd_params
{
uint64_t
pos_start
;
unsigned
long
int
block_size
;
unsigned
long
int
block_count
;
};
enum
sysfs_path_type
{
TYPE_START
,
TYPE_SIZE
};
const
int
port
=
0
;
// use this to simplify code copying from camogm.c
const
char
*
circbufFileNames
[]
=
{
DEV393_PATH
(
DEV393_CIRCBUF0
),
DEV393_PATH
(
DEV393_CIRCBUF1
),
DEV393_PATH
(
DEV393_CIRCBUF2
),
DEV393_PATH
(
DEV393_CIRCBUF3
)
};
unsigned
long
*
ccam_dma_buf
[
SENSOR_PORTS
];
int
debug_level
;
FILE
*
debug_file
;
int
open_files
(
camogm_state
*
state
);
void
clean_up
(
camogm_state
*
state
);
inline
int
is_fd_valid
(
int
fd
);
void
camogm_init
(
camogm_state
*
state
,
char
*
pipe_name
,
uint16_t
port_num
);
int
listener_loop
(
camogm_state
*
state
,
struct
dd_params
*
dd_params
);
unsigned
int
select_port
(
camogm_state
*
state
);
void
camogm_reset
(
camogm_state
*
state
);
int
camogm_debug_level
(
int
d
);
int
sendImageFrame
(
camogm_state
*
state
);
void
camogm_set_prefix
(
camogm_state
*
state
,
const
char
*
p
);
int
start_recording
(
camogm_state
*
state
);
int
end_recording
(
camogm_state
*
state
);
void
prep_data
(
camogm_state
*
state
,
struct
dd_params
*
dd_params
);
static
uint64_t
get_disk_size
(
const
char
*
name
);
static
int
get_disk_range
(
const
char
*
name
,
struct
range
*
rng
);
static
int
set_disk_range
(
const
struct
range
*
rng
);
static
int
get_sysfs_name
(
const
char
*
dev_name
,
char
*
sys_name
,
size_t
str_sz
,
int
type
);
static
int
find_state
(
FILE
*
f
,
uint64_t
*
pos
,
const
rawdev_buffer
*
rawdev
);
static
int
open_state_file
(
const
rawdev_buffer
*
rawdev
);
static
int
save_state_file
(
const
rawdev_buffer
*
rawdev
);
static
int
get_disk_range_from_driver
(
struct
range
*
range
);
void
camogm_init
(
camogm_state
*
state
,
char
*
pipe_name
,
uint16_t
port_num
)
{
const
char
sserial
[]
=
"elp0"
;
int
*
ipser
=
(
int
*
)
sserial
;
memset
(
state
,
0
,
sizeof
(
camogm_state
));
camogm_reset
(
state
);
// sets state->buf_overruns =- 1
state
->
serialno
=
ipser
[
0
];
debug_file
=
stderr
;
camogm_debug_level
(
DEFAULT_DEBUG_LVL
);
strcpy
(
state
->
debug_name
,
"stderr"
);
state
->
exif
=
DEFAULT_EXIF
;
state
->
frame_lengths
=
NULL
;
state
->
pipe_name
=
pipe_name
;
state
->
rawdev
.
start_pos
=
RAWDEV_START_OFFSET
;
state
->
rawdev
.
end_pos
=
state
->
rawdev
.
start_pos
;
state
->
rawdev
.
curr_pos_w
=
state
->
rawdev
.
start_pos
;
state
->
rawdev
.
curr_pos_r
=
state
->
rawdev
.
start_pos
;
// set first channel active (port 0 defined as constant)
state
->
active_chn
=
0x1
;
state
->
sock_port
=
port_num
;
}
void
camogm_reset
(
camogm_state
*
state
)
{
for
(
int
chn
=
0
;
chn
<
SENSOR_PORTS
;
chn
++
)
{
state
->
cirbuf_rp
[
chn
]
=
-
1
;
state
->
buf_overruns
[
chn
]
=
-
1
;
// first overrun will not count
}
}
int
camogm_debug_level
(
int
d
)
{
debug_level
=
d
;
return
0
;
}
void
clean_up
(
camogm_state
*
state
)
{
if
(
is_fd_valid
(
state
->
fd_circ
[
port
]))
{
munmap
(
ccam_dma_buf
[
port
],
state
->
circ_buff_size
[
port
]);
close
(
state
->
fd_circ
[
port
]);
}
}
inline
int
is_fd_valid
(
int
fd
)
{
return
fcntl
(
fd
,
F_GETFD
)
!=
-
1
||
errno
!=
EBADF
;
}
int
open_files
(
camogm_state
*
state
)
{
int
ret
=
0
;
// open circbuf and mmap it (once at startup)
state
->
fd_circ
[
port
]
=
open
(
circbufFileNames
[
port
],
O_RDWR
);
if
(
state
->
fd_circ
<
0
)
{
// check control OK
D0
(
fprintf
(
debug_file
,
"Error opening %s
\n
"
,
circbufFileNames
[
port
]));
clean_up
(
state
);
return
-
2
;
}
state
->
circ_buff_size
[
port
]
=
MMAP_BUFF_SIZE
;
ccam_dma_buf
[
port
]
=
(
unsigned
long
*
)
mmap
(
0
,
state
->
circ_buff_size
[
port
],
PROT_READ
|
PROT_WRITE
,
MAP_SHARED
,
state
->
fd_circ
[
port
],
0
);
if
((
int
)
ccam_dma_buf
[
port
]
==
-
1
)
{
D0
(
fprintf
(
debug_file
,
"Error in mmap of %s
\n
"
,
circbufFileNames
[
port
]));
clean_up
(
state
);
return
-
3
;
}
else
{
D0
(
fprintf
(
debug_file
,
"successfully mmap cirbuf region
\n
"
));
}
return
ret
;
}
int
sendImageFrame
(
camogm_state
*
state
)
{
struct
frame_data
fdata
=
{
0
};
if
(
state
->
rawdev_op
)
{
fdata
.
sensor_port
=
port
;
fdata
.
cirbuf_ptr
=
state
->
cirbuf_rp
[
port
];
fdata
.
jpeg_len
=
state
->
jpeg_len
;
if
(
state
->
exif
)
{
fdata
.
meta_index
=
state
->
this_frame_params
[
port
].
meta_index
;
fdata
.
cmd
|=
DRV_CMD_EXIF
;
}
fdata
.
cmd
|=
DRV_CMD_WRITE_TEST
;
if
(
write
(
state
->
rawdev
.
sysfs_fd
,
&
fdata
,
sizeof
(
struct
frame_data
))
<
0
)
{
D0
(
fprintf
(
debug_file
,
"Can not pass IO vector to driver: %s
\n
"
,
strerror
(
errno
)));
return
-
CAMOGM_FRAME_FILE_ERR
;
}
}
return
0
;
}
void
camogm_set_prefix
(
camogm_state
*
state
,
const
char
*
p
)
{
struct
range
rng
=
{
0
};
strncpy
(
state
->
rawdev
.
rawdev_path
,
p
,
sizeof
(
state
->
rawdev
.
rawdev_path
)
-
1
);
state
->
rawdev
.
rawdev_path
[
sizeof
(
state
->
rawdev
.
rawdev_path
)
-
1
]
=
'\0'
;
state
->
rawdev
.
end_pos
=
get_disk_size
(
state
->
rawdev
.
rawdev_path
);
if
(
state
->
rawdev
.
end_pos
==
0
)
{
state
->
rawdev_op
=
0
;
state
->
rawdev
.
end_pos
=
state
->
rawdev
.
start_pos
;
state
->
rawdev
.
rawdev_path
[
0
]
=
'\0'
;
D0
(
fprintf
(
debug_file
,
"ERROR: unable to initiate raw device operation
\n
"
));
}
else
{
D0
(
fprintf
(
debug_file
,
"WARNING: raw device write initiated
\n
"
));
state
->
rawdev_op
=
1
;
}
if
(
get_disk_range
(
state
->
rawdev
.
rawdev_path
,
&
rng
)
==
0
)
{
set_disk_range
(
&
rng
);
}
else
{
D0
(
fprintf
(
debug_file
,
"ERROR: unable to get disk size and starting sector
\n
"
));
}
}
static
int
get_sysfs_name
(
const
char
*
dev_name
,
char
*
sys_name
,
size_t
str_sz
,
int
type
)
{
int
ret
=
-
1
;
const
char
prefix
[]
=
"/sys/block/"
;
char
size_name
[]
=
"size"
;
char
start_name
[]
=
"start"
;
char
device_name
[
ELPHEL_PATH_MAX
]
=
{
0
};
char
disk_name
[
ELPHEL_PATH_MAX
]
=
{
0
};
char
part_name
[
ELPHEL_PATH_MAX
]
=
{
0
};
char
*
postfix
=
NULL
;
char
*
ptr
=
NULL
;
size_t
dname_sz
=
strlen
(
dev_name
)
-
1
;
strncpy
(
device_name
,
dev_name
,
ELPHEL_PATH_MAX
);
// strip trailing slash
if
(
device_name
[
dname_sz
]
==
'/'
)
{
device_name
[
dname_sz
]
=
'\0'
;
dname_sz
--
;
}
// get partition and disk names
ptr
=
strrchr
(
device_name
,
'/'
);
if
(
ptr
==
NULL
)
{
D0
(
fprintf
(
debug_file
,
"%s: the path specified is invalid
\n
"
,
__func__
));
return
ret
;
}
strcpy
(
part_name
,
ptr
+
1
);
strcpy
(
disk_name
,
ptr
+
1
);
if
(
strlen
(
disk_name
)
>
0
)
disk_name
[
strlen
(
disk_name
)
-
1
]
=
'\0'
;
if
(
type
==
TYPE_SIZE
)
postfix
=
size_name
;
else
if
(
type
==
TYPE_START
)
postfix
=
start_name
;
if
(
isdigit
(
device_name
[
dname_sz
]))
{
// we've got partition
ret
=
snprintf
(
sys_name
,
str_sz
,
"%s%s/%s/%s"
,
prefix
,
disk_name
,
part_name
,
postfix
);
}
else
{
// we've got entire disk
ret
=
snprintf
(
sys_name
,
str_sz
,
"%s%s/%s"
,
prefix
,
part_name
,
postfix
);
if
(
type
==
TYPE_START
)
// the 'start' does not exist for full disk, notify caller
// that we've got this situation here
sys_name
[
0
]
=
'\0'
;
}
return
ret
;
}
static
int
get_disk_range
(
const
char
*
name
,
struct
range
*
rng
)
{
int
ret
=
0
;
int
fd
;
uint64_t
val
;
char
data
[
SMALL_BUFF_LEN
]
=
{
0
};
char
sysfs_name
[
ELPHEL_PATH_MAX
]
=
{
0
};
// read start LBA
if
(
get_sysfs_name
(
name
,
sysfs_name
,
ELPHEL_PATH_MAX
,
TYPE_START
)
>
0
)
{
if
(
strlen
(
sysfs_name
)
>
0
)
{
fd
=
open
(
sysfs_name
,
O_RDONLY
);
if
(
fd
>=
0
)
{
read
(
fd
,
data
,
SMALL_BUFF_LEN
);
if
((
val
=
strtoull
(
data
,
NULL
,
10
))
!=
0
)
rng
->
from
=
val
;
else
ret
=
-
1
;
close
(
fd
);
}
}
else
{
rng
->
from
=
0
;
}
}
// read disk size in LBA
if
(
get_sysfs_name
(
name
,
sysfs_name
,
ELPHEL_PATH_MAX
,
TYPE_SIZE
)
>
0
)
{
fd
=
open
(
sysfs_name
,
O_RDONLY
);
if
(
fd
>=
0
)
{
read
(
fd
,
data
,
SMALL_BUFF_LEN
);
if
((
val
=
strtoull
(
data
,
NULL
,
10
))
!=
0
)
rng
->
to
=
rng
->
from
+
val
;
else
ret
=
-
1
;
close
(
fd
);
}
}
// sanity check
if
(
rng
->
from
>=
rng
->
to
)
ret
=
-
1
;
return
ret
;
}
static
int
set_disk_range
(
const
struct
range
*
rng
)
{
int
fd
;
int
ret
=
0
;
char
buff
[
SMALL_BUFF_LEN
]
=
{
0
};
int
len
;
fd
=
open
(
SYSFS_AHCI_LBA_START
,
O_WRONLY
);
if
(
fd
<
0
)
return
-
1
;
len
=
snprintf
(
buff
,
SMALL_BUFF_LEN
,
"%llu"
,
rng
->
from
);
write
(
fd
,
buff
,
len
+
1
);
close
(
fd
);
fd
=
open
(
SYSFS_AHCI_LBA_END
,
O_WRONLY
);
if
(
fd
<
0
)
return
-
1
;
len
=
snprintf
(
buff
,
SMALL_BUFF_LEN
,
"%llu"
,
rng
->
to
);
write
(
fd
,
buff
,
len
+
1
);
close
(
fd
);
return
ret
;
}
static
uint64_t
get_disk_size
(
const
char
*
name
)
{
int
fd
;
uint64_t
dev_sz
;
if
((
fd
=
open
(
name
,
O_RDONLY
))
<
0
)
{
perror
(
__func__
);
return
0
;
}
if
(
ioctl
(
fd
,
BLKGETSIZE64
,
&
dev_sz
)
<
0
)
{
perror
(
__func__
);
return
0
;
}
close
(
fd
);
return
dev_sz
;
}
/** Get starting and endign LBAs of the partition specified as raw device buffer */
static
int
get_disk_range_from_driver
(
struct
range
*
range
)
{
FILE
*
f
;
// get raw device buffer starting postion on disk
f
=
fopen
(
SYSFS_AHCI_LBA_START
,
"r"
);
if
(
f
==
NULL
)
{
return
-
1
;
}
fscanf
(
f
,
"%llu
\n
"
,
&
range
->
from
);
fclose
(
f
);
// get raw device buffer ending postion on disk
f
=
fopen
(
SYSFS_AHCI_LBA_END
,
"r"
);
if
(
f
==
NULL
)
{
return
-
1
;
}
fscanf
(
f
,
"%llu
\n
"
,
&
range
->
to
);
fclose
(
f
);
return
0
;
}
/** Get write pointer from a file. This functions check not only the name of a partition, but
* its geometry as well */
static
int
find_state
(
FILE
*
f
,
uint64_t
*
pos
,
const
rawdev_buffer
*
rawdev
)
{
size_t
len
;
uint64_t
start_pos
,
curr_pos
,
end_pos
;
struct
range
range
;
char
buff
[
ELPHEL_PATH_MAX
];
char
dev_name
[
ELPHEL_PATH_MAX
];
if
(
f
==
NULL
||
pos
==
NULL
)
return
-
1
;
if
(
get_disk_range_from_driver
(
&
range
)
!=
0
)
{
return
-
1
;
}
// skip first line containing file header
fgets
(
buff
,
ELPHEL_PATH_MAX
,
f
);
while
(
fgets
(
buff
,
ELPHEL_PATH_MAX
,
f
)
!=
NULL
)
{
sscanf
(
buff
,
STATE_FILE_FORMAT
,
dev_name
,
&
start_pos
,
&
curr_pos
,
&
end_pos
);
len
=
strlen
(
dev_name
);
if
(
strncmp
(
rawdev
->
rawdev_path
,
dev_name
,
len
)
==
0
&&
range
.
from
==
start_pos
&&
range
.
to
==
end_pos
)
{
*
pos
=
curr_pos
;
break
;
}
}
return
0
;
}
/** Read state from file and restore disk write pointer */
static
int
open_state_file
(
const
rawdev_buffer
*
rawdev
)
{
int
fd
,
len
;
FILE
*
f
;
int
ret
=
0
;
uint64_t
curr_pos
;
char
buff
[
SMALL_BUFF_LEN
]
=
{
0
};
if
(
strlen
(
rawdev
->
state_path
)
==
0
)
{
return
ret
;
}
f
=
fopen
(
rawdev
->
state_path
,
"r"
);
if
(
f
!=
NULL
)
{
if
(
find_state
(
f
,
&
curr_pos
,
rawdev
)
!=
-
1
)
{
fd
=
open
(
SYSFS_AHCI_LBA_CURRENT
,
O_WRONLY
);
if
(
fd
>=
0
)
{
len
=
snprintf
(
buff
,
SMALL_BUFF_LEN
,
"%llu"
,
curr_pos
);
write
(
fd
,
buff
,
len
+
1
);
close
(
fd
);
}
else
{
ret
=
-
1
;
}
}
fclose
(
f
);
}
else
{
ret
=
-
1
;
}
return
ret
;
}
/** Save current position of the disk write pointer */
static
int
save_state_file
(
const
rawdev_buffer
*
rawdev
)
{
int
ret
=
0
;
FILE
*
f
;
struct
range
range
;
uint64_t
curr_pos
;
if
(
strlen
(
rawdev
->
state_path
)
==
0
)
{
return
ret
;
}
if
(
get_disk_range_from_driver
(
&
range
)
!=
0
)
{
return
-
1
;
}
// get raw device buffer current postion on disk, this position indicates where recording has stopped
f
=
fopen
(
SYSFS_AHCI_LBA_CURRENT
,
"r"
);
if
(
f
==
NULL
)
{
return
-
1
;
}
fscanf
(
f
,
"%llu
\n
"
,
&
curr_pos
);
fclose
(
f
);
// save pointers to a regular file
f
=
fopen
(
rawdev
->
state_path
,
"w"
);
if
(
f
==
NULL
)
{
return
-
1
;
}
fprintf
(
f
,
"Device
\t\t
Start LBA
\t
Current LBA
\t
End LBA
\n
"
);
fprintf
(
f
,
STATE_FILE_FORMAT
,
rawdev
->
rawdev_path
,
range
.
from
,
curr_pos
,
range
.
to
);
fflush
(
f
);
fsync
(
fileno
(
f
));
fclose
(
f
);
return
ret
;
}
unsigned
int
select_port
(
camogm_state
*
state
)
{
// do not process commands
return
port
;
}
int
parse_cmd
(
camogm_state
*
state
,
FILE
*
npipe
)
{
return
0
;
}
int
start_recording
(
camogm_state
*
state
)
{
if
(
state
->
rawdev_op
)
{
if
(
open_state_file
(
&
state
->
rawdev
)
!=
0
)
{
D0
(
fprintf
(
debug_file
,
"Could not set write pointer via sysfs, recording will start from the beginning of partition: "
"%s
\n
"
,
state
->
rawdev
.
rawdev_path
));
}
state
->
rawdev
.
sysfs_fd
=
open
(
SYSFS_AHCI_WRITE
,
O_WRONLY
);
D6
(
fprintf
(
debug_file
,
"Open sysfs file: %s
\n
"
,
SYSFS_AHCI_WRITE
));
if
(
state
->
rawdev
.
sysfs_fd
<
0
)
{
D0
(
fprintf
(
debug_file
,
"Error opening sysfs file: %s
\n
"
,
SYSFS_AHCI_WRITE
));
return
-
CAMOGM_FRAME_FILE_ERR
;
}
}
return
0
;
}
int
end_recording
(
camogm_state
*
state
)
{
int
ret
=
0
;
struct
frame_data
fdata
=
{
0
};
if
(
state
->
rawdev_op
)
{
fdata
.
cmd
=
DRV_CMD_FINISH
;
if
(
write
(
state
->
rawdev
.
sysfs_fd
,
&
fdata
,
sizeof
(
struct
frame_data
))
<
0
)
{
D0
(
fprintf
(
debug_file
,
"Error sending 'finish' command to driver
\n
"
));
}
D6
(
fprintf
(
debug_file
,
"Closing sysfs file %s
\n
"
,
SYSFS_AHCI_WRITE
));
ret
=
close
(
state
->
rawdev
.
sysfs_fd
);
if
(
ret
==
-
1
)
D0
(
fprintf
(
debug_file
,
"Error: %s
\n
"
,
strerror
(
errno
)));
save_state_file
(
&
state
->
rawdev
);
}
return
ret
;
}
int
listener_loop
(
camogm_state
*
state
,
struct
dd_params
*
dd_params
)
{
FILE
*
cmd_file
;
int
rslt
,
cmd
;
int
process
=
1
;
int
curr_port
=
0
;
int
retry_cntr
=
0
;
int
ret
=
0
;
// enter main processing loop
while
(
process
)
{
curr_port
=
select_port
(
state
);
state
->
port_num
=
curr_port
;
// look at command queue first
cmd
=
parse_cmd
(
state
,
cmd_file
);
if
(
cmd
)
{
if
(
cmd
<
0
)
D0
(
fprintf
(
debug_file
,
"Unrecognized command
\n
"
));
}
else
if
(
state
->
prog_state
==
STATE_RUNNING
)
{
// no commands in queue, started
if
(
dd_params
->
block_count
!=
0
)
{
switch
((
rslt
=
-
sendImageFrame
(
state
)))
{
case
0
:
// file sent OK
dd_params
->
block_count
--
;
break
;
case
CAMOGM_FRAME_FILE_ERR
:
// we need to wait as the driver queue is full
usleep
(
COMMAND_LOOP_DELAY
);
break
;
default:
D0
(
fprintf
(
debug_file
,
"%s:line %d - should not get here (rslt=%d)
\n
"
,
__FILE__
,
__LINE__
,
rslt
));
clean_up
(
state
);
exit
(
-
1
);
}
// switch sendImageFrame()
D0
(
fprintf
(
debug_file
,
"Number of counts left: %lu
\n
"
,
dd_params
->
block_count
));
}
else
{
process
=
0
;
}
}
else
{
usleep
(
COMMAND_LOOP_DELAY
);
// make it longer but interruptible by signals?
}
}
// while (process)
return
ret
;
}
/** Write counter to cirbuf memory area */
void
prep_data
(
camogm_state
*
state
,
struct
dd_params
*
dd_params
)
{
state
->
cirbuf_rp
[
port
]
=
0
;
state
->
jpeg_len
=
dd_params
->
block_size
;
for
(
int
i
=
0
,
j
=
0
;
i
<
dd_params
->
block_size
;
i
++
)
{
ccam_dma_buf
[
port
][
i
]
=
j
;
j
++
;
}
}
int
main
(
int
argc
,
char
*
argv
[])
{
const
char
usage
[]
=
"This program is intended for disk write tests
\n
"
\
"Usage:
\n\n
"
\
"%s -d <path_to_disk> [-s state_file_name -b block_size -c count]
\n\n
"
\
"i.e. write one sector:
\n\n
"
\
"%s -d /dev/sda2 -b 512 -c 1
\n\n
"
;
int
ret
;
int
opt
;
uint16_t
port_num
=
0
;
size_t
str_len
;
camogm_state
sstate
;
char
pipe_name_str
[
ELPHEL_PATH_MAX
]
=
{
0
};
char
state_name_str
[
ELPHEL_PATH_MAX
]
=
{
0
};
char
disk_path
[
ELPHEL_PATH_MAX
]
=
{
0
};
struct
dd_params
dd_params
=
{
0
};
if
((
argc
<
2
)
||
(
argv
[
1
][
1
]
==
'-'
))
{
printf
(
usage
,
argv
[
0
],
argv
[
0
]);
return
EXIT_SUCCESS
;
}
while
((
opt
=
getopt
(
argc
,
argv
,
"b:c:d:n:p:s:h"
))
!=
-
1
)
{
switch
(
opt
)
{
case
'd'
:
strncpy
(
disk_path
,
(
const
char
*
)
optarg
,
ELPHEL_PATH_MAX
-
1
);
break
;
case
'n'
:
strncpy
(
pipe_name_str
,
(
const
char
*
)
optarg
,
ELPHEL_PATH_MAX
-
1
);
break
;
case
'p'
:
port_num
=
(
uint16_t
)
atoi
((
const
char
*
)
optarg
);
break
;
case
'h'
:
printf
(
usage
,
argv
[
0
],
argv
[
0
]);
return
EXIT_SUCCESS
;
case
's'
:
strncpy
(
state_name_str
,
(
const
char
*
)
optarg
,
ELPHEL_PATH_MAX
-
1
);
break
;
case
'b'
:
dd_params
.
block_size
=
strtoul
((
const
char
*
)
optarg
,
(
char
**
)
NULL
,
10
);
if
(
errno
!=
0
)
{
printf
(
"error parsing block size value: %s
\n
"
,
strerror
(
errno
));
return
EXIT_FAILURE
;
}
printf
(
"block size is set to %lu
\n
"
,
dd_params
.
block_size
);
break
;
case
'c'
:
dd_params
.
block_count
=
strtoul
((
const
char
*
)
optarg
,
(
char
**
)
NULL
,
10
);
if
(
errno
!=
0
)
{
printf
(
"error parsing block size value: %s
\n
"
,
strerror
(
errno
));
return
EXIT_FAILURE
;
}
printf
(
"block count is set to %lu
\n
"
,
dd_params
.
block_count
);
break
;
}
}
camogm_init
(
&
sstate
,
pipe_name_str
,
port_num
);
ret
=
open_files
(
&
sstate
);
if
(
ret
<
0
)
return
ret
;
str_len
=
strlen
(
state_name_str
);
if
(
str_len
>
0
)
{
strncpy
(
sstate
.
rawdev
.
state_path
,
state_name_str
,
str_len
+
1
);
}
camogm_set_prefix
(
&
sstate
,
disk_path
);
if
(
sstate
.
rawdev_op
==
1
)
{
prep_data
(
&
sstate
,
&
dd_params
);
ret
=
start_recording
(
&
sstate
);
if
(
ret
==
0
)
{
sstate
.
prog_state
=
STATE_RUNNING
;
ret
=
listener_loop
(
&
sstate
,
&
dd_params
);
end_recording
(
&
sstate
);
}
}
else
{
D0
(
fprintf
(
debug_file
,
"Unable to set %s as a disk path
\n
"
,
disk_path
));
clean_up
(
&
sstate
);
ret
=
EXIT_FAILURE
;
}
clean_up
(
&
sstate
);
return
ret
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment