| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394 |
- /*
- * 模块名称 : guix rt-thread兼容层
- * 文件名称 : gx_system_rtos_bind_rtthread.c
- * 版 本 : V1.0
- * 说 明 :
- *
- * 修改记录 :
- * 版本号 日期 作者 说明
- * V1.0 2020-11-20 HelloByeAll 首版
- * V1.1 2020-12-03 HelloByeAll 修改互斥量等初始化方法
- *
- */
- /* Include necessary system files. */
- #include "gx_api.h"
- #include "gx_system.h"
- #include "gx_system_rtos_bind.h"
- #ifndef GX_THREADX_BINDING
- /* This is an example of a generic RTOS binding. We have #ifdefed this code out
- of the GUIX library build, so that the user attempting to port to a new RTOS
- will intentionally observe a series of linker errors. These functions need to
- be implemented in a way that works correctly with the target RTOS.
- */
- #if defined(GUIX_BINDING_RT_THREAD)
- #include "rtthread.h"
- #ifndef OS_CFG_TICK_RATE_HZ
- #define OS_CFG_TICK_RATE_HZ 1000
- #endif
- #define GX_TIMER_TASK_PRIORITY (GX_SYSTEM_THREAD_PRIORITY + 1)
- #define GX_TIMER_TASK_STACK_SIZE 512
- void guix_timer_task_entry(void *);
- /* a few global status variables */
- GX_BOOL guix_timer_event_pending;
- /* define stack space for GUIX task */
- char guix_task_stack[GX_THREAD_STACK_SIZE];
- /* define stack space for timer task */
- char guix_timer_task_stack[GX_TIMER_TASK_STACK_SIZE];
- /* define semaphore for lock/unlock macros */
- static rt_mutex_t guix_system_lock_mutex;
- struct rt_thread guix_tcb;
- struct rt_thread guix_timer_tcb;
- /* a custom event structure, to hold event and linked list */
- typedef struct guix_linked_event_struct
- {
- GX_EVENT event_data; /* the GUIX event structure */
- struct guix_linked_event_struct *next; /* add link member */
- } GUIX_LINKED_EVENT;
- /* a custom fifo event queue structure */
- typedef struct guix_event_queue_struct
- {
- GUIX_LINKED_EVENT *first; /* first (oldest) event in fifo */
- GUIX_LINKED_EVENT *last; /* last (newest) event in fifo */
- GUIX_LINKED_EVENT *free; /* linked list of free events */
- GUIX_LINKED_EVENT *free_end; /* end of the free list */
- rt_sem_t count_sem; /* number of queued events */
- rt_mutex_t lock; /* lock to protect queue update */
- } GUIX_EVENT_QUEUE;
- /* an array of GX_EVENTs used to implement fifo queue */
- GUIX_LINKED_EVENT guix_event_array[GX_MAX_QUEUE_EVENTS];
- GUIX_EVENT_QUEUE guix_event_queue;
- /* rtos initialize: perform any setup that needs to be done before the GUIX task runs here */
- VOID gx_generic_rtos_initialize(VOID)
- {
- int Loop;
- GUIX_LINKED_EVENT *current;
- guix_timer_event_pending = GX_FALSE;
- guix_system_lock_mutex = rt_mutex_create("gx_system_lock", RT_IPC_FLAG_FIFO);
- gx_system_memory_allocator_set(rt_malloc, rt_free);
- /* initialize a custom fifo queue structure */
- guix_event_queue.first = GX_NULL;
- guix_event_queue.last = GX_NULL;
- guix_event_queue.free = guix_event_array;
- current = guix_event_queue.free;
- /* link all the structures together */
- for (Loop = 0; Loop < GX_MAX_QUEUE_EVENTS - 1; Loop++)
- {
- current->next = (current + 1);
- current = current->next;
- }
- current->next = GX_NULL; /* terminate the list */
- guix_event_queue.free_end = current;
- /* create mutex for lock access to this queue */
- guix_event_queue.lock = rt_mutex_create("gx_queue_lock", RT_IPC_FLAG_FIFO);
- /* create counting semaphore to track queue entries */
- guix_event_queue.count_sem = rt_sem_create("gx_queue_count", 0, RT_IPC_FLAG_FIFO);
- }
- VOID(*gx_system_thread_entry)
- (ULONG);
- // A small shell function to convert the void * arg expected by uC/OS to
- // a ULONG parameter expected by GUIX thread entry
- void gx_system_thread_entry_shell(void *parg)
- {
- gx_system_thread_entry((ULONG)parg);
- }
- /* thread_start: start the GUIX thread running. */
- UINT gx_generic_thread_start(VOID (*guix_thread_entry)(ULONG))
- {
- /* save the GUIX system thread entry function pointer */
- gx_system_thread_entry = guix_thread_entry;
- /* create the main GUIX task */
- rt_thread_init(&guix_tcb, "guix_task",
- gx_system_thread_entry_shell,
- GX_NULL,
- &guix_task_stack[0],
- GX_THREAD_STACK_SIZE,
- GX_SYSTEM_THREAD_PRIORITY,
- 20);
- /* create a simple task to generate timer events into GUIX */
- rt_thread_init(&guix_timer_tcb, "guix_timer_task",
- guix_timer_task_entry,
- GX_NULL,
- &guix_timer_task_stack[0],
- GX_TIMER_TASK_STACK_SIZE,
- GX_TIMER_TASK_PRIORITY,
- 20);
- rt_thread_startup(&guix_tcb);
- rt_thread_startup(&guix_timer_tcb);
- /* suspend the timer task until needed */
- rt_thread_suspend(&guix_timer_tcb);
- return GX_SUCCESS;
- }
- /* event_post: push an event into the fifo event queue */
- UINT gx_generic_event_post(GX_EVENT *event_ptr)
- {
- GUIX_LINKED_EVENT *linked_event;
- /* lock down the guix event queue */
- rt_mutex_take(guix_event_queue.lock, RT_WAITING_FOREVER);
- /* grab a free event slot */
- if (!guix_event_queue.free)
- {
- /* there are no free events, return failure */
- rt_mutex_release(guix_event_queue.lock);
- return GX_FAILURE;
- }
- linked_event = guix_event_queue.free;
- guix_event_queue.free = guix_event_queue.free->next;
- if (!guix_event_queue.free)
- {
- guix_event_queue.free_end = GX_NULL;
- }
- /* copy the event data into this slot */
- linked_event->event_data = *event_ptr;
- linked_event->next = GX_NULL;
- /* insert this event into fifo queue */
- if (guix_event_queue.last)
- {
- guix_event_queue.last->next = linked_event;
- }
- else
- {
- guix_event_queue.first = linked_event;
- }
- guix_event_queue.last = linked_event;
- /* Unlock the guix queue */
- rt_mutex_release(guix_event_queue.lock);
- /* increment event count */
- rt_sem_release(guix_event_queue.count_sem);
- return GX_SUCCESS;
- }
- /* event_fold: update existing matching event, otherwise post new event */
- UINT gx_generic_event_fold(GX_EVENT *event_ptr)
- {
- GUIX_LINKED_EVENT *pTest;
- /* Lock down the guix queue */
- rt_mutex_take(guix_event_queue.lock, RT_WAITING_FOREVER);
- // see if the same event is already in the queue:
- pTest = guix_event_queue.first;
- while (pTest)
- {
- if (pTest->event_data.gx_event_type == event_ptr->gx_event_type)
- {
- /* found matching event, update it and return */
- pTest->event_data.gx_event_payload.gx_event_ulongdata = event_ptr->gx_event_payload.gx_event_ulongdata;
- rt_mutex_release(guix_event_queue.lock);
- return GX_SUCCESS;
- }
- pTest = pTest->next;
- }
- /* did not find a match, push new event */
- rt_mutex_release(guix_event_queue.lock);
- gx_generic_event_post(event_ptr);
- return GX_SUCCESS;
- }
- /* event_pop: pop oldest event from fifo queue, block if wait and no events exist */
- UINT gx_generic_event_pop(GX_EVENT *put_event, GX_BOOL wait)
- {
- if (!wait)
- {
- if (guix_event_queue.first == GX_NULL)
- {
- /* the queue is empty, just return */
- return GX_FAILURE;
- }
- }
- /* wait for an event to arrive in queue */
- rt_sem_take(guix_event_queue.count_sem, RT_WAITING_FOREVER);
- /* lock down the queue */
- rt_mutex_take(guix_event_queue.lock, RT_WAITING_FOREVER);
- /* copy the event into destination */
- *put_event = guix_event_queue.first->event_data;
- /* link this event holder back into free list */
- if (guix_event_queue.free_end)
- {
- guix_event_queue.free_end->next = guix_event_queue.first;
- }
- else
- {
- guix_event_queue.free = guix_event_queue.first;
- }
- guix_event_queue.free_end = guix_event_queue.first;
- guix_event_queue.first = guix_event_queue.first->next;
- guix_event_queue.free_end->next = GX_NULL;
- if (!guix_event_queue.first)
- {
- guix_event_queue.last = GX_NULL;
- }
- /* check for popping out a timer event */
- if (put_event->gx_event_type == GX_EVENT_TIMER)
- {
- guix_timer_event_pending = GX_FALSE;
- }
- /* unlock the queue */
- rt_mutex_release(guix_event_queue.lock);
- return GX_SUCCESS;
- }
- /* event_purge: delete events targetted to particular widget */
- VOID gx_generic_event_purge(GX_WIDGET *target)
- {
- GX_BOOL Purge;
- GUIX_LINKED_EVENT *pTest;
- /* Lock down the guix queue */
- rt_mutex_take(guix_event_queue.lock, RT_WAITING_FOREVER);
- // look for events targetted to widget or widget children:
- pTest = guix_event_queue.first;
- while (pTest)
- {
- Purge = GX_FALSE;
- if (pTest->event_data.gx_event_target)
- {
- if (pTest->event_data.gx_event_target == target)
- {
- Purge = GX_TRUE;
- }
- else
- {
- gx_widget_child_detect(target, pTest->event_data.gx_event_target, &Purge);
- }
- if (Purge)
- {
- pTest->event_data.gx_event_target = GX_NULL;
- pTest->event_data.gx_event_type = 0;
- }
- }
- pTest = pTest->next;
- }
- rt_mutex_release(guix_event_queue.lock);
- }
- /* start the RTOS timer */
- VOID gx_generic_timer_start(VOID)
- {
- rt_thread_resume(&guix_timer_tcb);
- }
- /* stop the RTOS timer */
- VOID gx_generic_timer_stop(VOID)
- {
- rt_thread_suspend(&guix_timer_tcb);
- }
- /* lock the system protection mutex */
- VOID gx_generic_system_mutex_lock(VOID)
- {
- rt_mutex_take(guix_system_lock_mutex, RT_WAITING_FOREVER);
- }
- /* unlock system protection mutex */
- VOID gx_generic_system_mutex_unlock(VOID)
- {
- rt_mutex_release(guix_system_lock_mutex);
- }
- /* return number of low-level system timer ticks. Used for pen speed caculations */
- ULONG gx_generic_system_time_get(VOID)
- {
- return ((ULONG)rt_tick_get());
- }
- /* thread_identify: return current thread identifier, cast as VOID * */
- VOID *gx_generic_thread_identify(VOID)
- {
- return rt_thread_self();
- }
- /* a simple task to drive the GUIX timer mechanism */
- void guix_timer_task_entry(void *unused)
- {
- int TickCount = OS_CFG_TICK_RATE_HZ / GX_TICKS_SECOND;
- if (TickCount <= 0)
- {
- TickCount = 1;
- }
- while (1)
- {
- rt_thread_mdelay(TickCount);
- /* prevent sending timer events faster than they can be processed */
- if (!guix_timer_event_pending)
- {
- guix_timer_event_pending = GX_TRUE;
- _gx_system_timer_expiration(0);
- }
- }
- }
- VOID gx_generic_time_delay(int ticks)
- {
- rt_thread_mdelay(ticks);
- }
- #endif //(GUIX_BINDING_RT_THREAD)
- #endif //(GX_THREADX_BINDING)
- /*************************************** (END OF FILE) ****************************************/
|