From ff4075479ddf915317d3b38f4b1a1d0d8447d055 Mon Sep 17 00:00:00 2001 From: codercmd Date: Fri, 16 Dec 2022 10:15:34 +0000 Subject: [PATCH 01/44] add examples/Device/KEY_POLL.PY. Signed-off-by: codercmd --- examples/Device/KEY_POLL.PY | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 examples/Device/KEY_POLL.PY diff --git a/examples/Device/KEY_POLL.PY b/examples/Device/KEY_POLL.PY new file mode 100644 index 000000000..c698608fb --- /dev/null +++ b/examples/Device/KEY_POLL.PY @@ -0,0 +1,33 @@ +from machine import GPIO as STD_GPIO + +print('PikaScript LED KEY') + + +LED1 = STD_GPIO() +LED1.setPin('PE5') +LED1.setMode('out') +LED1.enable() + +LED2 = STD_GPIO() +LED2.setPin('PE6') +LED2.setMode('out') +LED2.enable() + +KEY1 = STD_GPIO() +KEY1.setPin('PE4') +# setPull要在setMode前面才行,PikaStdDevice_GPIO.c函数PikaStdDevice_GPIO_setPull不赋值pull +# PikaStdDevice_GPIO_platformSetMode中才赋值cfg->pull +KEY1.setPull('up') +KEY1.setMode('in') + +KEY1.enable() + +LED1.high() +LED2.high() +print(KEY1.read()) + +while True: + if KEY1.read() == 1: + LED1.high() + else: + LED1.low() From b520bc84cd1face70b1eac422f291e87416087bf Mon Sep 17 00:00:00 2001 From: dreamcmi <1912544842@qq.com> Date: Fri, 16 Dec 2022 21:36:35 +0800 Subject: [PATCH 02/44] fix hmac --- test/python/hmac/test_hmac.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 test/python/hmac/test_hmac.py diff --git a/test/python/hmac/test_hmac.py b/test/python/hmac/test_hmac.py new file mode 100644 index 000000000..f4232db47 --- /dev/null +++ b/test/python/hmac/test_hmac.py @@ -0,0 +1,16 @@ +import hmac + +secret = "0123456789" +payload = "helloworld" + +h = hmac.new(secret.encode(),digestmod="hmac-md5") +h.update(payload.encode()) +print("hmac-md5:",h.hexdigest()) + +h = hmac.new(secret.encode(),digestmod="hmac-sha1") +h.update(payload.encode()) +print("hmac-sha1:",h.hexdigest()) + +h = hmac.new(secret.encode(),digestmod="hmac-sha256") +h.update(payload.encode()) +print("hmac-sha256:",h.hexdigest()) From 2491fa71b2e4aff3cb1660a1ea8ca17af26bf8e5 Mon Sep 17 00:00:00 2001 From: dreamcmi <1912544842@qq.com> Date: Fri, 16 Dec 2022 21:38:49 +0800 Subject: [PATCH 03/44] fix hmac method --- examples/hmac/test_hmac.py | 16 ++ package/hmac/_hmac_HMAC.c | 265 +++--------------- .../pikascript-lib/hmac/_hmac_HMAC.c | 265 +++--------------- 3 files changed, 102 insertions(+), 444 deletions(-) create mode 100644 examples/hmac/test_hmac.py diff --git a/examples/hmac/test_hmac.py b/examples/hmac/test_hmac.py new file mode 100644 index 000000000..f4232db47 --- /dev/null +++ b/examples/hmac/test_hmac.py @@ -0,0 +1,16 @@ +import hmac + +secret = "0123456789" +payload = "helloworld" + +h = hmac.new(secret.encode(),digestmod="hmac-md5") +h.update(payload.encode()) +print("hmac-md5:",h.hexdigest()) + +h = hmac.new(secret.encode(),digestmod="hmac-sha1") +h.update(payload.encode()) +print("hmac-sha1:",h.hexdigest()) + +h = hmac.new(secret.encode(),digestmod="hmac-sha256") +h.update(payload.encode()) +print("hmac-sha256:",h.hexdigest()) diff --git a/package/hmac/_hmac_HMAC.c b/package/hmac/_hmac_HMAC.c index 439b4b7ca..4b3a9ea16 100644 --- a/package/hmac/_hmac_HMAC.c +++ b/package/hmac/_hmac_HMAC.c @@ -1,11 +1,7 @@ #include "_hmac_HMAC.h" - +#include "mbedtls/md.h" #include "string.h" -#include "mbedtls/md5.h" -#include "mbedtls/sha1.h" -#include "mbedtls/sha256.h" - enum { PIKA_HMAC_MD5 = 16, PIKA_HMAC_SHA1 = 20, @@ -20,214 +16,80 @@ void _hmac_HMAC_new(PikaObj* self, Arg* key, Arg* msg, char* digestmod) { if (ARG_TYPE_NONE != t) { if (ARG_TYPE_BYTES != t) { obj_setErrorCode(self, -2); // io error + obj_setSysOut(self, "hmac.new() key type error"); } } t = arg_getType(msg); if (ARG_TYPE_NONE != t) { if (ARG_TYPE_BYTES != t) { obj_setErrorCode(self, -2); // io error + obj_setSysOut(self, "hmac.new() msg type error"); } } - obj_setInt(self, "_digest_flags", 0); // flag - obj_setBytes(self, "_buff", NULL, PIKA_HMAC_SHA256); // digest buff - obj_setBytes(self, "_hexbuff", NULL, - PIKA_HMAC_SHA256 * 2); // hexdigest buff - obj_setBytes(self, "_k_ipad", NULL, 64); // key ipad - obj_setBytes(self, "_k_opad", NULL, 64); // key opad - size_t key_len = arg_getBytesSize(key); uint8_t* key_data = arg_getBytes(key); size_t msg_len = arg_getBytesSize(msg); uint8_t* msg_data = arg_getBytes(msg); - - uint8_t* k_ipad = obj_getBytes(self, "_k_ipad"); - uint8_t* k_opad = obj_getBytes(self, "_k_opad"); + obj_setInt(self, "_digest_flags", 0); // flag + obj_setBytes(self, "_buff", NULL, PIKA_HMAC_SHA256); // digest buff + obj_setBytes(self, "_hexbuff", NULL, PIKA_HMAC_SHA256 * 2); + memset(obj_getBytes(self, "_buff"), 0, PIKA_HMAC_SHA256); + memset(obj_getBytes(self, "_hexbuff"), 0, PIKA_HMAC_SHA256 * 2); + mbedtls_md_context_t ctx; + mbedtls_md_init(&ctx); if (strcmp(digestmod, "hmac-md5") == 0 || strcmp(digestmod, "HMAC-MD5") == 0) { - mbedtls_md5_context context; - - if (key_len > 64) { - mbedtls_md5_init(&context); - mbedtls_md5_starts(&context); - mbedtls_md5_update(&context, key_data, key_len); - mbedtls_md5_finish(&context, k_ipad); - mbedtls_md5_free(&context); - memcpy(k_opad, k_ipad, 64); - } else { - memcpy(k_ipad, key_data, key_len); - memcpy(k_opad, key_data, key_len); - } - - for (size_t i = 0; i < 64; i++) { - k_ipad[i] ^= 0x36; - k_opad[i] ^= 0x5c; - } - - mbedtls_md5_init(&context); - mbedtls_md5_starts(&context); - mbedtls_md5_update(&context, k_ipad, 64); - if (msg_len > 0) { - mbedtls_md5_update(&context, msg_data, msg_len); - } - - obj_setStruct(self, "context", context); - obj_setInt(self, "mode", PIKA_HMAC_MD5); + mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(MBEDTLS_MD_MD5), 1); + obj_setInt(self, "_mode", PIKA_HMAC_MD5); } else if (strcmp(digestmod, "hmac-sha1") == 0 || strcmp(digestmod, "HMAC-SHA1") == 0) { - mbedtls_sha1_context context; - - if (key_len > 64) { - mbedtls_sha1_init(&context); - mbedtls_sha1_starts(&context); - mbedtls_sha1_update(&context, key_data, key_len); - mbedtls_sha1_finish(&context, k_ipad); - mbedtls_sha1_free(&context); - memcpy(k_opad, k_ipad, 64); - } else { - memcpy(k_ipad, key_data, key_len); - memcpy(k_opad, key_data, key_len); - } - - for (size_t i = 0; i < 64; i++) { - k_ipad[i] ^= 0x36; - k_opad[i] ^= 0x5c; - } - - mbedtls_sha1_init(&context); - mbedtls_sha1_starts(&context); - mbedtls_sha1_update(&context, k_ipad, 64); - if (msg_len > 0) { - mbedtls_sha1_update(&context, msg_data, msg_len); - } - - obj_setStruct(self, "context", context); - obj_setInt(self, "mode", PIKA_HMAC_SHA1); + mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(MBEDTLS_MD_SHA1), 1); + obj_setInt(self, "_mode", PIKA_HMAC_SHA1); } else if (strcmp(digestmod, "hmac-sha256") == 0 || strcmp(digestmod, "HMAC-SHA256") == 0) { - mbedtls_sha256_context context; - - if (key_len > 64) { - mbedtls_sha256_init(&context); - mbedtls_sha256_starts(&context, 0); - mbedtls_sha256_update(&context, key_data, key_len); - mbedtls_sha256_finish(&context, k_ipad); - mbedtls_sha256_free(&context); - memcpy(k_opad, k_ipad, 64); - } else { - memcpy(k_ipad, key_data, key_len); - memcpy(k_opad, key_data, key_len); - } - - for (size_t i = 0; i < 64; i++) { - k_ipad[i] ^= 0x36; - k_opad[i] ^= 0x5c; - } - - mbedtls_sha256_init(&context); - mbedtls_sha256_starts(&context, 0); - mbedtls_sha256_update(&context, k_ipad, 64); - if (msg_len > 0) { - mbedtls_sha256_update(&context, msg_data, msg_len); - } - - obj_setStruct(self, "context", context); - obj_setInt(self, "mode", PIKA_HMAC_SHA256); + mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), 1); + obj_setInt(self, "_mode", PIKA_HMAC_SHA256); } else { - obj_setErrorCode(self, -1); // not support mode + obj_setErrorCode(self, -2); // io error + obj_setSysOut(self, "hmac.new() not support mode"); } + mbedtls_md_hmac_starts(&ctx, key_data, key_len); + if (msg_len > 0) { + mbedtls_md_hmac_update(&ctx, msg_data, msg_len); + } + obj_setStruct(self, "_context", ctx); } void _hmac_HMAC_update(PikaObj* self, Arg* msg) { ArgType t = arg_getType(msg); if (ARG_TYPE_BYTES != t) { obj_setErrorCode(self, -2); // io error + obj_setSysOut(self, "hmac.update() msg type error"); } size_t msg_len = arg_getBytesSize(msg); uint8_t* msg_data = arg_getBytes(msg); - void* context = obj_getStruct(self, "context"); - - if (msg_len > 0) { - switch (obj_getInt(self, "mode")) { - case PIKA_HMAC_MD5: - mbedtls_md5_update((mbedtls_md5_context*)context, msg_data, - msg_len); - break; - case PIKA_HMAC_SHA1: - mbedtls_sha1_update((mbedtls_sha1_context*)context, msg_data, - msg_len); - break; - case PIKA_HMAC_SHA256: - mbedtls_sha256_update((mbedtls_sha256_context*)context, - msg_data, msg_len); - break; - default: - break; - } - } else { - obj_setErrorCode(self, -2); // io error - } + mbedtls_md_context_t* ctx = obj_getStruct(self, "_context"); + mbedtls_md_hmac_update(ctx, msg_data, msg_len); } Arg* _hmac_HMAC_digest(PikaObj* self) { - uint8_t* k_opad = obj_getBytes(self, "_k_opad"); uint8_t* buff = obj_getBytes(self, "_buff"); uint8_t flag = obj_getInt(self, "_digest_flags"); if (flag & 0x01) // already digest { - return arg_newBytes(buff, obj_getInt(self, "mode")); + goto exit; } else { - void* context = obj_getStruct(self, "context"); - uint8_t mode = obj_getInt(self, "mode"); - switch (mode) { - case PIKA_HMAC_MD5: - mbedtls_md5_finish((mbedtls_md5_context*)context, buff); - mbedtls_md5_free((mbedtls_md5_context*)context); - - mbedtls_md5_init((mbedtls_md5_context*)context); - mbedtls_md5_starts((mbedtls_md5_context*)context); - mbedtls_md5_update((mbedtls_md5_context*)context, k_opad, 64); - mbedtls_md5_update((mbedtls_md5_context*)context, buff, - PIKA_HMAC_MD5); - mbedtls_md5_finish((mbedtls_md5_context*)context, buff); - mbedtls_md5_free((mbedtls_md5_context*)context); - break; - case PIKA_HMAC_SHA1: - mbedtls_sha1_finish((mbedtls_sha1_context*)context, buff); - mbedtls_sha1_free((mbedtls_sha1_context*)context); - - mbedtls_sha1_init((mbedtls_sha1_context*)context); - mbedtls_sha1_starts((mbedtls_sha1_context*)context); - mbedtls_sha1_update((mbedtls_sha1_context*)context, k_opad, 64); - mbedtls_sha1_update((mbedtls_sha1_context*)context, buff, - PIKA_HMAC_SHA1); - mbedtls_sha1_finish((mbedtls_sha1_context*)context, buff); - mbedtls_sha1_free((mbedtls_sha1_context*)context); - break; - case PIKA_HMAC_SHA256: - mbedtls_sha256_finish((mbedtls_sha256_context*)context, buff); - mbedtls_sha256_free((mbedtls_sha256_context*)context); - - mbedtls_sha256_init((mbedtls_sha256_context*)context); - mbedtls_sha256_starts((mbedtls_sha256_context*)context, 0); - mbedtls_sha256_update((mbedtls_sha256_context*)context, k_opad, - 64); - mbedtls_sha256_update((mbedtls_sha256_context*)context, buff, - PIKA_HMAC_SHA256); - mbedtls_sha256_finish((mbedtls_sha256_context*)context, buff); - mbedtls_sha256_free((mbedtls_sha256_context*)context); - break; - default: - obj_setErrorCode(self, -1); // not support mode - return arg_newNull(); // will not actually return to the python - break; - } + mbedtls_md_context_t* ctx = obj_getStruct(self, "_context"); + mbedtls_md_hmac_finish(ctx, buff); obj_setInt(self, "_digest_flags", flag | 0x01); - return arg_newBytes(buff, mode); + goto exit; } +exit: + return arg_newBytes(buff, obj_getInt(self, "_mode")); } char* _hmac_HMAC_hexdigest(PikaObj* self) { @@ -235,61 +97,20 @@ char* _hmac_HMAC_hexdigest(PikaObj* self) { uint8_t* hexbuff = obj_getBytes(self, "_hexbuff"); uint8_t flag = obj_getInt(self, "_digest_flags"); - if (flag & 0x01) { // already digest - hmac_to_hex(buff, obj_getInt(self, "mode"), hexbuff); + if (flag & 0x01) { // already digest obj_setInt(self, "_digest_flags", flag | 0x02); // set hexdigest flag - } else if (flag & 0x02) { // already hexdigest - + goto exit; + } else if (flag & 0x02) { // already hexdigest + return (char*)hexbuff; } else { - void* context = obj_getStruct(self, "context"); - uint8_t* k_opad = obj_getBytes(self, "_k_opad"); - - switch (obj_getInt(self, "mode")) { - case PIKA_HMAC_MD5: - mbedtls_md5_finish((mbedtls_md5_context*)context, buff); - mbedtls_md5_free((mbedtls_md5_context*)context); - - mbedtls_md5_init((mbedtls_md5_context*)context); - mbedtls_md5_starts((mbedtls_md5_context*)context); - mbedtls_md5_update((mbedtls_md5_context*)context, k_opad, 64); - mbedtls_md5_update((mbedtls_md5_context*)context, buff, - PIKA_HMAC_MD5); - mbedtls_md5_finish((mbedtls_md5_context*)context, buff); - mbedtls_md5_free((mbedtls_md5_context*)context); - break; - case PIKA_HMAC_SHA1: - mbedtls_sha1_finish((mbedtls_sha1_context*)context, buff); - mbedtls_sha1_free((mbedtls_sha1_context*)context); - - mbedtls_sha1_init((mbedtls_sha1_context*)context); - mbedtls_sha1_starts((mbedtls_sha1_context*)context); - mbedtls_sha1_update((mbedtls_sha1_context*)context, k_opad, 64); - mbedtls_sha1_update((mbedtls_sha1_context*)context, buff, - PIKA_HMAC_SHA1); - mbedtls_sha1_finish((mbedtls_sha1_context*)context, buff); - mbedtls_sha1_free((mbedtls_sha1_context*)context); - break; - case PIKA_HMAC_SHA256: - mbedtls_sha256_finish((mbedtls_sha256_context*)context, buff); - mbedtls_sha256_free((mbedtls_sha256_context*)context); - - mbedtls_sha256_init((mbedtls_sha256_context*)context); - mbedtls_sha256_starts((mbedtls_sha256_context*)context, 0); - mbedtls_sha256_update((mbedtls_sha256_context*)context, k_opad, - 64); - mbedtls_sha256_update((mbedtls_sha256_context*)context, buff, - PIKA_HMAC_SHA256); - mbedtls_sha256_finish((mbedtls_sha256_context*)context, buff); - mbedtls_sha256_free((mbedtls_sha256_context*)context); - break; - default: - obj_setErrorCode(self, -1); // not support mode - break; - } - hmac_to_hex(buff, PIKA_HMAC_MD5, hexbuff); - obj_setInt(self, "_digest_flags", - flag | 0x03); // set digest and hexdigest flags + mbedtls_md_context_t* ctx = obj_getStruct(self, "_context"); + mbedtls_md_hmac_finish(ctx, buff); + // set digest and hexdigest flags + obj_setInt(self, "_digest_flags", flag | 0x03); + goto exit; } +exit: + hmac_to_hex(buff, obj_getInt(self, "_mode"), hexbuff); return (char*)hexbuff; } diff --git a/port/linux/package/pikascript/pikascript-lib/hmac/_hmac_HMAC.c b/port/linux/package/pikascript/pikascript-lib/hmac/_hmac_HMAC.c index 439b4b7ca..4b3a9ea16 100644 --- a/port/linux/package/pikascript/pikascript-lib/hmac/_hmac_HMAC.c +++ b/port/linux/package/pikascript/pikascript-lib/hmac/_hmac_HMAC.c @@ -1,11 +1,7 @@ #include "_hmac_HMAC.h" - +#include "mbedtls/md.h" #include "string.h" -#include "mbedtls/md5.h" -#include "mbedtls/sha1.h" -#include "mbedtls/sha256.h" - enum { PIKA_HMAC_MD5 = 16, PIKA_HMAC_SHA1 = 20, @@ -20,214 +16,80 @@ void _hmac_HMAC_new(PikaObj* self, Arg* key, Arg* msg, char* digestmod) { if (ARG_TYPE_NONE != t) { if (ARG_TYPE_BYTES != t) { obj_setErrorCode(self, -2); // io error + obj_setSysOut(self, "hmac.new() key type error"); } } t = arg_getType(msg); if (ARG_TYPE_NONE != t) { if (ARG_TYPE_BYTES != t) { obj_setErrorCode(self, -2); // io error + obj_setSysOut(self, "hmac.new() msg type error"); } } - obj_setInt(self, "_digest_flags", 0); // flag - obj_setBytes(self, "_buff", NULL, PIKA_HMAC_SHA256); // digest buff - obj_setBytes(self, "_hexbuff", NULL, - PIKA_HMAC_SHA256 * 2); // hexdigest buff - obj_setBytes(self, "_k_ipad", NULL, 64); // key ipad - obj_setBytes(self, "_k_opad", NULL, 64); // key opad - size_t key_len = arg_getBytesSize(key); uint8_t* key_data = arg_getBytes(key); size_t msg_len = arg_getBytesSize(msg); uint8_t* msg_data = arg_getBytes(msg); - - uint8_t* k_ipad = obj_getBytes(self, "_k_ipad"); - uint8_t* k_opad = obj_getBytes(self, "_k_opad"); + obj_setInt(self, "_digest_flags", 0); // flag + obj_setBytes(self, "_buff", NULL, PIKA_HMAC_SHA256); // digest buff + obj_setBytes(self, "_hexbuff", NULL, PIKA_HMAC_SHA256 * 2); + memset(obj_getBytes(self, "_buff"), 0, PIKA_HMAC_SHA256); + memset(obj_getBytes(self, "_hexbuff"), 0, PIKA_HMAC_SHA256 * 2); + mbedtls_md_context_t ctx; + mbedtls_md_init(&ctx); if (strcmp(digestmod, "hmac-md5") == 0 || strcmp(digestmod, "HMAC-MD5") == 0) { - mbedtls_md5_context context; - - if (key_len > 64) { - mbedtls_md5_init(&context); - mbedtls_md5_starts(&context); - mbedtls_md5_update(&context, key_data, key_len); - mbedtls_md5_finish(&context, k_ipad); - mbedtls_md5_free(&context); - memcpy(k_opad, k_ipad, 64); - } else { - memcpy(k_ipad, key_data, key_len); - memcpy(k_opad, key_data, key_len); - } - - for (size_t i = 0; i < 64; i++) { - k_ipad[i] ^= 0x36; - k_opad[i] ^= 0x5c; - } - - mbedtls_md5_init(&context); - mbedtls_md5_starts(&context); - mbedtls_md5_update(&context, k_ipad, 64); - if (msg_len > 0) { - mbedtls_md5_update(&context, msg_data, msg_len); - } - - obj_setStruct(self, "context", context); - obj_setInt(self, "mode", PIKA_HMAC_MD5); + mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(MBEDTLS_MD_MD5), 1); + obj_setInt(self, "_mode", PIKA_HMAC_MD5); } else if (strcmp(digestmod, "hmac-sha1") == 0 || strcmp(digestmod, "HMAC-SHA1") == 0) { - mbedtls_sha1_context context; - - if (key_len > 64) { - mbedtls_sha1_init(&context); - mbedtls_sha1_starts(&context); - mbedtls_sha1_update(&context, key_data, key_len); - mbedtls_sha1_finish(&context, k_ipad); - mbedtls_sha1_free(&context); - memcpy(k_opad, k_ipad, 64); - } else { - memcpy(k_ipad, key_data, key_len); - memcpy(k_opad, key_data, key_len); - } - - for (size_t i = 0; i < 64; i++) { - k_ipad[i] ^= 0x36; - k_opad[i] ^= 0x5c; - } - - mbedtls_sha1_init(&context); - mbedtls_sha1_starts(&context); - mbedtls_sha1_update(&context, k_ipad, 64); - if (msg_len > 0) { - mbedtls_sha1_update(&context, msg_data, msg_len); - } - - obj_setStruct(self, "context", context); - obj_setInt(self, "mode", PIKA_HMAC_SHA1); + mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(MBEDTLS_MD_SHA1), 1); + obj_setInt(self, "_mode", PIKA_HMAC_SHA1); } else if (strcmp(digestmod, "hmac-sha256") == 0 || strcmp(digestmod, "HMAC-SHA256") == 0) { - mbedtls_sha256_context context; - - if (key_len > 64) { - mbedtls_sha256_init(&context); - mbedtls_sha256_starts(&context, 0); - mbedtls_sha256_update(&context, key_data, key_len); - mbedtls_sha256_finish(&context, k_ipad); - mbedtls_sha256_free(&context); - memcpy(k_opad, k_ipad, 64); - } else { - memcpy(k_ipad, key_data, key_len); - memcpy(k_opad, key_data, key_len); - } - - for (size_t i = 0; i < 64; i++) { - k_ipad[i] ^= 0x36; - k_opad[i] ^= 0x5c; - } - - mbedtls_sha256_init(&context); - mbedtls_sha256_starts(&context, 0); - mbedtls_sha256_update(&context, k_ipad, 64); - if (msg_len > 0) { - mbedtls_sha256_update(&context, msg_data, msg_len); - } - - obj_setStruct(self, "context", context); - obj_setInt(self, "mode", PIKA_HMAC_SHA256); + mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), 1); + obj_setInt(self, "_mode", PIKA_HMAC_SHA256); } else { - obj_setErrorCode(self, -1); // not support mode + obj_setErrorCode(self, -2); // io error + obj_setSysOut(self, "hmac.new() not support mode"); } + mbedtls_md_hmac_starts(&ctx, key_data, key_len); + if (msg_len > 0) { + mbedtls_md_hmac_update(&ctx, msg_data, msg_len); + } + obj_setStruct(self, "_context", ctx); } void _hmac_HMAC_update(PikaObj* self, Arg* msg) { ArgType t = arg_getType(msg); if (ARG_TYPE_BYTES != t) { obj_setErrorCode(self, -2); // io error + obj_setSysOut(self, "hmac.update() msg type error"); } size_t msg_len = arg_getBytesSize(msg); uint8_t* msg_data = arg_getBytes(msg); - void* context = obj_getStruct(self, "context"); - - if (msg_len > 0) { - switch (obj_getInt(self, "mode")) { - case PIKA_HMAC_MD5: - mbedtls_md5_update((mbedtls_md5_context*)context, msg_data, - msg_len); - break; - case PIKA_HMAC_SHA1: - mbedtls_sha1_update((mbedtls_sha1_context*)context, msg_data, - msg_len); - break; - case PIKA_HMAC_SHA256: - mbedtls_sha256_update((mbedtls_sha256_context*)context, - msg_data, msg_len); - break; - default: - break; - } - } else { - obj_setErrorCode(self, -2); // io error - } + mbedtls_md_context_t* ctx = obj_getStruct(self, "_context"); + mbedtls_md_hmac_update(ctx, msg_data, msg_len); } Arg* _hmac_HMAC_digest(PikaObj* self) { - uint8_t* k_opad = obj_getBytes(self, "_k_opad"); uint8_t* buff = obj_getBytes(self, "_buff"); uint8_t flag = obj_getInt(self, "_digest_flags"); if (flag & 0x01) // already digest { - return arg_newBytes(buff, obj_getInt(self, "mode")); + goto exit; } else { - void* context = obj_getStruct(self, "context"); - uint8_t mode = obj_getInt(self, "mode"); - switch (mode) { - case PIKA_HMAC_MD5: - mbedtls_md5_finish((mbedtls_md5_context*)context, buff); - mbedtls_md5_free((mbedtls_md5_context*)context); - - mbedtls_md5_init((mbedtls_md5_context*)context); - mbedtls_md5_starts((mbedtls_md5_context*)context); - mbedtls_md5_update((mbedtls_md5_context*)context, k_opad, 64); - mbedtls_md5_update((mbedtls_md5_context*)context, buff, - PIKA_HMAC_MD5); - mbedtls_md5_finish((mbedtls_md5_context*)context, buff); - mbedtls_md5_free((mbedtls_md5_context*)context); - break; - case PIKA_HMAC_SHA1: - mbedtls_sha1_finish((mbedtls_sha1_context*)context, buff); - mbedtls_sha1_free((mbedtls_sha1_context*)context); - - mbedtls_sha1_init((mbedtls_sha1_context*)context); - mbedtls_sha1_starts((mbedtls_sha1_context*)context); - mbedtls_sha1_update((mbedtls_sha1_context*)context, k_opad, 64); - mbedtls_sha1_update((mbedtls_sha1_context*)context, buff, - PIKA_HMAC_SHA1); - mbedtls_sha1_finish((mbedtls_sha1_context*)context, buff); - mbedtls_sha1_free((mbedtls_sha1_context*)context); - break; - case PIKA_HMAC_SHA256: - mbedtls_sha256_finish((mbedtls_sha256_context*)context, buff); - mbedtls_sha256_free((mbedtls_sha256_context*)context); - - mbedtls_sha256_init((mbedtls_sha256_context*)context); - mbedtls_sha256_starts((mbedtls_sha256_context*)context, 0); - mbedtls_sha256_update((mbedtls_sha256_context*)context, k_opad, - 64); - mbedtls_sha256_update((mbedtls_sha256_context*)context, buff, - PIKA_HMAC_SHA256); - mbedtls_sha256_finish((mbedtls_sha256_context*)context, buff); - mbedtls_sha256_free((mbedtls_sha256_context*)context); - break; - default: - obj_setErrorCode(self, -1); // not support mode - return arg_newNull(); // will not actually return to the python - break; - } + mbedtls_md_context_t* ctx = obj_getStruct(self, "_context"); + mbedtls_md_hmac_finish(ctx, buff); obj_setInt(self, "_digest_flags", flag | 0x01); - return arg_newBytes(buff, mode); + goto exit; } +exit: + return arg_newBytes(buff, obj_getInt(self, "_mode")); } char* _hmac_HMAC_hexdigest(PikaObj* self) { @@ -235,61 +97,20 @@ char* _hmac_HMAC_hexdigest(PikaObj* self) { uint8_t* hexbuff = obj_getBytes(self, "_hexbuff"); uint8_t flag = obj_getInt(self, "_digest_flags"); - if (flag & 0x01) { // already digest - hmac_to_hex(buff, obj_getInt(self, "mode"), hexbuff); + if (flag & 0x01) { // already digest obj_setInt(self, "_digest_flags", flag | 0x02); // set hexdigest flag - } else if (flag & 0x02) { // already hexdigest - + goto exit; + } else if (flag & 0x02) { // already hexdigest + return (char*)hexbuff; } else { - void* context = obj_getStruct(self, "context"); - uint8_t* k_opad = obj_getBytes(self, "_k_opad"); - - switch (obj_getInt(self, "mode")) { - case PIKA_HMAC_MD5: - mbedtls_md5_finish((mbedtls_md5_context*)context, buff); - mbedtls_md5_free((mbedtls_md5_context*)context); - - mbedtls_md5_init((mbedtls_md5_context*)context); - mbedtls_md5_starts((mbedtls_md5_context*)context); - mbedtls_md5_update((mbedtls_md5_context*)context, k_opad, 64); - mbedtls_md5_update((mbedtls_md5_context*)context, buff, - PIKA_HMAC_MD5); - mbedtls_md5_finish((mbedtls_md5_context*)context, buff); - mbedtls_md5_free((mbedtls_md5_context*)context); - break; - case PIKA_HMAC_SHA1: - mbedtls_sha1_finish((mbedtls_sha1_context*)context, buff); - mbedtls_sha1_free((mbedtls_sha1_context*)context); - - mbedtls_sha1_init((mbedtls_sha1_context*)context); - mbedtls_sha1_starts((mbedtls_sha1_context*)context); - mbedtls_sha1_update((mbedtls_sha1_context*)context, k_opad, 64); - mbedtls_sha1_update((mbedtls_sha1_context*)context, buff, - PIKA_HMAC_SHA1); - mbedtls_sha1_finish((mbedtls_sha1_context*)context, buff); - mbedtls_sha1_free((mbedtls_sha1_context*)context); - break; - case PIKA_HMAC_SHA256: - mbedtls_sha256_finish((mbedtls_sha256_context*)context, buff); - mbedtls_sha256_free((mbedtls_sha256_context*)context); - - mbedtls_sha256_init((mbedtls_sha256_context*)context); - mbedtls_sha256_starts((mbedtls_sha256_context*)context, 0); - mbedtls_sha256_update((mbedtls_sha256_context*)context, k_opad, - 64); - mbedtls_sha256_update((mbedtls_sha256_context*)context, buff, - PIKA_HMAC_SHA256); - mbedtls_sha256_finish((mbedtls_sha256_context*)context, buff); - mbedtls_sha256_free((mbedtls_sha256_context*)context); - break; - default: - obj_setErrorCode(self, -1); // not support mode - break; - } - hmac_to_hex(buff, PIKA_HMAC_MD5, hexbuff); - obj_setInt(self, "_digest_flags", - flag | 0x03); // set digest and hexdigest flags + mbedtls_md_context_t* ctx = obj_getStruct(self, "_context"); + mbedtls_md_hmac_finish(ctx, buff); + // set digest and hexdigest flags + obj_setInt(self, "_digest_flags", flag | 0x03); + goto exit; } +exit: + hmac_to_hex(buff, obj_getInt(self, "_mode"), hexbuff); return (char*)hexbuff; } From f6b97e1f7a8e0135d31b289fcfebbf030ab2caec Mon Sep 17 00:00:00 2001 From: lyon Date: Sat, 17 Dec 2022 15:47:08 +0800 Subject: [PATCH 04/44] add test for def not in --- src/PikaVersion.h | 2 +- test/VM-test.cpp | 21 +++++++++++++++++++++ test/parse-test.cpp | 19 +++++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/PikaVersion.h b/src/PikaVersion.h index fa1ddc4be..a22997e51 100644 --- a/src/PikaVersion.h +++ b/src/PikaVersion.h @@ -2,4 +2,4 @@ #define PIKA_VERSION_MINOR 11 #define PIKA_VERSION_MICRO 9 -#define PIKA_EDIT_TIME "2022/12/11 12:01:10" +#define PIKA_EDIT_TIME "2022/12/17 15:47:06" diff --git a/test/VM-test.cpp b/test/VM-test.cpp index 5d8300108..2575ed4ae 100644 --- a/test/VM-test.cpp +++ b/test/VM-test.cpp @@ -2419,6 +2419,27 @@ TEST(vm, issue_not_in) { EXPECT_EQ(pikaMemNow(), 0); } +TEST(vm, def_not_in) { + PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain); + extern unsigned char pikaModules_py_a[]; + obj_linkLibrary(pikaMain, pikaModules_py_a); + obj_run(pikaMain, + "t = ['hmac-md5', 'other']\n" + "def test(a=\"hmac-md5\"):\n" + " print(\"input:\", a)\n" + " print(\"table:\", t)\n" + " if a not in t:\n" + " print(\"a not in t\")\n" + " else:\n" + " print(\"a in t\")\n" + "test()\n"); + /* assert */ + EXPECT_STREQ(log_buff[0], "a in t\r\n"); + /* deinit */ + obj_deinit(pikaMain); + EXPECT_EQ(pikaMemNow(), 0); +} + #endif TEST_END \ No newline at end of file diff --git a/test/parse-test.cpp b/test/parse-test.cpp index dd8b24dac..a6b518b0a 100644 --- a/test/parse-test.cpp +++ b/test/parse-test.cpp @@ -5061,6 +5061,25 @@ TEST(parser, not_in) { EXPECT_EQ(pikaMemNow(), 0); } +// TEST(parser, def_not_in) { +// pikaMemInfo.heapUsedMax = 0; +// Args* buffs = New_strBuff(); +// char* lines = +// "def test(a=\"hmac-md5\"):\n" +// " print(\"input:\",a)\n" +// " print(\"table:\"t )\n" +// " if a not in t:\n" +// " print(\"a not in t\")else:\n" +// " print(\"a in t\")\n" +// "test()\n"; +// printf("%s\r\n", lines); +// char* pikaAsm = Parser_linesToAsm(buffs, lines); +// printf("%s", pikaAsm); +// EXPECT_STREQ(pikaAsm, ""); +// args_deinit(buffs); +// EXPECT_EQ(pikaMemNow(), 0); +// } + #endif TEST_END \ No newline at end of file From 765d32483f714189a104a71e9f82ecdc2ff3ea63 Mon Sep 17 00:00:00 2001 From: lyon Date: Sat, 17 Dec 2022 16:02:59 +0800 Subject: [PATCH 05/44] add __platform_panic_hanlde --- .../pikascript-lib/PikaStdDevice/pika_hal.c | 8 +++++--- .../pikascript/pikascript-lib/ctypes/ctypes.c | 3 +-- src/PikaObj.h | 2 +- src/PikaPlatform.c | 5 +++++ src/PikaPlatform.h | 3 +++ src/PikaVM.c | 18 ++++++------------ src/PikaVersion.h | 2 +- test/hal-test.cpp | 12 +++++++++++- 8 files changed, 33 insertions(+), 20 deletions(-) diff --git a/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/pika_hal.c b/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/pika_hal.c index f2ff8e0d4..1b241f88c 100644 --- a/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/pika_hal.c +++ b/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/pika_hal.c @@ -53,6 +53,7 @@ __exit: __platform_printf("Error: dev_open failed.\r\n"); if (dev->ioctl_config) { pikaFree(dev->ioctl_config, _pika_hal_dev_config_size(dev_type)); + dev->ioctl_config = NULL; } if (dev) { pikaFree(dev, sizeof(pika_dev)); @@ -71,11 +72,12 @@ int pika_hal_close(pika_dev* dev) { } ret = impl->close(dev); __exit: - if (NULL != dev) { - pikaFree(dev, sizeof(pika_dev)); - } if (NULL != dev->ioctl_config) { pikaFree(dev->ioctl_config, _pika_hal_dev_config_size(dev->type)); + dev->ioctl_config = NULL; + } + if (NULL != dev) { + pikaFree(dev, sizeof(pika_dev)); } return ret; } diff --git a/port/linux/package/pikascript/pikascript-lib/ctypes/ctypes.c b/port/linux/package/pikascript/pikascript-lib/ctypes/ctypes.c index d0acb7564..c9bd5222a 100644 --- a/port/linux/package/pikascript/pikascript-lib/ctypes/ctypes.c +++ b/port/linux/package/pikascript/pikascript-lib/ctypes/ctypes.c @@ -98,7 +98,6 @@ void ctypes_c_buffer___init__(PikaObj *self, Arg* value, int size){ strGetSize((char*)value_buffer) + 1); } else { __platform_printf("value type is not support!"); - while (1) - ; + __platform_panic_handle(); } } diff --git a/src/PikaObj.h b/src/PikaObj.h index 5d885d8e1..d1e89320b 100644 --- a/src/PikaObj.h +++ b/src/PikaObj.h @@ -388,7 +388,7 @@ static inline uint8_t obj_refcntNow(PikaObj* self) { #define WEAK_FUNCTION_NEED_OVERRIDE_ERROR(_) \ __platform_printf("Error: weak function `%s()` need override.\r\n", \ __FUNCTION__); \ - while (1) + __platform_panic_handle(); char* obj_cacheStr(PikaObj* self, char* str); PikaObj* _arg_to_obj(Arg* self, PIKA_BOOL* pIsTemp); diff --git a/src/PikaPlatform.c b/src/PikaPlatform.c index 7912a8cea..7a8ae2c6a 100644 --- a/src/PikaPlatform.c +++ b/src/PikaPlatform.c @@ -65,6 +65,11 @@ PIKA_WEAK void __platform_error_handle() { return; } +PIKA_WEAK void __platform_panic_handle() { + while (1) { + }; +} + PIKA_WEAK uint8_t __is_locked_pikaMemory(void) { return 0; } diff --git a/src/PikaPlatform.h b/src/PikaPlatform.h index e387254a4..8233bb743 100644 --- a/src/PikaPlatform.h +++ b/src/PikaPlatform.h @@ -168,6 +168,9 @@ long __platform_ftell(FILE* stream); /* error */ void __platform_error_handle(void); +/* panic */ +void __platform_panic_handle(void); + void __pks_hook_instruct(void); PIKA_BOOL __pks_hook_arg_cache_filter(void* self); PIKA_WEAK void __platform_thread_delay(void); diff --git a/src/PikaVM.c b/src/PikaVM.c index 66298280a..b7d86734c 100644 --- a/src/PikaVM.c +++ b/src/PikaVM.c @@ -65,8 +65,7 @@ static PIKA_BOOL _cq_isFull(volatile EventCQ* cq) { void VMSignal_deinit(void) { #if !PIKA_EVENT_ENABLE __platform_printf("PIKA_EVENT_ENABLE is not enable"); - while (1) { - }; + __platform_panic_handle(); #else for (int i = 0; i < PIKA_EVENT_LIST_SIZE; i++) { if (NULL != PikaVMSignal.cq.res[i]) { @@ -82,8 +81,7 @@ PIKA_RES VMSignal_pushEvent(PikaEventListener* lisener, int eventSignal) { #if !PIKA_EVENT_ENABLE __platform_printf("PIKA_EVENT_ENABLE is not enable"); - while (1) { - }; + __platform_panic_handle(); #else /* push to event_cq_buff */ if (_cq_isFull(&PikaVMSignal.cq)) { @@ -107,8 +105,7 @@ PIKA_RES VMSignal_popEvent(PikaEventListener** lisener_p, int* head) { #if !PIKA_EVENT_ENABLE __platform_printf("PIKA_EVENT_ENABLE is not enable"); - while (1) { - }; + __platform_panic_handle(); #else /* pop from event_cq_buff */ if (_cq_isEmpty(&PikaVMSignal.cq)) { @@ -126,8 +123,7 @@ PIKA_RES VMSignal_popEvent(PikaEventListener** lisener_p, void VMSignale_pickupEvent(void) { #if !PIKA_EVENT_ENABLE __platform_printf("PIKA_EVENT_ENABLE is not enable"); - while (1) { - }; + __platform_panic_handle(); #else PikaObj* event_lisener; uint32_t event_id; @@ -1138,8 +1134,7 @@ static int VMState_loadArgsFromMethodArg(VMState* vm, __platform_printf( "OverflowError: type list is too long, please use bigger " "PIKA_LINE_BUFF_SIZE\r\n"); - while (1) - ; + __platform_panic_handle(); } f.method_type = arg_getType(method_arg); @@ -1527,8 +1522,7 @@ static Arg* VM_instruction_handler_RUN(PikaObj* self, __platform_printf( "[ERROR] Too many args in RUN instruction, please use bigger " "#define PIKA_ARG_NUM_MAX\n"); - while (1) { - } + __platform_panic_handle(); } for (int i = 0; i < n_arg; i++) { stack_tmp[i] = stack_popArg_alloc(&(vm->stack)); diff --git a/src/PikaVersion.h b/src/PikaVersion.h index a22997e51..54bc29906 100644 --- a/src/PikaVersion.h +++ b/src/PikaVersion.h @@ -2,4 +2,4 @@ #define PIKA_VERSION_MINOR 11 #define PIKA_VERSION_MICRO 9 -#define PIKA_EDIT_TIME "2022/12/17 15:47:06" +#define PIKA_EDIT_TIME "2022/12/17 16:02:58" diff --git a/test/hal-test.cpp b/test/hal-test.cpp index 498417258..1429c9488 100644 --- a/test/hal-test.cpp +++ b/test/hal-test.cpp @@ -1,9 +1,19 @@ #include "test_common.h" extern "C" { #include "../package/pikascript/pikascript-lib/PikaStdDevice/pika_hal.h" + +int pika_hal_platform_GPIO_open(pika_dev* dev, char* name){ + return 0; } +int pika_hal_platform_GPIO_close(pika_dev* dev){ + return 0; +} + +} + + TEST(hal, open) { pika_dev* io = pika_hal_open(PIKA_HAL_GPIO, "PA10"); - EXPECT_EQ(0, (uintptr_t)io); + pika_hal_close(io); } From c402e1bb69cc1fd2491ddb966997afbf01cd718c Mon Sep 17 00:00:00 2001 From: dreamcmi <1912544842@qq.com> Date: Sun, 18 Dec 2022 15:33:42 +0800 Subject: [PATCH 06/44] fix base64.encode buffer too small --- package/base64/base64.c | 4 +++- port/linux/package/pikascript/pikascript-lib/base64/base64.c | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/package/base64/base64.c b/package/base64/base64.c index b2064b785..4368f5e31 100644 --- a/package/base64/base64.c +++ b/package/base64/base64.c @@ -6,6 +6,7 @@ Arg* base64_b64decode(PikaObj* self, Arg* s) { ArgType t = arg_getType(s); if (ARG_TYPE_BYTES != t) { obj_setErrorCode(self, -2); // io error + obj_setSysOut(self, "base64.b64decode input not bytes"); } uint8_t* input_buff = arg_getBytes(s); @@ -24,10 +25,11 @@ Arg* base64_b64encode(PikaObj* self, Arg* s) { ArgType t = arg_getType(s); if (ARG_TYPE_BYTES != t) { obj_setErrorCode(self, -2); // io error + obj_setSysOut(self, "base64.b64encode input not bytes"); } uint8_t* input_buff = arg_getBytes(s); size_t input_len = arg_getBytesSize(s); - obj_setBytes(self, "__de_buff", NULL, (size_t)(input_len * 1.5)); + obj_setBytes(self, "__de_buff", NULL, (size_t)(input_len * 2)); uint8_t* output_buff = obj_getBytes(self, "__de_buff"); size_t output_len = 0; mbedtls_base64_encode(output_buff, obj_getBytesSize(self, "__de_buff"), diff --git a/port/linux/package/pikascript/pikascript-lib/base64/base64.c b/port/linux/package/pikascript/pikascript-lib/base64/base64.c index b2064b785..4368f5e31 100644 --- a/port/linux/package/pikascript/pikascript-lib/base64/base64.c +++ b/port/linux/package/pikascript/pikascript-lib/base64/base64.c @@ -6,6 +6,7 @@ Arg* base64_b64decode(PikaObj* self, Arg* s) { ArgType t = arg_getType(s); if (ARG_TYPE_BYTES != t) { obj_setErrorCode(self, -2); // io error + obj_setSysOut(self, "base64.b64decode input not bytes"); } uint8_t* input_buff = arg_getBytes(s); @@ -24,10 +25,11 @@ Arg* base64_b64encode(PikaObj* self, Arg* s) { ArgType t = arg_getType(s); if (ARG_TYPE_BYTES != t) { obj_setErrorCode(self, -2); // io error + obj_setSysOut(self, "base64.b64encode input not bytes"); } uint8_t* input_buff = arg_getBytes(s); size_t input_len = arg_getBytesSize(s); - obj_setBytes(self, "__de_buff", NULL, (size_t)(input_len * 1.5)); + obj_setBytes(self, "__de_buff", NULL, (size_t)(input_len * 2)); uint8_t* output_buff = obj_getBytes(self, "__de_buff"); size_t output_len = 0; mbedtls_base64_encode(output_buff, obj_getBytesSize(self, "__de_buff"), From f06a26299574a8ef84991d48369edf0a88505857 Mon Sep 17 00:00:00 2001 From: dreamcmi <1912544842@qq.com> Date: Sun, 18 Dec 2022 15:38:31 +0800 Subject: [PATCH 07/44] optimize hmac memory usage --- package/hmac/_hmac_HMAC.c | 25 +++++++++++-------- .../pikascript-lib/hmac/_hmac_HMAC.c | 25 +++++++++++-------- 2 files changed, 30 insertions(+), 20 deletions(-) diff --git a/package/hmac/_hmac_HMAC.c b/package/hmac/_hmac_HMAC.c index 4b3a9ea16..ca983a349 100644 --- a/package/hmac/_hmac_HMAC.c +++ b/package/hmac/_hmac_HMAC.c @@ -10,15 +10,21 @@ enum { static void hmac_to_hex(uint8_t* s, int l, uint8_t* d); +static void init_buff(PikaObj* self, size_t h) { + obj_setBytes(self, "_buff", NULL, h); + obj_setBytes(self, "_hexbuff", NULL, (h * 2)); + memset(obj_getBytes(self, "_buff"), 0, h); + memset(obj_getBytes(self, "_hexbuff"), 0, (h * 2)); +} + void _hmac_HMAC_new(PikaObj* self, Arg* key, Arg* msg, char* digestmod) { ArgType t; t = arg_getType(key); - if (ARG_TYPE_NONE != t) { - if (ARG_TYPE_BYTES != t) { - obj_setErrorCode(self, -2); // io error - obj_setSysOut(self, "hmac.new() key type error"); - } + if (ARG_TYPE_BYTES != t) { + obj_setErrorCode(self, -2); // io error + obj_setSysOut(self, "hmac.new() key type error"); } + t = arg_getType(msg); if (ARG_TYPE_NONE != t) { if (ARG_TYPE_BYTES != t) { @@ -31,11 +37,7 @@ void _hmac_HMAC_new(PikaObj* self, Arg* key, Arg* msg, char* digestmod) { uint8_t* key_data = arg_getBytes(key); size_t msg_len = arg_getBytesSize(msg); uint8_t* msg_data = arg_getBytes(msg); - obj_setInt(self, "_digest_flags", 0); // flag - obj_setBytes(self, "_buff", NULL, PIKA_HMAC_SHA256); // digest buff - obj_setBytes(self, "_hexbuff", NULL, PIKA_HMAC_SHA256 * 2); - memset(obj_getBytes(self, "_buff"), 0, PIKA_HMAC_SHA256); - memset(obj_getBytes(self, "_hexbuff"), 0, PIKA_HMAC_SHA256 * 2); + obj_setInt(self, "_digest_flags", 0); // flag mbedtls_md_context_t ctx; mbedtls_md_init(&ctx); @@ -43,14 +45,17 @@ void _hmac_HMAC_new(PikaObj* self, Arg* key, Arg* msg, char* digestmod) { strcmp(digestmod, "HMAC-MD5") == 0) { mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(MBEDTLS_MD_MD5), 1); obj_setInt(self, "_mode", PIKA_HMAC_MD5); + init_buff(self, PIKA_HMAC_MD5); } else if (strcmp(digestmod, "hmac-sha1") == 0 || strcmp(digestmod, "HMAC-SHA1") == 0) { mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(MBEDTLS_MD_SHA1), 1); obj_setInt(self, "_mode", PIKA_HMAC_SHA1); + init_buff(self, PIKA_HMAC_SHA1); } else if (strcmp(digestmod, "hmac-sha256") == 0 || strcmp(digestmod, "HMAC-SHA256") == 0) { mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), 1); obj_setInt(self, "_mode", PIKA_HMAC_SHA256); + init_buff(self, PIKA_HMAC_SHA256); } else { obj_setErrorCode(self, -2); // io error obj_setSysOut(self, "hmac.new() not support mode"); diff --git a/port/linux/package/pikascript/pikascript-lib/hmac/_hmac_HMAC.c b/port/linux/package/pikascript/pikascript-lib/hmac/_hmac_HMAC.c index 4b3a9ea16..ca983a349 100644 --- a/port/linux/package/pikascript/pikascript-lib/hmac/_hmac_HMAC.c +++ b/port/linux/package/pikascript/pikascript-lib/hmac/_hmac_HMAC.c @@ -10,15 +10,21 @@ enum { static void hmac_to_hex(uint8_t* s, int l, uint8_t* d); +static void init_buff(PikaObj* self, size_t h) { + obj_setBytes(self, "_buff", NULL, h); + obj_setBytes(self, "_hexbuff", NULL, (h * 2)); + memset(obj_getBytes(self, "_buff"), 0, h); + memset(obj_getBytes(self, "_hexbuff"), 0, (h * 2)); +} + void _hmac_HMAC_new(PikaObj* self, Arg* key, Arg* msg, char* digestmod) { ArgType t; t = arg_getType(key); - if (ARG_TYPE_NONE != t) { - if (ARG_TYPE_BYTES != t) { - obj_setErrorCode(self, -2); // io error - obj_setSysOut(self, "hmac.new() key type error"); - } + if (ARG_TYPE_BYTES != t) { + obj_setErrorCode(self, -2); // io error + obj_setSysOut(self, "hmac.new() key type error"); } + t = arg_getType(msg); if (ARG_TYPE_NONE != t) { if (ARG_TYPE_BYTES != t) { @@ -31,11 +37,7 @@ void _hmac_HMAC_new(PikaObj* self, Arg* key, Arg* msg, char* digestmod) { uint8_t* key_data = arg_getBytes(key); size_t msg_len = arg_getBytesSize(msg); uint8_t* msg_data = arg_getBytes(msg); - obj_setInt(self, "_digest_flags", 0); // flag - obj_setBytes(self, "_buff", NULL, PIKA_HMAC_SHA256); // digest buff - obj_setBytes(self, "_hexbuff", NULL, PIKA_HMAC_SHA256 * 2); - memset(obj_getBytes(self, "_buff"), 0, PIKA_HMAC_SHA256); - memset(obj_getBytes(self, "_hexbuff"), 0, PIKA_HMAC_SHA256 * 2); + obj_setInt(self, "_digest_flags", 0); // flag mbedtls_md_context_t ctx; mbedtls_md_init(&ctx); @@ -43,14 +45,17 @@ void _hmac_HMAC_new(PikaObj* self, Arg* key, Arg* msg, char* digestmod) { strcmp(digestmod, "HMAC-MD5") == 0) { mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(MBEDTLS_MD_MD5), 1); obj_setInt(self, "_mode", PIKA_HMAC_MD5); + init_buff(self, PIKA_HMAC_MD5); } else if (strcmp(digestmod, "hmac-sha1") == 0 || strcmp(digestmod, "HMAC-SHA1") == 0) { mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(MBEDTLS_MD_SHA1), 1); obj_setInt(self, "_mode", PIKA_HMAC_SHA1); + init_buff(self, PIKA_HMAC_SHA1); } else if (strcmp(digestmod, "hmac-sha256") == 0 || strcmp(digestmod, "HMAC-SHA256") == 0) { mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), 1); obj_setInt(self, "_mode", PIKA_HMAC_SHA256); + init_buff(self, PIKA_HMAC_SHA256); } else { obj_setErrorCode(self, -2); // io error obj_setSysOut(self, "hmac.new() not support mode"); From a8bd50cfae082eea704c94f7c7a4171c2b1e6fe5 Mon Sep 17 00:00:00 2001 From: dreamcmi <1912544842@qq.com> Date: Sun, 18 Dec 2022 15:40:37 +0800 Subject: [PATCH 08/44] hmac compatible cpython input parameters --- examples/hmac/test_hmac.py | 6 +++--- package/hmac/_hmac_HMAC.c | 12 ++++++------ package/hmac/hmac.py | 2 +- port/linux/package/pikascript/hmac.py | 2 +- .../pikascript/pikascript-lib/hmac/_hmac_HMAC.c | 12 ++++++------ test/python/hmac/test_hmac.py | 6 +++--- 6 files changed, 20 insertions(+), 20 deletions(-) diff --git a/examples/hmac/test_hmac.py b/examples/hmac/test_hmac.py index f4232db47..1db0b1013 100644 --- a/examples/hmac/test_hmac.py +++ b/examples/hmac/test_hmac.py @@ -3,14 +3,14 @@ import hmac secret = "0123456789" payload = "helloworld" -h = hmac.new(secret.encode(),digestmod="hmac-md5") +h = hmac.new(secret.encode(),digestmod="md5") h.update(payload.encode()) print("hmac-md5:",h.hexdigest()) -h = hmac.new(secret.encode(),digestmod="hmac-sha1") +h = hmac.new(secret.encode(),digestmod="sha1") h.update(payload.encode()) print("hmac-sha1:",h.hexdigest()) -h = hmac.new(secret.encode(),digestmod="hmac-sha256") +h = hmac.new(secret.encode(),digestmod="sha256") h.update(payload.encode()) print("hmac-sha256:",h.hexdigest()) diff --git a/package/hmac/_hmac_HMAC.c b/package/hmac/_hmac_HMAC.c index ca983a349..02425a242 100644 --- a/package/hmac/_hmac_HMAC.c +++ b/package/hmac/_hmac_HMAC.c @@ -41,18 +41,18 @@ void _hmac_HMAC_new(PikaObj* self, Arg* key, Arg* msg, char* digestmod) { mbedtls_md_context_t ctx; mbedtls_md_init(&ctx); - if (strcmp(digestmod, "hmac-md5") == 0 || - strcmp(digestmod, "HMAC-MD5") == 0) { + if (strcmp(digestmod, "md5") == 0 || + strcmp(digestmod, "MD5") == 0) { mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(MBEDTLS_MD_MD5), 1); obj_setInt(self, "_mode", PIKA_HMAC_MD5); init_buff(self, PIKA_HMAC_MD5); - } else if (strcmp(digestmod, "hmac-sha1") == 0 || - strcmp(digestmod, "HMAC-SHA1") == 0) { + } else if (strcmp(digestmod, "sha1") == 0 || + strcmp(digestmod, "SHA1") == 0) { mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(MBEDTLS_MD_SHA1), 1); obj_setInt(self, "_mode", PIKA_HMAC_SHA1); init_buff(self, PIKA_HMAC_SHA1); - } else if (strcmp(digestmod, "hmac-sha256") == 0 || - strcmp(digestmod, "HMAC-SHA256") == 0) { + } else if (strcmp(digestmod, "sha256") == 0 || + strcmp(digestmod, "SHA256") == 0) { mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), 1); obj_setInt(self, "_mode", PIKA_HMAC_SHA256); init_buff(self, PIKA_HMAC_SHA256); diff --git a/package/hmac/hmac.py b/package/hmac/hmac.py index a632ce8ed..36836f6a2 100644 --- a/package/hmac/hmac.py +++ b/package/hmac/hmac.py @@ -1,6 +1,6 @@ import _hmac -def new(key:any, msg=None, digestmod="hmac-md5") -> _hmac.HMAC: +def new(key:any, msg=None, digestmod="md5") -> _hmac.HMAC: hmac = _hmac.HMAC() hmac.new(key, msg, digestmod) return hmac diff --git a/port/linux/package/pikascript/hmac.py b/port/linux/package/pikascript/hmac.py index a632ce8ed..36836f6a2 100644 --- a/port/linux/package/pikascript/hmac.py +++ b/port/linux/package/pikascript/hmac.py @@ -1,6 +1,6 @@ import _hmac -def new(key:any, msg=None, digestmod="hmac-md5") -> _hmac.HMAC: +def new(key:any, msg=None, digestmod="md5") -> _hmac.HMAC: hmac = _hmac.HMAC() hmac.new(key, msg, digestmod) return hmac diff --git a/port/linux/package/pikascript/pikascript-lib/hmac/_hmac_HMAC.c b/port/linux/package/pikascript/pikascript-lib/hmac/_hmac_HMAC.c index ca983a349..02425a242 100644 --- a/port/linux/package/pikascript/pikascript-lib/hmac/_hmac_HMAC.c +++ b/port/linux/package/pikascript/pikascript-lib/hmac/_hmac_HMAC.c @@ -41,18 +41,18 @@ void _hmac_HMAC_new(PikaObj* self, Arg* key, Arg* msg, char* digestmod) { mbedtls_md_context_t ctx; mbedtls_md_init(&ctx); - if (strcmp(digestmod, "hmac-md5") == 0 || - strcmp(digestmod, "HMAC-MD5") == 0) { + if (strcmp(digestmod, "md5") == 0 || + strcmp(digestmod, "MD5") == 0) { mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(MBEDTLS_MD_MD5), 1); obj_setInt(self, "_mode", PIKA_HMAC_MD5); init_buff(self, PIKA_HMAC_MD5); - } else if (strcmp(digestmod, "hmac-sha1") == 0 || - strcmp(digestmod, "HMAC-SHA1") == 0) { + } else if (strcmp(digestmod, "sha1") == 0 || + strcmp(digestmod, "SHA1") == 0) { mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(MBEDTLS_MD_SHA1), 1); obj_setInt(self, "_mode", PIKA_HMAC_SHA1); init_buff(self, PIKA_HMAC_SHA1); - } else if (strcmp(digestmod, "hmac-sha256") == 0 || - strcmp(digestmod, "HMAC-SHA256") == 0) { + } else if (strcmp(digestmod, "sha256") == 0 || + strcmp(digestmod, "SHA256") == 0) { mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), 1); obj_setInt(self, "_mode", PIKA_HMAC_SHA256); init_buff(self, PIKA_HMAC_SHA256); diff --git a/test/python/hmac/test_hmac.py b/test/python/hmac/test_hmac.py index f4232db47..1db0b1013 100644 --- a/test/python/hmac/test_hmac.py +++ b/test/python/hmac/test_hmac.py @@ -3,14 +3,14 @@ import hmac secret = "0123456789" payload = "helloworld" -h = hmac.new(secret.encode(),digestmod="hmac-md5") +h = hmac.new(secret.encode(),digestmod="md5") h.update(payload.encode()) print("hmac-md5:",h.hexdigest()) -h = hmac.new(secret.encode(),digestmod="hmac-sha1") +h = hmac.new(secret.encode(),digestmod="sha1") h.update(payload.encode()) print("hmac-sha1:",h.hexdigest()) -h = hmac.new(secret.encode(),digestmod="hmac-sha256") +h = hmac.new(secret.encode(),digestmod="sha256") h.update(payload.encode()) print("hmac-sha256:",h.hexdigest()) From fd6d39143c395dab61d256ef0c51d2da594f9f0a Mon Sep 17 00:00:00 2001 From: lyon Date: Mon, 19 Dec 2022 16:56:53 +0800 Subject: [PATCH 09/44] support uart for std by pika_hal --- package/PikaStdDevice/PikaStdDevice_UART.c | 60 +++++++++++++++++-- package/PikaStdDevice/pika_hal.c | 8 ++- .../PikaStdDevice/PikaStdDevice_UART.c | 60 +++++++++++++++++-- 3 files changed, 113 insertions(+), 15 deletions(-) diff --git a/package/PikaStdDevice/PikaStdDevice_UART.c b/package/PikaStdDevice/PikaStdDevice_UART.c index 0d491b3ad..301a08b5f 100644 --- a/package/PikaStdDevice/PikaStdDevice_UART.c +++ b/package/PikaStdDevice/PikaStdDevice_UART.c @@ -48,24 +48,72 @@ void PikaStdDevice_UART_writeBytes(PikaObj* self, uint8_t* data, int length) { obj_runNativeMethod(self, "platformWriteBytes", NULL); } +static pika_dev* _get_dev(PikaObj* self) { + pika_dev* dev = obj_getPtr(self, "pika_dev"); + if (NULL != dev) { + return dev; + } + int id = obj_getInt(self, "id"); + char id_str[32] = {0}; + sprintf(id_str, "%d", id); + dev = pika_hal_open(PIKA_HAL_UART, id_str); + if (NULL == dev) { + __platform_printf("Error: open UART '%s' failed.\r\n", id_str); + } + obj_setPtr(self, "pika_dev", dev); + return dev; +} + void PikaStdDevice_UART_platformEnable(PikaObj* self) { - ABSTRACT_METHOD_NEED_OVERRIDE_ERROR(); + pika_dev* dev = _get_dev(self); + if (NULL == dev) { + __platform_printf("Error: open UART '%d' failed.\r\n", + obj_getInt(self, "id")); + return; + } + pika_hal_UART_config cfg = {0}; + cfg.baudrate = obj_getInt(self, "baudRate"); + pika_hal_ioctl(dev, PIKA_HAL_IOCTL_CONFIG, &cfg); + pika_hal_ioctl(dev, PIKA_HAL_IOCTL_ENABLE); } + void PikaStdDevice_UART_platformRead(PikaObj* self) { - ABSTRACT_METHOD_NEED_OVERRIDE_ERROR(); + int len = obj_getInt(self, "length"); + obj_setBytes(self, "_readData", NULL, len + 1); + char* buff = obj_getBytes(self, "_readData"); + pika_dev* dev = _get_dev(self); + pika_hal_read(dev, buff, len); + obj_setStr(self, "readData", buff); } + void PikaStdDevice_UART_platformWrite(PikaObj* self) { - ABSTRACT_METHOD_NEED_OVERRIDE_ERROR(); + char* data = obj_getStr(self, "writeData"); + pika_dev* dev = _get_dev(self); + pika_hal_write(dev, data, strlen(data)); } void PikaStdDevice_UART_platformDisable(PikaObj* self) { - ABSTRACT_METHOD_NEED_OVERRIDE_ERROR(); + pika_dev* dev = _get_dev(self); + if (NULL == dev) { + __platform_printf("Error: open UART '%d' failed.\r\n", + obj_getInt(self, "id")); + return; + } + pika_hal_ioctl(dev, PIKA_HAL_IOCTL_DISABLE); } void PikaStdDevice_UART_platformReadBytes(PikaObj* self) { - ABSTRACT_METHOD_NEED_OVERRIDE_ERROR(); + int len = obj_getInt(self, "length"); + obj_setBytes(self, "_readData", NULL, len + 1); + uint8_t* buff = obj_getBytes(self, "_readData"); + pika_dev* dev = _get_dev(self); + pika_hal_read(dev, buff, len); + obj_setBytes(self, "readData", buff, len); } void PikaStdDevice_UART_platformWriteBytes(PikaObj* self) { - ABSTRACT_METHOD_NEED_OVERRIDE_ERROR(); + uint8_t* data = obj_getBytes(self, "writeData"); + int len = obj_getBytesLen(self, "writeData"); + pika_dev* dev = _get_dev(self); + pika_hal_write(dev, data, len); } diff --git a/package/PikaStdDevice/pika_hal.c b/package/PikaStdDevice/pika_hal.c index f2ff8e0d4..1b241f88c 100644 --- a/package/PikaStdDevice/pika_hal.c +++ b/package/PikaStdDevice/pika_hal.c @@ -53,6 +53,7 @@ __exit: __platform_printf("Error: dev_open failed.\r\n"); if (dev->ioctl_config) { pikaFree(dev->ioctl_config, _pika_hal_dev_config_size(dev_type)); + dev->ioctl_config = NULL; } if (dev) { pikaFree(dev, sizeof(pika_dev)); @@ -71,11 +72,12 @@ int pika_hal_close(pika_dev* dev) { } ret = impl->close(dev); __exit: - if (NULL != dev) { - pikaFree(dev, sizeof(pika_dev)); - } if (NULL != dev->ioctl_config) { pikaFree(dev->ioctl_config, _pika_hal_dev_config_size(dev->type)); + dev->ioctl_config = NULL; + } + if (NULL != dev) { + pikaFree(dev, sizeof(pika_dev)); } return ret; } diff --git a/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_UART.c b/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_UART.c index 0d491b3ad..301a08b5f 100644 --- a/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_UART.c +++ b/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_UART.c @@ -48,24 +48,72 @@ void PikaStdDevice_UART_writeBytes(PikaObj* self, uint8_t* data, int length) { obj_runNativeMethod(self, "platformWriteBytes", NULL); } +static pika_dev* _get_dev(PikaObj* self) { + pika_dev* dev = obj_getPtr(self, "pika_dev"); + if (NULL != dev) { + return dev; + } + int id = obj_getInt(self, "id"); + char id_str[32] = {0}; + sprintf(id_str, "%d", id); + dev = pika_hal_open(PIKA_HAL_UART, id_str); + if (NULL == dev) { + __platform_printf("Error: open UART '%s' failed.\r\n", id_str); + } + obj_setPtr(self, "pika_dev", dev); + return dev; +} + void PikaStdDevice_UART_platformEnable(PikaObj* self) { - ABSTRACT_METHOD_NEED_OVERRIDE_ERROR(); + pika_dev* dev = _get_dev(self); + if (NULL == dev) { + __platform_printf("Error: open UART '%d' failed.\r\n", + obj_getInt(self, "id")); + return; + } + pika_hal_UART_config cfg = {0}; + cfg.baudrate = obj_getInt(self, "baudRate"); + pika_hal_ioctl(dev, PIKA_HAL_IOCTL_CONFIG, &cfg); + pika_hal_ioctl(dev, PIKA_HAL_IOCTL_ENABLE); } + void PikaStdDevice_UART_platformRead(PikaObj* self) { - ABSTRACT_METHOD_NEED_OVERRIDE_ERROR(); + int len = obj_getInt(self, "length"); + obj_setBytes(self, "_readData", NULL, len + 1); + char* buff = obj_getBytes(self, "_readData"); + pika_dev* dev = _get_dev(self); + pika_hal_read(dev, buff, len); + obj_setStr(self, "readData", buff); } + void PikaStdDevice_UART_platformWrite(PikaObj* self) { - ABSTRACT_METHOD_NEED_OVERRIDE_ERROR(); + char* data = obj_getStr(self, "writeData"); + pika_dev* dev = _get_dev(self); + pika_hal_write(dev, data, strlen(data)); } void PikaStdDevice_UART_platformDisable(PikaObj* self) { - ABSTRACT_METHOD_NEED_OVERRIDE_ERROR(); + pika_dev* dev = _get_dev(self); + if (NULL == dev) { + __platform_printf("Error: open UART '%d' failed.\r\n", + obj_getInt(self, "id")); + return; + } + pika_hal_ioctl(dev, PIKA_HAL_IOCTL_DISABLE); } void PikaStdDevice_UART_platformReadBytes(PikaObj* self) { - ABSTRACT_METHOD_NEED_OVERRIDE_ERROR(); + int len = obj_getInt(self, "length"); + obj_setBytes(self, "_readData", NULL, len + 1); + uint8_t* buff = obj_getBytes(self, "_readData"); + pika_dev* dev = _get_dev(self); + pika_hal_read(dev, buff, len); + obj_setBytes(self, "readData", buff, len); } void PikaStdDevice_UART_platformWriteBytes(PikaObj* self) { - ABSTRACT_METHOD_NEED_OVERRIDE_ERROR(); + uint8_t* data = obj_getBytes(self, "writeData"); + int len = obj_getBytesLen(self, "writeData"); + pika_dev* dev = _get_dev(self); + pika_hal_write(dev, data, len); } From 559e408129970e852d0909aff2895942da8fc3cd Mon Sep 17 00:00:00 2001 From: dreamcmi <1912544842@qq.com> Date: Tue, 20 Dec 2022 22:11:49 +0800 Subject: [PATCH 10/44] update_toml --- packages.toml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages.toml b/packages.toml index 0dfd56c96..f922ac4a7 100644 --- a/packages.toml +++ b/packages.toml @@ -445,7 +445,10 @@ releases = [ [[packages]] name = "hmac" -releases = [ "v1.0.0 ca8fe36d68be16722317860394fdf78c620e3e2d" ] +releases = [ + "v1.0.0 ca8fe36d68be16722317860394fdf78c620e3e2d", + "v1.0.1 d75ce00c377e48c6058bbe1f824474802383e5e7" +] [[packages]] name = "BLIOT" From 0e829579b1932744c922dc6b024ab3c7ff319289 Mon Sep 17 00:00:00 2001 From: dreamcmi <1912544842@qq.com> Date: Tue, 20 Dec 2022 22:12:25 +0800 Subject: [PATCH 11/44] update_toml --- packages.toml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages.toml b/packages.toml index 0dfd56c96..18c70d81a 100644 --- a/packages.toml +++ b/packages.toml @@ -460,4 +460,7 @@ releases = [ "v0.0.1 5c45cba0c39d447fbe7a4a082ee3170188c3bcb7" ] [[packages]] name = "base64" -releases = [ "v0.0.1 1ae3ac23759fb2b5e0f77866af40986ac94e356d" ] +releases = [ + "v0.0.1 1ae3ac23759fb2b5e0f77866af40986ac94e356d", + "v1.0.0 d75ce00c377e48c6058bbe1f824474802383e5e7" +] From fce67d309d16c3608b896d1911a590141387984f Mon Sep 17 00:00:00 2001 From: lyon Date: Tue, 20 Dec 2022 22:44:39 +0800 Subject: [PATCH 12/44] use WEAK for std.time --- package/PikaStdDevice/PikaStdDevice_Time.c | 7 +++---- package/PikaStdDevice/PikaStdDevice_UART.c | 4 ++-- .../PikaStdDevice/PikaStdDevice_Time.c | 7 +++---- .../PikaStdDevice/PikaStdDevice_UART.c | 4 ++-- src/PikaPlatform.c | 18 ++++++++++++++++++ src/PikaPlatform.h | 5 ++++- 6 files changed, 32 insertions(+), 13 deletions(-) diff --git a/package/PikaStdDevice/PikaStdDevice_Time.c b/package/PikaStdDevice/PikaStdDevice_Time.c index 50ca25e47..caa8ae5ce 100644 --- a/package/PikaStdDevice/PikaStdDevice_Time.c +++ b/package/PikaStdDevice/PikaStdDevice_Time.c @@ -14,7 +14,7 @@ void PikaStdDevice_Time_sleep_ms(PikaObj* self, int ms) { #elif defined(_WIN32) Sleep(ms); #else - ABSTRACT_METHOD_NEED_OVERRIDE_ERROR(); + __platform_sleep_ms(ms); #endif } void PikaStdDevice_Time_sleep_s(PikaObj* self, int s) { @@ -23,13 +23,12 @@ void PikaStdDevice_Time_sleep_s(PikaObj* self, int s) { #elif defined(_WIN32) Sleep(s * 1000); #else - ABSTRACT_METHOD_NEED_OVERRIDE_ERROR(); + __platform_sleep_s(s); #endif } void PikaStdDevice_Time_platformGetTick(PikaObj* self) { - obj_setErrorCode(self, 1); - obj_setSysOut(self, "[error] platformGetTick() need to be override."); + obj_setInt(self, "tick", __platform_get_tick_ms()); } /* diff --git a/package/PikaStdDevice/PikaStdDevice_UART.c b/package/PikaStdDevice/PikaStdDevice_UART.c index 301a08b5f..7b3a22dad 100644 --- a/package/PikaStdDevice/PikaStdDevice_UART.c +++ b/package/PikaStdDevice/PikaStdDevice_UART.c @@ -80,7 +80,7 @@ void PikaStdDevice_UART_platformEnable(PikaObj* self) { void PikaStdDevice_UART_platformRead(PikaObj* self) { int len = obj_getInt(self, "length"); obj_setBytes(self, "_readData", NULL, len + 1); - char* buff = obj_getBytes(self, "_readData"); + char* buff = (char*)obj_getBytes(self, "_readData"); pika_dev* dev = _get_dev(self); pika_hal_read(dev, buff, len); obj_setStr(self, "readData", buff); @@ -113,7 +113,7 @@ void PikaStdDevice_UART_platformReadBytes(PikaObj* self) { void PikaStdDevice_UART_platformWriteBytes(PikaObj* self) { uint8_t* data = obj_getBytes(self, "writeData"); - int len = obj_getBytesLen(self, "writeData"); + int len = obj_getBytesSize(self, "writeData"); pika_dev* dev = _get_dev(self); pika_hal_write(dev, data, len); } diff --git a/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_Time.c b/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_Time.c index 50ca25e47..caa8ae5ce 100644 --- a/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_Time.c +++ b/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_Time.c @@ -14,7 +14,7 @@ void PikaStdDevice_Time_sleep_ms(PikaObj* self, int ms) { #elif defined(_WIN32) Sleep(ms); #else - ABSTRACT_METHOD_NEED_OVERRIDE_ERROR(); + __platform_sleep_ms(ms); #endif } void PikaStdDevice_Time_sleep_s(PikaObj* self, int s) { @@ -23,13 +23,12 @@ void PikaStdDevice_Time_sleep_s(PikaObj* self, int s) { #elif defined(_WIN32) Sleep(s * 1000); #else - ABSTRACT_METHOD_NEED_OVERRIDE_ERROR(); + __platform_sleep_s(s); #endif } void PikaStdDevice_Time_platformGetTick(PikaObj* self) { - obj_setErrorCode(self, 1); - obj_setSysOut(self, "[error] platformGetTick() need to be override."); + obj_setInt(self, "tick", __platform_get_tick_ms()); } /* diff --git a/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_UART.c b/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_UART.c index 301a08b5f..7b3a22dad 100644 --- a/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_UART.c +++ b/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_UART.c @@ -80,7 +80,7 @@ void PikaStdDevice_UART_platformEnable(PikaObj* self) { void PikaStdDevice_UART_platformRead(PikaObj* self) { int len = obj_getInt(self, "length"); obj_setBytes(self, "_readData", NULL, len + 1); - char* buff = obj_getBytes(self, "_readData"); + char* buff = (char*)obj_getBytes(self, "_readData"); pika_dev* dev = _get_dev(self); pika_hal_read(dev, buff, len); obj_setStr(self, "readData", buff); @@ -113,7 +113,7 @@ void PikaStdDevice_UART_platformReadBytes(PikaObj* self) { void PikaStdDevice_UART_platformWriteBytes(PikaObj* self) { uint8_t* data = obj_getBytes(self, "writeData"); - int len = obj_getBytesLen(self, "writeData"); + int len = obj_getBytesSize(self, "writeData"); pika_dev* dev = _get_dev(self); pika_hal_write(dev, data, len); } diff --git a/src/PikaPlatform.c b/src/PikaPlatform.c index 7a8ae2c6a..7e77b866e 100644 --- a/src/PikaPlatform.c +++ b/src/PikaPlatform.c @@ -253,3 +253,21 @@ PIKA_WEAK PIKA_BOOL __pks_hook_arg_cache_filter(void* self) { PIKA_WEAK void __platform_thread_delay(void) { return; } + +PIKA_WEAK uint64_t __platform_get_tick_ms(void){ + __platform_printf("Error: __platform_get_tick_ms need implementation!\r\n"); + while (1) { + } +} + +PIKA_WEAK void __platform_sleep_ms(uint32_t ms){ + __platform_printf("Error: __platform_sleep_ms need implementation!\r\n"); + while (1) { + } +} + +PIKA_WEAK void __platform_sleep_s(uint32_t s){ + __platform_printf("Error: __platform_sleep_s need implementation!\r\n"); + while (1) { + } +} diff --git a/src/PikaPlatform.h b/src/PikaPlatform.h index 8233bb743..2107138a8 100644 --- a/src/PikaPlatform.h +++ b/src/PikaPlatform.h @@ -173,7 +173,10 @@ void __platform_panic_handle(void); void __pks_hook_instruct(void); PIKA_BOOL __pks_hook_arg_cache_filter(void* self); -PIKA_WEAK void __platform_thread_delay(void); +void __platform_thread_delay(void); +uint64_t __platform_get_tick_ms(void); +void __platform_sleep_ms(uint32_t ms); +void __platform_sleep_s(uint32_t s); #if PIKA_FLOAT_TYPE_DOUBLE #define pika_float double From 3afd92608a02c4a7cbc8d60b6fcfb09f1cb0c20a Mon Sep 17 00:00:00 2001 From: lyon Date: Wed, 21 Dec 2022 00:13:19 +0800 Subject: [PATCH 13/44] fix typo of getArgByIndex --- package/PikaStdLib/PikaStdData_Dict.c | 16 ++++++++-------- port/linux/.vscode/launch.json | 2 +- .../PikaStdLib/PikaStdData_Dict.c | 16 ++++++++-------- src/PikaVM.c | 2 +- src/dataArgs.c | 2 +- src/dataArgs.h | 2 +- test/VM-test.cpp | 17 +++++++++++++++++ test/args-test.cpp | 4 ++-- 8 files changed, 39 insertions(+), 22 deletions(-) diff --git a/package/PikaStdLib/PikaStdData_Dict.c b/package/PikaStdLib/PikaStdData_Dict.c index 0423fabfa..63447c256 100644 --- a/package/PikaStdLib/PikaStdData_Dict.c +++ b/package/PikaStdLib/PikaStdData_Dict.c @@ -40,7 +40,7 @@ Arg* PikaStdData_Dict___iter__(PikaObj* self) { Arg* PikaStdData_Dict___next__(PikaObj* self) { int __iter_i = args_getInt(self->list, "__iter_i"); PikaDict* keys = obj_getPtr(self, "_keys"); - Arg* res = arg_copy(args_getArgByidex(&keys->super, __iter_i)); + Arg* res = arg_copy(args_getArgByIndex(&keys->super, __iter_i)); if (NULL == res) { return arg_newNull(); } @@ -91,7 +91,7 @@ Arg* PikaStdData_dict_keys___next__(PikaObj* self) { int __iter_i = args_getInt(self->list, "__iter_i"); PikaObj* dictptr = obj_getPtr(self, "dictptr"); PikaDict* keys = obj_getPtr(dictptr, "_keys"); - Arg* res = arg_copy(args_getArgByidex(&keys->super, __iter_i)); + Arg* res = arg_copy(args_getArgByIndex(&keys->super, __iter_i)); if (NULL == res) { return arg_newNull(); } @@ -107,7 +107,7 @@ char* PikaStdData_dict_keys___str__(PikaObj* self) { int i = 0; while (PIKA_TRUE) { - Arg* item = args_getArgByidex(&keys->super, i); + Arg* item = args_getArgByIndex(&keys->super, i); if (NULL == item) { break; } @@ -141,8 +141,8 @@ char* PikaStdData_Dict___str__(PikaObj* self) { int i = 0; while (PIKA_TRUE) { - Arg* item_key = args_getArgByidex(&keys->super, i); - Arg* item_val = args_getArgByidex(&dict->super, i); + Arg* item_key = args_getArgByIndex(&keys->super, i); + Arg* item_val = args_getArgByIndex(&dict->super, i); if (NULL == item_key) { break; } @@ -186,7 +186,7 @@ int PikaStdData_dict_keys___len__(PikaObj* self) { int dict_contains(PikaDict* dict, Arg* key) { int i = 0; while (PIKA_TRUE) { - Arg* item = args_getArgByidex(&dict->super, i); + Arg* item = args_getArgByIndex(&dict->super, i); if (NULL == item) { break; } @@ -219,8 +219,8 @@ Arg* PikaStdData_dict_items___next__(PikaObj* self) { PikaObj* dictptr = obj_getPtr(self, "dictptr"); PikaDict* keys = obj_getPtr(dictptr, "_keys"); PikaDict* dict = obj_getPtr(dictptr, "dict"); - Arg* key = args_getArgByidex(&keys->super, __iter_i); - Arg* val = args_getArgByidex(&dict->super, __iter_i); + Arg* key = args_getArgByIndex(&keys->super, __iter_i); + Arg* val = args_getArgByIndex(&dict->super, __iter_i); if (NULL == key) { return arg_newNull(); } diff --git a/port/linux/.vscode/launch.json b/port/linux/.vscode/launch.json index 3e2d3067c..dae3e3925 100644 --- a/port/linux/.vscode/launch.json +++ b/port/linux/.vscode/launch.json @@ -11,7 +11,7 @@ "program": "${workspaceFolder}/build/test/pikascript_test", // "program": "${workspaceFolder}/build/boot/demo06-pikamain/pikascript_demo06-pikamain", "args": [ - // "--gtest_filter=parser.not_in" + // "--gtest_filter=vm.class_keyword" ], "stopAtEntry": false, "cwd": "${workspaceFolder}", diff --git a/port/linux/package/pikascript/pikascript-lib/PikaStdLib/PikaStdData_Dict.c b/port/linux/package/pikascript/pikascript-lib/PikaStdLib/PikaStdData_Dict.c index 0423fabfa..63447c256 100644 --- a/port/linux/package/pikascript/pikascript-lib/PikaStdLib/PikaStdData_Dict.c +++ b/port/linux/package/pikascript/pikascript-lib/PikaStdLib/PikaStdData_Dict.c @@ -40,7 +40,7 @@ Arg* PikaStdData_Dict___iter__(PikaObj* self) { Arg* PikaStdData_Dict___next__(PikaObj* self) { int __iter_i = args_getInt(self->list, "__iter_i"); PikaDict* keys = obj_getPtr(self, "_keys"); - Arg* res = arg_copy(args_getArgByidex(&keys->super, __iter_i)); + Arg* res = arg_copy(args_getArgByIndex(&keys->super, __iter_i)); if (NULL == res) { return arg_newNull(); } @@ -91,7 +91,7 @@ Arg* PikaStdData_dict_keys___next__(PikaObj* self) { int __iter_i = args_getInt(self->list, "__iter_i"); PikaObj* dictptr = obj_getPtr(self, "dictptr"); PikaDict* keys = obj_getPtr(dictptr, "_keys"); - Arg* res = arg_copy(args_getArgByidex(&keys->super, __iter_i)); + Arg* res = arg_copy(args_getArgByIndex(&keys->super, __iter_i)); if (NULL == res) { return arg_newNull(); } @@ -107,7 +107,7 @@ char* PikaStdData_dict_keys___str__(PikaObj* self) { int i = 0; while (PIKA_TRUE) { - Arg* item = args_getArgByidex(&keys->super, i); + Arg* item = args_getArgByIndex(&keys->super, i); if (NULL == item) { break; } @@ -141,8 +141,8 @@ char* PikaStdData_Dict___str__(PikaObj* self) { int i = 0; while (PIKA_TRUE) { - Arg* item_key = args_getArgByidex(&keys->super, i); - Arg* item_val = args_getArgByidex(&dict->super, i); + Arg* item_key = args_getArgByIndex(&keys->super, i); + Arg* item_val = args_getArgByIndex(&dict->super, i); if (NULL == item_key) { break; } @@ -186,7 +186,7 @@ int PikaStdData_dict_keys___len__(PikaObj* self) { int dict_contains(PikaDict* dict, Arg* key) { int i = 0; while (PIKA_TRUE) { - Arg* item = args_getArgByidex(&dict->super, i); + Arg* item = args_getArgByIndex(&dict->super, i); if (NULL == item) { break; } @@ -219,8 +219,8 @@ Arg* PikaStdData_dict_items___next__(PikaObj* self) { PikaObj* dictptr = obj_getPtr(self, "dictptr"); PikaDict* keys = obj_getPtr(dictptr, "_keys"); PikaDict* dict = obj_getPtr(dictptr, "dict"); - Arg* key = args_getArgByidex(&keys->super, __iter_i); - Arg* val = args_getArgByidex(&dict->super, __iter_i); + Arg* key = args_getArgByIndex(&keys->super, __iter_i); + Arg* val = args_getArgByIndex(&dict->super, __iter_i); if (NULL == key) { return arg_newNull(); } diff --git a/src/PikaVM.c b/src/PikaVM.c index b7d86734c..521473573 100644 --- a/src/PikaVM.c +++ b/src/PikaVM.c @@ -1086,7 +1086,7 @@ static int _get_n_input_with_unpack(VMState* vm) { PikaDict* dict = obj_getPtr(obj, "dict"); int i_item = 0; while (PIKA_TRUE) { - Arg* item_val = args_getArgByidex(&dict->super, i_item); + Arg* item_val = args_getArgByIndex(&dict->super, i_item); if (NULL == item_val) { break; } diff --git a/src/dataArgs.c b/src/dataArgs.c index 04885be3b..64585c416 100644 --- a/src/dataArgs.c +++ b/src/dataArgs.c @@ -411,7 +411,7 @@ Arg* args_getArg(Args* self, char* name) { return (Arg*)node; } -Arg* args_getArgByidex(Args* self, int index) { +Arg* args_getArgByIndex(Args* self, int index) { pika_assert(NULL != self); LinkNode* nodeNow = self->firstNode; if (NULL == nodeNow) { diff --git a/src/dataArgs.h b/src/dataArgs.h index 81cb6d9de..47eb08afe 100644 --- a/src/dataArgs.h +++ b/src/dataArgs.h @@ -112,7 +112,7 @@ PIKA_RES args_foreach(Args* self, char* args_getBuff(Args* self, int32_t size); PIKA_RES args_pushArg(Args* self, Arg* arg); PIKA_RES args_pushArg_name(Args* self, char* name, Arg* arg); -Arg* args_getArgByidex(Args* self, int index); +Arg* args_getArgByIndex(Args* self, int index); void* args_getHeapStruct(Args* self, char* name); PIKA_RES args_removeArg_notDeinitArg(Args* self, Arg* argNow); uint8_t* args_getBytes(Args* self, char* name); diff --git a/test/VM-test.cpp b/test/VM-test.cpp index 2575ed4ae..97e5be1f2 100644 --- a/test/VM-test.cpp +++ b/test/VM-test.cpp @@ -2440,6 +2440,23 @@ TEST(vm, def_not_in) { EXPECT_EQ(pikaMemNow(), 0); } +TEST(vm, fn_pos_kw_issue1) { + /* init */ + pikaMemInfo.heapUsedMax = 0; + PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain); + /* run */ + __platform_printf("BEGIN\r\n"); + obj_run(pikaMain, + "def new(a=1, b=2):\n" + " print(a, b)\n" + "new(3, b = 2)\n"); + /* collect */ + /* assert */ + /* deinit */ + obj_deinit(pikaMain); + EXPECT_EQ(pikaMemNow(), 0); +} + #endif TEST_END \ No newline at end of file diff --git a/test/args-test.cpp b/test/args-test.cpp index a0914bd0a..17a02bb5e 100644 --- a/test/args-test.cpp +++ b/test/args-test.cpp @@ -169,8 +169,8 @@ TEST(args, index) { args_pushArg(args, arg_newInt(1)); args_pushArg(args, arg_newFloat(2.4)); - int a = arg_getInt(args_getArgByidex(args, 1)); - float b = arg_getFloat(args_getArgByidex(args, 0)); + int a = arg_getInt(args_getArgByIndex(args, 1)); + float b = arg_getFloat(args_getArgByIndex(args, 0)); /* assert */ EXPECT_EQ(a, 1); EXPECT_FLOAT_EQ(b, 2.4); From 1ceb015391a2bc9aefcef71f566f2d87253e3dac Mon Sep 17 00:00:00 2001 From: lyon Date: Wed, 21 Dec 2022 00:26:01 +0800 Subject: [PATCH 14/44] fix load err when fn(pos, kw=xxx) --- port/linux/.vscode/launch.json | 2 +- src/PikaVM.c | 34 +++++++++++++++++++--------------- test/VM-test.cpp | 2 ++ 3 files changed, 22 insertions(+), 16 deletions(-) diff --git a/port/linux/.vscode/launch.json b/port/linux/.vscode/launch.json index dae3e3925..cf73cad2f 100644 --- a/port/linux/.vscode/launch.json +++ b/port/linux/.vscode/launch.json @@ -11,7 +11,7 @@ "program": "${workspaceFolder}/build/test/pikascript_test", // "program": "${workspaceFolder}/build/boot/demo06-pikamain/pikascript_demo06-pikamain", "args": [ - // "--gtest_filter=vm.class_keyword" + // "--gtest_filter=vm.fn_pos_kw_issue1" ], "stopAtEntry": false, "cwd": "${workspaceFolder}", diff --git a/src/PikaVM.c b/src/PikaVM.c index 521473573..89cd94a0a 100644 --- a/src/PikaVM.c +++ b/src/PikaVM.c @@ -847,7 +847,8 @@ Arg* obj_runMethodArg(PikaObj* self, static char* _kw_to_default_all(FunctionArgsInfo* f, char* arg_name, int* argc, - Arg* argv[]) { + Arg* argv[], + Arg* call_arg) { #if PIKA_NANO return arg_name; #endif @@ -861,6 +862,17 @@ static char* _kw_to_default_all(FunctionArgsInfo* f, argv[(*argc)++] = arg_new; pikaDict_removeArg(f->kw, default_arg); } + } else { + /* can not load defalut from kw */ + if (NULL != call_arg && f->is_default) { + /* load default from pos */ + if (f->i_arg > f->n_positional) { + arg_setNameHash(call_arg, + hash_time33EndWith(arg_name, ':')); + argv[(*argc)++] = call_arg; + return (char*)1; + } + } } arg_name = strPopLastToken(f->type_list, ','); } @@ -980,20 +992,12 @@ static void _load_call_arg(VMState* vm, } } char* arg_name = strPopLastToken(f->type_list, ','); - /* load default from pos */ - if (f->i_arg > f->n_positional) { - if (f->is_default) { - if (arg_name[strlen(arg_name) - 1] == '=') { - /* found default arg*/ - arg_name[strlen(arg_name) - 1] = '\0'; - arg_setNameHash(call_arg, hash_time33EndWith(arg_name, ':')); - argv[(*argc)++] = call_arg; - } - return; - } - } /* load default from kw */ - arg_name = _kw_to_default_all(f, arg_name, argc, argv); + arg_name = _kw_to_default_all(f, arg_name, argc, argv, call_arg); + if (((char*)1) == arg_name) { + /* load default from pos */ + return; + } /* load position arg */ if (_kw_to_pos_one(f, arg_name, argc, argv)) { /* load pos from kw */ @@ -1235,7 +1239,7 @@ static int VMState_loadArgsFromMethodArg(VMState* vm, #if !PIKA_NANO_ENABLE if (strIsContain(f.type_list, '=')) { char* arg_name = strPopLastToken(f.type_list, ','); - _kw_to_default_all(&f, arg_name, &argc, argv); + _kw_to_default_all(&f, arg_name, &argc, argv, NULL); } /* load kw to pos */ _kw_to_pos_all(&f, &argc, argv); diff --git a/test/VM-test.cpp b/test/VM-test.cpp index 97e5be1f2..c2dbdc094 100644 --- a/test/VM-test.cpp +++ b/test/VM-test.cpp @@ -2452,11 +2452,13 @@ TEST(vm, fn_pos_kw_issue1) { "new(3, b = 2)\n"); /* collect */ /* assert */ + EXPECT_STREQ(log_buff[0], "3 2\r\n"); /* deinit */ obj_deinit(pikaMain); EXPECT_EQ(pikaMemNow(), 0); } + #endif TEST_END \ No newline at end of file From 67b56c9be40b6c1682e1834b1fb8fe17a3366e00 Mon Sep 17 00:00:00 2001 From: dreamcmi <1912544842@qq.com> Date: Wed, 21 Dec 2022 13:04:06 +0800 Subject: [PATCH 15/44] fix socket PIKA_LWIP_ENABLE macro --- package/socket/PikaPlatform_socket.c | 6 +++--- .../pikascript/pikascript-lib/socket/PikaPlatform_socket.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package/socket/PikaPlatform_socket.c b/package/socket/PikaPlatform_socket.c index 753f5aedb..482d7a74b 100644 --- a/package/socket/PikaPlatform_socket.c +++ b/package/socket/PikaPlatform_socket.c @@ -71,7 +71,7 @@ PIKA_WEAK int __platform_recv(int __fd, void* __buf, size_t __n, int __flags) { /* gethostname */ PIKA_WEAK int __platform_gethostname(char* __name, size_t __len) { -#if defined(__linux__) +#if defined(__linux__) || PIKA_LWIP_ENABLE return gethostname(__name, __len); #else WEAK_FUNCTION_NEED_OVERRIDE_ERROR(); @@ -110,7 +110,7 @@ PIKA_WEAK int __platform_setsockopt(int __fd, } PIKA_WEAK int __platform_fcntl(int fd, int cmd, long arg) { -#ifdef __linux__ +#if defined(__linux__) || PIKA_LWIP_ENABLE return fcntl(fd, cmd, arg); #else WEAK_FUNCTION_NEED_OVERRIDE_ERROR(); @@ -119,7 +119,7 @@ PIKA_WEAK int __platform_fcntl(int fd, int cmd, long arg) { /* os file API */ PIKA_WEAK int __platform_close(int __fd) { -#ifdef __linux__ +#if defined(__linux__) || PIKA_LWIP_ENABLE return close(__fd); #elif PIKA_FREERTOS_ENABLE return closesocket(__fd); diff --git a/port/linux/package/pikascript/pikascript-lib/socket/PikaPlatform_socket.c b/port/linux/package/pikascript/pikascript-lib/socket/PikaPlatform_socket.c index 753f5aedb..482d7a74b 100644 --- a/port/linux/package/pikascript/pikascript-lib/socket/PikaPlatform_socket.c +++ b/port/linux/package/pikascript/pikascript-lib/socket/PikaPlatform_socket.c @@ -71,7 +71,7 @@ PIKA_WEAK int __platform_recv(int __fd, void* __buf, size_t __n, int __flags) { /* gethostname */ PIKA_WEAK int __platform_gethostname(char* __name, size_t __len) { -#if defined(__linux__) +#if defined(__linux__) || PIKA_LWIP_ENABLE return gethostname(__name, __len); #else WEAK_FUNCTION_NEED_OVERRIDE_ERROR(); @@ -110,7 +110,7 @@ PIKA_WEAK int __platform_setsockopt(int __fd, } PIKA_WEAK int __platform_fcntl(int fd, int cmd, long arg) { -#ifdef __linux__ +#if defined(__linux__) || PIKA_LWIP_ENABLE return fcntl(fd, cmd, arg); #else WEAK_FUNCTION_NEED_OVERRIDE_ERROR(); @@ -119,7 +119,7 @@ PIKA_WEAK int __platform_fcntl(int fd, int cmd, long arg) { /* os file API */ PIKA_WEAK int __platform_close(int __fd) { -#ifdef __linux__ +#if defined(__linux__) || PIKA_LWIP_ENABLE return close(__fd); #elif PIKA_FREERTOS_ENABLE return closesocket(__fd); From e524c2b6ad6c6ca67ba5aeed1cd500f7f67315f0 Mon Sep 17 00:00:00 2001 From: lyon Date: Wed, 21 Dec 2022 13:08:42 +0800 Subject: [PATCH 16/44] fix fn_pos_kw_issus2 --- port/linux/.vscode/launch.json | 2 +- src/PikaVM.c | 6 ++++-- test/VM-test.cpp | 17 +++++++++++++++++ 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/port/linux/.vscode/launch.json b/port/linux/.vscode/launch.json index cf73cad2f..c5a12a310 100644 --- a/port/linux/.vscode/launch.json +++ b/port/linux/.vscode/launch.json @@ -11,7 +11,7 @@ "program": "${workspaceFolder}/build/test/pikascript_test", // "program": "${workspaceFolder}/build/boot/demo06-pikamain/pikascript_demo06-pikamain", "args": [ - // "--gtest_filter=vm.fn_pos_kw_issue1" + "--gtest_filter=vm.fn_pos_kw_issue2" ], "stopAtEntry": false, "cwd": "${workspaceFolder}", diff --git a/src/PikaVM.c b/src/PikaVM.c index 89cd94a0a..831fd4916 100644 --- a/src/PikaVM.c +++ b/src/PikaVM.c @@ -854,15 +854,17 @@ static char* _kw_to_default_all(FunctionArgsInfo* f, #endif while (strIsContain(arg_name, '=')) { strPopLastToken(arg_name, '='); + Arg* default_arg = NULL; /* load default arg from kws */ if (f->kw != NULL) { - Arg* default_arg = pikaDict_getArg(f->kw, arg_name); + default_arg = pikaDict_getArg(f->kw, arg_name); if (default_arg != NULL) { Arg* arg_new = arg_copy(default_arg); argv[(*argc)++] = arg_new; pikaDict_removeArg(f->kw, default_arg); } - } else { + } + if (f->kw == NULL || default_arg == NULL) { /* can not load defalut from kw */ if (NULL != call_arg && f->is_default) { /* load default from pos */ diff --git a/test/VM-test.cpp b/test/VM-test.cpp index c2dbdc094..3ee86e6c5 100644 --- a/test/VM-test.cpp +++ b/test/VM-test.cpp @@ -2458,6 +2458,23 @@ TEST(vm, fn_pos_kw_issue1) { EXPECT_EQ(pikaMemNow(), 0); } +TEST(vm, fn_pos_kw_issue2) { + /* init */ + pikaMemInfo.heapUsedMax = 0; + PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain); + /* run */ + __platform_printf("BEGIN\r\n"); + obj_run(pikaMain, + "def new(key:any, msg=None, digestmod=\"md5\"):\n" + " print(key, msg, digestmod)\n" + "new('123','456',digestmod=\"md5\")\n"); + /* collect */ + /* assert */ + EXPECT_STREQ(log_buff[0], "123 456 md5\r\n"); + /* deinit */ + obj_deinit(pikaMain); + EXPECT_EQ(pikaMemNow(), 0); +} #endif From f400b027d972bc4e1f9c953536c3d6caaf268215 Mon Sep 17 00:00:00 2001 From: lyon Date: Thu, 22 Dec 2022 14:22:39 +0800 Subject: [PATCH 17/44] add HAL_EVENT_CALLBACK_ENA config --- package/PikaStdDevice/pika_hal.c | 4 ++++ package/PikaStdDevice/pika_hal.h | 8 ++++++++ .../pikascript/pikascript-lib/PikaStdDevice/pika_hal.c | 4 ++++ .../pikascript/pikascript-lib/PikaStdDevice/pika_hal.h | 8 ++++++++ 4 files changed, 24 insertions(+) diff --git a/package/PikaStdDevice/pika_hal.c b/package/PikaStdDevice/pika_hal.c index 1b241f88c..7350a9ce1 100644 --- a/package/PikaStdDevice/pika_hal.c +++ b/package/PikaStdDevice/pika_hal.c @@ -185,6 +185,8 @@ int pika_hal_GPIO_ioctl_merge_config(pika_hal_GPIO_config* dst, _IOCTL_CONFIG_USE_DEFAULT(speed, PIKA_HAL_GPIO_SPEED_10M); _IOCTL_CONFIG_USE_DEFAULT(event_callback_rising, NULL); _IOCTL_CONFIG_USE_DEFAULT(event_callback_falling, NULL); + _IOCTL_CONFIG_USE_DEFAULT(event_callback_enable, + PIKA_HAL_EVENT_CALLBACK_ENA_ENABLE); return 0; } @@ -195,6 +197,8 @@ int pika_hal_UART_ioctl_merge_config(pika_hal_UART_config* dst, _IOCTL_CONFIG_USE_DEFAULT(stop_bits, PIKA_HAL_UART_STOP_BITS_1); _IOCTL_CONFIG_USE_DEFAULT(parity, PIKA_HAL_UART_PARITY_NONE); _IOCTL_CONFIG_USE_DEFAULT(event_callback_rx, NULL); + _IOCTL_CONFIG_USE_DEFAULT(event_callback_enable, + PIKA_HAL_EVENT_CALLBACK_ENA_ENABLE); return 0; } diff --git a/package/PikaStdDevice/pika_hal.h b/package/PikaStdDevice/pika_hal.h index 69df5ab3c..561828423 100644 --- a/package/PikaStdDevice/pika_hal.h +++ b/package/PikaStdDevice/pika_hal.h @@ -58,12 +58,19 @@ typedef enum { PIKA_HAL_GPIO_SPEED_100M = 100000000, } PIKA_HAL_GPIO_SPEED; +typedef enum { + _PIKA_HAL_EVENT_CALLBACK_ENA_UNUSED = 0, + PIKA_HAL_EVENT_CALLBACK_ENA_ENABLE, + PIKA_HAL_EVENT_CALLBACK_ENA_DISABLE, +} PIKA_HAL_EVENT_CALLBACK_ENA; + typedef struct { PIKA_HAL_GPIO_DIR dir; PIKA_HAL_GPIO_PULL pull; PIKA_HAL_GPIO_SPEED speed; void (*event_callback_rising)(pika_dev* dev); void (*event_callback_falling)(pika_dev* dev); + PIKA_HAL_EVENT_CALLBACK_ENA event_callback_enable; } pika_hal_GPIO_config; typedef enum { @@ -104,6 +111,7 @@ typedef struct { PIKA_HAL_UART_STOP_BITS stop_bits; PIKA_HAL_UART_PARITY parity; void (*event_callback_rx)(pika_dev* dev); + PIKA_HAL_EVENT_CALLBACK_ENA event_callback_enable; } pika_hal_UART_config; typedef uint32_t PIKA_HAL_IIC_SLAVE_ADDR; diff --git a/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/pika_hal.c b/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/pika_hal.c index 1b241f88c..7350a9ce1 100644 --- a/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/pika_hal.c +++ b/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/pika_hal.c @@ -185,6 +185,8 @@ int pika_hal_GPIO_ioctl_merge_config(pika_hal_GPIO_config* dst, _IOCTL_CONFIG_USE_DEFAULT(speed, PIKA_HAL_GPIO_SPEED_10M); _IOCTL_CONFIG_USE_DEFAULT(event_callback_rising, NULL); _IOCTL_CONFIG_USE_DEFAULT(event_callback_falling, NULL); + _IOCTL_CONFIG_USE_DEFAULT(event_callback_enable, + PIKA_HAL_EVENT_CALLBACK_ENA_ENABLE); return 0; } @@ -195,6 +197,8 @@ int pika_hal_UART_ioctl_merge_config(pika_hal_UART_config* dst, _IOCTL_CONFIG_USE_DEFAULT(stop_bits, PIKA_HAL_UART_STOP_BITS_1); _IOCTL_CONFIG_USE_DEFAULT(parity, PIKA_HAL_UART_PARITY_NONE); _IOCTL_CONFIG_USE_DEFAULT(event_callback_rx, NULL); + _IOCTL_CONFIG_USE_DEFAULT(event_callback_enable, + PIKA_HAL_EVENT_CALLBACK_ENA_ENABLE); return 0; } diff --git a/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/pika_hal.h b/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/pika_hal.h index 69df5ab3c..561828423 100644 --- a/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/pika_hal.h +++ b/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/pika_hal.h @@ -58,12 +58,19 @@ typedef enum { PIKA_HAL_GPIO_SPEED_100M = 100000000, } PIKA_HAL_GPIO_SPEED; +typedef enum { + _PIKA_HAL_EVENT_CALLBACK_ENA_UNUSED = 0, + PIKA_HAL_EVENT_CALLBACK_ENA_ENABLE, + PIKA_HAL_EVENT_CALLBACK_ENA_DISABLE, +} PIKA_HAL_EVENT_CALLBACK_ENA; + typedef struct { PIKA_HAL_GPIO_DIR dir; PIKA_HAL_GPIO_PULL pull; PIKA_HAL_GPIO_SPEED speed; void (*event_callback_rising)(pika_dev* dev); void (*event_callback_falling)(pika_dev* dev); + PIKA_HAL_EVENT_CALLBACK_ENA event_callback_enable; } pika_hal_GPIO_config; typedef enum { @@ -104,6 +111,7 @@ typedef struct { PIKA_HAL_UART_STOP_BITS stop_bits; PIKA_HAL_UART_PARITY parity; void (*event_callback_rx)(pika_dev* dev); + PIKA_HAL_EVENT_CALLBACK_ENA event_callback_enable; } pika_hal_UART_config; typedef uint32_t PIKA_HAL_IIC_SLAVE_ADDR; From 2bf121afcb5fdee15d35030b23be93d2fb936095 Mon Sep 17 00:00:00 2001 From: lyon Date: Thu, 22 Dec 2022 14:54:51 +0800 Subject: [PATCH 18/44] use EVENT_SIGNAL on event_callback --- package/PikaStdDevice/pika_hal.c | 5 ++--- package/PikaStdDevice/pika_hal.h | 14 +++++++++++--- .../pikascript-lib/PikaStdDevice/pika_hal.c | 5 ++--- .../pikascript-lib/PikaStdDevice/pika_hal.h | 14 +++++++++++--- 4 files changed, 26 insertions(+), 12 deletions(-) diff --git a/package/PikaStdDevice/pika_hal.c b/package/PikaStdDevice/pika_hal.c index 7350a9ce1..c8a975dfd 100644 --- a/package/PikaStdDevice/pika_hal.c +++ b/package/PikaStdDevice/pika_hal.c @@ -183,8 +183,7 @@ int pika_hal_GPIO_ioctl_merge_config(pika_hal_GPIO_config* dst, // printf("after merge: dst->dir=%d, src->dir=%d\r\n", dst->dir, src->dir); _IOCTL_CONFIG_USE_DEFAULT(pull, PIKA_HAL_GPIO_PULL_NONE); _IOCTL_CONFIG_USE_DEFAULT(speed, PIKA_HAL_GPIO_SPEED_10M); - _IOCTL_CONFIG_USE_DEFAULT(event_callback_rising, NULL); - _IOCTL_CONFIG_USE_DEFAULT(event_callback_falling, NULL); + _IOCTL_CONFIG_USE_DEFAULT(event_callback, NULL); _IOCTL_CONFIG_USE_DEFAULT(event_callback_enable, PIKA_HAL_EVENT_CALLBACK_ENA_ENABLE); return 0; @@ -196,7 +195,7 @@ int pika_hal_UART_ioctl_merge_config(pika_hal_UART_config* dst, _IOCTL_CONFIG_USE_DEFAULT(data_bits, PIKA_HAL_UART_DATA_BITS_8); _IOCTL_CONFIG_USE_DEFAULT(stop_bits, PIKA_HAL_UART_STOP_BITS_1); _IOCTL_CONFIG_USE_DEFAULT(parity, PIKA_HAL_UART_PARITY_NONE); - _IOCTL_CONFIG_USE_DEFAULT(event_callback_rx, NULL); + _IOCTL_CONFIG_USE_DEFAULT(event_callback, NULL); _IOCTL_CONFIG_USE_DEFAULT(event_callback_enable, PIKA_HAL_EVENT_CALLBACK_ENA_ENABLE); return 0; diff --git a/package/PikaStdDevice/pika_hal.h b/package/PikaStdDevice/pika_hal.h index 561828423..70cc5d22c 100644 --- a/package/PikaStdDevice/pika_hal.h +++ b/package/PikaStdDevice/pika_hal.h @@ -64,12 +64,16 @@ typedef enum { PIKA_HAL_EVENT_CALLBACK_ENA_DISABLE, } PIKA_HAL_EVENT_CALLBACK_ENA; +typedef enum { + PIKA_HAL_GPIO_EVENT_SIGNAL_RISING, + PIKA_HAL_GPIO_EVENT_SIGNAL_FALLING, +} PIKA_HAL_GPIO_EVENT_SIGNAL; + typedef struct { PIKA_HAL_GPIO_DIR dir; PIKA_HAL_GPIO_PULL pull; PIKA_HAL_GPIO_SPEED speed; - void (*event_callback_rising)(pika_dev* dev); - void (*event_callback_falling)(pika_dev* dev); + void (*event_callback)(pika_dev* dev, PIKA_HAL_GPIO_EVENT_SIGNAL signal); PIKA_HAL_EVENT_CALLBACK_ENA event_callback_enable; } pika_hal_GPIO_config; @@ -105,12 +109,16 @@ typedef enum { PIKA_HAL_UART_PARITY_EVEN, } PIKA_HAL_UART_PARITY; +typedef enum { + PIKA_HAL_UART_EVENT_SIGNAL_RX, +} PIKA_HAL_UART_EVENT_SIGNAL; + typedef struct { PIKA_HAL_UART_BAUDRATE baudrate; PIKA_HAL_UART_DATA_BITS data_bits; PIKA_HAL_UART_STOP_BITS stop_bits; PIKA_HAL_UART_PARITY parity; - void (*event_callback_rx)(pika_dev* dev); + void (*event_callback)(pika_dev* dev, PIKA_HAL_UART_EVENT_SIGNAL signal); PIKA_HAL_EVENT_CALLBACK_ENA event_callback_enable; } pika_hal_UART_config; diff --git a/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/pika_hal.c b/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/pika_hal.c index 7350a9ce1..c8a975dfd 100644 --- a/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/pika_hal.c +++ b/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/pika_hal.c @@ -183,8 +183,7 @@ int pika_hal_GPIO_ioctl_merge_config(pika_hal_GPIO_config* dst, // printf("after merge: dst->dir=%d, src->dir=%d\r\n", dst->dir, src->dir); _IOCTL_CONFIG_USE_DEFAULT(pull, PIKA_HAL_GPIO_PULL_NONE); _IOCTL_CONFIG_USE_DEFAULT(speed, PIKA_HAL_GPIO_SPEED_10M); - _IOCTL_CONFIG_USE_DEFAULT(event_callback_rising, NULL); - _IOCTL_CONFIG_USE_DEFAULT(event_callback_falling, NULL); + _IOCTL_CONFIG_USE_DEFAULT(event_callback, NULL); _IOCTL_CONFIG_USE_DEFAULT(event_callback_enable, PIKA_HAL_EVENT_CALLBACK_ENA_ENABLE); return 0; @@ -196,7 +195,7 @@ int pika_hal_UART_ioctl_merge_config(pika_hal_UART_config* dst, _IOCTL_CONFIG_USE_DEFAULT(data_bits, PIKA_HAL_UART_DATA_BITS_8); _IOCTL_CONFIG_USE_DEFAULT(stop_bits, PIKA_HAL_UART_STOP_BITS_1); _IOCTL_CONFIG_USE_DEFAULT(parity, PIKA_HAL_UART_PARITY_NONE); - _IOCTL_CONFIG_USE_DEFAULT(event_callback_rx, NULL); + _IOCTL_CONFIG_USE_DEFAULT(event_callback, NULL); _IOCTL_CONFIG_USE_DEFAULT(event_callback_enable, PIKA_HAL_EVENT_CALLBACK_ENA_ENABLE); return 0; diff --git a/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/pika_hal.h b/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/pika_hal.h index 561828423..70cc5d22c 100644 --- a/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/pika_hal.h +++ b/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/pika_hal.h @@ -64,12 +64,16 @@ typedef enum { PIKA_HAL_EVENT_CALLBACK_ENA_DISABLE, } PIKA_HAL_EVENT_CALLBACK_ENA; +typedef enum { + PIKA_HAL_GPIO_EVENT_SIGNAL_RISING, + PIKA_HAL_GPIO_EVENT_SIGNAL_FALLING, +} PIKA_HAL_GPIO_EVENT_SIGNAL; + typedef struct { PIKA_HAL_GPIO_DIR dir; PIKA_HAL_GPIO_PULL pull; PIKA_HAL_GPIO_SPEED speed; - void (*event_callback_rising)(pika_dev* dev); - void (*event_callback_falling)(pika_dev* dev); + void (*event_callback)(pika_dev* dev, PIKA_HAL_GPIO_EVENT_SIGNAL signal); PIKA_HAL_EVENT_CALLBACK_ENA event_callback_enable; } pika_hal_GPIO_config; @@ -105,12 +109,16 @@ typedef enum { PIKA_HAL_UART_PARITY_EVEN, } PIKA_HAL_UART_PARITY; +typedef enum { + PIKA_HAL_UART_EVENT_SIGNAL_RX, +} PIKA_HAL_UART_EVENT_SIGNAL; + typedef struct { PIKA_HAL_UART_BAUDRATE baudrate; PIKA_HAL_UART_DATA_BITS data_bits; PIKA_HAL_UART_STOP_BITS stop_bits; PIKA_HAL_UART_PARITY parity; - void (*event_callback_rx)(pika_dev* dev); + void (*event_callback)(pika_dev* dev, PIKA_HAL_UART_EVENT_SIGNAL signal); PIKA_HAL_EVENT_CALLBACK_ENA event_callback_enable; } pika_hal_UART_config; From f266440a77ee34b4b11c17c5c88751eeee5007f9 Mon Sep 17 00:00:00 2001 From: lyon Date: Thu, 22 Dec 2022 15:30:48 +0800 Subject: [PATCH 19/44] fix args_getArgByIndex --- src/dataArgs.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/dataArgs.h b/src/dataArgs.h index 47eb08afe..f7ec3b227 100644 --- a/src/dataArgs.h +++ b/src/dataArgs.h @@ -112,7 +112,6 @@ PIKA_RES args_foreach(Args* self, char* args_getBuff(Args* self, int32_t size); PIKA_RES args_pushArg(Args* self, Arg* arg); PIKA_RES args_pushArg_name(Args* self, char* name, Arg* arg); -Arg* args_getArgByIndex(Args* self, int index); void* args_getHeapStruct(Args* self, char* name); PIKA_RES args_removeArg_notDeinitArg(Args* self, Arg* argNow); uint8_t* args_getBytes(Args* self, char* name); From e891b5bed5ffb928fe32a8eabfbee80a26f7d07f Mon Sep 17 00:00:00 2001 From: lyon Date: Thu, 22 Dec 2022 15:33:15 +0800 Subject: [PATCH 20/44] fix type of args_getArgByIndex --- src/PikaVersion.h | 2 +- src/dataArgs.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/PikaVersion.h b/src/PikaVersion.h index 54bc29906..dc2a686c9 100644 --- a/src/PikaVersion.h +++ b/src/PikaVersion.h @@ -2,4 +2,4 @@ #define PIKA_VERSION_MINOR 11 #define PIKA_VERSION_MICRO 9 -#define PIKA_EDIT_TIME "2022/12/17 16:02:58" +#define PIKA_EDIT_TIME "2022/12/22 15:33:13" diff --git a/src/dataArgs.h b/src/dataArgs.h index f7ec3b227..7239f9551 100644 --- a/src/dataArgs.h +++ b/src/dataArgs.h @@ -41,7 +41,7 @@ void args_init(Args* self, Args* args); int32_t args_getSize(Args* self); LinkNode* args_getNode(Args* self, char* name); -Arg* args_getArgByIndex(Args* self, int32_t index); +Arg* args_getArgByIndex(Args* self, int index); Arg* args_getArg(Args* self, char* name); PIKA_RES args_removeArg(Args* self, Arg* argNow); PIKA_RES args_moveArg(Args* self, Args* dict, Arg* arg); From a49dec9f12b9de3cda2e7b908a12d1d42b76e2f3 Mon Sep 17 00:00:00 2001 From: dreamcmi <1912544842@qq.com> Date: Thu, 22 Dec 2022 16:28:25 +0800 Subject: [PATCH 21/44] rename base64.pyi to _base64.pyi --- package/base64/{base64.c => _base64.c} | 6 +++--- package/base64/_base64.pyi | 2 ++ package/base64/base64.py | 9 +++++++++ package/base64/base64.pyi | 2 -- port/linux/package/pikascript/_base64.pyi | 2 ++ port/linux/package/pikascript/base64.py | 9 +++++++++ .../pikascript-lib/base64/{base64.c => _base64.c} | 6 +++--- 7 files changed, 28 insertions(+), 8 deletions(-) rename package/base64/{base64.c => _base64.c} (92%) create mode 100644 package/base64/_base64.pyi create mode 100644 package/base64/base64.py delete mode 100644 package/base64/base64.pyi create mode 100644 port/linux/package/pikascript/_base64.pyi create mode 100644 port/linux/package/pikascript/base64.py rename port/linux/package/pikascript/pikascript-lib/base64/{base64.c => _base64.c} (92%) diff --git a/package/base64/base64.c b/package/base64/_base64.c similarity index 92% rename from package/base64/base64.c rename to package/base64/_base64.c index 4368f5e31..986a634fb 100644 --- a/package/base64/base64.c +++ b/package/base64/_base64.c @@ -1,8 +1,8 @@ -#include "base64.h" +#include "_base64.h" #include "mbedtls/base64.h" -Arg* base64_b64decode(PikaObj* self, Arg* s) { +Arg* _base64_b64decode(PikaObj* self, Arg* s) { ArgType t = arg_getType(s); if (ARG_TYPE_BYTES != t) { obj_setErrorCode(self, -2); // io error @@ -21,7 +21,7 @@ Arg* base64_b64decode(PikaObj* self, Arg* s) { return r; } -Arg* base64_b64encode(PikaObj* self, Arg* s) { +Arg* _base64_b64encode(PikaObj* self, Arg* s) { ArgType t = arg_getType(s); if (ARG_TYPE_BYTES != t) { obj_setErrorCode(self, -2); // io error diff --git a/package/base64/_base64.pyi b/package/base64/_base64.pyi new file mode 100644 index 000000000..a59462791 --- /dev/null +++ b/package/base64/_base64.pyi @@ -0,0 +1,2 @@ +def b64encode(s: any) -> any: ... +def b64decode(s: any) -> any: ... diff --git a/package/base64/base64.py b/package/base64/base64.py new file mode 100644 index 000000000..3428e7ee9 --- /dev/null +++ b/package/base64/base64.py @@ -0,0 +1,9 @@ +import _base64 + + +def b64encode(s: any): + return _base64.b64encode(s) + + +def b64decode(s: any): + return _base64.b64decode(s) diff --git a/package/base64/base64.pyi b/package/base64/base64.pyi deleted file mode 100644 index df03b5daa..000000000 --- a/package/base64/base64.pyi +++ /dev/null @@ -1,2 +0,0 @@ -def b64encode(self, s:any) -> any: ... -def b64decode(self, s:any) -> any: ... diff --git a/port/linux/package/pikascript/_base64.pyi b/port/linux/package/pikascript/_base64.pyi new file mode 100644 index 000000000..a59462791 --- /dev/null +++ b/port/linux/package/pikascript/_base64.pyi @@ -0,0 +1,2 @@ +def b64encode(s: any) -> any: ... +def b64decode(s: any) -> any: ... diff --git a/port/linux/package/pikascript/base64.py b/port/linux/package/pikascript/base64.py new file mode 100644 index 000000000..3428e7ee9 --- /dev/null +++ b/port/linux/package/pikascript/base64.py @@ -0,0 +1,9 @@ +import _base64 + + +def b64encode(s: any): + return _base64.b64encode(s) + + +def b64decode(s: any): + return _base64.b64decode(s) diff --git a/port/linux/package/pikascript/pikascript-lib/base64/base64.c b/port/linux/package/pikascript/pikascript-lib/base64/_base64.c similarity index 92% rename from port/linux/package/pikascript/pikascript-lib/base64/base64.c rename to port/linux/package/pikascript/pikascript-lib/base64/_base64.c index 4368f5e31..986a634fb 100644 --- a/port/linux/package/pikascript/pikascript-lib/base64/base64.c +++ b/port/linux/package/pikascript/pikascript-lib/base64/_base64.c @@ -1,8 +1,8 @@ -#include "base64.h" +#include "_base64.h" #include "mbedtls/base64.h" -Arg* base64_b64decode(PikaObj* self, Arg* s) { +Arg* _base64_b64decode(PikaObj* self, Arg* s) { ArgType t = arg_getType(s); if (ARG_TYPE_BYTES != t) { obj_setErrorCode(self, -2); // io error @@ -21,7 +21,7 @@ Arg* base64_b64decode(PikaObj* self, Arg* s) { return r; } -Arg* base64_b64encode(PikaObj* self, Arg* s) { +Arg* _base64_b64encode(PikaObj* self, Arg* s) { ArgType t = arg_getType(s); if (ARG_TYPE_BYTES != t) { obj_setErrorCode(self, -2); // io error From 29ad2b44817c5a72ace9f6d09cea7df6beb516f9 Mon Sep 17 00:00:00 2001 From: dreamcmi <1912544842@qq.com> Date: Thu, 22 Dec 2022 16:36:49 +0800 Subject: [PATCH 22/44] rm old base64.pyi --- port/linux/package/pikascript/base64.pyi | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 port/linux/package/pikascript/base64.pyi diff --git a/port/linux/package/pikascript/base64.pyi b/port/linux/package/pikascript/base64.pyi deleted file mode 100644 index df03b5daa..000000000 --- a/port/linux/package/pikascript/base64.pyi +++ /dev/null @@ -1,2 +0,0 @@ -def b64encode(self, s:any) -> any: ... -def b64decode(self, s:any) -> any: ... From 23be8b583f1e374f3823e4d47383ed9645dc789e Mon Sep 17 00:00:00 2001 From: dreamcmi <1912544842@qq.com> Date: Thu, 22 Dec 2022 16:37:29 +0800 Subject: [PATCH 23/44] fix base64 release --- packages.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages.toml b/packages.toml index 4863c71c2..4a5208630 100644 --- a/packages.toml +++ b/packages.toml @@ -465,5 +465,5 @@ releases = [ "v0.0.1 5c45cba0c39d447fbe7a4a082ee3170188c3bcb7" ] name = "base64" releases = [ "v0.0.1 1ae3ac23759fb2b5e0f77866af40986ac94e356d", - "v1.0.0 d75ce00c377e48c6058bbe1f824474802383e5e7" + "v1.0.0 29ad2b44817c5a72ace9f6d09cea7df6beb516f9" ] From 537958d1c42270d4ec0c84afeca171c55d860151 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=98=82?= Date: Thu, 22 Dec 2022 13:18:13 +0000 Subject: [PATCH 24/44] add examples/Device/GPIO_CALLBCK.py. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 李昂 --- examples/Device/GPIO_CALLBCK.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 examples/Device/GPIO_CALLBCK.py diff --git a/examples/Device/GPIO_CALLBCK.py b/examples/Device/GPIO_CALLBCK.py new file mode 100644 index 000000000..284421d9f --- /dev/null +++ b/examples/Device/GPIO_CALLBCK.py @@ -0,0 +1,15 @@ +import PikaStdDevice as std +print('hello pikascript') + +io = std.GPIO() +io.setPin('P4') +io.setMode('in') +io.enable() + +def cb1(signal): + print('cb1', signal) + +io.addEventCallBack(cb1, io.SIGNAL_FALLING) + +while True: + pass From 64091bcd551859f42bf64476a10f22e04cf99460 Mon Sep 17 00:00:00 2001 From: lyon Date: Fri, 23 Dec 2022 17:57:49 +0800 Subject: [PATCH 25/44] fix platform_getTick, fix socket LWIP gethostname --- package/PikaStdDevice/PikaStdDevice_Time.c | 2 +- package/socket/PikaPlatform_socket.c | 2 +- .../pikascript-lib/PikaStdDevice/PikaStdDevice_Time.c | 2 +- .../pikascript/pikascript-lib/socket/PikaPlatform_socket.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package/PikaStdDevice/PikaStdDevice_Time.c b/package/PikaStdDevice/PikaStdDevice_Time.c index caa8ae5ce..bc1084df0 100644 --- a/package/PikaStdDevice/PikaStdDevice_Time.c +++ b/package/PikaStdDevice/PikaStdDevice_Time.c @@ -28,7 +28,7 @@ void PikaStdDevice_Time_sleep_s(PikaObj* self, int s) { } void PikaStdDevice_Time_platformGetTick(PikaObj* self) { - obj_setInt(self, "tick", __platform_get_tick_ms()); + obj_setInt(self, "tick", __platform_getTick()); } /* diff --git a/package/socket/PikaPlatform_socket.c b/package/socket/PikaPlatform_socket.c index 482d7a74b..66cce47f7 100644 --- a/package/socket/PikaPlatform_socket.c +++ b/package/socket/PikaPlatform_socket.c @@ -71,7 +71,7 @@ PIKA_WEAK int __platform_recv(int __fd, void* __buf, size_t __n, int __flags) { /* gethostname */ PIKA_WEAK int __platform_gethostname(char* __name, size_t __len) { -#if defined(__linux__) || PIKA_LWIP_ENABLE +#if defined(__linux__) return gethostname(__name, __len); #else WEAK_FUNCTION_NEED_OVERRIDE_ERROR(); diff --git a/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_Time.c b/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_Time.c index caa8ae5ce..bc1084df0 100644 --- a/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_Time.c +++ b/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_Time.c @@ -28,7 +28,7 @@ void PikaStdDevice_Time_sleep_s(PikaObj* self, int s) { } void PikaStdDevice_Time_platformGetTick(PikaObj* self) { - obj_setInt(self, "tick", __platform_get_tick_ms()); + obj_setInt(self, "tick", __platform_getTick()); } /* diff --git a/port/linux/package/pikascript/pikascript-lib/socket/PikaPlatform_socket.c b/port/linux/package/pikascript/pikascript-lib/socket/PikaPlatform_socket.c index 482d7a74b..66cce47f7 100644 --- a/port/linux/package/pikascript/pikascript-lib/socket/PikaPlatform_socket.c +++ b/port/linux/package/pikascript/pikascript-lib/socket/PikaPlatform_socket.c @@ -71,7 +71,7 @@ PIKA_WEAK int __platform_recv(int __fd, void* __buf, size_t __n, int __flags) { /* gethostname */ PIKA_WEAK int __platform_gethostname(char* __name, size_t __len) { -#if defined(__linux__) || PIKA_LWIP_ENABLE +#if defined(__linux__) return gethostname(__name, __len); #else WEAK_FUNCTION_NEED_OVERRIDE_ERROR(); From d0c62dc249f8f47e158c59fe66ae10bd4c941406 Mon Sep 17 00:00:00 2001 From: lyon Date: Fri, 23 Dec 2022 18:03:41 +0800 Subject: [PATCH 26/44] fix lvgl typo, cancel requests post test --- package/pika_lvgl/pika_lv_wegit.c | 2 +- package/pika_lvgl/pika_lvgl.c | 4 ++-- test/requests-test.cpp | 3 +++ 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/package/pika_lvgl/pika_lv_wegit.c b/package/pika_lvgl/pika_lv_wegit.c index 5840dce6d..87b02aab6 100644 --- a/package/pika_lvgl/pika_lv_wegit.c +++ b/package/pika_lvgl/pika_lv_wegit.c @@ -125,7 +125,7 @@ void pika_lvgl_bar___init__(PikaObj* self, PikaObj* parent) { void pika_lvgl_bar_set_value(PikaObj* self, int value, int anim) { lv_obj_t* lv_obj = obj_getPtr(self, "lv_obj"); - lv_bar_set_value(lv_obj, value, value); + lv_bar_set_value(lv_obj, value, anim); } int pika_lvgl_bar_get_max_value(PikaObj* self) { diff --git a/package/pika_lvgl/pika_lvgl.c b/package/pika_lvgl/pika_lvgl.c index 5a6d7e550..3e2617f00 100644 --- a/package/pika_lvgl/pika_lvgl.c +++ b/package/pika_lvgl/pika_lvgl.c @@ -88,8 +88,8 @@ void pika_lvgl_TEXT_DECOR___init__(PikaObj* self) { } void pika_lvgl_ANIM___init__(PikaObj* self) { - obj_setInt(self, "ON", LV_ANIM_OFF); - obj_setInt(self, "OFF", LV_ANIM_ON); + obj_setInt(self, "ON", LV_ANIM_ON); + obj_setInt(self, "OFF", LV_ANIM_OFF); } void pika_lvgl_ALIGN___init__(PikaObj* self) { diff --git a/test/requests-test.cpp b/test/requests-test.cpp index 148710a31..a7c7e33b4 100644 --- a/test/requests-test.cpp +++ b/test/requests-test.cpp @@ -267,6 +267,8 @@ TEST(requests, get_basic) { EXPECT_EQ(pikaMemNow(), 0); } +//! Enable it manually if needed +#if 0 TEST(requests, post_data) { PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain); extern unsigned char pikaModules_py_a[]; @@ -278,5 +280,6 @@ TEST(requests, post_data) { obj_deinit(pikaMain); EXPECT_EQ(pikaMemNow(), 0); } +#endif #endif From 55508d7e84747017869870c1c8e97e189d5ab5db Mon Sep 17 00:00:00 2001 From: lyon Date: Fri, 23 Dec 2022 18:11:49 +0800 Subject: [PATCH 27/44] support del(x) --- port/linux/.vscode/launch.json | 2 +- src/PikaParser.c | 10 ++++++++-- src/PikaPlatform.c | 6 ------ src/PikaPlatform.h | 3 ++- test/parse-test.cpp | 15 +++++++++++++++ 5 files changed, 26 insertions(+), 10 deletions(-) diff --git a/port/linux/.vscode/launch.json b/port/linux/.vscode/launch.json index c5a12a310..6543a1d0f 100644 --- a/port/linux/.vscode/launch.json +++ b/port/linux/.vscode/launch.json @@ -11,7 +11,7 @@ "program": "${workspaceFolder}/build/test/pikascript_test", // "program": "${workspaceFolder}/build/boot/demo06-pikamain/pikascript_demo06-pikamain", "args": [ - "--gtest_filter=vm.fn_pos_kw_issue2" + // "--gtest_filter=vm.fn_pos_kw_issue2" ], "stopAtEntry": false, "cwd": "${workspaceFolder}", diff --git a/src/PikaParser.c b/src/PikaParser.c index 13a494252..3149e032c 100644 --- a/src/PikaParser.c +++ b/src/PikaParser.c @@ -2046,9 +2046,15 @@ AST* AST_parseLine_withBlockStack_withBlockDeepth(char* line, AST_setNodeAttr(ast, "global", global_list); goto block_matched; } - if (strIsStartWith(line_start, "del ")) { + if (strIsStartWith(line_start, "del ") || + strIsStartWith(line_start, "del(")) { stmt = ""; - char* del_dir = line_start + sizeof("del ") - 1; + char* del_dir = NULL; + if (line_start[3] == '(') { + del_dir = strsCut(&buffs, line_start, '(', ')'); + } else { + del_dir = line_start + sizeof("del ") - 1; + } del_dir = strsGetCleanCmd(&buffs, del_dir); AST_setNodeAttr(ast, "del", del_dir); goto block_matched; diff --git a/src/PikaPlatform.c b/src/PikaPlatform.c index 7e77b866e..4a55de0b2 100644 --- a/src/PikaPlatform.c +++ b/src/PikaPlatform.c @@ -254,12 +254,6 @@ PIKA_WEAK void __platform_thread_delay(void) { return; } -PIKA_WEAK uint64_t __platform_get_tick_ms(void){ - __platform_printf("Error: __platform_get_tick_ms need implementation!\r\n"); - while (1) { - } -} - PIKA_WEAK void __platform_sleep_ms(uint32_t ms){ __platform_printf("Error: __platform_sleep_ms need implementation!\r\n"); while (1) { diff --git a/src/PikaPlatform.h b/src/PikaPlatform.h index 2107138a8..41c0a9c62 100644 --- a/src/PikaPlatform.h +++ b/src/PikaPlatform.h @@ -174,7 +174,8 @@ void __platform_panic_handle(void); void __pks_hook_instruct(void); PIKA_BOOL __pks_hook_arg_cache_filter(void* self); void __platform_thread_delay(void); -uint64_t __platform_get_tick_ms(void); +int64_t __platform_getTick(void); + void __platform_sleep_ms(uint32_t ms); void __platform_sleep_s(uint32_t s); diff --git a/test/parse-test.cpp b/test/parse-test.cpp index a6b518b0a..44b5f6aa4 100644 --- a/test/parse-test.cpp +++ b/test/parse-test.cpp @@ -3644,6 +3644,21 @@ TEST(parser, _del) { EXPECT_EQ(pikaMemNow(), 0); } +TEST(parser, _del_issue1) { + pikaMemInfo.heapUsedMax = 0; + Args* buffs = New_strBuff(); + char* lines = "del(a)\n"; + __platform_printf("%s\n", lines); + char* pikaAsm = Parser_linesToAsm(buffs, lines); + __platform_printf("%s", pikaAsm); + EXPECT_STREQ(pikaAsm, + "B0\n" + "0 DEL a\n" + "B0\n"); + args_deinit(buffs); + EXPECT_EQ(pikaMemNow(), 0); +} + #if PIKA_SYNTAX_SLICE_ENABLE TEST(parser, issue_fa13f4) { pikaMemInfo.heapUsedMax = 0; From 36ef746f5791a57212cc1d02fe885814e613e60c Mon Sep 17 00:00:00 2001 From: lyon Date: Fri, 23 Dec 2022 18:16:53 +0800 Subject: [PATCH 28/44] add_files --- package/PikaStdDevice/PikaStdDevice.pyi | 41 +++++++++++++++++++--- package/PikaStdDevice/PikaStdDevice_GPIO.c | 38 ++++++++++++++++++++ package/PikaStdDevice/PikaStdDevice_Time.c | 2 +- package/PikaStdDevice/PikaStdDevice_UART.c | 6 +++- package/PikaStdDevice/pika_hal.c | 8 +++-- package/PikaStdDevice/pika_hal.h | 12 +++++-- 6 files changed, 96 insertions(+), 11 deletions(-) diff --git a/package/PikaStdDevice/PikaStdDevice.pyi b/package/PikaStdDevice/PikaStdDevice.pyi index 69642e8f4..54e23d17a 100644 --- a/package/PikaStdDevice/PikaStdDevice.pyi +++ b/package/PikaStdDevice/PikaStdDevice.pyi @@ -9,7 +9,7 @@ Document: https://pikadoc.readthedocs.io/en/latest/PikaStdDevice%20%E6%A0%87%E5% from PikaObj import * -class GPIO(BaseDev): +class GPIO: def __init__(self): ... def setPin(self, pinName: str): @@ -68,6 +68,21 @@ class GPIO(BaseDev): def read(self) -> int: """Read the pin value.""" + SIGNAL_RISING: int + SIGNAL_FALLING: int + SIGNAL_ANY: int + + def addEventCallBack(self, eventCallBack: any, filter: int): + """ + Add a callback function to the pin. + Example: + ``` python + def cb1(signal): + print("cb1", signal) + io.addEventCallBack(cb1, io.SIGNAL_RISING) + ``` + """ + @abstractmethod def platformHigh(self): ... @@ -175,10 +190,11 @@ class DAC(BaseDev): def disable(self): """Disable the DAC.""" - def write(self, val:float): + def write(self, val: float): """write the DAC value.""" -class UART(BaseDev): + +class UART: def __init__(self): ... def setBaudRate(self, baudRate: int): @@ -205,6 +221,21 @@ class UART(BaseDev): def readBytes(self, length: int) -> bytes: """Read bytes from the UART.""" + + SIGNAL_RX: int + SIGNAL_TX: int + + def addEventCallBack(self, eventCallBack: any, filter: int): + """ + Add a callback function to the pin. + Example: + ``` python + def cb1(signal): + print(uart.read(-1)) + io.addEventCallBack(cb1, uart.SIGNAL_RX) + ``` + """ + @abstractmethod def platformEnable(self): ... @@ -436,7 +467,7 @@ class CAN(BaseDev): def readBytes(self, length: int) -> bytes: """Read bytes from the CAN.""" - def addFilter(self, id: int, ide: int, rtr: int, mode: int, mask: int, hdr: int): + def addFilter(self, id: int, ide: int, rtr: int, mode: int, mask: int, hdr: int): """Add a filter.""" @abstractmethod @@ -460,7 +491,7 @@ class CAN(BaseDev): class BaseDev: @PIKA_C_MACRO_IF("PIKA_EVENT_ENABLE") - def addEventCallBack(self, eventCallback: any): + def addEventCallBack(self, eventCallback: any): """ Add an event callback. """ @abstractmethod diff --git a/package/PikaStdDevice/PikaStdDevice_GPIO.c b/package/PikaStdDevice/PikaStdDevice_GPIO.c index 9071d40af..c581f0eaf 100644 --- a/package/PikaStdDevice/PikaStdDevice_GPIO.c +++ b/package/PikaStdDevice/PikaStdDevice_GPIO.c @@ -22,6 +22,9 @@ void PikaStdDevice_GPIO_setId(PikaObj* self, int id) { void PikaStdDevice_GPIO___init__(PikaObj* self) { PikaStdDevice_GPIO_init(self); + obj_setInt(self, "SIGNAL_RISING", PIKA_HAL_GPIO_EVENT_SIGNAL_RISING); + obj_setInt(self, "SIGNAL_FALLING", PIKA_HAL_GPIO_EVENT_SIGNAL_FALLING); + obj_setInt(self, "SIGNAL_ANY", PIKA_HAL_GPIO_EVENT_SIGNAL_ANY); } void PikaStdDevice_GPIO_disable(PikaObj* self) { @@ -145,3 +148,38 @@ void PikaStdDevice_GPIO_platformRead(PikaObj* self) { pika_hal_read(dev, &val, sizeof(val)); obj_setInt(self, "readBuff", val); } + +extern PikaEventListener* g_pika_device_event_listener; + +void _pika_hal_GPIO_event_callback(pika_dev* dev, + PIKA_HAL_GPIO_EVENT_SIGNAL signal) { + pks_eventLisener_sendSignal(g_pika_device_event_listener, (uint32_t)dev, + signal); +} + +void PikaStdDevice_GPIO_addEventCallBack(PikaObj* self, + Arg* eventCallBack, + int filter) { + pika_dev* dev = _get_dev(self); +#if PIKA_EVENT_ENABLE + obj_setArg(self, "eventCallBack", eventCallBack); + /* init event_listener for the first time */ + if (NULL == g_pika_device_event_listener) { + pks_eventLisener_init(&g_pika_device_event_listener); + } + /* use the pointer of dev as the event id */ + uint32_t eventId = (uint32_t)dev; + /* regist event to event listener */ + pks_eventLicener_registEvent(g_pika_device_event_listener, eventId, self); + + /* regist event to pika_hal */ + pika_hal_GPIO_config cfg_cb = {0}; + cfg_cb.event_callback = _pika_hal_GPIO_event_callback; + cfg_cb.event_callback_filter = filter; + cfg_cb.event_callback_ena = PIKA_HAL_EVENT_CALLBACK_ENA_ENABLE; + pika_hal_ioctl(dev, PIKA_HAL_IOCTL_CONFIG, &cfg_cb); +#else + obj_setErrorCode(self, 1); + obj_setSysOut(self, "[error] PIKA_EVENT_ENABLE is disabled."); +#endif +} diff --git a/package/PikaStdDevice/PikaStdDevice_Time.c b/package/PikaStdDevice/PikaStdDevice_Time.c index bc1084df0..caa8ae5ce 100644 --- a/package/PikaStdDevice/PikaStdDevice_Time.c +++ b/package/PikaStdDevice/PikaStdDevice_Time.c @@ -28,7 +28,7 @@ void PikaStdDevice_Time_sleep_s(PikaObj* self, int s) { } void PikaStdDevice_Time_platformGetTick(PikaObj* self) { - obj_setInt(self, "tick", __platform_getTick()); + obj_setInt(self, "tick", __platform_get_tick_ms()); } /* diff --git a/package/PikaStdDevice/PikaStdDevice_UART.c b/package/PikaStdDevice/PikaStdDevice_UART.c index 7b3a22dad..7415f866f 100644 --- a/package/PikaStdDevice/PikaStdDevice_UART.c +++ b/package/PikaStdDevice/PikaStdDevice_UART.c @@ -55,7 +55,7 @@ static pika_dev* _get_dev(PikaObj* self) { } int id = obj_getInt(self, "id"); char id_str[32] = {0}; - sprintf(id_str, "%d", id); + sprintf(id_str, "UART%d", id); dev = pika_hal_open(PIKA_HAL_UART, id_str); if (NULL == dev) { __platform_printf("Error: open UART '%s' failed.\r\n", id_str); @@ -117,3 +117,7 @@ void PikaStdDevice_UART_platformWriteBytes(PikaObj* self) { pika_dev* dev = _get_dev(self); pika_hal_write(dev, data, len); } + +void PikaStdDevice_UART_addEventCallBack(PikaObj *self, Arg* eventCallBack, int filter){ + +} diff --git a/package/PikaStdDevice/pika_hal.c b/package/PikaStdDevice/pika_hal.c index c8a975dfd..45e6888bf 100644 --- a/package/PikaStdDevice/pika_hal.c +++ b/package/PikaStdDevice/pika_hal.c @@ -184,7 +184,9 @@ int pika_hal_GPIO_ioctl_merge_config(pika_hal_GPIO_config* dst, _IOCTL_CONFIG_USE_DEFAULT(pull, PIKA_HAL_GPIO_PULL_NONE); _IOCTL_CONFIG_USE_DEFAULT(speed, PIKA_HAL_GPIO_SPEED_10M); _IOCTL_CONFIG_USE_DEFAULT(event_callback, NULL); - _IOCTL_CONFIG_USE_DEFAULT(event_callback_enable, + _IOCTL_CONFIG_USE_DEFAULT(event_callback_filter, + PIKA_HAL_GPIO_EVENT_SIGNAL_RISING); + _IOCTL_CONFIG_USE_DEFAULT(event_callback_ena, PIKA_HAL_EVENT_CALLBACK_ENA_ENABLE); return 0; } @@ -196,7 +198,9 @@ int pika_hal_UART_ioctl_merge_config(pika_hal_UART_config* dst, _IOCTL_CONFIG_USE_DEFAULT(stop_bits, PIKA_HAL_UART_STOP_BITS_1); _IOCTL_CONFIG_USE_DEFAULT(parity, PIKA_HAL_UART_PARITY_NONE); _IOCTL_CONFIG_USE_DEFAULT(event_callback, NULL); - _IOCTL_CONFIG_USE_DEFAULT(event_callback_enable, + _IOCTL_CONFIG_USE_DEFAULT(event_callback_filter, + PIKA_HAL_UART_EVENT_SIGNAL_RX); + _IOCTL_CONFIG_USE_DEFAULT(event_callback_ena, PIKA_HAL_EVENT_CALLBACK_ENA_ENABLE); return 0; } diff --git a/package/PikaStdDevice/pika_hal.h b/package/PikaStdDevice/pika_hal.h index 70cc5d22c..ec9b96287 100644 --- a/package/PikaStdDevice/pika_hal.h +++ b/package/PikaStdDevice/pika_hal.h @@ -65,8 +65,10 @@ typedef enum { } PIKA_HAL_EVENT_CALLBACK_ENA; typedef enum { + _PIKA_HAL_GPIO_EVENT_SIGNAL_UNUSED = 0, PIKA_HAL_GPIO_EVENT_SIGNAL_RISING, PIKA_HAL_GPIO_EVENT_SIGNAL_FALLING, + PIKA_HAL_GPIO_EVENT_SIGNAL_ANY, } PIKA_HAL_GPIO_EVENT_SIGNAL; typedef struct { @@ -74,7 +76,8 @@ typedef struct { PIKA_HAL_GPIO_PULL pull; PIKA_HAL_GPIO_SPEED speed; void (*event_callback)(pika_dev* dev, PIKA_HAL_GPIO_EVENT_SIGNAL signal); - PIKA_HAL_EVENT_CALLBACK_ENA event_callback_enable; + PIKA_HAL_GPIO_EVENT_SIGNAL event_callback_filter; + PIKA_HAL_EVENT_CALLBACK_ENA event_callback_ena; } pika_hal_GPIO_config; typedef enum { @@ -100,6 +103,7 @@ typedef enum { _PIKA_HAL_UART_STOP_BITS_UNUSED = 0, PIKA_HAL_UART_STOP_BITS_1 = 1, PIKA_HAL_UART_STOP_BITS_2 = 2, + PIKA_HAL_UART_STOP_BITS_1_5 = 3, } PIKA_HAL_UART_STOP_BITS; typedef enum { @@ -110,7 +114,10 @@ typedef enum { } PIKA_HAL_UART_PARITY; typedef enum { + _PIKA_HAL_UART_EVENT_SIGNAL_UNUSED = 0, PIKA_HAL_UART_EVENT_SIGNAL_RX, + PIKA_HAL_UART_EVENT_SIGNAL_TX, + PIKA_HAL_UART_EVENT_SIGNAL_ANY, } PIKA_HAL_UART_EVENT_SIGNAL; typedef struct { @@ -119,7 +126,8 @@ typedef struct { PIKA_HAL_UART_STOP_BITS stop_bits; PIKA_HAL_UART_PARITY parity; void (*event_callback)(pika_dev* dev, PIKA_HAL_UART_EVENT_SIGNAL signal); - PIKA_HAL_EVENT_CALLBACK_ENA event_callback_enable; + PIKA_HAL_UART_EVENT_SIGNAL event_callback_filter; + PIKA_HAL_EVENT_CALLBACK_ENA event_callback_ena; } pika_hal_UART_config; typedef uint32_t PIKA_HAL_IIC_SLAVE_ADDR; From dfba4e266c87a6feb6092e3443b3545ca48031d0 Mon Sep 17 00:00:00 2001 From: lyon Date: Fri, 23 Dec 2022 18:16:53 +0800 Subject: [PATCH 29/44] update_toml --- packages.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages.toml b/packages.toml index 4a5208630..ff3a7e983 100644 --- a/packages.toml +++ b/packages.toml @@ -173,7 +173,8 @@ releases = [ "v1.11.8 58ff9fe16688be2e77ed220604aa8b1271b72d80", "v2.0.0 e89c585f46ee98811611ea56d5abfc618a41ee3b", "v2.1.0 852daad3c9a95dbce54dbf1d2cdb5b2321826b4f", - "v2.1.1 5eadba95fa573e3409f65c6392804d3c60d627ac" + "v2.1.1 5eadba95fa573e3409f65c6392804d3c60d627ac", + "v2.1.2 36ef746f5791a57212cc1d02fe885814e613e60c" ] [[packages]] From f7235ae459ab6694b25cb34fdfcc5a5cac3ed17f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=98=82?= Date: Fri, 23 Dec 2022 10:17:49 +0000 Subject: [PATCH 30/44] update package/PikaStdDevice/PikaStdDevice_Time.c. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 李昂 --- package/PikaStdDevice/PikaStdDevice_Time.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/PikaStdDevice/PikaStdDevice_Time.c b/package/PikaStdDevice/PikaStdDevice_Time.c index caa8ae5ce..bc1084df0 100644 --- a/package/PikaStdDevice/PikaStdDevice_Time.c +++ b/package/PikaStdDevice/PikaStdDevice_Time.c @@ -28,7 +28,7 @@ void PikaStdDevice_Time_sleep_s(PikaObj* self, int s) { } void PikaStdDevice_Time_platformGetTick(PikaObj* self) { - obj_setInt(self, "tick", __platform_get_tick_ms()); + obj_setInt(self, "tick", __platform_getTick()); } /* From 256319e035eda052f2e5580fd372e07f2042a38b Mon Sep 17 00:00:00 2001 From: lyon Date: Fri, 23 Dec 2022 18:19:16 +0800 Subject: [PATCH 31/44] update port linux std fix baseDev.addEventCallBack use setCallBack in std update std support flow control for uart add flowcontrol API for std.uart --- package/PikaStdDevice/PikaStdDevice.pyi | 18 +++++-- package/PikaStdDevice/PikaStdDevice_GPIO.c | 10 ++-- package/PikaStdDevice/PikaStdDevice_UART.c | 19 ++++++-- package/PikaStdDevice/pika_hal.c | 1 + package/PikaStdDevice/pika_hal.h | 9 ++++ package/TemplateDevice/TemplateDevice.pyi | 1 + package/TemplateDevice/TemplateDevice_GPIO.c | 12 +++++ port/linux/.vscode/settings.json | 3 +- .../package/pikascript/PikaStdDevice.pyi | 47 +++++++++++++++++-- .../PikaStdDevice/PikaStdDevice_GPIO.c | 38 +++++++++++++++ .../PikaStdDevice/PikaStdDevice_UART.c | 19 +++++++- .../pikascript-lib/PikaStdDevice/pika_hal.c | 9 +++- .../pikascript-lib/PikaStdDevice/pika_hal.h | 21 ++++++++- src/PikaObj.c | 10 ++-- test/event-test.cpp | 2 +- test/python/TemplateDevice/gpio_cb.py | 21 +++++++++ 16 files changed, 211 insertions(+), 29 deletions(-) create mode 100644 test/python/TemplateDevice/gpio_cb.py diff --git a/package/PikaStdDevice/PikaStdDevice.pyi b/package/PikaStdDevice/PikaStdDevice.pyi index 54e23d17a..b32f0a4e3 100644 --- a/package/PikaStdDevice/PikaStdDevice.pyi +++ b/package/PikaStdDevice/PikaStdDevice.pyi @@ -9,7 +9,7 @@ Document: https://pikadoc.readthedocs.io/en/latest/PikaStdDevice%20%E6%A0%87%E5% from PikaObj import * -class GPIO: +class GPIO(BaseDev): def __init__(self): ... def setPin(self, pinName: str): @@ -72,14 +72,14 @@ class GPIO: SIGNAL_FALLING: int SIGNAL_ANY: int - def addEventCallBack(self, eventCallBack: any, filter: int): + def setCallBack(self, eventCallBack: any, filter: int): """ Add a callback function to the pin. Example: ``` python def cb1(signal): print("cb1", signal) - io.addEventCallBack(cb1, io.SIGNAL_RISING) + io.setCallBack(cb1, io.SIGNAL_RISING) ``` """ @@ -202,6 +202,14 @@ class UART: def setId(self, id: int): """Set the id of the UART.""" + + FLOW_CONTROL_NONE: int + FLOW_CONTROL_RTS: int + FLOW_CONTROL_CTS: int + FLOW_CONTROL_RTS_CTS: int + + def setFlowControl(self, flowControl: int): + """Set the flow control of the UART.""" def enable(self): """Enable the UART.""" @@ -225,14 +233,14 @@ class UART: SIGNAL_RX: int SIGNAL_TX: int - def addEventCallBack(self, eventCallBack: any, filter: int): + def setCallBack(self, eventCallBack: any, filter: int): """ Add a callback function to the pin. Example: ``` python def cb1(signal): print(uart.read(-1)) - io.addEventCallBack(cb1, uart.SIGNAL_RX) + io.setCallBack(cb1, uart.SIGNAL_RX) ``` """ diff --git a/package/PikaStdDevice/PikaStdDevice_GPIO.c b/package/PikaStdDevice/PikaStdDevice_GPIO.c index c581f0eaf..8b0466138 100644 --- a/package/PikaStdDevice/PikaStdDevice_GPIO.c +++ b/package/PikaStdDevice/PikaStdDevice_GPIO.c @@ -153,13 +153,13 @@ extern PikaEventListener* g_pika_device_event_listener; void _pika_hal_GPIO_event_callback(pika_dev* dev, PIKA_HAL_GPIO_EVENT_SIGNAL signal) { - pks_eventLisener_sendSignal(g_pika_device_event_listener, (uint32_t)dev, + pks_eventLisener_sendSignal(g_pika_device_event_listener, (uintptr_t)dev, signal); } -void PikaStdDevice_GPIO_addEventCallBack(PikaObj* self, - Arg* eventCallBack, - int filter) { +void PikaStdDevice_GPIO_setCallBack(PikaObj* self, + Arg* eventCallBack, + int filter) { pika_dev* dev = _get_dev(self); #if PIKA_EVENT_ENABLE obj_setArg(self, "eventCallBack", eventCallBack); @@ -168,7 +168,7 @@ void PikaStdDevice_GPIO_addEventCallBack(PikaObj* self, pks_eventLisener_init(&g_pika_device_event_listener); } /* use the pointer of dev as the event id */ - uint32_t eventId = (uint32_t)dev; + uint32_t eventId = (uintptr_t)dev; /* regist event to event listener */ pks_eventLicener_registEvent(g_pika_device_event_listener, eventId, self); diff --git a/package/PikaStdDevice/PikaStdDevice_UART.c b/package/PikaStdDevice/PikaStdDevice_UART.c index 7415f866f..30f9d179a 100644 --- a/package/PikaStdDevice/PikaStdDevice_UART.c +++ b/package/PikaStdDevice/PikaStdDevice_UART.c @@ -14,6 +14,12 @@ void PikaStdDevice_UART_init(PikaObj* self) { obj_setInt(self, "baudRate", 115200); obj_setInt(self, "id", 1); obj_setStr(self, "readBuff", ""); + obj_setInt(self, "FLOW_CONTROL_NONE", PIKA_HAL_UART_FLOW_CONTROL_NONE); + obj_setInt(self, "FLOW_CONTROL_RTS", PIKA_HAL_UART_FLOW_CONTROL_RTS); + obj_setInt(self, "FLOW_CONTROL_CTS", PIKA_HAL_UART_FLOW_CONTROL_CTS); + obj_setInt(self, "FLOW_CONTROL_RTS_CTS", + PIKA_HAL_UART_FLOW_CONTROL_RTS_CTS); + obj_setInt(self, "flowControl", PIKA_HAL_UART_FLOW_CONTROL_NONE); } void PikaStdDevice_UART___init__(PikaObj* self) { @@ -35,9 +41,15 @@ Arg* PikaStdDevice_UART_readBytes(PikaObj* self, int length) { void PikaStdDevice_UART_setBaudRate(PikaObj* self, int baudRate) { obj_setInt(self, "baudRate", baudRate); } + +void PikaStdDevice_UART_setFlowControl(PikaObj *self, int flowControl){ + obj_setInt(self, "flowControl", flowControl); +} + void PikaStdDevice_UART_setId(PikaObj* self, int id) { obj_setInt(self, "id", id); } + void PikaStdDevice_UART_write(PikaObj* self, char* data) { obj_setStr(self, "writeData", data); obj_runNativeMethod(self, "platformWrite", NULL); @@ -73,6 +85,7 @@ void PikaStdDevice_UART_platformEnable(PikaObj* self) { } pika_hal_UART_config cfg = {0}; cfg.baudrate = obj_getInt(self, "baudRate"); + cfg.flow_control = obj_getInt(self, "flowControl"); pika_hal_ioctl(dev, PIKA_HAL_IOCTL_CONFIG, &cfg); pika_hal_ioctl(dev, PIKA_HAL_IOCTL_ENABLE); } @@ -118,6 +131,6 @@ void PikaStdDevice_UART_platformWriteBytes(PikaObj* self) { pika_hal_write(dev, data, len); } -void PikaStdDevice_UART_addEventCallBack(PikaObj *self, Arg* eventCallBack, int filter){ - -} +void PikaStdDevice_UART_setCallBack(PikaObj* self, + Arg* eventCallBack, + int filter) {} diff --git a/package/PikaStdDevice/pika_hal.c b/package/PikaStdDevice/pika_hal.c index 45e6888bf..6568b520c 100644 --- a/package/PikaStdDevice/pika_hal.c +++ b/package/PikaStdDevice/pika_hal.c @@ -197,6 +197,7 @@ int pika_hal_UART_ioctl_merge_config(pika_hal_UART_config* dst, _IOCTL_CONFIG_USE_DEFAULT(data_bits, PIKA_HAL_UART_DATA_BITS_8); _IOCTL_CONFIG_USE_DEFAULT(stop_bits, PIKA_HAL_UART_STOP_BITS_1); _IOCTL_CONFIG_USE_DEFAULT(parity, PIKA_HAL_UART_PARITY_NONE); + _IOCTL_CONFIG_USE_DEFAULT(flow_control, PIKA_HAL_UART_FLOW_CONTROL_NONE); _IOCTL_CONFIG_USE_DEFAULT(event_callback, NULL); _IOCTL_CONFIG_USE_DEFAULT(event_callback_filter, PIKA_HAL_UART_EVENT_SIGNAL_RX); diff --git a/package/PikaStdDevice/pika_hal.h b/package/PikaStdDevice/pika_hal.h index ec9b96287..c1c950fad 100644 --- a/package/PikaStdDevice/pika_hal.h +++ b/package/PikaStdDevice/pika_hal.h @@ -120,11 +120,20 @@ typedef enum { PIKA_HAL_UART_EVENT_SIGNAL_ANY, } PIKA_HAL_UART_EVENT_SIGNAL; +typedef enum { + _PIKA_HAL_UART_FLOW_CONTROL_UNUSED = 0, + PIKA_HAL_UART_FLOW_CONTROL_NONE, + PIKA_HAL_UART_FLOW_CONTROL_RTS, + PIKA_HAL_UART_FLOW_CONTROL_CTS, + PIKA_HAL_UART_FLOW_CONTROL_RTS_CTS, +} PIKA_HAL_UART_FLOW_CONTROL; + typedef struct { PIKA_HAL_UART_BAUDRATE baudrate; PIKA_HAL_UART_DATA_BITS data_bits; PIKA_HAL_UART_STOP_BITS stop_bits; PIKA_HAL_UART_PARITY parity; + PIKA_HAL_UART_FLOW_CONTROL flow_control; void (*event_callback)(pika_dev* dev, PIKA_HAL_UART_EVENT_SIGNAL signal); PIKA_HAL_UART_EVENT_SIGNAL event_callback_filter; PIKA_HAL_EVENT_CALLBACK_ENA event_callback_ena; diff --git a/package/TemplateDevice/TemplateDevice.pyi b/package/TemplateDevice/TemplateDevice.pyi index 4087ac32b..22c4d94f1 100644 --- a/package/TemplateDevice/TemplateDevice.pyi +++ b/package/TemplateDevice/TemplateDevice.pyi @@ -10,6 +10,7 @@ class GPIO(PikaStdDevice.GPIO): def platformSetMode(self): ... def platformRead(self): ... def platformGetEventId(self): ... + def eventTest(self): ... class Time(PikaStdDevice.Time): diff --git a/package/TemplateDevice/TemplateDevice_GPIO.c b/package/TemplateDevice/TemplateDevice_GPIO.c index c06a67b12..f7c398841 100644 --- a/package/TemplateDevice/TemplateDevice_GPIO.c +++ b/package/TemplateDevice/TemplateDevice_GPIO.c @@ -14,3 +14,15 @@ void TemplateDevice_GPIO_platformGetEventId(PikaObj* self) { obj_setInt(self, "eventId", GPIO_PA8_EVENT_ID); } } + +extern PikaEventListener* g_pika_device_event_listener; +#define EVENT_SIGNAL_IO_RISING_EDGE 0x01 +#define EVENT_SIGNAL_IO_FALLING_EDGE 0x02 +#define GPIO_PA8_EVENT_ID 0x08 + +void TemplateDevice_GPIO_eventTest(PikaObj* self) { + pks_eventLisener_sendSignal(g_pika_device_event_listener, GPIO_PA8_EVENT_ID, + EVENT_SIGNAL_IO_FALLING_EDGE); + pks_eventLisener_sendSignal(g_pika_device_event_listener, GPIO_PA8_EVENT_ID, + EVENT_SIGNAL_IO_RISING_EDGE); +} diff --git a/port/linux/.vscode/settings.json b/port/linux/.vscode/settings.json index adc4b7a56..b47105a87 100644 --- a/port/linux/.vscode/settings.json +++ b/port/linux/.vscode/settings.json @@ -93,7 +93,8 @@ "__instruction_def.h": "c", "pika_hal_def.h": "c", "pika_hal_table.h": "c", - "pika_hal_table_rule.h": "c" + "pika_hal_table_rule.h": "c", + "pikastddevice_uart.h": "c" }, "python.formatting.provider": "autopep8", "C_Cpp.errorSquiggles": "Disabled" diff --git a/port/linux/package/pikascript/PikaStdDevice.pyi b/port/linux/package/pikascript/PikaStdDevice.pyi index 69642e8f4..b32f0a4e3 100644 --- a/port/linux/package/pikascript/PikaStdDevice.pyi +++ b/port/linux/package/pikascript/PikaStdDevice.pyi @@ -68,6 +68,21 @@ class GPIO(BaseDev): def read(self) -> int: """Read the pin value.""" + SIGNAL_RISING: int + SIGNAL_FALLING: int + SIGNAL_ANY: int + + def setCallBack(self, eventCallBack: any, filter: int): + """ + Add a callback function to the pin. + Example: + ``` python + def cb1(signal): + print("cb1", signal) + io.setCallBack(cb1, io.SIGNAL_RISING) + ``` + """ + @abstractmethod def platformHigh(self): ... @@ -175,10 +190,11 @@ class DAC(BaseDev): def disable(self): """Disable the DAC.""" - def write(self, val:float): + def write(self, val: float): """write the DAC value.""" -class UART(BaseDev): + +class UART: def __init__(self): ... def setBaudRate(self, baudRate: int): @@ -186,6 +202,14 @@ class UART(BaseDev): def setId(self, id: int): """Set the id of the UART.""" + + FLOW_CONTROL_NONE: int + FLOW_CONTROL_RTS: int + FLOW_CONTROL_CTS: int + FLOW_CONTROL_RTS_CTS: int + + def setFlowControl(self, flowControl: int): + """Set the flow control of the UART.""" def enable(self): """Enable the UART.""" @@ -205,6 +229,21 @@ class UART(BaseDev): def readBytes(self, length: int) -> bytes: """Read bytes from the UART.""" + + SIGNAL_RX: int + SIGNAL_TX: int + + def setCallBack(self, eventCallBack: any, filter: int): + """ + Add a callback function to the pin. + Example: + ``` python + def cb1(signal): + print(uart.read(-1)) + io.setCallBack(cb1, uart.SIGNAL_RX) + ``` + """ + @abstractmethod def platformEnable(self): ... @@ -436,7 +475,7 @@ class CAN(BaseDev): def readBytes(self, length: int) -> bytes: """Read bytes from the CAN.""" - def addFilter(self, id: int, ide: int, rtr: int, mode: int, mask: int, hdr: int): + def addFilter(self, id: int, ide: int, rtr: int, mode: int, mask: int, hdr: int): """Add a filter.""" @abstractmethod @@ -460,7 +499,7 @@ class CAN(BaseDev): class BaseDev: @PIKA_C_MACRO_IF("PIKA_EVENT_ENABLE") - def addEventCallBack(self, eventCallback: any): + def addEventCallBack(self, eventCallback: any): """ Add an event callback. """ @abstractmethod diff --git a/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_GPIO.c b/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_GPIO.c index 9071d40af..8b0466138 100644 --- a/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_GPIO.c +++ b/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_GPIO.c @@ -22,6 +22,9 @@ void PikaStdDevice_GPIO_setId(PikaObj* self, int id) { void PikaStdDevice_GPIO___init__(PikaObj* self) { PikaStdDevice_GPIO_init(self); + obj_setInt(self, "SIGNAL_RISING", PIKA_HAL_GPIO_EVENT_SIGNAL_RISING); + obj_setInt(self, "SIGNAL_FALLING", PIKA_HAL_GPIO_EVENT_SIGNAL_FALLING); + obj_setInt(self, "SIGNAL_ANY", PIKA_HAL_GPIO_EVENT_SIGNAL_ANY); } void PikaStdDevice_GPIO_disable(PikaObj* self) { @@ -145,3 +148,38 @@ void PikaStdDevice_GPIO_platformRead(PikaObj* self) { pika_hal_read(dev, &val, sizeof(val)); obj_setInt(self, "readBuff", val); } + +extern PikaEventListener* g_pika_device_event_listener; + +void _pika_hal_GPIO_event_callback(pika_dev* dev, + PIKA_HAL_GPIO_EVENT_SIGNAL signal) { + pks_eventLisener_sendSignal(g_pika_device_event_listener, (uintptr_t)dev, + signal); +} + +void PikaStdDevice_GPIO_setCallBack(PikaObj* self, + Arg* eventCallBack, + int filter) { + pika_dev* dev = _get_dev(self); +#if PIKA_EVENT_ENABLE + obj_setArg(self, "eventCallBack", eventCallBack); + /* init event_listener for the first time */ + if (NULL == g_pika_device_event_listener) { + pks_eventLisener_init(&g_pika_device_event_listener); + } + /* use the pointer of dev as the event id */ + uint32_t eventId = (uintptr_t)dev; + /* regist event to event listener */ + pks_eventLicener_registEvent(g_pika_device_event_listener, eventId, self); + + /* regist event to pika_hal */ + pika_hal_GPIO_config cfg_cb = {0}; + cfg_cb.event_callback = _pika_hal_GPIO_event_callback; + cfg_cb.event_callback_filter = filter; + cfg_cb.event_callback_ena = PIKA_HAL_EVENT_CALLBACK_ENA_ENABLE; + pika_hal_ioctl(dev, PIKA_HAL_IOCTL_CONFIG, &cfg_cb); +#else + obj_setErrorCode(self, 1); + obj_setSysOut(self, "[error] PIKA_EVENT_ENABLE is disabled."); +#endif +} diff --git a/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_UART.c b/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_UART.c index 7b3a22dad..30f9d179a 100644 --- a/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_UART.c +++ b/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_UART.c @@ -14,6 +14,12 @@ void PikaStdDevice_UART_init(PikaObj* self) { obj_setInt(self, "baudRate", 115200); obj_setInt(self, "id", 1); obj_setStr(self, "readBuff", ""); + obj_setInt(self, "FLOW_CONTROL_NONE", PIKA_HAL_UART_FLOW_CONTROL_NONE); + obj_setInt(self, "FLOW_CONTROL_RTS", PIKA_HAL_UART_FLOW_CONTROL_RTS); + obj_setInt(self, "FLOW_CONTROL_CTS", PIKA_HAL_UART_FLOW_CONTROL_CTS); + obj_setInt(self, "FLOW_CONTROL_RTS_CTS", + PIKA_HAL_UART_FLOW_CONTROL_RTS_CTS); + obj_setInt(self, "flowControl", PIKA_HAL_UART_FLOW_CONTROL_NONE); } void PikaStdDevice_UART___init__(PikaObj* self) { @@ -35,9 +41,15 @@ Arg* PikaStdDevice_UART_readBytes(PikaObj* self, int length) { void PikaStdDevice_UART_setBaudRate(PikaObj* self, int baudRate) { obj_setInt(self, "baudRate", baudRate); } + +void PikaStdDevice_UART_setFlowControl(PikaObj *self, int flowControl){ + obj_setInt(self, "flowControl", flowControl); +} + void PikaStdDevice_UART_setId(PikaObj* self, int id) { obj_setInt(self, "id", id); } + void PikaStdDevice_UART_write(PikaObj* self, char* data) { obj_setStr(self, "writeData", data); obj_runNativeMethod(self, "platformWrite", NULL); @@ -55,7 +67,7 @@ static pika_dev* _get_dev(PikaObj* self) { } int id = obj_getInt(self, "id"); char id_str[32] = {0}; - sprintf(id_str, "%d", id); + sprintf(id_str, "UART%d", id); dev = pika_hal_open(PIKA_HAL_UART, id_str); if (NULL == dev) { __platform_printf("Error: open UART '%s' failed.\r\n", id_str); @@ -73,6 +85,7 @@ void PikaStdDevice_UART_platformEnable(PikaObj* self) { } pika_hal_UART_config cfg = {0}; cfg.baudrate = obj_getInt(self, "baudRate"); + cfg.flow_control = obj_getInt(self, "flowControl"); pika_hal_ioctl(dev, PIKA_HAL_IOCTL_CONFIG, &cfg); pika_hal_ioctl(dev, PIKA_HAL_IOCTL_ENABLE); } @@ -117,3 +130,7 @@ void PikaStdDevice_UART_platformWriteBytes(PikaObj* self) { pika_dev* dev = _get_dev(self); pika_hal_write(dev, data, len); } + +void PikaStdDevice_UART_setCallBack(PikaObj* self, + Arg* eventCallBack, + int filter) {} diff --git a/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/pika_hal.c b/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/pika_hal.c index c8a975dfd..6568b520c 100644 --- a/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/pika_hal.c +++ b/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/pika_hal.c @@ -184,7 +184,9 @@ int pika_hal_GPIO_ioctl_merge_config(pika_hal_GPIO_config* dst, _IOCTL_CONFIG_USE_DEFAULT(pull, PIKA_HAL_GPIO_PULL_NONE); _IOCTL_CONFIG_USE_DEFAULT(speed, PIKA_HAL_GPIO_SPEED_10M); _IOCTL_CONFIG_USE_DEFAULT(event_callback, NULL); - _IOCTL_CONFIG_USE_DEFAULT(event_callback_enable, + _IOCTL_CONFIG_USE_DEFAULT(event_callback_filter, + PIKA_HAL_GPIO_EVENT_SIGNAL_RISING); + _IOCTL_CONFIG_USE_DEFAULT(event_callback_ena, PIKA_HAL_EVENT_CALLBACK_ENA_ENABLE); return 0; } @@ -195,8 +197,11 @@ int pika_hal_UART_ioctl_merge_config(pika_hal_UART_config* dst, _IOCTL_CONFIG_USE_DEFAULT(data_bits, PIKA_HAL_UART_DATA_BITS_8); _IOCTL_CONFIG_USE_DEFAULT(stop_bits, PIKA_HAL_UART_STOP_BITS_1); _IOCTL_CONFIG_USE_DEFAULT(parity, PIKA_HAL_UART_PARITY_NONE); + _IOCTL_CONFIG_USE_DEFAULT(flow_control, PIKA_HAL_UART_FLOW_CONTROL_NONE); _IOCTL_CONFIG_USE_DEFAULT(event_callback, NULL); - _IOCTL_CONFIG_USE_DEFAULT(event_callback_enable, + _IOCTL_CONFIG_USE_DEFAULT(event_callback_filter, + PIKA_HAL_UART_EVENT_SIGNAL_RX); + _IOCTL_CONFIG_USE_DEFAULT(event_callback_ena, PIKA_HAL_EVENT_CALLBACK_ENA_ENABLE); return 0; } diff --git a/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/pika_hal.h b/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/pika_hal.h index 70cc5d22c..c1c950fad 100644 --- a/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/pika_hal.h +++ b/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/pika_hal.h @@ -65,8 +65,10 @@ typedef enum { } PIKA_HAL_EVENT_CALLBACK_ENA; typedef enum { + _PIKA_HAL_GPIO_EVENT_SIGNAL_UNUSED = 0, PIKA_HAL_GPIO_EVENT_SIGNAL_RISING, PIKA_HAL_GPIO_EVENT_SIGNAL_FALLING, + PIKA_HAL_GPIO_EVENT_SIGNAL_ANY, } PIKA_HAL_GPIO_EVENT_SIGNAL; typedef struct { @@ -74,7 +76,8 @@ typedef struct { PIKA_HAL_GPIO_PULL pull; PIKA_HAL_GPIO_SPEED speed; void (*event_callback)(pika_dev* dev, PIKA_HAL_GPIO_EVENT_SIGNAL signal); - PIKA_HAL_EVENT_CALLBACK_ENA event_callback_enable; + PIKA_HAL_GPIO_EVENT_SIGNAL event_callback_filter; + PIKA_HAL_EVENT_CALLBACK_ENA event_callback_ena; } pika_hal_GPIO_config; typedef enum { @@ -100,6 +103,7 @@ typedef enum { _PIKA_HAL_UART_STOP_BITS_UNUSED = 0, PIKA_HAL_UART_STOP_BITS_1 = 1, PIKA_HAL_UART_STOP_BITS_2 = 2, + PIKA_HAL_UART_STOP_BITS_1_5 = 3, } PIKA_HAL_UART_STOP_BITS; typedef enum { @@ -110,16 +114,29 @@ typedef enum { } PIKA_HAL_UART_PARITY; typedef enum { + _PIKA_HAL_UART_EVENT_SIGNAL_UNUSED = 0, PIKA_HAL_UART_EVENT_SIGNAL_RX, + PIKA_HAL_UART_EVENT_SIGNAL_TX, + PIKA_HAL_UART_EVENT_SIGNAL_ANY, } PIKA_HAL_UART_EVENT_SIGNAL; +typedef enum { + _PIKA_HAL_UART_FLOW_CONTROL_UNUSED = 0, + PIKA_HAL_UART_FLOW_CONTROL_NONE, + PIKA_HAL_UART_FLOW_CONTROL_RTS, + PIKA_HAL_UART_FLOW_CONTROL_CTS, + PIKA_HAL_UART_FLOW_CONTROL_RTS_CTS, +} PIKA_HAL_UART_FLOW_CONTROL; + typedef struct { PIKA_HAL_UART_BAUDRATE baudrate; PIKA_HAL_UART_DATA_BITS data_bits; PIKA_HAL_UART_STOP_BITS stop_bits; PIKA_HAL_UART_PARITY parity; + PIKA_HAL_UART_FLOW_CONTROL flow_control; void (*event_callback)(pika_dev* dev, PIKA_HAL_UART_EVENT_SIGNAL signal); - PIKA_HAL_EVENT_CALLBACK_ENA event_callback_enable; + PIKA_HAL_UART_EVENT_SIGNAL event_callback_filter; + PIKA_HAL_EVENT_CALLBACK_ENA event_callback_ena; } pika_hal_UART_config; typedef uint32_t PIKA_HAL_IIC_SLAVE_ADDR; diff --git a/src/PikaObj.c b/src/PikaObj.c index 9c833a8f1..37eab7b39 100644 --- a/src/PikaObj.c +++ b/src/PikaObj.c @@ -1635,11 +1635,11 @@ void pks_eventLisener_sendSignal(PikaEventListener* self, #else /* push event handler to vm event list */ if (PIKA_RES_OK != VMSignal_pushEvent(self, eventId, eventSignal)) { - __platform_printf( - "OverflowError: event list is full, please use bigger " - "PIKA_EVENT_LIST_SIZE\r\n"); - while (1) { - } + // __platform_printf( + // "OverflowError: event list is full, please use bigger " + // "PIKA_EVENT_LIST_SIZE\r\n"); + // while (1) { + // } } if (0 == VMSignal_getVMCnt()) { /* no vm running, pick up event imediately */ diff --git a/test/event-test.cpp b/test/event-test.cpp index 94b5fdbbe..9327af28a 100644 --- a/test/event-test.cpp +++ b/test/event-test.cpp @@ -7,7 +7,7 @@ TEST(event, gpio) { /* init */ PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain); /* run */ - pikaVM_runSingleFile(pikaMain, "../../examples/TemplateDevice/gpio_cb.py"); + pikaVM_runSingleFile(pikaMain, "test/python/TemplateDevice/gpio_cb.py"); #define EVENT_SIGAL_IO_RISING_EDGE 0x01 #define EVENT_SIGAL_IO_FALLING_EDGE 0x02 diff --git a/test/python/TemplateDevice/gpio_cb.py b/test/python/TemplateDevice/gpio_cb.py new file mode 100644 index 000000000..951dbf564 --- /dev/null +++ b/test/python/TemplateDevice/gpio_cb.py @@ -0,0 +1,21 @@ +import TemplateDevice + +io1 = TemplateDevice.GPIO() +io1.setPin('PA8') +io1.setMode('in') +io1.enable() + +EVENT_SIGAL_IO_RISING_EDGE = 0x01 +EVENT_SIGAL_IO_FALLING_EDGE = 0x02 + + +def callBack1(signal): + if signal == EVENT_SIGAL_IO_RISING_EDGE: + print('get rising edge!') + elif signal == EVENT_SIGAL_IO_FALLING_EDGE: + print('get falling edge!') + else: + return signal + + +io1.addEventCallBack(callBack1) From 6c1d9ebc8124b391a4ec50edffc3df7f114d564e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=98=82?= Date: Fri, 23 Dec 2022 11:21:21 +0000 Subject: [PATCH 32/44] update examples/Device/GPIO_CALLBCK.py. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 李昂 --- examples/Device/GPIO_CALLBCK.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/Device/GPIO_CALLBCK.py b/examples/Device/GPIO_CALLBCK.py index 284421d9f..768c137c6 100644 --- a/examples/Device/GPIO_CALLBCK.py +++ b/examples/Device/GPIO_CALLBCK.py @@ -9,7 +9,7 @@ io.enable() def cb1(signal): print('cb1', signal) -io.addEventCallBack(cb1, io.SIGNAL_FALLING) +io.setCallBack(cb1, io.SIGNAL_FALLING) while True: pass From 8c9dcfb618a0fe120995edd79ff91f488fb1b438 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=98=82?= Date: Fri, 23 Dec 2022 12:20:36 +0000 Subject: [PATCH 33/44] add examples/Device/UART_CALLBACK.py. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 李昂 --- examples/Device/UART_CALLBACK.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 examples/Device/UART_CALLBACK.py diff --git a/examples/Device/UART_CALLBACK.py b/examples/Device/UART_CALLBACK.py new file mode 100644 index 000000000..ff1311d34 --- /dev/null +++ b/examples/Device/UART_CALLBACK.py @@ -0,0 +1,15 @@ +import PikaStdDevice as std +print('hello pikascript') + +uart = std.UART() +uart.setId(0) +uart.setBaudRate(115200) +uart.enable() + +def cb1(signal): + print('recv:', uart.read(32)) + +uart.setCallBack(cb1, uart.SIGNAL_RX) + +while True: + pass From fc69ce4145c053d0a5f9191e8706014c5bee4ca8 Mon Sep 17 00:00:00 2001 From: lyon Date: Fri, 23 Dec 2022 20:22:33 +0800 Subject: [PATCH 34/44] add_files --- package/BLIOT/pika_hal_BLIOT_GPIO.c | 36 ++++++ package/BLIOT/pika_hal_BLIOT_SPI.c | 23 +++- package/BLIOT/pika_hal_BLIOT_UART.c | 161 ++++++++++++++++++++++++ package/BLIOT/pika_hal_BLIOT_irq_task.c | 52 ++++++++ package/BLIOT/pika_hal_BLIOT_irq_task.h | 12 ++ 5 files changed, 281 insertions(+), 3 deletions(-) create mode 100644 package/BLIOT/pika_hal_BLIOT_UART.c create mode 100644 package/BLIOT/pika_hal_BLIOT_irq_task.c create mode 100644 package/BLIOT/pika_hal_BLIOT_irq_task.h diff --git a/package/BLIOT/pika_hal_BLIOT_GPIO.c b/package/BLIOT/pika_hal_BLIOT_GPIO.c index 1aa1948e1..8d5cae6d5 100644 --- a/package/BLIOT/pika_hal_BLIOT_GPIO.c +++ b/package/BLIOT/pika_hal_BLIOT_GPIO.c @@ -1,6 +1,7 @@ #include #include #include "../PikaStdDevice/pika_hal.h" +#include "pika_hal_BLIOT_irq_task.h" int pika_hal_platform_GPIO_open(pika_dev* dev, char* name) { dev->platform_data = pikaMalloc(sizeof(hosal_gpio_dev_t)); @@ -56,6 +57,15 @@ int pika_hal_platform_GPIO_ioctl_disable(pika_dev* dev) { return 0; } +extern volatile _BLIOT_irq g_irq; +void _hosal_gpio_irq_handler(void* arg) { + if (g_irq.gpio_irq_trigger) { + return; + } + g_irq.gpio_irq_arg = arg; + g_irq.gpio_irq_trigger = 1; +} + int pika_hal_platform_GPIO_ioctl_config(pika_dev* dev, pika_hal_GPIO_config* cfg) { hosal_gpio_dev_t* platform_gpio = (hosal_gpio_dev_t*)dev->platform_data; @@ -84,9 +94,11 @@ int pika_hal_platform_GPIO_ioctl_config(pika_dev* dev, switch (cfg->pull) { case PIKA_HAL_GPIO_PULL_NONE: platform_gpio->config = INPUT_HIGH_IMPEDANCE; + break; case PIKA_HAL_GPIO_PULL_UP: platform_gpio->config = INPUT_PULL_UP; + break; case PIKA_HAL_GPIO_PULL_DOWN: /* not supported */ @@ -94,6 +106,7 @@ int pika_hal_platform_GPIO_ioctl_config(pika_dev* dev, default: return -1; } + break; default: #if PIKA_DEBUG_ENABLE __platform_printf("GPIO set port %d to unknown\r\n", @@ -101,5 +114,28 @@ int pika_hal_platform_GPIO_ioctl_config(pika_dev* dev, #endif return -1; } + + /* support event callback */ + if (NULL != cfg->event_callback && + PIKA_HAL_EVENT_CALLBACK_ENA_ENABLE == cfg->event_callback_ena) { + switch (cfg->event_callback_filter) { + case PIKA_HAL_GPIO_EVENT_SIGNAL_RISING: + hosal_gpio_irq_set(dev->platform_data, HOSAL_IRQ_TRIG_POS_PULSE, + _hosal_gpio_irq_handler, dev); + break; + case PIKA_HAL_GPIO_EVENT_SIGNAL_FALLING: + hosal_gpio_irq_set(dev->platform_data, HOSAL_IRQ_TRIG_NEG_PULSE, + _hosal_gpio_irq_handler, dev); + break; + + default: + __platform_printf( + "Error: not supported event callback filter %d\r\n", + cfg->event_callback_filter); + return -1; + } + /* start irq task thread */ + _BLIOT_irq_task_start(); + } return 0; } diff --git a/package/BLIOT/pika_hal_BLIOT_SPI.c b/package/BLIOT/pika_hal_BLIOT_SPI.c index cc021b7dc..7fedf5ed6 100644 --- a/package/BLIOT/pika_hal_BLIOT_SPI.c +++ b/package/BLIOT/pika_hal_BLIOT_SPI.c @@ -101,7 +101,10 @@ int pika_hal_platform_SPI_ioctl_enable(pika_dev* dev) { platform_spi->port, platform_spi->config.freq, platform_spi->config.mode, platform_spi->config.polar_phase); #endif - hosal_spi_init(platform_spi); + if (0 != hosal_spi_init(platform_spi)) { + __platform_printf("SPI: Open SPI%d failed\r\n", platform_spi->port); + return -1; + } return 0; } return -1; @@ -119,11 +122,25 @@ int pika_hal_platform_SPI_ioctl_disable(pika_dev* dev) { int pika_hal_platform_SPI_write(pika_dev* dev, void* buf, size_t count) { hosal_spi_dev_t* platform_spi = (hosal_spi_dev_t*)dev->platform_data; pika_hal_SPI_config* cfg = (pika_hal_SPI_config*)dev->ioctl_config; - return hosal_spi_send(platform_spi, buf, count, cfg->timeout); +#if PIKA_DEBUG_ENABLE + __platform_printf("SPI: Write %d bytes\r\n", count); +#endif + int ret = hosal_spi_send(platform_spi, buf, count, cfg->timeout); + if (0 != ret) { + __platform_printf("SPI: Write %d bytes failed\r\n", count); + } + return ret; } int pika_hal_platform_SPI_read(pika_dev* dev, void* buf, size_t count) { hosal_spi_dev_t* platform_spi = (hosal_spi_dev_t*)dev->platform_data; pika_hal_SPI_config* cfg = (pika_hal_SPI_config*)dev->ioctl_config; - return hosal_spi_recv(platform_spi, buf, count, cfg->timeout); +#if PIKA_DEBUG_ENABLE + __platform_printf("SPI: Read %d bytes\r\n", count); +#endif + int ret = hosal_spi_recv(platform_spi, buf, count, cfg->timeout); + if (0 != ret) { + __platform_printf("SPI: Read %d bytes failed\r\n", count); + } + return ret; } diff --git a/package/BLIOT/pika_hal_BLIOT_UART.c b/package/BLIOT/pika_hal_BLIOT_UART.c new file mode 100644 index 000000000..7fd1a15eb --- /dev/null +++ b/package/BLIOT/pika_hal_BLIOT_UART.c @@ -0,0 +1,161 @@ +#include +#include "../PikaStdDevice/pika_hal.h" +#include "pika_hal_BLIOT_irq_task.h" + +extern hosal_uart_dev_t uart_stdio; + +int pika_hal_platform_UART_open(pika_dev* dev, char* name) { + /* Support UART1 */ + if (name[0] == 'U' && name[1] == 'A' && name[2] == 'R' && name[3] == 'T') { + hosal_uart_dev_t* platform_uart = &uart_stdio; + dev->platform_data = platform_uart; + int UART_num = fast_atoi(name + 4); +#if PIKA_DEBUG_ENABLE + __platform_printf("opening UART%d\r\n", UART_num); +#endif + return 0; + } + return -1; +} + +int pika_hal_platform_UART_close(pika_dev* dev) { + hosal_uart_dev_t* platform_uart = (hosal_uart_dev_t*)dev->platform_data; + if (platform_uart == &uart_stdio) { + return 0; + } + if (NULL != platform_uart) { + pikaFree(platform_uart, sizeof(hosal_uart_dev_t)); + } + return 0; +} + +extern volatile _BLIOT_irq g_irq; +int _hosal_uart_irq_handler(void* p_arg) { + if (g_irq.uart_irq_trigger) { + return 0; + } + g_irq.uart_irq_arg = p_arg; + g_irq.uart_irq_trigger = 1; + return 0; +} + +int pika_hal_platform_UART_ioctl_config(pika_dev* dev, + pika_hal_UART_config* cfg) { + hosal_uart_dev_t* platform_uart = (hosal_uart_dev_t*)dev->platform_data; + if (platform_uart != &uart_stdio) { + platform_uart->config.baud_rate = cfg->baudrate; + switch (cfg->data_bits) { + case PIKA_HAL_UART_DATA_BITS_5: + platform_uart->config.data_width = HOSAL_DATA_WIDTH_5BIT; + break; + case PIKA_HAL_UART_DATA_BITS_6: + platform_uart->config.data_width = HOSAL_DATA_WIDTH_6BIT; + break; + case PIKA_HAL_UART_DATA_BITS_7: + platform_uart->config.data_width = HOSAL_DATA_WIDTH_7BIT; + break; + case PIKA_HAL_UART_DATA_BITS_8: + platform_uart->config.data_width = HOSAL_DATA_WIDTH_8BIT; + break; + default: + platform_uart->config.data_width = HOSAL_DATA_WIDTH_8BIT; + break; + } + switch (cfg->parity) { + case PIKA_HAL_UART_PARITY_NONE: + platform_uart->config.parity = HOSAL_NO_PARITY; + break; + case PIKA_HAL_UART_PARITY_ODD: + platform_uart->config.parity = HOSAL_ODD_PARITY; + break; + case PIKA_HAL_UART_PARITY_EVEN: + platform_uart->config.parity = HOSAL_EVEN_PARITY; + break; + default: + platform_uart->config.parity = HOSAL_NO_PARITY; + break; + } + switch (cfg->stop_bits) { + case PIKA_HAL_UART_STOP_BITS_1: + platform_uart->config.stop_bits = HOSAL_STOP_BITS_1; + break; + case PIKA_HAL_UART_STOP_BITS_2: + platform_uart->config.stop_bits = HOSAL_STOP_BITS_2; + break; + case PIKA_HAL_UART_STOP_BITS_1_5: + platform_uart->config.stop_bits = HOSAL_STOP_BITS_1_5; + break; + default: + platform_uart->config.stop_bits = HOSAL_STOP_BITS_1; + break; + } + } + + /* support event callback */ + if (NULL != cfg->event_callback && + PIKA_HAL_EVENT_CALLBACK_ENA_ENABLE == cfg->event_callback_ena) { + hosal_uart_ioctl(platform_uart, HOSAL_UART_MODE_SET, + (void*)HOSAL_UART_MODE_INT); + switch (cfg->event_callback_filter) { + /* Configure UART to interrupt mode */ + case PIKA_HAL_UART_EVENT_SIGNAL_RX: +#if PIKA_DEBUG_ENABLE + __platform_printf("Setting UART_RX callback\r\n"); +#endif + hosal_uart_callback_set(platform_uart, HOSAL_UART_RX_CALLBACK, + _hosal_uart_irq_handler, dev); + break; + case PIKA_HAL_UART_EVENT_SIGNAL_TX: +#if PIKA_DEBUG_ENABLE + __platform_printf("Setting UART_TX callback\r\n"); +#endif + hosal_uart_callback_set(platform_uart, HOSAL_UART_TX_CALLBACK, + _hosal_uart_irq_handler, dev); + break; + default: + __platform_printf( + "Error: not supported event callback filter %d\r\n", + cfg->event_callback_filter); + return -1; + } + /* start irq task thread */ + _BLIOT_irq_task_start(); + } +#if PIKA_DEBUG_ENABLE +#endif + return 0; +} + +int pika_hal_platform_UART_ioctl_enable(pika_dev* dev) { + if (!dev->is_enabled) { + hosal_uart_dev_t* platform_uart = (hosal_uart_dev_t*)dev->platform_data; + if (platform_uart == &uart_stdio) { + return 0; + } + hosal_uart_init(platform_uart); + return 0; + } + return -1; +} + +int pika_hal_platform_UART_ioctl_disable(pika_dev* dev) { + if (dev->is_enabled) { + hosal_uart_dev_t* platform_uart = (hosal_uart_dev_t*)dev->platform_data; + if (platform_uart == &uart_stdio) { + return 0; + } + hosal_uart_finalize(platform_uart); + return 0; + } + return -1; +} + +int pika_hal_platform_UART_write(pika_dev* dev, void* buf, size_t count) { + hosal_uart_dev_t* platform_uart = (hosal_uart_dev_t*)dev->platform_data; + return hosal_uart_send(platform_uart, buf, count); +} + +int pika_hal_platform_UART_read(pika_dev* dev, void* buf, size_t count) { + hosal_uart_dev_t* platform_uart = (hosal_uart_dev_t*)dev->platform_data; + return hosal_uart_receive(platform_uart, buf, count); +} diff --git a/package/BLIOT/pika_hal_BLIOT_irq_task.c b/package/BLIOT/pika_hal_BLIOT_irq_task.c new file mode 100644 index 000000000..eaaddabc1 --- /dev/null +++ b/package/BLIOT/pika_hal_BLIOT_irq_task.c @@ -0,0 +1,52 @@ +#include "pika_hal_BLIOT_irq_task.h" +#include +#include + +volatile _BLIOT_irq g_irq = {0}; + +static void _irq_task(void* pvParameters) { + while (1) { + vTaskDelay(10); + if (g_irq.gpio_irq_trigger) { + g_irq.gpio_irq_trigger = 0; + pika_dev* dev = (pika_dev*)g_irq.gpio_irq_arg; + pika_hal_GPIO_config* cfg = dev->ioctl_config; + cfg->event_callback(dev, cfg->event_callback_filter); + } + if (g_irq.uart_irq_trigger) { + g_irq.uart_irq_trigger = 0; + pika_dev* dev = (pika_dev*)g_irq.uart_irq_arg; + pika_hal_UART_config* cfg = dev->ioctl_config; + cfg->event_callback(dev, cfg->event_callback_filter); + } + } +} + +static int _BLIOT_irq_init(volatile _BLIOT_irq* irq) { + irq->task_created = 0; + irq->gpio_irq_trigger = 0; + irq->gpio_irq_arg = NULL; + return 0; +} + +int _BLIOT_irq_task_start() { + /* already started, skip */ + if (1 == g_irq.task_created) { + return 0; + } + _BLIOT_irq_init(&g_irq); + g_irq.task_created = 1; +#if PIKA_DEBUG_ENABLE + __platform_printf("Creating _irq_task\r\n"); +#endif + BaseType_t ret = + xTaskCreate(_irq_task, (char*)"_irq_task", 4096, NULL, 15, NULL); + +#if PIKA_DEBUG_ENABLE + if (pdPASS == ret) { + __platform_printf("Create _irq_task succeed.\r\n"); + return 0; + } +#endif + return -1; +} diff --git a/package/BLIOT/pika_hal_BLIOT_irq_task.h b/package/BLIOT/pika_hal_BLIOT_irq_task.h new file mode 100644 index 000000000..b6cee7261 --- /dev/null +++ b/package/BLIOT/pika_hal_BLIOT_irq_task.h @@ -0,0 +1,12 @@ +#include "../PikaStdDevice/pika_hal.h" + +typedef struct { + uint8_t task_created; + uint8_t gpio_irq_trigger; + void* gpio_irq_arg; + + uint8_t uart_irq_trigger; + void* uart_irq_arg; +} _BLIOT_irq; + +int _BLIOT_irq_task_start(); From 83efce79dd31ecda3367b91628b43b99facdc31e Mon Sep 17 00:00:00 2001 From: lyon Date: Fri, 23 Dec 2022 20:22:34 +0800 Subject: [PATCH 35/44] update_toml --- packages.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages.toml b/packages.toml index ff3a7e983..500b4d1dd 100644 --- a/packages.toml +++ b/packages.toml @@ -455,7 +455,8 @@ releases = [ name = "BLIOT" releases = [ "v0.1.0 4599ce8681d293a5cc7682115205ab5e85e9b5e8", - "v0.2.0 eee8e1848eed77f3ebed777230104ebb4dfc3263" + "v0.2.0 eee8e1848eed77f3ebed777230104ebb4dfc3263", + "v0.3.0 fc69ce4145c053d0a5f9191e8706014c5bee4ca8" ] [[packages]] From 747fc1be13d57f920b436a2dbbfce253d8c3546f Mon Sep 17 00:00:00 2001 From: lyon Date: Fri, 23 Dec 2022 20:23:40 +0800 Subject: [PATCH 36/44] add_files --- package/PikaStdDevice/PikaStdDevice_ADC.c | 3 +- package/PikaStdDevice/PikaStdDevice_BaseDev.c | 5 +-- package/PikaStdDevice/PikaStdDevice_CAN.c | 2 +- package/PikaStdDevice/PikaStdDevice_DAC.c | 3 +- package/PikaStdDevice/PikaStdDevice_GPIO.c | 26 +++----------- package/PikaStdDevice/PikaStdDevice_IIC.c | 4 +-- package/PikaStdDevice/PikaStdDevice_PWM.c | 3 +- package/PikaStdDevice/PikaStdDevice_SPI.c | 4 +-- package/PikaStdDevice/PikaStdDevice_Time.c | 3 +- package/PikaStdDevice/PikaStdDevice_UART.c | 35 ++++++++++++++----- package/PikaStdDevice/PikaStdDevice_common.c | 19 ++++++++++ package/PikaStdDevice/PikaStdDevice_common.h | 12 +++++++ 12 files changed, 70 insertions(+), 49 deletions(-) create mode 100644 package/PikaStdDevice/PikaStdDevice_common.c create mode 100644 package/PikaStdDevice/PikaStdDevice_common.h diff --git a/package/PikaStdDevice/PikaStdDevice_ADC.c b/package/PikaStdDevice/PikaStdDevice_ADC.c index 835d53c07..c659077b1 100644 --- a/package/PikaStdDevice/PikaStdDevice_ADC.c +++ b/package/PikaStdDevice/PikaStdDevice_ADC.c @@ -1,6 +1,5 @@ #include "PikaStdDevice_ADC.h" -#include "BaseObj.h" -#include "pika_hal.h" +#include "PikaStdDevice_common.h" void PikaStdDevice_ADC_enable(PikaObj* self) { obj_runNativeMethod(self, "platformEnable", NULL); diff --git a/package/PikaStdDevice/PikaStdDevice_BaseDev.c b/package/PikaStdDevice/PikaStdDevice_BaseDev.c index a9cdbdec1..9ce6df9b8 100644 --- a/package/PikaStdDevice/PikaStdDevice_BaseDev.c +++ b/package/PikaStdDevice/PikaStdDevice_BaseDev.c @@ -1,8 +1,5 @@ #include "PikaStdDevice_BaseDev.h" -#include "BaseObj.h" -#include "PikaObj.h" -#include "dataStrs.h" -#include "pika_hal.h" +#include "PikaStdDevice_common.h" #if !PIKASCRIPT_VERSION_REQUIRE_MINIMUN(1, 10, 4) #error "This library requires PikaScript version 1.10.4 or higher" diff --git a/package/PikaStdDevice/PikaStdDevice_CAN.c b/package/PikaStdDevice/PikaStdDevice_CAN.c index c34701046..830c45b7c 100644 --- a/package/PikaStdDevice/PikaStdDevice_CAN.c +++ b/package/PikaStdDevice/PikaStdDevice_CAN.c @@ -1,5 +1,5 @@ #include "PikaStdDevice_CAN.h" -#include "pika_hal.h" +#include "PikaStdDevice_common.h" void PikaStdDevice_CAN___init__(PikaObj* self) {} diff --git a/package/PikaStdDevice/PikaStdDevice_DAC.c b/package/PikaStdDevice/PikaStdDevice_DAC.c index 4aa2c26de..da29a5246 100644 --- a/package/PikaStdDevice/PikaStdDevice_DAC.c +++ b/package/PikaStdDevice/PikaStdDevice_DAC.c @@ -1,6 +1,5 @@ #include "PikaStdDevice_DAC.h" -#include "BaseObj.h" -#include "pika_hal.h" +#include "PikaStdDevice_common.h" static pika_dev* _get_dev(PikaObj* self) { pika_dev* dev = obj_getPtr(self, "pika_dev"); diff --git a/package/PikaStdDevice/PikaStdDevice_GPIO.c b/package/PikaStdDevice/PikaStdDevice_GPIO.c index 8b0466138..9465ba729 100644 --- a/package/PikaStdDevice/PikaStdDevice_GPIO.c +++ b/package/PikaStdDevice/PikaStdDevice_GPIO.c @@ -1,6 +1,5 @@ #include "PikaStdDevice_GPIO.h" -#include "BaseObj.h" -#include "pika_hal.h" +#include "PikaStdDevice_common.h" void PikaStdDevice_GPIO_init(PikaObj* self) { obj_setInt(self, "isEnable", 0); @@ -149,32 +148,15 @@ void PikaStdDevice_GPIO_platformRead(PikaObj* self) { obj_setInt(self, "readBuff", val); } -extern PikaEventListener* g_pika_device_event_listener; - -void _pika_hal_GPIO_event_callback(pika_dev* dev, - PIKA_HAL_GPIO_EVENT_SIGNAL signal) { - pks_eventLisener_sendSignal(g_pika_device_event_listener, (uintptr_t)dev, - signal); -} - void PikaStdDevice_GPIO_setCallBack(PikaObj* self, - Arg* eventCallBack, + Arg* eventCallback, int filter) { pika_dev* dev = _get_dev(self); #if PIKA_EVENT_ENABLE - obj_setArg(self, "eventCallBack", eventCallBack); - /* init event_listener for the first time */ - if (NULL == g_pika_device_event_listener) { - pks_eventLisener_init(&g_pika_device_event_listener); - } - /* use the pointer of dev as the event id */ - uint32_t eventId = (uintptr_t)dev; - /* regist event to event listener */ - pks_eventLicener_registEvent(g_pika_device_event_listener, eventId, self); - + _PikaStdDevice_setCallBack(self, eventCallback, (uintptr_t)dev); /* regist event to pika_hal */ pika_hal_GPIO_config cfg_cb = {0}; - cfg_cb.event_callback = _pika_hal_GPIO_event_callback; + cfg_cb.event_callback = (void*)_PikaStdDevice_event_handler; cfg_cb.event_callback_filter = filter; cfg_cb.event_callback_ena = PIKA_HAL_EVENT_CALLBACK_ENA_ENABLE; pika_hal_ioctl(dev, PIKA_HAL_IOCTL_CONFIG, &cfg_cb); diff --git a/package/PikaStdDevice/PikaStdDevice_IIC.c b/package/PikaStdDevice/PikaStdDevice_IIC.c index d519a82c1..332d896e2 100644 --- a/package/PikaStdDevice/PikaStdDevice_IIC.c +++ b/package/PikaStdDevice/PikaStdDevice_IIC.c @@ -1,7 +1,5 @@ #include "PikaStdDevice_IIC.h" -#include "BaseObj.h" -#include "PikaObj.h" -#include "pika_hal.h" +#include "PikaStdDevice_common.h" void PikaStdDevice_IIC_init(PikaObj* self) { obj_setInt(self, "deviceAddr", 0); diff --git a/package/PikaStdDevice/PikaStdDevice_PWM.c b/package/PikaStdDevice/PikaStdDevice_PWM.c index 89215b09f..d999f9231 100644 --- a/package/PikaStdDevice/PikaStdDevice_PWM.c +++ b/package/PikaStdDevice/PikaStdDevice_PWM.c @@ -1,6 +1,5 @@ #include "PikaStdDevice_PWM.h" -#include "BaseObj.h" -#include "pika_hal.h" +#include "PikaStdDevice_common.h" void PikaStdDevice_PWM_init(PikaObj* self) { obj_setStr(self, "pin", "none"); diff --git a/package/PikaStdDevice/PikaStdDevice_SPI.c b/package/PikaStdDevice/PikaStdDevice_SPI.c index 108dbc1ae..fe55ddf12 100644 --- a/package/PikaStdDevice/PikaStdDevice_SPI.c +++ b/package/PikaStdDevice/PikaStdDevice_SPI.c @@ -1,7 +1,5 @@ #include "PikaStdDevice_SPI.h" -#include "BaseObj.h" -#include "PikaObj.h" -#include "pika_hal.h" +#include "PikaStdDevice_common.h" void PikaStdDevice_SPI___init__(PikaObj* self) { obj_setInt(self, "baudRate", 1000); diff --git a/package/PikaStdDevice/PikaStdDevice_Time.c b/package/PikaStdDevice/PikaStdDevice_Time.c index bc1084df0..f0c3dd7ca 100644 --- a/package/PikaStdDevice/PikaStdDevice_Time.c +++ b/package/PikaStdDevice/PikaStdDevice_Time.c @@ -1,6 +1,5 @@ #include "PikaStdDevice_Time.h" -#include "BaseObj.h" -#include "pika_hal.h" +#include "PikaStdDevice_common.h" #if defined(__linux) #include #endif diff --git a/package/PikaStdDevice/PikaStdDevice_UART.c b/package/PikaStdDevice/PikaStdDevice_UART.c index 30f9d179a..7c4f3d90f 100644 --- a/package/PikaStdDevice/PikaStdDevice_UART.c +++ b/package/PikaStdDevice/PikaStdDevice_UART.c @@ -1,6 +1,5 @@ #include "PikaStdDevice_UART.h" -#include "BaseObj.h" -#include "pika_hal.h" +#include "PikaStdDevice_common.h" void PikaStdDevice_UART_enable(PikaObj* self) { obj_runNativeMethod(self, "platformEnable", NULL); @@ -11,14 +10,19 @@ void PikaStdDevice_UART_disable(PikaObj* self) { } void PikaStdDevice_UART_init(PikaObj* self) { - obj_setInt(self, "baudRate", 115200); - obj_setInt(self, "id", 1); - obj_setStr(self, "readBuff", ""); + /* const */ obj_setInt(self, "FLOW_CONTROL_NONE", PIKA_HAL_UART_FLOW_CONTROL_NONE); obj_setInt(self, "FLOW_CONTROL_RTS", PIKA_HAL_UART_FLOW_CONTROL_RTS); obj_setInt(self, "FLOW_CONTROL_CTS", PIKA_HAL_UART_FLOW_CONTROL_CTS); obj_setInt(self, "FLOW_CONTROL_RTS_CTS", PIKA_HAL_UART_FLOW_CONTROL_RTS_CTS); + + obj_setInt(self, "SIGNAL_RX", PIKA_HAL_UART_EVENT_SIGNAL_RX); + obj_setInt(self, "SIGNAL_TX", PIKA_HAL_UART_EVENT_SIGNAL_TX); + + obj_setInt(self, "baudRate", 115200); + obj_setInt(self, "id", 1); + obj_setStr(self, "readBuff", ""); obj_setInt(self, "flowControl", PIKA_HAL_UART_FLOW_CONTROL_NONE); } @@ -42,7 +46,7 @@ void PikaStdDevice_UART_setBaudRate(PikaObj* self, int baudRate) { obj_setInt(self, "baudRate", baudRate); } -void PikaStdDevice_UART_setFlowControl(PikaObj *self, int flowControl){ +void PikaStdDevice_UART_setFlowControl(PikaObj* self, int flowControl) { obj_setInt(self, "flowControl", flowControl); } @@ -95,7 +99,8 @@ void PikaStdDevice_UART_platformRead(PikaObj* self) { obj_setBytes(self, "_readData", NULL, len + 1); char* buff = (char*)obj_getBytes(self, "_readData"); pika_dev* dev = _get_dev(self); - pika_hal_read(dev, buff, len); + int len_get = pika_hal_read(dev, buff, len); + buff[len_get] = 0; obj_setStr(self, "readData", buff); } @@ -133,4 +138,18 @@ void PikaStdDevice_UART_platformWriteBytes(PikaObj* self) { void PikaStdDevice_UART_setCallBack(PikaObj* self, Arg* eventCallBack, - int filter) {} + int filter) { + pika_dev* dev = _get_dev(self); +#if PIKA_EVENT_ENABLE + _PikaStdDevice_setCallBack(self, eventCallBack, (uintptr_t)dev); + /* regist event to pika_hal */ + pika_hal_UART_config cfg_cb = {0}; + cfg_cb.event_callback = (void*)_PikaStdDevice_event_handler; + cfg_cb.event_callback_filter = filter; + cfg_cb.event_callback_ena = PIKA_HAL_EVENT_CALLBACK_ENA_ENABLE; + pika_hal_ioctl(dev, PIKA_HAL_IOCTL_CONFIG, &cfg_cb); +#else + obj_setErrorCode(self, 1); + obj_setSysOut(self, "[error] PIKA_EVENT_ENABLE is disabled."); +#endif +} diff --git a/package/PikaStdDevice/PikaStdDevice_common.c b/package/PikaStdDevice/PikaStdDevice_common.c new file mode 100644 index 000000000..373e41f56 --- /dev/null +++ b/package/PikaStdDevice/PikaStdDevice_common.c @@ -0,0 +1,19 @@ +#include "PikaStdDevice_common.h" + +extern PikaEventListener* g_pika_device_event_listener; +void _PikaStdDevice_event_handler(pika_dev* dev, int signal) { + pks_eventLisener_sendSignal(g_pika_device_event_listener, (uintptr_t)dev, + signal); +} + +void _PikaStdDevice_setCallBack(PikaObj* self, + Arg* eventCallback, + uint32_t eventId) { + obj_setArg(self, "eventCallBack", eventCallback); + /* init event_listener for the first time */ + if (NULL == g_pika_device_event_listener) { + pks_eventLisener_init(&g_pika_device_event_listener); + } + /* regist event to event listener */ + pks_eventLicener_registEvent(g_pika_device_event_listener, eventId, self); +} diff --git a/package/PikaStdDevice/PikaStdDevice_common.h b/package/PikaStdDevice/PikaStdDevice_common.h new file mode 100644 index 000000000..a8a19a86c --- /dev/null +++ b/package/PikaStdDevice/PikaStdDevice_common.h @@ -0,0 +1,12 @@ +#ifndef _PIKA_STDDEVICE_COMMON_H +#define _PIKA_STDDEVICE_COMMON_H +#include "PikaObj.h" +#include "PikaVM.h" +#include "pika_hal.h" +void _PikaStdDevice_setCallBack(PikaObj* self, + Arg* eventCallback, + uint32_t eventId); + +void _PikaStdDevice_event_handler(pika_dev* dev, int signal); + +#endif From 8c9f36a81ed0df7398bd0fc608b571e51aa52d48 Mon Sep 17 00:00:00 2001 From: lyon Date: Fri, 23 Dec 2022 20:23:40 +0800 Subject: [PATCH 37/44] update_toml --- packages.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages.toml b/packages.toml index ff3a7e983..7fed374b6 100644 --- a/packages.toml +++ b/packages.toml @@ -174,7 +174,8 @@ releases = [ "v2.0.0 e89c585f46ee98811611ea56d5abfc618a41ee3b", "v2.1.0 852daad3c9a95dbce54dbf1d2cdb5b2321826b4f", "v2.1.1 5eadba95fa573e3409f65c6392804d3c60d627ac", - "v2.1.2 36ef746f5791a57212cc1d02fe885814e613e60c" + "v2.1.2 36ef746f5791a57212cc1d02fe885814e613e60c", + "v2.2.0 747fc1be13d57f920b436a2dbbfce253d8c3546f" ] [[packages]] From 72fb6bd5edfaacacaca0f48d99d88ce49802c96c Mon Sep 17 00:00:00 2001 From: lyon Date: Fri, 23 Dec 2022 20:30:56 +0800 Subject: [PATCH 38/44] update port std --- .../PikaStdDevice/PikaStdDevice_ADC.c | 3 +- .../PikaStdDevice/PikaStdDevice_BaseDev.c | 5 +-- .../PikaStdDevice/PikaStdDevice_CAN.c | 2 +- .../PikaStdDevice/PikaStdDevice_DAC.c | 3 +- .../PikaStdDevice/PikaStdDevice_GPIO.c | 26 +++----------- .../PikaStdDevice/PikaStdDevice_IIC.c | 4 +-- .../PikaStdDevice/PikaStdDevice_PWM.c | 3 +- .../PikaStdDevice/PikaStdDevice_SPI.c | 4 +-- .../PikaStdDevice/PikaStdDevice_Time.c | 3 +- .../PikaStdDevice/PikaStdDevice_UART.c | 35 ++++++++++++++----- 10 files changed, 39 insertions(+), 49 deletions(-) diff --git a/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_ADC.c b/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_ADC.c index 835d53c07..c659077b1 100644 --- a/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_ADC.c +++ b/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_ADC.c @@ -1,6 +1,5 @@ #include "PikaStdDevice_ADC.h" -#include "BaseObj.h" -#include "pika_hal.h" +#include "PikaStdDevice_common.h" void PikaStdDevice_ADC_enable(PikaObj* self) { obj_runNativeMethod(self, "platformEnable", NULL); diff --git a/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_BaseDev.c b/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_BaseDev.c index a9cdbdec1..9ce6df9b8 100644 --- a/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_BaseDev.c +++ b/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_BaseDev.c @@ -1,8 +1,5 @@ #include "PikaStdDevice_BaseDev.h" -#include "BaseObj.h" -#include "PikaObj.h" -#include "dataStrs.h" -#include "pika_hal.h" +#include "PikaStdDevice_common.h" #if !PIKASCRIPT_VERSION_REQUIRE_MINIMUN(1, 10, 4) #error "This library requires PikaScript version 1.10.4 or higher" diff --git a/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_CAN.c b/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_CAN.c index c34701046..830c45b7c 100644 --- a/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_CAN.c +++ b/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_CAN.c @@ -1,5 +1,5 @@ #include "PikaStdDevice_CAN.h" -#include "pika_hal.h" +#include "PikaStdDevice_common.h" void PikaStdDevice_CAN___init__(PikaObj* self) {} diff --git a/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_DAC.c b/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_DAC.c index 4aa2c26de..da29a5246 100644 --- a/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_DAC.c +++ b/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_DAC.c @@ -1,6 +1,5 @@ #include "PikaStdDevice_DAC.h" -#include "BaseObj.h" -#include "pika_hal.h" +#include "PikaStdDevice_common.h" static pika_dev* _get_dev(PikaObj* self) { pika_dev* dev = obj_getPtr(self, "pika_dev"); diff --git a/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_GPIO.c b/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_GPIO.c index 8b0466138..9465ba729 100644 --- a/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_GPIO.c +++ b/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_GPIO.c @@ -1,6 +1,5 @@ #include "PikaStdDevice_GPIO.h" -#include "BaseObj.h" -#include "pika_hal.h" +#include "PikaStdDevice_common.h" void PikaStdDevice_GPIO_init(PikaObj* self) { obj_setInt(self, "isEnable", 0); @@ -149,32 +148,15 @@ void PikaStdDevice_GPIO_platformRead(PikaObj* self) { obj_setInt(self, "readBuff", val); } -extern PikaEventListener* g_pika_device_event_listener; - -void _pika_hal_GPIO_event_callback(pika_dev* dev, - PIKA_HAL_GPIO_EVENT_SIGNAL signal) { - pks_eventLisener_sendSignal(g_pika_device_event_listener, (uintptr_t)dev, - signal); -} - void PikaStdDevice_GPIO_setCallBack(PikaObj* self, - Arg* eventCallBack, + Arg* eventCallback, int filter) { pika_dev* dev = _get_dev(self); #if PIKA_EVENT_ENABLE - obj_setArg(self, "eventCallBack", eventCallBack); - /* init event_listener for the first time */ - if (NULL == g_pika_device_event_listener) { - pks_eventLisener_init(&g_pika_device_event_listener); - } - /* use the pointer of dev as the event id */ - uint32_t eventId = (uintptr_t)dev; - /* regist event to event listener */ - pks_eventLicener_registEvent(g_pika_device_event_listener, eventId, self); - + _PikaStdDevice_setCallBack(self, eventCallback, (uintptr_t)dev); /* regist event to pika_hal */ pika_hal_GPIO_config cfg_cb = {0}; - cfg_cb.event_callback = _pika_hal_GPIO_event_callback; + cfg_cb.event_callback = (void*)_PikaStdDevice_event_handler; cfg_cb.event_callback_filter = filter; cfg_cb.event_callback_ena = PIKA_HAL_EVENT_CALLBACK_ENA_ENABLE; pika_hal_ioctl(dev, PIKA_HAL_IOCTL_CONFIG, &cfg_cb); diff --git a/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_IIC.c b/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_IIC.c index d519a82c1..332d896e2 100644 --- a/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_IIC.c +++ b/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_IIC.c @@ -1,7 +1,5 @@ #include "PikaStdDevice_IIC.h" -#include "BaseObj.h" -#include "PikaObj.h" -#include "pika_hal.h" +#include "PikaStdDevice_common.h" void PikaStdDevice_IIC_init(PikaObj* self) { obj_setInt(self, "deviceAddr", 0); diff --git a/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_PWM.c b/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_PWM.c index 89215b09f..d999f9231 100644 --- a/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_PWM.c +++ b/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_PWM.c @@ -1,6 +1,5 @@ #include "PikaStdDevice_PWM.h" -#include "BaseObj.h" -#include "pika_hal.h" +#include "PikaStdDevice_common.h" void PikaStdDevice_PWM_init(PikaObj* self) { obj_setStr(self, "pin", "none"); diff --git a/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_SPI.c b/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_SPI.c index 108dbc1ae..fe55ddf12 100644 --- a/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_SPI.c +++ b/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_SPI.c @@ -1,7 +1,5 @@ #include "PikaStdDevice_SPI.h" -#include "BaseObj.h" -#include "PikaObj.h" -#include "pika_hal.h" +#include "PikaStdDevice_common.h" void PikaStdDevice_SPI___init__(PikaObj* self) { obj_setInt(self, "baudRate", 1000); diff --git a/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_Time.c b/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_Time.c index bc1084df0..f0c3dd7ca 100644 --- a/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_Time.c +++ b/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_Time.c @@ -1,6 +1,5 @@ #include "PikaStdDevice_Time.h" -#include "BaseObj.h" -#include "pika_hal.h" +#include "PikaStdDevice_common.h" #if defined(__linux) #include #endif diff --git a/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_UART.c b/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_UART.c index 30f9d179a..7c4f3d90f 100644 --- a/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_UART.c +++ b/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_UART.c @@ -1,6 +1,5 @@ #include "PikaStdDevice_UART.h" -#include "BaseObj.h" -#include "pika_hal.h" +#include "PikaStdDevice_common.h" void PikaStdDevice_UART_enable(PikaObj* self) { obj_runNativeMethod(self, "platformEnable", NULL); @@ -11,14 +10,19 @@ void PikaStdDevice_UART_disable(PikaObj* self) { } void PikaStdDevice_UART_init(PikaObj* self) { - obj_setInt(self, "baudRate", 115200); - obj_setInt(self, "id", 1); - obj_setStr(self, "readBuff", ""); + /* const */ obj_setInt(self, "FLOW_CONTROL_NONE", PIKA_HAL_UART_FLOW_CONTROL_NONE); obj_setInt(self, "FLOW_CONTROL_RTS", PIKA_HAL_UART_FLOW_CONTROL_RTS); obj_setInt(self, "FLOW_CONTROL_CTS", PIKA_HAL_UART_FLOW_CONTROL_CTS); obj_setInt(self, "FLOW_CONTROL_RTS_CTS", PIKA_HAL_UART_FLOW_CONTROL_RTS_CTS); + + obj_setInt(self, "SIGNAL_RX", PIKA_HAL_UART_EVENT_SIGNAL_RX); + obj_setInt(self, "SIGNAL_TX", PIKA_HAL_UART_EVENT_SIGNAL_TX); + + obj_setInt(self, "baudRate", 115200); + obj_setInt(self, "id", 1); + obj_setStr(self, "readBuff", ""); obj_setInt(self, "flowControl", PIKA_HAL_UART_FLOW_CONTROL_NONE); } @@ -42,7 +46,7 @@ void PikaStdDevice_UART_setBaudRate(PikaObj* self, int baudRate) { obj_setInt(self, "baudRate", baudRate); } -void PikaStdDevice_UART_setFlowControl(PikaObj *self, int flowControl){ +void PikaStdDevice_UART_setFlowControl(PikaObj* self, int flowControl) { obj_setInt(self, "flowControl", flowControl); } @@ -95,7 +99,8 @@ void PikaStdDevice_UART_platformRead(PikaObj* self) { obj_setBytes(self, "_readData", NULL, len + 1); char* buff = (char*)obj_getBytes(self, "_readData"); pika_dev* dev = _get_dev(self); - pika_hal_read(dev, buff, len); + int len_get = pika_hal_read(dev, buff, len); + buff[len_get] = 0; obj_setStr(self, "readData", buff); } @@ -133,4 +138,18 @@ void PikaStdDevice_UART_platformWriteBytes(PikaObj* self) { void PikaStdDevice_UART_setCallBack(PikaObj* self, Arg* eventCallBack, - int filter) {} + int filter) { + pika_dev* dev = _get_dev(self); +#if PIKA_EVENT_ENABLE + _PikaStdDevice_setCallBack(self, eventCallBack, (uintptr_t)dev); + /* regist event to pika_hal */ + pika_hal_UART_config cfg_cb = {0}; + cfg_cb.event_callback = (void*)_PikaStdDevice_event_handler; + cfg_cb.event_callback_filter = filter; + cfg_cb.event_callback_ena = PIKA_HAL_EVENT_CALLBACK_ENA_ENABLE; + pika_hal_ioctl(dev, PIKA_HAL_IOCTL_CONFIG, &cfg_cb); +#else + obj_setErrorCode(self, 1); + obj_setSysOut(self, "[error] PIKA_EVENT_ENABLE is disabled."); +#endif +} From 61a37077059161c1dc0d313503f37f70167bfc8a Mon Sep 17 00:00:00 2001 From: lyon Date: Sat, 24 Dec 2022 14:54:46 +0800 Subject: [PATCH 39/44] add std_common --- .../PikaStdDevice/PikaStdDevice_common.c | 19 +++++++++++++++++++ .../PikaStdDevice/PikaStdDevice_common.h | 12 ++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_common.c create mode 100644 port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_common.h diff --git a/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_common.c b/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_common.c new file mode 100644 index 000000000..373e41f56 --- /dev/null +++ b/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_common.c @@ -0,0 +1,19 @@ +#include "PikaStdDevice_common.h" + +extern PikaEventListener* g_pika_device_event_listener; +void _PikaStdDevice_event_handler(pika_dev* dev, int signal) { + pks_eventLisener_sendSignal(g_pika_device_event_listener, (uintptr_t)dev, + signal); +} + +void _PikaStdDevice_setCallBack(PikaObj* self, + Arg* eventCallback, + uint32_t eventId) { + obj_setArg(self, "eventCallBack", eventCallback); + /* init event_listener for the first time */ + if (NULL == g_pika_device_event_listener) { + pks_eventLisener_init(&g_pika_device_event_listener); + } + /* regist event to event listener */ + pks_eventLicener_registEvent(g_pika_device_event_listener, eventId, self); +} diff --git a/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_common.h b/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_common.h new file mode 100644 index 000000000..a8a19a86c --- /dev/null +++ b/port/linux/package/pikascript/pikascript-lib/PikaStdDevice/PikaStdDevice_common.h @@ -0,0 +1,12 @@ +#ifndef _PIKA_STDDEVICE_COMMON_H +#define _PIKA_STDDEVICE_COMMON_H +#include "PikaObj.h" +#include "PikaVM.h" +#include "pika_hal.h" +void _PikaStdDevice_setCallBack(PikaObj* self, + Arg* eventCallback, + uint32_t eventId); + +void _PikaStdDevice_event_handler(pika_dev* dev, int signal); + +#endif From 75ce1ba5c81b9e8bfbe3c0df974cac9dd43014a0 Mon Sep 17 00:00:00 2001 From: lyon Date: Sat, 24 Dec 2022 15:03:35 +0800 Subject: [PATCH 40/44] fix LLD --- package/PikaStdLib/PikaStdLib_SysObj.c | 4 ++++ .../pikascript/pikascript-lib/PikaStdLib/PikaStdLib_SysObj.c | 4 ++++ src/dataArg.c | 2 +- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/package/PikaStdLib/PikaStdLib_SysObj.c b/package/PikaStdLib/PikaStdLib_SysObj.c index 70dd39da4..e1f7e0245 100644 --- a/package/PikaStdLib/PikaStdLib_SysObj.c +++ b/package/PikaStdLib/PikaStdLib_SysObj.c @@ -443,7 +443,11 @@ static char* __print_arg(PikaObj* self, Arg* val) { } if (arg_type == ARG_TYPE_INT) { int64_t value = arg_getInt(val); +#if PIKA_PRINT_LLD_ENABLE res = strsFormat(&buffs, 32, "%lld", value); +#else + res = strsFormat(&buffs, 32, "%d", value); +#endif goto __exit; } if (arg_type == ARG_TYPE_FLOAT) { diff --git a/port/linux/package/pikascript/pikascript-lib/PikaStdLib/PikaStdLib_SysObj.c b/port/linux/package/pikascript/pikascript-lib/PikaStdLib/PikaStdLib_SysObj.c index 70dd39da4..e1f7e0245 100644 --- a/port/linux/package/pikascript/pikascript-lib/PikaStdLib/PikaStdLib_SysObj.c +++ b/port/linux/package/pikascript/pikascript-lib/PikaStdLib/PikaStdLib_SysObj.c @@ -443,7 +443,11 @@ static char* __print_arg(PikaObj* self, Arg* val) { } if (arg_type == ARG_TYPE_INT) { int64_t value = arg_getInt(val); +#if PIKA_PRINT_LLD_ENABLE res = strsFormat(&buffs, 32, "%lld", value); +#else + res = strsFormat(&buffs, 32, "%d", value); +#endif goto __exit; } if (arg_type == ARG_TYPE_FLOAT) { diff --git a/src/dataArg.c b/src/dataArg.c index 77a02e695..c249ad8f0 100644 --- a/src/dataArg.c +++ b/src/dataArg.c @@ -295,7 +295,7 @@ void arg_singlePrint(Arg* self, PIKA_BOOL in_REPL, char* end) { #if PIKA_PRINT_LLD_ENABLE __platform_printf("%lld%s", (long long int)arg_getInt(self), end); #else - __platform_printf("%d%s", (int)arg_getInt(arg), end); + __platform_printf("%d%s", (int)arg_getInt(self), end); #endif return; } From 56703bf803b1d3af2ac33b01b97fab252b7a5b26 Mon Sep 17 00:00:00 2001 From: lyon Date: Sat, 24 Dec 2022 15:41:54 +0800 Subject: [PATCH 41/44] add pika_libc --- package/pika_libc/pika_vsnprintf.c | 1268 +++++++++++++++++ .../pikascript-lib/pika_libc/pika_vsnprintf.c | 1268 +++++++++++++++++ test/pika_config_gtest.c | 9 +- 3 files changed, 2541 insertions(+), 4 deletions(-) create mode 100644 package/pika_libc/pika_vsnprintf.c create mode 100644 port/linux/package/pikascript/pikascript-lib/pika_libc/pika_vsnprintf.c diff --git a/package/pika_libc/pika_vsnprintf.c b/package/pika_libc/pika_vsnprintf.c new file mode 100644 index 000000000..0e02438a4 --- /dev/null +++ b/package/pika_libc/pika_vsnprintf.c @@ -0,0 +1,1268 @@ +/* + * Copyright (c) 2021, Meco Jianting Man + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-11-27 Meco Man porting for rt_vsnprintf as the fully functional + * version + */ + +/** + * @author (c) Eyal Rozenberg + * 2021, Haifa, Palestine/Israel + * @author (c) Marco Paland (info@paland.com) + * 2014-2019, PALANDesign Hannover, Germany + * + * @note Others have made smaller contributions to this file: see the + * contributors page at https://github.com/eyalroz/printf/graphs/contributors + * or ask one of the authors. + * + * @brief Small stand-alone implementation of the printf family of functions + * (`(v)printf`, `(v)s(n)printf` etc., geared towards use on embedded systems + * with a very limited resources. + * + * @note the implementations are thread-safe; re-entrant; use no functions from + * the standard library; and do not dynamically allocate any memory. + * + * @license The MIT License (MIT) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include +#include +#include +#include "pika_adapter_rtt.h" + +// 'ntoa' conversion buffer size, this must be big enough to hold one converted +// numeric number including padded zeros (dynamically created on stack) +#ifndef PRINTF_INTEGER_BUFFER_SIZE +#define PRINTF_INTEGER_BUFFER_SIZE 32 +#endif + +// 'ftoa' conversion buffer size, this must be big enough to hold one converted +// float number including padded zeros (dynamically created on stack) +#ifndef PRINTF_FTOA_BUFFER_SIZE +#define PRINTF_FTOA_BUFFER_SIZE 32 +#endif + +// Support for the decimal notation floating point conversion specifiers (%f, +// %F) +#ifndef PRINTF_SUPPORT_DECIMAL_SPECIFIERS +#define PRINTF_SUPPORT_DECIMAL_SPECIFIERS 1 +#endif + +// Support for the exponential notatin floating point conversion specifiers (%e, +// %g, %E, %G) +#ifndef PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS +#define PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS 1 +#endif + +// Default precision for the floating point conversion specifiers (the C +// standard sets this at 6) +#ifndef PRINTF_DEFAULT_FLOAT_PRECISION +#define PRINTF_DEFAULT_FLOAT_PRECISION 6 +#endif + +// According to the C languages standard, printf() and related functions must be +// able to print any integral number in floating-point notation, regardless of +// length, when using the %f specifier - possibly hundreds of characters, +// potentially overflowing your buffers. In this implementation, all values +// beyond this threshold are switched to exponential notation. +#ifndef PRINTF_MAX_INTEGRAL_DIGITS_FOR_DECIMAL +#define PRINTF_MAX_INTEGRAL_DIGITS_FOR_DECIMAL 9 +#endif + +// Support for the long long integral types (with the ll, z and t length +// modifiers for specifiers %d,%i,%o,%x,%X,%u, and with the %p specifier). Note: +// 'L' (long double) is not supported. +#ifndef PRINTF_SUPPORT_LONG_LONG +#define PRINTF_SUPPORT_LONG_LONG 1 +#endif + +#if PRINTF_SUPPORT_LONG_LONG +typedef unsigned long long printf_unsigned_value_t; +typedef long long printf_signed_value_t; +#else +typedef unsigned long printf_unsigned_value_t; +typedef long printf_signed_value_t; +#endif + +#define PRINTF_PREFER_DECIMAL false +#define PRINTF_PREFER_EXPONENTIAL true + +/////////////////////////////////////////////////////////////////////////////// + +// The following will convert the number-of-digits into an exponential-notation +// literal +#define PRINTF_CONCATENATE(s1, s2) s1##s2 +#define PRINTF_EXPAND_THEN_CONCATENATE(s1, s2) PRINTF_CONCATENATE(s1, s2) +#define PRINTF_FLOAT_NOTATION_THRESHOLD \ + PRINTF_EXPAND_THEN_CONCATENATE(1e, PRINTF_MAX_INTEGRAL_DIGITS_FOR_DECIMAL) + +// internal flag definitions +#define FLAGS_ZEROPAD (1U << 0U) +#define FLAGS_LEFT (1U << 1U) +#define FLAGS_PLUS (1U << 2U) +#define FLAGS_SPACE (1U << 3U) +#define FLAGS_HASH (1U << 4U) +#define FLAGS_UPPERCASE (1U << 5U) +#define FLAGS_CHAR (1U << 6U) +#define FLAGS_SHORT (1U << 7U) +#define FLAGS_LONG (1U << 8U) +#define FLAGS_LONG_LONG (1U << 9U) +#define FLAGS_PRECISION (1U << 10U) +#define FLAGS_ADAPT_EXP (1U << 11U) +#define FLAGS_POINTER (1U << 12U) +// Note: Similar, but not identical, effect as FLAGS_HASH + +#define BASE_BINARY 2 +#define BASE_OCTAL 8 +#define BASE_DECIMAL 10 +#define BASE_HEX 16 + +typedef uint8_t numeric_base_t; + +#if (PRINTF_SUPPORT_DECIMAL_SPECIFIERS || PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS) +#include +#if FLT_RADIX != 2 +#error "Non-binary-radix floating-point types are unsupported." +#endif + +#if DBL_MANT_DIG == 24 + +#define DOUBLE_SIZE_IN_BITS 32 +typedef uint32_t double_uint_t; +#define DOUBLE_EXPONENT_MASK 0xFFU +#define DOUBLE_BASE_EXPONENT 127 + +#elif DBL_MANT_DIG == 53 + +#define DOUBLE_SIZE_IN_BITS 64 +typedef uint64_t double_uint_t; +#define DOUBLE_EXPONENT_MASK 0x7FFU +#define DOUBLE_BASE_EXPONENT 1023 + +#else +#error "Unsupported double type configuration" +#endif +#define DOUBLE_STORED_MANTISSA_BITS (DBL_MANT_DIG - 1) + +typedef union { + double_uint_t U; + double F; +} double_with_bit_access; + +// This is unnecessary in C99, since compound initializers can be used, +// but: 1. Some compilers are finicky about this; 2. Some people may want to +// convert this to C89; +// 3. If you try to use it as C++, only C++20 supports compound literals +static inline double_with_bit_access get_bit_access(double x) { + double_with_bit_access dwba; + dwba.F = x; + return dwba; +} + +static inline int get_sign(double x) { + // The sign is stored in the highest bit + return get_bit_access(x).U >> (DOUBLE_SIZE_IN_BITS - 1); +} + +static inline int get_exp2(double_with_bit_access x) { + // The exponent in an IEEE-754 floating-point number occupies a contiguous + // sequence of bits (e.g. 52..62 for 64-bit doubles), but with a non-trivial + // representation: An unsigned offset from some negative value (with the + // extremal offset values reserved for special use). + return (int)((x.U >> DOUBLE_STORED_MANTISSA_BITS) & DOUBLE_EXPONENT_MASK) - + DOUBLE_BASE_EXPONENT; +} +#define PRINTF_ABS(_x) ((_x) > 0 ? (_x) : -(_x)) + +#endif // (PRINTF_SUPPORT_DECIMAL_SPECIFIERS || + // PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS) + +// Note in particular the behavior here on LONG_MIN or LLONG_MIN; it is valid +// and well-defined, but if you're not careful you can easily trigger undefined +// behavior with -LONG_MIN or -LLONG_MIN +#define ABS_FOR_PRINTING(_x) \ + ((printf_unsigned_value_t)((_x) > 0 ? (_x) : -((printf_signed_value_t)_x))) + +// output function type +typedef void (*out_fct_type)(char character, + void* buffer, + size_t idx, + size_t maxlen); + +// wrapper (used as buffer) for output function type +typedef struct { + void (*fct)(char character, void* arg); + void* arg; +} out_function_wrapper_type; + +// internal buffer output +static inline void out_buffer(char character, + void* buffer, + size_t idx, + size_t maxlen) { + if (idx < maxlen) { + ((char*)buffer)[idx] = character; + } +} + +// internal null output +static inline void out_discard(char character, + void* buffer, + size_t idx, + size_t maxlen) { + (void)character; + (void)buffer; + (void)idx; + (void)maxlen; +} + +// internal secure strlen +// @return The length of the string (excluding the terminating 0) limited by +// 'maxsize' +static inline unsigned int strnlen_s_(const char* str, size_t maxsize) { + const char* s; + for (s = str; *s && maxsize--; ++s) + ; + return (unsigned int)(s - str); +} + +// internal test if char is a digit (0-9) +// @return true if char is a digit +static inline bool is_digit_(char ch) { + return (ch >= '0') && (ch <= '9'); +} + +// internal ASCII string to unsigned int conversion +static unsigned int atoi_(const char** str) { + unsigned int i = 0U; + while (is_digit_(**str)) { + i = i * 10U + (unsigned int)(*((*str)++) - '0'); + } + return i; +} + +// output the specified string in reverse, taking care of any zero-padding +static size_t out_rev_(out_fct_type out, + char* buffer, + size_t idx, + size_t maxlen, + const char* buf, + size_t len, + unsigned int width, + unsigned int flags) { + const size_t start_idx = idx; + + // pad spaces up to given width + if (!(flags & FLAGS_LEFT) && !(flags & FLAGS_ZEROPAD)) { + for (size_t i = len; i < width; i++) { + out(' ', buffer, idx++, maxlen); + } + } + + // reverse string + while (len) { + out(buf[--len], buffer, idx++, maxlen); + } + + // append pad spaces up to given width + if (flags & FLAGS_LEFT) { + while (idx - start_idx < width) { + out(' ', buffer, idx++, maxlen); + } + } + + return idx; +} + +// Invoked by print_integer after the actual number has been printed, performing +// necessary work on the number's prefix (as the number is initially printed in +// reverse order) +static size_t print_integer_finalization(out_fct_type out, + char* buffer, + size_t idx, + size_t maxlen, + char* buf, + size_t len, + bool negative, + numeric_base_t base, + unsigned int precision, + unsigned int width, + unsigned int flags) { + size_t unpadded_len = len; + + // pad with leading zeros + { + if (!(flags & FLAGS_LEFT)) { + if (width && (flags & FLAGS_ZEROPAD) && + (negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) { + width--; + } + while ((flags & FLAGS_ZEROPAD) && (len < width) && + (len < PRINTF_INTEGER_BUFFER_SIZE)) { + buf[len++] = '0'; + } + } + + while ((len < precision) && (len < PRINTF_INTEGER_BUFFER_SIZE)) { + buf[len++] = '0'; + } + + if (base == BASE_OCTAL && (len > unpadded_len)) { + // Since we've written some zeros, we've satisfied the alternative + // format leading space requirement + flags &= ~FLAGS_HASH; + } + } + + // handle hash + if (flags & (FLAGS_HASH | FLAGS_POINTER)) { + if (!(flags & FLAGS_PRECISION) && len && + ((len == precision) || (len == width))) { + // Let's take back some padding digits to fit in what will + // eventually be the format-specific prefix + if (unpadded_len < len) { + len--; + } + if (len && (base == BASE_HEX)) { + if (unpadded_len < len) { + len--; + } + } + } + if ((base == BASE_HEX) && !(flags & FLAGS_UPPERCASE) && + (len < PRINTF_INTEGER_BUFFER_SIZE)) { + buf[len++] = 'x'; + } else if ((base == BASE_HEX) && (flags & FLAGS_UPPERCASE) && + (len < PRINTF_INTEGER_BUFFER_SIZE)) { + buf[len++] = 'X'; + } else if ((base == BASE_BINARY) && + (len < PRINTF_INTEGER_BUFFER_SIZE)) { + buf[len++] = 'b'; + } + if (len < PRINTF_INTEGER_BUFFER_SIZE) { + buf[len++] = '0'; + } + } + + if (len < PRINTF_INTEGER_BUFFER_SIZE) { + if (negative) { + buf[len++] = '-'; + } else if (flags & FLAGS_PLUS) { + buf[len++] = '+'; // ignore the space if the '+' exists + } else if (flags & FLAGS_SPACE) { + buf[len++] = ' '; + } + } + + return out_rev_(out, buffer, idx, maxlen, buf, len, width, flags); +} + +// An internal itoa-like function +static size_t print_integer(out_fct_type out, + char* buffer, + size_t idx, + size_t maxlen, + printf_unsigned_value_t value, + bool negative, + numeric_base_t base, + unsigned int precision, + unsigned int width, + unsigned int flags) { + char buf[PRINTF_INTEGER_BUFFER_SIZE]; + size_t len = 0U; + + if (!value) { + if (!(flags & FLAGS_PRECISION)) { + buf[len++] = '0'; + flags &= ~FLAGS_HASH; + // We drop this flag this since either the alternative and regular + // modes of the specifier don't differ on 0 values, or (in the case + // of octal) we've already provided the special handling for this + // mode. + } else if (base == BASE_HEX) { + flags &= ~FLAGS_HASH; + // We drop this flag this since either the alternative and regular + // modes of the specifier don't differ on 0 values + } + } else { + do { + const char digit = (char)(value % base); + buf[len++] = + (char)(digit < 10 ? '0' + digit + : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + + digit - 10); + value /= base; + } while (value && (len < PRINTF_INTEGER_BUFFER_SIZE)); + } + + return print_integer_finalization(out, buffer, idx, maxlen, buf, len, + negative, base, precision, width, flags); +} + +#if (PRINTF_SUPPORT_DECIMAL_SPECIFIERS || PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS) + +struct double_components { + int_fast64_t integral; + int_fast64_t fractional; + bool is_negative; +}; + +#define NUM_DECIMAL_DIGITS_IN_INT64_T 18 +#define PRINTF_MAX_PRECOMPUTED_POWER_OF_10 NUM_DECIMAL_DIGITS_IN_INT64_T +static const double powers_of_10[NUM_DECIMAL_DIGITS_IN_INT64_T] = { + 1e00, 1e01, 1e02, 1e03, 1e04, 1e05, 1e06, 1e07, 1e08, + 1e09, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17}; + +#define PRINTF_MAX_SUPPORTED_PRECISION NUM_DECIMAL_DIGITS_IN_INT64_T - 1 + +// Break up a double number - which is known to be a finite non-negative number +// - into its base-10 parts: integral - before the decimal point, and fractional +// - after it. Taken the precision into account, but does not change it even +// internally. +static struct double_components get_components(double number, + unsigned int precision) { + struct double_components number_; + number_.is_negative = get_sign(number); + double abs_number = (number_.is_negative) ? -number : number; + number_.integral = (int_fast64_t)abs_number; + double remainder = + (abs_number - number_.integral) * powers_of_10[precision]; + number_.fractional = (int_fast64_t)remainder; + + remainder -= (double)number_.fractional; + + if (remainder > 0.5) { + ++number_.fractional; + // handle rollover, e.g. case 0.99 with precision 1 is 1.0 + if ((double)number_.fractional >= powers_of_10[precision]) { + number_.fractional = 0; + ++number_.integral; + } + } else if (remainder == 0.5) { + if ((number_.fractional == 0U) || (number_.fractional & 1U)) { + // if halfway, round up if odd OR if last digit is 0 + ++number_.fractional; + } + } + + if (precision == 0U) { + remainder = abs_number - (double)number_.integral; + if ((!(remainder < 0.5) || (remainder > 0.5)) && + (number_.integral & 1)) { + // exactly 0.5 and ODD, then round up + // 1.5 -> 2, but 2.5 -> 2 + ++number_.integral; + } + } + return number_; +} + +struct scaling_factor { + double raw_factor; + bool multiply; // if true, need to multiply by raw_factor; otherwise need + // to divide by it +}; + +double apply_scaling(double num, struct scaling_factor normalization) { + return normalization.multiply ? num * normalization.raw_factor + : num / normalization.raw_factor; +} + +double unapply_scaling(double normalized, struct scaling_factor normalization) { + return normalization.multiply ? normalized / normalization.raw_factor + : normalized * normalization.raw_factor; +} + +struct scaling_factor update_normalization(struct scaling_factor sf, + double extra_multiplicative_factor) { + struct scaling_factor result; + if (sf.multiply) { + result.multiply = true; + result.raw_factor = sf.raw_factor * extra_multiplicative_factor; + } else { + int factor_exp2 = get_exp2(get_bit_access(sf.raw_factor)); + int extra_factor_exp2 = + get_exp2(get_bit_access(extra_multiplicative_factor)); + + // Divide the larger-exponent raw raw_factor by the smaller + if (PRINTF_ABS(factor_exp2) > PRINTF_ABS(extra_factor_exp2)) { + result.multiply = false; + result.raw_factor = sf.raw_factor / extra_multiplicative_factor; + } else { + result.multiply = true; + result.raw_factor = extra_multiplicative_factor / sf.raw_factor; + } + } + return result; +} + +#if PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS +static struct double_components get_normalized_components( + bool negative, + unsigned int precision, + double non_normalized, + struct scaling_factor normalization) { + struct double_components components; + components.is_negative = negative; + components.integral = + (int_fast64_t)apply_scaling(non_normalized, normalization); + double remainder = + non_normalized - + unapply_scaling((double)components.integral, normalization); + double prec_power_of_10 = powers_of_10[precision]; + struct scaling_factor account_for_precision = + update_normalization(normalization, prec_power_of_10); + double scaled_remainder = apply_scaling(remainder, account_for_precision); + double rounding_threshold = 0.5; + + if (precision == 0U) { + components.fractional = 0; + components.integral += (scaled_remainder >= rounding_threshold); + if (scaled_remainder == rounding_threshold) { + // banker's rounding: Round towards the even number (making the mean + // error 0) + components.integral &= ~((int_fast64_t)0x1); + } + } else { + components.fractional = (int_fast64_t)scaled_remainder; + scaled_remainder -= components.fractional; + + components.fractional += (scaled_remainder >= rounding_threshold); + if (scaled_remainder == rounding_threshold) { + // banker's rounding: Round towards the even number (making the mean + // error 0) + components.fractional &= ~((int_fast64_t)0x1); + } + // handle rollover, e.g. the case of 0.99 with precision 1 becoming + // (0,100), and must then be corrected into (1, 0). + if ((double)components.fractional >= prec_power_of_10) { + components.fractional = 0; + ++components.integral; + } + } + return components; +} +#endif + +static size_t print_broken_up_decimal(struct double_components number_, + out_fct_type out, + char* buffer, + size_t idx, + size_t maxlen, + unsigned int precision, + unsigned int width, + unsigned int flags, + char* buf, + size_t len) { + if (precision != 0U) { + // do fractional part, as an unsigned number + + unsigned int count = precision; + + if (flags & FLAGS_ADAPT_EXP && !(flags & FLAGS_HASH)) { + // %g/%G mandates we skip the trailing 0 digits... + if (number_.fractional > 0) { + while (true) { + int_fast64_t digit = number_.fractional % 10U; + if (digit != 0) { + break; + } + --count; + number_.fractional /= 10U; + } + } + // ... and even the decimal point if there are no + // non-zero fractional part digits (see below) + } + + if (number_.fractional > 0 || !(flags & FLAGS_ADAPT_EXP) || + (flags & FLAGS_HASH)) { + while (len < PRINTF_FTOA_BUFFER_SIZE) { + --count; + buf[len++] = (char)('0' + number_.fractional % 10U); + if (!(number_.fractional /= 10U)) { + break; + } + } + // add extra 0s + while ((len < PRINTF_FTOA_BUFFER_SIZE) && (count-- > 0U)) { + buf[len++] = '0'; + } + if (len < PRINTF_FTOA_BUFFER_SIZE) { + buf[len++] = '.'; + } + } + } else { + if (flags & FLAGS_HASH) { + if (len < PRINTF_FTOA_BUFFER_SIZE) { + buf[len++] = '.'; + } + } + } + + // Write the integer part of the number (it comes after the fractional + // since the character order is reversed) + while (len < PRINTF_FTOA_BUFFER_SIZE) { + buf[len++] = (char)('0' + (number_.integral % 10)); + if (!(number_.integral /= 10)) { + break; + } + } + + // pad leading zeros + if (!(flags & FLAGS_LEFT) && (flags & FLAGS_ZEROPAD)) { + if (width && + (number_.is_negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) { + width--; + } + while ((len < width) && (len < PRINTF_FTOA_BUFFER_SIZE)) { + buf[len++] = '0'; + } + } + + if (len < PRINTF_FTOA_BUFFER_SIZE) { + if (number_.is_negative) { + buf[len++] = '-'; + } else if (flags & FLAGS_PLUS) { + buf[len++] = '+'; // ignore the space if the '+' exists + } else if (flags & FLAGS_SPACE) { + buf[len++] = ' '; + } + } + + return out_rev_(out, buffer, idx, maxlen, buf, len, width, flags); +} + +// internal ftoa for fixed decimal floating point +static size_t print_decimal_number(out_fct_type out, + char* buffer, + size_t idx, + size_t maxlen, + double number, + unsigned int precision, + unsigned int width, + unsigned int flags, + char* buf, + size_t len) { + struct double_components value_ = get_components(number, precision); + return print_broken_up_decimal(value_, out, buffer, idx, maxlen, precision, + width, flags, buf, len); +} + +#if PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS +// internal ftoa variant for exponential floating-point type, contributed by +// Martijn Jasperse +static size_t print_exponential_number(out_fct_type out, + char* buffer, + size_t idx, + size_t maxlen, + double number, + unsigned int precision, + unsigned int width, + unsigned int flags, + char* buf, + size_t len) { + const bool negative = get_sign(number); + // This number will decrease gradually (by factors of 10) as we "extract" + // the exponent out of it + double abs_number = negative ? -number : number; + + int exp10; + bool abs_exp10_covered_by_powers_table; + struct scaling_factor normalization; + + // Determine the decimal exponent + if (abs_number == 0.0) { + // TODO: This is a special-case for 0.0 (and -0.0); but proper handling + // is required for denormals more generally. + exp10 = 0; // ... and no need to set a normalization factor or check + // the powers table + } else { + double_with_bit_access conv = get_bit_access(abs_number); + { + // based on the algorithm by David Gay + // (https://www.ampl.com/netlib/fp/dtoa.c) + int exp2 = get_exp2(conv); + // drop the exponent, so conv.F comes into the range [1,2) + conv.U = + (conv.U & + (((double_uint_t)(1) << DOUBLE_STORED_MANTISSA_BITS) - 1U)) | + ((double_uint_t)DOUBLE_BASE_EXPONENT + << DOUBLE_STORED_MANTISSA_BITS); + // now approximate log10 from the log2 integer part and an expansion + // of ln around 1.5 + exp10 = (int)(0.1760912590558 + exp2 * 0.301029995663981 + + (conv.F - 1.5) * 0.289529654602168); + // now we want to compute 10^exp10 but we want to be sure it won't + // overflow + exp2 = (int)(exp10 * 3.321928094887362 + 0.5); + const double z = + exp10 * 2.302585092994046 - exp2 * 0.6931471805599453; + const double z2 = z * z; + conv.U = ((double_uint_t)(exp2) + DOUBLE_BASE_EXPONENT) + << DOUBLE_STORED_MANTISSA_BITS; + // compute exp(z) using continued fractions, see + // https://en.wikipedia.org/wiki/Exponential_function#Continued_fractions_for_ex + conv.F *= 1 + 2 * z / (2 - z + (z2 / (6 + (z2 / (10 + z2 / 14))))); + // correct for rounding errors + if (abs_number < conv.F) { + exp10--; + conv.F /= 10; + } + } + abs_exp10_covered_by_powers_table = + PRINTF_ABS(exp10) < PRINTF_MAX_PRECOMPUTED_POWER_OF_10; + normalization.raw_factor = abs_exp10_covered_by_powers_table + ? powers_of_10[PRINTF_ABS(exp10)] + : conv.F; + } + + // We now begin accounting for the widths of the two parts of our printed + // field: the decimal part after decimal exponent extraction, and the + // base-10 exponent part. For both of these, the value of 0 has a special + // meaning, but not the same one: a 0 exponent-part width means "don't print + // the exponent"; a 0 decimal-part width means "use as many characters as + // necessary". + + bool fall_back_to_decimal_only_mode = false; + if (flags & FLAGS_ADAPT_EXP) { + int required_significant_digits = (precision == 0) ? 1 : (int)precision; + // Should we want to fall-back to "%f" mode, and only print the decimal + // part? + fall_back_to_decimal_only_mode = + (exp10 >= -4 && exp10 < required_significant_digits); + // Now, let's adjust the precision + // This also decided how we adjust the precision value - as in "%g" + // mode, "precision" is the number of _significant digits_, and this is + // when we "translate" the precision value to an actual number of + // decimal digits. + int precision_ = + (fall_back_to_decimal_only_mode) + ? (int)precision - 1 - exp10 + : (int)precision - + 1; // the presence of the exponent ensures only one + // significant digit comes before the decimal point + precision = (precision_ > 0 ? (unsigned)precision_ : 0U); + flags |= FLAGS_PRECISION; // make sure print_broken_up_decimal respects + // our choice above + } + + normalization.multiply = (exp10 < 0 && abs_exp10_covered_by_powers_table); + bool should_skip_normalization = + (fall_back_to_decimal_only_mode || exp10 == 0); + struct double_components decimal_part_components = + should_skip_normalization + ? get_components(negative ? -abs_number : abs_number, precision) + : get_normalized_components(negative, precision, abs_number, + normalization); + + // Account for roll-over, e.g. rounding from 9.99 to 100.0 - which effects + // the exponent and may require additional tweaking of the parts + if (fall_back_to_decimal_only_mode) { + if ((flags & FLAGS_ADAPT_EXP) && exp10 >= -1 && + decimal_part_components.integral == powers_of_10[exp10 + 1]) { + exp10++; // Not strictly necessary, since exp10 is no longer really + // used + precision--; + // ... and it should already be the case that + // decimal_part_components.fractional == 0 + } + // TODO: What about rollover strictly within the fractional part? + } else { + if (decimal_part_components.integral >= 10) { + exp10++; + decimal_part_components.integral = 1; + decimal_part_components.fractional = 0; + } + } + + // the exp10 format is "E%+03d" and largest possible exp10 value for a + // 64-bit double is "307" (for 2^1023), so we set aside 4-5 characters + // overall + unsigned int exp10_part_width = fall_back_to_decimal_only_mode ? 0U + : (PRINTF_ABS(exp10) < 100) ? 4U + : 5U; + + unsigned int decimal_part_width = + ((flags & FLAGS_LEFT) && exp10_part_width) + ? + // We're padding on the right, so the width constraint is the + // exponent part's problem, not the decimal part's, so we'll use as + // many characters as we need: + 0U + : + // We're padding on the left; so the width constraint is the decimal + // part's problem. Well, can both the decimal part and the exponent + // part fit within our overall width? + ((width > exp10_part_width) + ? + // Yes, so we limit our decimal part's width. + // (Note this is trivially valid even if we've fallen back to + // "%f" mode) + width - exp10_part_width + : + // No; we just give up on any restriction on the decimal part + // and use as many characters as we need + 0U); + + const size_t start_idx = idx; + idx = print_broken_up_decimal(decimal_part_components, out, buffer, idx, + maxlen, precision, decimal_part_width, flags, + buf, len); + + if (!fall_back_to_decimal_only_mode) { + out((flags & FLAGS_UPPERCASE) ? 'E' : 'e', buffer, idx++, maxlen); + idx = print_integer(out, buffer, idx, maxlen, ABS_FOR_PRINTING(exp10), + exp10 < 0, 10, 0, exp10_part_width - 1, + FLAGS_ZEROPAD | FLAGS_PLUS); + if (flags & FLAGS_LEFT) { + // We need to right-pad with spaces to meet the width requirement + while (idx - start_idx < width) + out(' ', buffer, idx++, maxlen); + } + } + return idx; +} +#endif // PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS + +static size_t print_floating_point(out_fct_type out, + char* buffer, + size_t idx, + size_t maxlen, + double value, + unsigned int precision, + unsigned int width, + unsigned int flags, + bool prefer_exponential) { + char buf[PRINTF_FTOA_BUFFER_SIZE]; + size_t len = 0U; + + // test for special values + if (value != value) + return out_rev_(out, buffer, idx, maxlen, "nan", 3, width, flags); + if (value < -DBL_MAX) + return out_rev_(out, buffer, idx, maxlen, "fni-", 4, width, flags); + if (value > DBL_MAX) + return out_rev_(out, buffer, idx, maxlen, + (flags & FLAGS_PLUS) ? "fni+" : "fni", + (flags & FLAGS_PLUS) ? 4U : 3U, width, flags); + + if (!prefer_exponential && ((value > PRINTF_FLOAT_NOTATION_THRESHOLD) || + (value < -PRINTF_FLOAT_NOTATION_THRESHOLD))) { + // The required behavior of standard printf is to print _every_ + // integral-part digit -- which could mean printing hundreds of + // characters, overflowing any fixed internal buffer and necessitating a + // more complicated implementation. +#if PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS + return print_exponential_number(out, buffer, idx, maxlen, value, + precision, width, flags, buf, len); +#else + return 0U; +#endif + } + + // set default precision, if not set explicitly + if (!(flags & FLAGS_PRECISION)) { + precision = PRINTF_DEFAULT_FLOAT_PRECISION; + } + + // limit precision so that our integer holding the fractional part does not + // overflow + while ((len < PRINTF_FTOA_BUFFER_SIZE) && + (precision > PRINTF_MAX_SUPPORTED_PRECISION)) { + buf[len++] = + '0'; // This respects the precision in terms of result length only + precision--; + } + + return +#if PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS + prefer_exponential + ? print_exponential_number(out, buffer, idx, maxlen, value, + precision, width, flags, buf, len) + : +#endif + print_decimal_number(out, buffer, idx, maxlen, value, precision, + width, flags, buf, len); +} + +#endif // (PRINTF_SUPPORT_DECIMAL_SPECIFIERS || + // PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS) + +// internal vsnprintf +static int __vsnprintf(out_fct_type out, + char* buffer, + const size_t maxlen, + const char* format, + va_list va) { + unsigned int flags, width, precision, n; + size_t idx = 0U; + + if (!buffer) { + // use null output function + out = out_discard; + } + + while (*format) { + // format specifier? %[flags][width][.precision][length] + if (*format != '%') { + // no + out(*format, buffer, idx++, maxlen); + format++; + continue; + } else { + // yes, evaluate it + format++; + } + + // evaluate flags + flags = 0U; + do { + switch (*format) { + case '0': + flags |= FLAGS_ZEROPAD; + format++; + n = 1U; + break; + case '-': + flags |= FLAGS_LEFT; + format++; + n = 1U; + break; + case '+': + flags |= FLAGS_PLUS; + format++; + n = 1U; + break; + case ' ': + flags |= FLAGS_SPACE; + format++; + n = 1U; + break; + case '#': + flags |= FLAGS_HASH; + format++; + n = 1U; + break; + default: + n = 0U; + break; + } + } while (n); + + // evaluate width field + width = 0U; + if (is_digit_(*format)) { + width = atoi_(&format); + } else if (*format == '*') { + const int w = va_arg(va, int); + if (w < 0) { + flags |= FLAGS_LEFT; // reverse padding + width = (unsigned int)-w; + } else { + width = (unsigned int)w; + } + format++; + } + + // evaluate precision field + precision = 0U; + if (*format == '.') { + flags |= FLAGS_PRECISION; + format++; + if (is_digit_(*format)) { + precision = atoi_(&format); + } else if (*format == '*') { + const int precision_ = (int)va_arg(va, int); + precision = precision_ > 0 ? (unsigned int)precision_ : 0U; + format++; + } + } + + // evaluate length field + switch (*format) { + case 'l': + flags |= FLAGS_LONG; + format++; + if (*format == 'l') { + flags |= FLAGS_LONG_LONG; + format++; + } + break; + case 'h': + flags |= FLAGS_SHORT; + format++; + if (*format == 'h') { + flags |= FLAGS_CHAR; + format++; + } + break; + case 't': + flags |= (sizeof(ptrdiff_t) == sizeof(long) ? FLAGS_LONG + : FLAGS_LONG_LONG); + format++; + break; + case 'j': + flags |= (sizeof(intmax_t) == sizeof(long) ? FLAGS_LONG + : FLAGS_LONG_LONG); + format++; + break; + case 'z': + flags |= (sizeof(size_t) == sizeof(long) ? FLAGS_LONG + : FLAGS_LONG_LONG); + format++; + break; + default: + break; + } + + // evaluate specifier + switch (*format) { + case 'd': + case 'i': + case 'u': + case 'x': + case 'X': + case 'o': + case 'b': { + // set the base + numeric_base_t base; + if (*format == 'x' || *format == 'X') { + base = BASE_HEX; + } else if (*format == 'o') { + base = BASE_OCTAL; + } else if (*format == 'b') { + base = BASE_BINARY; + } else { + base = BASE_DECIMAL; + flags &= ~FLAGS_HASH; // no hash for dec format + } + // uppercase + if (*format == 'X') { + flags |= FLAGS_UPPERCASE; + } + + // no plus or space flag for u, x, X, o, b + if ((*format != 'i') && (*format != 'd')) { + flags &= ~(FLAGS_PLUS | FLAGS_SPACE); + } + + // ignore '0' flag when precision is given + if (flags & FLAGS_PRECISION) { + flags &= ~FLAGS_ZEROPAD; + } + + // convert the integer + if ((*format == 'i') || (*format == 'd')) { + // signed + if (flags & FLAGS_LONG_LONG) { +#if PRINTF_SUPPORT_LONG_LONG + const long long value = va_arg(va, long long); + idx = print_integer(out, buffer, idx, maxlen, + ABS_FOR_PRINTING(value), value < 0, + base, precision, width, flags); +#endif + } else if (flags & FLAGS_LONG) { + const long value = va_arg(va, long); + idx = print_integer(out, buffer, idx, maxlen, + ABS_FOR_PRINTING(value), value < 0, + base, precision, width, flags); + } else { + const int value = + (flags & FLAGS_CHAR) ? (signed char)va_arg(va, int) + : (flags & FLAGS_SHORT) ? (short int)va_arg(va, int) + : va_arg(va, int); + idx = print_integer(out, buffer, idx, maxlen, + ABS_FOR_PRINTING(value), value < 0, + base, precision, width, flags); + } + } else { + // unsigned + if (flags & FLAGS_LONG_LONG) { +#if PRINTF_SUPPORT_LONG_LONG + idx = + print_integer(out, buffer, idx, maxlen, + (printf_unsigned_value_t)va_arg( + va, unsigned long long), + false, base, precision, width, flags); +#endif + } else if (flags & FLAGS_LONG) { + idx = print_integer( + out, buffer, idx, maxlen, + (printf_unsigned_value_t)va_arg(va, unsigned long), + false, base, precision, width, flags); + } else { + const unsigned int value = + (flags & FLAGS_CHAR) + ? (unsigned char)va_arg(va, unsigned int) + : (flags & FLAGS_SHORT) + ? (unsigned short int)va_arg(va, unsigned int) + : va_arg(va, unsigned int); + idx = + print_integer(out, buffer, idx, maxlen, + (printf_unsigned_value_t)value, false, + base, precision, width, flags); + } + } + format++; + break; + } +#if PRINTF_SUPPORT_DECIMAL_SPECIFIERS + case 'f': + case 'F': + if (*format == 'F') + flags |= FLAGS_UPPERCASE; + idx = print_floating_point(out, buffer, idx, maxlen, + va_arg(va, double), precision, width, + flags, PRINTF_PREFER_DECIMAL); + format++; + break; +#endif +#if PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS + case 'e': + case 'E': + case 'g': + case 'G': + if ((*format == 'g') || (*format == 'G')) + flags |= FLAGS_ADAPT_EXP; + if ((*format == 'E') || (*format == 'G')) + flags |= FLAGS_UPPERCASE; + idx = print_floating_point(out, buffer, idx, maxlen, + va_arg(va, double), precision, width, + flags, PRINTF_PREFER_EXPONENTIAL); + format++; + break; +#endif // PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS + case 'c': { + unsigned int l = 1U; + // pre padding + if (!(flags & FLAGS_LEFT)) { + while (l++ < width) { + out(' ', buffer, idx++, maxlen); + } + } + // char output + out((char)va_arg(va, int), buffer, idx++, maxlen); + // post padding + if (flags & FLAGS_LEFT) { + while (l++ < width) { + out(' ', buffer, idx++, maxlen); + } + } + format++; + break; + } + + case 's': { + const char* p = va_arg(va, char*); + if (p == NULL) { + idx = out_rev_(out, buffer, idx, maxlen, ")llun(", 6, width, + flags); + } else { + unsigned int l = + strnlen_s_(p, precision ? precision : (size_t)-1); + // pre padding + if (flags & FLAGS_PRECISION) { + l = (l < precision ? l : precision); + } + if (!(flags & FLAGS_LEFT)) { + while (l++ < width) { + out(' ', buffer, idx++, maxlen); + } + } + // string output + while ((*p != 0) && + (!(flags & FLAGS_PRECISION) || precision--)) { + out(*(p++), buffer, idx++, maxlen); + } + // post padding + if (flags & FLAGS_LEFT) { + while (l++ < width) { + out(' ', buffer, idx++, maxlen); + } + } + } + format++; + break; + } + + case 'p': { + width = sizeof(void*) * 2U + + 2; // 2 hex chars per byte + the "0x" prefix + flags |= FLAGS_ZEROPAD | FLAGS_POINTER; + uintptr_t value = (uintptr_t)va_arg(va, void*); + idx = (value == (uintptr_t)NULL) + ? out_rev_(out, buffer, idx, maxlen, ")lin(", 5, + width, flags) + : print_integer(out, buffer, idx, maxlen, + (printf_unsigned_value_t)value, false, + BASE_HEX, precision, width, flags); + format++; + break; + } + + case '%': + out('%', buffer, idx++, maxlen); + format++; + break; + + default: + out(*format, buffer, idx++, maxlen); + format++; + break; + } + } + + // termination + out((char)0, buffer, idx < maxlen ? idx : maxlen - 1U, maxlen); + + // return written chars without terminating \0 + return (int)idx; +} + +/** + * This function will fill a formatted string to buffer. + * + * @param buf is the buffer to save formatted string. + * + * @param size is the size of buffer. + * + * @param fmt is the format parameters. + * + * @param args is a list of variable parameters. + * + * @return The number of characters actually written to buffer. + */ +int pika_vsnprintf(char* buf, rt_size_t size, const char* fmt, va_list args) { + return __vsnprintf(out_buffer, buf, size, fmt, args); +} + +int __platform_vsnprintf(char* buff, + size_t size, + const char* fmt, + va_list args) { + return pika_vsnprintf(buff, size, fmt, args); +} diff --git a/port/linux/package/pikascript/pikascript-lib/pika_libc/pika_vsnprintf.c b/port/linux/package/pikascript/pikascript-lib/pika_libc/pika_vsnprintf.c new file mode 100644 index 000000000..0e02438a4 --- /dev/null +++ b/port/linux/package/pikascript/pikascript-lib/pika_libc/pika_vsnprintf.c @@ -0,0 +1,1268 @@ +/* + * Copyright (c) 2021, Meco Jianting Man + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-11-27 Meco Man porting for rt_vsnprintf as the fully functional + * version + */ + +/** + * @author (c) Eyal Rozenberg + * 2021, Haifa, Palestine/Israel + * @author (c) Marco Paland (info@paland.com) + * 2014-2019, PALANDesign Hannover, Germany + * + * @note Others have made smaller contributions to this file: see the + * contributors page at https://github.com/eyalroz/printf/graphs/contributors + * or ask one of the authors. + * + * @brief Small stand-alone implementation of the printf family of functions + * (`(v)printf`, `(v)s(n)printf` etc., geared towards use on embedded systems + * with a very limited resources. + * + * @note the implementations are thread-safe; re-entrant; use no functions from + * the standard library; and do not dynamically allocate any memory. + * + * @license The MIT License (MIT) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include +#include +#include +#include "pika_adapter_rtt.h" + +// 'ntoa' conversion buffer size, this must be big enough to hold one converted +// numeric number including padded zeros (dynamically created on stack) +#ifndef PRINTF_INTEGER_BUFFER_SIZE +#define PRINTF_INTEGER_BUFFER_SIZE 32 +#endif + +// 'ftoa' conversion buffer size, this must be big enough to hold one converted +// float number including padded zeros (dynamically created on stack) +#ifndef PRINTF_FTOA_BUFFER_SIZE +#define PRINTF_FTOA_BUFFER_SIZE 32 +#endif + +// Support for the decimal notation floating point conversion specifiers (%f, +// %F) +#ifndef PRINTF_SUPPORT_DECIMAL_SPECIFIERS +#define PRINTF_SUPPORT_DECIMAL_SPECIFIERS 1 +#endif + +// Support for the exponential notatin floating point conversion specifiers (%e, +// %g, %E, %G) +#ifndef PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS +#define PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS 1 +#endif + +// Default precision for the floating point conversion specifiers (the C +// standard sets this at 6) +#ifndef PRINTF_DEFAULT_FLOAT_PRECISION +#define PRINTF_DEFAULT_FLOAT_PRECISION 6 +#endif + +// According to the C languages standard, printf() and related functions must be +// able to print any integral number in floating-point notation, regardless of +// length, when using the %f specifier - possibly hundreds of characters, +// potentially overflowing your buffers. In this implementation, all values +// beyond this threshold are switched to exponential notation. +#ifndef PRINTF_MAX_INTEGRAL_DIGITS_FOR_DECIMAL +#define PRINTF_MAX_INTEGRAL_DIGITS_FOR_DECIMAL 9 +#endif + +// Support for the long long integral types (with the ll, z and t length +// modifiers for specifiers %d,%i,%o,%x,%X,%u, and with the %p specifier). Note: +// 'L' (long double) is not supported. +#ifndef PRINTF_SUPPORT_LONG_LONG +#define PRINTF_SUPPORT_LONG_LONG 1 +#endif + +#if PRINTF_SUPPORT_LONG_LONG +typedef unsigned long long printf_unsigned_value_t; +typedef long long printf_signed_value_t; +#else +typedef unsigned long printf_unsigned_value_t; +typedef long printf_signed_value_t; +#endif + +#define PRINTF_PREFER_DECIMAL false +#define PRINTF_PREFER_EXPONENTIAL true + +/////////////////////////////////////////////////////////////////////////////// + +// The following will convert the number-of-digits into an exponential-notation +// literal +#define PRINTF_CONCATENATE(s1, s2) s1##s2 +#define PRINTF_EXPAND_THEN_CONCATENATE(s1, s2) PRINTF_CONCATENATE(s1, s2) +#define PRINTF_FLOAT_NOTATION_THRESHOLD \ + PRINTF_EXPAND_THEN_CONCATENATE(1e, PRINTF_MAX_INTEGRAL_DIGITS_FOR_DECIMAL) + +// internal flag definitions +#define FLAGS_ZEROPAD (1U << 0U) +#define FLAGS_LEFT (1U << 1U) +#define FLAGS_PLUS (1U << 2U) +#define FLAGS_SPACE (1U << 3U) +#define FLAGS_HASH (1U << 4U) +#define FLAGS_UPPERCASE (1U << 5U) +#define FLAGS_CHAR (1U << 6U) +#define FLAGS_SHORT (1U << 7U) +#define FLAGS_LONG (1U << 8U) +#define FLAGS_LONG_LONG (1U << 9U) +#define FLAGS_PRECISION (1U << 10U) +#define FLAGS_ADAPT_EXP (1U << 11U) +#define FLAGS_POINTER (1U << 12U) +// Note: Similar, but not identical, effect as FLAGS_HASH + +#define BASE_BINARY 2 +#define BASE_OCTAL 8 +#define BASE_DECIMAL 10 +#define BASE_HEX 16 + +typedef uint8_t numeric_base_t; + +#if (PRINTF_SUPPORT_DECIMAL_SPECIFIERS || PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS) +#include +#if FLT_RADIX != 2 +#error "Non-binary-radix floating-point types are unsupported." +#endif + +#if DBL_MANT_DIG == 24 + +#define DOUBLE_SIZE_IN_BITS 32 +typedef uint32_t double_uint_t; +#define DOUBLE_EXPONENT_MASK 0xFFU +#define DOUBLE_BASE_EXPONENT 127 + +#elif DBL_MANT_DIG == 53 + +#define DOUBLE_SIZE_IN_BITS 64 +typedef uint64_t double_uint_t; +#define DOUBLE_EXPONENT_MASK 0x7FFU +#define DOUBLE_BASE_EXPONENT 1023 + +#else +#error "Unsupported double type configuration" +#endif +#define DOUBLE_STORED_MANTISSA_BITS (DBL_MANT_DIG - 1) + +typedef union { + double_uint_t U; + double F; +} double_with_bit_access; + +// This is unnecessary in C99, since compound initializers can be used, +// but: 1. Some compilers are finicky about this; 2. Some people may want to +// convert this to C89; +// 3. If you try to use it as C++, only C++20 supports compound literals +static inline double_with_bit_access get_bit_access(double x) { + double_with_bit_access dwba; + dwba.F = x; + return dwba; +} + +static inline int get_sign(double x) { + // The sign is stored in the highest bit + return get_bit_access(x).U >> (DOUBLE_SIZE_IN_BITS - 1); +} + +static inline int get_exp2(double_with_bit_access x) { + // The exponent in an IEEE-754 floating-point number occupies a contiguous + // sequence of bits (e.g. 52..62 for 64-bit doubles), but with a non-trivial + // representation: An unsigned offset from some negative value (with the + // extremal offset values reserved for special use). + return (int)((x.U >> DOUBLE_STORED_MANTISSA_BITS) & DOUBLE_EXPONENT_MASK) - + DOUBLE_BASE_EXPONENT; +} +#define PRINTF_ABS(_x) ((_x) > 0 ? (_x) : -(_x)) + +#endif // (PRINTF_SUPPORT_DECIMAL_SPECIFIERS || + // PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS) + +// Note in particular the behavior here on LONG_MIN or LLONG_MIN; it is valid +// and well-defined, but if you're not careful you can easily trigger undefined +// behavior with -LONG_MIN or -LLONG_MIN +#define ABS_FOR_PRINTING(_x) \ + ((printf_unsigned_value_t)((_x) > 0 ? (_x) : -((printf_signed_value_t)_x))) + +// output function type +typedef void (*out_fct_type)(char character, + void* buffer, + size_t idx, + size_t maxlen); + +// wrapper (used as buffer) for output function type +typedef struct { + void (*fct)(char character, void* arg); + void* arg; +} out_function_wrapper_type; + +// internal buffer output +static inline void out_buffer(char character, + void* buffer, + size_t idx, + size_t maxlen) { + if (idx < maxlen) { + ((char*)buffer)[idx] = character; + } +} + +// internal null output +static inline void out_discard(char character, + void* buffer, + size_t idx, + size_t maxlen) { + (void)character; + (void)buffer; + (void)idx; + (void)maxlen; +} + +// internal secure strlen +// @return The length of the string (excluding the terminating 0) limited by +// 'maxsize' +static inline unsigned int strnlen_s_(const char* str, size_t maxsize) { + const char* s; + for (s = str; *s && maxsize--; ++s) + ; + return (unsigned int)(s - str); +} + +// internal test if char is a digit (0-9) +// @return true if char is a digit +static inline bool is_digit_(char ch) { + return (ch >= '0') && (ch <= '9'); +} + +// internal ASCII string to unsigned int conversion +static unsigned int atoi_(const char** str) { + unsigned int i = 0U; + while (is_digit_(**str)) { + i = i * 10U + (unsigned int)(*((*str)++) - '0'); + } + return i; +} + +// output the specified string in reverse, taking care of any zero-padding +static size_t out_rev_(out_fct_type out, + char* buffer, + size_t idx, + size_t maxlen, + const char* buf, + size_t len, + unsigned int width, + unsigned int flags) { + const size_t start_idx = idx; + + // pad spaces up to given width + if (!(flags & FLAGS_LEFT) && !(flags & FLAGS_ZEROPAD)) { + for (size_t i = len; i < width; i++) { + out(' ', buffer, idx++, maxlen); + } + } + + // reverse string + while (len) { + out(buf[--len], buffer, idx++, maxlen); + } + + // append pad spaces up to given width + if (flags & FLAGS_LEFT) { + while (idx - start_idx < width) { + out(' ', buffer, idx++, maxlen); + } + } + + return idx; +} + +// Invoked by print_integer after the actual number has been printed, performing +// necessary work on the number's prefix (as the number is initially printed in +// reverse order) +static size_t print_integer_finalization(out_fct_type out, + char* buffer, + size_t idx, + size_t maxlen, + char* buf, + size_t len, + bool negative, + numeric_base_t base, + unsigned int precision, + unsigned int width, + unsigned int flags) { + size_t unpadded_len = len; + + // pad with leading zeros + { + if (!(flags & FLAGS_LEFT)) { + if (width && (flags & FLAGS_ZEROPAD) && + (negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) { + width--; + } + while ((flags & FLAGS_ZEROPAD) && (len < width) && + (len < PRINTF_INTEGER_BUFFER_SIZE)) { + buf[len++] = '0'; + } + } + + while ((len < precision) && (len < PRINTF_INTEGER_BUFFER_SIZE)) { + buf[len++] = '0'; + } + + if (base == BASE_OCTAL && (len > unpadded_len)) { + // Since we've written some zeros, we've satisfied the alternative + // format leading space requirement + flags &= ~FLAGS_HASH; + } + } + + // handle hash + if (flags & (FLAGS_HASH | FLAGS_POINTER)) { + if (!(flags & FLAGS_PRECISION) && len && + ((len == precision) || (len == width))) { + // Let's take back some padding digits to fit in what will + // eventually be the format-specific prefix + if (unpadded_len < len) { + len--; + } + if (len && (base == BASE_HEX)) { + if (unpadded_len < len) { + len--; + } + } + } + if ((base == BASE_HEX) && !(flags & FLAGS_UPPERCASE) && + (len < PRINTF_INTEGER_BUFFER_SIZE)) { + buf[len++] = 'x'; + } else if ((base == BASE_HEX) && (flags & FLAGS_UPPERCASE) && + (len < PRINTF_INTEGER_BUFFER_SIZE)) { + buf[len++] = 'X'; + } else if ((base == BASE_BINARY) && + (len < PRINTF_INTEGER_BUFFER_SIZE)) { + buf[len++] = 'b'; + } + if (len < PRINTF_INTEGER_BUFFER_SIZE) { + buf[len++] = '0'; + } + } + + if (len < PRINTF_INTEGER_BUFFER_SIZE) { + if (negative) { + buf[len++] = '-'; + } else if (flags & FLAGS_PLUS) { + buf[len++] = '+'; // ignore the space if the '+' exists + } else if (flags & FLAGS_SPACE) { + buf[len++] = ' '; + } + } + + return out_rev_(out, buffer, idx, maxlen, buf, len, width, flags); +} + +// An internal itoa-like function +static size_t print_integer(out_fct_type out, + char* buffer, + size_t idx, + size_t maxlen, + printf_unsigned_value_t value, + bool negative, + numeric_base_t base, + unsigned int precision, + unsigned int width, + unsigned int flags) { + char buf[PRINTF_INTEGER_BUFFER_SIZE]; + size_t len = 0U; + + if (!value) { + if (!(flags & FLAGS_PRECISION)) { + buf[len++] = '0'; + flags &= ~FLAGS_HASH; + // We drop this flag this since either the alternative and regular + // modes of the specifier don't differ on 0 values, or (in the case + // of octal) we've already provided the special handling for this + // mode. + } else if (base == BASE_HEX) { + flags &= ~FLAGS_HASH; + // We drop this flag this since either the alternative and regular + // modes of the specifier don't differ on 0 values + } + } else { + do { + const char digit = (char)(value % base); + buf[len++] = + (char)(digit < 10 ? '0' + digit + : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + + digit - 10); + value /= base; + } while (value && (len < PRINTF_INTEGER_BUFFER_SIZE)); + } + + return print_integer_finalization(out, buffer, idx, maxlen, buf, len, + negative, base, precision, width, flags); +} + +#if (PRINTF_SUPPORT_DECIMAL_SPECIFIERS || PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS) + +struct double_components { + int_fast64_t integral; + int_fast64_t fractional; + bool is_negative; +}; + +#define NUM_DECIMAL_DIGITS_IN_INT64_T 18 +#define PRINTF_MAX_PRECOMPUTED_POWER_OF_10 NUM_DECIMAL_DIGITS_IN_INT64_T +static const double powers_of_10[NUM_DECIMAL_DIGITS_IN_INT64_T] = { + 1e00, 1e01, 1e02, 1e03, 1e04, 1e05, 1e06, 1e07, 1e08, + 1e09, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17}; + +#define PRINTF_MAX_SUPPORTED_PRECISION NUM_DECIMAL_DIGITS_IN_INT64_T - 1 + +// Break up a double number - which is known to be a finite non-negative number +// - into its base-10 parts: integral - before the decimal point, and fractional +// - after it. Taken the precision into account, but does not change it even +// internally. +static struct double_components get_components(double number, + unsigned int precision) { + struct double_components number_; + number_.is_negative = get_sign(number); + double abs_number = (number_.is_negative) ? -number : number; + number_.integral = (int_fast64_t)abs_number; + double remainder = + (abs_number - number_.integral) * powers_of_10[precision]; + number_.fractional = (int_fast64_t)remainder; + + remainder -= (double)number_.fractional; + + if (remainder > 0.5) { + ++number_.fractional; + // handle rollover, e.g. case 0.99 with precision 1 is 1.0 + if ((double)number_.fractional >= powers_of_10[precision]) { + number_.fractional = 0; + ++number_.integral; + } + } else if (remainder == 0.5) { + if ((number_.fractional == 0U) || (number_.fractional & 1U)) { + // if halfway, round up if odd OR if last digit is 0 + ++number_.fractional; + } + } + + if (precision == 0U) { + remainder = abs_number - (double)number_.integral; + if ((!(remainder < 0.5) || (remainder > 0.5)) && + (number_.integral & 1)) { + // exactly 0.5 and ODD, then round up + // 1.5 -> 2, but 2.5 -> 2 + ++number_.integral; + } + } + return number_; +} + +struct scaling_factor { + double raw_factor; + bool multiply; // if true, need to multiply by raw_factor; otherwise need + // to divide by it +}; + +double apply_scaling(double num, struct scaling_factor normalization) { + return normalization.multiply ? num * normalization.raw_factor + : num / normalization.raw_factor; +} + +double unapply_scaling(double normalized, struct scaling_factor normalization) { + return normalization.multiply ? normalized / normalization.raw_factor + : normalized * normalization.raw_factor; +} + +struct scaling_factor update_normalization(struct scaling_factor sf, + double extra_multiplicative_factor) { + struct scaling_factor result; + if (sf.multiply) { + result.multiply = true; + result.raw_factor = sf.raw_factor * extra_multiplicative_factor; + } else { + int factor_exp2 = get_exp2(get_bit_access(sf.raw_factor)); + int extra_factor_exp2 = + get_exp2(get_bit_access(extra_multiplicative_factor)); + + // Divide the larger-exponent raw raw_factor by the smaller + if (PRINTF_ABS(factor_exp2) > PRINTF_ABS(extra_factor_exp2)) { + result.multiply = false; + result.raw_factor = sf.raw_factor / extra_multiplicative_factor; + } else { + result.multiply = true; + result.raw_factor = extra_multiplicative_factor / sf.raw_factor; + } + } + return result; +} + +#if PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS +static struct double_components get_normalized_components( + bool negative, + unsigned int precision, + double non_normalized, + struct scaling_factor normalization) { + struct double_components components; + components.is_negative = negative; + components.integral = + (int_fast64_t)apply_scaling(non_normalized, normalization); + double remainder = + non_normalized - + unapply_scaling((double)components.integral, normalization); + double prec_power_of_10 = powers_of_10[precision]; + struct scaling_factor account_for_precision = + update_normalization(normalization, prec_power_of_10); + double scaled_remainder = apply_scaling(remainder, account_for_precision); + double rounding_threshold = 0.5; + + if (precision == 0U) { + components.fractional = 0; + components.integral += (scaled_remainder >= rounding_threshold); + if (scaled_remainder == rounding_threshold) { + // banker's rounding: Round towards the even number (making the mean + // error 0) + components.integral &= ~((int_fast64_t)0x1); + } + } else { + components.fractional = (int_fast64_t)scaled_remainder; + scaled_remainder -= components.fractional; + + components.fractional += (scaled_remainder >= rounding_threshold); + if (scaled_remainder == rounding_threshold) { + // banker's rounding: Round towards the even number (making the mean + // error 0) + components.fractional &= ~((int_fast64_t)0x1); + } + // handle rollover, e.g. the case of 0.99 with precision 1 becoming + // (0,100), and must then be corrected into (1, 0). + if ((double)components.fractional >= prec_power_of_10) { + components.fractional = 0; + ++components.integral; + } + } + return components; +} +#endif + +static size_t print_broken_up_decimal(struct double_components number_, + out_fct_type out, + char* buffer, + size_t idx, + size_t maxlen, + unsigned int precision, + unsigned int width, + unsigned int flags, + char* buf, + size_t len) { + if (precision != 0U) { + // do fractional part, as an unsigned number + + unsigned int count = precision; + + if (flags & FLAGS_ADAPT_EXP && !(flags & FLAGS_HASH)) { + // %g/%G mandates we skip the trailing 0 digits... + if (number_.fractional > 0) { + while (true) { + int_fast64_t digit = number_.fractional % 10U; + if (digit != 0) { + break; + } + --count; + number_.fractional /= 10U; + } + } + // ... and even the decimal point if there are no + // non-zero fractional part digits (see below) + } + + if (number_.fractional > 0 || !(flags & FLAGS_ADAPT_EXP) || + (flags & FLAGS_HASH)) { + while (len < PRINTF_FTOA_BUFFER_SIZE) { + --count; + buf[len++] = (char)('0' + number_.fractional % 10U); + if (!(number_.fractional /= 10U)) { + break; + } + } + // add extra 0s + while ((len < PRINTF_FTOA_BUFFER_SIZE) && (count-- > 0U)) { + buf[len++] = '0'; + } + if (len < PRINTF_FTOA_BUFFER_SIZE) { + buf[len++] = '.'; + } + } + } else { + if (flags & FLAGS_HASH) { + if (len < PRINTF_FTOA_BUFFER_SIZE) { + buf[len++] = '.'; + } + } + } + + // Write the integer part of the number (it comes after the fractional + // since the character order is reversed) + while (len < PRINTF_FTOA_BUFFER_SIZE) { + buf[len++] = (char)('0' + (number_.integral % 10)); + if (!(number_.integral /= 10)) { + break; + } + } + + // pad leading zeros + if (!(flags & FLAGS_LEFT) && (flags & FLAGS_ZEROPAD)) { + if (width && + (number_.is_negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) { + width--; + } + while ((len < width) && (len < PRINTF_FTOA_BUFFER_SIZE)) { + buf[len++] = '0'; + } + } + + if (len < PRINTF_FTOA_BUFFER_SIZE) { + if (number_.is_negative) { + buf[len++] = '-'; + } else if (flags & FLAGS_PLUS) { + buf[len++] = '+'; // ignore the space if the '+' exists + } else if (flags & FLAGS_SPACE) { + buf[len++] = ' '; + } + } + + return out_rev_(out, buffer, idx, maxlen, buf, len, width, flags); +} + +// internal ftoa for fixed decimal floating point +static size_t print_decimal_number(out_fct_type out, + char* buffer, + size_t idx, + size_t maxlen, + double number, + unsigned int precision, + unsigned int width, + unsigned int flags, + char* buf, + size_t len) { + struct double_components value_ = get_components(number, precision); + return print_broken_up_decimal(value_, out, buffer, idx, maxlen, precision, + width, flags, buf, len); +} + +#if PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS +// internal ftoa variant for exponential floating-point type, contributed by +// Martijn Jasperse +static size_t print_exponential_number(out_fct_type out, + char* buffer, + size_t idx, + size_t maxlen, + double number, + unsigned int precision, + unsigned int width, + unsigned int flags, + char* buf, + size_t len) { + const bool negative = get_sign(number); + // This number will decrease gradually (by factors of 10) as we "extract" + // the exponent out of it + double abs_number = negative ? -number : number; + + int exp10; + bool abs_exp10_covered_by_powers_table; + struct scaling_factor normalization; + + // Determine the decimal exponent + if (abs_number == 0.0) { + // TODO: This is a special-case for 0.0 (and -0.0); but proper handling + // is required for denormals more generally. + exp10 = 0; // ... and no need to set a normalization factor or check + // the powers table + } else { + double_with_bit_access conv = get_bit_access(abs_number); + { + // based on the algorithm by David Gay + // (https://www.ampl.com/netlib/fp/dtoa.c) + int exp2 = get_exp2(conv); + // drop the exponent, so conv.F comes into the range [1,2) + conv.U = + (conv.U & + (((double_uint_t)(1) << DOUBLE_STORED_MANTISSA_BITS) - 1U)) | + ((double_uint_t)DOUBLE_BASE_EXPONENT + << DOUBLE_STORED_MANTISSA_BITS); + // now approximate log10 from the log2 integer part and an expansion + // of ln around 1.5 + exp10 = (int)(0.1760912590558 + exp2 * 0.301029995663981 + + (conv.F - 1.5) * 0.289529654602168); + // now we want to compute 10^exp10 but we want to be sure it won't + // overflow + exp2 = (int)(exp10 * 3.321928094887362 + 0.5); + const double z = + exp10 * 2.302585092994046 - exp2 * 0.6931471805599453; + const double z2 = z * z; + conv.U = ((double_uint_t)(exp2) + DOUBLE_BASE_EXPONENT) + << DOUBLE_STORED_MANTISSA_BITS; + // compute exp(z) using continued fractions, see + // https://en.wikipedia.org/wiki/Exponential_function#Continued_fractions_for_ex + conv.F *= 1 + 2 * z / (2 - z + (z2 / (6 + (z2 / (10 + z2 / 14))))); + // correct for rounding errors + if (abs_number < conv.F) { + exp10--; + conv.F /= 10; + } + } + abs_exp10_covered_by_powers_table = + PRINTF_ABS(exp10) < PRINTF_MAX_PRECOMPUTED_POWER_OF_10; + normalization.raw_factor = abs_exp10_covered_by_powers_table + ? powers_of_10[PRINTF_ABS(exp10)] + : conv.F; + } + + // We now begin accounting for the widths of the two parts of our printed + // field: the decimal part after decimal exponent extraction, and the + // base-10 exponent part. For both of these, the value of 0 has a special + // meaning, but not the same one: a 0 exponent-part width means "don't print + // the exponent"; a 0 decimal-part width means "use as many characters as + // necessary". + + bool fall_back_to_decimal_only_mode = false; + if (flags & FLAGS_ADAPT_EXP) { + int required_significant_digits = (precision == 0) ? 1 : (int)precision; + // Should we want to fall-back to "%f" mode, and only print the decimal + // part? + fall_back_to_decimal_only_mode = + (exp10 >= -4 && exp10 < required_significant_digits); + // Now, let's adjust the precision + // This also decided how we adjust the precision value - as in "%g" + // mode, "precision" is the number of _significant digits_, and this is + // when we "translate" the precision value to an actual number of + // decimal digits. + int precision_ = + (fall_back_to_decimal_only_mode) + ? (int)precision - 1 - exp10 + : (int)precision - + 1; // the presence of the exponent ensures only one + // significant digit comes before the decimal point + precision = (precision_ > 0 ? (unsigned)precision_ : 0U); + flags |= FLAGS_PRECISION; // make sure print_broken_up_decimal respects + // our choice above + } + + normalization.multiply = (exp10 < 0 && abs_exp10_covered_by_powers_table); + bool should_skip_normalization = + (fall_back_to_decimal_only_mode || exp10 == 0); + struct double_components decimal_part_components = + should_skip_normalization + ? get_components(negative ? -abs_number : abs_number, precision) + : get_normalized_components(negative, precision, abs_number, + normalization); + + // Account for roll-over, e.g. rounding from 9.99 to 100.0 - which effects + // the exponent and may require additional tweaking of the parts + if (fall_back_to_decimal_only_mode) { + if ((flags & FLAGS_ADAPT_EXP) && exp10 >= -1 && + decimal_part_components.integral == powers_of_10[exp10 + 1]) { + exp10++; // Not strictly necessary, since exp10 is no longer really + // used + precision--; + // ... and it should already be the case that + // decimal_part_components.fractional == 0 + } + // TODO: What about rollover strictly within the fractional part? + } else { + if (decimal_part_components.integral >= 10) { + exp10++; + decimal_part_components.integral = 1; + decimal_part_components.fractional = 0; + } + } + + // the exp10 format is "E%+03d" and largest possible exp10 value for a + // 64-bit double is "307" (for 2^1023), so we set aside 4-5 characters + // overall + unsigned int exp10_part_width = fall_back_to_decimal_only_mode ? 0U + : (PRINTF_ABS(exp10) < 100) ? 4U + : 5U; + + unsigned int decimal_part_width = + ((flags & FLAGS_LEFT) && exp10_part_width) + ? + // We're padding on the right, so the width constraint is the + // exponent part's problem, not the decimal part's, so we'll use as + // many characters as we need: + 0U + : + // We're padding on the left; so the width constraint is the decimal + // part's problem. Well, can both the decimal part and the exponent + // part fit within our overall width? + ((width > exp10_part_width) + ? + // Yes, so we limit our decimal part's width. + // (Note this is trivially valid even if we've fallen back to + // "%f" mode) + width - exp10_part_width + : + // No; we just give up on any restriction on the decimal part + // and use as many characters as we need + 0U); + + const size_t start_idx = idx; + idx = print_broken_up_decimal(decimal_part_components, out, buffer, idx, + maxlen, precision, decimal_part_width, flags, + buf, len); + + if (!fall_back_to_decimal_only_mode) { + out((flags & FLAGS_UPPERCASE) ? 'E' : 'e', buffer, idx++, maxlen); + idx = print_integer(out, buffer, idx, maxlen, ABS_FOR_PRINTING(exp10), + exp10 < 0, 10, 0, exp10_part_width - 1, + FLAGS_ZEROPAD | FLAGS_PLUS); + if (flags & FLAGS_LEFT) { + // We need to right-pad with spaces to meet the width requirement + while (idx - start_idx < width) + out(' ', buffer, idx++, maxlen); + } + } + return idx; +} +#endif // PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS + +static size_t print_floating_point(out_fct_type out, + char* buffer, + size_t idx, + size_t maxlen, + double value, + unsigned int precision, + unsigned int width, + unsigned int flags, + bool prefer_exponential) { + char buf[PRINTF_FTOA_BUFFER_SIZE]; + size_t len = 0U; + + // test for special values + if (value != value) + return out_rev_(out, buffer, idx, maxlen, "nan", 3, width, flags); + if (value < -DBL_MAX) + return out_rev_(out, buffer, idx, maxlen, "fni-", 4, width, flags); + if (value > DBL_MAX) + return out_rev_(out, buffer, idx, maxlen, + (flags & FLAGS_PLUS) ? "fni+" : "fni", + (flags & FLAGS_PLUS) ? 4U : 3U, width, flags); + + if (!prefer_exponential && ((value > PRINTF_FLOAT_NOTATION_THRESHOLD) || + (value < -PRINTF_FLOAT_NOTATION_THRESHOLD))) { + // The required behavior of standard printf is to print _every_ + // integral-part digit -- which could mean printing hundreds of + // characters, overflowing any fixed internal buffer and necessitating a + // more complicated implementation. +#if PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS + return print_exponential_number(out, buffer, idx, maxlen, value, + precision, width, flags, buf, len); +#else + return 0U; +#endif + } + + // set default precision, if not set explicitly + if (!(flags & FLAGS_PRECISION)) { + precision = PRINTF_DEFAULT_FLOAT_PRECISION; + } + + // limit precision so that our integer holding the fractional part does not + // overflow + while ((len < PRINTF_FTOA_BUFFER_SIZE) && + (precision > PRINTF_MAX_SUPPORTED_PRECISION)) { + buf[len++] = + '0'; // This respects the precision in terms of result length only + precision--; + } + + return +#if PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS + prefer_exponential + ? print_exponential_number(out, buffer, idx, maxlen, value, + precision, width, flags, buf, len) + : +#endif + print_decimal_number(out, buffer, idx, maxlen, value, precision, + width, flags, buf, len); +} + +#endif // (PRINTF_SUPPORT_DECIMAL_SPECIFIERS || + // PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS) + +// internal vsnprintf +static int __vsnprintf(out_fct_type out, + char* buffer, + const size_t maxlen, + const char* format, + va_list va) { + unsigned int flags, width, precision, n; + size_t idx = 0U; + + if (!buffer) { + // use null output function + out = out_discard; + } + + while (*format) { + // format specifier? %[flags][width][.precision][length] + if (*format != '%') { + // no + out(*format, buffer, idx++, maxlen); + format++; + continue; + } else { + // yes, evaluate it + format++; + } + + // evaluate flags + flags = 0U; + do { + switch (*format) { + case '0': + flags |= FLAGS_ZEROPAD; + format++; + n = 1U; + break; + case '-': + flags |= FLAGS_LEFT; + format++; + n = 1U; + break; + case '+': + flags |= FLAGS_PLUS; + format++; + n = 1U; + break; + case ' ': + flags |= FLAGS_SPACE; + format++; + n = 1U; + break; + case '#': + flags |= FLAGS_HASH; + format++; + n = 1U; + break; + default: + n = 0U; + break; + } + } while (n); + + // evaluate width field + width = 0U; + if (is_digit_(*format)) { + width = atoi_(&format); + } else if (*format == '*') { + const int w = va_arg(va, int); + if (w < 0) { + flags |= FLAGS_LEFT; // reverse padding + width = (unsigned int)-w; + } else { + width = (unsigned int)w; + } + format++; + } + + // evaluate precision field + precision = 0U; + if (*format == '.') { + flags |= FLAGS_PRECISION; + format++; + if (is_digit_(*format)) { + precision = atoi_(&format); + } else if (*format == '*') { + const int precision_ = (int)va_arg(va, int); + precision = precision_ > 0 ? (unsigned int)precision_ : 0U; + format++; + } + } + + // evaluate length field + switch (*format) { + case 'l': + flags |= FLAGS_LONG; + format++; + if (*format == 'l') { + flags |= FLAGS_LONG_LONG; + format++; + } + break; + case 'h': + flags |= FLAGS_SHORT; + format++; + if (*format == 'h') { + flags |= FLAGS_CHAR; + format++; + } + break; + case 't': + flags |= (sizeof(ptrdiff_t) == sizeof(long) ? FLAGS_LONG + : FLAGS_LONG_LONG); + format++; + break; + case 'j': + flags |= (sizeof(intmax_t) == sizeof(long) ? FLAGS_LONG + : FLAGS_LONG_LONG); + format++; + break; + case 'z': + flags |= (sizeof(size_t) == sizeof(long) ? FLAGS_LONG + : FLAGS_LONG_LONG); + format++; + break; + default: + break; + } + + // evaluate specifier + switch (*format) { + case 'd': + case 'i': + case 'u': + case 'x': + case 'X': + case 'o': + case 'b': { + // set the base + numeric_base_t base; + if (*format == 'x' || *format == 'X') { + base = BASE_HEX; + } else if (*format == 'o') { + base = BASE_OCTAL; + } else if (*format == 'b') { + base = BASE_BINARY; + } else { + base = BASE_DECIMAL; + flags &= ~FLAGS_HASH; // no hash for dec format + } + // uppercase + if (*format == 'X') { + flags |= FLAGS_UPPERCASE; + } + + // no plus or space flag for u, x, X, o, b + if ((*format != 'i') && (*format != 'd')) { + flags &= ~(FLAGS_PLUS | FLAGS_SPACE); + } + + // ignore '0' flag when precision is given + if (flags & FLAGS_PRECISION) { + flags &= ~FLAGS_ZEROPAD; + } + + // convert the integer + if ((*format == 'i') || (*format == 'd')) { + // signed + if (flags & FLAGS_LONG_LONG) { +#if PRINTF_SUPPORT_LONG_LONG + const long long value = va_arg(va, long long); + idx = print_integer(out, buffer, idx, maxlen, + ABS_FOR_PRINTING(value), value < 0, + base, precision, width, flags); +#endif + } else if (flags & FLAGS_LONG) { + const long value = va_arg(va, long); + idx = print_integer(out, buffer, idx, maxlen, + ABS_FOR_PRINTING(value), value < 0, + base, precision, width, flags); + } else { + const int value = + (flags & FLAGS_CHAR) ? (signed char)va_arg(va, int) + : (flags & FLAGS_SHORT) ? (short int)va_arg(va, int) + : va_arg(va, int); + idx = print_integer(out, buffer, idx, maxlen, + ABS_FOR_PRINTING(value), value < 0, + base, precision, width, flags); + } + } else { + // unsigned + if (flags & FLAGS_LONG_LONG) { +#if PRINTF_SUPPORT_LONG_LONG + idx = + print_integer(out, buffer, idx, maxlen, + (printf_unsigned_value_t)va_arg( + va, unsigned long long), + false, base, precision, width, flags); +#endif + } else if (flags & FLAGS_LONG) { + idx = print_integer( + out, buffer, idx, maxlen, + (printf_unsigned_value_t)va_arg(va, unsigned long), + false, base, precision, width, flags); + } else { + const unsigned int value = + (flags & FLAGS_CHAR) + ? (unsigned char)va_arg(va, unsigned int) + : (flags & FLAGS_SHORT) + ? (unsigned short int)va_arg(va, unsigned int) + : va_arg(va, unsigned int); + idx = + print_integer(out, buffer, idx, maxlen, + (printf_unsigned_value_t)value, false, + base, precision, width, flags); + } + } + format++; + break; + } +#if PRINTF_SUPPORT_DECIMAL_SPECIFIERS + case 'f': + case 'F': + if (*format == 'F') + flags |= FLAGS_UPPERCASE; + idx = print_floating_point(out, buffer, idx, maxlen, + va_arg(va, double), precision, width, + flags, PRINTF_PREFER_DECIMAL); + format++; + break; +#endif +#if PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS + case 'e': + case 'E': + case 'g': + case 'G': + if ((*format == 'g') || (*format == 'G')) + flags |= FLAGS_ADAPT_EXP; + if ((*format == 'E') || (*format == 'G')) + flags |= FLAGS_UPPERCASE; + idx = print_floating_point(out, buffer, idx, maxlen, + va_arg(va, double), precision, width, + flags, PRINTF_PREFER_EXPONENTIAL); + format++; + break; +#endif // PRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS + case 'c': { + unsigned int l = 1U; + // pre padding + if (!(flags & FLAGS_LEFT)) { + while (l++ < width) { + out(' ', buffer, idx++, maxlen); + } + } + // char output + out((char)va_arg(va, int), buffer, idx++, maxlen); + // post padding + if (flags & FLAGS_LEFT) { + while (l++ < width) { + out(' ', buffer, idx++, maxlen); + } + } + format++; + break; + } + + case 's': { + const char* p = va_arg(va, char*); + if (p == NULL) { + idx = out_rev_(out, buffer, idx, maxlen, ")llun(", 6, width, + flags); + } else { + unsigned int l = + strnlen_s_(p, precision ? precision : (size_t)-1); + // pre padding + if (flags & FLAGS_PRECISION) { + l = (l < precision ? l : precision); + } + if (!(flags & FLAGS_LEFT)) { + while (l++ < width) { + out(' ', buffer, idx++, maxlen); + } + } + // string output + while ((*p != 0) && + (!(flags & FLAGS_PRECISION) || precision--)) { + out(*(p++), buffer, idx++, maxlen); + } + // post padding + if (flags & FLAGS_LEFT) { + while (l++ < width) { + out(' ', buffer, idx++, maxlen); + } + } + } + format++; + break; + } + + case 'p': { + width = sizeof(void*) * 2U + + 2; // 2 hex chars per byte + the "0x" prefix + flags |= FLAGS_ZEROPAD | FLAGS_POINTER; + uintptr_t value = (uintptr_t)va_arg(va, void*); + idx = (value == (uintptr_t)NULL) + ? out_rev_(out, buffer, idx, maxlen, ")lin(", 5, + width, flags) + : print_integer(out, buffer, idx, maxlen, + (printf_unsigned_value_t)value, false, + BASE_HEX, precision, width, flags); + format++; + break; + } + + case '%': + out('%', buffer, idx++, maxlen); + format++; + break; + + default: + out(*format, buffer, idx++, maxlen); + format++; + break; + } + } + + // termination + out((char)0, buffer, idx < maxlen ? idx : maxlen - 1U, maxlen); + + // return written chars without terminating \0 + return (int)idx; +} + +/** + * This function will fill a formatted string to buffer. + * + * @param buf is the buffer to save formatted string. + * + * @param size is the size of buffer. + * + * @param fmt is the format parameters. + * + * @param args is a list of variable parameters. + * + * @return The number of characters actually written to buffer. + */ +int pika_vsnprintf(char* buf, rt_size_t size, const char* fmt, va_list args) { + return __vsnprintf(out_buffer, buf, size, fmt, args); +} + +int __platform_vsnprintf(char* buff, + size_t size, + const char* fmt, + va_list args) { + return pika_vsnprintf(buff, size, fmt, args); +} diff --git a/test/pika_config_gtest.c b/test/pika_config_gtest.c index 1eeeea46a..7e0f6bb75 100644 --- a/test/pika_config_gtest.c +++ b/test/pika_config_gtest.c @@ -10,15 +10,16 @@ uint32_t log_index = 0; /* save printf content to log_buff */ void __platform_printf(char* fmt, ...) { va_list args; - va_start(args, fmt); - vprintf(fmt, args); - va_end(args); for (int i = LOG_BUFF_MAX - 2; i >= 0; i--) { memcpy(log_buff[i + 1], log_buff[i], LOG_SIZE); } va_start(args, fmt); - vsnprintf(log_buff[0], LOG_SIZE - 1, fmt, args); + __platform_vsnprintf(log_buff[0], LOG_SIZE - 1, fmt, args); va_end(args); + /* putchar */ + for (int i = 0; i < strlen(log_buff[0]); i++) { + __platform_putchar(log_buff[0][i]); + } } #endif From 42a3cebb085a4a995d80031685dbf630e053aa55 Mon Sep 17 00:00:00 2001 From: lyon Date: Sat, 24 Dec 2022 15:42:01 +0800 Subject: [PATCH 42/44] connect *printf all to vsnprintf --- src/PikaPlatform.c | 42 +++++++++++++++++++++++++++++------------- src/PikaPlatform.h | 1 + 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/src/PikaPlatform.c b/src/PikaPlatform.c index 4a55de0b2..a805b912f 100644 --- a/src/PikaPlatform.c +++ b/src/PikaPlatform.c @@ -78,17 +78,9 @@ PIKA_WEAK int64_t __platform_getTick(void) { return -1; } -#ifndef __platform_printf -PIKA_WEAK void __platform_printf(char* fmt, ...) { - va_list args; - va_start(args, fmt); - vprintf(fmt, args); - va_end(args); -} -#endif - PIKA_WEAK int __platform_vsprintf(char* buff, char* fmt, va_list args) { - return vsprintf(buff, fmt, args); + /* vsnprintf */ + return __platform_vsnprintf(buff, PIKA_SPRINTF_BUFF_SIZE, fmt, args); } PIKA_WEAK int __platform_snprintf(char* buff, @@ -102,6 +94,30 @@ PIKA_WEAK int __platform_snprintf(char* buff, return ret; } +PIKA_WEAK int __platform_putchar(char ch) { + return putchar(ch); +} + +PIKA_WEAK int __platform_vprintf(char* fmt, va_list args) { + /* vsprintf to vprintf */ + char buff[PIKA_SPRINTF_BUFF_SIZE]; + __platform_vsprintf(buff, fmt, args); + /* putchar */ + for (int i = 0; i < strlen(buff); i++) { + __platform_putchar(buff[i]); + } + return 0; +} + +#ifndef __platform_printf +PIKA_WEAK void __platform_printf(char* fmt, ...) { + va_list args; + va_start(args, fmt); + __platform_vprintf(fmt, args); + va_end(args); +} +#endif + PIKA_WEAK char* __platform_strdup(const char* src) { char* dst = (char*)__platform_malloc(strlen(src) + 1); if (dst) { @@ -124,7 +140,7 @@ PIKA_WEAK int __platform_vsnprintf(char* buff, PIKA_WEAK int __platform_sprintf(char* buff, char* fmt, ...) { va_list args; va_start(args, fmt); - int res = vsnprintf(buff, PIKA_SPRINTF_BUFF_SIZE, fmt, args); + int res = __platform_vsnprintf(buff, PIKA_SPRINTF_BUFF_SIZE, fmt, args); va_end(args); if (res >= PIKA_SPRINTF_BUFF_SIZE) { __platform_printf( @@ -254,13 +270,13 @@ PIKA_WEAK void __platform_thread_delay(void) { return; } -PIKA_WEAK void __platform_sleep_ms(uint32_t ms){ +PIKA_WEAK void __platform_sleep_ms(uint32_t ms) { __platform_printf("Error: __platform_sleep_ms need implementation!\r\n"); while (1) { } } -PIKA_WEAK void __platform_sleep_s(uint32_t s){ +PIKA_WEAK void __platform_sleep_s(uint32_t s) { __platform_printf("Error: __platform_sleep_s need implementation!\r\n"); while (1) { } diff --git a/src/PikaPlatform.h b/src/PikaPlatform.h index 41c0a9c62..2760ace48 100644 --- a/src/PikaPlatform.h +++ b/src/PikaPlatform.h @@ -156,6 +156,7 @@ uint8_t __is_locked_pikaMemory(void); /* support shell */ char __platform_getchar(void); +int __platform_putchar(char ch); /* file API */ FILE* __platform_fopen(const char* filename, const char* modes); From ae59623eafa6b87b5f682366f0b1c6bd278b46fd Mon Sep 17 00:00:00 2001 From: lyon1998 Date: Sat, 24 Dec 2022 15:43:09 +0800 Subject: [PATCH 43/44] update_toml --- packages.toml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages.toml b/packages.toml index e27461e8f..42972cdc9 100644 --- a/packages.toml +++ b/packages.toml @@ -470,3 +470,7 @@ releases = [ "v0.0.1 1ae3ac23759fb2b5e0f77866af40986ac94e356d", "v1.0.0 29ad2b44817c5a72ace9f6d09cea7df6beb516f9" ] + +[[packages]] +name = "pika_libc" +releases = [ "v1.0.0 42a3cebb085a4a995d80031685dbf630e053aa55" ] From b45056ed4271f62408677ee0b4b5aebde8f8dffd Mon Sep 17 00:00:00 2001 From: lyon Date: Sat, 24 Dec 2022 15:53:01 +0800 Subject: [PATCH 44/44] add pyi for pika_libc --- package/pika_libc/pika_libc.pyi | 0 port/linux/package/pikascript/pika_libc.pyi | 0 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 package/pika_libc/pika_libc.pyi create mode 100644 port/linux/package/pikascript/pika_libc.pyi diff --git a/package/pika_libc/pika_libc.pyi b/package/pika_libc/pika_libc.pyi new file mode 100644 index 000000000..e69de29bb diff --git a/port/linux/package/pikascript/pika_libc.pyi b/port/linux/package/pikascript/pika_libc.pyi new file mode 100644 index 000000000..e69de29bb