+5
- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
// Heap memory allocate function (must not be used!)
caddr_t _sbrk(int incr) {
<...>
void some_bastard_called_sbrk();
some_bastard_called_sbrk(); // Produce linker error in case it is used
}
_ATTRIBUTE ((__format__ (__printf__, 1, 2)))
int printf (const char *__restrict format, ...)
{
<маленький трехколесный велосипед>
}
int putchar(int c)
{
<...>
}
int puts(const char *s)
{
<...>
}
_ATTRIBUTE ((__format__ (__printf__, 2, 3)))
int sprintf (char *__restrict s, const char *__restrict format, ...)
{
<...>
}
STM32. Я просто хочу использовать printf для вывода в последовательный порт и не течь. Ведь для этого нужно только реализовать int _write(int file, char *data, int len) и всё. Ой, а почему иногда программа падает где-то в кишках рантайма?
Может, стек переполняется? Да нет, проверил, значения в норме...
Просто стандартная библиотека от ST - это не курсовая ардуинщика, тут все системно, хендлы потоков, дескрипторы устройств и управляющие структуры. При первом обращении printf (и sprintf тоже!) выделяет себе в куче около 400 байт. Замечательное решение, помогающее сэкономить память, если мы не используем стандартный вывод! А куча тут - это просто последовательно заполняемая область памяти, размеры которой задаются в linker script (я вообще 0 указал, я ведь не использую malloc). Проверять выход за пределы кучи мы, конечно, не будем - зачем, когда рядом такая замечательная, никому не нужная область стека.
Да, и если забыть отключить буферизацию setvbuf(stdin/stdout/stderr, NULL, _IONBF, 0); , то он выделит не 400 байт, а килобайт (на контроллере с 8K RAM).
В общем, ах, оставьте меня, сам все напишу.
Только надо еще putchar и puts реализовать, а то компилятор любит printf'ы оптимизировать. И не забыть, что puts добавляет перевод строки. Уф, вроде все.
Запостил: Steve_Brown,
05 Августа 2022
j123123 05.08.2022 22:44 # −1
Можешь использовать dprintf, ему никакой "FILE *" с "stdout" не нужен, только "int" с "STDOUT_FILENO"
int dprintf(int fd, const char *format, ...)
Steve_Brown 08.08.2022 14:44 # 0
EDIT: Ну да: undefined reference to `some_bastard_called_sbrk'
guest6 05.08.2022 23:58 # −10
sbrk вроде и правда не нужен, нужно ммапить в кучу
А вместо машинерии printf можно срать сисколом прямо в stdout (итебе еще повезло что там С++ с cout нет)
зы: циферки вон уже принес расщирение позиксовое, которое реализует сёмантику printf, но без CRT а поверх прямо голово write
bormand 06.08.2022 07:27 # −10
На контроллере без MMU?
guest6 06.08.2022 17:52 # −10
без мму бркают наверное. Ну типа вот у нас есть память, вот отсюда до сюда стек, потом брк, потом хип. Брк туда сюда двигают, и текут
так?
bormand 06.08.2022 17:53 # −10
guest6 06.08.2022 17:58 # −10
а так можно динамически в рантайме выбирать, что под стек что под кучу
bormand 06.08.2022 18:08 # −10
Какая надёжность )))
З.Ы. Это тебе не интел, там у стека ограничителей обычно нету. Разве что через MPU навертеть, но он не везде есть.
CMEPTb 08.08.2022 15:40 # 0
Steve_Brown 08.08.2022 15:10 # 0
А сисколлы ты тут сам реализуешь. Рантайм же не знает, в какой порт ты срешь (а, может, вообще по SPI передаешь), так что пишешь какой-нибудь MySerialOutputChar(char c) { while (!TRANSMIT_BUF_EMPTY()); TRANSMIT(c); } , ну а если printf хочешь использовать, то подсовываешь ему _write(<...>) { while (len--) MySerialOutputChar(*data++); } и все типа работает.
Ну, можно, конечно, везде MySerialOutputString понавтыкать, но хотелось же %d%08X.
bormanb 06.08.2022 01:10 # +5
KOPOBA 06.08.2022 02:44 # −1
bormand 06.08.2022 09:09 # −10
bormand 06.08.2022 09:40 # −10
guest6 06.08.2022 10:12 # −10
bormand 06.08.2022 10:22 # −10
bormanb 07.08.2022 16:59 # 0
Rooster 07.08.2022 05:42 # 0
Пишеш закащику: «насяника у мене тут не влезает, нужно конь троллер по лучше»
bormand 07.08.2022 09:04 # −10
Espruino.
Steve_Brown 08.08.2022 15:20 # 0
ISO 06.08.2022 17:48 # −10
Lure_Of_Chaos 04.04.2023 18:16 # 0
Вдруг навстречу ему - здоровенная такая, страхолюдина, и говорит жалостливо:
"Чего орешь, ужин ты мой?.."