Lcd companion boards support (VKLCD50RTA & VKLCD70RT)
What is this ?
This is a demo program using Renesas RGA library & USB Camera to demonstrate VK-RZ/A1H's companion boards workability.
Supported companion Boards:
VKLCD50RTA
VKLCD70RT
How to Configure ?
You can choose which display is installed by altering the lcd_panel.h file
Leave the active one & comment out the others:
#define LCD_VDC5_CH0_PANEL LCD_CH0_PANEL_VKLCD50RTA //#define LCD_VDC5_CH0_PANEL LCD_CH0_PANEL_VKLCD70RT
You can alter the whole demo with your pictures if you like:
How to compile ?
- The Demo can be compiled in 3 modes:
- I. Execution from the internal 10-MB on-chip SRAM.
- II. Execution from the on-board serial FALSH in dual (32-MB) mode.
- After import in the online compiler just leave only the VKRZA1H_DOUBLE.sct & delete all others linker files in the TOOLCHAIN_ARM_STD folder.
- Drag & drop the result binary in MBED disk, (previously inited in double flash mode)
- III. Execution from the on-board serial FALSH in single (16-MB) mode.
- After import in the online compiler just leave only the VKRZA1H_SINGLE.sct & delete all others linker files in the TOOLCHAIN_ARM_STD folder.
- Drag & drop the result binary in MBED disk, (previously inited in single flash mode )
Quick presentation:
Other demos ?
More demos you can find on our FTP
Diff: rtos/rtos/Thread.cpp
- Revision:
- 0:6435b67ad23c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtos/rtos/Thread.cpp Thu Feb 16 10:23:48 2017 +0000 @@ -0,0 +1,349 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2012 ARM Limited + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "Thread.h" + +#include "mbed.h" +#include "rtos_idle.h" + +// rt_tid2ptcb is an internal function which we exposed to get TCB for thread id +#undef NULL //Workaround for conflicting macros in rt_TypeDef.h and stdio.h +#include "rt_TypeDef.h" + +extern "C" P_TCB rt_tid2ptcb(osThreadId thread_id); + +namespace rtos { + +void Thread::constructor(osPriority priority, + uint32_t stack_size, unsigned char *stack_pointer) { + _tid = 0; + _dynamic_stack = (stack_pointer == NULL); + +#if defined(__MBED_CMSIS_RTOS_CA9) || defined(__MBED_CMSIS_RTOS_CM) + _thread_def.tpriority = priority; + _thread_def.stacksize = stack_size; + _thread_def.stack_pointer = (uint32_t*)stack_pointer; +#endif +} + +void Thread::constructor(Callback<void()> task, + osPriority priority, uint32_t stack_size, unsigned char *stack_pointer) { + constructor(priority, stack_size, stack_pointer); + + switch (start(task)) { + case osErrorResource: + error("OS ran out of threads!\n"); + break; + case osErrorParameter: + error("Thread already running!\n"); + break; + case osErrorNoMemory: + error("Error allocating the stack memory\n"); + default: + break; + } +} + +osStatus Thread::start(Callback<void()> task) { + _mutex.lock(); + + if (_tid != 0) { + _mutex.unlock(); + return osErrorParameter; + } + +#if defined(__MBED_CMSIS_RTOS_CA9) || defined(__MBED_CMSIS_RTOS_CM) + _thread_def.pthread = Thread::_thunk; + if (_thread_def.stack_pointer == NULL) { + _thread_def.stack_pointer = new uint32_t[_thread_def.stacksize/sizeof(uint32_t)]; + if (_thread_def.stack_pointer == NULL) { + _mutex.unlock(); + return osErrorNoMemory; + } + } + + //Fill the stack with a magic word for maximum usage checking + for (uint32_t i = 0; i < (_thread_def.stacksize / sizeof(uint32_t)); i++) { + _thread_def.stack_pointer[i] = 0xE25A2EA5; + } +#endif + _task = task; + _tid = osThreadCreate(&_thread_def, this); + if (_tid == NULL) { + if (_dynamic_stack) delete[] (_thread_def.stack_pointer); + _mutex.unlock(); + return osErrorResource; + } + + _mutex.unlock(); + return osOK; +} + +osStatus Thread::terminate() { + osStatus ret; + _mutex.lock(); + + ret = osThreadTerminate(_tid); + _tid = (osThreadId)NULL; + + // Wake threads joining the terminated thread + _join_sem.release(); + + _mutex.unlock(); + return ret; +} + +osStatus Thread::join() { + int32_t ret = _join_sem.wait(); + if (ret < 0) { + return osErrorOS; + } + // Release sem so any other threads joining this thread wake up + _join_sem.release(); + return osOK; +} + +osStatus Thread::set_priority(osPriority priority) { + osStatus ret; + _mutex.lock(); + + ret = osThreadSetPriority(_tid, priority); + + _mutex.unlock(); + return ret; +} + +osPriority Thread::get_priority() { + osPriority ret; + _mutex.lock(); + + ret = osThreadGetPriority(_tid); + + _mutex.unlock(); + return ret; +} + +int32_t Thread::signal_set(int32_t signals) { + // osSignalSet is thread safe as long as the underlying + // thread does not get terminated or return from main + return osSignalSet(_tid, signals); +} + +int32_t Thread::signal_clr(int32_t signals) { + // osSignalClear is thread safe as long as the underlying + // thread does not get terminated or return from main + return osSignalClear(_tid, signals); +} + +Thread::State Thread::get_state() { +#if !defined(__MBED_CMSIS_RTOS_CA9) && !defined(__MBED_CMSIS_RTOS_CM) +#ifdef CMSIS_OS_RTX + State status = Deleted; + _mutex.lock(); + + if (_tid != NULL) { + status = (State)_thread_def.tcb.state; + } + + _mutex.unlock(); + return status; +#endif +#else + State status = Deleted; + _mutex.lock(); + + if (_tid != NULL) { + status = (State)osThreadGetState(_tid); + } + + _mutex.unlock(); + return status; +#endif +} + +uint32_t Thread::stack_size() { +#ifndef __MBED_CMSIS_RTOS_CA9 +#if defined(CMSIS_OS_RTX) && !defined(__MBED_CMSIS_RTOS_CM) + uint32_t size = 0; + _mutex.lock(); + + if (_tid != NULL) { + size = _thread_def.tcb.priv_stack; + } + + _mutex.unlock(); + return size; +#else + uint32_t size = 0; + _mutex.lock(); + + if (_tid != NULL) { + P_TCB tcb = rt_tid2ptcb(_tid); + size = tcb->priv_stack; + } + + _mutex.unlock(); + return size; +#endif +#else + return 0; +#endif +} + +uint32_t Thread::free_stack() { +#ifndef __MBED_CMSIS_RTOS_CA9 +#if defined(CMSIS_OS_RTX) && !defined(__MBED_CMSIS_RTOS_CM) + uint32_t size = 0; + _mutex.lock(); + + if (_tid != NULL) { + uint32_t bottom = (uint32_t)_thread_def.tcb.stack; + size = _thread_def.tcb.tsk_stack - bottom; + } + + _mutex.unlock(); + return size; +#else + uint32_t size = 0; + _mutex.lock(); + + if (_tid != NULL) { + P_TCB tcb = rt_tid2ptcb(_tid); + uint32_t bottom = (uint32_t)tcb->stack; + size = tcb->tsk_stack - bottom; + } + + _mutex.unlock(); + return size; +#endif +#else + return 0; +#endif +} + +uint32_t Thread::used_stack() { +#ifndef __MBED_CMSIS_RTOS_CA9 +#if defined(CMSIS_OS_RTX) && !defined(__MBED_CMSIS_RTOS_CM) + uint32_t size = 0; + _mutex.lock(); + + if (_tid != NULL) { + uint32_t top = (uint32_t)_thread_def.tcb.stack + _thread_def.tcb.priv_stack; + size = top - _thread_def.tcb.tsk_stack; + } + + _mutex.unlock(); + return size; +#else + uint32_t size = 0; + _mutex.lock(); + + if (_tid != NULL) { + P_TCB tcb = rt_tid2ptcb(_tid); + uint32_t top = (uint32_t)tcb->stack + tcb->priv_stack; + size = top - tcb->tsk_stack; + } + + _mutex.unlock(); + return size; +#endif +#else + return 0; +#endif +} + +uint32_t Thread::max_stack() { +#ifndef __MBED_CMSIS_RTOS_CA9 +#if defined(CMSIS_OS_RTX) && !defined(__MBED_CMSIS_RTOS_CM) + uint32_t size = 0; + _mutex.lock(); + + if (_tid != NULL) { + uint32_t high_mark = 0; + while (_thread_def.tcb.stack[high_mark] == 0xE25A2EA5) + high_mark++; + size = _thread_def.tcb.priv_stack - (high_mark * 4); + } + + _mutex.unlock(); + return size; +#else + uint32_t size = 0; + _mutex.lock(); + + if (_tid != NULL) { + P_TCB tcb = rt_tid2ptcb(_tid); + uint32_t high_mark = 0; + while (tcb->stack[high_mark] == 0xE25A2EA5) + high_mark++; + size = tcb->priv_stack - (high_mark * 4); + } + + _mutex.unlock(); + return size; +#endif +#else + return 0; +#endif +} + +osEvent Thread::signal_wait(int32_t signals, uint32_t millisec) { + return osSignalWait(signals, millisec); +} + +osStatus Thread::wait(uint32_t millisec) { + return osDelay(millisec); +} + +osStatus Thread::yield() { + return osThreadYield(); +} + +osThreadId Thread::gettid() { + return osThreadGetId(); +} + +void Thread::attach_idle_hook(void (*fptr)(void)) { + rtos_attach_idle_hook(fptr); +} + +Thread::~Thread() { + // terminate is thread safe + terminate(); +#ifdef __MBED_CMSIS_RTOS_CM + if (_dynamic_stack) { + delete[] (_thread_def.stack_pointer); + } +#endif +} + +void Thread::_thunk(const void * thread_ptr) +{ + Thread *t = (Thread*)thread_ptr; + t->_task(); + t->_mutex.lock(); + t->_tid = (osThreadId)NULL; + t->_join_sem.release(); + // rtos will release the mutex automatically +} + +} +