268 lines
6.7 KiB
C
268 lines
6.7 KiB
C
/*
|
|
* copro.c
|
|
* Implements Copro's abstraction layer
|
|
*
|
|
* Copyright (C) 2018, STMicroelectronics - All Rights Reserved
|
|
* Author: Vincent Abriou <vincent.abriou@st.com> for STMicroelectronics.
|
|
*
|
|
* License type: GPLv2
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License version 2 as published by
|
|
* the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
* or FITNESS FOR A PARTICULAR PURPOSE.
|
|
* See the GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along with
|
|
* this program. If not, see
|
|
* <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdint.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <sys/ioctl.h>
|
|
#include <termios.h>
|
|
#include <unistd.h>
|
|
#include <errno.h>
|
|
#include <fcntl.h>
|
|
#include <string.h>
|
|
|
|
#include "copro.h"
|
|
|
|
#define MAX_BUF 80
|
|
|
|
/* The file descriptor used to manage our TTY over RPMSG */
|
|
static int mFdRpmsg = -1;
|
|
|
|
int copro_isFwRunning(void)
|
|
{
|
|
int fd;
|
|
size_t byte_read;
|
|
int result = 0;
|
|
unsigned char bufRead[MAX_BUF];
|
|
char *user = getenv("USER");
|
|
if (user && strncmp(user, "root", 4)) {
|
|
system("XTERM=xterm su root -c 'cat /sys/class/remoteproc/remoteproc0/state' > /tmp/remoteproc0_state");
|
|
fd = open("/tmp/remoteproc0_state", O_RDONLY);
|
|
} else {
|
|
fd = open("/sys/class/remoteproc/remoteproc0/state", O_RDONLY);
|
|
}
|
|
if (fd < 0) {
|
|
printf("Error opening remoteproc0/state, err=-%d\n", errno);
|
|
return (errno * -1);
|
|
}
|
|
byte_read = (size_t) read (fd, bufRead, MAX_BUF);
|
|
if (byte_read >= strlen("running")) {
|
|
char* pos = strstr((char*)bufRead, "running");
|
|
if(pos) {
|
|
result = 1;
|
|
}
|
|
}
|
|
close(fd);
|
|
return result;
|
|
}
|
|
|
|
int copro_stopFw(void)
|
|
{
|
|
int fd;
|
|
char *user = getenv("USER");
|
|
if (user && strncmp(user, "root",4)) {
|
|
system("su root -c 'echo stop > /sys/class/remoteproc/remoteproc0/state'");
|
|
return 0;
|
|
}
|
|
fd = open("/sys/class/remoteproc/remoteproc0/state", O_RDWR);
|
|
if (fd < 0) {
|
|
printf("Error opening remoteproc0/state, err=-%d\n", errno);
|
|
return (errno * -1);
|
|
}
|
|
write(fd, "stop", strlen("stop"));
|
|
close(fd);
|
|
return 0;
|
|
}
|
|
|
|
int copro_startFw(void)
|
|
{
|
|
int fd;
|
|
char *user = getenv("USER");
|
|
if (user && strncmp(user, "root",4)) {
|
|
system("su root -c 'echo start > /sys/class/remoteproc/remoteproc0/state'");
|
|
return 0;
|
|
}
|
|
fd = open("/sys/class/remoteproc/remoteproc0/state", O_RDWR);
|
|
if (fd < 0) {
|
|
printf("Error opening remoteproc0/state, err=-%d\n", errno);
|
|
return (errno * -1);
|
|
}
|
|
write(fd, "start", strlen("start"));
|
|
close(fd);
|
|
return 0;
|
|
}
|
|
|
|
int copro_getFwPath(char* pathStr)
|
|
{
|
|
int fd;
|
|
int byte_read;
|
|
char *user = getenv("USER");
|
|
if (user && strncmp(user, "root",4)) {
|
|
system("XTERM=xterm su root -c 'cat /sys/module/firmware_class/parameters/path' > /tmp/parameters_path");
|
|
fd = open("/tmp/parameters_path", O_RDONLY);
|
|
} else {
|
|
fd = open("/sys/module/firmware_class/parameters/path", O_RDONLY);
|
|
}
|
|
if (fd < 0) {
|
|
printf("Error opening firmware_class/parameters/path, err=-%d\n", errno);
|
|
return (errno * -1);
|
|
}
|
|
byte_read = read (fd, pathStr, MAX_BUF);
|
|
close(fd);
|
|
return byte_read;
|
|
}
|
|
|
|
int copro_setFwPath(char* pathStr)
|
|
{
|
|
int fd;
|
|
int result = 0;
|
|
char *user = getenv("USER");
|
|
if (user && strncmp(user, "root",4)) {
|
|
char cmd[1024];
|
|
snprintf(cmd, 1024, "su root -c 'echo %s > /sys/module/firmware_class/parameters/path'", pathStr);
|
|
system(cmd);
|
|
return strlen(pathStr);
|
|
}
|
|
fd = open("/sys/module/firmware_class/parameters/path", O_RDWR);
|
|
if (fd < 0) {
|
|
printf("Error opening firmware_class/parameters/path, err=-%d\n", errno);
|
|
return (errno * -1);
|
|
}
|
|
result = write(fd, pathStr, strlen(pathStr));
|
|
close(fd);
|
|
return result;
|
|
}
|
|
|
|
int copro_getFwName(char* name)
|
|
{
|
|
int fd;
|
|
int byte_read;
|
|
char *user = getenv("USER");
|
|
if (user && strncmp(user, "root",4)) {
|
|
system("XTERM=xterm su root -c 'cat /sys/class/remoteproc/remoteproc0/firmware' > /tmp/remoteproc0_firmware");
|
|
fd = open("/tmp/remoteproc0_firmware", O_RDONLY);
|
|
} else {
|
|
fd = open("/sys/class/remoteproc/remoteproc0/firmware", O_RDWR);
|
|
}
|
|
if (fd < 0) {
|
|
printf("Error opening remoteproc0/firmware, err=-%d\n", errno);
|
|
return (errno * -1);
|
|
}
|
|
byte_read = read (fd, name, MAX_BUF);
|
|
close(fd);
|
|
/* remove \n from the read character */
|
|
return byte_read - 1;
|
|
}
|
|
|
|
int copro_setFwName(char* nameStr)
|
|
{
|
|
int fd;
|
|
int result = 0;
|
|
char *user = getenv("USER");
|
|
if (user && strncmp(user, "root",4)) {
|
|
char cmd[1024];
|
|
snprintf(cmd, 1024, "su root -c 'echo %s > /sys/class/remoteproc/remoteproc0/firmware'", nameStr);
|
|
system(cmd);
|
|
return strlen(nameStr);
|
|
}
|
|
fd = open("/sys/class/remoteproc/remoteproc0/firmware", O_RDWR);
|
|
if (fd < 0) {
|
|
printf("Error opening remoteproc0/firmware, err=-%d\n", errno);
|
|
return (errno * -1);
|
|
}
|
|
result = write(fd, nameStr, strlen(nameStr));
|
|
close(fd);
|
|
return result;
|
|
}
|
|
|
|
int copro_openTtyRpmsg(int modeRaw)
|
|
{
|
|
struct termios tiorpmsg;
|
|
mFdRpmsg = open("/dev/ttyRPMSG0", O_RDWR | O_NOCTTY | O_NONBLOCK);
|
|
if (mFdRpmsg < 0) {
|
|
printf("Error opening ttyRPMSG0, err=-%d\n", errno);
|
|
return (errno * -1);
|
|
}
|
|
/* get current port settings */
|
|
tcgetattr(mFdRpmsg,&tiorpmsg);
|
|
if (modeRaw) {
|
|
tiorpmsg.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP
|
|
| INLCR | IGNCR | ICRNL | IXON);
|
|
tiorpmsg.c_oflag &= ~OPOST;
|
|
tiorpmsg.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
|
|
tiorpmsg.c_cflag &= ~(CSIZE | PARENB);
|
|
tiorpmsg.c_cflag |= CS8;
|
|
} else {
|
|
/* ECHO off, other bits unchanged */
|
|
tiorpmsg.c_lflag &= ~ECHO;
|
|
/*do not convert LF to CR LF */
|
|
tiorpmsg.c_oflag &= ~ONLCR;
|
|
}
|
|
tcsetattr(mFdRpmsg, TCSANOW, &tiorpmsg);
|
|
return 0;
|
|
}
|
|
|
|
int copro_closeTtyRpmsg(void)
|
|
{
|
|
close(mFdRpmsg);
|
|
mFdRpmsg = -1;
|
|
return 0;
|
|
}
|
|
|
|
int copro_writeTtyRpmsg(int len, char* pData)
|
|
{
|
|
int result = 0;
|
|
if (mFdRpmsg < 0) {
|
|
printf("Error writing ttyRPMSG0, fileDescriptor is not set\n");
|
|
return mFdRpmsg;
|
|
}
|
|
result = write(mFdRpmsg, pData, len);
|
|
return result;
|
|
}
|
|
|
|
int copro_readTtyRpmsg(int len, char* pData)
|
|
{
|
|
int byte_rd, byte_avail;
|
|
int result = 0;
|
|
if (mFdRpmsg < 0) {
|
|
printf("Error reading ttyRPMSG0, fileDescriptor is not set\n");
|
|
return mFdRpmsg;
|
|
}
|
|
ioctl(mFdRpmsg, FIONREAD, &byte_avail);
|
|
if (byte_avail > 0) {
|
|
if (byte_avail >= len) {
|
|
byte_rd = read (mFdRpmsg, pData, len);
|
|
} else {
|
|
byte_rd = read (mFdRpmsg, pData, byte_avail);
|
|
}
|
|
/*printf("copro_readTtyRpmsg, read successfully %d bytes to %p, [0]=0x%x\n", byte_rd, pData, pData[0]);*/
|
|
result = byte_rd;
|
|
} else {
|
|
result = 0;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
char copro_computeCRC(char *bb, int size)
|
|
{
|
|
short sum = 0;
|
|
|
|
for (int i = 0; i < size - 1; i++)
|
|
sum += (bb[i] & 0xFF);
|
|
|
|
char res = (char) (sum & 0xFF);
|
|
res += (char) (sum >> 8);
|
|
return res;
|
|
}
|