diff --git a/meson.build b/meson.build index 9bb5357f..d23e3b8c 100644 --- a/meson.build +++ b/meson.build @@ -1,7 +1,7 @@ ## ## OpenRTX - Modular Open Source Radio Firmware ## -project('OpenRTX', 'c', +project('OpenRTX', ['c', 'cpp'], version : '0.1', default_options : ['warning_level=3']) @@ -11,8 +11,7 @@ project('OpenRTX', 'c', ## OpenRTX -openrtx_src = ['openrtx/src/bootstrap.c', - 'openrtx/src/state.c', +openrtx_src = ['openrtx/src/state.c', 'openrtx/src/ui/ui.c', 'openrtx/src/ui/ui_main.c', 'openrtx/src/ui/ui_menu.c', @@ -21,6 +20,7 @@ openrtx_src = ['openrtx/src/bootstrap.c', 'openrtx/src/graphics.c', 'openrtx/src/input.c', 'openrtx/src/calibUtils.c', + 'openrtx/src/queue.c', 'openrtx/src/rtx.c', 'openrtx/src/gps.c'] @@ -28,10 +28,8 @@ openrtx_src = ['openrtx/src/bootstrap.c', ## Replace main executable with platform test if get_option('test') != '' openrtx_src += 'tests/platform/'+get_option('test')+'.c' - openrtx_def = {'RUN_TESTSUITE': ''} else openrtx_src += 'openrtx/src/main.c' - openrtx_def = {} endif openrtx_inc = ['openrtx/include', @@ -45,36 +43,11 @@ openrtx_inc = ['openrtx/include', 'platform/drivers/baseband'] ## RTOS -rtos_src = ['lib/rtos/uC-OS3/Source/__dbg_uCOS-III.c', - 'lib/rtos/uC-OS3/Source/os_cfg_app.c', - 'lib/rtos/uC-OS3/Source/os_core.c', - 'lib/rtos/uC-OS3/Source/os_dbg.c', - 'lib/rtos/uC-OS3/Source/os_flag.c', - 'lib/rtos/uC-OS3/Source/os_mem.c', - 'lib/rtos/uC-OS3/Source/os_msg.c', - 'lib/rtos/uC-OS3/Source/os_mutex.c', - 'lib/rtos/uC-OS3/Source/os_prio.c', - 'lib/rtos/uC-OS3/Source/os_q.c', - 'lib/rtos/uC-OS3/Source/os_sem.c', - 'lib/rtos/uC-OS3/Source/os_stat.c', - 'lib/rtos/uC-OS3/Source/os_task.c', - 'lib/rtos/uC-OS3/Source/os_tick.c', - 'lib/rtos/uC-OS3/Source/os_time.c', - 'lib/rtos/uC-OS3/Source/os_tmr.c', - 'lib/rtos/uC-OS3/Source/os_var.c', - 'lib/rtos/uC-OS3/Cfg/os_app_hooks.c', - 'lib/rtos/uC-CPU/cpu_core.c', - 'lib/rtos/uC-LIB/lib_ascii.c', - 'lib/rtos/uC-LIB/lib_math.c', - 'lib/rtos/uC-LIB/lib_mem.c', - 'lib/rtos/uC-LIB/lib_str.c'] - -rtos_inc = ['lib/rtos/uC-OS3/Source', - 'lib/rtos/uC-OS3/Cfg', - 'lib/rtos/uC-CPU', - 'lib/rtos/uC-CPU/Cfg', - 'lib/rtos/uC-LIB', - 'lib/rtos/uC-LIB/Cfg'] +rtos_inc = ['lib/miosix-kernel', + 'lib/miosix-kernel/arch', + 'lib/miosix-kernel/arch/cortexM4_stm32f4/common', + 'lib/miosix-kernel/arch/cortexM4_stm32f4/M4_openrtx', + 'lib/miosix-kernel/config/arch/cortexM4_stm32f4/M4_openrtx'] ## minmea, a lightweight GPS NMEA 0183 parser library @@ -82,13 +55,13 @@ minmea_src = ['lib/minmea/minmea.c'] minmea_inc = ['lib/minmea/include'] -src = openrtx_src + rtos_src + minmea_src +src = openrtx_src + minmea_src inc = openrtx_inc + rtos_inc + minmea_inc ## ## Definitions ## -def = openrtx_def + {'DONT_USE_CMSIS_INIT': ''} +def = {'DONT_USE_CMSIS_INIT': ''} ## ## MCU-dependent sources and includes @@ -96,8 +69,9 @@ def = openrtx_def + {'DONT_USE_CMSIS_INIT': ''} ## STM32F405 -stm32f405_src = ['platform/mcu/STM32F4xx/boot/startup.c', - 'platform/mcu/STM32F4xx/boot/libc_integration.c', +stm32f405_src = ['platform/mcu/STM32F4xx/boot/startup.cpp', + 'platform/mcu/STM32F4xx/boot/bsp.cpp', + 'platform/mcu/STM32F4xx/boot/libc_integration.cpp', 'platform/mcu/STM32F4xx/drivers/usb/usb_bsp.c', 'platform/mcu/STM32F4xx/drivers/usb/usb_core.c', 'platform/mcu/STM32F4xx/drivers/usb/usb_dcd.c', @@ -109,50 +83,38 @@ stm32f405_src = ['platform/mcu/STM32F4xx/boot/startup.c', 'platform/mcu/STM32F4xx/drivers/usb/usbd_usr.c', 'platform/mcu/STM32F4xx/drivers/gpio.c', 'platform/mcu/STM32F4xx/drivers/usb_vcom.c', - 'platform/mcu/STM32F4xx/drivers/delays.c', + 'platform/mcu/STM32F4xx/drivers/delays.cpp', 'platform/mcu/STM32F4xx/drivers/rtc.c', - 'platform/mcu/CMSIS/Device/ST/STM32F4xx/Source/system_stm32f4xx.c', - 'lib/rtos/uC-OS3/Ports/ARM-Cortex-M/ARMv7-M/os_cpu_c.c', - 'lib/rtos/uC-OS3/Ports/ARM-Cortex-M/ARMv7-M/os_cpu_a.s', - 'lib/rtos/uC-CPU/ARM-Cortex-M/ARMv7-M/cpu_c.c', - 'lib/rtos/uC-CPU/ARM-Cortex-M/ARMv7-M/cpu_a.s'] + 'platform/mcu/CMSIS/Device/ST/STM32F4xx/Source/system_stm32f4xx.c'] stm32f405_inc = ['platform/mcu/CMSIS/Include', 'platform/mcu/CMSIS/Device/ST/STM32F4xx/Include', 'platform/mcu/STM32F4xx', 'platform/mcu/STM32F4xx/drivers', - 'platform/mcu/STM32F4xx/drivers/usb', - 'lib/rtos/uC-OS3/Ports/ARM-Cortex-M/ARMv7-M', - 'lib/rtos/uC-CPU/ARM-Cortex-M/ARMv7-M'] + 'platform/mcu/STM32F4xx/drivers/usb'] stm32f405_def = {'STM32F40_41xxx': '', 'HSE_VALUE':'8000000'} ## MK22FN512 -mk22fn512_src = ['platform/mcu/MK22FN512xxx12/boot/startup.c', - 'platform/mcu/MK22FN512xxx12/boot/libc_integration.c', +mk22fn512_src = ['platform/mcu/MK22FN512xxx12/boot/startup.cpp', + 'platform/mcu/MK22FN512xxx12/boot/bsp.cpp', + 'platform/mcu/MK22FN512xxx12/boot/libc_integration.cpp', 'platform/mcu/MK22FN512xxx12/drivers/gpio.c', - 'platform/mcu/MK22FN512xxx12/drivers/delays.c', - 'platform/mcu/MK22FN512xxx12/drivers/rtc.c', + 'platform/mcu/MK22FN512xxx12/drivers/delays.cpp', 'platform/mcu/MK22FN512xxx12/drivers/I2C0.c', - 'platform/mcu/MK22FN512xxx12/drivers/usb/usb_device_cdc_acm.c', - 'platform/mcu/MK22FN512xxx12/drivers/usb/usb_device_ch9.c', - 'platform/mcu/MK22FN512xxx12/drivers/usb/usb_device_dci.c', - 'platform/mcu/MK22FN512xxx12/drivers/usb/usb_device_descriptor.c', - 'platform/mcu/MK22FN512xxx12/drivers/usb/usb_device_khci.c', - 'platform/mcu/MK22FN512xxx12/drivers/usb/usb_osa_bm.c', - 'platform/mcu/MK22FN512xxx12/drivers/usb_vcom.c', - 'platform/mcu/CMSIS/Device/NXP/MK22FN512xxx12/Source/system_MK22F51212.c', - 'lib/rtos/uC-OS3/Ports/ARM-Cortex-M/ARMv7-M/os_cpu_c.c', - 'lib/rtos/uC-OS3/Ports/ARM-Cortex-M/ARMv7-M/os_cpu_a.s', - 'lib/rtos/uC-CPU/ARM-Cortex-M/ARMv7-M/cpu_c.c', - 'lib/rtos/uC-CPU/ARM-Cortex-M/ARMv7-M/cpu_a.s'] +# 'platform/mcu/MK22FN512xxx12/drivers/usb/usb_device_cdc_acm.c', +# 'platform/mcu/MK22FN512xxx12/drivers/usb/usb_device_ch9.c', +# 'platform/mcu/MK22FN512xxx12/drivers/usb/usb_device_dci.c', +# 'platform/mcu/MK22FN512xxx12/drivers/usb/usb_device_descriptor.c', +# 'platform/mcu/MK22FN512xxx12/drivers/usb/usb_device_khci.c', +# 'platform/mcu/MK22FN512xxx12/drivers/usb/usb_osa_bm.c', +# 'platform/mcu/MK22FN512xxx12/drivers/usb_vcom.c', + 'platform/mcu/CMSIS/Device/NXP/MK22FN512xxx12/Source/system_MK22F51212.c'] mk22fn512_inc = ['platform/mcu/CMSIS/Include', 'platform/mcu/CMSIS/Device/NXP/MK22FN512xxx12/Include', - 'platform/mcu/MK22FN512xxx12/drivers', - 'lib/rtos/uC-OS3/Ports/ARM-Cortex-M/ARMv7-M', - 'lib/rtos/uC-CPU/ARM-Cortex-M/ARMv7-M'] + 'platform/mcu/MK22FN512xxx12/drivers'] mk22fn512_def = {} @@ -170,9 +132,7 @@ linux_src = src + ['platform/targets/linux/emulator/emulator.c', 'platform/mcu/x86_64/drivers/delays.c', 'platform/mcu/x86_64/drivers/rtc.c', 'platform/drivers/baseband/radio_linux.c', - 'platform/targets/linux/platform.c', - 'lib/rtos/uC-OS3/Ports/POSIX/os_cpu_c.c', - 'lib/rtos/uC-CPU/Posix/cpu_c.c'] + 'platform/targets/linux/platform.c'] # GDx family display emulation @@ -180,9 +140,7 @@ linux_src = src + ['platform/targets/linux/emulator/emulator.c', # MDx family display emulation linux_def = def + {'SCREEN_WIDTH': '160', 'SCREEN_HEIGHT': '128', 'PIX_FMT_RGB565': ''} -linux_inc = inc + ['lib/rtos/uC-OS3/Ports/POSIX', - 'lib/rtos/uC-CPU/Posix', - 'platform/targets/linux', +linux_inc = inc + ['platform/targets/linux', 'platform/targets/linux/emulator'] if not meson.is_cross_build() @@ -194,7 +152,7 @@ else endif ## TYT MD-3x0 family -md3x0_src = src + stm32f405_src + ['platform/drivers/display/HX8353_MDx.c', +md3x0_src = src + stm32f405_src + ['platform/drivers/display/HX8353_MDx.cpp', 'platform/drivers/keyboard/keyboard_MDx.c', 'platform/drivers/NVM/W25Qx.c', 'platform/drivers/NVM/spiFlash_MDx.c', @@ -204,7 +162,7 @@ md3x0_src = src + stm32f405_src + ['platform/drivers/display/HX8353_MDx.c', 'platform/drivers/baseband/SKY72310.c', 'platform/drivers/baseband/radio_MD3x0.c', 'platform/drivers/baseband/HR_C5000.c', - 'platform/drivers/GPS/GPS_MDx.c', + 'platform/drivers/GPS/GPS_MDx.cpp', 'platform/targets/MD-3x0/platform.c'] md3x0_inc = inc + stm32f405_inc + ['platform/targets/MD-3x0'] @@ -212,7 +170,7 @@ md3x0_def = def + stm32f405_def + {'PLATFORM_MD3x0': '', 'timegm': 'mktime'} ## TYT MD-UV380 -mduv380_src = src + stm32f405_src + ['platform/drivers/display/HX8353_MDx.c', +mduv380_src = src + stm32f405_src + ['platform/drivers/display/HX8353_MDx.cpp', 'platform/drivers/keyboard/keyboard_MDx.c', 'platform/drivers/NVM/W25Qx.c', 'platform/drivers/NVM/spiFlash_MDx.c', @@ -220,7 +178,7 @@ mduv380_src = src + stm32f405_src + ['platform/drivers/display/HX8353_MDx.c', 'platform/drivers/ADC/ADC1_MDx.c', 'platform/drivers/tones/toneGenerator_MDx.c', 'platform/drivers/baseband/radio_UV3x0.c', - 'platform/drivers/GPS/GPS_MDx.c', + 'platform/drivers/GPS/GPS_MDx.cpp', 'platform/targets/MD-UV380/platform.c'] mduv380_inc = inc + stm32f405_inc + ['platform/targets/MD-UV380'] @@ -355,38 +313,44 @@ linux_opts = {'sources': linux_src, 'dependencies': linux_dep, 'link_args' : linux_l_args} -md3x0_opts = {'sources': md3x0_src, - 'c_args': md3x0_args, +md3x0_opts = {'sources' : md3x0_src, + 'c_args' : md3x0_args, + 'cpp_args': md3x0_args, 'link_args' : ['-Wl,-T../platform/mcu/STM32F4xx/linker_script.ld', '-Wl,--print-memory-usage'], 'include_directories': md3x0_inc} mduv380_opts = {'sources': mduv380_src, 'c_args': mduv380_args, + 'cpp_args': mduv380_args, 'link_args' : ['-Wl,-T../platform/mcu/STM32F4xx/linker_script.ld', '-Wl,--print-memory-usage'], 'include_directories': mduv380_inc} mduv380g_opts = {'sources': mduv380_src, 'c_args': mduv380g_args, + 'cpp_args': mduv380g_args, 'link_args' : ['-Wl,-T../platform/mcu/STM32F4xx/linker_script.ld', '-Wl,--print-memory-usage'], 'include_directories': mduv380_inc} gd77_opts = {'sources': gd77_src, 'c_args': gd77_args, + 'cpp_args': gd77_args, 'link_args' : ['-Wl,-T../platform/mcu/MK22FN512xxx12/linker_script.ld', '-Wl,--print-memory-usage'], 'include_directories':gd77_inc} dm1801_opts = {'sources': dm1801_src, 'c_args': dm1801_args, + 'cpp_args': dm1801_args, 'link_args' : ['-Wl,-T../platform/mcu/MK22FN512xxx12/linker_script.ld', '-Wl,--print-memory-usage'], 'include_directories':dm1801_inc} md9600_opts = {'sources': md9600_src, 'c_args': md9600_args, + 'cpp_args': md9600_args, 'link_args' : ['-Wl,-T../platform/mcu/STM32F4xx/linker_script.ld', '-Wl,--print-memory-usage'], 'include_directories': md9600_inc} diff --git a/openrtx/include/event.h b/openrtx/include/event.h index b681d14d..5019cc5a 100644 --- a/openrtx/include/event.h +++ b/openrtx/include/event.h @@ -48,7 +48,7 @@ typedef union payload : 30; }; - void *value; + uint32_t value; }event_t; #endif /* EVENT_H */ diff --git a/openrtx/include/queue.h b/openrtx/include/queue.h new file mode 100644 index 00000000..25b29ac5 --- /dev/null +++ b/openrtx/include/queue.h @@ -0,0 +1,26 @@ +#include +#include +#include +#include +#include + +// Ring buffer size (MAX = 255) +#define MSG_QTY 10 + +typedef struct queue_t +{ + pthread_mutex_t mutex; + pthread_cond_t not_empty; + uint8_t read_pos; + uint8_t write_pos; + uint8_t msg_num; + uint32_t buffer[MSG_QTY]; +} queue_t; + +void queue_init(queue_t *q); + +void queue_terminate(queue_t *q); + +bool queue_pend(queue_t *q, uint32_t *msg, bool blocking); + +bool queue_post(queue_t *q, uint32_t msg); diff --git a/openrtx/include/threads.h b/openrtx/include/threads.h index ce4f203b..3a2f3c15 100644 --- a/openrtx/include/threads.h +++ b/openrtx/include/threads.h @@ -28,7 +28,7 @@ */ void create_threads(); -#ifdef __arm__ +// #ifdef __arm__ /** * Stack size for UI task, in bytes. @@ -55,30 +55,30 @@ void create_threads(); */ #define GPS_TASK_STKSIZE 2048 -#else /* __arm__ */ - -#define UI_TASK_STKSIZE 4096 - -/** - * Stack size for Keyboard task, in bytes. - */ -#define KBD_TASK_STKSIZE 256 - -/** - * Stack size for device update task, in bytes. - */ -#define DEV_TASK_STKSIZE 1024 - -/** - * Stack size for baseband control task, in bytes. - */ -#define RTX_TASK_STKSIZE 1024 - -/** - * Stack size for GPS task, in bytes. - */ -#define GPS_TASK_STKSIZE 1024 - -#endif /* __arm__ */ +// #else /* __arm__ */ +// +// #define UI_TASK_STKSIZE 4096 +// +// /** +// * Stack size for Keyboard task, in bytes. +// */ +// #define KBD_TASK_STKSIZE 256 +// +// /** +// * Stack size for device update task, in bytes. +// */ +// #define DEV_TASK_STKSIZE 1024 +// +// /** +// * Stack size for baseband control task, in bytes. +// */ +// #define RTX_TASK_STKSIZE 1024 +// +// /** +// * Stack size for GPS task, in bytes. +// */ +// #define GPS_TASK_STKSIZE 1024 +// +// #endif /* __arm__ */ #endif /* THREADS_H */ diff --git a/openrtx/src/graphics.c b/openrtx/src/graphics.c index 239b43b1..c0406797 100644 --- a/openrtx/src/graphics.c +++ b/openrtx/src/graphics.c @@ -22,7 +22,6 @@ * It is suitable for both color, grayscale and B/W display */ -#include #include #include #include diff --git a/openrtx/src/main.c b/openrtx/src/main.c index 5915cd5e..6cac1d59 100644 --- a/openrtx/src/main.c +++ b/openrtx/src/main.c @@ -18,7 +18,6 @@ * along with this program; if not, see * ***************************************************************************/ -#include #include #include #include @@ -26,12 +25,11 @@ #include #include #include +#include #include int main(void) { - OS_ERR os_err; - // Initialize platform drivers platform_init(); @@ -46,11 +44,11 @@ int main(void) gfx_render(); // Wait 30ms before turning on backlight to hide random pixels on screen - OSTimeDlyHMSM(0u, 0u, 0u, 30u, OS_OPT_TIME_HMSM_STRICT, &os_err); + sleepFor(0u, 30u); platform_setBacklightLevel(255); // Keep the splash screen for 1 second - OSTimeDlyHMSM(0u, 0u, 1u, 0u, OS_OPT_TIME_HMSM_STRICT, &os_err); + sleepFor(1u, 0u); // Create OpenRTX threads create_threads(); diff --git a/openrtx/src/queue.c b/openrtx/src/queue.c new file mode 100644 index 00000000..9f199c46 --- /dev/null +++ b/openrtx/src/queue.c @@ -0,0 +1,68 @@ +#include +#include "queue.h" + +void queue_init(queue_t *q) { + if(q == NULL) + return; + pthread_mutex_init(&q->mutex, NULL); + pthread_cond_init(&q->not_empty, NULL); + q->read_pos = 0; + q->write_pos = 0; + q->msg_num = 0; +} + +void queue_terminate(queue_t *q) { + if(q == NULL) + return; + pthread_mutex_destroy(&q->mutex); + pthread_cond_destroy(&q->not_empty); +} + +bool queue_pend(queue_t *q, uint32_t *msg, bool blocking) { + if((q == NULL) || (msg == NULL)) + return false; + pthread_mutex_lock(&q->mutex); + // The queue is empty + if(q->msg_num == 0) + { + if(blocking) + { + while(q->msg_num == 0) + pthread_cond_wait(&q->not_empty, &q->mutex); + } + else + { + pthread_mutex_unlock(&q->mutex); + return false; + } + } + *msg = q->buffer[q->read_pos]; + // Wrap around pointer to make a circular buffer + q->read_pos = (q->read_pos + 1) % MSG_QTY; + q->msg_num -= 1; + pthread_mutex_unlock(&q->mutex); + return true; +} + +bool queue_post(queue_t *q, uint32_t msg) { + if(q == NULL) + return false; + pthread_mutex_lock(&q->mutex); + if(q->msg_num < MSG_QTY) + { + q->buffer[q->write_pos] = msg; + // Wrap around pointer to make a circular buffer + q->write_pos = (q->write_pos + 1) % MSG_QTY; + // Signal that the queue is not empty + if(q->msg_num == 0) + pthread_cond_signal(&q->not_empty); + q->msg_num += 1; + } + else + { + pthread_mutex_unlock(&q->mutex); + return false; + } + pthread_mutex_unlock(&q->mutex); + return true; +} diff --git a/openrtx/src/rtx.c b/openrtx/src/rtx.c index c759a016..1a788703 100644 --- a/openrtx/src/rtx.c +++ b/openrtx/src/rtx.c @@ -26,15 +26,15 @@ #include #include -OS_MUTEX *cfgMutex; /* Mutex for incoming config messages */ -OS_Q cfgMailbox; /* Queue for incoming config messages */ +pthread_mutex_t *cfgMutex; /* Mutex for incoming config messages */ -rtxStatus_t rtxStatus; /* RTX driver status */ +const rtxStatus_t *newCnf; /* Pointer for incoming config messages */ +rtxStatus_t rtxStatus; /* RTX driver status */ -bool sqlOpen; /* Flag for squelch open/close */ -bool enterRx; /* Flag for RX mode activation */ +bool sqlOpen; /* Flag for squelch open/close */ +bool enterRx; /* Flag for RX mode activation */ -float rssi; /* Current RSSI in dBm */ +float rssi; /* Current RSSI in dBm */ /* * These functions below provide a basic API for audio path management. They @@ -100,17 +100,11 @@ void _afCtrlTerminate() } -void rtx_init(OS_MUTEX *m) +void rtx_init(pthread_mutex_t *m) { /* Initialise mutex for configuration access */ cfgMutex = m; - - /* Create the message queue for RTX configuration */ - OS_ERR err; - OSQCreate((OS_Q *) &cfgMailbox, - (CPU_CHAR *) "", - (OS_MSG_QTY) 1, - (OS_ERR *) &err); + newCnf = NULL; /* * Default initialisation for rtx status @@ -152,28 +146,9 @@ void rtx_terminate() void rtx_configure(const rtxStatus_t *cfg) { - OS_ERR err; - OSQPost((OS_Q *) &cfgMailbox, - (void *) cfg, - (OS_MSG_SIZE) sizeof(rtxStatus_t *), - (OS_OPT ) OS_OPT_POST_FIFO, - (OS_ERR *) &err); - - /* - * In case message queue is not empty, flush the old and unread configuration - * and post the new one. - */ - if(err == OS_ERR_Q_MAX) - { - OSQFlush((OS_Q *) &cfgMailbox, - (OS_ERR *) &err); - - OSQPost((OS_Q *) &cfgMailbox, - (void *) cfg, - (OS_MSG_SIZE) sizeof(rtxStatus_t *), - (OS_OPT ) OS_OPT_POST_FIFO, - (OS_ERR *) &err); - } + pthread_mutex_lock(cfgMutex); + newCnf = cfg; + pthread_mutex_unlock(cfgMutex); } rtxStatus_t rtx_getCurrentStatus() @@ -183,60 +158,54 @@ rtxStatus_t rtx_getCurrentStatus() void rtx_taskFunc() { - OS_ERR err; - OS_MSG_SIZE size; - void *msg = OSQPend((OS_Q *) &cfgMailbox, - (OS_TICK ) 0, - (OS_OPT ) OS_OPT_PEND_NON_BLOCKING, - (OS_MSG_SIZE *) &size, - (CPU_TS *) NULL, - (OS_ERR *) &err); - /* Configuration update logic */ - if((err == OS_ERR_NONE) && (msg != NULL)) + bool reconfigure = false; + if(pthread_mutex_trylock(cfgMutex) == 0) { - /* Try locking mutex for read access */ - OSMutexPend(cfgMutex, 0, OS_OPT_PEND_NON_BLOCKING, NULL, &err); - - if(err == OS_ERR_NONE) + if(newCnf != NULL) { /* Copy new configuration and override opStatus flags */ uint8_t tmp = rtxStatus.opStatus; - memcpy(&rtxStatus, msg, sizeof(rtxStatus_t)); + memcpy(&rtxStatus, newCnf, sizeof(rtxStatus_t)); rtxStatus.opStatus = tmp; - /* Done, release mutex */ - OSMutexPost(cfgMutex, OS_OPT_POST_NONE, &err); - - /* Update HW configuration */ - radio_setOpmode(rtxStatus.opMode); - radio_setBandwidth(rtxStatus.bandwidth); - radio_setCSS(rtxStatus.rxTone, rtxStatus.txTone); - radio_updateCalibrationParams(&rtxStatus); - - /* - * If currently transmitting or receiving, update VCO frequency and - * call again enableRx/enableTx. - * This is done because the new configuration may have changed the - * RX and TX frequencies, requiring an update of both the VCO - * settings and of some tuning parameters, like APC voltage, which - * are managed by enableRx/enableTx. - */ - if(rtxStatus.opStatus == TX) - { - radio_setVcoFrequency(rtxStatus.txFrequency, true); - radio_enableTx(rtxStatus.txPower, rtxStatus.txToneEn); - } - - if(rtxStatus.opStatus == RX) - { - radio_setVcoFrequency(rtxStatus.rxFrequency, false); - radio_enableRx(); - } - - /* TODO: temporarily force to RX mode if rtx is off. */ - if(rtxStatus.opStatus == OFF) enterRx = true; + reconfigure = true; + newCnf = NULL; } + + pthread_mutex_unlock(cfgMutex); + } + + if(reconfigure) + { + /* Update HW configuration */ + radio_setOpmode(rtxStatus.opMode); + radio_setBandwidth(rtxStatus.bandwidth); + radio_setCSS(rtxStatus.rxTone, rtxStatus.txTone); + radio_updateCalibrationParams(&rtxStatus); + + /* + * If currently transmitting or receiving, update VCO frequency and + * call again enableRx/enableTx. + * This is done because the new configuration may have changed the + * RX and TX frequencies, requiring an update of both the VCO + * settings and of some tuning parameters, like APC voltage, which + * are managed by enableRx/enableTx. + */ + if(rtxStatus.opStatus == TX) + { + radio_setVcoFrequency(rtxStatus.txFrequency, true); + radio_enableTx(rtxStatus.txPower, rtxStatus.txToneEn); + } + + if(rtxStatus.opStatus == RX) + { + radio_setVcoFrequency(rtxStatus.rxFrequency, false); + radio_enableRx(); + } + + /* TODO: temporarily force to RX mode if rtx is off. */ + if(rtxStatus.opStatus == OFF) enterRx = true; } /* RX logic */ diff --git a/openrtx/src/threads.c b/openrtx/src/threads.c index 979ed8f8..a45bc7ec 100644 --- a/openrtx/src/threads.c +++ b/openrtx/src/threads.c @@ -19,7 +19,7 @@ ***************************************************************************/ #include -#include +#include #include #include #include @@ -27,8 +27,10 @@ #include #include #include +#include #include #include +#include #include #ifdef HAS_GPS #include @@ -36,67 +38,31 @@ #endif /* Mutex for concurrent access to state variable */ -static OS_MUTEX state_mutex; - -/* Queue for sending and receiving ui update requests */ -static OS_Q ui_queue; +pthread_mutex_t state_mutex; /* Mutex for concurrent access to RTX state variable */ -static OS_MUTEX rtx_mutex; +pthread_mutex_t rtx_mutex; /* Mutex to avoid reading keyboard during display update */ -static OS_MUTEX display_mutex; +pthread_mutex_t display_mutex; - /**************************** IMPORTANT NOTE *********************************** - * * - * Rationale for "xx_TASK_STKSIZE/sizeof(CPU_STK)": uC/OS-III manages task * - * stack in terms of CPU_STK elements which, on a 32-bit target, are something * - * like uint32_t, that is, one CPU_STK elements takes four bytes. * - * * - * Now, the majority of the world manages stack in terms of *bytes* and this * - * leads to an excessive RAM usage if not properly managed. For example, if * - * we have, say, xx_TASK_SIZE = 128 with these odd CPU_STK elements we end * - * up eating 128*4 = 512 bytes. * - * The simple workaround for this is dividing the stack size by sizeof(CPU_STK)* - *******************************************************************************/ - -/* UI task control block and stack */ -static OS_TCB ui_tcb; -static CPU_STK ui_stk[UI_TASK_STKSIZE/sizeof(CPU_STK)]; - -/* Keyboard task control block and stack */ -static OS_TCB kbd_tcb; -static CPU_STK kbd_stk[KBD_TASK_STKSIZE/sizeof(CPU_STK)]; - -/* Device task control block and stack */ -static OS_TCB dev_tcb; -static CPU_STK dev_stk[DEV_TASK_STKSIZE/sizeof(CPU_STK)]; - -/* Baseband task control block and stack */ -static OS_TCB rtx_tcb; -static CPU_STK rtx_stk[RTX_TASK_STKSIZE/sizeof(CPU_STK)]; - -#ifdef HAS_GPS -/* GPS task control block and stack */ -static OS_TCB gps_tcb; -static CPU_STK gps_stk[GPS_TASK_STKSIZE/sizeof(CPU_STK)]; -#endif +/* Queue for sending and receiving ui update requests */ +queue_t ui_queue; /** * \internal Task function in charge of updating the UI. */ -static void ui_task(void *arg) +void *ui_task(void *arg) { (void) arg; - OS_ERR os_err; - OS_MSG_SIZE msg_size = 0; - rtxStatus_t rtx_cfg; + // RTX needs synchronization bool sync_rtx = true; + rtxStatus_t rtx_cfg; // Get initial state local copy - OSMutexPend(&state_mutex, 0u, OS_OPT_PEND_BLOCKING, 0u, &os_err); - OSMutexPost(&state_mutex, OS_OPT_POST_NONE, &os_err); +// OSMutexPend(&state_mutex, 0u, OS_OPT_PEND_BLOCKING, 0u, &os_err); +// OSMutexPost(&state_mutex, OS_OPT_POST_NONE, &os_err); // Initial GUI draw ui_updateGUI(last_state); @@ -106,23 +72,23 @@ static void ui_task(void *arg) { // Read from the keyboard queue (returns 0 if no message is present) // Copy keyboard_t keys from received void * pointer msg - void *msg = OSQPend(&ui_queue, 0u, OS_OPT_PEND_BLOCKING, - &msg_size, 0u, &os_err); - event_t event = ((event_t) msg); + event_t event; + event.value = 0; + (void) queue_pend(&ui_queue, &event.value, true); // Lock mutex, read and write state - OSMutexPend(&state_mutex, 0u, OS_OPT_PEND_BLOCKING, 0u, &os_err); + pthread_mutex_lock(&state_mutex); // React to keypresses and update FSM inside state ui_updateFSM(event, &sync_rtx); // Update state local copy ui_saveState(); // Unlock mutex - OSMutexPost(&state_mutex, OS_OPT_POST_NONE, &os_err); + pthread_mutex_unlock(&state_mutex); // If synchronization needed take mutex and update RTX configuration if(sync_rtx) { - OSMutexPend(&rtx_mutex, 0, OS_OPT_PEND_BLOCKING, NULL, &os_err); + pthread_mutex_lock(&rtx_mutex); rtx_cfg.opMode = state.channel.mode; rtx_cfg.bandwidth = state.channel.bandwidth; rtx_cfg.rxFrequency = state.channel.rx_frequency; @@ -133,7 +99,7 @@ static void ui_task(void *arg) rtx_cfg.rxTone = ctcss_tone[state.channel.fm.rxTone]; rtx_cfg.txToneEn = state.channel.fm.txToneEn; rtx_cfg.txTone = ctcss_tone[state.channel.fm.txTone]; - OSMutexPost(&rtx_mutex, OS_OPT_POST_NONE, &os_err); + pthread_mutex_unlock(&rtx_mutex); rtx_configure(&rtx_cfg); sync_rtx = false; @@ -142,9 +108,9 @@ static void ui_task(void *arg) // Redraw GUI based on last state copy ui_updateGUI(); // Lock display mutex and render display - OSMutexPend(&display_mutex, 0u, OS_OPT_PEND_BLOCKING, 0u, &os_err); + pthread_mutex_lock(&display_mutex); gfx_render(); - OSMutexPost(&display_mutex, OS_OPT_POST_NONE, &os_err); + pthread_mutex_unlock(&display_mutex); // We don't need a delay because we lock on incoming events // TODO: Enable self refresh when a continuous visualization is enabled @@ -156,17 +122,16 @@ static void ui_task(void *arg) /** * \internal Task function for reading and sending keyboard status. */ -static void kbd_task(void *arg) +void *kbd_task(void *arg) { (void) arg; - OS_ERR os_err; // Initialize keyboard driver kbd_init(); // Allocate timestamp array - OS_TICK key_ts[kbd_num_keys]; - OS_TICK now; + long long key_ts[kbd_num_keys]; + long long now; // Allocate bool array to send only one long-press event bool long_press_sent[kbd_num_keys]; @@ -183,10 +148,10 @@ static void kbd_task(void *arg) long_press = false; send_event = false; // Lock display mutex and read keyboard status - OSMutexPend(&display_mutex, 0u, OS_OPT_PEND_NON_BLOCKING, 0u, &os_err); + pthread_mutex_lock(&display_mutex); keys = kbd_getKeys(); - OSMutexPost(&display_mutex, OS_OPT_POST_NONE, &os_err); - now = OSTimeGet(&os_err); + pthread_mutex_unlock(&display_mutex); + now = getTick(); // The key status has changed if(keys != prev_keys) { @@ -232,29 +197,27 @@ static void kbd_task(void *arg) event.type = EVENT_KBD; event.payload = msg.value; // Send keyboard status in queue - OSQPost(&ui_queue, (void *)event.value, sizeof(event_t), - OS_OPT_POST_FIFO + OS_OPT_POST_NO_SCHED, &os_err); + (void) queue_post(&ui_queue, event.value); } // Save current keyboard state as previous prev_keys = keys; // Read keyboard state at 20Hz - OSTimeDlyHMSM(0u, 0u, 0u, 50u, OS_OPT_TIME_HMSM_STRICT, &os_err); + sleepFor(0u, 50u); } } /** * \internal Task function in charge of updating the radio state. */ -static void dev_task(void *arg) +void *dev_task(void *arg) { (void) arg; - OS_ERR os_err; while(1) { // Lock mutex and update internal state - OSMutexPend(&state_mutex, 0u, OS_OPT_PEND_BLOCKING, 0u, &os_err); + pthread_mutex_lock(&state_mutex); #ifdef HAS_RTC state.time = rtc_getTime(); @@ -268,34 +231,32 @@ static void dev_task(void *arg) state.charge = battery_getCharge(state.v_bat); state.rssi = rtx_getRssi(); - OSMutexPost(&state_mutex, OS_OPT_POST_NONE, &os_err); + pthread_mutex_unlock(&state_mutex); // Signal state update to UI thread event_t dev_msg; dev_msg.type = EVENT_STATUS; dev_msg.payload = 0; - OSQPost(&ui_queue, (void *)dev_msg.value, sizeof(event_t), - OS_OPT_POST_FIFO + OS_OPT_POST_NO_SCHED, &os_err); + (void) queue_post(&ui_queue, dev_msg.value); // Execute state update thread every 1s - OSTimeDlyHMSM(0u, 0u, 1u, 0u, OS_OPT_TIME_HMSM_STRICT, &os_err); + sleepFor(1u, 0u); } } /** * \internal Task function for RTX management. */ -static void rtx_task(void *arg) +void *rtx_task(void *arg) { (void) arg; - OS_ERR os_err; rtx_init(&rtx_mutex); while(1) { rtx_taskFunc(); - OSTimeDlyHMSM(0u, 0u, 0u, 30u, OS_OPT_TIME_HMSM_STRICT, &os_err); + sleepFor(0u, 30u); } } @@ -303,20 +264,19 @@ static void rtx_task(void *arg) /** * \internal Task function for parsing GPS data and updating radio state. */ -static void gps_task(void *arg) +void *gps_task(void *arg) { (void) arg; - OS_ERR os_err; + char line[MINMEA_MAX_LENGTH*10]; - if (!gps_detect(5000)) - return; + if (!gps_detect(5000)) return NULL; gps_init(9600); // Lock mutex to read internal state - OSMutexPend(&state_mutex, 0u, OS_OPT_PEND_BLOCKING, 0u, &os_err); + pthread_mutex_lock(&state_mutex); bool enabled = state.settings.gps_enabled; - OSMutexPost(&state_mutex, OS_OPT_POST_NONE, &os_err); + pthread_mutex_unlock(&state_mutex); if(enabled) gps_enable(); else @@ -328,13 +288,13 @@ static void gps_task(void *arg) if(len != -1) { // Lock mutex and update internal state - OSMutexPend(&state_mutex, 0u, OS_OPT_PEND_BLOCKING, 0u, &os_err); + pthread_mutex_lock(&state_mutex); // GPS readout is blocking, no need to delay here gps_taskFunc(line, len, &state); // Unlock state mutex - OSMutexPost(&state_mutex, OS_OPT_POST_NONE, &os_err); + pthread_mutex_unlock(&state_mutex); } } } @@ -345,107 +305,61 @@ static void gps_task(void *arg) */ void create_threads() { - OS_ERR os_err; - // Create state mutex - OSMutexCreate((OS_MUTEX *) &state_mutex, - (CPU_CHAR *) "State Mutex", - (OS_ERR *) &os_err); - - // Create UI event queue - OSQCreate((OS_Q *) &ui_queue, - (CPU_CHAR *) "UI event queue", - (OS_MSG_QTY ) 10, - (OS_ERR *) &os_err); + pthread_mutex_init(&state_mutex, NULL); // Create RTX state mutex - OSMutexCreate((OS_MUTEX *) &rtx_mutex, - (CPU_CHAR *) "RTX Mutex", - (OS_ERR *) &os_err); + pthread_mutex_init(&rtx_mutex, NULL); // Create display mutex - OSMutexCreate((OS_MUTEX *) &display_mutex, - (CPU_CHAR *) "Display Mutex", - (OS_ERR *) &os_err); + pthread_mutex_init(&display_mutex, NULL); + + // Create UI event queue + queue_init(&ui_queue); // State initialization, execute before starting all tasks state_init(); // Create rtx radio thread - OSTaskCreate((OS_TCB *) &rtx_tcb, - (CPU_CHAR *) "RTX Task", - (OS_TASK_PTR ) rtx_task, - (void *) 0, - (OS_PRIO ) 5, - (CPU_STK *) &rtx_stk[0], - (CPU_STK ) 0, - (CPU_STK_SIZE) RTX_TASK_STKSIZE/sizeof(CPU_STK), - (OS_MSG_QTY ) 0, - (OS_TICK ) 0, - (void *) 0, - (OS_OPT ) (OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR), - (OS_ERR *) &os_err); + pthread_t rtx_thread; + pthread_attr_t rtx_attr; + + pthread_attr_init(&rtx_attr); + pthread_attr_setstacksize(&rtx_attr, RTX_TASK_STKSIZE); + pthread_create(&rtx_thread, &rtx_attr, rtx_task, NULL); // Create UI thread - OSTaskCreate((OS_TCB *) &ui_tcb, - (CPU_CHAR *) "UI Task", - (OS_TASK_PTR ) ui_task, - (void *) 0, - (OS_PRIO ) 10, - (CPU_STK *) &ui_stk[0], - (CPU_STK ) 0, - (CPU_STK_SIZE) UI_TASK_STKSIZE/sizeof(CPU_STK), - (OS_MSG_QTY ) 0, - (OS_TICK ) 0, - (void *) 0, - (OS_OPT ) (OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR), - (OS_ERR *) &os_err); + pthread_t ui_thread; + pthread_attr_t ui_attr; + + pthread_attr_init(&ui_attr); + pthread_attr_setstacksize(&ui_attr, UI_TASK_STKSIZE); + pthread_create(&ui_thread, &ui_attr, ui_task, NULL); // Create Keyboard thread - OSTaskCreate((OS_TCB *) &kbd_tcb, - (CPU_CHAR *) "Keyboard Task", - (OS_TASK_PTR ) kbd_task, - (void *) 0, - (OS_PRIO ) 20, - (CPU_STK *) &kbd_stk[0], - (CPU_STK ) 0, - (CPU_STK_SIZE) KBD_TASK_STKSIZE/4, - (OS_MSG_QTY ) 0, - (OS_TICK ) 0, - (void *) 0, - (OS_OPT ) (OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR), - (OS_ERR *) &os_err); + pthread_t kbd_thread; + pthread_attr_t kbd_attr; + + pthread_attr_init(&kbd_attr); + pthread_attr_setstacksize(&kbd_attr, KBD_TASK_STKSIZE); +// pthread_create(&kbd_thread, &kbd_attr, kbd_task, NULL); #ifdef HAS_GPS // Create GPS thread - OSTaskCreate((OS_TCB *) &gps_tcb, - (CPU_CHAR *) "GPS Task", - (OS_TASK_PTR ) gps_task, - (void *) 0, - (OS_PRIO ) 25, - (CPU_STK *) &gps_stk[0], - (CPU_STK ) 0, - (CPU_STK_SIZE) GPS_TASK_STKSIZE/sizeof(CPU_STK), - (OS_MSG_QTY ) 0, - (OS_TICK ) 0, - (void *) 0, - (OS_OPT ) (OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR), - (OS_ERR *) &os_err); + pthread_t gps_thread; + pthread_attr_t gps_attr; + + pthread_attr_init(&gps_attr); + pthread_attr_setstacksize(&gps_attr, GPS_TASK_STKSIZE); +// pthread_create(&gps_thread, &gps_attr, gps_task, NULL); + #endif // Create state thread - OSTaskCreate((OS_TCB *) &dev_tcb, - (CPU_CHAR *) "Device Task", - (OS_TASK_PTR ) dev_task, - (void *) 0, - (OS_PRIO ) 30, - (CPU_STK *) &dev_stk[0], - (CPU_STK ) 0, - (CPU_STK_SIZE) DEV_TASK_STKSIZE/sizeof(CPU_STK), - (OS_MSG_QTY ) 0, - (OS_TICK ) 0, - (void *) 0, - (OS_OPT ) (OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR), - (OS_ERR *) &os_err); + pthread_t state_thread; + pthread_attr_t state_attr; + pthread_attr_init(&state_attr); + pthread_attr_setstacksize(&state_attr, DEV_TASK_STKSIZE); +// pthread_create(&state_thread, &state_attr, dev_task, NULL); } diff --git a/platform/mcu/STM32F4xx/boot/bsp.cpp b/platform/mcu/STM32F4xx/boot/bsp.cpp index 25c59f2d..7dd077bb 100644 --- a/platform/mcu/STM32F4xx/boot/bsp.cpp +++ b/platform/mcu/STM32F4xx/boot/bsp.cpp @@ -28,6 +28,7 @@ #include #include #include +#include "../drivers/usb_vcom.h" namespace miosix { @@ -53,7 +54,7 @@ void IRQbspInit() void bspInit2() { - + vcom_init(); } // diff --git a/platform/mcu/STM32F4xx/boot/libc_integration.cpp b/platform/mcu/STM32F4xx/boot/libc_integration.cpp index dc9ab69f..137ba0ce 100644 --- a/platform/mcu/STM32F4xx/boot/libc_integration.cpp +++ b/platform/mcu/STM32F4xx/boot/libc_integration.cpp @@ -17,6 +17,7 @@ #include #include +#include "../drivers/usb_vcom.h" #include "filesystem/file_access.h" using namespace std; @@ -31,11 +32,11 @@ extern "C" { */ int _write_r(struct _reent *ptr, int fd, const void *buf, size_t cnt) { -// if(fd == STDOUT_FILENO || fd == STDERR_FILENO) -// { -// vcom_writeBlock(buf, cnt); -// return cnt; -// } + if(fd == STDOUT_FILENO || fd == STDERR_FILENO) + { + vcom_writeBlock(buf, cnt); + return cnt; + } /* If fd is not stdout or stderr */ ptr->_errno = EBADF; @@ -48,15 +49,14 @@ int _write_r(struct _reent *ptr, int fd, const void *buf, size_t cnt) */ int _read_r(struct _reent *ptr, int fd, void *buf, size_t cnt) { -// if(fd == STDIN_FILENO) -// { -// for(;;) -// { -// ssize_t r = vcom_readBlock(buf, cnt); -// if((r < 0) || (r == (ssize_t)(cnt))) return r; -// } -// } -// else + if(fd == STDIN_FILENO) + { + for(;;) + { + ssize_t r = vcom_readBlock(buf, cnt); + if((r < 0) || (r == (ssize_t)(cnt))) return r; + } + } /* If fd is not stdin */ ptr->_errno = EBADF; diff --git a/platform/mcu/STM32F4xx/drivers/usb/usb_bsp.c b/platform/mcu/STM32F4xx/drivers/usb/usb_bsp.c index a9062094..c4b7c9c8 100644 --- a/platform/mcu/STM32F4xx/drivers/usb/usb_bsp.c +++ b/platform/mcu/STM32F4xx/drivers/usb/usb_bsp.c @@ -4,7 +4,7 @@ * @author MCD Application Team * @version V1.1.0 * @date 19-March-2012 - * @brief This file is responsible to offer board support package and is + * @brief This file is responsible to offer board support package and is * configurable by user. ****************************************************************************** * @attention @@ -17,21 +17,20 @@ * * http://www.st.com/software_license_agreement_liberty_v2 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ****************************************************************************** - */ + */ /* Includes ------------------------------------------------------------------*/ #include "usb_bsp.h" #include "usbd_conf.h" #include "stm32f4xx.h" #include -#include #include extern USB_OTG_CORE_HANDLE USB_OTG_dev; @@ -98,10 +97,8 @@ void USB_OTG_BSP_mDelay (const uint32_t msec) delayMs(msec); } -void OTG_FS_IRQHandler(void) +void _Z17OTG_FS_IRQHandlerv(void) { - OSIntEnter(); USBD_OTG_ISR_Handler (&USB_OTG_dev); - OSIntExit(); } diff --git a/platform/mcu/STM32F4xx/drivers/usb_vcom.h b/platform/mcu/STM32F4xx/drivers/usb_vcom.h index 545e6553..be2bf851 100644 --- a/platform/mcu/STM32F4xx/drivers/usb_vcom.h +++ b/platform/mcu/STM32F4xx/drivers/usb_vcom.h @@ -22,6 +22,10 @@ #include #include "stm32f4xx.h" +#ifdef __cplusplus +extern "C" { +#endif + /** * Size of the reception buffer for incoming data from the USB host, in bytes. * NOTE: value is equal to the size of one USB bulk transfer, do not change @@ -53,4 +57,8 @@ ssize_t vcom_writeBlock(const void *buf, size_t len); */ ssize_t vcom_readBlock(void *buf, size_t len); +#ifdef __cplusplus +} +#endif + #endif /* USB_VCOM_H */