Moving to miosix kernel: swapped old uC/OS-III task management functions with pthread ones

replace/f3fc701f24a2f962f6a16b2e6d468db8eb38ccfd
Silvano Seva 2021-03-10 16:32:40 +01:00
rodzic 2b28ea0525
commit fb3447b0c6
13 zmienionych plików z 327 dodań i 383 usunięć

Wyświetl plik

@ -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}

Wyświetl plik

@ -48,7 +48,7 @@ typedef union
payload : 30;
};
void *value;
uint32_t value;
}event_t;
#endif /* EVENT_H */

Wyświetl plik

@ -0,0 +1,26 @@
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
// 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);

Wyświetl plik

@ -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 */

Wyświetl plik

@ -22,7 +22,6 @@
* It is suitable for both color, grayscale and B/W display
*/
#include <os.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>

Wyświetl plik

@ -18,7 +18,6 @@
* along with this program; if not, see <http://www.gnu.org/licenses/> *
***************************************************************************/
#include <os.h>
#include <ui.h>
#include <stdlib.h>
#include <inttypes.h>
@ -26,12 +25,11 @@
#include <interfaces/platform.h>
#include <battery.h>
#include <interfaces/graphics.h>
#include <interfaces/delays.h>
#include <hwconfig.h>
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();

Wyświetl plik

@ -0,0 +1,68 @@
#include <stdio.h>
#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;
}

Wyświetl plik

@ -26,15 +26,15 @@
#include <interfaces/gpio.h>
#include <hwconfig.h>
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 */

Wyświetl plik

@ -19,7 +19,7 @@
***************************************************************************/
#include <hwconfig.h>
#include <os.h>
#include <pthread.h>
#include <ui.h>
#include <state.h>
#include <threads.h>
@ -27,8 +27,10 @@
#include <interfaces/keyboard.h>
#include <interfaces/graphics.h>
#include <interfaces/platform.h>
#include <interfaces/delays.h>
#include <event.h>
#include <rtx.h>
#include <queue.h>
#include <minmea.h>
#ifdef HAS_GPS
#include <interfaces/gps.h>
@ -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);
}

Wyświetl plik

@ -28,6 +28,7 @@
#include <kernel/kernel.h>
#include <kernel/sync.h>
#include <hwconfig.h>
#include "../drivers/usb_vcom.h"
namespace miosix
{
@ -53,7 +54,7 @@ void IRQbspInit()
void bspInit2()
{
vcom_init();
}
//

Wyświetl plik

@ -17,6 +17,7 @@
#include <stdio.h>
#include <reent.h>
#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;

Wyświetl plik

@ -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 <interfaces/gpio.h>
#include <os.h>
#include <interfaces/delays.h>
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();
}

Wyświetl plik

@ -22,6 +22,10 @@
#include <unistd.h>
#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 */