#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <rc/model.h>
#include <rc/time.h>
#include <rc/start_stop.h>
#define MAXBUF 128
#define TIMEOUT_S 30
#define START_LOG "/var/log/robotcontrol/startup_log.txt"
static int set_gpio_permissions();
static int check_timeout();
static int check_pwm();
static int check_eqep();
static int check_pru();
static uint64_t start_us;
int main()
{
char buf[MAXBUF];
double time;
rc_model_t model;
if(geteuid()!=0){
fprintf(stderr,"ERROR: rc_startup_routine must be run as root\n");
return -1;
}
start_us = rc_nanos_since_boot()/1000;
time = rc_nanos_since_boot()/1000000000.0;
sprintf(buf, "echo 'start time (s): %6.2f' > %s",time,START_LOG);
system(buf);
model = rc_model();
if(model!=MODEL_BB_BLACK_RC && model!=MODEL_BB_BLACK_W_RC && model!=MODEL_BB_BLUE){
if(system("grep -q robotcontrol /boot/uEnv.txt")!=0){
fprintf(stderr,"robotcontrol service can only run on BB Blue, Black, and Black wireless when the robotcontrol device tree is in use.\n");
return 0;
}
}
while(set_gpio_permissions()!=0){
if(check_timeout()){
system("echo 'timeout reached while waiting for gpio driver' >> " START_LOG);
fprintf(stderr,"timeout reached while waiting for gpio driver\n");
return 0;
}
rc_usleep(500000);
}
time = rc_nanos_since_boot()/1000000000.0;
sprintf(buf, "echo 'time (s): %4.2f GPIO loaded' >> %s",time,START_LOG);
system(buf);
while(check_pwm()!=0){
if(check_timeout()){
system("echo 'timeout reached while waiting for pwm driver' >> " START_LOG);
fprintf(stderr,"timeout reached while waiting for pwm driver\n");
return 0;
}
rc_usleep(500000);
}
time = rc_nanos_since_boot()/1000000000.0;
sprintf(buf, "echo 'time (s): %4.2f PWM loaded' >> %s",time,START_LOG);
system(buf);
while(check_eqep()!=0){
if(check_timeout()){
system("echo 'timeout reached while waiting for eQEP driver' >> " START_LOG);
fprintf(stderr,"timeout reached while waiting for eQEP driver\n");
return 0;
}
rc_usleep(500000);
}
time = rc_nanos_since_boot()/1000000000.0;
sprintf(buf, "echo 'time (s): %4.2f eQEP loaded' >> %s",time,START_LOG);
system(buf);
while(check_pru()!=0){
if(check_timeout()){
system("echo 'timeout reached while waiting for PRU remoteproc driver' >> " START_LOG);
fprintf(stderr,"timeout reached while waiting for PRU remoteproc driver\n");
return -1;
}
rc_usleep(500000);
}
time = rc_nanos_since_boot()/1000000000.0;
sprintf(buf, "echo 'time (s): %4.2f PRU loaded' >> %s",time,START_LOG);
system(buf);
printf("robotcontrol startup routine complete\n");
system("echo 'startup routine complete' >> " START_LOG);
return 0;
}
int set_gpio_permissions(){
int ret;
if(access("/dev/gpiochip3",F_OK)!=0){
return -1;
}
if(access("/dev/gpiochip2",F_OK)!=0){
return -1;
}
if(access("/dev/gpiochip1",F_OK)!=0){
return -1;
}
if(access("/dev/gpiochip0",F_OK)!=0){
return -1;
}
ret=system("/bin/chown -R root:gpio /dev/gpiochip* ");
if(ret){
fprintf(stderr,"ERROR setting gpiochip owner, returned %d\n",ret);
}
ret=system("/bin/chmod -R ug+rw /dev/gpiochip* ");
if(ret){
fprintf(stderr,"ERROR setting gpiochip permission, returned %d\n",ret);
}
return 0;
}
int check_timeout()
{
uint64_t new_us = rc_nanos_since_boot()/1000;
int seconds = (new_us-start_us)/1000000;
if(seconds>TIMEOUT_S){
printf("TIMEOUT REACHED\n");
system("echo 'TIMEOUT_REACHED' >> " START_LOG);
return 1;
}
return 0;
}
int check_pwm()
{
if(access("/sys/devices/platform/ocp/48300000.epwmss/48300200.pwm/",F_OK)!=0){
return -1;
}
if(access("/sys/devices/platform/ocp/48302000.epwmss/48302200.pwm/",F_OK)!=0){
return -1;
}
if(access("/sys/devices/platform/ocp/48304000.epwmss/48304200.pwm/",F_OK)!=0){
return -1;
}
return 0;
}
int check_eqep()
{
if(access("/sys/devices/platform/ocp/48300000.epwmss/48300180.eqep/enabled", F_OK)){
fprintf(stderr,"missing eqep0\n");
return -1;
}
if(access("/sys/devices/platform/ocp/48302000.epwmss/48302180.eqep/enabled", F_OK)){
fprintf(stderr,"missing eqep0\n");
return -1;
}
if(access("/sys/devices/platform/ocp/48304000.epwmss/48304180.eqep/enabled", F_OK)){
fprintf(stderr,"missing eqep0\n");
return -1;
}
return 0;
}
int check_pru()
{
if(access("/dev/remoteproc/pruss-core0", F_OK)){
return -1;
}
return 0;
}