From f817fdab6990d89558c6b98a7ca06b11c63976cb Mon Sep 17 00:00:00 2001 From: e5l Date: Mon, 15 Aug 2016 16:55:32 +0300 Subject: [PATCH] translator: car echo --- car_fmw/Makefile | 4 +- car_fmw/src/echo.kt | 11 ++++++ car_fmw/src/include/communication.kt | 12 ++++++ car_fmw/src/include/general.kt | 1 + car_fmw/src/include/leds.kt | 22 +++++++++++ car_fmw/src/main.kt | 23 +++++------ car_fmw/src/proto_runtime/CodedInputStream.kt | 24 ++++++------ .../src/proto_runtime/CodedOutputStream.kt | 38 +++++++++++++------ car_fmw/src/proto_runtime/WireFormat.kt | 17 +++++---- car_fmw/src/simpleRoute.kt | 16 +------- car_hw/src/communication.c | 37 +++++++++++++----- car_hw/src/include/communication.h | 8 +++- car_hw/src/include/memory.h | 3 ++ car_hw/src/main.c | 10 +++++ 14 files changed, 157 insertions(+), 69 deletions(-) create mode 100644 car_fmw/src/echo.kt create mode 100644 car_hw/src/include/memory.h diff --git a/car_fmw/Makefile b/car_fmw/Makefile index ae2849a4f3d..5507b9a349a 100644 --- a/car_fmw/Makefile +++ b/car_fmw/Makefile @@ -48,7 +48,7 @@ $(CAR_FMW_BIN): $(CAR_FMW_ELF) $(BIN_DIR) $(OBJ_COPY) -O binary $< $@ $(CAR_FMW_ELF): $(LIB_CAR_HW) $(LIB_KOT) - $(CC) $(CFLAGS) $^ -T stm32_flash.ld -o $@ + $(CC) -Os $(CFLAGS) $^ -T stm32_flash.ld -o $@ $(LIB_CAR_HW): cd $(CAR_HW_DIR) && make @@ -83,7 +83,7 @@ flash: $(CAR_FMW_BIN) debug: -killall st-util (setsid $(ST_DIR)/st-util 2>/dev/null 1>&2)& - $(GDB) $(CAR_FMW_ELF) -x $(ST_DIR)/../gdb.cmds + $(GDB) $(CAR_FMW_ELF) -tui -x $(ST_DIR)/../gdb.cmds clean: rm -rf bin/* diff --git a/car_fmw/src/echo.kt b/car_fmw/src/echo.kt new file mode 100644 index 00000000000..6bc1d8a6604 --- /dev/null +++ b/car_fmw/src/echo.kt @@ -0,0 +1,11 @@ + +fun echoUsb() { + led_on() + + clear_buffer() + while (true) { + val command = receive_int(); + send_int(command) + } + +} \ No newline at end of file diff --git a/car_fmw/src/include/communication.kt b/car_fmw/src/include/communication.kt index d36b4a4e1f0..20be4d5f691 100644 --- a/car_fmw/src/include/communication.kt +++ b/car_fmw/src/include/communication.kt @@ -1,8 +1,20 @@ external fun VCP_init() +external fun clear_buffer() + external fun send_int(i: Int) external fun send_buffer(size: Int, pointer: Int) +external fun receive_int(): Int +external fun receive_buffer(size: Int, pointer: Int) + +fun receiveByteArray(): ByteArray { + val result = ByteArray(receive_int()) + receive_buffer(result.size, result.data) + + return result +} + fun sendByteArray(arr: ByteArray) { send_buffer(arr.size, arr.data) } \ No newline at end of file diff --git a/car_fmw/src/include/general.kt b/car_fmw/src/include/general.kt index b6f7da271a4..096cce1d623 100644 --- a/car_fmw/src/include/general.kt +++ b/car_fmw/src/include/general.kt @@ -4,4 +4,5 @@ fun init() { engine_init() leds_init() VCP_init() + clear_buffer() } diff --git a/car_fmw/src/include/leds.kt b/car_fmw/src/include/leds.kt index 7eeb37a6242..f9bc4d4f475 100644 --- a/car_fmw/src/include/leds.kt +++ b/car_fmw/src/include/leds.kt @@ -7,3 +7,25 @@ val LED_GREEN = 0 val LED_ORANGE = 1 val LED_RED = 2 val LED_BLUE = 3 + +val BLINK_DURATION: Int = 1000 + +fun led_on() { + led_set(LED_GREEN, true) + led_set(LED_BLUE, true) + led_set(LED_RED, true) + led_set(LED_ORANGE, true) +} + +fun led_off() { + led_set(LED_GREEN, false) + led_set(LED_BLUE, false) + led_set(LED_RED, false) + led_set(LED_ORANGE, false) +} + +fun blink() { + led_on() + wait(BLINK_DURATION) + led_off() +} diff --git a/car_fmw/src/main.kt b/car_fmw/src/main.kt index fa6ffc829aa..a5678b9db53 100644 --- a/car_fmw/src/main.kt +++ b/car_fmw/src/main.kt @@ -1,16 +1,17 @@ +//fun writeProto() { +// val msg = DirectionResponse.BuilderDirectionResponse(4242).build() +// val size = msg.getSizeNoTag() +// val buffer = ByteArray(size) +// val outputStream = CodedOutputStream(buffer) +// +// msg.writeTo(outputStream) +// sendByteArray(buffer) +// send_int(0xDDEEFF) +//} -fun writeProto() { - val msg = DirectionResponse.BuilderDirectionResponse(4242).build() - val size = msg.getSizeNoTag() - val buffer = ByteArray(size) - val outputStream = CodedOutputStream(buffer) - - msg.writeTo(outputStream) - sendByteArray(buffer) - send_int(0xDDEEFF) -} +val PROGRAM_DURATION: Int = 1000 fun main() { init() - simpleRoute() + echoUsb() } diff --git a/car_fmw/src/proto_runtime/CodedInputStream.kt b/car_fmw/src/proto_runtime/CodedInputStream.kt index 5474b90fcc4..1ba96e47970 100644 --- a/car_fmw/src/proto_runtime/CodedInputStream.kt +++ b/car_fmw/src/proto_runtime/CodedInputStream.kt @@ -150,22 +150,22 @@ class CodedInputStream(val buffer: ByteArray) { // reads varint not larger than 32-bit integer according to protobuf varint-encoding fun readInt32NoTag(): Int { var done: Boolean = false - var result: Int = 0 + var result: Long = 0 var step: Int = 0 while (!done) { val byte: Int = inputStream.read().toInt() result = result or ( - (byte and WireFormat.VARINT_INFO_BITS_MASK) - shl - (WireFormat.VARINT_INFO_BITS_COUNT * step) - ) + (byte and WireFormat.VARINT_INFO_BITS_MASK).toLong() + shl + (WireFormat.VARINT_INFO_BITS_COUNT * step) + ).toLong() step++ if ((byte and WireFormat.VARINT_UTIL_BIT_MASK) == 0) { done = true } } - return result + return result.toInt() } // reads varint not larger than 64-bit integer according to protobuf varint-encoding @@ -177,10 +177,10 @@ class CodedInputStream(val buffer: ByteArray) { val byte: Int = inputStream.read().toInt() result = result or ( - (byte and WireFormat.VARINT_INFO_BITS_MASK).toLong() - shl - (WireFormat.VARINT_INFO_BITS_COUNT * step) - ) + (byte and WireFormat.VARINT_INFO_BITS_MASK).toLong() + shl + (WireFormat.VARINT_INFO_BITS_COUNT * step) + ) step++ if ((byte and WireFormat.VARINT_UTIL_BIT_MASK) == 0 /* || byte == -1 ???? */) { done = true @@ -192,13 +192,13 @@ class CodedInputStream(val buffer: ByteArray) { // reads zig-zag encoded integer not larger than 32-bit long fun readZigZag32NoTag(): Int { val value = readInt32NoTag() - return (value shr 1) xor (-(value and 1)) // bit magic for decoding zig-zag number + return (value ushr 1) xor (-(value and 1)) // bit magic for decoding zig-zag number } // reads zig-zag encoded integer not larger than 64-bit long fun readZigZag64NoTag(): Long { val value = readInt64NoTag() - return (value shr 1) xor (-(value and 1L)) // bit magic for decoding zig-zag number + return (value ushr 1) xor (-(value and 1L)) // bit magic for decoding zig-zag number } // checks if at least one more byte can be read from underlying input stream diff --git a/car_fmw/src/proto_runtime/CodedOutputStream.kt b/car_fmw/src/proto_runtime/CodedOutputStream.kt index a55d5a9f2c7..7470239a2ba 100644 --- a/car_fmw/src/proto_runtime/CodedOutputStream.kt +++ b/car_fmw/src/proto_runtime/CodedOutputStream.kt @@ -11,7 +11,7 @@ class CodedOutputStream(val buffer: ByteArray) { fun writeTag(fieldNumber: Int, type: WireType) { val tag = (fieldNumber shl 3) or type.id - writeInt32NoTag(tag) + writeRawVarint32(tag) } fun writeInt32(fieldNumber: Int, value: Int) { @@ -19,15 +19,24 @@ class CodedOutputStream(val buffer: ByteArray) { writeInt32NoTag(value) } + fun writeInt32NoTag(value: Int) { + if (value < 0) { // sign-extend negative values + writeRawVarint64(value.toLong()) + return + } + writeRawVarint32(value) + } + // Note that unsigned integer types are stored as their signed counterparts with top bit // simply stored in the sign bit - similar to Java's protobuf implementation. Hence, all // methods, writing unsigned ints simply redirect call to corresponding signed-writing method fun writeUInt32(fieldNumber: Int, value: Int) { - writeInt32(fieldNumber, value) + writeTag(fieldNumber, WireType.VARINT) + writeUInt32NoTag(value) } fun writeUInt32NoTag(value: Int) { - writeInt32NoTag(value) + writeRawVarint32(value) } fun writeInt64(fieldNumber: Int, value: Long) { @@ -35,13 +44,18 @@ class CodedOutputStream(val buffer: ByteArray) { writeInt64NoTag(value) } + fun writeInt64NoTag(value: Long) { + writeRawVarint64(value) + } + // See notes on unsigned integers implementation above fun writeUInt64(fieldNumber: Int, value: Long) { - writeInt64(fieldNumber, value) + writeTag(fieldNumber, WireType.VARINT) + writeUInt64NoTag(value) } fun writeUInt64NoTag(value: Long) { - writeInt64NoTag(value) + writeRawVarint64(value) } fun writeBool(fieldNumber: Int, value: Boolean) { @@ -50,7 +64,7 @@ class CodedOutputStream(val buffer: ByteArray) { } fun writeBoolNoTag(value: Boolean) { - writeInt32NoTag(if (value) 1 else 0) + writeRawVarint32(if (value) 1 else 0) } // Writing enums is like writing one int32 number. Caller is responsible for converting enum-object to ordinal @@ -60,7 +74,7 @@ class CodedOutputStream(val buffer: ByteArray) { } fun writeEnumNoTag(value: Int) { - writeInt32NoTag(value) + writeRawVarint32(value) } fun writeSInt32(fieldNumber: Int, value: Int) { @@ -69,7 +83,7 @@ class CodedOutputStream(val buffer: ByteArray) { } fun writeSInt32NoTag(value: Int) { - writeInt32NoTag((value shl 1) xor (value shr 31)) + writeUInt32NoTag((value shl 1) xor (value shr 31)) } fun writeSInt64(fieldNumber: Int, value: Long) { @@ -78,7 +92,7 @@ class CodedOutputStream(val buffer: ByteArray) { } fun writeSInt64NoTag(value: Long) { - writeInt64NoTag((value shl 1) xor (value shr 63)) + writeUInt64NoTag((value shl 1) xor (value shr 63)) } fun writeBytes(fieldNumber: Int, value: ByteArray) { @@ -90,7 +104,7 @@ class CodedOutputStream(val buffer: ByteArray) { } fun writeBytesNoTag(value: ByteArray) { - writeInt32NoTag(value.size) + writeRawVarint32(value.size) output.write(value) } @@ -99,7 +113,7 @@ class CodedOutputStream(val buffer: ByteArray) { * Then she/he can re-use low-level methods for operating with raw values, that are not annotated with Protobuf tags. */ - fun writeInt32NoTag(value: Int) { + fun writeRawVarint32(value: Int) { var curValue: Int = value // we have at most 32 information bits. With overhead of 1 bit per 7 bits we need at most 5 bytes for encoding @@ -124,7 +138,7 @@ class CodedOutputStream(val buffer: ByteArray) { output.write(res, 0, resSize) } - fun writeInt64NoTag(value: Long) { + fun writeRawVarint64(value: Long) { var curValue: Long = value // we have at most 64 information bits. With overhead of 1 bit per 7 bits we need at most 10 bytes for encoding diff --git a/car_fmw/src/proto_runtime/WireFormat.kt b/car_fmw/src/proto_runtime/WireFormat.kt index 881ae1bd30b..d43c6e37003 100644 --- a/car_fmw/src/proto_runtime/WireFormat.kt +++ b/car_fmw/src/proto_runtime/WireFormat.kt @@ -25,20 +25,20 @@ object WireFormat { fun getVarint32Size(value: Int): Int { var curValue = value var size = 0 - while (curValue != 0) { + do { size += 1 curValue = curValue ushr VARINT_INFO_BITS_COUNT - } + } while (curValue != 0) return size } fun getVarint64Size(value: Long): Int { var curValue = value var size = 0 - while (curValue != 0L) { + do { size += 1 curValue = curValue ushr VARINT_INFO_BITS_COUNT - } + }while (curValue != 0L) return size } @@ -51,15 +51,18 @@ object WireFormat { } fun getInt32Size(fieldNumber: Int, value: Int): Int { - return getTagSize(fieldNumber, WireType.VARINT) + getVarint32Size(value) + return getTagSize(fieldNumber, WireType.VARINT) + getInt32SizeNoTag(value) } fun getInt32SizeNoTag(value: Int): Int { + if (value < 0) { + return getVarint64Size(value.toLong()) + } return getVarint32Size(value) } fun getUInt32Size(fieldNumber: Int, value: Int): Int { - return getInt32Size(fieldNumber, value) + return getTagSize(fieldNumber, WireType.VARINT) + getUInt32SizeNoTag(value) } fun getUInt32SizeNoTag(value: Int): Int { @@ -67,7 +70,7 @@ object WireFormat { } fun getInt64Size(fieldNumber: Int, value: Long): Int { - return getTagSize(fieldNumber, WireType.VARINT) + getVarint64Size(value) + return getTagSize(fieldNumber, WireType.VARINT) + getUInt64SizeNoTag(value) } fun getInt64SizeNoTag(value: Long): Int { diff --git a/car_fmw/src/simpleRoute.kt b/car_fmw/src/simpleRoute.kt index 841ac00502a..69f19886198 100644 --- a/car_fmw/src/simpleRoute.kt +++ b/car_fmw/src/simpleRoute.kt @@ -1,23 +1,9 @@ -val PROGRAM_DURATION: Int = 3000 -val BLINK_DURATION: Int = 500 - -fun blink() { - led_set(LED_GREEN, true) - led_set(LED_BLUE, true) - led_set(LED_RED, true) - led_set(LED_ORANGE, true) - wait(BLINK_DURATION) - led_set(LED_GREEN, false) - led_set(LED_BLUE, false) - led_set(LED_RED, false) - led_set(LED_ORANGE, false) -} fun simpleRoute() { while (true) { wait(PROGRAM_DURATION) blink() - writeProto() +// writeProto() } } \ No newline at end of file diff --git a/car_hw/src/communication.c b/car_hw/src/communication.c index 7d406e450c7..59dba53f893 100644 --- a/car_hw/src/communication.c +++ b/car_hw/src/communication.c @@ -4,37 +4,56 @@ #include #include +#include "memory.h" + +void clear_buffer() +{ + uint8_t tmp_char; + while (VCP_get_char(&tmp_char)); +} + void send_int(int n) { int i = 0; - char* buffer = (char*) &n; + char *buffer = (char *) &n; - VCP_put_char(0xAA); for (; i < sizeof(int); ++i) { VCP_put_char(buffer[i]); } - VCP_put_char(0xAA); } void send_buffer(int size, int pointer) { int i = 0; + char *buffer = (char *) pointer; send_int(size); - VCP_put_char(0xAA); - char* buffer = (char*) pointer; for (; i < size; ++i) { VCP_put_char(buffer[i]); } - VCP_put_char(0xAA); } int receive_int() { - return 0; + int i = 0; + char buffer[sizeof(int)]; + + while (i < 4) { + while (!VCP_get_char(&buffer[i])); + i++; + } + + return *((int*) buffer); } -int receive_buffer() +void receive_buffer(int size, int pointer) { - return 0; + char* buffer = (char*) pointer; + int i = 0; + + for (; i < size; ++i) { + while(!VCP_get_char(&buffer[i])); + } + + return buffer; } diff --git a/car_hw/src/include/communication.h b/car_hw/src/include/communication.h index a3a13ab27ee..cc9284874ef 100644 --- a/car_hw/src/include/communication.h +++ b/car_hw/src/include/communication.h @@ -1,7 +1,13 @@ #pragma once +void clear_buffer(); + void send_int(int i); void send_buffer(int size, int pointer); int receive_int(); -int receive_buffer(); +void receive_buffer(int size, int pointer); + +void set_state(int i); +int get_state(); + diff --git a/car_hw/src/include/memory.h b/car_hw/src/include/memory.h new file mode 100644 index 00000000000..738b4c1687c --- /dev/null +++ b/car_hw/src/include/memory.h @@ -0,0 +1,3 @@ +#pragma once + +extern char* malloc_static(int); diff --git a/car_hw/src/main.c b/car_hw/src/main.c index 25c84af094b..22bb7f8c191 100644 --- a/car_hw/src/main.c +++ b/car_hw/src/main.c @@ -11,3 +11,13 @@ #include "stm32f4xx_conf.h" #include "stm32f4xx_it.h" +int state = 0; + +void set_state(int i) { + state = i; +} + +int get_state() { + return state; +} +