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
25d5b846
Commit
25d5b846
authored
Feb 27, 2019
by
Anders Blomdell
Browse files
Use-counts in place
parent
b7839ae1
Changes
10
Hide whitespace changes
Inline
Side-by-side
Makefile
View file @
25d5b846
...
...
@@ -3,7 +3,8 @@ CCFLAGS+=-Wall -Werror -I$(shell pwd) -g
LDFLAGS
+=
-L
$(
shell
pwd
)
/build/
-lmoberg
MODULES
:=
$(
wildcard
modules/
*
)
export
CCFLAGS
LDFLAGS
LDFLAGS_parse_config
=
-ldl
-export-dynamic
LDFLAGS_parse_config
=
-ldl
#-export-dynamic
all
:
$(LIBRARIES:%=build/%) $(MODULES)
echo
$(MODULES)
...
...
moberg.c
View file @
25d5b846
...
...
@@ -14,19 +14,66 @@
#include
<moberg_config.h>
#include
<moberg_parser.h>
struct
moberg_digital_in_t
{
int
index
;
char
*
driver
;
};
static
struct
deferred_action
{
struct
deferred_action
*
next
;
int
(
*
action
)(
void
*
param
);
void
*
param
;
}
*
deferred_action
=
NULL
;
struct
moberg
{
struct
moberg_config
*
config
;
struct
{
int
c
ount
;
struct
moberg_
digital_in_t
*
value
;
}
digital
_in
;
struct
channel_list
{
int
c
apacity
;
struct
moberg_
channel
*
*
value
;
}
analog_in
,
analog_out
,
digital_in
,
digital_out
,
encoder
_in
;
};
static
int
channel_list_set
(
struct
channel_list
*
list
,
int
index
,
struct
moberg_channel
*
value
)
{
if
(
list
->
capacity
<=
index
)
{
int
capacity
;
for
(
capacity
=
2
;
capacity
<=
index
;
capacity
*=
2
);
void
*
new
=
realloc
(
list
->
value
,
capacity
*
sizeof
(
**
list
->
value
));
if
(
!
new
)
{
goto
err
;
}
void
*
p
=
new
+
list
->
capacity
*
sizeof
(
*
list
->
value
);
memset
(
p
,
0
,
(
capacity
-
list
->
capacity
)
*
sizeof
(
**
list
->
value
));
list
->
value
=
new
;
list
->
capacity
=
capacity
;
}
if
(
0
<=
index
&&
index
<
list
->
capacity
)
{
list
->
value
[
index
]
=
value
;
return
1
;
}
err:
return
0
;
}
static
int
channel_list_get
(
struct
channel_list
*
list
,
int
index
,
struct
moberg_channel
**
value
)
{
if
(
0
<=
index
&&
index
<
list
->
capacity
)
{
*
value
=
list
->
value
[
index
];
return
1
;
}
return
0
;
}
static
void
channel_list_free
(
struct
channel_list
*
list
)
{
for
(
int
i
=
0
;
i
<
list
->
capacity
;
i
++
)
{
if
(
list
->
value
[
i
])
{
list
->
value
[
i
]
->
down
(
list
->
value
[
i
]);
}
}
free
(
list
->
value
);
}
static
void
parse_config_at
(
struct
moberg
*
moberg
,
int
dirfd
,
...
...
@@ -88,12 +135,77 @@ static void parse_config_dir_at(
}
static
int
install_channel
(
struct
moberg
*
moberg
,
int
index
,
struct
moberg_device
*
device
,
struct
moberg_channel
*
channel
)
{
fprintf
(
stderr
,
"CHAN %p %d %d
\n
"
,
channel
,
channel
->
kind
,
index
);
if
(
channel
)
{
struct
moberg_channel
*
old
=
NULL
;
switch
(
channel
->
kind
)
{
case
chan_ANALOGIN
:
channel_list_get
(
&
moberg
->
analog_in
,
index
,
&
old
);
break
;
case
chan_ANALOGOUT
:
channel_list_get
(
&
moberg
->
analog_out
,
index
,
&
old
);
break
;
case
chan_DIGITALIN
:
channel_list_get
(
&
moberg
->
digital_in
,
index
,
&
old
);
break
;
case
chan_DIGITALOUT
:
channel_list_get
(
&
moberg
->
digital_out
,
index
,
&
old
);
break
;
case
chan_ENCODERIN
:
channel_list_get
(
&
moberg
->
encoder_in
,
index
,
&
old
);
break
;
}
if
(
old
)
{
old
->
down
(
old
);
}
channel
->
up
(
channel
);
/* TODO: Clean up old channel */
switch
(
channel
->
kind
)
{
case
chan_ANALOGIN
:
if
(
!
channel_list_set
(
&
moberg
->
analog_in
,
index
,
channel
))
{
goto
err
;
}
break
;
case
chan_ANALOGOUT
:
if
(
!
channel_list_set
(
&
moberg
->
analog_out
,
index
,
channel
))
{
goto
err
;
}
break
;
case
chan_DIGITALIN
:
if
(
!
channel_list_set
(
&
moberg
->
digital_in
,
index
,
channel
))
{
goto
err
;
}
break
;
case
chan_DIGITALOUT
:
if
(
!
channel_list_set
(
&
moberg
->
digital_out
,
index
,
channel
))
{
goto
err
;
}
break
;
case
chan_ENCODERIN
:
if
(
!
channel_list_set
(
&
moberg
->
encoder_in
,
index
,
channel
))
{
goto
err
;
}
break
;
}
}
return
1
;
err:
return
0
;
}
static
int
install_config
(
struct
moberg
*
moberg
)
{
struct
moberg_install_channels
install
=
{
.
context
=
moberg
struct
moberg_channel_install
install
=
{
.
context
=
moberg
,
.
channel
=
install_channel
};
return
moberg_config_install_channels
(
moberg
->
config
,
&
install
);
/* TODO cleanup unused devices...*/
}
struct
moberg
*
moberg_new
(
...
...
@@ -104,6 +216,16 @@ struct moberg *moberg_new(
fprintf
(
stderr
,
"Failed to allocate moberg struct
\n
"
);
goto
err
;
}
result
->
analog_in
.
capacity
=
0
;
result
->
analog_in
.
value
=
NULL
;
result
->
analog_out
.
capacity
=
0
;
result
->
analog_out
.
value
=
NULL
;
result
->
digital_in
.
capacity
=
0
;
result
->
digital_in
.
value
=
NULL
;
result
->
digital_out
.
capacity
=
0
;
result
->
digital_out
.
value
=
NULL
;
result
->
encoder_in
.
capacity
=
0
;
result
->
encoder_in
.
value
=
NULL
;
if
(
config
)
{
result
->
config
=
config
;
}
else
{
...
...
@@ -118,7 +240,6 @@ struct moberg *moberg_new(
parse_config_at
(
result
,
dirfd1
,
"moberg.conf"
);
int
dirfd2
=
openat
(
dirfd1
,
"moberg.d"
,
O_DIRECTORY
);
if
(
dirfd2
>=
0
)
{
parse_config_dir_at
(
result
,
dirfd2
);
parse_config_dir_at
(
result
,
dirfd2
);
close
(
dirfd2
);
}
...
...
@@ -141,8 +262,20 @@ void moberg_free(struct moberg *moberg)
{
if
(
moberg
)
{
moberg_config_free
(
moberg
->
config
);
channel_list_free
(
&
moberg
->
analog_in
);
channel_list_free
(
&
moberg
->
analog_out
);
channel_list_free
(
&
moberg
->
digital_in
);
channel_list_free
(
&
moberg
->
digital_out
);
channel_list_free
(
&
moberg
->
encoder_in
);
free
(
moberg
);
}
while
(
deferred_action
)
{
fprintf
(
stderr
,
"RUNNING deferred
\n
"
);
struct
deferred_action
*
deferred
=
deferred_action
;
deferred_action
=
deferred_action
->
next
;
deferred
->
action
(
deferred
->
param
);
free
(
deferred
);
}
}
enum
moberg_status
moberg_start
(
...
...
@@ -160,3 +293,16 @@ enum moberg_status moberg_stop(
return
moberg_OK
;
}
void
moberg_deferred_action
(
int
(
*
action
)(
void
*
param
),
void
*
param
)
{
struct
deferred_action
*
deferred
=
malloc
(
sizeof
(
*
deferred
));
if
(
deferred
)
{
fprintf
(
stderr
,
"DEFERRED %p %p
\n
"
,
action
,
param
);
deferred
->
next
=
deferred_action
;
deferred
->
action
=
action
;
deferred
->
param
=
param
;
deferred_action
=
deferred
;
}
}
moberg_config.c
View file @
25d5b846
...
...
@@ -2,71 +2,12 @@
#include
<string.h>
#include
<moberg_config.h>
#define LIST_COND_GROW(LIST, INDEX, ONERR) \
({ \
if (LIST.capacity <= INDEX) { \
int new_cap; \
for (new_cap = 2 ; new_cap <= INDEX ; new_cap *= 2); \
void *new = realloc(LIST.value, new_cap * sizeof(*LIST.value)); \
if (! new) { ONERR; } \
void *p = new + LIST.capacity * sizeof(*LIST.value); \
memset(p, 0, (new_cap - LIST.capacity) * sizeof(*LIST.value)); \
LIST.value = new; \
LIST.capacity= new_cap; \
} \
})
#define LIST_SET(LIST, INDEX, VALUE, ONERR) \
( LIST_COND_GROW(LIST, INDEX, ONERR), \
LIST.value[INDEX] = VALUE )
#define LIST_GET(LIST, INDEX, VALUE, ONERR) \
( LIST_COND_GROW(LIST, INDEX, ONERR), \
LIST.value[INDEX] )
struct
moberg_config
{
struct
device_entry
{
struct
device_entry
*
next
;
struct
moberg_device
*
device
;
}
*
device
;
#if 0
struct {
int capacity;
struct analog_in_entry {
struct moberg_device* device;
struct moberg_device_analog_in *channel;
} *value;
} analog_in;
struct {
int capacity;
struct analog_out_entry {
struct moberg_device* device;
struct moberg_device_analog_out *channel;
} *value;
} analog_out;
struct {
int capacity;
struct digital_in_entry {
struct moberg_device* device;
struct moberg_device_digital_in *channel;
} *value;
} digital_in;
struct {
int capacity;
struct digital_out_entry {
struct moberg_device* device;
struct moberg_device_digital_out *channel;
} *value;
} digital_out;
struct {
int capacity;
struct encoder_in_entry {
struct moberg_device* device;
struct moberg_device_encoder_in *channel;
} *value;
} encoder_in;
#endif
}
*
device_head
,
**
device_tail
;
};
struct
moberg_config
*
moberg_config_new
()
...
...
@@ -74,19 +15,8 @@ struct moberg_config *moberg_config_new()
struct
moberg_config
*
result
=
malloc
(
sizeof
*
result
);
if
(
result
)
{
result
->
device
=
NULL
;
#if 0
result->analog_in.capacity = 0;
result->analog_in.value = NULL;
result->analog_out.capacity = 0;
result->analog_out.value = NULL;
result->digital_in.capacity = 0;
result->digital_in.value = NULL;
result->digital_out.capacity = 0;
result->digital_out.value = NULL;
result->encoder_in.capacity = 0;
result->encoder_in.value = NULL;
#endif
result
->
device_head
=
NULL
;
result
->
device_tail
=
&
result
->
device_head
;
}
return
result
;
...
...
@@ -94,31 +24,30 @@ struct moberg_config *moberg_config_new()
void
moberg_config_free
(
struct
moberg_config
*
config
)
{
struct
device_entry
*
entry
=
config
->
device
;
struct
device_entry
*
entry
=
config
->
device
_head
;
while
(
entry
)
{
struct
device_entry
*
tmp
=
entry
;
entry
=
entry
->
next
;
moberg_device_free
(
tmp
->
device
);
free
(
tmp
);
}
#if 0
free(config->analog_in.value);
free(config->analog_out.value);
free(config->digital_in.value);
free(config->digital_out.value);
free(config->encoder_in.value);
#endif
free
(
config
);
}
int
moberg_config_join
(
struct
moberg_config
*
dest
,
struct
moberg_config
*
src
)
{
if
(
src
&&
dest
)
{
struct
device_entry
**
tail
;
for
(
tail
=
&
dest
->
device
;
*
tail
;
tail
=
&
(
*
tail
)
->
next
)
{
}
*
tail
=
src
->
device
;
src
->
device
=
NULL
;
if
(
src
&&
dest
)
{
while
(
src
->
device_head
)
{
struct
device_entry
*
d
=
src
->
device_head
;
src
->
device_head
=
d
->
next
;
if
(
!
src
->
device_head
)
{
src
->
device_tail
=
&
src
->
device_head
;
}
*
dest
->
device_tail
=
d
;
dest
->
device_tail
=
&
d
->
next
;
}
return
1
;
}
return
0
;
...
...
@@ -129,79 +58,25 @@ int moberg_config_add_device(struct moberg_config *config,
{
struct
device_entry
*
entry
=
malloc
(
sizeof
(
*
entry
));
entry
->
next
=
config
->
device
;
if
(
!
entry
)
{
goto
err
;
}
entry
->
next
=
NULL
;
entry
->
device
=
device
;
config
->
device
=
entry
;
*
config
->
device_tail
=
entry
;
config
->
device_tail
=
&
entry
->
next
;
return
1
;
err:
return
0
;
}
int
moberg_config_install_channels
(
struct
moberg_config
*
config
,
struct
moberg_
install_channels
*
install
)
struct
moberg_
channel_install
*
install
)
{
return
moberg_device_install_channels
(
config
->
device
->
device
,
install
);
int
result
=
1
;
for
(
struct
device_entry
*
d
=
config
->
device_head
;
d
;
d
=
d
->
next
)
{
result
&=
moberg_device_install_channels
(
d
->
device
,
install
);
}
return
result
;
}
#if 0
int moberg_config_add_analog_in(struct moberg_config *config,
int index,
struct moberg_device* device,
struct moberg_device_analog_in *channel)
{
struct analog_in_entry e = { device, channel };
LIST_SET(config->analog_in, index, e, goto err);
return 1;
err:
return 0;
}
int moberg_config_add_analog_out(struct moberg_config *config,
int index,
struct moberg_device* device,
struct moberg_device_analog_out *channel)
{
struct analog_out_entry e = { device, channel };
LIST_SET(config->analog_out, index, e, goto err);
return 1;
err:
return 0;
}
int moberg_config_add_digital_in(struct moberg_config *config,
int index,
struct moberg_device* device,
struct moberg_device_digital_in *channel)
{
struct digital_in_entry e = { device, channel };
LIST_SET(config->digital_in, index, e, goto err);
return 1;
err:
return 0;
}
int moberg_config_add_digital_out(struct moberg_config *config,
int index,
struct moberg_device* device,
struct moberg_device_digital_out *channel)
{
struct digital_out_entry e = { device, channel };
LIST_SET(config->digital_out, index, e, goto err);
return 1;
err:
return 0;
}
int moberg_config_add_encoder_in(struct moberg_config *config,
int index,
struct moberg_device* device,
struct moberg_device_encoder_in *channel)
{
struct encoder_in_entry e = { device, channel };
LIST_SET(config->encoder_in, index, e, goto err);
return 1;
err:
return 0;
}
#endif
moberg_config.h
View file @
25d5b846
...
...
@@ -15,33 +15,6 @@ int moberg_config_add_device(struct moberg_config *config,
struct
moberg_device
*
device
);
int
moberg_config_install_channels
(
struct
moberg_config
*
config
,
struct
moberg_install_channels
*
install
);
#if 0
int moberg_config_add_analog_in(struct moberg_config *config,
int index,
struct moberg_device* device,
struct moberg_device_analog_in *channel);
int moberg_config_add_analog_out(struct moberg_config *config,
int index,
struct moberg_device* device,
struct moberg_device_analog_out *channel);
int moberg_config_add_digital_in(struct moberg_config *config,
int index,
struct moberg_device* device,
struct moberg_device_digital_in *channel);
int moberg_config_add_digital_out(struct moberg_config *config,
int index,
struct moberg_device* device,
struct moberg_device_digital_out *channel);
int moberg_config_add_encoder_in(struct moberg_config *config,
int index,
struct moberg_device* device,
struct moberg_device_encoder_in *channel);
# endif
struct
moberg_channel_install
*
install
);
#endif
moberg_device.c
View file @
25d5b846
...
...
@@ -4,25 +4,26 @@
#include
<dlfcn.h>
#include
<moberg_config.h>
#include
<moberg_device.h>
#include
<moberg_channel.h>
struct
moberg_device
{
void
*
driver_handle
;
struct
moberg_device_driver
driver
;
struct
moberg_device_con
fig
*
device_con
fig
;
struct
moberg_device_con
text
*
device_con
text
;
struct
channel_list
{
struct
channel_list
*
next
;
enum
moberg_channel_kind
kind
;
int
index
;
union
channel
{
struct
moberg_device_analog_in
*
analog_in
;
struct
moberg_device_analog_out
*
analog_out
;
struct
moberg_device_digital_in
*
digital_in
;
struct
moberg_device_digital_out
*
digital_out
;
struct
moberg_device_encoder_in
*
encoder_in
;
struct
moberg_channel_analog_in
*
analog_in
;
struct
moberg_channel_analog_out
*
analog_out
;
struct
moberg_channel_digital_in
*
digital_in
;
struct
moberg_channel_digital_out
*
digital_out
;
struct
moberg_channel_encoder_in
*
encoder_in
;
struct
moberg_channel
*
channel
;
}
u
;
}
*
channel_head
,
**
channel_tail
;
struct
map_range
{
struct
moberg_
config
*
config
;
struct
moberg_
device
*
device
;
enum
moberg_channel_kind
kind
;
int
min
;
int
max
;
...
...
@@ -52,15 +53,21 @@ struct moberg_device *moberg_device_new(const char *driver)
fprintf
(
stderr
,
"Could not allocate result for %s
\n
"
,
name
);
goto
dlclose_driver
;
}
result
->
driver_handle
=
handle
;
result
->
driver
=
*
device_driver
;
result
->
device_config
=
NULL
;
result
->
device_context
=
result
->
driver
.
new
(
dlclose
,
handle
);
if
(
result
->
device_context
)
{
result
->
driver
.
up
(
result
->
device_context
);
}
else
{
fprintf
(
stderr
,
"Could not allocate context for %s
\n
"
,
name
);
goto
free_result
;
}
result
->
channel_head
=
NULL
;
result
->
channel_tail
=
&
result
->
channel_head
;
result
->
range
=
NULL
;
goto
free_name
;
free_result:
free
(
result
);
dlclose_driver:
dlclose
(
handle
);
free_name:
...
...
@@ -78,48 +85,15 @@ void moberg_device_free(struct moberg_device *device)
free
(
channel
);
channel
=
next
;
}
device
->
driver
.
config_free
(
device
->
device_config
);
free
(
device
->
device_config
);
dlclose
(
device
->
driver_handle
);
int
use
=
device
->
driver
.
down
(
device
->
device_context
);
fprintf
(
stderr
,
"USE: %d
\n
"
,
use
);
free
(
device
);
}
int
moberg_device_parse_config
(
struct
moberg_device
*
device
,
struct
moberg_parser_context
*
context
)
{
return
device
->
driver
.
parse_config
(
device
,
context
);
}
int
moberg_device_set_config
(
struct
moberg_device
*
device
,
struct
moberg_device_config
*
config
)
struct
moberg_parser_context
*
parser
)
{
if
(
device
->
device_config
)
{
device
->
driver
.
config_free
(
device
->
device_config
);
free
(
device
->
device_config
);
}
device
->
device_config
=
config
;
return
1
;
}
int
moberg_device_parse_map
(
struct
moberg_device
*
device
,
struct
moberg_config
*
config
,
struct
moberg_parser_context
*
context
,
enum
moberg_channel_kind
kind
,
int
min
,
int
max
)
{
int
result
;
struct
map_range
r
=
{
.
config
=
config
,
.
kind
=
kind
,
.
min
=
min
,
.
max
=
max
};
device
->
range
=
&
r
;
result
=
device
->
driver
.
parse_map
(
device
,
context
,
kind
);
device
->
range
=
NULL
;
printf
(
"RRR %d %d
\n
"
,
r
.
min
,
r
.
max
);
return
result
;
return
device
->
driver
.
parse_config
(
device
->
device_context
,
parser
);
}
static
int
add_channel
(
struct
moberg_device
*
device
,
...
...
@@ -141,7 +115,7 @@ err:
}
int
moberg_device_add_analog_in
(
struct
moberg_device
*
device
,
struct
moberg_
device
_analog_in
*
channel
)
struct
moberg_
channel
_analog_in
*
channel
)
{
int
result
=
0
;
...
...
@@ -156,7 +130,7 @@ int moberg_device_add_analog_in(struct moberg_device* device,
}
int
moberg_device_add_analog_out
(
struct
moberg_device
*
device
,
struct
moberg_
device
_analog_out
*
channel
)
struct
moberg_
channel
_analog_out
*
channel
)
{
int
result
=
0
;
...
...
@@ -171,7 +145,7 @@ int moberg_device_add_analog_out(struct moberg_device* device,
}
int
moberg_device_add_digital_in
(
struct
moberg_device
*
device
,
struct
moberg_
device
_digital_in
*
channel
)
struct
moberg_
channel
_digital_in
*
channel
)
{
int
result
=
0
;
...
...
@@ -186,7 +160,7 @@ int moberg_device_add_digital_in(struct moberg_device* device,
}
int
moberg_device_add_digital_out
(
struct
moberg_device
*
device
,
struct
moberg_
device
_digital_out
*
channel
)
struct
moberg_
channel
_digital_out
*
channel
)
{
int
result
=
0