41 static int mainline_epoll_fd;
47 static int rtPriority = 2;
48 static void *rt_thread(
void *arg);
49 static pthread_t rt_thread_id;
50 static int rt_thread_epoll_fd;
52 static int rtControlPriority = 80;
53 static void *rt_control_thread(
void *arg);
54 static pthread_t rt_control_thread_id;
55 static int rt_control_thread_epoll_fd;
64 static void periodic_task_init(
struct period_info *pinfo);
65 static void wait_rest_of_period(
struct period_info *pinfo);
67 void configureCANopen(
int nodeId,
int rtPriority,
int CANdevice0Index,
char *CANdevice);
72 static void sigHandler(
int sig) {
79 int main(
int argc,
char *argv[]) {
81 CO_NMT_reset_cmd_t reset = CO_RESET_NOT;
82 bool_t firstRun =
true;
83 bool_t rebootEnable =
false;
84 char CANdevice[10] =
"vcan0";
87 int CANdevice0Index = if_nametoindex(CANdevice);
92 if (signal(SIGINT, sigHandler) == SIG_ERR)
93 CO_errExit(
"Program init - SIGINIT handler creation failed");
94 if (signal(SIGTERM, sigHandler) == SIG_ERR)
95 CO_errExit(
"Program init - SIGTERM handler creation failed");
96 printf(
"starting CANopen device with Node ID %d(0x%02X)", nodeId, nodeId);
98 while (reset != CO_RESET_APP && reset != CO_RESET_QUIT &&
CO_endProgram == 0) {
100 CO_ReturnError_t err;
106 CO->CANmodule[0]->CANnormal =
false;
110 if (CO_init(CANdevice0Index, nodeId, 0) != CO_ERROR_NO) {
112 snprintf(s, 120,
"Communication reset - CANopen initialization failed, err=%d", err);
116 CO_EM_initCallback(CO->em, taskMain_cbSignal);
117 CO_SDO_initCallback(CO->SDO[0], taskMain_cbSignal);
118 CO_SDOclient_initCallback(CO->SDOclient, taskMain_cbSignal);
127 mainline_epoll_fd = epoll_create(4);
128 if (mainline_epoll_fd == -1)
129 CO_errExit(
"Program init - epoll_create mainline failed");
132 taskMain_init(mainline_epoll_fd, &OD_performance[ODA_performance_mainCycleMaxTime]);
134 rt_thread_epoll_fd = epoll_create(2);
135 if (rt_thread_epoll_fd == -1)
136 CO_errExit(
"Program init - epoll_create rt_thread failed");
138 CANrx_taskTmr_init(rt_thread_epoll_fd,
TMR_TASK_INTERVAL_NS, &OD_performance[ODA_performance_timerCycleMaxTime]);
142 if (pthread_create(&rt_thread_id, NULL, rt_thread, NULL) != 0)
143 CO_errExit(
"Program init - rt_thread creation failed");
145 if (rtPriority > 0) {
146 struct sched_param param;
147 param.sched_priority = rtPriority;
148 if (pthread_setschedparam(rt_thread_id, SCHED_FIFO, ¶m) != 0)
149 CO_errExit(
"Program init - rt_thread set scheduler failed");
152 if (pthread_create(&rt_control_thread_id, NULL, rt_control_thread, NULL) != 0)
153 CO_errExit(
"Program init - rt_thread_control creation failed");
155 if (rtPriority > 0) {
156 struct sched_param paramc;
157 paramc.sched_priority = rtControlPriority;
158 if (pthread_setschedparam(rt_control_thread_id, SCHED_FIFO, ¶mc) != 0)
159 CO_errExit(
"Program init - rt_thread set scheduler failed");
162 CO_CANsetNormalMode(CO->CANmodule[0]);
164 reset = CO_RESET_NOT;
172 struct epoll_event ev;
173 ready = epoll_wait(mainline_epoll_fd, &ev, 1, -1);
175 if (errno != EINTR) {
178 }
else if (taskMain_process(ev.data.fd, &reset,
CO_timer1ms)) {
195 if (pthread_join(rt_thread_id, NULL) != 0) {
196 CO_errExit(
"Program end - pthread_join failed");
198 if (pthread_join(rt_control_thread_id, NULL) != 0) {
199 CO_errExit(
"Program end - pthread_join failed");
203 CANrx_taskTmr_close();
205 CO_delete(CANdevice0Index);
206 printf(
"Canopend on %s (nodeId=0x%02X) - finished.\n\n", CANdevice, nodeId);
208 if (rebootEnable && reset == CO_RESET_APP) {
210 if (reboot(LINUX_REBOOT_CMD_RESTART) != 0) {
220 static void *rt_thread(
void *arg) {
222 struct epoll_event ev;
223 int ready = epoll_wait(rt_thread_epoll_fd, &ev, 1, -1);
225 if (errno != EINTR) {
228 }
else if (CANrx_taskTmr_process(ev.data.fd)) {
234 for (i = 0; i < OD_traceEnable && i < CO_NO_TRACE; i++) {
239 if (OD_performance[ODA_performance_timerCycleMaxTime] >
TMR_TASK_OVERFLOW_US && rtPriority > 0 && CO->CANmodule[0]->CANnormal) {
240 CO_errorReport(CO->em, CO_EM_ISR_TIMER_OVERFLOW, CO_EMC_SOFTWARE_INTERNAL, 0x22400000L | OD_performance[ODA_performance_timerCycleMaxTime]);
253 static void *rt_control_thread(
void *arg) {
255 periodic_task_init(&pinfo);
258 wait_rest_of_period(&pinfo);
262 wait_rest_of_period(&pinfo);
267 static void inc_period(
struct period_info *pinfo) {
276 static void periodic_task_init(
struct period_info *pinfo) {
280 clock_gettime(CLOCK_MONOTONIC, &(pinfo->
next_period));
282 static void wait_rest_of_period(
struct period_info *pinfo) {
286 clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &pinfo->
next_period, NULL);
291 if (nodeId < 1 || nodeId > 127) {
292 fprintf(stderr,
"NODE ID outside range (%d)\n", nodeId);
296 if (rtPriority != -1 && (rtPriority < sched_get_priority_min(SCHED_FIFO) || rtPriority > sched_get_priority_max(SCHED_FIFO))) {
297 fprintf(stderr,
"Wrong RT priority (%d)\n", rtPriority);
301 if (CANdevice0Index == 0) {
303 snprintf(s, 120,
"Can't find CAN device \"%s\"", CANdevice);
308 if (CO_OD_RAM.FirstWord != CO_OD_RAM.LastWord) {
309 fprintf(stderr,
"Program init - Canopend- Error in CO_OD_RAM.\n");
318 CO_errorReport(CO->em, CO_EM_GENERIC_SOFTWARE_ERROR, CO_EMC_SOFTWARE_INTERNAL, info);
319 fprintf(stderr,
"canopend generic error: 0x%X\n", info);
void app_programEnd(void)
void CO_errExit(char *msg)
void CO_error(const uint32_t info)
struct timespec next_period
volatile uint32_t CO_timer1ms
void app_communicationReset(void)
void CO_time_init(CO_time_t *tm, CO_SDO_t *SDO, uint64_t *epochTimeBaseMs, uint32_t *epochTimeOffsetMs, uint16_t idx_OD_time)
void CO_time_process(CO_time_t *tm)
uint64_t * epochTimeBaseMs
void app_programControlLoop(void)
Time object, usable for timestamping - Defined in CANOpen code.
void app_programStart(void)
#define TMR_TASK_OVERFLOW_US
#define TMR_TASK_INTERVAL_NS
Task Timer used for the Control Loop.
#define INCREMENT_1MS(var)
void app_programAsync(uint16_t timer1msDiffy)
pthread_mutex_t CO_CAN_VALID_mtx
volatile sig_atomic_t CO_endProgram
int main(int argc, char *argv[])
void configureCANopen(int nodeId, int rtPriority, int CANdevice0Index, char *CANdevice)
uint32_t * epochTimeOffsetMs