@Vadimatorikda
Инженер-программист, embedded разработчик

Для чего нужны в CPP системные методы _exit, _open, _read, _write, _lseek, _fstat, _link, _unlink, _stat, _close, _execve, _fork, _getpid, _isatty...?

Заметил, что при сборке проекта для микроконтроллера на C++, при использовании виртуальных функций, new или же методов printf/scanf, требуются следующие системные функции:
void _exit(int i);
int _open(const char *name, int flags, int mode);
int _read(int file, char *ptr, int len);
int _write(int file, char *buffer, unsigned int count);
int _lseek(int file, int ptr, int dir);
int _fstat(int file, struct stat *st);
int _link(char *old, char *new);
int _unlink(char *name);
int _stat(char *file, struct stat *st);
int _close(int file);
int _execve(char *name, char **argv, char **env);
int _fork();
int _getpid();
int _isatty(int file);
int _kill(int pid, int sig);
caddr_t _sbrk(int incr);
int times(struct tm *buf);
int _wait(int *status);


Вопрос, где можно прочитать, для чего каждая функция нужна и при каких условиях они вызываются? Чаще всего я просто подключаю имеющийся с FreeRTOS готовый файл с уже расписанными функциями:
spoiler
/**
 * <b>File:</b> stf_syscalls_minimal.c
 *
 * <b>Project:</b> FreeRTOS.org STM32 demo using Eclipse
 *
 * <b>Description:</b> This is the complete set of system definitions (primarily subroutines) required.
 * It implements the minimal functionality required to allow libc to link, and fail gracefully where OS services
 * are not available.
 *
 * For more information see the newlib documentation at http://sourceware.org/newlib/
 *
 * <b>Cereated:</b> 09/04/2009
 *
 * <dl>
 * <dt><b>Autor</b>:</dt>
 * <dd>Stefano Oliveri</dd>
 * <dt><b>E-mail:</b></dt>
 * <dd>software@stf12.net</dd>
 * </dl>
 */

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <time.h>
#include <sys/stat.h>

// Function declaration.
void _exit(int i);
int _open(const char *name, int flags, int mode);
int _read(int file, char *ptr, int len);
int _write(int file, char *buffer, unsigned int count);
int _lseek(int file, int ptr, int dir);
int _fstat(int file, struct stat *st);
int _link(char *old, char *new);
int _unlink(char *name);
int _stat(char *file, struct stat *st);
int _close(int file);
int _execve(char *name, char **argv, char **env);
int _fork();
int _getpid();
int _isatty(int file);
int _kill(int pid, int sig);
caddr_t _sbrk(int incr);
int times(struct tm *buf);
int _wait(int *status);

#undef errno
extern int errno;
char *__env[1] = {0};
char **__environ = __env;
extern unsigned int _heap;
extern unsigned int _eheap;
static caddr_t heap = NULL;


// Function definition.

void _exit(int i)
{
	printf("Program exit with code %d", i);
	while (1);
}

int putChar(int ch);

int _write(int file, char *buffer, unsigned int count)
{
	register unsigned int i;
	for (i = 0; i < count; ++i) {
		putChar(*buffer++);
	}

	return count;
}

int _close(int file)
{
	return -1;
}

int _fstat(int file, struct stat *st)
{
	st->st_mode = S_IFCHR;
	return 0;
}

int _isatty(int file)
{
	return 1;
}

int _lseek(int file, int ptr, int dir)
{
	return 0;
}

int _read(int file, char *ptr, int len)
{
	return 0;
}

caddr_t _sbrk(int incr)
{
	caddr_t prevHeap;
	caddr_t nextHeap;

	if (heap == NULL)
	{ // first allocation
		heap = (caddr_t) & _heap;
	}

	prevHeap = heap;

	// Always return data aligned on a 8 byte boundary
	nextHeap = (caddr_t) (((unsigned int) (heap + incr) + 7) & ~7);

	// Check enough space and there is no collision with stack coming the other way
	// if stack is above start of heap
	if (nextHeap >= (caddr_t) & _eheap)
	{
		errno = ENOMEM;
		return NULL; // error - no more memory
	}
	else
	{
		heap = nextHeap;
		return (caddr_t) prevHeap;
	}
}

int _open(const char *name, int flags, int mode)
{
	return -1;
}

int _link(char *old, char *new)
{
	errno = EMLINK;
	return -1;
}

int _unlink(char *name)
{
	errno = ENOENT;
	return -1;
}

int _stat(char *file, struct stat *st)
{
	st->st_mode = S_IFCHR;
	return 0;
}

int _execve(char *name, char **argv, char **env)
{
	errno = ENOMEM;
	return -1;
}

int _fork()
{
	errno = EAGAIN;
	return -1;
}

int _getpid()
{
	return 1;
}

int _kill(int pid, int sig)
{
	errno = EINVAL;
	return (-1);
}

int times(struct tm *buf)
{
	return -1;
}

int _wait(int *status)
{
	errno = ECHILD;
	return -1;
}
Однако интересно узнать, что каждая из них означает, чтобы переделать под себя что-то.
  • Вопрос задан
  • 541 просмотр
Решения вопроса 1
pi314
@pi314
Президент Солнечной системы и окрестностей
Вот интересно, для кого товарищ Стефано Оливери старался писать комментарий? Там же все черным по-английскио написано. Это - минимальная имплементация функций, которые libc ожидает от системы. Подробнее: раз, два, и уж совершенно конкретно, три. Последнее находится в три клика по ссылке из комментария ))
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
RiseOfDeath
@RiseOfDeath
Диванный эксперт.
void _exit(int i);//Завершение программы. Не актуально для контроллера (если только у вас нет системы или какого-нибудь "менеджера процессов") - сделайте бесконечный цикл или рестарт
int _open(const char *name, int flags, int mode); //открытие файла или устройства, типа UART
int _read(int file, char *ptr, int len); //Чтение из файла или устройства, типа UART
int _write(int file, char *buffer, unsigned int count); //Запись в файл или устройство, типа UART
int _lseek(int file, int ptr, int dir);//Честно говоря не помню, кажется перемещение "текущей" позиции чтения/записи в файле
int _fstat(int file, struct stat *st);//Смотрите что делает аналогичная функция в стандартной библиотеке, я точно не помню, но что-то с получением инфы о файле/устройстве
int _link(char *old, char *new); //
int _unlink(char *name); //Если не ошибаюсь, удаление ссылки на файл (если она последняя - то удаление самого файла)
int _stat(char *file, struct stat *st);//ХЗ, не помню
int _close(int file);//Закрытие файла/устройства
int _execve(char *name, char **argv, char **env);//хз
int _fork();//Форк процесса. (см. выше про процессы)
int _getpid(); //Получение ID процесса (см. выше про процессы)
int _isatty(int file);//Судя по названию - проверка является-ли файл терминалом (фактически для контроллера проверка на UART)
int _kill(int pid, int sig);//Убийство процесса (см. выше про процессы)
caddr_t _sbrk(int incr);//хз
int times(struct tm *buf);//хз
int _wait(int *status);//Ожидание завершения потока (см. выше про процессы)


p.s.

Ну и это не "готовый файл с расписанными функциями", там все функции кроме read/write и exit - тупо заглушки
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы