osi_api.h 78 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700
  1. /* Copyright (C) 2018 RDA Technologies Limited and/or its affiliates("RDA").
  2. * All rights reserved.
  3. *
  4. * This software is supplied "AS IS" without any warranties.
  5. * RDA assumes no responsibility or liability for the use of the software,
  6. * conveys no license or title under any patent, copyright, or mask work
  7. * right to the product. RDA reserves the right to make changes in the
  8. * software without notification. RDA also make no representation or
  9. * warranty that such application will be suitable for the specified use
  10. * without further testing or modification.
  11. */
  12. #ifndef _OSI_API_H_
  13. #define _OSI_API_H_
  14. #include <stdint.h>
  15. #include <stdbool.h>
  16. #include <stddef.h>
  17. #ifndef _MSC_VER
  18. #include "kernel_config.h"
  19. #endif
  20. #include "osi_compiler.h"
  21. #include "osi_vsmap.h"
  22. #include "osi_clock.h"
  23. #include "quec_proj_config.h"
  24. #ifdef __cplusplus
  25. extern "C" {
  26. #endif
  27. #define OSI_WAIT_FOREVER (-1U)
  28. #define OSI_DELAY_MAX (-1U)
  29. /**
  30. * Special value to indicate timer callback will be invoked in
  31. * timer ISR.
  32. */
  33. #define OSI_TIMER_IN_ISR ((osiThread_t *)NULL)
  34. /**
  35. * Special value to indicate timer callback will be invoked in
  36. * timer service thread.
  37. */
  38. #define OSI_TIMER_IN_SERVICE ((osiThread_t *)0xffffffff)
  39. /**
  40. * reserved event id to indicate nop
  41. */
  42. #define OSI_EVENT_ID_NONE (0)
  43. /**
  44. * reserved event id to indicate quit event loop
  45. */
  46. #define OSI_EVENT_ID_QUIT (8)
  47. /**
  48. * elapsed timer for counting elapsed time
  49. */
  50. typedef uint32_t osiElapsedTimer_t;
  51. /**
  52. * opaque data structure for timer
  53. */
  54. typedef struct osiTimer osiTimer_t;
  55. /**
  56. * opaque data structure for timer pool
  57. */
  58. typedef struct osiTimerPool osiTimerPool_t;
  59. /**
  60. * opaque data structure for thread
  61. */
  62. typedef struct osiThread osiThread_t;
  63. /**
  64. * opaque data structure for message queue
  65. */
  66. typedef struct osiMessageQueue osiMessageQueue_t;
  67. /**
  68. * opaque data structure for event queue
  69. *
  70. * Event queue is just a message queue, and the message is \p osiEvent_t
  71. * (event itself rather than pointer).
  72. */
  73. typedef struct osiEventQueue osiEventQueue_t;
  74. /**
  75. * opaque data structure for mutex
  76. */
  77. typedef struct osiMutex osiMutex_t;
  78. /**
  79. * opaque data structure for semaphore
  80. */
  81. typedef struct osiSemaphore osiSemaphore_t;
  82. /**
  83. * opaque data structure for work
  84. */
  85. typedef struct osiWork osiWork_t;
  86. /**
  87. * opaque data structure for work queue
  88. */
  89. typedef struct osiWorkQueue osiWorkQueue_t;
  90. /**
  91. * opaque data structure for thread notify
  92. */
  93. typedef struct osiNotify osiNotify_t;
  94. /**
  95. * function type of callback
  96. */
  97. typedef void (*osiCallback_t)(void *ctx);
  98. /**
  99. * function type of thread entry
  100. */
  101. typedef void (*osiThreadEntry_t)(void *argument);
  102. /**
  103. * function type of interrupt handler
  104. */
  105. typedef void (*osiIrqHandler_t)(void *ctx);
  106. /**
  107. * event, with ID and 3 parameters
  108. */
  109. typedef struct osiEvent
  110. {
  111. uint32_t id; ///< event identifier
  112. uint32_t param1; ///< 1st parameter
  113. uint32_t param2; ///< 2nd parameter
  114. uint32_t param3; ///< 3rd parameter
  115. } osiEvent_t;
  116. /**
  117. * thread priority
  118. *
  119. * The definition is independent of implementation. Though some
  120. * implementation will use larger value for higher priority and
  121. * others will use smaller value for highe priority, this enum will
  122. * use larger value for higher priority.
  123. *
  124. * \p OSI_PRIORITY_IDLE and \p OSI_PRIORITY_HISR are reserved, can't
  125. * be used.
  126. *
  127. * The definition is the same as CMSIS-RTOS.
  128. */
  129. typedef enum
  130. {
  131. OSI_PRIORITY_IDLE = 1, // reserved
  132. OSI_PRIORITY_LOW = 8,
  133. OSI_PRIORITY_BELOW_NORMAL = 16,
  134. #ifdef CONFIG_QUEC_PROJECT_FEATURE
  135. OSI_PRIORITY_NORMAL_LOWER = 23,
  136. #endif
  137. OSI_PRIORITY_NORMAL = 24,
  138. OSI_PRIORITY_ABOVE_NORMAL = 32,
  139. OSI_PRIORITY_HIGH = 40,
  140. OSI_PRIORITY_REALTIME = 48,
  141. OSI_PRIORITY_HISR = 56, // reserved
  142. } osiThreadPriority_t;
  143. /**
  144. * suspend mode
  145. *
  146. * System behavior of suspend modes will be diffrent among underlay
  147. * platform. Driver shall take care the difference, and most likely
  148. * application won't take care it.
  149. */
  150. typedef enum osiSuspendMode
  151. {
  152. OSI_SUSPEND_PM0, ///< light sleep
  153. OSI_SUSPEND_PM1, ///< 1st level suspend mode
  154. OSI_SUSPEND_PM2 ///< 2nd level suspend mode
  155. } osiSuspendMode_t;
  156. /**
  157. * resume wakeup source
  158. *
  159. * Resume wakeup source depends on platform. They should be defined in
  160. * \p hal_chip.h. One bit indicates one source, and multiple sources are
  161. * possible. \p OSI_RESUME_ABORT is reserved to indicate suspend is
  162. * aborted.
  163. */
  164. typedef enum osiResumeSource
  165. {
  166. OSI_RESUME_ABORT = (1 << 31), ///< resume by suspend aborted
  167. } osiResumeSource_t;
  168. /**
  169. * \brief boot cause
  170. *
  171. * This list is for cold boot cause. Though it is rare, it is possible
  172. * there exist multiple boot causes simultanuously.
  173. *
  174. * Usually boot cause is determined from hardware status registers.
  175. */
  176. typedef enum osiBootCause
  177. {
  178. OSI_BOOTCAUSE_UNKNOWN = 0, ///< placeholder for unknown reason
  179. OSI_BOOTCAUSE_PWRKEY = (1 << 0), ///< boot by power key
  180. OSI_BOOTCAUSE_PIN_RESET = (1 << 1), ///< boot by pin reset
  181. OSI_BOOTCAUSE_ALARM = (1 << 2), ///< boot by alarm
  182. OSI_BOOTCAUSE_CHARGE = (1 << 3), ///< boot by charge in
  183. OSI_BOOTCAUSE_WDG = (1 << 4), ///< boot by watchdog
  184. OSI_BOOTCAUSE_PIN_WAKEUP = (1 << 5), ///< boot by gpio wakeup
  185. OSI_BOOTCAUSE_SMPL_WAKEUP = (1 << 6), ///< boot from SMPL
  186. OSI_BOOTCAUSE_GPT_WAKEUP = (1 << 7), ///< boot from GPT
  187. OSI_BOOTCAUSE_WDG_IN_PSM = (1 << 8), ///< boot by watchdog rst
  188. OSI_BOOTCAUSE_PANIC = (1 << 9), ///< boot by panic reset
  189. OSI_BOOTCAUSE_PM2BOOT = (1 << 10), ///< boot from PM2 cold boot
  190. } osiBootCause_t;
  191. /**
  192. * boot mode
  193. *
  194. * Besides normal boot, there are several other boot modes. For each
  195. * platform, not all boot modes are supported.
  196. *
  197. * Usually, boot mode can be determined by hardware (for example, some
  198. * GPIO) or software (for example, by flags written at \p osiShutdown).
  199. */
  200. typedef enum osiBootMode
  201. {
  202. OSI_BOOTMODE_NORMAL = 0, ///< normal boot
  203. OSI_BOOTMODE_DOWNLOAD = 0x444e, ///< 'DN' boot to download mode
  204. OSI_BOOTMODE_CALIB = 0x434c, ///< 'CL' boot to calibration mode
  205. OSI_BOOTMODE_CALIB_POST = 0x4350, ///< 'CP' boot to calibration post mode
  206. OSI_BOOTMODE_NB_CALIB = 0x4e43, ///< 'NC' boot to NB calibration mode
  207. OSI_BOOTMODE_BBAT = 0x4241, ///< 'BA' boot to BBAT mode
  208. OSI_BOOTMODE_UPGRADE = 0x4654, ///< 'FT' boot to bootloader upgrade
  209. OSI_BOOTMODE_PSM_RESTORE = 0x5053, ///< 'PS' boot to PSM restore
  210. OSI_SHUTDOWN_OPENCPU_PM2_RESTORE = 0x6045, ///< 'OPM' boot to opencpu PSM restore
  211. OSI_BOOTMODE_OPENCPU_PSM_RESTORE = 0x6056, ///< 'OPS' boot to opencpu PSM restore
  212. } osiBootMode_t;
  213. /**
  214. * shudown mode
  215. *
  216. * For each platform, not all shutdown modes are supported.
  217. *
  218. * \p OSI_SHUTDOWN_PANIC is a special case. Though it is a *shutdown mode*,
  219. * it will appear as \p OSI_BOOTCAUSE_PANIC after reset.
  220. *
  221. * \p OSI_SHUTDOWN_PSM_PM2BOOT is a special case. The bootmode will be
  222. * \p OSI_BOOTMODE_PSM_RESTORE and there is cause \p OSI_BOOTCAUSE_PM2BOOT.
  223. */
  224. typedef enum osiShutdownMode
  225. {
  226. OSI_SHUTDOWN_RESET = 0, ///< normal reset
  227. OSI_SHUTDOWN_FORCE_DOWNLOAD = 0x5244, ///< 'RD' reset to force download mode
  228. OSI_SHUTDOWN_DOWNLOAD = 0x444e, ///< 'DN' reset to download mode
  229. OSI_SHUTDOWN_BL_DOWNLOAD = 0x4244, ///< 'BD' reset to bootloader download mode
  230. OSI_SHUTDOWN_CALIB_MODE = 0x434c, ///< 'CL' reset to calibration mode
  231. OSI_SHUTDOWN_NB_CALIB_MODE = 0x4e43, ///< 'NC' reset to NB calibration mode
  232. OSI_SHUTDOWN_BBAT_MODE = 0x4241, ///< 'BA' reset to BBAT mode
  233. OSI_SHUTDOWN_UPGRADE = 0x4654, ///< 'FT' reset to upgrade mode
  234. OSI_SHUTDOWN_POWER_OFF = 0x4f46, ///< 'OF' power off
  235. OSI_SHUTDOWN_PSM_SLEEP = 0x5053, ///< 'PS' power saving mode
  236. OSI_SHUTDOWN_PSM_PM2BOOT = 0x5042, ///< 'PB' power saving mode with PM2
  237. OSI_SHUTDOWN_PANIC = 0x504e, ///< 'PN' panic reset
  238. OSI_SHUTDOWN_OPENCPU_PM2_SLEEP = 0x6045, ///< 'OPM' opencpu power mode 2
  239. OSI_SHUTDOWN_OPENCPU_PSM_SLEEP = 0x6056, ///< 'OPS' opencpu power saving mode
  240. OSI_SHUTDOWN_OPENCPU_SWITCH = 0x5357, ///< 'SW' opencpu switch system
  241. OSI_SHUTDOWN_CANCEL = 0xffff, ///< special value for shutdown callback
  242. } osiShutdownMode_t;
  243. /**
  244. * PSM data owner
  245. */
  246. typedef enum osiPsmDataOwner
  247. {
  248. OSI_PSMDATA_OWNER_KERNEL, ///< kernel
  249. OSI_PSMDATA_OWNER_STACK, ///< stack
  250. OSI_PSMDATA_OWNER_AT, ///< AT engine
  251. OSI_PSMDATA_OWNER_CFW, ///< CFW
  252. OSI_PSMDATA_OWNER_NBTIMER, ///< NBIOT timers
  253. OSI_PSMDATA_OWNER_NBSDB, ///< NBIOT sdb
  254. OSI_PSMDATA_OWNER_NBLPS, ///< NBIOT LPS
  255. OSI_PSMDATA_OWNER_LWIP, ///< LWIP
  256. OSI_PSMDATA_OWNER_USER = 100, ///< start owner for user application
  257. } osiPsmDataOwner_t;
  258. /**
  259. * shuwdown callback function type
  260. *
  261. * Before shutdown, the registered callbacks will be invokes. The callbacks
  262. * are executed in system high priority work queue, and with interrupt
  263. * disabled. So, the callbacks shouldn't rely on system high priority work
  264. * queue and interrupts. However, thread schedule is still working and
  265. * multi-thread can work still.
  266. */
  267. typedef void (*osiShutdownCallback_t)(void *ctx, osiShutdownMode_t mode);
  268. /**
  269. * invoke global constructors
  270. *
  271. * Global constructors are not called during boot. Rather, they will be called
  272. * in \p osiInvokeGlobalCtors, and it shall be called in \p osiAppStart.
  273. *
  274. * At \p osiAppStart, RTOS is ready. So, it is permitted to call more OSI
  275. * APIs at global constructors.
  276. *
  277. * Though global constructors are supported. It is not encouraged to use this
  278. * feature. Only use this feature when you really know what you are doing.
  279. */
  280. void osiInvokeGlobalCtors(void);
  281. /**
  282. * kernel start
  283. *
  284. * Start the kernel. This API will create system threads (at least,
  285. * idle thread) and start thread scheduler. So, it won't return.
  286. *
  287. * Before \p osiKernelStart is called, kernel data structure may be
  288. * uninitialized, and many osi APIs can be called. Including
  289. *
  290. * - timer
  291. * - IRQ
  292. * - power management
  293. */
  294. OSI_NO_RETURN void osiKernelStart(void);
  295. /**
  296. * suspend thread scheduler
  297. *
  298. * After scheduler is suspended, there are no thread context switch.
  299. * However, interrupt handlers will be executed.
  300. *
  301. * The meaning of return flag depends on underlay RTOS. Don't assume the
  302. * meaning of the return value.
  303. *
  304. * \return scheduler suspend flag.
  305. */
  306. uint32_t osiSchedulerSuspend(void);
  307. /**
  308. * resume thread scheduler
  309. *
  310. * Scheduler suspend and resume is not *recursive*. That is, after
  311. * \p osiSchedulerResume is called, scheduler is resumed no matter
  312. * how many times \p osiSchedulerSuspend are called.
  313. *
  314. * \param [in] flag scheduler suspend flag returned by the latest
  315. * \p osiSchedulerSuspend
  316. */
  317. void osiSchedulerResume(uint32_t flag);
  318. /**
  319. * \brief enter critical section
  320. *
  321. * The underlay RTOS may have different implementation for critical
  322. * section. It may manipulate CPU IRQ enable bit(s), or manipulate
  323. * IRQ mask.
  324. *
  325. * This can be called in ISR.
  326. *
  327. * \return critical section flags
  328. */
  329. uint32_t osiEnterCritical(void);
  330. /**
  331. * \brief exit critical section
  332. *
  333. * Critical section flags is implementation depend. It should be the value
  334. * returned by \p osiEnterCritical, and don't change the value manually.
  335. *
  336. * Critical section is *recursive*. That is, after \p osiExitCritical is
  337. * called, it doesn't mean system will enter *unprotected* state. Rather,
  338. * it will return to state before last call of \p osiEnterCritical.
  339. * For example:
  340. *
  341. * \code{.cpp}
  342. * uint32_t critical1 = osiEnterCritical();
  343. * uint32_t critical2 = osiEnterCritical();
  344. * // ...
  345. * osiExitCritical(critical2);
  346. * osiExitCritical(critical1);
  347. * \endcode
  348. *
  349. * After the first call of \p osiExitCritical, system is in *protected*
  350. * state still.
  351. *
  352. * In recursive, the exit order must be the reverse order of enter. For
  353. * example, the following codes are wrong:
  354. *
  355. * \code{.cpp}
  356. * uint32_t critical1 = osiEnterCritical();
  357. * uint32_t critical2 = osiEnterCritical();
  358. * // ...
  359. * osiExitCritical(critical1);
  360. * osiExitCritical(critical2);
  361. * \endcode
  362. *
  363. * This can be called in ISR.
  364. *
  365. * \param critical critical section flags
  366. */
  367. void osiExitCritical(uint32_t critical);
  368. /**
  369. * \brief get IRQ flags and disable IRQ
  370. *
  371. * This will always manipulate CPU IRQ enable bit(s).
  372. *
  373. * After this call, \p osiEnterCritical can't be called. When
  374. * \p osiEnterCritical manipulates IRQ mask, it is very possible that
  375. * it will change CPU IRQ enable bit(s) without protection.
  376. *
  377. * In most cases, \p osiIrqSave and \p osiIrqRestore shouldn't be
  378. * used, unless you really know what you are doing.
  379. *
  380. * \return IRQ flags before disable IRQ
  381. */
  382. uint32_t osiIrqSave(void);
  383. /**
  384. * \brief restore IRQ flags
  385. *
  386. * IRQ flags is arch and implementation depend. It should be the value
  387. * returned by \p osiIrqSave, and don't change the value manually.
  388. *
  389. * \param flags IRQ flags
  390. */
  391. void osiIrqRestore(uint32_t flags);
  392. /**
  393. * set interrupt handler
  394. *
  395. * When interrupt arrived, the registered handler will be called with
  396. * the registered context pointer.
  397. *
  398. * For each interrupt, only one handler can be registered. When a handler
  399. * is already registered for an interrupt, \p osiIrqSetHandler will
  400. * replace the old one.
  401. *
  402. * \p irqn depends on interrupt controller in system. When GIC is used,
  403. * it is the number in GIC.
  404. *
  405. * \param irqn IRQ number
  406. * \param handler IRQ handler
  407. * \param ctx IRQ handler context pointer
  408. * \return
  409. * - true on success
  410. * - false on invalid parameters
  411. */
  412. bool osiIrqSetHandler(uint32_t irqn, osiIrqHandler_t handler, void *ctx);
  413. /**
  414. * enable interrupt
  415. *
  416. * \param irqn IRQ number
  417. * \return
  418. * - true on success
  419. * - false on invalid parameters
  420. */
  421. bool osiIrqEnable(uint32_t irqn);
  422. /**
  423. * disable interrupt
  424. *
  425. * \param irqn IRQ number
  426. * \return
  427. * - true on success
  428. * - false on invalid parameters
  429. */
  430. bool osiIrqDisable(uint32_t irqn);
  431. /**
  432. * whether interrupt is enabled
  433. *
  434. * \param irqn IRQ number
  435. * \return
  436. * - true if interrupt is enabled
  437. * - false if interrupt is disabled
  438. */
  439. bool osiIrqEnabled(uint32_t irqn);
  440. /**
  441. * set interrupt priority
  442. *
  443. * \p priority depends on interrupt controller used on system. When GIC
  444. * is used, \p priority should follow GIC requirement and meaning.
  445. *
  446. * \param irqn IRQ number
  447. * \param priority IRQ priority
  448. * \return
  449. * - true on success
  450. * - false on invalid parameters
  451. */
  452. bool osiIrqSetPriority(uint32_t irqn, uint32_t priority);
  453. /**
  454. * get interrupt priority
  455. *
  456. * When \p irqn is invalid, 0x80000000U will be returned.
  457. *
  458. * \param irqn IRQ number
  459. * \return IRQ priority
  460. */
  461. uint32_t osiIrqGetPriority(uint32_t irqn);
  462. /**
  463. * set interrupt group
  464. *
  465. * This is only valid when GIC is used.
  466. *
  467. * \param irqn IRQ number
  468. * \param group GIC group
  469. * \return
  470. * - true on success
  471. * - false on invalid parameters
  472. */
  473. bool osiIrqSetGroup(uint32_t irqn, uint32_t group);
  474. /**
  475. * check whether there are pending interrupt
  476. *
  477. * This is for special purpose. It shall be called with interrupt disabled
  478. * (not masked off).
  479. *
  480. * This may be unimplemented in some chips.
  481. *
  482. * \return
  483. * - true if there are interrupt pending.
  484. */
  485. bool osiIrqPending(void);
  486. /**
  487. * enable D-cache
  488. *
  489. * Usually, it shouldn't be called in application. It will only be called
  490. * once in boot code.
  491. *
  492. * Not all platforms implement this API.
  493. */
  494. void osiDCacheEnable(void);
  495. /**
  496. * disable D-cache
  497. *
  498. * Usually, it shouldn't be called in application. And most likely it will
  499. * never be called. It is provided for completeness.
  500. *
  501. * Not all platforms implement this API.
  502. */
  503. void osiDCacheDisable(void);
  504. /**
  505. * enable I-cache
  506. *
  507. * Usually, it shouldn't be called in application. It will only be called
  508. * once in boot code.
  509. *
  510. * Not all platforms implement this API.
  511. */
  512. void osiICacheEnable(void);
  513. /**
  514. * disable I-cache
  515. *
  516. * Usually, it shouldn't be called in application. And most likely it will
  517. * never be called. It is provided for completeness.
  518. *
  519. * Not all platforms implement this API.
  520. */
  521. void osiICacheDisable(void);
  522. /**
  523. * clean (write back) D-cache
  524. *
  525. * Usually it shall be called **before** the cachable memory will be read by
  526. * not cache coherent hardware.
  527. *
  528. * D-cache clean will operate by cache line. So, is the memory range is
  529. * not cache line aligned, other memory on the cache line will be cleaned
  530. * also. For example, assuming D-cache line size is 32 byte,
  531. * \p osiDCacheClean((void *)8, 32) will clean [0-8], [40-64] also.
  532. *
  533. * When D-cache coherence is needed to be considered, it is recommended to
  534. * declare or allocate memory by the following:
  535. *
  536. * \code{.cpp}
  537. * char mem1[SIZE] OSI_CACHE_LINE_ALIGNED;
  538. * void *mem2 = memalign(CONFIG_CACHE_LINE_SIZE, size);
  539. * \endcode
  540. *
  541. * \param address starting address to be cleaned
  542. * \param size size to be cleaned
  543. */
  544. void osiDCacheClean(const void *address, size_t size);
  545. /**
  546. * invalidate D-cache
  547. *
  548. * Usually it shall be called **before** the cachable memory will be write by
  549. * not cache coherent hardware.
  550. *
  551. * D-cache line alignment is very important for \p osiDCacheInvalidate.
  552. * Otherwise, other memory on the cache line will be changed randomly.
  553. *
  554. * \param address starting address to be cleaned
  555. * \param size size to be cleaned
  556. */
  557. void osiDCacheInvalidate(const void *address, size_t size);
  558. /**
  559. * clean and invalidate D-cache
  560. *
  561. * \param address starting address to be cleaned
  562. * \param size size to be cleaned
  563. */
  564. void osiDCacheCleanInvalidate(const void *address, size_t size);
  565. /**
  566. * invalidate D-cache range
  567. *
  568. * \param address starting address to be cleaned
  569. * \param size size to be cleaned
  570. */
  571. void osiICacheInvalidate(const void *address, size_t size);
  572. /**
  573. * sync D-cahce with I-cache
  574. *
  575. * It shall be called after code memory is operated as data (such as,
  576. * copy codes from flash to RAM).
  577. *
  578. * \param address starting address to be cleaned
  579. * \param size size to be cleaned
  580. */
  581. void osiICacheSync(const void *address, size_t size);
  582. /**
  583. * clean all D-cache
  584. */
  585. void osiDCacheCleanAll(void);
  586. /**
  587. * invalidate all D-cache
  588. */
  589. void osiDCacheInvalidateAll(void);
  590. /**
  591. * clean and invalidate all D-cache
  592. */
  593. void osiDCacheCleanInvalidateAll(void);
  594. /**
  595. * invalidate all I-cache
  596. */
  597. void osiICacheInvalidateAll(void);
  598. /**
  599. * sync D-cahce with I-cache for all
  600. */
  601. void osiICacheSyncAll(void);
  602. /**
  603. * create a thread
  604. *
  605. * Each \p osiThread_t will have an event queue. So, the event queue
  606. * depth should be specified at creation.
  607. *
  608. * \p name will be copied to thread control block. So, \p name can be dynamic
  609. * memory.
  610. *
  611. * After a thread is created, it will be executed immediately. So, it is
  612. * possible that \p entry will be executed before the return value is
  613. * assigned to some variable, if the new thread priority is higher than
  614. * current thread priority. Pay attention to use thread pointer in
  615. * \p entry.
  616. *
  617. * \code{.cpp}
  618. * void entry(void *argument) {
  619. * osiThread_t *thread = osiThreadCurrent();
  620. * for (;;) {
  621. * osiEvent_t event = {};
  622. * osiEventWait(thread, &event);
  623. * ......
  624. * }
  625. * }
  626. * \endcode
  627. *
  628. * In some underlay RTOS, there are limitation on maximum stack size.
  629. * For example, when \p configSTACK_DEPTH_TYPE is defined as \p uint16_t,
  630. * the stack size must be less than 64KB*4.
  631. *
  632. * \param name thread name
  633. * \param entry thread entry function
  634. * \param argument thread entry function argument
  635. * \param priority thread priority
  636. * \param stack_size thread stack size in byte
  637. * \param event_count thread event queue depth (count of events can be hold)
  638. * \return
  639. * - thread pointer
  640. * - NULL if failed
  641. */
  642. osiThread_t *osiThreadCreate(const char *name, osiThreadEntry_t entry, void *argument,
  643. uint32_t priority, uint32_t stack_size,
  644. uint32_t event_count);
  645. #ifdef CONFIG_QUEC_PROJECT_FEATURE
  646. /**
  647. * create a thread
  648. *
  649. * Each \p osiThread_t will have an event queue. So, the event queue
  650. * depth should be specified at creation.
  651. *
  652. * \p name will be copied to thread control block. So, \p name can be dynamic
  653. * memory.
  654. *
  655. * After a thread is created, it will be executed immediately. So, it is
  656. * possible that \p entry will be executed before the return value is
  657. * assigned to some variable, if the new thread priority is higher than
  658. * current thread priority. Pay attention to use thread pointer in
  659. * \p entry.
  660. *
  661. * \code{.cpp}
  662. * void entry(void *argument) {
  663. * osiThread_t *thread = osiThreadCurrent();
  664. * for (;;) {
  665. * osiEvent_t event = {};
  666. * osiEventWait(thread, &event);
  667. * ......
  668. * }
  669. * }
  670. * \endcode
  671. *
  672. * In some underlay RTOS, there are limitation on maximum stack size.
  673. * For example, when \p configSTACK_DEPTH_TYPE is defined as \p uint16_t,
  674. * the stack size must be less than 64KB*4.
  675. *
  676. * \param name thread name
  677. * \param entry thread entry function
  678. * \param argument thread entry function argument
  679. * \param priority thread priority
  680. * \param stack_size thread stack size in byte
  681. * \param event_count thread event queue depth (count of events can be hold)
  682. * \return
  683. * - thread pointer
  684. * - NULL if failed
  685. */
  686. osiThread_t *quec_osiThreadCreate(const char *name, osiThreadEntry_t entry, void *argument,
  687. uint32_t priority, uint32_t stack_size,
  688. uint32_t event_count);
  689. #endif
  690. /**
  691. * create a thread with specified stack
  692. *
  693. * It is similar to \p osiThreadCreate, and the stack won't be dynamic created.
  694. * Rather, the specified buffer \p stack will be used at the stack of the
  695. * thread. Typical usage is to create performance sensitive thread, and set stack
  696. * in SRAM to improve performance.
  697. *
  698. * Application should always use \p osiThreadCreate. It may be unimplemented on
  699. * some platforms.
  700. *
  701. * \param name thread name
  702. * \param entry thread entry function
  703. * \param argument thread entry function argument
  704. * \param priority thread priority
  705. * \param stack thread stack buffer, must be valid
  706. * \param stack_size thread stack size in byte
  707. * \param event_count thread event queue depth (count of events can be hold)
  708. * \return
  709. * - thread pointer
  710. * - NULL if failed
  711. */
  712. osiThread_t *osiThreadCreateWithStack(const char *name, osiThreadEntry_t entry, void *argument,
  713. uint32_t priority, void *stack, uint32_t stack_size,
  714. uint32_t event_count);
  715. /**
  716. * get event queue of thread
  717. *
  718. * When \p thread is NULL, return the event queue of current thread.
  719. *
  720. * \param thread thread pointer
  721. * \return event queue of the thread
  722. */
  723. osiEventQueue_t *osiThreadEventQueue(osiThread_t *thread);
  724. /**
  725. * get current thread pointer
  726. *
  727. * \return current thread pointer
  728. */
  729. osiThread_t *osiThreadCurrent(void);
  730. /**
  731. * set whether current thread need FPU
  732. *
  733. * Obsoleted. Floating point can be used in all threads, and ISR. This API
  734. * is just for compatible, and implemented as empty.
  735. *
  736. * \param enabled true for enable FPU, false for disable FPU.
  737. */
  738. void osiThreadSetFPUEnabled(bool enabled);
  739. /**
  740. * get thread priority
  741. *
  742. * When \p thread is NULL, return the priotity of current thread.
  743. *
  744. * \param thread thread pointer
  745. * \return priotity of the thread
  746. */
  747. uint32_t osiThreadPriority(osiThread_t *thread);
  748. /**
  749. * set thread priority
  750. *
  751. * When \p thread is NULL, set the priotity of current thread.
  752. *
  753. * After the priority changed, it is possible thread context switch
  754. * will occur. However, don't depend on this feature.
  755. *
  756. * \param thread thread pointer
  757. * \param priority priority to be set
  758. * \return
  759. * - true on success
  760. * - false on invalid parameter
  761. */
  762. bool osiThreadSetPriority(osiThread_t *thread, uint32_t priority);
  763. /**
  764. * suspend a thread
  765. *
  766. * When \p thread is NULL, suspend current thread.
  767. *
  768. * \param thread thread pointer
  769. */
  770. void osiThreadSuspend(osiThread_t *thread);
  771. /**
  772. * resume a thread
  773. *
  774. * \p thread can't be NULL.
  775. *
  776. * \param thread thread pointer
  777. */
  778. void osiThreadResume(osiThread_t *thread);
  779. /**
  780. * current thread yield
  781. *
  782. * When there are threads with the same priority, other threads will
  783. * be scheduled.
  784. */
  785. void osiThreadYield(void);
  786. /**
  787. * current thread sleep
  788. *
  789. * Change current thread into sleep mode, and will be rescheduled
  790. * after the specified period.
  791. *
  792. * This will use the underlay RTOS mechanism. It is possible the sleep
  793. * time precision is the tick of underlay RTOS.
  794. *
  795. * \param ms sleep time in milliseconds
  796. */
  797. void osiThreadSleep(uint32_t ms);
  798. /**
  799. * current thread sleep with high precision timer
  800. *
  801. * It won't use the underlay RTOS mechanism, rather it will use high
  802. * precision timer.
  803. *
  804. * It will be used when high precision sleep time is needed.
  805. *
  806. * \param us sleep time in microseconds
  807. */
  808. void osiThreadSleepUS(uint32_t us);
  809. /**
  810. * current thread sleep with relaxed timeout
  811. *
  812. * It is a power optimization version of \p osiThreadSleep. Due to power
  813. * saving, it is possible that current thread will be wakeup later then
  814. * *normal timeout*, but it will wakeup no later than *relaxed timeout*
  815. * even system will enter suspend.
  816. *
  817. * When \p relax_ms is \p OSI_DELAY_MAX, it means it can be ignored
  818. * completed for power saving. However, after system is awoken, the thread
  819. * will be wakeup still if the *normal timeout* is expired.
  820. *
  821. * \param ms sleep time in milliseconds
  822. * \param relax_ms relaxed sleep time in milliseconds
  823. */
  824. void osiThreadSleepRelaxed(uint32_t ms, uint32_t relax_ms);
  825. /**
  826. * thread stack unused space
  827. *
  828. * It needs underlay RTOS support. When the underlay RTOS doesn't support
  829. * this feature, it returns 0.
  830. *
  831. * The typical method to support this feature in underlay RTOS is to check
  832. * stack content, and comparing with preset magic byte or word.
  833. *
  834. * It is recommended to use it only for debug.
  835. *
  836. * \param thread thread pointer, NULL for current thread
  837. * \return
  838. * - thread stack unused space in bytes
  839. * - 0 if the underlay RTOS doesn't support this feature
  840. */
  841. uint32_t osiThreadStackUnused(osiThread_t *thread);
  842. /**
  843. * space from current stack pointer to current thread stack end
  844. *
  845. * When \p refill is true, the current stack space will be fill with magic
  846. * byte or word for measuring unused stack. When underlay RTOS doesn't
  847. * support feature to measure stack remain, \p refill will be ignored.
  848. *
  849. * It is recommended to use it only for debug.
  850. *
  851. * \return
  852. * - space to current thread stack end, in bytes
  853. */
  854. uint32_t osiThreadStackCurrentSpace(bool refill);
  855. /**
  856. * current thread exit
  857. *
  858. * When a thread is finished, \p osiThreadExit must be called. And
  859. * kernel will release thread resources at appropriate time.
  860. */
  861. OSI_NO_RETURN void osiThreadExit(void);
  862. /**
  863. * show thread information through trace
  864. *
  865. * It is for debug purpose only.
  866. */
  867. void osiShowThreadState(void);
  868. /**
  869. * send an event to a thread
  870. *
  871. * At send, the body of \p event will be copied to event queue
  872. * rather then send the pointer of \p event.
  873. *
  874. * When event queue of the target thread is full, the caller thread
  875. * will be block until there are rooms in target thread event queue.
  876. *
  877. * This can be called in ISR. And in ISR, it will return false when event
  878. * queue is full, and not wait.
  879. *
  880. * \param thread thread pointer, can't be NULL
  881. * \param event event to be sent
  882. * \return
  883. * - true on success
  884. * - false on invalid parameter
  885. */
  886. bool osiEventSend(osiThread_t *thread, const osiEvent_t *event);
  887. /**
  888. * send event loop quit event to a thread
  889. *
  890. * This is the normalized method to notify a thread to quit. When \p thread
  891. * is the current thread, \p wait can't be true.
  892. *
  893. * \code{.cpp}
  894. * // caller thread
  895. * osiSendQuitEvent(thread);
  896. *
  897. * // thread to quit
  898. * for (;;) {
  899. * osiEvent_t event = {};
  900. * osiEventWait(thread, &event);
  901. * if (event.id == OSI_EVENT_ID_QUIT)
  902. * break;
  903. *
  904. * // ......
  905. * }
  906. * osiThreadExit();
  907. * \endcode
  908. *
  909. * \param thread thread pointer, can't be NULL
  910. * \param wait whether to wait thread exit
  911. * \return
  912. * - true on success
  913. * - false on invalid parameter
  914. */
  915. bool osiSendQuitEvent(osiThread_t *thread, bool wait);
  916. /**
  917. * send an event to a thread with timeout
  918. *
  919. * When \p timeout is 0, this will return false immediately. When \p timeout
  920. * is \p OSI_WAIT_FOREVER, this will wait forever until there are
  921. * rooms in target thread event queue.
  922. *
  923. * This can be called in ISR. And in ISR, \p timeout will be ignored.
  924. *
  925. * \param thread thread pointer, can't be NULL
  926. * \param event event to be sent
  927. * \param timeout timeout in milliseconds
  928. * \return
  929. * - true on success
  930. * - false on invalid parameter, or timeout
  931. */
  932. bool osiEventTrySend(osiThread_t *thread, const osiEvent_t *event, uint32_t timeout);
  933. /**
  934. * wait an event
  935. *
  936. * Wait an event from current thread event queue. When current thread
  937. * event queue is empty, it will be blocked forever until there are
  938. * event in event queue.
  939. *
  940. * The event body will be copied to \p event.
  941. *
  942. * There are some event ID used by system. After system event is received
  943. * and process, this will return an event with ID of 0. Application can
  944. * ignore event ID 0 safely.
  945. *
  946. * It **can't** be called in ISR. And in ISR, it will return false directly.
  947. *
  948. * \param thread thread pointer, can't be NULL
  949. * \param event event pointer
  950. * \return
  951. * - true on success
  952. * - false on invalid parameter
  953. */
  954. bool osiEventWait(osiThread_t *thread, osiEvent_t *event);
  955. /**
  956. * wait an event with timeout
  957. *
  958. * When \p timeout is 0, this will return false immediately. When \p timeout
  959. * is \p OSI_WAIT_FOREVER, this will wait forever until there are
  960. * events in target thread event queue.
  961. *
  962. * It **can't** be called in ISR. And in ISR, it will return false directly.
  963. *
  964. * \param thread thread pointer, can't be NULL
  965. * \param event event pointer
  966. * \param timeout timeout in milliseconds
  967. * \return
  968. * - true on success
  969. * - false on invalid parameter, or timeout
  970. */
  971. bool osiEventTryWait(osiThread_t *thread, osiEvent_t *event, uint32_t timeout);
  972. /**
  973. * whether there are pending event in event queue
  974. *
  975. * It can be called in both thread context and ISR context.
  976. *
  977. * \param thread thread pointer, can't be NULL
  978. * \return
  979. * - true if there are pending event
  980. * - false if not
  981. */
  982. bool osiEventPending(osiThread_t *thread);
  983. /**
  984. * get the pending event count in event queue
  985. *
  986. * It can be called in both thread context and ISR context.
  987. *
  988. * \param thread thread pointer, can't be NULL
  989. * \return
  990. * - the pending event count in event queue
  991. * - 0 on invalid parameter
  992. */
  993. uint32_t osiEventPendingCount(osiThread_t *thread);
  994. /**
  995. * get the space of event count in event queue
  996. *
  997. * It can be called in both thread context and ISR context.
  998. *
  999. * \param thread thread pointer, can't be NULL
  1000. * \return
  1001. * - the space of event count in event queue
  1002. * - 0 on invalid parameter
  1003. */
  1004. uint32_t osiEventSpaceCount(osiThread_t *thread);
  1005. /**
  1006. * set callback to be executed on thread
  1007. *
  1008. * Thread callback is implemented by \p osiEvent_t.
  1009. *
  1010. * This can be called in ISR. In ISR, the callback event will be lost when
  1011. * the event queue of target thread is full.
  1012. *
  1013. * \param thread thread pointer, can't be NULL
  1014. * \param cb callback to be executed
  1015. * \param cb_ctx callback context
  1016. * \return
  1017. * - true on success
  1018. * - false on invalid parameter, or event queue is full in ISR
  1019. */
  1020. bool osiThreadCallback(osiThread_t *thread, osiCallback_t cb, void *cb_ctx);
  1021. /**
  1022. * \brief create a work
  1023. *
  1024. * \p run can't be NULL, and \p complete can be NULL.
  1025. *
  1026. * \param run execute function of the work
  1027. * \param complete callback to be invoked after the work is finished
  1028. * \param ctx context of \p run and \p complete
  1029. * \return
  1030. * - the created work
  1031. * - NULL if invalid parameter or out of memory
  1032. */
  1033. osiWork_t *osiWorkCreate(osiCallback_t run, osiCallback_t complete, void *ctx);
  1034. /**
  1035. * \brief delete the work
  1036. *
  1037. * When \p work is running when it is called, it will be deleted after the
  1038. * current run finished.
  1039. *
  1040. * \param work the work to be deleted
  1041. */
  1042. void osiWorkDelete(osiWork_t *work);
  1043. /**
  1044. * \brief reset callback of existed work
  1045. *
  1046. * This can change the callbacks of existed work. It can be used to setup
  1047. * a kind of *work flow*. An example:
  1048. *
  1049. * \code{.cpp}
  1050. * static void prvPrepare(void *param) {
  1051. * // ....
  1052. * osiWorkResetCallback(work, prvRealJob, NULL, ctx);
  1053. * }
  1054. *
  1055. * static void prvRealJob(void *param) {
  1056. * // ...
  1057. * }
  1058. *
  1059. * void init(void) {
  1060. * work = osiWorkCreate(prvPrepare, NULL, ctx);
  1061. * osiWorkEnqueue(work, wa);
  1062. * }
  1063. * \endcode
  1064. *
  1065. * This is clearer than creating multiple work instances.
  1066. *
  1067. * Though it is not typical application, the callbacks can be changed when
  1068. * the work is already queued. In this case, there may exist corner cases
  1069. * about whether the previous or the new callbacks will be invoked, depends
  1070. * on thread priorities. Caller should take care about this.
  1071. *
  1072. * When it is called inside work callback, the new callbacks will be invoked
  1073. * at the next timer when work is invoked.
  1074. *
  1075. * \param work the work pointer, must be valid
  1076. * \param run execute function of the work
  1077. * \param complete callback to be invoked after the work is finished
  1078. * \param ctx context of \p run and \p complete
  1079. * \return
  1080. * - true on success
  1081. * - false on fail, invalid parameters
  1082. */
  1083. bool osiWorkResetCallback(osiWork_t *work, osiCallback_t run, osiCallback_t complete, void *ctx);
  1084. /**
  1085. * \brief enqueue a work in specified work queue
  1086. *
  1087. * When \p work is running, it will be queued to \p wq again and then it
  1088. * will be invoked again.
  1089. *
  1090. * When \p work is queued, and \p wq is the same as original work queue,
  1091. * nothing will be done. When \p wq is not the same as the original
  1092. * work queue, it will be removed from the original work queue, and
  1093. * queue the work into the specified work queue.
  1094. *
  1095. * This can be called in ISR.
  1096. *
  1097. * \param work the work pointer, must be valid
  1098. * \param wq work queue to run the work, must be valid
  1099. * \return
  1100. * - true on success
  1101. * - false for invalid parameter, or work is running
  1102. */
  1103. bool osiWorkEnqueue(osiWork_t *work, osiWorkQueue_t *wq);
  1104. /**
  1105. * \brief enqueue a work in the last of specified work queue
  1106. *
  1107. * It is similar to \p osiWorkEnqueue, except it will consider work order.
  1108. * For example:
  1109. *
  1110. * \code{.cpp}
  1111. * osiWorkEnqueue(work1, wq);
  1112. * osiWorkEnqueue(work2, wq);
  1113. * osiWorkEnqueue(work1, wq);
  1114. * \endcode
  1115. *
  1116. * If work queue is busy on another work during these calls, and when work
  1117. * queue processing these works, it will:
  1118. * - execute work1->callback
  1119. * - execute work2->callback
  1120. *
  1121. * So, even the order of works aren't preserved. \p work1 is the last queued
  1122. * work, and the real last executed work is \p work2.
  1123. *
  1124. * With \p osiWorkEnqueueLast, it will ensure that the last queued work will
  1125. * be executed at the last.
  1126. *
  1127. * \param work the work pointer, must be valid
  1128. * \param wq work queue to run the work, must be valid
  1129. * \return
  1130. * - true on success
  1131. * - false for invalid parameter, or work is running
  1132. */
  1133. bool osiWorkEnqueueLast(osiWork_t *work, osiWorkQueue_t *wq);
  1134. /**
  1135. * \brief cancel a work
  1136. *
  1137. * When \p work is running, the current execution won't be interrupted.
  1138. *
  1139. * \param work the work pointer, must be valid
  1140. */
  1141. void osiWorkCancel(osiWork_t *work);
  1142. /**
  1143. * \brief wait a work finish
  1144. *
  1145. * When \p work is running or enqued, this will wait the work finish.
  1146. * When \p timeout is 0, it will return immediately. When \p timeout
  1147. * is \p OSI_WAIT_FOREVER, it will wait infinitely until the work is
  1148. * finished.
  1149. *
  1150. * \param work the work pointer, must be valid
  1151. * \param timeout wait timeout
  1152. * \return
  1153. * - true if the work is finished
  1154. * - false on invalid parameter, or wait timeout
  1155. */
  1156. bool osiWorkWaitFinish(osiWork_t *work, unsigned timeout);
  1157. /**
  1158. * \brief create work queue
  1159. *
  1160. * Multiple threads can be created to reduce work execution latency. For
  1161. * example, when one thread in a work queue is blocked, other threads of
  1162. * the work queue can execute other works queued to the work queue.
  1163. *
  1164. * The maximum thread count is implementation dependent. So, it is possible
  1165. * that the created thread count is less than \p thread_count. And also it is
  1166. * possible that \p thread_count is ignored.
  1167. *
  1168. * The created threads have the same priority and stack size.
  1169. *
  1170. * The work queue thread entry function can't be customized
  1171. *
  1172. * \param name work queue name
  1173. * \param thread_count thread count to be created for the work queue
  1174. * \param priority work queue thread priority
  1175. * \param stack_size thread stack size in byte
  1176. * \return
  1177. * - the work queue pointer
  1178. * - NULL if failed
  1179. */
  1180. osiWorkQueue_t *osiWorkQueueCreate(const char *name, size_t thread_count, uint32_t priority, uint32_t stack_size);
  1181. /**
  1182. * \brief delete work queue
  1183. *
  1184. * All resources of the work queue will be deleted.
  1185. *
  1186. * The works in running will continue, and \p complete will be invoked as
  1187. * normal. However, queued work in the work queue won't be executed any more.
  1188. *
  1189. * \param wq work queue to be deleted
  1190. */
  1191. void osiWorkQueueDelete(osiWorkQueue_t *wq);
  1192. /**
  1193. * \brief get the system high priority work queue
  1194. *
  1195. * A work queue with priority \p OSI_PRIORITY_HIGH will be created at kernel
  1196. * start.
  1197. *
  1198. * \return the system high priority work queue
  1199. */
  1200. osiWorkQueue_t *osiSysWorkQueueHighPriority(void);
  1201. /**
  1202. * \brief get the system low priority work queue
  1203. *
  1204. * A work queue with priority \p OSI_PRIORITY_LOW will be created at kernel
  1205. * start.
  1206. *
  1207. * \return the system low priority work queue
  1208. */
  1209. osiWorkQueue_t *osiSysWorkQueueLowPriority(void);
  1210. /**
  1211. * \brief get the system work queue for asynchronuous file system write
  1212. *
  1213. * A work queue with priority \p OSI_PRIORITY_BELOW_NORMAL will be created
  1214. * at kernel start. This work queue shall be used for asynchronuous file
  1215. * system write.
  1216. *
  1217. * Usually file write is slow, especially for file system on NOR flash.
  1218. * When faster response is needed, file write can be deferred to this
  1219. * work queue. Also, the work queue will be flushed before system shutdown.
  1220. *
  1221. * \return the system file write work queue
  1222. */
  1223. osiWorkQueue_t *osiSysWorkQueueFileWrite(void);
  1224. /**
  1225. * \brief create a thread notify
  1226. *
  1227. * Thread notify is thread callback with state to avoid duplicated event
  1228. * to be sent to thread event queue.
  1229. *
  1230. * \param thread thread to execute the callback, can't be NULL
  1231. * \param cb callback to be executed, can't be NULL
  1232. * \param ctx callback context
  1233. * \return
  1234. * - created notify
  1235. * - NULL if parameters are invalid or out of memory
  1236. */
  1237. osiNotify_t *osiNotifyCreate(osiThread_t *thread, osiCallback_t cb, void *ctx);
  1238. /**
  1239. * \brief delete a thread notify
  1240. *
  1241. * The memory of the thread notify will be released.
  1242. *
  1243. * When the thread notify is already in thread event queue, the callback
  1244. * won't be invoked, and the memory may be released delayed.
  1245. *
  1246. * \param notify thread notify pointer, must be valid
  1247. */
  1248. void osiNotifyDelete(osiNotify_t *notify);
  1249. /**
  1250. * \brief trigger a thread notify
  1251. *
  1252. * When the thread notify event isn't in thread event queue, an event for
  1253. * thread notify will be queued to the tail of thread event queue.
  1254. *
  1255. * \param notify thread notify pointer, must be valid
  1256. */
  1257. void osiNotifyTrigger(osiNotify_t *notify);
  1258. /**
  1259. * \brief cancel a thread notify
  1260. *
  1261. * When the thread notify event has already sent to thread event queue,
  1262. * the invocation of the callback will be cancelled.
  1263. *
  1264. * \param notify thread notify pointer, must be valid
  1265. */
  1266. void osiNotifyCancel(osiNotify_t *notify);
  1267. /**
  1268. * \brief create a timer
  1269. *
  1270. * Create a timer with specified callback and callback context. After create,
  1271. * the timer is in stop state. Application can start it in various mode.
  1272. *
  1273. * When \p thread is \p OSI_TIMER_IN_ISR, the callback will be executed in
  1274. * timer ISR. So, the callback should follow ISR programming guide. This is
  1275. * **not** recommended unless it is absolutely needed.
  1276. *
  1277. * When \p thread is \p OSI_TIMER_IN_SERVICE, the callback will be executed
  1278. * in timer service thread.
  1279. *
  1280. * Otherwise, the callback will be executed in the specified thread through
  1281. * *event* mechanism.
  1282. *
  1283. * It is needed to call \p osiTimerDelete to free resources.
  1284. *
  1285. * \param thread thread to execute the callback
  1286. * \param cb callback to be executed after timer expire
  1287. * \param ctx callback context
  1288. * \return
  1289. * - the created timer instance
  1290. * - NULL at out of memory, or invalid parameter
  1291. */
  1292. osiTimer_t *osiTimerCreate(osiThread_t *thread, osiCallback_t cb, void *ctx);
  1293. /**
  1294. * \brief create a timer, enqueue a work on expiration
  1295. *
  1296. * Create a timer with specified callback and callback context. After create,
  1297. * the timer is in stop state. Application can start it in various mode.
  1298. *
  1299. * At expiration, \p work will be enqueued to \p wq.
  1300. *
  1301. * It is needed to call \p osiTimerDelete to free resources.
  1302. *
  1303. * \param work work to be enqueued at expiration
  1304. * \param wq work queue to be enqueued at expiration
  1305. * \return
  1306. * - the created timer instance
  1307. * - NULL at out of memory, or invalid parameter
  1308. */
  1309. osiTimer_t *osiTimerCreateWork(osiWork_t *work, osiWorkQueue_t *wq);
  1310. /**
  1311. * \brief create a timer, EV_TIMER on expiration
  1312. *
  1313. * This is for legacy codes only. **Don't** use it except at porting
  1314. * legacy codes.
  1315. *
  1316. * Create a timer with specified timerid. After the timer expired, the
  1317. * specified thread will receive an event { EV_TIMER, timerid, 0, 0}.
  1318. *
  1319. * It is needed to call \p osiTimerDelete to free resources.
  1320. *
  1321. * \param thread thread to execute the callback, it can't be NULL
  1322. * \param timerid timerid in expiration event
  1323. * \return
  1324. * - the created timer instance
  1325. * - NULL at out of memory, or invalid parameter
  1326. */
  1327. osiTimer_t *osiTimerEventCreate(osiThread_t *thread, uint32_t timerid);
  1328. /**
  1329. * \brief set/change callback of timer
  1330. *
  1331. * In most cases, timer callback set at create is not needed to be changed.
  1332. *
  1333. * \p timer should be created by \p osiTimerCreate. Special values of
  1334. * \p thread follow \p osiTimerCreate.
  1335. *
  1336. * It is permitted to change \p thread of timer, including special values.
  1337. * For example, it is permitted to change a timer executing in timer service
  1338. * to timer executing in specified thread. However, it is not recommended.
  1339. *
  1340. * This can only be called when \p timer is stopped. Otherwise, it will
  1341. * return false.
  1342. *
  1343. * \param timer timer to be changed
  1344. * \param thread thread to execute the callback
  1345. * \param cb callback to be executed after timer expire
  1346. * \param ctx callback context
  1347. * \return
  1348. * - true on success
  1349. * - false on invalid parameter
  1350. */
  1351. bool osiTimerSetCallback(osiTimer_t *timer, osiThread_t *thread, osiCallback_t cb, void *ctx);
  1352. /**
  1353. * \brief set/change work and work queue of timer
  1354. *
  1355. * In most cases, timer work and work queue set at create is not needed to be changed.
  1356. *
  1357. * \p timer should be created by \p osiTimerCreateWork, to enqueue work to work
  1358. * queue at expiration.
  1359. *
  1360. * \param timer timer to be changed
  1361. * \param work work to be enqueued at expiration
  1362. * \param wq work queue to be enqueued at expiration
  1363. * \return
  1364. * - true on success
  1365. * - false on invalid parameter
  1366. */
  1367. bool osiTimerSetWork(osiTimer_t *timer, osiWork_t *work, osiWorkQueue_t *wq);
  1368. /**
  1369. * \brief set/change timer event
  1370. *
  1371. * In most cases, timer thread and id set at create is not needed to be changed.
  1372. *
  1373. * \p timer should be created by \p osiTimerEventCreate.
  1374. *
  1375. * \param timer timer to be changed
  1376. * \param thread thread to execute the callback, it can't be NULL
  1377. * \param timerid timerid in expiration event
  1378. * \return
  1379. * - true on success
  1380. * - false on invalid parameter
  1381. */
  1382. bool osiTimerSetEvent(osiTimer_t *timer, osiThread_t *thread, uint32_t timerid);
  1383. /**
  1384. * \brief delete a timer
  1385. *
  1386. * Delete the timer, and free associated resources.
  1387. *
  1388. * When the timer callback will be executed in thread rather than ISR, and the
  1389. * event for timer expiration has been sent, some resources won't be freed
  1390. * immediately. Rather, they will be freed after the timer expiration event
  1391. * is popped out from thread event queue. However, the callback won't be
  1392. * executed even delete is delayed.
  1393. *
  1394. * Refer to document about corner case of timer thread callback.
  1395. *
  1396. * \param timer the timer to be deleted
  1397. */
  1398. void osiTimerDelete(osiTimer_t *timer);
  1399. /**
  1400. * \brief change timer relaxed timeout for running timer
  1401. *
  1402. * When the timer is not running, it will return false.
  1403. *
  1404. * When the timer is started, this will change the relaxed timeout
  1405. * specified at start.
  1406. *
  1407. * This can be called for both one shot timer and periodic timer.
  1408. *
  1409. * \p relaxed_ms is the additional time based on normal timeout. It will
  1410. * only be used for sleep. When \p relaxed_ms is 0, this timer will wakeup
  1411. * system even system enter sleep mode. When \p relaxed_ms is
  1412. * \p OSI_DELAY_MAX, this timer will not wakeup system when system enter
  1413. * sleep mode. Otherwise, system will process the timer no later than the
  1414. * normal timeout plus additional timeout.
  1415. *
  1416. * For example, when the period of a timer is 100ms, and relaxed timeout
  1417. * is 500ms, system will process the timer no later than 600ms. This can
  1418. * make system sleep more time, and reduce power consumption.
  1419. *
  1420. * For periodic timer, the additional timeout is add to normal timeout of
  1421. * earch run. For example, a periodic timer period is 100ms, and relaxed
  1422. * timeout is 50ms, then system will process the timer no later than 150ms.
  1423. * And even the timer is delayed to 150ms due to system sleep, the next
  1424. * timeout is 200ms unchanged. Another example, a periodic timer period
  1425. * is 100ms, and relaxed timeout is 500ms, then system will process the
  1426. * timer no later than 600ms. When the timer is delayed to 600ms due to
  1427. * system sleep, the callback will be invoked only once even 6 periods are
  1428. * elapsed. The next timeout is at 700ms.
  1429. *
  1430. * \param timer the timer to be set
  1431. * \param relaxed_ms relaxed timeout in milliseconds
  1432. * \return
  1433. * - true on success
  1434. * - false on invalid parameter, or timer is not running
  1435. */
  1436. bool osiTimerChangeRelaxed(osiTimer_t *timer, uint32_t relaxed_ms);
  1437. /**
  1438. * \brief set timer period for next call
  1439. *
  1440. * The properties will be used by next \p osiTimerStartLast. It can only be
  1441. * called when the timer is not running.
  1442. *
  1443. * It is the same as \p osiTimerSetPeriodRelaxed, with \p relaxed_ms
  1444. * as 0.
  1445. *
  1446. * \param timer the timer to be set
  1447. * \param ms period in milliseconds
  1448. * \param periodic true for periodic, false for one shot
  1449. * \return
  1450. * - true on success
  1451. * - false on invalid parameter, or timer is started
  1452. */
  1453. bool osiTimerSetPeriod(osiTimer_t *timer, uint32_t ms, bool periodic);
  1454. /**
  1455. * \brief set timer period for next call, with relaxed timeout
  1456. *
  1457. * The properties will be used by next \p osiTimerStartLast. It can only be
  1458. * called when the timer is not running.
  1459. *
  1460. * \param timer the timer to be set
  1461. * \param ms period in milliseconds
  1462. * \param relaxed_ms relaxed timeout in milliseconds
  1463. * \param periodic true for periodic, false for one shot
  1464. * \return
  1465. * - true on success
  1466. * - false on invalid parameter
  1467. */
  1468. bool osiTimerSetPeriodRelaxed(osiTimer_t *timer, uint32_t ms, uint32_t relaxed_ms, bool periodic);
  1469. /**
  1470. * \brief whether timer is started
  1471. *
  1472. * \param timer the timer to be set
  1473. * \return
  1474. * - true if the timer is started
  1475. * - false if not started, or invalid parameter
  1476. */
  1477. bool osiTimerIsRunning(osiTimer_t *timer);
  1478. /**
  1479. * \brief get remaining time of timer in milliseconds
  1480. *
  1481. * Even the timer is already timed out, it will return 0 rather then negative
  1482. * value. For example, thread callback timer is already timed out, but the
  1483. * callback hasn't invoked in the specified thread.
  1484. *
  1485. * \param timer the timer to be set
  1486. * \return
  1487. * - remaining time
  1488. * - timer is not started, or invalid parameter
  1489. */
  1490. int64_t osiTimerRemaining(osiTimer_t *timer);
  1491. /**
  1492. * \brief timer expiration time in milliseconds
  1493. *
  1494. * The expiration time is in the same coordinate of \p osiUpTime.
  1495. *
  1496. * When the timer is not running, it will return -1. For already timeed out
  1497. * timer, the return value may be smaller than \p osiUpTime.
  1498. *
  1499. * \param timer the timer to be checked
  1500. * \return
  1501. * - expiration time
  1502. * - -1 if the timer is not running
  1503. */
  1504. int64_t osiTimerExpiration(osiTimer_t *timer);
  1505. /**
  1506. * \brief start a timer with last period
  1507. *
  1508. * The last period is the period set by \p osiTimerSetPeriod, or other start
  1509. * APIs with period parameter.
  1510. *
  1511. * It is recommended that not to mixing start API with period parameter, and
  1512. * start API without period parameter. Though the behavior is determinstic,
  1513. * it is harder to be understood.
  1514. *
  1515. * \param timer the timer to be started
  1516. * \return
  1517. * - true on success
  1518. * - false on invalid parameter
  1519. */
  1520. bool osiTimerStartLast(osiTimer_t *timer);
  1521. /**
  1522. * \brief start a timer
  1523. *
  1524. * Start a timer, and the timer will be expired in specified period from
  1525. * now. After the callback is executed, the timer will come to stopped state
  1526. * automatically.
  1527. *
  1528. * When the timer is in stated state before this function, the previous
  1529. * expiration won't be executed.
  1530. *
  1531. * Refer to document about corner case of timer thread callback.
  1532. *
  1533. * It is valid that the timeout period is 0. In this case, the timer will
  1534. * expire very soon.
  1535. *
  1536. * Due to timeout is 32bits of milliseconds, The maximum timeout period is
  1537. * ~50 days.
  1538. *
  1539. * It is the same as \p osiTimerStartRelaxed, with \p relaxed_ms is 0.
  1540. *
  1541. * \param timer the timer to be started
  1542. * \param ms timeout period
  1543. * \return
  1544. * - true on success
  1545. * - false on invalid parameter
  1546. */
  1547. bool osiTimerStart(osiTimer_t *timer, uint32_t ms);
  1548. /**
  1549. * \brief start a timer with relaxed timeout
  1550. *
  1551. * It is a power optimization version of \p osiTimerStart.
  1552. *
  1553. * Refer to \p osiTimerChangeRelaxed for explaination of \p relaxed_ms.
  1554. *
  1555. * \param timer the timer to be started
  1556. * \param ms normal timeout period
  1557. * \param relax_ms relaxed timeout period
  1558. * \return
  1559. * - true on success
  1560. * - false on invalid parameter
  1561. */
  1562. bool osiTimerStartRelaxed(osiTimer_t *timer, uint32_t ms, uint32_t relax_ms);
  1563. /**
  1564. * \brief start a timer, timeout in unit of microseconds
  1565. *
  1566. * Timeout in microseconds can support higher precision. However, the maximum
  1567. * timeout is shorter, ~1.2 hours.
  1568. *
  1569. * The real precision depends on hardware.
  1570. * \param timer the timer to be started
  1571. * \param us timeout period in microseconds
  1572. * \return
  1573. * - true on success
  1574. * - false on invalid parameter
  1575. */
  1576. bool osiTimerStartMicrosecond(osiTimer_t *timer, uint32_t us);
  1577. /**
  1578. * \brief start a periodic timer
  1579. *
  1580. * Internally, the period may be aligned to hardware tick (larger than
  1581. * 16384Hz), there may exist accumulated error in long run. So, don't use
  1582. * periodic timer count for long time time, \p osiUpTime is a better choice.
  1583. *
  1584. * When the period of periodic timer is too small, it will have serious impact
  1585. * on system. Internally, the period taking effect will no less than
  1586. * \p CONFIG_KERNEL_PERIODIC_TIMER_MIN_PERIOD.
  1587. *
  1588. * It is the same as \p osiTimerStartPeriodicRelaxed, with \p relaxed_ms is 0.
  1589. *
  1590. * \param timer the timer to be started
  1591. * \param ms interval in milliseconds
  1592. * \return
  1593. * - true on success
  1594. * - false on invalid parameter
  1595. */
  1596. bool osiTimerStartPeriodic(osiTimer_t *timer, uint32_t ms);
  1597. /**
  1598. * \brief start a periodic timer with relaxed timeout
  1599. *
  1600. * It is a power optimization version of \p osiTimerStartPeriodic.
  1601. *
  1602. * Refer to \p osiTimerChangeRelaxed for explaination of \p relaxed_ms.
  1603. *
  1604. * \param timer the timer to be started
  1605. * \param ms interval in milliseconds
  1606. * \param relaxed_ms relaxed timeout period
  1607. * \return
  1608. * - true on success
  1609. * - false on invalid parameter
  1610. */
  1611. bool osiTimerStartPeriodicRelaxed(osiTimer_t *timer, uint32_t ms, uint32_t relaxed_ms);
  1612. /**
  1613. * \brief stop a time
  1614. *
  1615. * Stop a not-started or stopped timer is valid, just do nothing.
  1616. *
  1617. * Refer to document about corner case of timer thread callback.
  1618. *
  1619. * \param timer the timer to be stopped
  1620. * \return
  1621. * - true on success
  1622. * - false on invalid parameter
  1623. */
  1624. bool osiTimerStop(osiTimer_t *timer);
  1625. /**
  1626. * create a message queue
  1627. *
  1628. * \param msg_count maximum message count can be hold in queue
  1629. * \param msg_size size of each message in bytes
  1630. * \return
  1631. * - message queue pointer
  1632. * - NULL on invalid parameter or out of memory
  1633. */
  1634. osiMessageQueue_t *osiMessageQueueCreate(uint32_t msg_count, uint32_t msg_size);
  1635. /**
  1636. * delete a message queue
  1637. *
  1638. * When \p mq is NULL, nothing will be done, just as \p free.
  1639. *
  1640. * \param mq message queue pointer
  1641. */
  1642. void osiMessageQueueDelete(osiMessageQueue_t *mq);
  1643. /**
  1644. * put a message to message queue
  1645. *
  1646. * \p msg should hold content size the same as \p msg_size specified at
  1647. * \p osiMessageQueueCreate.
  1648. *
  1649. * After put, the content of \p msg will be copied to message queue.
  1650. *
  1651. * When \p mq is full, it will be blocked until there are rooms.
  1652. *
  1653. * This can be called in ISR. And in ISR, it will return false when queue
  1654. * is full, and not wait.
  1655. *
  1656. * \param mq message queue pointer
  1657. * \param msg mesage pointer
  1658. * \return
  1659. * - true on success
  1660. * - false on invalid parameter
  1661. */
  1662. bool osiMessageQueuePut(osiMessageQueue_t *mq, const void *msg);
  1663. /**
  1664. * put a message to message queue with timeout
  1665. *
  1666. * This can be called in ISR. And in ISR, \p timeout will be ignored.
  1667. *
  1668. * \param mq message queue pointer
  1669. * \param msg mesage pointer
  1670. * \param timeout timeout in milliseconds
  1671. * \return
  1672. * - true on success
  1673. * - false on invalid parameter or timeout
  1674. */
  1675. bool osiMessageQueueTryPut(osiMessageQueue_t *mq, const void *msg, uint32_t timeout);
  1676. /**
  1677. * get a message to message queue
  1678. *
  1679. * \p msg should be able tp hold content size of \p msg_size specified at
  1680. * \p osiMessageQueueCreate.
  1681. *
  1682. * After get, the content of message will be copied to \p msg.
  1683. *
  1684. * When \p mq is empty, it will be blocked until there are messages.
  1685. *
  1686. * This can be called in ISR. And in ISR, it will return false when queue
  1687. * is empty, and not wait.
  1688. *
  1689. * \param mq message queue pointer
  1690. * \param msg mesage pointer
  1691. * \return
  1692. * - true on success
  1693. * - false on invalid parameter
  1694. */
  1695. bool osiMessageQueueGet(osiMessageQueue_t *mq, void *msg);
  1696. /**
  1697. * get a message to message queue with timeout
  1698. *
  1699. * This can be called in ISR. And in ISR, \p timeout will be ignored.
  1700. *
  1701. * \param mq message queue pointer
  1702. * \param msg mesage pointer
  1703. * \param timeout timeout in milliseconds
  1704. * \return
  1705. * - true on success
  1706. * - false on invalid parameter or timeout
  1707. */
  1708. bool osiMessageQueueTryGet(osiMessageQueue_t *mq, void *msg, uint32_t timeout);
  1709. /**
  1710. * get the pending message count in message queue
  1711. *
  1712. * It can be called in both thread context and ISR context.
  1713. *
  1714. * \param mq message queue pointer
  1715. * \return
  1716. * - the pending message count in message queue
  1717. * - 0 on invalid parameter
  1718. */
  1719. uint32_t osiMessageQueuePendingCount(osiMessageQueue_t *mq);
  1720. /**
  1721. * get the space of message count in message queue
  1722. *
  1723. * It can be called in both thread context and ISR context.
  1724. *
  1725. * \param mq message queue pointer
  1726. * \return
  1727. * - the space of message count in message queue
  1728. * - 0 on invalid parameter
  1729. */
  1730. uint32_t osiMessageQueueSpaceCount(osiMessageQueue_t *mq);
  1731. /**
  1732. * create a semaphore
  1733. *
  1734. * When \p max_count is 1, it is a binary semaphore. Otherwise, it is
  1735. * counting semaphore.
  1736. *
  1737. * \param max_count maximum count of the semaphore
  1738. * \param init_count initial count of the semaphore
  1739. * \return
  1740. * - semaphore pointer
  1741. * - NULL on invalid parameter or out of memory
  1742. */
  1743. osiSemaphore_t *osiSemaphoreCreate(uint32_t max_count, uint32_t init_count);
  1744. /**
  1745. * delete the semaphore
  1746. *
  1747. * When there are blocked thread on the semaphore, the behavior is undefined
  1748. * for \p osiSemaphoreDelete.
  1749. *
  1750. * \param semaphore semaphore pointer
  1751. */
  1752. void osiSemaphoreDelete(osiSemaphore_t *semaphore);
  1753. /**
  1754. * acquire from semaphore
  1755. *
  1756. * After acquire, the count of semaphore will be decreased by 1.
  1757. *
  1758. * When the count of semaphore is 0, it will be blocked until the count
  1759. * becomes non-zero (increased by \p osiSemaphoreRelease).
  1760. *
  1761. * This can be called in ISR. And in ISR, it will return false when
  1762. * semaphore is unavailable, and not wait.
  1763. *
  1764. * \param semaphore semaphore pointer
  1765. * \return
  1766. * - true on success
  1767. * - false on invalid parameter, or unavailable in ISR
  1768. */
  1769. bool osiSemaphoreAcquire(osiSemaphore_t *semaphore);
  1770. /**
  1771. * acquire from semaphore with timeout
  1772. *
  1773. * This can be called in ISR. And in ISR, \p timeout will be ignored.
  1774. *
  1775. * \param semaphore semaphore pointer
  1776. * \param timeout timeout in milliseconds
  1777. * \return
  1778. * - true on success
  1779. * - false on timeout
  1780. */
  1781. bool osiSemaphoreTryAcquire(osiSemaphore_t *semaphore, uint32_t timeout);
  1782. /**
  1783. * release to semaphore
  1784. *
  1785. * After release, the count of semaphore will be increased by 1.
  1786. * When there are blocked thread on the semaphore, one of the blocked
  1787. * thread will be unblocked.
  1788. *
  1789. * This can be called in ISR.
  1790. *
  1791. * \param semaphore semaphore pointer
  1792. */
  1793. void osiSemaphoreRelease(osiSemaphore_t *semaphore);
  1794. /**
  1795. * create a mutex
  1796. *
  1797. * After creation, the mutex is in *open* state.
  1798. *
  1799. * \return
  1800. * - mutex pointer
  1801. * - NULL on out of memory
  1802. */
  1803. osiMutex_t *osiMutexCreate(void);
  1804. /**
  1805. * delete the mutex
  1806. *
  1807. * When \p mutex is NULL, nothing will be done, just as \p free.
  1808. *
  1809. * \param mutex mutex pointer to be deleted
  1810. */
  1811. void osiMutexDelete(osiMutex_t *mutex);
  1812. /**
  1813. * lock the mutex
  1814. *
  1815. * When \p mutex is locked by another thread, it will wait forever
  1816. * until the mutex is unlocked.
  1817. *
  1818. * It **can't** be called in ISR. And in ISR, it will return directly.
  1819. *
  1820. * \param mutex mutex pointer to be locked
  1821. */
  1822. void osiMutexLock(osiMutex_t *mutex);
  1823. /**
  1824. * lock the mutex with timeout
  1825. *
  1826. * It **can't** be called in ISR. And in ISR, it will return false directly.
  1827. *
  1828. * \param mutex mutex pointer to be locked
  1829. * \param timeout timeout in milliseconds
  1830. * \return
  1831. * - true on success
  1832. * - false on timeout
  1833. */
  1834. bool osiMutexTryLock(osiMutex_t *mutex, uint32_t timeout);
  1835. /**
  1836. * unlock the mutex
  1837. *
  1838. * It **can't** be called in ISR. And in ISR, it will return directly.
  1839. *
  1840. * \param mutex mutex pointer to be unlocked
  1841. */
  1842. void osiMutexUnlock(osiMutex_t *mutex);
  1843. /**
  1844. * \brief monoclinic system time
  1845. *
  1846. * It is a relative time from system boot. Even after suspend and resume,
  1847. * the monoclinic system time will be contiguous.
  1848. *
  1849. * At PSM wakeup (if supported), it is not contiguous.
  1850. *
  1851. * \return monoclinic system time in milliseconds
  1852. */
  1853. int64_t osiUpTime(void);
  1854. /**
  1855. * \brief monoclinic system time in microsecond
  1856. *
  1857. * The monoclinic system time in unit of microsecond.
  1858. *
  1859. * \return monoclinic system time in microseconds
  1860. */
  1861. int64_t osiUpTimeUS(void);
  1862. /**
  1863. * \brief set monoclinic system time
  1864. *
  1865. * When it is known that the hardware resource for monoclinic system time
  1866. * is discontinued, such as power off during deep sleep, this is called to
  1867. * set monoclinic system time.
  1868. *
  1869. * When up time is changed, epoch time and local time aren't be changed.
  1870. *
  1871. * It should only be called in system integration.
  1872. *
  1873. * \param ms target monoclinic system time in milliseconds
  1874. */
  1875. void osiSetUpTime(int64_t ms);
  1876. /**
  1877. * \brief set monoclinic system time
  1878. *
  1879. * When it is known that the hardware resource for monoclinic system time
  1880. * is discontinued, such as power off during deep sleep, this is called to
  1881. * set monoclinic system time.
  1882. *
  1883. * When up time is changed, epoch time and local time aren't be changed.
  1884. *
  1885. * It should only be called in system integration.
  1886. *
  1887. * \param us target monoclinic system time in microseconds
  1888. */
  1889. void osiSetUpTimeUS(int64_t us);
  1890. /**
  1891. * \brief get the epoch time
  1892. *
  1893. * The time is millisecond (1/1000 second) from 1970-01-01 UTC. To avoid
  1894. * overflow, the data type is 64 bits.
  1895. *
  1896. * Epoch time is not monoclinic time. For example, when system time is
  1897. * synchronized with network, there may exist a jump (forward or backward)
  1898. * of epoch time.
  1899. *
  1900. * In 2 cases, this system time may be not reliable:
  1901. * - During boot, and before RTC is initialized.
  1902. * - During wakeup, and the elapsed sleep time hasn't compensated.
  1903. *
  1904. * \return epoch time in milliseconds
  1905. */
  1906. int64_t osiEpochTime(void);
  1907. /**
  1908. * \brief get the epoch time in second
  1909. *
  1910. * The time is seconds from 1970-01-01 UTC. To avoid overflow, the data
  1911. * type is 64 bits.
  1912. * - signed 32bits will overflow at year 2038
  1913. * - unsigned 32bits will overflow at year 2106
  1914. *
  1915. * Epoch time is not monoclinic time. For example, when system time is
  1916. * synchronized with network, there may exist a jump (forward or backward)
  1917. * of epoch time.
  1918. *
  1919. * In 2 cases, this system time may be not reliable:
  1920. * - During boot, and before RTC is initialized.
  1921. * - During wakeup, and the elapsed sleep time hasn't compensated.
  1922. *
  1923. * \return epoch time in seconds
  1924. */
  1925. int64_t osiEpochSecond(void);
  1926. /**
  1927. * \brief set the monoclinic system time
  1928. *
  1929. * After the system time is changed, RTC won't be updated automatically.
  1930. * It is needed to call RTC API to sync system time to RTC.
  1931. *
  1932. * When epoch time is changed, the monoclilinc system up time isn't changed,
  1933. * and local time is changed correspondingly. The delta bewteen epoch time
  1934. * and local time is only affected by timezone.
  1935. *
  1936. * \param ms epoch time in milliseconds
  1937. *
  1938. * \return true on succeed else fail
  1939. */
  1940. bool osiSetEpochTime(int64_t ms);
  1941. /**
  1942. * \brief set the monoclinic system time
  1943. *
  1944. * After the system time is changed, RTC won't be updated automatically.
  1945. * It is needed to call RTC API to sync system time to RTC.
  1946. *
  1947. * When epoch time is changed, the monoclilinc system up time isn't changed,
  1948. * and local time is changed correspondingly. The delta bewteen epoch time
  1949. * and local time is only affected by timezone.
  1950. *
  1951. * \param us epoch time in microseconds
  1952. *
  1953. * \return true on succeed else fail
  1954. */
  1955. bool osiSetEpochTimeUS(int64_t us);
  1956. /**
  1957. * \brief get time zone in second
  1958. *
  1959. * Time zone is the offset between local time and epoch time:
  1960. * local_time = epoch_time + time_zone
  1961. *
  1962. * OSI won't keep time zone at power off. Other module should store
  1963. * time zone in NVRAM, and set to OSI at boot.
  1964. *
  1965. * \return time zone in second
  1966. */
  1967. int osiTimeZoneOffset(void);
  1968. /**
  1969. * \brief set time zone in second
  1970. *
  1971. * Time zone is the offset between local time and epoch time:
  1972. * local_time = epoch_time + time_zone
  1973. *
  1974. * Time zone should be in [-12*3600, 12*3600]. However, it is not checked
  1975. * inside this. The caller should make sure the \p offset is reasonable.
  1976. *
  1977. * \param offset time zone in second
  1978. */
  1979. void osiSetTimeZoneOffset(int offset);
  1980. /**
  1981. * \brief get the local time
  1982. *
  1983. * It is just: epoch_time + time_zone
  1984. *
  1985. * \return local time in milliseconds
  1986. */
  1987. int64_t osiLocalTime(void);
  1988. /**
  1989. * \brief get the local time in seconds
  1990. *
  1991. * It is just: epoch_time + time_zone
  1992. *
  1993. * \return local time in seconds
  1994. */
  1995. int64_t osiLocalSecond(void);
  1996. /**
  1997. * \brief convert epoch time to up time
  1998. *
  1999. * When some values has special meanings, such as INT64_MAX means invalid or not
  2000. * exist, caller should check special values before call this.
  2001. *
  2002. * \param epoch epoch time in milliseconds
  2003. * \return up time in milliseconds
  2004. */
  2005. int64_t osiEpochToUpTime(int64_t epoch);
  2006. /**
  2007. * \brief start counting of elsapsed timer
  2008. *
  2009. * \param timer elapsed timer, must be valid
  2010. */
  2011. void osiElapsedTimerStart(osiElapsedTimer_t *timer);
  2012. /**
  2013. * \brief elapsed milliseconds after start
  2014. *
  2015. * \param timer elapsed timer, must be valid
  2016. * \return
  2017. * - elapsed milliseconds after start
  2018. */
  2019. uint32_t osiElapsedTime(osiElapsedTimer_t *timer);
  2020. /**
  2021. * \brief elapsed microseconds after start
  2022. *
  2023. * \param timer elapsed timer, must be valid
  2024. * \return
  2025. * - elapsed microseconds after start
  2026. */
  2027. uint32_t osiElapsedTimeUS(osiElapsedTimer_t *timer);
  2028. /**
  2029. * \brief convert uptime to epoch time
  2030. *
  2031. * When some values has special meanings, such as INT64_MAX means invalid or not
  2032. * exist, caller should check special values before call this.
  2033. *
  2034. * \param uptime up time in milliseconds
  2035. * \return epoch time in milliseconds
  2036. */
  2037. int64_t osiUpTimeToEpoch(int64_t uptime);
  2038. /**
  2039. * \brief PM source callbacks
  2040. *
  2041. * All the callbacks are called with interrupt disabled. So, it is not
  2042. * needed to call \p osiEnterCritical or \p osiIrqSave for protection.
  2043. * And it is not error to call them.
  2044. *
  2045. * Don't call blocking API in the callback.
  2046. */
  2047. typedef struct osiPmSourceOps
  2048. {
  2049. void (*suspend)(void *ctx, osiSuspendMode_t mode); ///< callback to be called before suspend
  2050. void (*resume)(void *ctx, osiSuspendMode_t mode, uint32_t source); ///< callback to be called after resume
  2051. bool (*prepare)(void *ctx); ///< callback to be called at suspend check
  2052. void (*prepare_abort)(void *ctx); ///< callback to be called at suspend check fail
  2053. } osiPmSourceOps_t;
  2054. /**
  2055. * PM source opaque data struct
  2056. */
  2057. typedef struct osiPmSource osiPmSource_t;
  2058. /**
  2059. * \brief power management module initialization
  2060. *
  2061. * It should be called in early stage of boot, due to many other modules
  2062. * may register suspend and resume callback at initialization.
  2063. */
  2064. void osiPmInit(void);
  2065. /**
  2066. * \brief power management core start
  2067. *
  2068. * To avoid suspend too early, PM core won't be started at initialization
  2069. * automatically. After system is initialized, and necessary PM sources
  2070. * are created, \p osiPmStart shall be called.
  2071. *
  2072. * Only after \p osiPmStart is called, PM core will check and enter suspend.
  2073. */
  2074. void osiPmStart(void);
  2075. /**
  2076. * \brief power management core stop
  2077. *
  2078. * Stop PM core, and systen will never suspend.
  2079. *
  2080. * It is only for debug. And it shouldn't be used in real application.
  2081. */
  2082. void osiPmStop(void);
  2083. /**
  2084. * \brief create PM source
  2085. *
  2086. * Modules are distinguished by FOURCC *tag*. So, tag should be unique
  2087. * system wise.
  2088. *
  2089. * When the *tag* is already registered, it will return existed PM source.
  2090. *
  2091. * \p ops is permitted to be NULL, and all callbacks inside it are permitted
  2092. * to be NULL.
  2093. *
  2094. * Resume callbacks are called in create order, suspend callbacks are called
  2095. * in revered order. When resume order does matter, call \p osiPmResumeReorder
  2096. * or \p osiPmResumeFirst to change resume order.
  2097. *
  2098. * The returned pointer should be destroyed and freed by \p osiPmSourceDelete.
  2099. *
  2100. * PM source lock and unlock is binary. That is, there is no *counter* inside.
  2101. * When \p osiPmWakeUnlock is called, the PM source won't prevent system
  2102. * suspend, no matter how many times of \p osiPmWakeLock is called.
  2103. *
  2104. * \param tag module tag
  2105. * \param ops callbacks during suspend and resume
  2106. * \param ctx callback context, shared by all callbacks
  2107. * \return
  2108. * - PM source pointer
  2109. * - NULL on out of memory
  2110. */
  2111. osiPmSource_t *osiPmSourceCreate(uint32_t tag, const osiPmSourceOps_t *ops, void *ctx);
  2112. /**
  2113. * \brief destroy PM source
  2114. *
  2115. * \param ps PM source
  2116. */
  2117. void osiPmSourceDelete(osiPmSource_t *ps);
  2118. /**
  2119. * \brief ensure resume callback order
  2120. *
  2121. * In cases that the resume callback order is important, this API will check
  2122. * and change resume callback order if needed. After the call, the resumed
  2123. * order is ensured.
  2124. *
  2125. * When resume callback order is changed, suspend callback order is changed
  2126. * also.
  2127. *
  2128. * It won't be checked whether the tags are valid.
  2129. *
  2130. * \param tag_later module tag to be resumed laster
  2131. * \param tag_earlier module tag to be resumed earlier
  2132. */
  2133. void osiPmResumeReorder(uint32_t tag_later, uint32_t tag_earlier);
  2134. /**
  2135. * \brief move PM source to the first in resume order
  2136. *
  2137. * Find the PM source, and move it to the head of resume list. When PM source
  2138. * with \p tag is not found in resume list, nothing will be done.
  2139. *
  2140. * \param tag module tag to be moved
  2141. */
  2142. void osiPmResumeFirst(uint32_t tag);
  2143. /**
  2144. * \brief wake lock to prevent suspend
  2145. *
  2146. * Indicate the PM source will prevent system suspend. PM source is *NOT*
  2147. * counting, \p osiPmWakeLock will just set the PM source state. Multiple
  2148. * calls of \p osiPmWakeLock is equivalent to a single call.
  2149. *
  2150. * When \p ops.prepare is not NULL, the internal state of PM source is
  2151. * *suspend possible* rather than *active*. When system wants to
  2152. * suspend, \p ops.prepare will be called to double check whether
  2153. * suspend is permitted.
  2154. *
  2155. * \param ps PM source
  2156. */
  2157. void osiPmWakeLock(osiPmSource_t *ps);
  2158. /**
  2159. * \brief wake unlock to permit suspend
  2160. *
  2161. * Indicate the PM source won't prevent system suspend. PM source is *NOT*
  2162. * counting. No matter how many calls of \p osiPmWakeLock are called,
  2163. * \p osiPmWakeUnlock will set the PM source to unlock state.
  2164. *
  2165. * \param ps PM source
  2166. */
  2167. void osiPmWakeUnlock(osiPmSource_t *ps);
  2168. /**
  2169. * \brief set 32K sleep flag
  2170. *
  2171. * For platforms support both 32K sleep and suspend, the default sleep
  2172. * mode is suspend. When it is needed to use 32K sleep forcedly, it is
  2173. * needed to call this API.
  2174. *
  2175. * Each bit of \p flag represents a request source. When there are any
  2176. * 32K sleep requests, system will use 32K sleep rather than suspend.
  2177. *
  2178. * The 32K sleep request sources depend on platform. And they are
  2179. * defined in platform dependent hal_chip.h.
  2180. *
  2181. * \param flag 32K sleep request flag
  2182. */
  2183. void osiSet32KSleepFlag(uint32_t flag);
  2184. /**
  2185. * \brief clear 32K sleep flag
  2186. *
  2187. * \param flag 32K sleep request flag
  2188. */
  2189. void osiClear32KSleepFlag(uint32_t flag);
  2190. /**
  2191. * \brief register a shutdown callback
  2192. *
  2193. * When the callback and context is already registered, it will return
  2194. * false.
  2195. *
  2196. * The order to invoke callbacks is undefined.
  2197. *
  2198. * *Don't* call \p osiRegisterShutdownCallback or
  2199. * \p osiUnregisterShutdownCallback inside the callbacks.
  2200. *
  2201. * \param cb shutdown callback to be registered, can't be NULL
  2202. * \param ctx shutdown callback context
  2203. * \return
  2204. * - true if callback registered
  2205. * - false if callback is already registered, or callback is NULL
  2206. */
  2207. bool osiRegisterShutdownCallback(osiShutdownCallback_t cb, void *ctx);
  2208. /**
  2209. * \brief unregister a shutdown callback
  2210. *
  2211. * \param cb shutdown callback to be unregistered, can't be NULL
  2212. * \param ctx shutdown callback context
  2213. * \return
  2214. * - true if callback unregistered
  2215. * - false if callback isn't found
  2216. */
  2217. bool osiUnregisterShutdownCallback(osiShutdownCallback_t cb, void *ctx);
  2218. /**
  2219. * \brief set PSM sleep ready
  2220. *
  2221. * \param start_time the start time of psm request, in uptime
  2222. * \param sleep_time psm sleep time
  2223. */
  2224. void osiSetPsmSleepReady(int64_t start_time, int64_t sleep_time);
  2225. /**
  2226. * \brief set PSM sleep not ready
  2227. */
  2228. void osiSetPsmSleepNotReady(void);
  2229. /**
  2230. * \brief whether PSM sleep is ready
  2231. *
  2232. * \return
  2233. * - true if PSM sleep is ready
  2234. * - false if PSM sleep is not ready
  2235. */
  2236. bool osiIsPsmSleepReady(void);
  2237. /**
  2238. * \brief get PSM elapsed time in milliseconds
  2239. *
  2240. * The elapsed time is starting from \p start_time parameter of
  2241. * \p osiSetPsmSleepReady.
  2242. *
  2243. * \return
  2244. * - PSM elsapsed time
  2245. * - 0 if PSM is not ready
  2246. */
  2247. int64_t osiGetPsmElapsedTime(void);
  2248. /**
  2249. * \brief get cp deep sleep time in milliseconds
  2250. *
  2251. * \return cp deep sleep time
  2252. */
  2253. uint64_t osiCpDeepSleepTime(void);
  2254. /**
  2255. * \brief shutdown to specified mode
  2256. *
  2257. * When parameter is wrong, it will return false:
  2258. * - When \p mode is OSI_SHUTDOWN_PSM_SLEEP, and PSM isn't enabled.
  2259. * Caller should check whether PSM is enabled before calling
  2260. * \p osiShutdown.
  2261. * - When \p mode is not supported in the platform.
  2262. *
  2263. * It never return true.
  2264. *
  2265. * \param mode shutdown mode
  2266. * \return
  2267. * - false on parameter error
  2268. */
  2269. bool osiShutdown(osiShutdownMode_t mode);
  2270. /**
  2271. * \brief get boot causes
  2272. *
  2273. * It is possible there are multiple boot causes. The returned value is
  2274. * bit or of all boot causes.
  2275. *
  2276. * It is possible hardware registers will be cleared after accessed. So,
  2277. * always call \p osiGetBootCauses to get the boot causes, rather than
  2278. * accessing hardware registers directly.
  2279. *
  2280. * \return boot causes
  2281. */
  2282. uint32_t osiGetBootCauses(void);
  2283. /**
  2284. * \brief set a boot cause
  2285. *
  2286. * It is intended only for system integration.
  2287. *
  2288. * \param cause boot cause
  2289. */
  2290. void osiSetBootCause(osiBootCause_t cause);
  2291. /**
  2292. * \brief clear a boot cause
  2293. *
  2294. * It is intended only for system integration.
  2295. *
  2296. * \param cause boot cause
  2297. */
  2298. void osiClearBootCause(osiBootCause_t cause);
  2299. /**
  2300. * \brief get boot mode
  2301. *
  2302. * \return boot mode
  2303. */
  2304. osiBootMode_t osiGetBootMode(void);
  2305. /**
  2306. * \brief set boot mode
  2307. *
  2308. * It is intended only for system integration. At calling, caller should
  2309. * take care conflict of other boot mode detection.
  2310. *
  2311. * \param mode boot mode
  2312. */
  2313. void osiSetBootMode(osiBootMode_t mode);
  2314. /**
  2315. * \brief PSM restore
  2316. *
  2317. * It should be called in system initialization, after file system
  2318. * initialization.
  2319. */
  2320. void osiPsmRestore(void);
  2321. /**
  2322. * \brief save PSM data
  2323. *
  2324. * PSM data save is implemented in platform. PSM data should be saved in
  2325. * persistent storage, which can be flash or aon memory. Caller shouldn't
  2326. * assume the storage type.
  2327. *
  2328. * It should only be called in \p osiShutdown callbacks.
  2329. *
  2330. * For each owner, \p osiPsmDataSave shall be called only once at most.
  2331. *
  2332. * It is recommended to use fixed size buffer, which is the same at each
  2333. * PSM shutdown. However, variable size buffer is also supported.
  2334. *
  2335. * As a special case, \p size of 0 is permitted. It just keep record that
  2336. * the owner is saved without real data.
  2337. *
  2338. * \param owner PSM data owner
  2339. * \param buf owner's PSM data buffer
  2340. * \param size owner's PSM data buffer size
  2341. * \return
  2342. * - true on success
  2343. * - false on fail
  2344. * - duplicated owner
  2345. * - out of memory
  2346. */
  2347. bool osiPsmDataSave(osiPsmDataOwner_t owner, const void *buf, uint32_t size);
  2348. /**
  2349. * \brief restore PSM data
  2350. *
  2351. * Restore PSM data. At PSM resume boot, PSM data owner calls this to get
  2352. * the data saved by \p osiPsmDataSave
  2353. *
  2354. * The buffer size should be equal or larger than the saved size. If it is
  2355. * smaller than saved size, return -1.
  2356. *
  2357. * When \p buf is NULL, it will return PSM data size without copy. It can
  2358. * be used to get the PSM data size.
  2359. *
  2360. * \param owner PSM data owner
  2361. * \param buf buffer for owner's PSM data
  2362. * \param size buffer size
  2363. * \return
  2364. * - PSM data size on success
  2365. * - 0 if there are no PSM data
  2366. * - -1 on error
  2367. */
  2368. int osiPsmDataRestore(osiPsmDataOwner_t owner, void *buf, uint32_t size);
  2369. /**
  2370. * send out debug event to trace tool
  2371. *
  2372. * If system and trace tool support debug event, this will send
  2373. * a word to trace tool.
  2374. *
  2375. * It should be only used in quick debug. It is possible that platform
  2376. * can't support debug event, and debug event output may be turned off
  2377. * by compiling option.
  2378. *
  2379. * It is possible that debughost may be blocked. And then debughost event
  2380. * sent will timeout.
  2381. *
  2382. * NOTE: Debug event output will take times. For example, when debug host
  2383. * baud rate is 921600, it may take up to 109us. And when debughost is
  2384. * blocked, it may take 200us for timeout.
  2385. *
  2386. * \param event word which will appear on trace tool
  2387. * \return
  2388. * - true if the event is sent
  2389. * - false if the event sent timeout
  2390. */
  2391. bool osiDebugEvent(uint32_t event);
  2392. /**
  2393. * panic
  2394. *
  2395. * Called on fatal error, and system can't go on.
  2396. *
  2397. * It is different from \p assert. It will always cause system panic,
  2398. * and there are no compiling option to ignore it.
  2399. */
  2400. void osiPanic(void);
  2401. /**
  2402. * panic with specified address
  2403. *
  2404. * It is the same as \p osiPanic, except \p address is shown in log,
  2405. * rather than the return address of caller.
  2406. */
  2407. void osiPanicAt(void *address);
  2408. /**
  2409. * panic with no_return keyword
  2410. *
  2411. * Called on fatal error, and system can't go on.
  2412. *
  2413. * It is used for posix API, eg exit and abort
  2414. */
  2415. OSI_NO_RETURN void osiPanicPosix(void);
  2416. /**
  2417. * whether system is in panic mode
  2418. *
  2419. * In panic mode, system will still run a small daemon. And there is no
  2420. * interrupt in panic mode. So, features used in panic daemon shall take
  2421. * care of this.
  2422. *
  2423. * \return
  2424. * - true if system is in panic mode
  2425. * - false if system is not in panic mode
  2426. */
  2427. bool osiIsPanic(void);
  2428. /**
  2429. * register enter and polling callback at blue screen mode
  2430. *
  2431. * The maximum panic handler is pre-configured.
  2432. *
  2433. * \param enter callback to be caled when entering panic mode
  2434. * \param poll callback to be caled when during panic mode
  2435. * \param param callback parameter
  2436. * \return
  2437. * - true on success
  2438. * - false on fail, invalid paramters or too many handlers
  2439. */
  2440. bool osiRegisterBlueScreenHandler(osiCallback_t enter, osiCallback_t poll, void *param);
  2441. /**
  2442. * optional assert
  2443. *
  2444. * It is a macro. When \p CONFIG_KERNEL_ASSERT_ENABLED is defined, it will
  2445. * panic when \p expect_true is not true. When \p CONFIG_KERNEL_ASSERT_ENABLED
  2446. * is not defined, it will be expanded as empty.
  2447. *
  2448. * \p info is just a remainder in source code. It won't be used.
  2449. */
  2450. #ifdef CONFIG_KERNEL_ASSERT_ENABLED
  2451. #define OSI_ASSERT(expect_true, info) OSI_DO_WHILE0(if (!(expect_true)) osiPanic();)
  2452. #else
  2453. #define OSI_ASSERT(expect_true, info)
  2454. #endif
  2455. /**
  2456. * busy loop delay
  2457. *
  2458. * The precision of delay depends on platform. And it will ensure to delay
  2459. * at least the specified time.
  2460. *
  2461. * \param us delay time in microseconds
  2462. */
  2463. OSI_NO_MIPS16 void osiDelayUS(uint32_t us);
  2464. /**
  2465. * delay by CPU loop
  2466. *
  2467. * The absolute delay time depends on CPU frequency. \p count is the loop
  2468. * count, not the delayed instruction count.
  2469. *
  2470. * \param count delay loop count
  2471. */
  2472. void osiDelayLoops(uint32_t count);
  2473. /**
  2474. * call function with specified stack
  2475. *
  2476. * This will only be called with low level codes, and most likely, it is not
  2477. * needed for application.
  2478. *
  2479. * This function is located in SRAM. So, it can be called even the external
  2480. * RAM in unavailable.
  2481. *
  2482. * \p function shall have 2 parameters at most. It can return one word. When
  2483. * \p function doesn't return value, the return value of this wrapper is
  2484. * undefined.
  2485. *
  2486. * \p sp should be 8 bytes aligned.
  2487. *
  2488. * \param sp the stack to be used for \p function
  2489. * \param function the real function
  2490. * \param param0 the first parameter for \p function
  2491. * \param param1 the second parameter for \p function
  2492. * \return
  2493. * - the return value of \p function
  2494. */
  2495. uint32_t osiCallWithStack(void *sp, void *function, uint32_t param0, uint32_t param1);
  2496. #ifdef __cplusplus
  2497. }
  2498. #endif
  2499. #endif