Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Mattias Fält
moberg
Commits
21b59266
Commit
21b59266
authored
Feb 28, 2019
by
Anders Blomdell
Browse files
AnalogIn works for comedi
parent
87b88706
Changes
15
Hide whitespace changes
Inline
Side-by-side
Makefile
View file @
21b59266
...
...
@@ -44,6 +44,7 @@ test: all
clean
:
find build
-type
f
-delete
rm
-f
*
~
make
-C
test
clean
build/libmoberg.so
:
build/lib/moberg_config.o
build/libmoberg.so
:
build/lib/moberg_device.o
...
...
moberg.c
View file @
21b59266
...
...
@@ -13,6 +13,7 @@
#include
<moberg.h>
#include
<moberg_config.h>
#include
<moberg_parser.h>
#include
<moberg_module.h>
struct
moberg
{
struct
moberg_config
*
config
;
...
...
@@ -20,19 +21,19 @@ struct moberg {
int
capacity
;
struct
moberg_channel
**
value
;
}
analog_in
,
analog_out
,
digital_in
,
digital_out
,
encoder_in
;
};
struct
deferred_action
{
struct
deferred_action
*
next
;
int
(
*
action
)(
void
*
param
);
void
*
param
;
}
*
deferred_action
;
static
struct
deferred_action
{
struct
deferred_action
*
next
;
int
(
*
action
)(
void
*
param
);
void
*
param
;
}
*
deferred_action
=
NULL
;
};
static
void
run_deferred_actions
()
static
void
run_deferred_actions
(
struct
moberg
*
moberg
)
{
while
(
deferred_action
)
{
struct
deferred_action
*
deferred
=
deferred_action
;
deferred_action
=
deferred
_action
->
next
;
while
(
moberg
->
deferred_action
)
{
struct
deferred_action
*
deferred
=
moberg
->
deferred_action
;
moberg
->
deferred_action
=
deferred
->
next
;
deferred
->
action
(
deferred
->
param
);
free
(
deferred
);
}
...
...
@@ -100,7 +101,7 @@ static void parse_config_at(
buf
[
statbuf
.
st_size
]
=
0
;
}
printf
(
"Parsing... %s %d %d
\n
"
,
pathname
,
dirfd
,
fd
);
struct
moberg_config
*
config
=
moberg_parse
(
buf
);
struct
moberg_config
*
config
=
moberg_parse
(
moberg
,
buf
);
printf
(
"-> %p
\n
"
,
config
);
if
(
config
)
{
if
(
!
moberg
->
config
)
{
...
...
@@ -236,6 +237,7 @@ struct moberg *moberg_new(
result
->
digital_out
.
value
=
NULL
;
result
->
encoder_in
.
capacity
=
0
;
result
->
encoder_in
.
value
=
NULL
;
result
->
deferred_action
=
NULL
;
if
(
config
)
{
result
->
config
=
config
;
}
else
{
...
...
@@ -263,7 +265,7 @@ struct moberg *moberg_new(
/* Parse environment overrides */
}
install_config
(
result
);
run_deferred_actions
();
run_deferred_actions
(
result
);
err:
return
result
;
...
...
@@ -278,37 +280,72 @@ void moberg_free(struct moberg *moberg)
channel_list_free
(
&
moberg
->
digital_in
);
channel_list_free
(
&
moberg
->
digital_out
);
channel_list_free
(
&
moberg
->
encoder_in
);
run_deferred_actions
(
moberg
);
free
(
moberg
);
}
run_deferred_actions
();
}
enum
moberg_status
moberg_start
(
/* Input/output */
int
moberg_analog_in_open
(
struct
moberg
*
moberg
,
int
index
,
struct
moberg_analog_in
*
analog_in
)
{
struct
moberg_channel
*
channel
=
NULL
;
channel_list_get
(
&
moberg
->
analog_in
,
index
,
&
channel
);
if
(
channel
)
{
printf
(
"Call open
\n
"
);
channel
->
open
(
channel
);
channel
->
up
(
channel
);
*
analog_in
=
channel
->
action
.
analog_in
;
return
1
;
}
return
0
;
}
int
moberg_analog_in_close
(
struct
moberg
*
moberg
,
int
index
,
struct
moberg_analog_in
analog_in
)
{
struct
moberg_channel
*
channel
=
NULL
;
channel_list_get
(
&
moberg
->
analog_in
,
index
,
&
channel
);
if
(
channel
&&
channel
->
action
.
analog_in
.
context
==
analog_in
.
context
)
{
printf
(
"Call close
\n
"
);
channel
->
close
(
channel
);
channel
->
down
(
channel
);
}
return
1
;
}
/* System init functionality (systemd/init/...) */
int
moberg_start
(
struct
moberg
*
moberg
,
FILE
*
f
)
{
return
moberg_config_start
(
moberg
->
config
,
f
);
return
moberg_OK
;
}
enum
moberg_status
moberg_stop
(
int
moberg_stop
(
struct
moberg
*
moberg
,
FILE
*
f
)
{
return
moberg_config_stop
(
moberg
->
config
,
f
);
return
moberg_OK
;
}
void
moberg_deferred_action
(
int
(
*
action
)(
void
*
param
),
void
*
param
)
/* Intended for final cleanup actions (dlclose so far...) */
void
moberg_deferred_action
(
struct
moberg
*
moberg
,
int
(
*
action
)(
void
*
param
),
void
*
param
)
{
struct
deferred_action
*
deferred
=
malloc
(
sizeof
(
*
deferred
));
if
(
deferred
)
{
deferred
->
next
=
deferred_action
;
deferred
->
next
=
moberg
->
deferred_action
;
deferred
->
action
=
action
;
deferred
->
param
=
param
;
deferred_action
=
deferred
;
moberg
->
deferred_action
=
deferred
;
}
}
moberg.h
View file @
21b59266
...
...
@@ -6,46 +6,54 @@
struct
moberg
;
struct
moberg_config
;
enum
moberg_status
{
moberg_OK
};
/* Creation & free */
struct
moberg
*
moberg_new
(
struct
moberg_config
*
config
);
void
moberg_free
(
struct
moberg
*
moberg
);
/* Input/output
functions
*/
/* Input/output */
enum
moberg_status
moberg_analog_in
(
double
*
value
,
struct
moberg
*
moberg
,
int
channel
)
;
struct
moberg_analog_in
{
struct
moberg_channel_analog_in
*
context
;
int
(
*
read
)(
struct
moberg
_channel_analog_in
*
,
double
*
value
);
}
;
enum
moberg_status
moberg_analog_out
(
double
value
,
struct
moberg
*
moberg
,
int
channel
)
;
struct
moberg_analog_out
{
struct
moberg_channel_analog_out
*
context
;
int
(
*
write
)(
struct
moberg_channel_analog_in
*
,
double
value
);
}
;
enum
moberg_status
moberg_digital_in
(
in
t
*
value
,
struct
moberg
*
moberg
,
int
channel
)
;
struct
moberg_digital_in
{
struct
moberg_channel_digital_
in
*
context
;
int
(
*
read
)(
struct
moberg
_channel_digital_in
*
,
int
*
value
);
}
;
enum
moberg_status
moberg_digital_out
(
int
value
,
struct
moberg
*
moberg
,
int
channel
)
;
struct
moberg_digital_out
{
struct
moberg_channel_digital_out
*
context
;
int
(
*
write
)(
struct
moberg_channel_digital_out
*
,
int
value
);
}
;
enum
moberg_status
moberg_encoder_in
(
long
*
value
,
struct
moberg
*
moberg
,
int
channel
);
struct
moberg_encoder_in
{
struct
moberg_channel_encoder_in
*
context
;
int
(
*
read
)(
struct
moberg_channel_encoder_in
*
,
long
*
value
);
};
int
moberg_analog_in_open
(
struct
moberg
*
moberg
,
int
index
,
struct
moberg_analog_in
*
analog_in
);
int
moberg_analog_in_close
(
struct
moberg
*
moberg
,
int
index
,
struct
moberg_analog_in
analog_in
);
/*
Install
functionality */
/*
System init
functionality
(systemd/init/...)
*/
enum
moberg_status
moberg_start
(
int
moberg_start
(
struct
moberg
*
moberg
,
FILE
*
f
);
enum
moberg_status
moberg_stop
(
int
moberg_stop
(
struct
moberg
*
moberg
,
FILE
*
f
);
...
...
moberg_channel.h
View file @
21b59266
...
...
@@ -25,26 +25,11 @@ struct moberg_channel {
/* I/O operations */
enum
moberg_channel_kind
kind
;
union
moberg_channel_action
{
struct
{
struct
moberg_channel_analog_in
*
context
;
int
(
*
read
)(
struct
moberg_channel_analog_in
*
,
double
*
value
);
}
analog_in
;
struct
{
struct
moberg_channel_analog_out
*
context
;
int
(
*
write
)(
struct
moberg_channel_context
*
,
double
value
);
}
analog_out
;
struct
{
struct
moberg_channel_digital_in
*
context
;
int
(
*
read
)(
struct
moberg_channel_context
*
,
int
*
value
);
}
digital_in
;
struct
{
struct
moberg_channel_digital_out
*
context
;
int
(
*
write
)(
struct
moberg_channel_context
*
,
int
value
);
}
digital_out
;
struct
{
struct
moberg_channel_encoder_in
*
context
;
int
(
*
read
)(
struct
moberg_channel_context
*
,
long
*
value
);
}
encoder_in
;
struct
moberg_analog_in
analog_in
;
struct
moberg_analog_out
analog_out
;
struct
moberg_digital_in
digital_in
;
struct
moberg_digital_out
digital_out
;
struct
moberg_encoder_in
encoder_in
;
}
action
;
};
...
...
moberg_device.c
View file @
21b59266
...
...
@@ -30,7 +30,8 @@ struct moberg_device {
}
*
range
;
};
struct
moberg_device
*
moberg_device_new
(
const
char
*
driver
)
struct
moberg_device
*
moberg_device_new
(
struct
moberg
*
moberg
,
const
char
*
driver
)
{
struct
moberg_device
*
result
=
NULL
;
...
...
@@ -54,7 +55,7 @@ struct moberg_device *moberg_device_new(const char *driver)
goto
dlclose_driver
;
}
result
->
driver
=
*
device_driver
;
result
->
device_context
=
result
->
driver
.
new
(
dlclose
,
handle
);
result
->
device_context
=
result
->
driver
.
new
(
moberg
,
dlclose
,
handle
);
if
(
result
->
device_context
)
{
result
->
driver
.
up
(
result
->
device_context
);
}
else
{
...
...
moberg_device.h
View file @
21b59266
...
...
@@ -13,7 +13,8 @@ struct moberg_parser_context;
struct
moberg_device_driver
{
/* Create new device context */
struct
moberg_device_context
*
(
*
new
)(
int
(
*
dlclose
)(
void
*
dlhandle
),
struct
moberg_device_context
*
(
*
new
)(
struct
moberg
*
moberg
,
int
(
*
dlclose
)(
void
*
dlhandle
),
void
*
dlhandle
);
/* Use-count of device, when it reaches zero, device will be free'd */
int
(
*
up
)(
struct
moberg_device_context
*
context
);
...
...
@@ -41,7 +42,8 @@ struct moberg_device_driver {
struct
moberg_device
;
struct
moberg_device
*
moberg_device_new
(
const
char
*
driver
);
struct
moberg_device
*
moberg_device_new
(
struct
moberg
*
moberg
,
const
char
*
driver
);
void
moberg_device_free
(
struct
moberg_device
*
device
);
...
...
moberg_module.h
View file @
21b59266
...
...
@@ -55,6 +55,7 @@ void moberg_parser_failed(
FILE
*
f
);
void
moberg_deferred_action
(
struct
moberg
*
moberg
,
int
(
*
action
)(
void
*
param
),
void
*
param
);
...
...
moberg_parser.c
View file @
21b59266
...
...
@@ -361,7 +361,8 @@ err:
return
0
;
}
static
int
parse
(
context_t
*
c
)
static
int
parse
(
struct
moberg
*
moberg
,
context_t
*
c
)
{
for
(;;)
{
if
(
acceptsym
(
c
,
tok_EOF
,
NULL
))
{
...
...
@@ -381,18 +382,20 @@ static int parse(context_t *c)
t
.
u
.
idstr
.
length
,
t
.
u
.
idstr
.
value
);
goto
err
;
}
device
=
moberg_device_new
(
name
);
device
=
moberg_device_new
(
moberg
,
name
);
free
(
name
);
if
(
!
device
)
{
goto
err
;
}
if
(
!
parse_device
(
c
,
device
))
{
moberg_device_free
(
device
);
goto
err
;
goto
device_free
;
}
if
(
!
moberg_config_add_device
(
c
->
config
,
device
))
{
moberg_device_free
(
device
);
goto
err
;
goto
device_free
;
}
continue
;
device_free:
moberg_device_free
(
device
);
goto
err
;
}
}
return
1
;
...
...
@@ -403,7 +406,8 @@ err:
return
0
;
}
struct
moberg_config
*
moberg_parse
(
const
char
*
buf
)
struct
moberg_config
*
moberg_parse
(
struct
moberg
*
moberg
,
const
char
*
buf
)
{
context_t
context
;
...
...
@@ -413,7 +417,7 @@ struct moberg_config *moberg_parse(const char *buf)
context
.
buf
=
buf
;
context
.
p
=
context
.
buf
;
nextsym
(
&
context
);
if
(
!
parse
(
&
context
))
{
if
(
!
parse
(
moberg
,
&
context
))
{
moberg_config_free
(
context
.
config
);
context
.
config
=
NULL
;
}
...
...
moberg_parser.h
View file @
21b59266
#ifndef __MOBERG_PARSER_H__
#define __MOBERG_PARSER_H__
#include
<moberg.h>
#include
<moberg_config.h>
struct
moberg_parser_context
;
struct
moberg_config
*
moberg_parse
(
const
char
*
buf
);
struct
moberg_config
*
moberg_parse
(
struct
moberg
*
moberg
,
const
char
*
buf
);
#endif
modules/comedi/Makefile
View file @
21b59266
LIBRARIES
=
libmoberg_comedi.so
CCFLAGS
+=
-Wall
-Werror
-I
../..
-g
LDFLAGS
+=
-Lbuild
/
-lmoberg
MODULES
=
$(
wildcard
modules/
*
)
all
:
$(LIBRARIES:%=../../build/%)
../../build/libmoberg_comedi.so
:
comedi.c Makefile
$(CC)
-o
$@
$(CCFLAGS)
-shared
-fPIC
$<
$(CC)
-o
$@
$(CCFLAGS)
-shared
-fPIC
-lcomedi
$<
../../build/libmoberg_comedi.so
:
../../moberg_module.h
modules/comedi/comedi.c
View file @
21b59266
...
...
@@ -5,6 +5,7 @@
#include
<stdio.h>
#include
<stdlib.h>
#include
<string.h>
#include
<comedilib.h>
typedef
enum
moberg_parser_token_kind
kind_t
;
typedef
struct
moberg_parser_token
token_t
;
...
...
@@ -12,10 +13,15 @@ typedef struct moberg_parser_ident ident_t;
typedef
struct
moberg_parser_context
context_t
;
struct
moberg_device_context
{
struct
moberg
*
moberg
;
int
(
*
dlclose
)(
void
*
dlhandle
);
void
*
dlhandle
;
int
use_count
;
char
*
name
;
struct
{
int
count
;
comedi_t
*
handle
;
}
comedi
;
struct
idstr
{
struct
idstr
*
next
;
struct
idstr
*
prev
;
...
...
@@ -28,6 +34,15 @@ struct moberg_channel_context {
void
*
to_free
;
/* To be free'd when use_count goes to zero */
struct
moberg_device_context
*
device
;
int
use_count
;
struct
channel_descriptor
{
int
subdevice
;
int
subchannel
;
int
route
;
lsampl_t
maxdata
;
double
min
;
double
max
;
double
delta
;
}
descriptor
;
};
struct
moberg_channel_analog_in
{
...
...
@@ -55,13 +70,29 @@ struct moberg_channel_encoder_in {
struct
moberg_channel_context
channel_context
;
};
static
struct
moberg_device_context
*
new_context
(
int
(
*
dlclose
)(
void
*
dlhandle
),
void
*
dlhandle
)
static
int
analog_in_read
(
struct
moberg_channel_analog_in
*
analog_in
,
double
*
value
)
{
struct
channel_descriptor
descriptor
=
analog_in
->
channel_context
.
descriptor
;
lsampl_t
data
;
comedi_data_read
(
analog_in
->
channel_context
.
device
->
comedi
.
handle
,
descriptor
.
subdevice
,
descriptor
.
subchannel
,
0
,
0
,
&
data
);
*
value
=
descriptor
.
min
+
data
*
descriptor
.
delta
;
fprintf
(
stderr
,
"Data: %d %f
\n
"
,
data
,
*
value
);
return
1
;
}
static
struct
moberg_device_context
*
new_context
(
struct
moberg
*
moberg
,
int
(
*
dlclose
)(
void
*
dlhandle
),
void
*
dlhandle
)
{
struct
moberg_device_context
*
result
=
malloc
(
sizeof
(
*
result
));
if
(
result
)
{
memset
(
result
,
0
,
sizeof
(
*
result
));
result
->
moberg
=
moberg
;
result
->
dlclose
=
dlclose
;
result
->
dlhandle
=
dlhandle
;
result
->
modprobe_list
.
next
=
&
result
->
modprobe_list
;
...
...
@@ -72,41 +103,67 @@ static struct moberg_device_context *new_context(
return
result
;
}
static
int
device_up
(
struct
moberg_device_context
*
context
)
static
int
device_up
(
struct
moberg_device_context
*
device
)
{
context
->
use_count
++
;
return
context
->
use_count
;
device
->
use_count
++
;
return
device
->
use_count
;
}
static
int
device_down
(
struct
moberg_device_context
*
context
)
static
int
device_down
(
struct
moberg_device_context
*
device
)
{
context
->
use_count
--
;
int
result
=
context
->
use_count
;
if
(
context
->
use_count
<=
0
)
{
moberg_deferred_action
(
context
->
dlclose
,
context
->
dlhandle
);
free
(
context
->
name
);
device
->
use_count
--
;
int
result
=
device
->
use_count
;
if
(
device
->
use_count
<=
0
)
{
moberg_deferred_action
(
device
->
moberg
,
device
->
dlclose
,
device
->
dlhandle
);
free
(
device
->
name
);
struct
idstr
*
e
;
e
=
context
->
modprobe_list
.
next
;
while
(
e
!=
&
context
->
modprobe_list
)
{
e
=
device
->
modprobe_list
.
next
;
while
(
e
!=
&
device
->
modprobe_list
)
{
struct
idstr
*
next
=
e
->
next
;
free
(
e
->
value
);
free
(
e
);
e
=
next
;
}
e
=
context
->
config_list
.
next
;
while
(
e
!=
&
context
->
config_list
)
{
e
=
device
->
config_list
.
next
;
while
(
e
!=
&
device
->
config_list
)
{
struct
idstr
*
next
=
e
->
next
;
free
(
e
->
value
);
free
(
e
);
e
=
next
;
}
free
(
context
);
free
(
device
);
return
0
;
}
return
result
;
}
static
int
device_open
(
struct
moberg_device_context
*
device
)
{
if
(
device
->
comedi
.
count
==
0
)
{
device
->
comedi
.
handle
=
comedi_open
(
device
->
name
);
if
(
device
->
comedi
.
handle
==
NULL
)
{
goto
err
;
}
}
device
->
comedi
.
count
++
;
return
1
;
err:
fprintf
(
stderr
,
"Failed to open %s
\n
"
,
device
->
name
);
return
0
;
}
static
int
device_close
(
struct
moberg_device_context
*
device
)
{
device
->
comedi
.
count
--
;
if
(
device
->
comedi
.
count
==
0
)
{
comedi_close
(
device
->
comedi
.
handle
);
}
return
1
;
}
static
int
channel_up
(
struct
moberg_channel
*
channel
)
{
device_up
(
channel
->
context
->
device
);
...
...
@@ -125,22 +182,73 @@ static int channel_down(struct moberg_channel *channel)
return
channel
->
context
->
use_count
;
}
static
int
channel_open
(
struct
moberg_channel
*
channel
)
{
channel_up
(
channel
);
if
(
!
device_open
(
channel
->
context
->
device
))
{
goto
err
;
}
fprintf
(
stderr
,
"Open %s[%d][%d]
\n
"
,
channel
->
context
->
device
->
name
,
channel
->
context
->
descriptor
.
subdevice
,
channel
->
context
->
descriptor
.
subchannel
);
lsampl_t
maxdata
;
comedi_range
*
range
;
maxdata
=
comedi_get_maxdata
(
channel
->
context
->
device
->
comedi
.
handle
,
channel
->
context
->
descriptor
.
subdevice
,
channel
->
context
->
descriptor
.
subchannel
);
range
=
comedi_get_range
(
channel
->
context
->
device
->
comedi
.
handle
,
channel
->
context
->
descriptor
.
subdevice
,
channel
->
context
->
descriptor
.
subchannel
,
0
);
if
(
!
maxdata
)
{
fprintf
(
stderr
,
"Failed to get maxdata for %s[%d][%d]
\n
"
,
channel
->
context
->
device
->
name
,
channel
->
context
->
descriptor
.
subdevice
,
channel
->
context
->
descriptor
.
subchannel
);
goto
err
;
}
if
(
!
range
)
{
fprintf
(
stderr
,
"Failed to get range for %s[%d][%d]
\n
"
,
channel
->
context
->
device
->
name
,
channel
->
context
->
descriptor
.
subdevice
,
channel
->
context
->
descriptor
.
subchannel
);
goto
err
;
}
channel
->
context
->
descriptor
.
maxdata
=
maxdata
;
channel
->
context
->
descriptor
.
min
=
range
->
min
;
channel
->
context
->
descriptor
.
max
=
range
->
max
;
channel
->
context
->
descriptor
.
delta
=
(
range
->
max
-
range
->
min
)
/
maxdata
;
return
1
;
err:
return
0
;
}
static
int
channel_close
(
struct
moberg_channel
*
channel
)
{
device_close
(
channel
->
context
->
device
);
channel_down
(
channel
);
return
1
;
}
static
void
init_channel
(
struct
moberg_channel
*
channel
,
void
*
to_free
,
struct
moberg_channel_context
*
context
,
struct
moberg_device_context
*
device
,
struct
channel_descriptor
descriptor
,
enum
moberg_channel_kind
kind
,
union
moberg_channel_action
action
)
{
context
->
to_free
=
to_free
;
context
->
device
=
device
;
context
->
use_count
=
0
;
context
->
descriptor
=
descriptor
;
channel
->
context
=
context
;
channel
->
up
=
channel_up
;
channel
->
down
=
channel_down
;