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
b4d4414a
Commit
b4d4414a
authored
May 24, 2023
by
Andrey Filippov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Intermediate step - with 4K sectors, better threads handling
parent
6be06d67
Changes
5
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
497 additions
and
242 deletions
+497
-242
camogm.c
src/camogm.c
+38
-9
camogm.h
src/camogm.h
+16
-6
camogm_align.c
src/camogm_align.c
+280
-185
camogm_align.h
src/camogm_align.h
+7
-6
camogm_jpeg.c
src/camogm_jpeg.c
+156
-36
No files found.
src/camogm.c
View file @
b4d4414a
...
@@ -163,6 +163,7 @@ static int get_disk_range(const char *name, struct range *rng);
...
@@ -163,6 +163,7 @@ static int get_disk_range(const char *name, struct range *rng);
static
int
set_disk_range
(
const
struct
range
*
rng
);
static
int
set_disk_range
(
const
struct
range
*
rng
);
static
void
get_disk_info
(
camogm_state
*
state
);
static
void
get_disk_info
(
camogm_state
*
state
);
static
struct
timeval
get_fpga_time
(
const
int
fd_fparsall
,
unsigned
int
port
);
static
struct
timeval
get_fpga_time
(
const
int
fd_fparsall
,
unsigned
int
port
);
int
open_files
(
camogm_state
*
state
);
int
open_files
(
camogm_state
*
state
);
unsigned
long
getGPValue
(
unsigned
int
port
,
unsigned
long
GPNumber
);
unsigned
long
getGPValue
(
unsigned
int
port
,
unsigned
long
GPNumber
);
void
setGValue
(
unsigned
int
port
,
unsigned
long
GNumber
,
unsigned
long
value
);
void
setGValue
(
unsigned
int
port
,
unsigned
long
GNumber
,
unsigned
long
value
);
...
@@ -280,7 +281,12 @@ void camogm_init(camogm_state *state, char *pipe_name, uint16_t port_num)
...
@@ -280,7 +281,12 @@ void camogm_init(camogm_state *state, char *pipe_name, uint16_t port_num)
state
->
rawdev
.
mmap_default_size
=
MMAP_CHUNK_SIZE
;
state
->
rawdev
.
mmap_default_size
=
MMAP_CHUNK_SIZE
;
state
->
sock_port
=
port_num
;
state
->
sock_port
=
port_num
;
state
->
writer_params
.
data_ready
=
false
;
// state->writer_params.data_ready = false;
state
->
writer_params
.
chunk_page_prep
=
0
;
// will prepare page 0
state
->
writer_params
.
chunk_page_write
=
0
;
// will write page 0
state
->
writer_params
.
exit_thread
=
false
;
state
->
writer_params
.
exit_thread
=
false
;
state
->
writer_params
.
state
=
STATE_STOPPED
;
state
->
writer_params
.
state
=
STATE_STOPPED
;
...
@@ -692,7 +698,7 @@ int sendImageFrame(camogm_state *state)
...
@@ -692,7 +698,7 @@ int sendImageFrame(camogm_state *state)
state
->
writer_params
.
segments
=
1
;
state
->
writer_params
.
segments
=
1
;
}
}
D3
(
fprintf
(
debug_file
,
"
\t
cirbuf_rp[%d] = 0x%x
\t
"
,
port
,
state
->
cirbuf_rp
[
port
]));
D3
(
fprintf
(
debug_file
,
"
\t
cirbuf_rp[%d] = 0x%x
\t
"
,
port
,
state
->
cirbuf_rp
[
port
]));
D3
(
fprintf
(
debug_file
,
"_12_"
));
D3
(
fprintf
(
debug_file
,
"_12_
\n
"
));
if
(
state
->
this_frame_params
[
port
].
color
!=
COLORMODE_RAW
)
{
// Tiff
if
(
state
->
this_frame_params
[
port
].
color
!=
COLORMODE_RAW
)
{
// Tiff
state
->
packetchunks
[
state
->
chunk_index
].
bytes
=
2
;
state
->
packetchunks
[
state
->
chunk_index
].
bytes
=
2
;
state
->
packetchunks
[
state
->
chunk_index
++
].
chunk
=
(
unsigned
char
*
)
trailer
;
state
->
packetchunks
[
state
->
chunk_index
++
].
chunk
=
(
unsigned
char
*
)
trailer
;
...
@@ -701,6 +707,7 @@ int sendImageFrame(camogm_state *state)
...
@@ -701,6 +707,7 @@ int sendImageFrame(camogm_state *state)
dbg_show_packetchunks
(
state
);
dbg_show_packetchunks
(
state
);
D6
(
fprintf
(
debug_file
,
"_12.5_ before CAMOGM_FORMAT_XXX @ %06d
\n
"
,
get_fpga_usec
(
state
->
fd_fparmsall
[
0
],
0
)));
switch
(
state
->
format
)
{
switch
(
state
->
format
)
{
case
CAMOGM_FORMAT_NONE
:
rslt
=
0
;
break
;
case
CAMOGM_FORMAT_NONE
:
rslt
=
0
;
break
;
...
@@ -741,14 +748,14 @@ int sendImageFrame(camogm_state *state)
...
@@ -741,14 +748,14 @@ int sendImageFrame(camogm_state *state)
// end_time.tv_sec, end_time.tv_usec,
// end_time.tv_sec, end_time.tv_usec,
// state->rawdev.last_jpeg_size));
// state->rawdev.last_jpeg_size));
// D6(fprintf(debug_file, "Write speed: %d MB/s\n", mbps));
// D6(fprintf(debug_file, "Write speed: %d MB/s\n", mbps));
D6
(
fprintf
(
debug_file
,
"Exit sendImageFrame() OK @ %06d
\n
"
,
get_fpga_usec
(
state
->
fd_fparmsall
[
0
],
0
)));
return
0
;
return
0
;
}
}
static
void
dbg_show_packetchunks
(
camogm_state
*
state
)
static
void
dbg_show_packetchunks
(
camogm_state
*
state
)
{
{
int
i
;
int
i
;
for
(
i
=
0
;
i
<
FILE_CHUNKS_NUM
;
i
++
)
{
for
(
i
=
0
;
i
<
state
->
chunk_index
;
i
++
)
{
D4
(
fprintf
(
debug_file
,
"packetchunk[%d]: ptr = %p, size = %d
\n
"
,
i
,
state
->
packetchunks
[
i
].
chunk
,
state
->
packetchunks
[
i
].
bytes
));
D4
(
fprintf
(
debug_file
,
"packetchunk[%d]: ptr = %p, size = %d
\n
"
,
i
,
state
->
packetchunks
[
i
].
chunk
,
state
->
packetchunks
[
i
].
bytes
));
}
}
}
}
...
@@ -1386,7 +1393,7 @@ int parse_cmd(camogm_state *state, FILE* npipe)
...
@@ -1386,7 +1393,7 @@ int parse_cmd(camogm_state *state, FILE* npipe)
//skip empty commands
//skip empty commands
while
(((
cmd
=
getLineFromPipe
(
npipe
)))
&&
!
cmd
[
0
])
;
while
(((
cmd
=
getLineFromPipe
(
npipe
)))
&&
!
cmd
[
0
])
;
if
(
!
cmd
)
return
0
;
// nothing in the pipe
if
(
!
cmd
)
return
0
;
// nothing in the pipe
D2
(
fprintf
(
debug_file
,
"Got command: '%s'
\n
"
,
cmd
));
D2
(
fprintf
(
debug_file
,
"Got command: '%s'
@ %06d -> "
,
cmd
,
get_fpga_usec
(
state
->
fd_fparmsall
[
0
],
0
)
));
// Acknowledge received command by copying frame number to per-daemon parameter
// Acknowledge received command by copying frame number to per-daemon parameter
// GLOBALPARS(state->port_num, G_DAEMON_ERR + lastDaemonBit[state->port_num]) = GLOBALPARS(state->port_num, G_THIS_FRAME);
// GLOBALPARS(state->port_num, G_DAEMON_ERR + lastDaemonBit[state->port_num]) = GLOBALPARS(state->port_num, G_THIS_FRAME);
...
@@ -1655,6 +1662,7 @@ int listener_loop(camogm_state *state)
...
@@ -1655,6 +1662,7 @@ int listener_loop(camogm_state *state)
// enter main processing loop
// enter main processing loop
while
(
process
)
{
while
(
process
)
{
D6
(
fprintf
(
debug_file
,
"--------------- Listener loop @ %06d
\n
"
,
get_fpga_usec
(
state
->
fd_fparmsall
[
0
],
0
)));
curr_port
=
select_port
(
state
);
curr_port
=
select_port
(
state
);
state
->
port_num
=
curr_port
;
state
->
port_num
=
curr_port
;
// look at command queue first
// look at command queue first
...
@@ -1668,14 +1676,19 @@ int listener_loop(camogm_state *state)
...
@@ -1668,14 +1676,19 @@ int listener_loop(camogm_state *state)
#endif
#endif
cmd
=
parse_cmd
(
state
,
cmd_file
);
cmd
=
parse_cmd
(
state
,
cmd_file
);
if
(
cmd
)
{
if
(
cmd
)
{
D2
(
fprintf
(
debug_file
,
"DONE command @ %06d
\n
"
,
get_fpga_usec
(
state
->
fd_fparmsall
[
0
],
0
)));
if
(
cmd
<
0
)
D0
(
fprintf
(
debug_file
,
"Unrecognized command
\n
"
));
if
(
cmd
<
0
)
D0
(
fprintf
(
debug_file
,
"Unrecognized command
\n
"
));
#ifdef USE_POLL
#ifdef USE_POLL
}
}
#endif
#endif
}
else
if
(
state
->
prog_state
==
STATE_RUNNING
)
{
// no commands in queue, started
continue
;
// } else if (state->prog_state == STATE_RUNNING) { // no commands in queue, started
}
if
(
state
->
prog_state
==
STATE_RUNNING
)
{
// no commands in queue, started
D6
(
fprintf
(
debug_file
,
"state->prog_state == STATE_RUNNING "
));
D6
(
fprintf
(
debug_file
,
"state->prog_state == STATE_RUNNING "
));
rslt
=
-
sendImageFrame
(
state
);
rslt
=
-
sendImageFrame
(
state
);
D6
(
fprintf
(
debug_file
,
" ==> %d
"
,
rslt
));
D6
(
fprintf
(
debug_file
,
" ==> %d
@ %06d
\n
"
,
rslt
,
get_fpga_usec
(
state
->
fd_fparmsall
[
0
],
0
)
));
switch
(
rslt
)
{
switch
(
rslt
)
{
case
0
:
case
0
:
break
;
// frame sent OK, nothing to do (TODO: check file length/duration)
break
;
// frame sent OK, nothing to do (TODO: check file length/duration)
...
@@ -1692,6 +1705,7 @@ int listener_loop(camogm_state *state)
...
@@ -1692,6 +1705,7 @@ int listener_loop(camogm_state *state)
D0
(
fprintf
(
debug_file
,
"%s:line %d got broken frame (%d) while waiting for ready. Before that fp0=0x%x
\n
"
,
__FILE__
,
__LINE__
,
fp1
,
fp0
));
D0
(
fprintf
(
debug_file
,
"%s:line %d got broken frame (%d) while waiting for ready. Before that fp0=0x%x
\n
"
,
__FILE__
,
__LINE__
,
fp1
,
fp0
));
rslt
=
CAMOGM_FRAME_BROKEN
;
rslt
=
CAMOGM_FRAME_BROKEN
;
}
else
{
}
else
{
D6
(
fprintf
(
debug_file
,
"No compressed frame ready, skipped 1 frame sync for port %d @ %06d
\n
"
,
curr_port
,
get_fpga_usec
(
state
->
fd_fparmsall
[
0
],
0
)));
break
;
break
;
}
}
}
}
...
@@ -1760,10 +1774,14 @@ int listener_loop(camogm_state *state)
...
@@ -1760,10 +1774,14 @@ int listener_loop(camogm_state *state)
// add port number to error code to facilitate debugging
// add port number to error code to facilitate debugging
state
->
last_error_code
=
rslt
+
100
*
state
->
port_num
;
state
->
last_error_code
=
rslt
+
100
*
state
->
port_num
;
}
else
if
(
state
->
prog_state
==
STATE_READING
)
{
}
else
if
(
state
->
prog_state
==
STATE_READING
)
{
D6
(
fprintf
(
debug_file
,
"COMMAND_LOOP_DELAY start for STATE_READING@ %06d
\n
"
,
get_fpga_usec
(
state
->
fd_fparmsall
[
0
],
0
)));
usleep
(
COMMAND_LOOP_DELAY
);
usleep
(
COMMAND_LOOP_DELAY
);
D6
(
fprintf
(
debug_file
,
"COMMAND_LOOP_DELAY end for STATE_READING@ %06d
\n
"
,
get_fpga_usec
(
state
->
fd_fparmsall
[
0
],
0
)));
}
else
{
// not running, not starting
}
else
{
// not running, not starting
state
->
rawdev
.
thread_state
=
STATE_RUNNING
;
state
->
rawdev
.
thread_state
=
STATE_RUNNING
;
D6
(
fprintf
(
debug_file
,
"COMMAND_LOOP_DELAY start for STATE_RUNNING@ %06d
\n
"
,
get_fpga_usec
(
state
->
fd_fparmsall
[
0
],
0
)));
usleep
(
COMMAND_LOOP_DELAY
);
// make it longer but interruptible by signals?
usleep
(
COMMAND_LOOP_DELAY
);
// make it longer but interruptible by signals?
D6
(
fprintf
(
debug_file
,
"COMMAND_LOOP_DELAY end for STATE_RUNNING@ %06d
\n
"
,
get_fpga_usec
(
state
->
fd_fparmsall
[
0
],
0
)));
}
}
#ifdef USE_POLL
#ifdef USE_POLL
// } // if pfd.revents & POLLIN
// } // if pfd.revents & POLLIN
...
@@ -2265,3 +2283,14 @@ struct timeval get_fpga_time(const int fd_fparsall, unsigned int port)
...
@@ -2265,3 +2283,14 @@ struct timeval get_fpga_time(const int fd_fparsall, unsigned int port)
return
tv
;
return
tv
;
}
}
/**
* @brief Get current FPGA microseconds of time to use for timing of the code
* @return FPGA current microseconds
*/
inline
int
get_fpga_usec
(
const
int
fd_fparsall
,
unsigned
int
port
)
{
lseek
(
fd_fparsall
,
LSEEK_GET_FPGA_TIME
,
SEEK_END
);
// return (int) getGPValue(port, G_MICROSECONDS);
return
(
int
)
GLOBALPARS
(
port
,
G_MICROSECONDS
);
}
src/camogm.h
View file @
b4d4414a
...
@@ -67,7 +67,9 @@
...
@@ -67,7 +67,9 @@
#define COMMAND_LOOP_DELAY 500000
#define COMMAND_LOOP_DELAY 500000
/** @brief File can be split up to this number of chunks */
/** @brief File can be split up to this number of chunks */
#define FILE_CHUNKS_NUM 8
#define FILE_CHUNKS_NUM 8
/** @brief Number of chunk pages to overlap preparation with SSD raw write */
#define FILE_CHUNKS_PAGES 2
#define FILE_CHUNKS_TOTAL ((FILE_CHUNKS_NUM) * (FILE_CHUNKS_PAGES))
/**
/**
* @enum state_flags
* @enum state_flags
* @brief Program state flags
* @brief Program state flags
...
@@ -145,25 +147,32 @@ struct writer_params {
...
@@ -145,25 +147,32 @@ struct writer_params {
pthread_mutex_t
writer_mutex
;
///< synchronization mutex for main and writing threads
pthread_mutex_t
writer_mutex
;
///< synchronization mutex for main and writing threads
pthread_cond_t
writer_cond
;
///< conditional variable indicating that writer thread can proceed with new frame
pthread_cond_t
writer_cond
;
///< conditional variable indicating that writer thread can proceed with new frame
pthread_cond_t
main_cond
;
///< conditional variable indicating that main thread can update write pointers
pthread_cond_t
main_cond
;
///< conditional variable indicating that main thread can update write pointers
bool
data_ready
;
///< flag indicating that new frame is ready for recording, access to this flag
// bool data_ready; ///< flag indicating that new frame is ready for recording, access to this flag
///< must be protected with #writer_mutex. Set this flag in main thread and reset in
// ///< must be protected with #writer_mutex. Set this flag in main thread and reset in
///< disk writing thread.
// ///< disk writing thread.
// ///< For overlapping disk raw writes with chunks preparation (should be atomic - use #writer_mutex)
int
chunk_page_prep
;
///< page of chunks being prepared. Incremented (mod) after data is prepared for raw write
int
chunk_page_write
;
///< page of chunks to write. Incremented (mod) after recording to disk
int
last_ret_val
;
///< error value return during last frame recording (if any occurred)
int
last_ret_val
;
///< error value return during last frame recording (if any occurred)
bool
exit_thread
;
///< flag indicating that the writing thread should terminate
bool
exit_thread
;
///< flag indicating that the writing thread should terminate
int
state
;
///< the state of disk writing thread
int
state
;
///< the state of disk writing thread
int
segments
;
///< the number of segments in frame
int
segments
;
///< the number of segments in frame
struct
iovec
*
data_chunks
;
///< a set of vectors pointing to aligned frame data buffers
struct
iovec
*
data_chunks
;
///< a set of vectors pointing to aligned frame data buffers
struct
iovec
was_CHUNK_REM
;
///< extracting to a separate entity data_chunks[CHUNK_REM]
// struct iovec *was_CHUNK_COMMON; ///< extracting to a separate entity data_chunks[CHUNK_COMMON]
struct
iovec
prev_rem_vect
;
///< vector pointing to the remainder of the previous frame
struct
iovec
prev_rem_vect
;
///< vector pointing to the remainder of the previous frame
unsigned
char
*
rem_buff
;
///< buffer containing the unaligned remainder of the current frame
unsigned
char
*
rem_buff
;
///< buffer containing the unaligned remainder of the current frame
unsigned
char
*
prev_rem_buff
;
///< buffer containing the unaligned remainder of the previous frame
unsigned
char
*
prev_rem_buff
;
///< buffer containing the unaligned remainder of the previous frame
unsigned
char
*
common_buff
;
///< buffer for aligned JPEG header
// get rid of common_buff
// unsigned char *common_buff; ///< buffer for aligned JPEG header // make multiple?
unsigned
char
*
common_buffs
[
FILE_CHUNKS_PAGES
];
///< buffer for aligned JPEG header // make multiple?
uint64_t
lba_start
;
///< disk starting LBA
uint64_t
lba_start
;
///< disk starting LBA
uint64_t
lba_current
;
///< current write position in LBAs
uint64_t
lba_current
;
///< current write position in LBAs
uint64_t
lba_end
;
///< disk last LBA
uint64_t
lba_end
;
///< disk last LBA
time_t
stat_update
;
///< time when status file was updated
time_t
stat_update
;
///< time when status file was updated
bool
dummy_read
;
///<
i
nable dummy read cycle (debug feature)
bool
dummy_read
;
///<
e
nable dummy read cycle (debug feature)
};
};
/**
/**
* @struct camogm_state
* @struct camogm_state
...
@@ -272,5 +281,6 @@ void setGValue(unsigned int port, unsigned long GNumber, unsigned long value);
...
@@ -272,5 +281,6 @@ void setGValue(unsigned int port, unsigned long GNumber, unsigned long value);
int
waitDaemonEnabled
(
unsigned
int
port
,
int
daemonBit
);
int
waitDaemonEnabled
(
unsigned
int
port
,
int
daemonBit
);
int
isDaemonEnabled
(
unsigned
int
port
,
int
daemonBit
);
int
isDaemonEnabled
(
unsigned
int
port
,
int
daemonBit
);
int
is_fd_valid
(
int
fd
);
int
is_fd_valid
(
int
fd
);
int
get_fpga_usec
(
const
int
fd_fparsall
,
unsigned
int
port
);
#endif
/* _CAMOGM_H */
#endif
/* _CAMOGM_H */
src/camogm_align.c
View file @
b4d4414a
This diff is collapsed.
Click to expand it.
src/camogm_align.h
View file @
b4d4414a
...
@@ -22,8 +22,9 @@
...
@@ -22,8 +22,9 @@
#include <sys/types.h>
#include <sys/types.h>
#include "camogm.h"
#include "camogm.h"
// TODO: Change PHY_BLOCK_SIZE to 4096 as it is 4096!
#define PHY_BLOCK_SIZE 512 ///< Physical disk block size
//#define PHY_BLOCK_SIZE 512 ///< Physical disk block size
#define PHY_BLOCK_SIZE 4096 ///< Physical disk block size
#define JPEG_MARKER_LEN 2 ///< The size in bytes of JPEG marker
#define JPEG_MARKER_LEN 2 ///< The size in bytes of JPEG marker
#define JPEG_SIZE_LEN 2 ///< The size in bytes of JPEG marker length field
#define JPEG_SIZE_LEN 2 ///< The size in bytes of JPEG marker length field
#define INCLUDE_REM 1 ///< Include REM buffer to total size calculation
#define INCLUDE_REM 1 ///< Include REM buffer to total size calculation
...
@@ -73,10 +74,10 @@ enum {
...
@@ -73,10 +74,10 @@ enum {
int
init_align_buffers
(
camogm_state
*
state
);
int
init_align_buffers
(
camogm_state
*
state
);
void
deinit_align_buffers
(
camogm_state
*
state
);
void
deinit_align_buffers
(
camogm_state
*
state
);
void
align_frame
(
camogm_state
*
state
);
void
align_frame
(
camogm_state
*
state
);
void
reset_chunks
(
struct
iovec
*
vects
,
int
all
);
void
reset_chunks
(
camogm_state
*
state
,
int
all
,
int
page
);
int
update_lba
(
camogm_state
*
state
);
//
int update_lba(camogm_state *state);
int
get_data_buffers
(
camogm_state
*
state
,
struct
iovec
*
mapped
,
size_t
all_sz
);
int
get_data_buffers
(
camogm_state
*
state
,
struct
iovec
*
mapped
,
size_t
mapped_sz
,
int
page
);
int
prep_last_block
(
camogm_state
*
state
);
int
prep_last_block
(
camogm_state
*
state
,
int
page
);
off64_t
lba_to_offset
(
uint64_t
lba
);
off64_t
lba_to_offset
(
uint64_t
lba
);
...
...
src/camogm_jpeg.c
View file @
b4d4414a
This diff is collapsed.
Click to expand it.
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