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
d336db3a
Commit
d336db3a
authored
Sep 09, 2016
by
Mikhail Karpenko
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Write driver commands to sysfs
parent
9a60ffa3
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
48 additions
and
117 deletions
+48
-117
camogm.c
camogm.c
+0
-16
camogm.h
camogm.h
+1
-0
camogm_jpeg.c
camogm_jpeg.c
+47
-101
No files found.
camogm.c
View file @
d336db3a
...
...
@@ -490,9 +490,6 @@ int sendImageFrame(camogm_state *state)
int
*
ifp_this
=
(
int
*
)
&
(
state
->
this_frame_params
[
state
->
port_num
]);
int
fp
;
int
port
=
state
->
port_num
;
unsigned
char
app15
[
64
]
=
{
0xff
,
0xef
};
int
app15_pos
=
0
;
int
stuffing
;
// This is probably needed only for Quicktime (not to exceed already allocated frame index)
if
(
state
->
frameno
>=
(
state
->
max_frames
))
{
...
...
@@ -606,28 +603,15 @@ int sendImageFrame(camogm_state *state)
state
->
packetchunks
[
state
->
chunk_index
++
].
chunk
=
state
->
jpegHeader
[
port
];
state
->
packetchunks
[
state
->
chunk_index
].
bytes
=
state
->
exifSize
[
port
];
state
->
packetchunks
[
state
->
chunk_index
++
].
chunk
=
state
->
ed
[
port
];
app15_pos
=
state
->
chunk_index
++
;
state
->
packetchunks
[
state
->
chunk_index
].
bytes
=
state
->
head_size
[
port
]
-
2
;
state
->
packetchunks
[
state
->
chunk_index
++
].
chunk
=
&
(
state
->
jpegHeader
[
port
][
2
]);
stuffing
=
32
-
(
2
+
state
->
exifSize
[
port
]
+
state
->
head_size
[
port
])
%
32
;
}
else
{
D3
(
fprintf
(
debug_file
,
"_8_"
));
app15_pos
=
state
->
chunk_index
++
;
state
->
packetchunks
[
state
->
chunk_index
].
bytes
=
state
->
head_size
[
port
];
state
->
packetchunks
[
state
->
chunk_index
++
].
chunk
=
state
->
jpegHeader
[
port
];
stuffing
=
32
-
(
state
->
head_size
[
port
]
%
32
);
}
D3
(
fprintf
(
debug_file
,
"_9_"
));
// align JPEG (+ Exif) header to 32 bytes by adding APP15 marker
if
(
stuffing
<
4
)
{
stuffing
+=
32
;
}
app15
[
3
]
=
stuffing
-
2
;
state
->
packetchunks
[
app15_pos
].
bytes
=
stuffing
;
state
->
packetchunks
[
app15_pos
].
chunk
=
app15
;
fprintf
(
debug_file
,
"
\n
add %d stuffing bytes as APP15
\n
"
,
stuffing
);
/* JPEG image data may be split in two segments (rolled over buffer end) - process both variants */
if
((
state
->
cirbuf_rp
[
port
]
+
state
->
jpeg_len
)
>
state
->
circ_buff_size
[
port
])
{
// two segments
/* copy from the beginning of the frame to the end of the buffer */
...
...
camogm.h
View file @
d336db3a
...
...
@@ -124,6 +124,7 @@ typedef struct {
pthread_t
tid
;
volatile
int
thread_state
;
unsigned
char
*
disk_mmap
;
int
sysfs_fd
;
}
rawdev_buffer
;
/**
...
...
camogm_jpeg.c
View file @
d336db3a
...
...
@@ -31,10 +31,21 @@
#include "camogm_jpeg.h"
/** The position of size field in copy buffer */
#define VECTOR_SZ_POS 0
/** The position of vector pointer field in copy buffer */
#define POINTER_POS 1
/* this should be in system includes */
#define DRV_CMD_WRITE (1 << 0)
#define DRV_CMD_FINISH (1 << 1)
#define DRV_CMD_EXIF (1 << 2)
struct
frame_data
{
unsigned
int
sensor_port
;
int
cirbuf_ptr
;
int
jpeg_len
;
int
meta_index
;
int
cmd
;
};
const
char
sysfs_fname
[]
=
"/sys/devices/soc0/amba@0/80000000.elphel-ahci/write"
;
/* end of system includes */
int
camogm_init_jpeg
(
camogm_state
*
state
)
{
...
...
@@ -84,12 +95,15 @@ int camogm_start_jpeg(camogm_state *state)
D3
(
fprintf
(
debug_file
,
"Open raw device %s; start_pos = %llu, end_pos = %llu, curr_pos = %llu
\n
"
,
state
->
rawdev
.
rawdev_path
,
state
->
rawdev
.
start_pos
,
state
->
rawdev
.
end_pos
,
state
->
rawdev
.
curr_pos_w
));
lseek64
(
state
->
rawdev
.
rawdev_fd
,
state
->
rawdev
.
curr_pos_w
,
SEEK_SET
);
state
->
rawdev
.
sysfs_fd
=
open
(
sysfs_fname
,
O_WRONLY
);
if
(
state
->
rawdev
.
sysfs_fd
<
0
)
{
D0
(
fprintf
(
debug_file
,
"Error opening sysfs file: %s
\n
"
,
sysfs_fname
));
return
-
CAMOGM_FRAME_FILE_ERR
;
}
}
}
fprintf
(
debug_file
,
"Start recording buffer usage statistics
\n
"
);
fprintf
(
debug_file
,
"
\"
JPEG write time, us
\"
,
\"
free buff, %
\"
,
\"
free buff, %
\"
,
\"
free buff, %
\"
,
\"
free buff, %
\"\n
"
);
return
0
;
}
...
...
@@ -111,8 +125,8 @@ int camogm_frame_jpeg(camogm_state *state)
int
port
=
state
->
port_num
;
uint32_t
start_time
,
end_time
;
off_t
free_space
;
struct
frame_data
fdata
=
{
0
};
start_time
=
lseek
(
state
->
fd_circ
[
0
],
LSEEK_CIRC_UTIME
,
SEEK_END
);
if
(
!
state
->
rawdev_op
)
{
l
=
0
;
for
(
i
=
0
;
i
<
(
state
->
chunk_index
)
-
1
;
i
++
)
{
...
...
@@ -134,104 +148,23 @@ int camogm_frame_jpeg(camogm_state *state)
}
close
(
state
->
ivf
);
}
else
{
// D3(fprintf(debug_file, "\n%s: current pointers start_pos = %llu, end_pos = %llu, curr_pos = %llu, data in buffer %d\n", __func__,
// state->rawdev.start_pos, state->rawdev.end_pos, state->rawdev.curr_pos_w, l));
// split_index = -1;
// for (int i = 0, total_len = 0; i < state->chunk_index - 1; i++) {
// total_len += state->packetchunks[i + 1].bytes;
// if (total_len + state->rawdev.curr_pos_w > state->rawdev.end_pos) {
// split_index = i;
// chunks_used++;
// D3(fprintf(debug_file, "\n>>> raw storage roll over detected\n"));
// break;
// }
// }
// k = 0;
// l = 0;
// for (int i = 0; i < chunks_used; i++) {
// ++k;
// if (i == split_index) {
// // one of the chunks rolls over the end of the raw storage, split it into two segments and
// // use additional chunk in chunks_iovec for this additional segment
// split_cntr = state->rawdev.end_pos - (l + state->rawdev.curr_pos_w);
// split_ptr = state->packetchunks[k].chunk + split_cntr;
//
// D3(fprintf(debug_file, "Splitting chunk #%d: total chunk size = %ld, start address = 0x%p\n",
// i, state->packetchunks[k].bytes, state->packetchunks[k].chunk));
//
// // be careful with indexes here
// chunks_iovec[i].iov_base = state->packetchunks[k].chunk;
// chunks_iovec[i].iov_len = split_cntr;
// l += chunks_iovec[i].iov_len;
// chunks_iovec[++i].iov_base = split_ptr + 1;
// chunks_iovec[i].iov_len = state->packetchunks[k].bytes - split_cntr;
// l += chunks_iovec[i].iov_len;
// } else {
// chunks_iovec[i].iov_base = state->packetchunks[k].chunk;
// chunks_iovec[i].iov_len = state->packetchunks[k].bytes;
// l += chunks_iovec[i].iov_len;
// }
// }
//
// if (split_index < 0) {
// iovlen = writev(state->rawdev.rawdev_fd, chunks_iovec, chunks_used);
// } else {
// iovlen = writev(state->rawdev.rawdev_fd, chunks_iovec, split_index + 1);
// fprintf(debug_file, "write first part: split_index = %d, %d bytes written\n", split_index, iovlen);
// if (lseek64(state->rawdev.rawdev_fd, state->rawdev.start_pos, SEEK_SET) != state->rawdev.start_pos) {
// perror(__func__);
// D0(fprintf(debug_file, "error positioning file pointer to the beginning of raw device\n"));
// return -CAMOGM_FRAME_FILE_ERR;
// }
// state->rawdev.overrun++;
// iovlen += writev(state->rawdev.rawdev_fd, &chunks_iovec[split_index + 1], chunks_used - split_index);
// fprintf(debug_file, "write second part: split_index + 1 = %d, chunks_used - split_index = %d, %d bytes written in total\n",
// split_index + 1, chunks_used - split_index, iovlen);
// }
// if (iovlen < l) {
// j = errno;
// perror(__func__);
// D0(fprintf(debug_file, "writev error %d (returned %d, expected %d)\n", j, iovlen, l));
// return -CAMOGM_FRAME_FILE_ERR;
// }
// state->rawdev.curr_pos_w += l;
// if (state->rawdev.curr_pos_w > state->rawdev.end_pos)
// state->rawdev.curr_pos_w = state->rawdev.curr_pos_w - state->rawdev.end_pos + state->rawdev.start_pos;
// D6(fprintf(debug_file, "%d bytes written, curr_pos = %llu\n", l, state->rawdev.curr_pos_w));
uint8_t
buff
[
128
]
=
{
0
};
uint32_t
*
buff_p
=
(
uint32_t
*
)
buff
;
uint8_t
*
pos
;
int
fd
=
open
(
"/sys/devices/soc0/amba@0/80000000.elphel-ahci/write"
,
O_WRONLY
);
if
(
fd
<
0
)
{
perror
(
"ERROR: can not open test_write file
\n
"
);
return
-
CAMOGM_FRAME_FILE_ERR
;
}
buff_p
[
VECTOR_SZ_POS
]
=
state
->
chunk_index
-
1
;
fprintf
(
debug_file
,
"dump iovect array
\n
"
);
for
(
int
i
=
0
;
i
<
state
->
chunk_index
-
1
;
i
++
)
{
fprintf
(
debug_file
,
"ptr: %p, length: %ld
\n
"
,
state
->
packetchunks
[
i
+
1
].
chunk
,
state
->
packetchunks
[
i
+
1
].
bytes
);
}
buff_p
[
POINTER_POS
]
=
(
uint32_t
)
&
state
->
packetchunks
[
1
];
if
(
write
(
fd
,
buff
,
8
)
<
0
)
{
perror
(
"Can not pass IO vector to driver:"
);
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
;
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
;
}
close
(
fd
);
}
end_time
=
lseek
(
state
->
fd_circ
[
0
],
LSEEK_CIRC_UTIME
,
SEEK_END
);
// fprintf(debug_file, "JPEG write time = %u us\n", end_time - start_time);
// fprintf(debug_file, "Free space in buffers: ");
// for (int i = 0; i < SENSOR_PORTS; i++) {
// int buff_size, jpeg_pos;
// jpeg_pos = lseek(state->fd_circ[i], 0 , SEEK_CUR);
// free_space = lseek(state->fd_circ[i], LSEEK_CIRC_FREE, SEEK_END);
// buff_size = lseek(state->fd_circ[i], 0, SEEK_END);
// lseek(state->fd_circ[i], jpeg_pos, SEEK_SET);
// fprintf(debug_file, "chn %d = %ld ",
// i,
// (int)(100 * (float)free_space / (float)buff_size));
// }
// fprintf(debug_file, "\b\n");
return
0
;
}
...
...
@@ -246,9 +179,22 @@ int camogm_frame_jpeg(camogm_state *state)
int
camogm_end_jpeg
(
camogm_state
*
state
)
{
int
ret
=
0
;
struct
frame_data
fdata
=
{
0
};
if
(
state
->
rawdev_op
)
{
ret
=
close
(
state
->
rawdev
.
rawdev_fd
);
D0
(
fprintf
(
debug_file
,
"Closing raw device %s
\n
"
,
state
->
rawdev
.
rawdev_path
));
ret
=
close
(
state
->
rawdev
.
rawdev_fd
);
if
(
ret
==
-
1
)
D0
(
fprintf
(
debug_file
,
"Error: %s
\n
"
,
strerror
(
errno
)));
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
"
));
}
D0
(
fprintf
(
debug_file
,
"Closing sysfs file %s
\n
"
,
sysfs_fname
));
ret
=
close
(
state
->
rawdev
.
sysfs_fd
);
if
(
ret
==
-
1
)
D0
(
fprintf
(
debug_file
,
"Error: %s
\n
"
,
strerror
(
errno
)));
}
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