Перенос на новую плату
This commit is contained in:
commit
485fc5d856
|
|
@ -0,0 +1,23 @@
|
||||||
|
{
|
||||||
|
"dep": [
|
||||||
|
{
|
||||||
|
"type": "git",
|
||||||
|
"provider": "GONEC_NEW",
|
||||||
|
"repo": "SerialPortInterface"
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"type": "git",
|
||||||
|
"provider": "GONEC_NEW",
|
||||||
|
"repo": "SystemDelayInterface"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"cmake": {
|
||||||
|
"inc_dirs": [
|
||||||
|
"./"
|
||||||
|
],
|
||||||
|
"srcs": [
|
||||||
|
"./**.c"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
#include "stream.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
debug_sprintf (char *buf, int size, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
stream_buf_t u;
|
||||||
|
va_list args;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
stropen (&u, buf, size);
|
||||||
|
va_start (args, fmt);
|
||||||
|
err = vprintf (&u, fmt, args);
|
||||||
|
va_end (args);
|
||||||
|
strclose (&u);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
#include "stream.h"
|
||||||
|
|
||||||
|
int debug_scanf (const unsigned char *buf, const char *fmt, ...) {
|
||||||
|
stream_buf_t u;
|
||||||
|
va_list args;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
stropen (&u, (unsigned char*) buf, 0);
|
||||||
|
va_start (args, fmt);
|
||||||
|
err = vscanf (&u, fmt, args);
|
||||||
|
va_end (args);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef TEST
|
||||||
|
/*
|
||||||
|
* Testing sscanf(3).
|
||||||
|
*/
|
||||||
|
#undef printf
|
||||||
|
int printf (const char *format, ...);
|
||||||
|
|
||||||
|
int
|
||||||
|
main (void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
short s;
|
||||||
|
long l;
|
||||||
|
char a[20], b[20];
|
||||||
|
|
||||||
|
sscanf (" -123 +123 123xyzwvabcdefghijk ", " %d%ho%lx%5c%s",
|
||||||
|
&i, &s, &l, a, b);
|
||||||
|
printf ("i=%d s=%d l=%ld a=`%.5s' b=`%s'\n",
|
||||||
|
i, s, l, a, b);
|
||||||
|
|
||||||
|
sscanf ("abc0123456789xyz", "abc%[0123456789]xyz", a);
|
||||||
|
printf ("a =`%s'\n", a);
|
||||||
|
|
||||||
|
sscanf ("abc0123456789xyz", "abc%[0-9]xyz", a);
|
||||||
|
printf ("a =`%s'\n", a);
|
||||||
|
|
||||||
|
sscanf ("abc0123456789xyz", "abc%[^a-z]xyz", a);
|
||||||
|
printf ("a =`%s'\n", a);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,91 @@
|
||||||
|
#ifndef __STREAM_FAST_H_
|
||||||
|
#define __STREAM_FAST_H_ 1
|
||||||
|
|
||||||
|
#include "SerialPortIO.h"
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#define bool_t int
|
||||||
|
|
||||||
|
#define FETCH_BYTE(p) (*(unsigned char*)(p))
|
||||||
|
|
||||||
|
int debug_printf (tSerialPortIO *portIo, const char *fmt, ...);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Поток данных.
|
||||||
|
* Имеет интерфейс, состоящий из четырех процедур:
|
||||||
|
* выдача байта, опрос последнего выданного байта,
|
||||||
|
* прием байта, и опрос первого байта во входящей очереди без удаления.
|
||||||
|
*/
|
||||||
|
typedef struct _stream_t {
|
||||||
|
struct _stream_interface_t *interface;
|
||||||
|
} stream_t;
|
||||||
|
|
||||||
|
typedef struct _stream_interface_t {
|
||||||
|
void (*putc) (stream_t *u, short c);
|
||||||
|
unsigned short (*getc) (stream_t *u);
|
||||||
|
int (*peekc) (stream_t *u);
|
||||||
|
void (*flush) (stream_t *u);
|
||||||
|
bool_t (*eof) (stream_t *u);
|
||||||
|
void (*close) (stream_t *u);
|
||||||
|
} stream_interface_t;
|
||||||
|
|
||||||
|
#define to_stream(x) ((stream_t*)&(x)->interface)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Методы приходится делать в виде макросов,
|
||||||
|
* т.к. необходимо приведение типа к родительскому.
|
||||||
|
*/
|
||||||
|
#define putchar(x,s) (x)->interface->putc(to_stream (x), s)
|
||||||
|
#define getchar(x) (x)->interface->getc(to_stream (x))
|
||||||
|
#define peekchar(x) (x)->interface->peekc(to_stream (x))
|
||||||
|
#define fflush(x) if ((x)->interface->flush) \
|
||||||
|
(x)->interface->flush(to_stream (x))
|
||||||
|
#define feof(x) ((x)->interface->eof ? \
|
||||||
|
(x)->interface->eof(to_stream (x)) : 0)
|
||||||
|
#define fclose(x) if ((x)->interface->close) \
|
||||||
|
(x)->interface->close(to_stream (x))
|
||||||
|
#define freceiver(x) ((x)->interface->receiver ? \
|
||||||
|
(x)->interface->receiver(to_stream (x)) : 0)
|
||||||
|
|
||||||
|
#define puts(x,str) stream_puts (to_stream (x), str)
|
||||||
|
#define gets(x,str,n) stream_gets (to_stream (x), str, n)
|
||||||
|
#define vprintf(x,f,a) stream_vprintf (to_stream (x), f, a)
|
||||||
|
#define vscanf(x,f,a) stream_vscanf (to_stream (x), f, a)
|
||||||
|
|
||||||
|
/* LY: умышленно вызываем ошибки там, где без необходимости вместо puts() используется printf() */
|
||||||
|
#define printf(x,f,...) stream_printf (to_stream (x), f, ##__VA_ARGS__)
|
||||||
|
|
||||||
|
void drain_input (stream_t *u); /* LY: чистит забуферизированный в потоке ввод. */
|
||||||
|
int stream_puts (stream_t *u, const char *str);
|
||||||
|
unsigned char *stream_gets (stream_t *u, unsigned char *str, int len);
|
||||||
|
//int stream_printf (stream_t *u, const char *fmt, ...);
|
||||||
|
int stream_vprintf (stream_t *u, const char *fmt, va_list args);
|
||||||
|
|
||||||
|
int stream_scanf (stream_t *u, const char *fmt, ...);
|
||||||
|
int stream_vscanf (stream_t *u, const char *fmt, va_list argp);
|
||||||
|
|
||||||
|
int debug_sprintf (char *buf, int size, const char *fmt, ...);
|
||||||
|
//int vsnprintf (unsigned char *buf, int size, const char *fmt, va_list args);
|
||||||
|
int stream_serial_vprintf (tSerialPortIO *stream, char const *fmt, va_list args);
|
||||||
|
int debug_scanf (const unsigned char *buf, const char *fmt, ...);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Вывод в строку как в поток.
|
||||||
|
* Для snprintf и т.п.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
const stream_interface_t *interface;
|
||||||
|
unsigned char *buf;
|
||||||
|
int size;
|
||||||
|
} stream_buf_t;
|
||||||
|
|
||||||
|
stream_t *stropen (stream_buf_t *u, unsigned char *buf, int size);
|
||||||
|
void strclose (stream_buf_t *u);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* LY: выдает результат vprintf без печати, т.е. считает кол-во символов.
|
||||||
|
*/
|
||||||
|
int vprintf_getlen (const char *fmt, va_list args);
|
||||||
|
extern stream_t null_stream;
|
||||||
|
|
||||||
|
#endif /* __STREAM_FAST_H_ */
|
||||||
|
|
@ -0,0 +1,81 @@
|
||||||
|
#include "stream.h"
|
||||||
|
|
||||||
|
static void
|
||||||
|
buf_putchar (stream_buf_t *u, short c)
|
||||||
|
{
|
||||||
|
if (u->size > 1) {
|
||||||
|
/* TODO: unicode to utf8 conversion. */
|
||||||
|
*u->buf++ = c;
|
||||||
|
--u->size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned short
|
||||||
|
buf_getchar (stream_buf_t *u)
|
||||||
|
{
|
||||||
|
/* TODO: utf8 to unicode conversion. */
|
||||||
|
unsigned char c = *u->buf;
|
||||||
|
|
||||||
|
if (! c)
|
||||||
|
return 0;
|
||||||
|
++u->buf;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
buf_peekchar (stream_buf_t *u)
|
||||||
|
{
|
||||||
|
/* TODO: utf8 to unicode conversion. */
|
||||||
|
unsigned char c = *u->buf;
|
||||||
|
|
||||||
|
if (! c)
|
||||||
|
return -1;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool_t
|
||||||
|
buf_feof (stream_buf_t *u)
|
||||||
|
{
|
||||||
|
return ! *u->buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
static stream_interface_t buf_interface = {
|
||||||
|
.putc =
|
||||||
|
#if __STDC__
|
||||||
|
(void (*) (stream_t*, short))
|
||||||
|
#endif
|
||||||
|
buf_putchar,
|
||||||
|
.getc =
|
||||||
|
#if __STDC__
|
||||||
|
(unsigned short (*) (stream_t*))
|
||||||
|
#endif
|
||||||
|
buf_getchar,
|
||||||
|
.peekc =
|
||||||
|
#if __STDC__
|
||||||
|
(int (*) (stream_t*))
|
||||||
|
#endif
|
||||||
|
buf_peekchar,
|
||||||
|
.eof =
|
||||||
|
#if __STDC__
|
||||||
|
(bool_t (*) (stream_t*))
|
||||||
|
#endif
|
||||||
|
buf_feof,
|
||||||
|
};
|
||||||
|
|
||||||
|
stream_t *
|
||||||
|
stropen (stream_buf_t *u, unsigned char *buf, int size)
|
||||||
|
{
|
||||||
|
u->interface = &buf_interface;
|
||||||
|
u->buf = buf;
|
||||||
|
u->size = size;
|
||||||
|
return (stream_t*) u;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
strclose (stream_buf_t *u)
|
||||||
|
{
|
||||||
|
if (u->size > 0) {
|
||||||
|
*u->buf++ = 0;
|
||||||
|
--u->size;
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,276 @@
|
||||||
|
|
||||||
|
#include "cmsis_os.h"
|
||||||
|
#include "SerialPortIO.h"
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include "SystemDelayInterface.h"
|
||||||
|
//#include "BaseTypes.h"
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include "stream.h"
|
||||||
|
|
||||||
|
#define SHORT 0
|
||||||
|
#define REGULAR 1
|
||||||
|
#define LONG 2
|
||||||
|
|
||||||
|
#define ISSPACE(c) (c==' ' || c=='\t' || c=='\n')
|
||||||
|
#define ISDIGIT(c,base) ((c>='0' && c<='9') || (base==16 && \
|
||||||
|
(('a'<=c && c<='f') || ('A'<=c && c<='F'))))
|
||||||
|
|
||||||
|
static unsigned char
|
||||||
|
scan_number (stream_t *stream, void *ptr, unsigned char base,
|
||||||
|
unsigned short len, unsigned char size)
|
||||||
|
{
|
||||||
|
int c;
|
||||||
|
long val;
|
||||||
|
unsigned char negate;
|
||||||
|
|
||||||
|
/* Skip spaces. */
|
||||||
|
for (;;) {
|
||||||
|
c = peekchar (stream);
|
||||||
|
if (c < 0)
|
||||||
|
return 0;
|
||||||
|
if (! ISSPACE ((unsigned char) c))
|
||||||
|
break;
|
||||||
|
getchar (stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get sign. */
|
||||||
|
negate = 0;
|
||||||
|
if (c == '-' || c == '+') {
|
||||||
|
if (c == '-')
|
||||||
|
negate = 1;
|
||||||
|
getchar (stream);
|
||||||
|
len--;
|
||||||
|
if (len == 0 || feof (stream))
|
||||||
|
return 0;
|
||||||
|
c = peekchar (stream);
|
||||||
|
}
|
||||||
|
if (! ISDIGIT (c, base))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
val = 0;
|
||||||
|
while (len-- > 0) {
|
||||||
|
/* Scan digits. */
|
||||||
|
if (! ISDIGIT (c, base))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (ptr) {
|
||||||
|
/* Get next digit. */
|
||||||
|
if (base == 8) val <<= 3;
|
||||||
|
else if (base == 10) val *= 10;
|
||||||
|
else val <<= 4;
|
||||||
|
|
||||||
|
if ('0' <= c && c <= '9') c -= '0';
|
||||||
|
else if ('a' <= c && c <= 'f') c -= 'a' - 10;
|
||||||
|
else c -= 'A' - 10;
|
||||||
|
|
||||||
|
val += c;
|
||||||
|
}
|
||||||
|
getchar (stream);
|
||||||
|
c = peekchar (stream);
|
||||||
|
if (c < 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (! ptr)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (negate)
|
||||||
|
val = -val;
|
||||||
|
|
||||||
|
switch (size) {
|
||||||
|
case SHORT:
|
||||||
|
*(short*) ptr = val;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case REGULAR:
|
||||||
|
*(int*) ptr = val;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LONG:
|
||||||
|
*(long*) ptr = val;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned char
|
||||||
|
match_pattern (unsigned char sym, const char *pattern)
|
||||||
|
{
|
||||||
|
unsigned char next, inversion, cstart, cend;
|
||||||
|
|
||||||
|
inversion = 0;
|
||||||
|
next = FETCH_BYTE (pattern++);
|
||||||
|
if (next == '^') {
|
||||||
|
inversion = 1;
|
||||||
|
next = FETCH_BYTE (pattern++);
|
||||||
|
}
|
||||||
|
while (next != ']') {
|
||||||
|
if (next == '\0')
|
||||||
|
return 0; /* unterminated [ */
|
||||||
|
|
||||||
|
cstart = cend = next;
|
||||||
|
next = FETCH_BYTE (pattern++);
|
||||||
|
if (next == '-' && (cend = FETCH_BYTE (pattern)) != ']') {
|
||||||
|
if (cend == '\0')
|
||||||
|
return 0;
|
||||||
|
++pattern;
|
||||||
|
next = FETCH_BYTE (pattern++);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sym >= cstart && sym <= cend)
|
||||||
|
return ! inversion;
|
||||||
|
}
|
||||||
|
return inversion;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned char
|
||||||
|
scan_string (stream_t *stream, char *ptr, unsigned char type,
|
||||||
|
unsigned short len, const char *pattern)
|
||||||
|
{
|
||||||
|
unsigned char ch = 0;
|
||||||
|
char *optr;
|
||||||
|
|
||||||
|
optr = ptr;
|
||||||
|
while (! feof (stream)) {
|
||||||
|
ch = getchar (stream);
|
||||||
|
|
||||||
|
/* Skip spaces, for 's'-format. */
|
||||||
|
if (type != 's' || ! ISSPACE (ch))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
while (! feof (stream)) {
|
||||||
|
if (type == 's') {
|
||||||
|
if (ISSPACE (ch))
|
||||||
|
break;
|
||||||
|
} else if (type == '[') {
|
||||||
|
if (! match_pattern (ch, pattern))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (ptr)
|
||||||
|
*ptr++ = ch;
|
||||||
|
if (--len <= 0)
|
||||||
|
break;
|
||||||
|
ch = getchar (stream);
|
||||||
|
}
|
||||||
|
if (ptr != optr) {
|
||||||
|
if (type != 'c')
|
||||||
|
*ptr++ = '\0';
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Scan and recognize input according to a format
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
stream_vscanf (stream_t *stream,
|
||||||
|
const char *fmt, /* Format string for the scanf */
|
||||||
|
va_list argp) /* Arguments to scanf */
|
||||||
|
{
|
||||||
|
unsigned char ch, size, base;
|
||||||
|
unsigned short len;
|
||||||
|
int nmatch, ic;
|
||||||
|
void *ptr;
|
||||||
|
const char *pattern = 0;
|
||||||
|
|
||||||
|
nmatch = 0;
|
||||||
|
for (;;) switch (ch = FETCH_BYTE (fmt++)) {
|
||||||
|
case '\0':
|
||||||
|
return nmatch;
|
||||||
|
case '%':
|
||||||
|
ch = FETCH_BYTE (fmt++);
|
||||||
|
if (ch == '%')
|
||||||
|
goto def;
|
||||||
|
if (ch != '*')
|
||||||
|
ptr = va_arg (argp, void*);
|
||||||
|
else {
|
||||||
|
ptr = 0;
|
||||||
|
ch = FETCH_BYTE (fmt++);
|
||||||
|
}
|
||||||
|
len = 0;
|
||||||
|
size = REGULAR;
|
||||||
|
while (ch >= '0' && ch <= '9') {
|
||||||
|
len = len*10 + ch - '0';
|
||||||
|
ch = FETCH_BYTE (fmt++);
|
||||||
|
}
|
||||||
|
if (len == 0)
|
||||||
|
len = 30000;
|
||||||
|
|
||||||
|
if (ch == 'l') {
|
||||||
|
ch = FETCH_BYTE (fmt++);
|
||||||
|
size = LONG;
|
||||||
|
} else if (ch == 'h') {
|
||||||
|
size = SHORT;
|
||||||
|
ch = FETCH_BYTE (fmt++);
|
||||||
|
} else if (ch == '[') {
|
||||||
|
pattern = fmt;
|
||||||
|
ch = FETCH_BYTE (fmt);
|
||||||
|
if (ch == '^')
|
||||||
|
ch = FETCH_BYTE (++fmt);
|
||||||
|
while (ch != 0 && ch != ']')
|
||||||
|
ch = FETCH_BYTE (++fmt);
|
||||||
|
if (ch != 0)
|
||||||
|
++fmt;
|
||||||
|
ch = '[';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ch >= 'A' && ch <= 'Z') {
|
||||||
|
ch = ch + 'a' - 'A';
|
||||||
|
size = LONG;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (ch) {
|
||||||
|
case 0:
|
||||||
|
return -1;
|
||||||
|
case 'c':
|
||||||
|
if (len == 30000)
|
||||||
|
len = 1;
|
||||||
|
goto string;
|
||||||
|
case 's':
|
||||||
|
case '[':
|
||||||
|
string: if (scan_string (stream, (char*) ptr, ch, len,
|
||||||
|
pattern) && ptr)
|
||||||
|
++nmatch;
|
||||||
|
break;
|
||||||
|
case 'o':
|
||||||
|
base = 8;
|
||||||
|
goto number;
|
||||||
|
case 'x':
|
||||||
|
base = 16;
|
||||||
|
goto number;
|
||||||
|
case 'd':
|
||||||
|
base = 10;
|
||||||
|
number: if (scan_number (stream, ptr, base, len, size) && ptr)
|
||||||
|
++nmatch;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (feof (stream))
|
||||||
|
return nmatch ? nmatch : -1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ' ':
|
||||||
|
case '\n':
|
||||||
|
case '\t':
|
||||||
|
/* Skip spaces. */
|
||||||
|
for (;;) {
|
||||||
|
ic = peekchar (stream);
|
||||||
|
if (ic < 0)
|
||||||
|
break;
|
||||||
|
if (! ISSPACE ((unsigned char) ic))
|
||||||
|
break;
|
||||||
|
getchar (stream);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
def: ic = peekchar (stream);
|
||||||
|
if (ic < 0)
|
||||||
|
return -1;
|
||||||
|
if ((unsigned char) ic != ch)
|
||||||
|
return nmatch;
|
||||||
|
getchar (stream);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue