Commit add3fa41 authored by Jeroen Vreeken's avatar Jeroen Vreeken
Browse files

Fix stupid null pointer in ethercat time code.

Add realloc function to controller_mem
Move reallocs in blocks to new controller_mem functions
Add test case for block_state_machine.
parent d0a8fcc9
......@@ -124,8 +124,8 @@ static void ensure_state(struct controller_block *sm, uint32_t state)
return;
}
priv->state_table = realloc(priv->state_table,
sizeof(struct state) * (priv->state_nr + 1));
priv->state_table = controller_mem_realloc(CONTROLLER_MEM_PERIODIC_READ,
priv->state_table, sizeof(struct state) * (priv->state_nr + 1));
memset(priv->state_table + priv->state_nr, 0, sizeof(struct state));
priv->state_table[priv->state_nr].state = state;
......@@ -177,7 +177,8 @@ static void add_transition(struct controller_block *sm,
to_statenr = get_state(sm, to);
nr = priv->state_table[statenr].transition_nr;
priv->state_table[statenr].transitions = realloc(
priv->state_table[statenr].transitions = controller_mem_realloc(
CONTROLLER_MEM_PERIODIC_READ,
priv->state_table[statenr].transitions,
sizeof(struct transition) * (nr + 1));
priv->state_table[statenr].transitions[nr].in = controller_mem_calloc(
......
trigger {
{ "immediate" }
}
blocks (10.0, 0.0) {
{ "state_machine", "sm", 2, 3 }
{ "test_input_bool", "reset" }
{ "test_input_bool", "in0" }
{ "test_input_bool", "in1" }
{ "test_output_uint32", "state" }
{ "test_output_bool", "out0" }
{ "test_output_bool", "out1" }
{ "test_output_bool", "out2" }
}
links {
{ "reset", "value", "sm", "reset", true }
{ "in0", "value", "sm", "in0", true }
{ "in1", "value", "sm", "in1", true }
{ "sm", "state", "state", "value", true }
{ "sm", "out0", "out0", "value", true }
{ "sm", "out1", "out1", "value", true }
{ "sm", "out2", "out2", "value", true }
}
params {
{ "reset", "value", 3, (int) { true, true, false } }
{ "in0", "value", 40,
(int) { true, true, true, true, true,
true, true, true, true, true,
true, true, true, true, true,
true, true, true, true, true,
false, false, false, false, false,
false, false, false, false, false,
false, false, false, false, false,
false, false, false, false, false } }
{ "in1", "value", 40,
(int) { false, false, false, false, false,
false, false, false, false, false,
false, false, false, false, false,
false, false, false, false, false,
false, false, false, false, false,
false, false, false, false, false,
false, false, false, false, false,
false, false, false, true, false } }
{ "sm", "state", 0, (int) { 0, 0, 0 } }
{ "sm", "state", 1, (int) { 0, 0, 1 } }
{ "sm", "state", 2, (int) { 0, 1, 0 } }
{ "sm", "state", 3, (int) { 0, 1, 1 } }
{ "sm", "state", 4, (int) { 1, 0, 0 } }
{ "sm", "state", 5, (int) { 1, 0, 1 } }
{ "sm", "state", 6, (int) { 1, 1, 0 } }
{ "sm", "state", 7, (int) { 1, 1, 1 } }
{ "sm", "transition", 0, 1, (int) { 1, 0 }, (int) { 1, 1 } }
{ "sm", "transition", 1, 2, (int) { 1, 0 }, (int) { 1, 1 } }
{ "sm", "transition", 2, 3, (int) { 1, 0 }, (int) { 1, 1 } }
{ "sm", "transition", 3, 4, (int) { 1, 0 }, (int) { 1, 1 } }
{ "sm", "transition", 4, 5, (int) { 1, 0 }, (int) { 1, 1 } }
{ "sm", "transition", 5, 6, (int) { 1, 0 }, (int) { 1, 1 } }
{ "sm", "transition", 6, 7, (int) { 1, 0 }, (int) { 1, 1 } }
{ "sm", "transition", 7, 0, (int) { 1, 0 }, (int) { 1, 1 } }
{ "sm", "transition", 0, 7, (int) { 0, 0 }, (int) { 1, 1 } }
{ "sm", "transition", 1, 0, (int) { 0, 0 }, (int) { 1, 1 } }
{ "sm", "transition", 2, 1, (int) { 0, 0 }, (int) { 1, 1 } }
{ "sm", "transition", 3, 2, (int) { 0, 0 }, (int) { 1, 1 } }
{ "sm", "transition", 4, 3, (int) { 0, 0 }, (int) { 1, 1 } }
{ "sm", "transition", 5, 4, (int) { 0, 0 }, (int) { 1, 1 } }
{ "sm", "transition", 6, 5, (int) { 0, 0 }, (int) { 1, 1 } }
{ "sm", "transition", 7, 6, (int) { 0, 0 }, (int) { 1, 1 } }
{ "state", "value", 40,
(int) { 0, 0, 1, 2, 3, 4, 5, 6, 7, 0,
1, 2, 3, 4, 5, 6, 7, 0, 1, 2,
1, 0, 7, 6, 5, 4, 3, 2, 1, 0,
7, 6, 5, 4, 3, 2, 1, 0, 0, 7 } }
{ "out0", "value", 40,
(int) { 0, 0, 0, 0, 0, 1, 1, 1, 1, 0,
0, 0, 0, 1, 1, 1, 1, 0, 0, 0,
0, 0, 1, 1, 1, 1, 0, 0, 0, 0,
1, 1, 1, 1, 0, 0, 0, 0, 0, 4 } }
{ "out1", "value", 40,
(int) { 0, 0, 0, 1, 1, 0, 0, 1, 1, 0,
0, 1, 1, 0, 0, 1, 1, 0, 0, 1,
0, 0, 1, 1, 0, 0, 1, 1, 0, 0,
1, 1, 0, 0, 1, 1, 0, 0, 0, 1 } }
{ "out2", "value", 40,
(int) { 0, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 0, 1 } }
}
......@@ -158,7 +158,9 @@ static int param_set_traject(struct controller_block *player, int argc, va_list
traject_nr = findtraject(priv, traject.nr);
if (traject_nr == priv->nr) {
priv->trajectories = realloc(priv->trajectories,
priv->trajectories = controller_mem_realloc(
CONTROLLER_MEM_PERIODIC_READ,
priv->trajectories,
sizeof(struct block_trajectplayer_param *) *
priv->nr + 1);
priv->trajectories[priv->nr] = controller_mem_calloc(
......@@ -168,10 +170,12 @@ static int param_set_traject(struct controller_block *player, int argc, va_list
priv->trajectories[traject_nr]->nr = traject.nr;
}
priv->trajectories[traject_nr]->len = traject.len;
priv->trajectories[traject_nr]->position = realloc(
priv->trajectories[traject_nr]->position = controller_mem_realloc(
CONTROLLER_MEM_PERIODIC_READ,
priv->trajectories[traject_nr]->position,
sizeof(float) * traject.len);
priv->trajectories[traject_nr]->time = realloc(
priv->trajectories[traject_nr]->time = controller_mem_realloc(
CONTROLLER_MEM_PERIODIC_READ,
priv->trajectories[traject_nr]->time,
sizeof(float) * traject.len);
memcpy(priv->trajectories[traject_nr]->position,
......
......@@ -91,5 +91,6 @@ CTRL_TESTS += \
$(DIR)/block_setpoint_generator_1d.test.ctrl \
$(DIR)/block_setpoint_generator_3d.test.ctrl \
$(DIR)/block_servo_state.test.ctrl \
$(DIR)/block_state_machine.test.ctrl \
$(DIR)/block_quantize.test.ctrl
......@@ -194,7 +194,7 @@ void controller_block_add(struct controller_block *newblock)
log_send(LOG_T_DEBUG, "\tParams:");
struct controller_block_param_list *entry;
for (entry = newblock->param; entry; entry = entry->next)
log_send(LOG_T_DEBUG, "\t\t%d\t%s%s", i,
log_send(LOG_T_DEBUG, "\t\t%s%s",
entry->name, entry->sample ? " (SAMPLE)" : "");
nr_blocks++;
......
......@@ -153,6 +153,80 @@ void *controller_mem_calloc(int flags, size_t nmemb, size_t size)
return ptr;
}
void *controller_mem_realloc(int flags, void *ptr, size_t size)
{
if (!size) {
controller_mem_free(ptr);
return NULL;
}
if (!ptr) {
return controller_mem_calloc(flags, 1, size);
}
struct controller_mem_block *block;
struct controller_mem_chunk *chunk;
for (block = blocks; block; block = block->next) {
for (chunk = block->chunks; chunk; chunk = chunk->next) {
if ((char *)block->base + chunk->off == ptr) {
if (size == chunk->len)
return ptr;
if (size < chunk->len) {
if (!chunk->next || chunk->next->used) {
struct controller_mem_chunk *next;
next = calloc(1, sizeof(*next));
if (!next)
break;
next->next = chunk->next;
next->off = chunk->off + chunk->len;
next->len = 0;
}
size_t nlen = chunk->len - size;
chunk->next->len += nlen;
chunk->next->off -= nlen;
chunk->len = size;
return ptr;
}
if (size > chunk->len &&
chunk->next && !chunk->next->used &&
chunk->next->len + chunk->len >= size) {
size_t nnew = size - chunk->len;
chunk->next->len -= nnew;
chunk->next->off += nnew;
chunk->len += nnew;
if (chunk->next->len == 0) {
void *fptr = chunk->next;
chunk->next = chunk->next->next;
free(fptr);
}
return ptr;
}
break;
}
}
if (chunk)
break;
}
if (!chunk) {
return realloc(ptr, size);
}
/* no luck */
void *newptr = controller_mem_calloc(flags, 1, size);
memcpy(newptr, ptr, chunk->len);
controller_mem_free(ptr);
return newptr;
}
void controller_mem_free(void *ptr)
{
struct controller_mem_block *block;
......
......@@ -24,6 +24,7 @@
#define CONTROLLER_MEM_PERIODIC_READ 2
void *controller_mem_calloc(int flags, size_t nmemb, size_t size);
void *controller_mem_realloc(int flags, void *ptr, size_t size);
void controller_mem_free(void *);
#endif /* _INCLUDE_CONTROLLER_MEM_H_ */
......@@ -182,9 +182,9 @@ static struct controller_block * block_beckhoff_el1xxx_create(char *name, int ar
sizeof(struct controller_block_private));
block->private->dev = esc;
esc_esi_device_fill(esc);
esc->block = block;
esc->block_rx = block;
esc_esi_device_fill(esc);
esc->callback_rx = callback_rx;
esc_device_initialize_operational(esc);
......
......@@ -197,10 +197,10 @@ static struct controller_block * block_beckhoff_el2502_create(char *name, int ar
if (!block)
return NULL;
esc_esi_device_fill(esc);
esc->block = block;
esc->block_tx = block;
esc->block_rx = block;
esc_esi_device_fill(esc);
esc->callback_tx = callback_tx;
esc->pre_operational_hook = pre_operational_hook;
......
......@@ -183,9 +183,9 @@ static struct controller_block * block_beckhoff_el2xxx_create(char *name, int ar
sizeof(struct controller_block_private));
block->private->dev = esc;
esc_esi_device_fill(esc);
esc->block = block;
esc->block_tx = block;
esc_esi_device_fill(esc);
esc->callback_tx = callback_tx;
esc_device_initialize_operational(esc);
......
......@@ -465,9 +465,9 @@ static struct controller_block * block_beckhoff_el3xxx_create(char *name, int ar
return NULL;
block->private->dev = esc;
esc_esi_device_fill(esc);
esc->block = block;
esc->block_rx = block;
esc_esi_device_fill(esc);
esc->callback_rx = callback_rx;
esc->pre_operational_hook = pre_operational_hook;
......
......@@ -486,9 +486,9 @@ static struct controller_block * block_beckhoff_el4xxx_create(char *name, int ar
return NULL;
block->private->dev = esc;
esc_esi_device_fill(esc);
esc->block = block;
esc->block_tx = block;
esc_esi_device_fill(esc);
esc->callback_tx = callback_tx;
esc->pre_operational_hook = pre_operational_hook;
......
......@@ -108,9 +108,9 @@ static struct controller_block * block_beckhoff_el5001_create(char *name, int ar
return NULL;
block->private->dev = esc;
esc_esi_device_fill(esc);
esc->block = block;
esc->block_rx = block;
esc_esi_device_fill(esc);
esc->callback_rx = callback_rx;
esc->pre_operational_hook = pre_operational_hook;
......
......@@ -177,13 +177,13 @@ static struct controller_block * block_beckhoff_el5101_create(char *name, int ar
return NULL;
block->private->dev = esc;
esc->block = block;
esc->block_tx = block;
esc->block_rx = block;
esc_esi_device_fill(esc);
esc->dc_sync.sync0_active = false;
esc->block = block;
esc->block_tx = block;
esc->block_rx = block;
esc->callback_tx = callback_tx;
esc->callback_rx = callback_rx;
esc->pre_operational_hook = pre_operational_hook;
......
......@@ -652,10 +652,10 @@ static struct controller_block * block_beckhoff_el7031_create(char *name, int ar
return NULL;
block->private->esc = esc;
esc_esi_device_fill(esc);
esc->block = block;
esc->block_rx = block;
esc->block_tx = block;
esc_esi_device_fill(esc);
esc->client_tx->callback = callback_tx;
esc->client_rx->callback = callback_rx;
esc->pre_operational_hook = pre_operational_hook;
......
......@@ -659,10 +659,10 @@ static struct controller_block *block_stoeber_create(char *name, int argc, va_li
private->brake_resistor = brake_resistor;
private->brake_power = brake_power;
esc_esi_device_fill(esc);
esc->block = stoeber;
esc->block_tx = stoeber_tx;
esc->block_rx = stoeber_rx;
esc_esi_device_fill(esc);
esc->callback_tx = callback_tx;
esc->callback_rx = callback_rx;
esc->pre_operational_hook = pre_operational_hook;
......
......@@ -393,8 +393,12 @@ static int esc_esi_device_fill_dc(struct esc_device *dev)
int i, nr;
double period;
uint32_t period_cycle;
struct controller_time *t = NULL;
period = controller_time_period_get(dev->block_tx->time);
if (dev->block)
t = dev->block->time;
period = controller_time_period_get(t);
period_cycle = (uint32_t)(period * 1000 * 1000 * 1000);
for (cat = dev->categories;
......
......@@ -91,8 +91,14 @@ int esc_watchdog_init(struct esc_device *dev)
uint8_t val8;
int r = 0;
double timeout_sec;
struct controller_time *t = NULL;
timeout_sec = controller_time_period_get(dev->block_tx->time) * 2;
if (dev->block_tx)
t = dev->block_tx->time;
else if (dev->block)
t = dev->block->time;
timeout_sec = controller_time_period_get(t) * 2;
addr.addr.position.off = ESC_ADDR_MAP_WATCHDOG_COUNTER_PD;
val8 = 0;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment