PikaPlatform.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424
  1. /*
  2. * This file is part of the PikaPython project.
  3. * http://github.com/pikastech/pikapython
  4. *
  5. * MIT License
  6. *
  7. * Copyright (c) 2021 lyon liang6516@outlook.com
  8. *
  9. * Permission is hereby granted, free of charge, to any person obtaining a
  10. * copy of this software and associated documentation files (the "Software"),
  11. * to deal in the Software without restriction, including without limitation
  12. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  13. * and/or sell copies of the Software, and to permit persons to whom the
  14. * Software is furnished to do so, subject to the following conditions:
  15. *
  16. * The above copyright notice and this permission notice shall be included in
  17. * all copies or substantial portions of the Software.
  18. *
  19. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  20. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  22. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  23. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  24. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  25. * DEALINGS IN THE SOFTWARE.
  26. */
  27. #ifdef __cplusplus
  28. extern "C" {
  29. #endif
  30. /* adapter for old api */
  31. #include "./pika_adapter_old_api.h"
  32. #ifndef __PIKA_PALTFORM__H
  33. #define __PIKA_PALTFORM__H
  34. #include <stdarg.h>
  35. #include <stdint.h>
  36. #include <stdio.h>
  37. #include <stdlib.h>
  38. #include <string.h>
  39. #include <time.h>
  40. #ifdef __linux
  41. #include <unistd.h>
  42. #endif
  43. #define ANSI_COLOR_RED "\x1b[31m"
  44. #define ANSI_COLOR_GREEN "\x1b[32m"
  45. #define ANSI_COLOR_YELLOW "\x1b[33m"
  46. #define ANSI_COLOR_BLUE "\x1b[34m"
  47. #define ANSI_COLOR_MAGENTA "\x1b[35m"
  48. #define ANSI_COLOR_CYAN "\x1b[36m"
  49. #define ANSI_COLOR_RESET "\x1b[0m"
  50. #define PIKA_ASSERT_2(expr, msg, ...) \
  51. if (!(expr)) { \
  52. pika_platform_printf((char*)"Assertion \"%s\" failed, in function: %s(). \r\n (at %s:%d)\n" msg, #expr, __FUNCTION__, __FILE__, __LINE__, __VA_ARGS__); \
  53. pika_platform_abort_handler(); \
  54. abort(); \
  55. }
  56. #define PIKA_ASSERT_1(expr) \
  57. if (!(expr)) { \
  58. pika_platform_printf((char*)"Assertion \"%s\" failed, in function: %s(). \r\n (at %s:%d)\n", #expr, __FUNCTION__, __FILE__, __LINE__); \
  59. pika_platform_abort_handler(); \
  60. abort(); \
  61. }
  62. #define GET_MACRO(_1, _2, NAME, ...) NAME
  63. /* clang-format off */
  64. #if PIKA_ASSERT_ENABLE
  65. #define pika_assert PIKA_ASSERT_1
  66. #define pika_assert_msg PIKA_ASSERT_2
  67. #else
  68. #define pika_assert(...) (void)0;
  69. #define pika_assert_msg(...) (void)0;
  70. #endif
  71. /* clang-format on */
  72. /* Compiler */
  73. #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 5000000) /* ARM Compiler \
  74. */
  75. #define PIKA_WEAK __attribute__((weak))
  76. #elif defined(__IAR_SYSTEMS_ICC__) /* for IAR Compiler */
  77. #define PIKA_WEAK __weak
  78. #elif defined(__MINGW32__) /* MINGW32 Compiler */
  79. #define PIKA_WEAK
  80. #elif defined(__GNUC__) /* GNU GCC Compiler */
  81. #define PIKA_WEAK __attribute__((weak))
  82. #endif
  83. /* default PIKA_WEAK */
  84. #ifndef PIKA_WEAK
  85. #define PIKA_WEAK
  86. #endif
  87. /* align for bytecode */
  88. #if defined(_WIN32)
  89. #define PIKA_BYTECODE_ALIGN
  90. #else
  91. #define PIKA_BYTECODE_ALIGN __attribute__((aligned(4)))
  92. #endif
  93. #if defined(_WIN32)
  94. #pragma warning(disable : 4113)
  95. #endif
  96. #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 5000000) && \
  97. (__ARMCC_VERSION < 6000000)
  98. #pragma diag_suppress 66
  99. #pragma diag_suppress 188
  100. #pragma diag_suppress 546
  101. #pragma diag_suppress 177
  102. #endif
  103. /* OS */
  104. #if defined(__RTTHREAD__) && PIKA_RTTHREAD_ENABLE
  105. #include <rtthread.h>
  106. #define pika_platform_printf(...) rt_kprintf(__VA_ARGS__)
  107. #elif defined(__ZEUSOS__) && PIKA_ZEUSOS_ENABLE
  108. #include "zos.h"
  109. #define pika_platform_printf(...) zos_kprintf(__VA_ARGS__)
  110. #endif
  111. typedef enum {
  112. PIKA_RES_OK = 0,
  113. PIKA_RES_ERR_RUNTIME_ERROR = -1,
  114. PIKA_RES_ERR_ARG_NO_FOUND = -2,
  115. PIKA_RES_ERR_UNKNOWN_INSTRUCTION = -3,
  116. PIKA_RES_ERR_OUT_OF_RANGE = -4,
  117. PIKA_RES_ERR_IO_ERROR = -5,
  118. PIKA_RES_ERR_INSUFFICIENT_RESOURCE = -6,
  119. PIKA_RES_ERR_INVALID_PARAM = -7,
  120. PIKA_RES_ERR_INVALID_PTR = -8,
  121. PIKA_RES_ERR_UNALIGNED_PTR = -9,
  122. PIKA_RES_ERR_INVALID_VERSION_NUMBER = -10,
  123. PIKA_RES_ERR_ILLEGAL_MAGIC_CODE = -11,
  124. PIKA_RES_ERR_OPERATION_FAILED = -12,
  125. PIKA_RES_ERR_UNKNOWN = -13,
  126. PIKA_RES_ERR_SYNTAX_ERROR = -14,
  127. PIKA_RES_ERR_IO = -15,
  128. PIKA_RES_ERR_ASSERT = -16,
  129. PIKA_RES_ERR_SIGNAL_EVENT_FULL = -17,
  130. PIKA_RES_ERR_SIGNAL_EVENT_EMPTY = -18,
  131. PIKA_RES_ERR_INDEX = -19,
  132. } PIKA_RES;
  133. /* clang-format off */
  134. /* pikascript bool type */
  135. #define pika_bool int64_t
  136. #define pika_true 1
  137. #define pika_false 0
  138. #define _PIKA_BOOL_ERR -1
  139. #define _PIKA_INT_ERR (-999999999)
  140. #define _PIKA_FLOAT_ERR (-999999999.0)
  141. /* clang-format on */
  142. /*
  143. [Note]:
  144. Create a pika_config.c to override the following weak functions to
  145. config PikaScript. [Example]: 1.
  146. https://gitee.com/Lyon1998/pikascript/blob/master/package/STM32G030Booter/pika_config.c
  147. 2.
  148. https://gitee.com/Lyon1998/pikascript/blob/master/package/pikaRTBooter/pika_config.c
  149. */
  150. /* interrupt config */
  151. void pika_platform_enable_irq_handle(void);
  152. void pika_platform_disable_irq_handle(void);
  153. void pika_platform_abort_handler(void);
  154. /* printf family config */
  155. #ifndef pika_platform_printf
  156. void pika_platform_printf(char* fmt, ...);
  157. #endif
  158. int pika_vprintf(char* fmt, va_list args);
  159. int pika_sprintf(char* buff, char* fmt, ...);
  160. int pika_vsprintf(char* buff, char* fmt, va_list args);
  161. int pika_putchar(char ch);
  162. int pika_platform_vsnprintf(char* buff,
  163. size_t size,
  164. const char* fmt,
  165. va_list args);
  166. int pika_snprintf(char* buff, size_t size, const char* fmt, ...);
  167. char* pika_platform_strdup(const char* src);
  168. size_t pika_platform_tick_from_millisecond(size_t ms);
  169. /* libc config */
  170. void* pika_platform_malloc(size_t size);
  171. void* pika_platform_calloc(size_t num, size_t size);
  172. void pika_platform_free(void* ptr);
  173. void* pika_reallocn(void* ptr, size_t size_old, size_t size_new);
  174. void* pika_platform_realloc(void* ptr, size_t size);
  175. void* pika_platform_memset(void* mem, int ch, size_t size);
  176. void* pika_platform_memcpy(void* dir, const void* src, size_t size);
  177. int pika_platform_memcmp(const void* s1, const void* s2, size_t n);
  178. void* pika_platform_memmove(void* s1, void* s2, size_t n);
  179. /* pika memory pool config */
  180. void pika_platform_wait(void);
  181. /* support shell */
  182. char pika_platform_getchar(void);
  183. int pika_platform_getchar_nonblocking(char* ch);
  184. int pika_platform_putchar(char ch);
  185. int pika_platform_fflush(void* stream);
  186. #define PIKA_TIMEOUT_FOREVER 0xFFFFFFFF
  187. int pika_platform_repl_recv(uint8_t* buff, size_t size, uint32_t timeout);
  188. /* file API */
  189. FILE* pika_platform_fopen(const char* filename, const char* modes);
  190. int pika_platform_fclose(FILE* stream);
  191. size_t pika_platform_fwrite(const void* ptr,
  192. size_t size,
  193. size_t n,
  194. FILE* stream);
  195. size_t pika_platform_fread(void* ptr, size_t size, size_t n, FILE* stream);
  196. int pika_platform_fseek(FILE* stream, long offset, int whence);
  197. long pika_platform_ftell(FILE* stream);
  198. char* pika_platform_getcwd(char* buf, size_t size);
  199. int pika_platform_chdir(const char* path);
  200. int pika_platform_rmdir(const char* pathname);
  201. int pika_platform_mkdir(const char* pathname, int mode);
  202. char* pika_platform_realpath(const char* path, char* resolved_path);
  203. int pika_platform_path_exists(const char* path);
  204. int pika_platform_path_isdir(const char* path);
  205. int pika_platform_path_isfile(const char* path);
  206. int pika_platform_remove(const char* pathname);
  207. int pika_platform_rename(const char* oldpath, const char* newpath);
  208. char** pika_platform_listdir(const char* path, int* count);
  209. /* error */
  210. void pika_platform_error_handle(void);
  211. /* panic */
  212. void pika_platform_panic_handle(void);
  213. int64_t pika_platform_get_tick(void);
  214. void pika_platform_sleep_ms(uint32_t ms);
  215. void pika_platform_sleep_us(uint32_t us);
  216. void pika_hook_instruct(void);
  217. void pika_thread_idle_hook(void);
  218. PIKA_BOOL pika_hook_arg_cache_filter(void* self);
  219. void* pika_user_malloc(size_t size);
  220. void pika_user_free(void* ptr, size_t size);
  221. uint8_t pika_is_locked_pikaMemory(void);
  222. #if PIKA_FLOAT_TYPE_DOUBLE
  223. #define pika_float double
  224. #else
  225. #define pika_float float
  226. #endif
  227. #ifdef _WIN32
  228. #pragma warning(disable : 4996)
  229. #endif
  230. /* Thread Platform */
  231. #ifdef __linux
  232. #include <pthread.h>
  233. #include <sched.h>
  234. typedef struct pika_platform_thread {
  235. pthread_t thread;
  236. pthread_mutex_t mutex;
  237. pthread_cond_t cond;
  238. } pika_platform_thread_t;
  239. #elif PIKA_WIN_PTHREAD_ENABLE
  240. #ifndef HAVE_STRUCT_TIMESPEC
  241. #define HAVE_STRUCT_TIMESPEC
  242. #endif
  243. #include <pthread.h>
  244. typedef struct pika_platform_thread {
  245. pthread_t thread;
  246. pthread_mutex_t mutex;
  247. pthread_cond_t cond;
  248. } pika_platform_thread_t;
  249. #elif PIKA_FREERTOS_ENABLE
  250. #include "FreeRTOS.h"
  251. #include "task.h"
  252. typedef struct pika_platform_thread {
  253. TaskHandle_t thread;
  254. #if PIKA_THREAD_MALLOC_STACK_ENABLE
  255. uint32_t thread_stack_size;
  256. uint8_t* thread_stack;
  257. StaticTask_t task_buffer;
  258. #endif
  259. } pika_platform_thread_t;
  260. #elif PIKA_RTTHREAD_ENABLE
  261. #include <rtthread.h>
  262. typedef struct pika_platform_thread {
  263. rt_thread_t thread;
  264. } pika_platform_thread_t;
  265. #elif PIKA_ZEUSOS_ENABLE
  266. #include "zos.h"
  267. typedef struct pika_platform_thread {
  268. zos_task_t thread;
  269. } pika_platform_thread_t;
  270. #else
  271. typedef struct pika_platform_thread {
  272. void* platform_data;
  273. } pika_platform_thread_t;
  274. #endif
  275. pika_platform_thread_t* pika_platform_thread_init(const char* name,
  276. void (*entry)(void*),
  277. void* const param,
  278. unsigned int stack_size,
  279. unsigned int priority,
  280. unsigned int tick);
  281. uint64_t pika_platform_thread_self(void);
  282. void pika_platform_thread_yield(void);
  283. void pika_platform_thread_startup(pika_platform_thread_t* thread);
  284. void pika_platform_thread_stop(pika_platform_thread_t* thread);
  285. void pika_platform_thread_start(pika_platform_thread_t* thread);
  286. void pika_platform_thread_destroy(pika_platform_thread_t* thread);
  287. void pika_platform_thread_exit(pika_platform_thread_t* thread);
  288. #if defined(__linux) || (PIKA_WIN_PTHREAD_ENABLE)
  289. #include <pthread.h>
  290. typedef pthread_mutex_t pika_mutex_platform_data_t;
  291. #elif PIKA_FREERTOS_ENABLE
  292. #include "FreeRTOS.h"
  293. #include "semphr.h"
  294. typedef SemaphoreHandle_t pika_mutex_platform_data_t;
  295. #elif PIKA_RTTHREAD_ENABLE
  296. #include <rtthread.h>
  297. typedef rt_mutex_t pika_mutex_platform_data_t;
  298. #elif PIKA_ZEUSOS_ENABLE
  299. #include "zos.h"
  300. typedef zos_mutex_t pika_mutex_platform_data_t;
  301. #else
  302. typedef void* pika_mutex_platform_data_t;
  303. #endif
  304. typedef struct pika_platform_thread_mutex {
  305. pika_mutex_platform_data_t mutex;
  306. volatile int is_init;
  307. volatile int is_first_lock;
  308. volatile int bare_lock;
  309. } pika_platform_thread_mutex_t;
  310. int pika_platform_thread_mutex_init(pika_platform_thread_mutex_t* m);
  311. int pika_platform_thread_mutex_lock(pika_platform_thread_mutex_t* m);
  312. int pika_platform_thread_mutex_trylock(pika_platform_thread_mutex_t* m);
  313. int pika_platform_thread_mutex_unlock(pika_platform_thread_mutex_t* m);
  314. int pika_platform_thread_mutex_destroy(pika_platform_thread_mutex_t* m);
  315. typedef struct pika_thread_recursive_mutex {
  316. pika_platform_thread_mutex_t mutex;
  317. uint64_t owner;
  318. volatile int lock_times;
  319. } pika_thread_recursive_mutex_t;
  320. int pika_thread_recursive_mutex_init(pika_thread_recursive_mutex_t* m);
  321. int pika_thread_recursive_mutex_lock(pika_thread_recursive_mutex_t* m);
  322. int pika_thread_recursive_mutex_trylock(pika_thread_recursive_mutex_t* m);
  323. int pika_thread_recursive_mutex_unlock(pika_thread_recursive_mutex_t* m);
  324. int pika_thread_recursive_mutex_destroy(pika_thread_recursive_mutex_t* m);
  325. #ifdef __linux
  326. #include <sys/time.h>
  327. typedef struct pika_platform_timer {
  328. struct timeval time;
  329. } pika_platform_timer_t;
  330. #elif PIKA_FREERTOS_ENABLE
  331. #include "FreeRTOS.h"
  332. #include "task.h"
  333. typedef struct pika_platform_timer {
  334. uint32_t time;
  335. } pika_platform_timer_t;
  336. #elif PIKA_RTTHREAD_ENABLE
  337. #include <rtthread.h>
  338. typedef struct pika_platform_timer {
  339. uint32_t time;
  340. } pika_platform_timer_t;
  341. #elif PIKA_ZEUSOS_ENABLE
  342. #include "zos.h"
  343. typedef struct pika_platform_timer {
  344. uint32_t time;
  345. } pika_platform_timer_t;
  346. #else
  347. typedef struct pika_platform_timer {
  348. void* platform_data;
  349. } pika_platform_timer_t;
  350. #endif
  351. void pika_platform_thread_timer_init(pika_platform_timer_t* timer);
  352. void pika_platform_thread_timer_cutdown(pika_platform_timer_t* timer,
  353. unsigned int timeout);
  354. char pika_platform_thread_timer_is_expired(pika_platform_timer_t* timer);
  355. int pika_platform_thread_timer_remain(pika_platform_timer_t* timer);
  356. unsigned long pika_platform_thread_timer_now(void);
  357. void pika_platform_thread_timer_usleep(unsigned long usec);
  358. void pika_platform_reboot(void);
  359. void pika_platform_clear(void);
  360. #define WEAK_FUNCTION_NEED_OVERRIDE_INFO(_) \
  361. pika_platform_printf(ANSI_COLOR_RED \
  362. "Error: The function `%s()` has been invoked, but " \
  363. "it is not implemented.\r\n" ANSI_COLOR_RESET, \
  364. __FUNCTION__); \
  365. pika_platform_printf( \
  366. ANSI_COLOR_CYAN \
  367. "Info: The function `%s()` is defined as a weak function by default. " \
  368. "It should be overridden on this platform.\r\n" ANSI_COLOR_RESET, \
  369. __FUNCTION__);
  370. #define WEAK_FUNCTION_NEED_OVERRIDE_ERROR(_) \
  371. WEAK_FUNCTION_NEED_OVERRIDE_INFO(_) \
  372. pika_platform_panic_handle();
  373. #define WEAK_FUNCTION_NEED_OVERRIDE_ERROR_LOWLEVEL(_) \
  374. WEAK_FUNCTION_NEED_OVERRIDE_INFO(_) \
  375. while (1) { \
  376. }
  377. #endif
  378. #ifdef __cplusplus
  379. }
  380. #endif