chelper: Compile with gcc -fwhole-program option
Use the -fwhole-program option when compiling the host C code. This makes it easier to support inlining across C files. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
parent
189ebb4c7d
commit
8a830ff0ce
|
@ -11,7 +11,9 @@ import cffi
|
||||||
# c_helper.so compiling
|
# c_helper.so compiling
|
||||||
######################################################################
|
######################################################################
|
||||||
|
|
||||||
COMPILE_CMD = "gcc -Wall -g -O2 -shared -fPIC -o %s %s"
|
COMPILE_CMD = ("gcc -Wall -g -O2 -shared -fPIC"
|
||||||
|
" -flto -fwhole-program -fno-use-linker-plugin"
|
||||||
|
" -o %s %s")
|
||||||
SOURCE_FILES = ['stepcompress.c', 'serialqueue.c', 'pyhelper.c']
|
SOURCE_FILES = ['stepcompress.c', 'serialqueue.c', 'pyhelper.c']
|
||||||
DEST_LIB = "c_helper.so"
|
DEST_LIB = "c_helper.so"
|
||||||
OTHER_FILES = ['list.h', 'serialqueue.h', 'pyhelper.h']
|
OTHER_FILES = ['list.h', 'serialqueue.h', 'pyhelper.h']
|
||||||
|
@ -56,9 +58,6 @@ defs_serialqueue = """
|
||||||
void serialqueue_free_commandqueue(struct command_queue *cq);
|
void serialqueue_free_commandqueue(struct command_queue *cq);
|
||||||
void serialqueue_send(struct serialqueue *sq, struct command_queue *cq
|
void serialqueue_send(struct serialqueue *sq, struct command_queue *cq
|
||||||
, uint8_t *msg, int len, uint64_t min_clock, uint64_t req_clock);
|
, uint8_t *msg, int len, uint64_t min_clock, uint64_t req_clock);
|
||||||
void serialqueue_encode_and_send(struct serialqueue *sq
|
|
||||||
, struct command_queue *cq, uint32_t *data, int len
|
|
||||||
, uint64_t min_clock, uint64_t req_clock);
|
|
||||||
void serialqueue_pull(struct serialqueue *sq
|
void serialqueue_pull(struct serialqueue *sq
|
||||||
, struct pull_queue_message *pqm);
|
, struct pull_queue_message *pqm);
|
||||||
void serialqueue_set_baud_adjust(struct serialqueue *sq, double baud_adjust);
|
void serialqueue_set_baud_adjust(struct serialqueue *sq, double baud_adjust);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// Helper functions for C / Python interface
|
// Helper functions for C / Python interface
|
||||||
//
|
//
|
||||||
// Copyright (C) 2016 Kevin O'Connor <kevin@koconnor.net>
|
// Copyright (C) 2016-2018 Kevin O'Connor <kevin@koconnor.net>
|
||||||
//
|
//
|
||||||
// This file may be distributed under the terms of the GNU GPLv3 license.
|
// This file may be distributed under the terms of the GNU GPLv3 license.
|
||||||
|
|
||||||
|
@ -10,10 +10,11 @@
|
||||||
#include <stdio.h> // fprintf
|
#include <stdio.h> // fprintf
|
||||||
#include <string.h> // strerror
|
#include <string.h> // strerror
|
||||||
#include <time.h> // struct timespec
|
#include <time.h> // struct timespec
|
||||||
|
#include "compiler.h" // __visible
|
||||||
#include "pyhelper.h" // get_monotonic
|
#include "pyhelper.h" // get_monotonic
|
||||||
|
|
||||||
// Return the monotonic system time as a double
|
// Return the monotonic system time as a double
|
||||||
double
|
double __visible
|
||||||
get_monotonic(void)
|
get_monotonic(void)
|
||||||
{
|
{
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
|
@ -41,7 +42,7 @@ default_logger(const char *msg)
|
||||||
|
|
||||||
static void (*python_logging_callback)(const char *msg) = default_logger;
|
static void (*python_logging_callback)(const char *msg) = default_logger;
|
||||||
|
|
||||||
void
|
void __visible
|
||||||
set_python_logging_callback(void (*func)(const char *))
|
set_python_logging_callback(void (*func)(const char *))
|
||||||
{
|
{
|
||||||
python_logging_callback = func;
|
python_logging_callback = func;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// Serial port command queuing
|
// Serial port command queuing
|
||||||
//
|
//
|
||||||
// Copyright (C) 2016 Kevin O'Connor <kevin@koconnor.net>
|
// Copyright (C) 2016-2018 Kevin O'Connor <kevin@koconnor.net>
|
||||||
//
|
//
|
||||||
// This file may be distributed under the terms of the GNU GPLv3 license.
|
// This file may be distributed under the terms of the GNU GPLv3 license.
|
||||||
//
|
//
|
||||||
|
@ -23,6 +23,7 @@
|
||||||
#include <string.h> // memset
|
#include <string.h> // memset
|
||||||
#include <termios.h> // tcflush
|
#include <termios.h> // tcflush
|
||||||
#include <unistd.h> // pipe
|
#include <unistd.h> // pipe
|
||||||
|
#include "compiler.h" // __visible
|
||||||
#include "list.h" // list_add_tail
|
#include "list.h" // list_add_tail
|
||||||
#include "pyhelper.h" // get_monotonic
|
#include "pyhelper.h" // get_monotonic
|
||||||
#include "serialqueue.h" // struct queue_message
|
#include "serialqueue.h" // struct queue_message
|
||||||
|
@ -797,7 +798,7 @@ background_thread(void *data)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new 'struct serialqueue' object
|
// Create a new 'struct serialqueue' object
|
||||||
struct serialqueue *
|
struct serialqueue * __visible
|
||||||
serialqueue_alloc(int serial_fd, int write_only)
|
serialqueue_alloc(int serial_fd, int write_only)
|
||||||
{
|
{
|
||||||
struct serialqueue *sq = malloc(sizeof(*sq));
|
struct serialqueue *sq = malloc(sizeof(*sq));
|
||||||
|
@ -859,7 +860,7 @@ fail:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Request that the background thread exit
|
// Request that the background thread exit
|
||||||
void
|
void __visible
|
||||||
serialqueue_exit(struct serialqueue *sq)
|
serialqueue_exit(struct serialqueue *sq)
|
||||||
{
|
{
|
||||||
pollreactor_do_exit(&sq->pr);
|
pollreactor_do_exit(&sq->pr);
|
||||||
|
@ -870,7 +871,7 @@ serialqueue_exit(struct serialqueue *sq)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Free all resources associated with a serialqueue
|
// Free all resources associated with a serialqueue
|
||||||
void
|
void __visible
|
||||||
serialqueue_free(struct serialqueue *sq)
|
serialqueue_free(struct serialqueue *sq)
|
||||||
{
|
{
|
||||||
if (!sq)
|
if (!sq)
|
||||||
|
@ -895,7 +896,7 @@ serialqueue_free(struct serialqueue *sq)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocate a 'struct command_queue'
|
// Allocate a 'struct command_queue'
|
||||||
struct command_queue *
|
struct command_queue * __visible
|
||||||
serialqueue_alloc_commandqueue(void)
|
serialqueue_alloc_commandqueue(void)
|
||||||
{
|
{
|
||||||
struct command_queue *cq = malloc(sizeof(*cq));
|
struct command_queue *cq = malloc(sizeof(*cq));
|
||||||
|
@ -906,7 +907,7 @@ serialqueue_alloc_commandqueue(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Free a 'struct command_queue'
|
// Free a 'struct command_queue'
|
||||||
void
|
void __visible
|
||||||
serialqueue_free_commandqueue(struct command_queue *cq)
|
serialqueue_free_commandqueue(struct command_queue *cq)
|
||||||
{
|
{
|
||||||
if (!cq)
|
if (!cq)
|
||||||
|
@ -956,7 +957,7 @@ serialqueue_send_batch(struct serialqueue *sq, struct command_queue *cq
|
||||||
|
|
||||||
// Schedule the transmission of a message on the serial port at a
|
// Schedule the transmission of a message on the serial port at a
|
||||||
// given time and priority.
|
// given time and priority.
|
||||||
void
|
void __visible
|
||||||
serialqueue_send(struct serialqueue *sq, struct command_queue *cq
|
serialqueue_send(struct serialqueue *sq, struct command_queue *cq
|
||||||
, uint8_t *msg, int len, uint64_t min_clock, uint64_t req_clock)
|
, uint8_t *msg, int len, uint64_t min_clock, uint64_t req_clock)
|
||||||
{
|
{
|
||||||
|
@ -988,7 +989,7 @@ serialqueue_encode_and_send(struct serialqueue *sq, struct command_queue *cq
|
||||||
|
|
||||||
// Return a message read from the serial port (or wait for one if none
|
// Return a message read from the serial port (or wait for one if none
|
||||||
// available)
|
// available)
|
||||||
void
|
void __visible
|
||||||
serialqueue_pull(struct serialqueue *sq, struct pull_queue_message *pqm)
|
serialqueue_pull(struct serialqueue *sq, struct pull_queue_message *pqm)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&sq->lock);
|
pthread_mutex_lock(&sq->lock);
|
||||||
|
@ -1022,7 +1023,7 @@ exit:
|
||||||
pthread_mutex_unlock(&sq->lock);
|
pthread_mutex_unlock(&sq->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void __visible
|
||||||
serialqueue_set_baud_adjust(struct serialqueue *sq, double baud_adjust)
|
serialqueue_set_baud_adjust(struct serialqueue *sq, double baud_adjust)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&sq->lock);
|
pthread_mutex_lock(&sq->lock);
|
||||||
|
@ -1030,7 +1031,7 @@ serialqueue_set_baud_adjust(struct serialqueue *sq, double baud_adjust)
|
||||||
pthread_mutex_unlock(&sq->lock);
|
pthread_mutex_unlock(&sq->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void __visible
|
||||||
serialqueue_set_receive_window(struct serialqueue *sq, int receive_window)
|
serialqueue_set_receive_window(struct serialqueue *sq, int receive_window)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&sq->lock);
|
pthread_mutex_lock(&sq->lock);
|
||||||
|
@ -1040,7 +1041,7 @@ serialqueue_set_receive_window(struct serialqueue *sq, int receive_window)
|
||||||
|
|
||||||
// Set the estimated clock rate of the mcu on the other end of the
|
// Set the estimated clock rate of the mcu on the other end of the
|
||||||
// serial port
|
// serial port
|
||||||
void
|
void __visible
|
||||||
serialqueue_set_clock_est(struct serialqueue *sq, double est_freq
|
serialqueue_set_clock_est(struct serialqueue *sq, double est_freq
|
||||||
, double last_clock_time, uint64_t last_clock)
|
, double last_clock_time, uint64_t last_clock)
|
||||||
{
|
{
|
||||||
|
@ -1052,7 +1053,7 @@ serialqueue_set_clock_est(struct serialqueue *sq, double est_freq
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return a string buffer containing statistics for the serial port
|
// Return a string buffer containing statistics for the serial port
|
||||||
void
|
void __visible
|
||||||
serialqueue_get_stats(struct serialqueue *sq, char *buf, int len)
|
serialqueue_get_stats(struct serialqueue *sq, char *buf, int len)
|
||||||
{
|
{
|
||||||
struct serialqueue stats;
|
struct serialqueue stats;
|
||||||
|
@ -1074,7 +1075,7 @@ serialqueue_get_stats(struct serialqueue *sq, char *buf, int len)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract old messages stored in the debug queues
|
// Extract old messages stored in the debug queues
|
||||||
int
|
int __visible
|
||||||
serialqueue_extract_old(struct serialqueue *sq, int sentq
|
serialqueue_extract_old(struct serialqueue *sq, int sentq
|
||||||
, struct pull_queue_message *q, int max)
|
, struct pull_queue_message *q, int max)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// Stepper pulse schedule compression
|
// Stepper pulse schedule compression
|
||||||
//
|
//
|
||||||
// Copyright (C) 2016,2017 Kevin O'Connor <kevin@koconnor.net>
|
// Copyright (C) 2016-2018 Kevin O'Connor <kevin@koconnor.net>
|
||||||
//
|
//
|
||||||
// This file may be distributed under the terms of the GNU GPLv3 license.
|
// This file may be distributed under the terms of the GNU GPLv3 license.
|
||||||
//
|
//
|
||||||
|
@ -229,7 +229,7 @@ check_line(struct stepcompress *sc, struct step_move move)
|
||||||
****************************************************************/
|
****************************************************************/
|
||||||
|
|
||||||
// Allocate a new 'stepcompress' object
|
// Allocate a new 'stepcompress' object
|
||||||
struct stepcompress *
|
struct stepcompress * __visible
|
||||||
stepcompress_alloc(uint32_t max_error, uint32_t queue_step_msgid
|
stepcompress_alloc(uint32_t max_error, uint32_t queue_step_msgid
|
||||||
, uint32_t set_next_step_dir_msgid, uint32_t invert_sdir
|
, uint32_t set_next_step_dir_msgid, uint32_t invert_sdir
|
||||||
, uint32_t oid)
|
, uint32_t oid)
|
||||||
|
@ -247,7 +247,7 @@ stepcompress_alloc(uint32_t max_error, uint32_t queue_step_msgid
|
||||||
}
|
}
|
||||||
|
|
||||||
// Free memory associated with a 'stepcompress' object
|
// Free memory associated with a 'stepcompress' object
|
||||||
void
|
void __visible
|
||||||
stepcompress_free(struct stepcompress *sc)
|
stepcompress_free(struct stepcompress *sc)
|
||||||
{
|
{
|
||||||
if (!sc)
|
if (!sc)
|
||||||
|
@ -328,7 +328,7 @@ set_next_step_dir(struct stepcompress *sc, int sdir)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset the internal state of the stepcompress object
|
// Reset the internal state of the stepcompress object
|
||||||
int
|
int __visible
|
||||||
stepcompress_reset(struct stepcompress *sc, uint64_t last_step_clock)
|
stepcompress_reset(struct stepcompress *sc, uint64_t last_step_clock)
|
||||||
{
|
{
|
||||||
int ret = stepcompress_flush(sc, UINT64_MAX);
|
int ret = stepcompress_flush(sc, UINT64_MAX);
|
||||||
|
@ -340,7 +340,7 @@ stepcompress_reset(struct stepcompress *sc, uint64_t last_step_clock)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Indicate the stepper is in homing mode (or done homing if zero)
|
// Indicate the stepper is in homing mode (or done homing if zero)
|
||||||
int
|
int __visible
|
||||||
stepcompress_set_homing(struct stepcompress *sc, uint64_t homing_clock)
|
stepcompress_set_homing(struct stepcompress *sc, uint64_t homing_clock)
|
||||||
{
|
{
|
||||||
int ret = stepcompress_flush(sc, UINT64_MAX);
|
int ret = stepcompress_flush(sc, UINT64_MAX);
|
||||||
|
@ -351,7 +351,7 @@ stepcompress_set_homing(struct stepcompress *sc, uint64_t homing_clock)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Queue an mcu command to go out in order with stepper commands
|
// Queue an mcu command to go out in order with stepper commands
|
||||||
int
|
int __visible
|
||||||
stepcompress_queue_msg(struct stepcompress *sc, uint32_t *data, int len)
|
stepcompress_queue_msg(struct stepcompress *sc, uint32_t *data, int len)
|
||||||
{
|
{
|
||||||
int ret = stepcompress_flush(sc, UINT64_MAX);
|
int ret = stepcompress_flush(sc, UINT64_MAX);
|
||||||
|
@ -502,7 +502,7 @@ static inline double safe_sqrt(double v) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Schedule a step event at the specified step_clock time
|
// Schedule a step event at the specified step_clock time
|
||||||
int32_t
|
int32_t __visible
|
||||||
stepcompress_push(struct stepcompress *sc, double print_time, int32_t sdir)
|
stepcompress_push(struct stepcompress *sc, double print_time, int32_t sdir)
|
||||||
{
|
{
|
||||||
int ret = set_next_step_dir(sc, !!sdir);
|
int ret = set_next_step_dir(sc, !!sdir);
|
||||||
|
@ -522,7 +522,7 @@ stepcompress_push(struct stepcompress *sc, double print_time, int32_t sdir)
|
||||||
// Otherwise it uses the formula:
|
// Otherwise it uses the formula:
|
||||||
// step_time = (print_time + sqrt(2*step_num/accel + (start_sv/accel)**2)
|
// step_time = (print_time + sqrt(2*step_num/accel + (start_sv/accel)**2)
|
||||||
// - start_sv/accel)
|
// - start_sv/accel)
|
||||||
int32_t
|
int32_t __visible
|
||||||
stepcompress_push_const(
|
stepcompress_push_const(
|
||||||
struct stepcompress *sc, double print_time
|
struct stepcompress *sc, double print_time
|
||||||
, double step_offset, double steps, double start_sv, double accel)
|
, double step_offset, double steps, double start_sv, double accel)
|
||||||
|
@ -672,7 +672,7 @@ _stepcompress_push_delta(
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t
|
int32_t __visible
|
||||||
stepcompress_push_delta(
|
stepcompress_push_delta(
|
||||||
struct stepcompress *sc, double print_time, double move_sd
|
struct stepcompress *sc, double print_time, double move_sd
|
||||||
, double start_sv, double accel
|
, double start_sv, double accel
|
||||||
|
@ -729,7 +729,7 @@ struct steppersync {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Allocate a new 'steppersync' object
|
// Allocate a new 'steppersync' object
|
||||||
struct steppersync *
|
struct steppersync * __visible
|
||||||
steppersync_alloc(struct serialqueue *sq, struct stepcompress **sc_list
|
steppersync_alloc(struct serialqueue *sq, struct stepcompress **sc_list
|
||||||
, int sc_num, int move_num)
|
, int sc_num, int move_num)
|
||||||
{
|
{
|
||||||
|
@ -750,7 +750,7 @@ steppersync_alloc(struct serialqueue *sq, struct stepcompress **sc_list
|
||||||
}
|
}
|
||||||
|
|
||||||
// Free memory associated with a 'steppersync' object
|
// Free memory associated with a 'steppersync' object
|
||||||
void
|
void __visible
|
||||||
steppersync_free(struct steppersync *ss)
|
steppersync_free(struct steppersync *ss)
|
||||||
{
|
{
|
||||||
if (!ss)
|
if (!ss)
|
||||||
|
@ -762,7 +762,7 @@ steppersync_free(struct steppersync *ss)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the conversion rate of 'print_time' to mcu clock
|
// Set the conversion rate of 'print_time' to mcu clock
|
||||||
void
|
void __visible
|
||||||
steppersync_set_time(struct steppersync *ss, double time_offset, double mcu_freq)
|
steppersync_set_time(struct steppersync *ss, double time_offset, double mcu_freq)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -798,7 +798,7 @@ heap_replace(struct steppersync *ss, uint64_t req_clock)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find and transmit any scheduled steps prior to the given 'move_clock'
|
// Find and transmit any scheduled steps prior to the given 'move_clock'
|
||||||
int
|
int __visible
|
||||||
steppersync_flush(struct steppersync *ss, uint64_t move_clock)
|
steppersync_flush(struct steppersync *ss, uint64_t move_clock)
|
||||||
{
|
{
|
||||||
// Flush each stepcompress to the specified move_clock
|
// Flush each stepcompress to the specified move_clock
|
||||||
|
|
Loading…
Reference in New Issue