diff --git a/common.mk b/common.mk index 7361f70..2880752 100644 --- a/common.mk +++ b/common.mk @@ -99,7 +99,7 @@ C_CXX_FLAGS = -Wall -Werror -Wl,-EL -nostdlib -mlongcalls -mtext-section-lit # Flags for C only CFLAGS = $(C_CXX_FLAGS) -std=gnu99 # Flags for C++ only -CXXFLAGS = $(C_CXX_FLAGS) -fno-exceptions +CXXFLAGS = $(C_CXX_FLAGS) -fno-exceptions -fno-rtti LDFLAGS = -nostdlib -Wl,--no-check-sections -Wl,-L$(BUILD_DIR)sdklib -Wl,-L$(ROOT)lib -u $(ENTRY_SYMBOL) -Wl,-static -Wl,-Map=build/${PROGRAM}.map $(EXTRA_LDFLAGS) ifeq ($(FLAVOR),debug) @@ -177,7 +177,7 @@ IMGTOOL_ARGS=-$(IMGTOOL_FLASH_SIZE) -$(FLASH_MODE) -$(FLASH_SPEED) # Placing $(PROGRAM_DIR) and $(PROGRAM_DIR)include first allows # programs to have their own copies of header config files for components # , which is useful for overriding things. -INC_DIRS = $(PROGRAM_DIR) $(PROGRAM_DIR)include $(ROOT)include +INC_DIRS = $(PROGRAM_DIR) $(PROGRAM_DIR)include $(ROOT)include $(ROOT)extras ifeq ($(OWN_LIBC),1) INC_DIRS += $(ROOT)libc/xtensa-lx106-elf/include diff --git a/examples/cpp_01_tasks/Makefile b/examples/cpp_01_tasks/Makefile new file mode 100644 index 0000000..458932f --- /dev/null +++ b/examples/cpp_01_tasks/Makefile @@ -0,0 +1,3 @@ +# Simple makefile for simple example +PROGRAM=cpp_01_tasks +include ../../common.mk diff --git a/examples/cpp_01_tasks/main.cpp b/examples/cpp_01_tasks/main.cpp new file mode 100644 index 0000000..133d1c5 --- /dev/null +++ b/examples/cpp_01_tasks/main.cpp @@ -0,0 +1,100 @@ +/* + * ESP8266 FreeRTOS Firmware + * Copyright (C) 2015 Michael Jacobsen + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * https://github.com/SuperHouse/esp-open-rtos + * + */ + +#include "cplusplus/cplusplus.hpp" +#include "thread/task.hpp" +#include "thread/queue.hpp" + +#include "espressif/esp_common.h" + +/****************************************************************************************************************** + * task_1_t + * + */ +class task_1_t: public esp_open_rtos::thread::task_t +{ +public: + esp_open_rtos::thread::queue_t queue; + +private: + void task() + { + printf("task_1_t::task(): start\n"); + + uint32_t count = 0; + + while(true) { + sleep(1000); + queue.post(count); + count++; + } + } +}; +/****************************************************************************************************************** + * task_2_t + * + */ +class task_2_t: public esp_open_rtos::thread::task_t +{ +public: + esp_open_rtos::thread::queue_t queue; + +private: + void task() + { + printf("task_2_t::task(): start\n"); + + while(true) { + uint32_t count; + + if(queue.receive(count, 1500) == 0) { + printf("task_2_t::task(): got %lu\n", count); + } + else { + printf("task_2_t::task(): no msg\n"); + } + } + } +}; +/****************************************************************************************************************** + * globals + * + */ +task_1_t task_1; +task_2_t task_2; + +esp_open_rtos::thread::queue_t MyQueue; + +/** + * + */ +extern "C" void user_init(void) +{ + sdk_uart_div_modify(0, UART_CLK_FREQ / 115200); + + MyQueue.create(10); + + task_1.queue = MyQueue; + task_2.queue = MyQueue; + + task_1.task_create("tsk1"); + task_2.task_create("tsk2"); +} \ No newline at end of file diff --git a/extras/cplusplus/component.mk b/extras/cplusplus/component.mk new file mode 100644 index 0000000..3f5673d --- /dev/null +++ b/extras/cplusplus/component.mk @@ -0,0 +1,3 @@ +# Component makefile for extras/cplusplus + +INC_DIRS += $(ROOT)extras diff --git a/extras/cplusplus/cplusplus.hpp b/extras/cplusplus/cplusplus.hpp new file mode 100644 index 0000000..cc58031 --- /dev/null +++ b/extras/cplusplus/cplusplus.hpp @@ -0,0 +1,68 @@ +/* + * ESP8266 FreeRTOS Firmware + * Copyright (C) 2015 Michael Jacobsen + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * https://github.com/SuperHouse/esp-open-rtos + * + */ + +#ifndef COM_THOLUSI_ESP_OPEN_RTOS_CPLUSPLUS_HPP +#define COM_THOLUSI_ESP_OPEN_RTOS_CPLUSPLUS_HPP + +#include + +/****************************************************************************************************************** + * C++ new and delete operators + * + */ + +/** + * + * @param size + * @return + */ +inline void *operator new(size_t size) +{ + return malloc(size); +} +/** + * + * @param size + * @return + */ +inline void *operator new[](size_t size) +{ + return malloc(size); +} +/** + * + * @param ptr + */ +inline void operator delete(void * ptr) +{ + free(ptr); +} +/** + * + * @param ptr + */ +inline void operator delete[](void * ptr) +{ + free(ptr); +} + +#endif /* COM_THOLUSI_ESP_OPEN_RTOS_CPLUSPLUS_HPP */ + diff --git a/extras/thread/component.mk b/extras/thread/component.mk new file mode 100644 index 0000000..46193ef --- /dev/null +++ b/extras/thread/component.mk @@ -0,0 +1,3 @@ +# Component makefile for extras/thread + +INC_DIRS += $(ROOT)extras diff --git a/extras/thread/mutex.hpp b/extras/thread/mutex.hpp new file mode 100644 index 0000000..d3db1da --- /dev/null +++ b/extras/thread/mutex.hpp @@ -0,0 +1,90 @@ +/* + * ESP8266 FreeRTOS Firmware + * Copyright (C) 2015 Michael Jacobsen + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * https://github.com/SuperHouse/esp-open-rtos + * + */ + +#ifndef COM_THOLUSI_ESP_OPEN_RTOS_MUTEX_HPP +#define COM_THOLUSI_ESP_OPEN_RTOS_MUTEX_HPP + +#include "semphr.h" + +namespace esp_open_rtos { +namespace thread { + +/****************************************************************************************************************** + * class mutex_t + * + */ +class mutex_t +{ +public: + /** + * + */ + inline mutex_t() + { + mutex = xSemaphoreCreateMutex(); + } + /** + * + */ + inline ~mutex_t() + { + vQueueDelete(mutex); + } + /** + * + * @return + */ + inline int lock() + { + return (xSemaphoreTake(mutex, portMAX_DELAY) == pdTRUE) ? 0 : -1; + } + /** + * + * @param ms + * @return + */ + inline int try_lock(unsigned long ms) + { + return (xSemaphoreTake(mutex, ms / portTICK_RATE_MS) == pdTRUE) ? 0 : -1; + } + /** + * + * @return + */ + inline int unlock() + { + return (xSemaphoreGive(mutex) == pdTRUE) ? 0 : -1; + } + +private: + xSemaphoreHandle mutex; + + // Disable copy construction and assignment. + mutex_t (const mutex_t&); + const mutex_t &operator = (const mutex_t&); +}; + +} //namespace thread { +} //namespace esp_open_rtos { + + +#endif /* COM_THOLUSI_ESP_OPEN_RTOS_MUTEX_HPP */ + diff --git a/extras/thread/queue.hpp b/extras/thread/queue.hpp new file mode 100644 index 0000000..fd14166 --- /dev/null +++ b/extras/thread/queue.hpp @@ -0,0 +1,120 @@ +/* + * ESP8266 FreeRTOS Firmware + * Copyright (C) 2015 Michael Jacobsen + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * https://github.com/SuperHouse/esp-open-rtos + * + */ + +#ifndef COM_THOLUSI_ESP_OPEN_RTOS_QUEUE_HPP +#define COM_THOLUSI_ESP_OPEN_RTOS_QUEUE_HPP + +#include "FreeRTOS.h" +#include "queue.h" + +namespace esp_open_rtos { +namespace thread { + +/****************************************************************************************************************** + * class queue_t + * + */ +template +class queue_t +{ +public: + /** + * + */ + inline queue_t() + { + queue = 0; + } + /** + * + * @param uxQueueLength + * @param uxItemSize + * @return + */ + inline int create(unsigned portBASE_TYPE uxQueueLength) + { + queue = xQueueCreate(uxQueueLength, sizeof(Data)); + + if(queue == NULL) { + return -1; + } + else { + return 0; + } + } + /** + * + * @param data + * @param ms + * @return + */ + inline void destroy() + { + vQueueDelete(queue); + queue = 0; + } + /** + * + * @param data + * @param ms + * @return + */ + inline int post(const Data& data, unsigned long ms = 0) + { + return (xQueueSend(queue, &data, ms / portTICK_RATE_MS) == pdTRUE) ? 0 : -1; + } + /** + * + * @param data + * @param ms + * @return + */ + inline int receive(Data& data, unsigned long ms = 0) + { + return (xQueueReceive(queue, &data, ms / portTICK_RATE_MS) == pdTRUE) ? 0 : -1; + } + /** + * + * @param other + * @return + */ + const queue_t &operator = (const queue_t& other) + { + if(this != &other) { // protect against invalid self-assignment + queue = other.queue; + } + + return *this; + } + +private: + xQueueHandle queue; + + // Disable copy construction. + queue_t (const queue_t&); +}; + +} //namespace thread { +} //namespace esp_open_rtos { + + +#endif /* COM_THOLUSI_ESP_OPEN_RTOS_QUEUE_HPP */ + diff --git a/extras/thread/task.hpp b/extras/thread/task.hpp new file mode 100644 index 0000000..dc527f0 --- /dev/null +++ b/extras/thread/task.hpp @@ -0,0 +1,99 @@ +/* + * ESP8266 FreeRTOS Firmware + * Copyright (C) 2015 Michael Jacobsen + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * https://github.com/SuperHouse/esp-open-rtos + * + */ + +#ifndef COM_THOLUSI_ESP_OPEN_RTOS_TASK_HPP +#define COM_THOLUSI_ESP_OPEN_RTOS_TASK_HPP + +#include "FreeRTOS.h" +#include "task.h" + +namespace esp_open_rtos { +namespace thread { + +/****************************************************************************************************************** + * task_t + * + */ +class task_t +{ +public: + /** + * + */ + task_t() + {} + /** + * + * @param pcName + * @param usStackDepth + * @param uxPriority + * @return + */ + int task_create(const char* const pcName, unsigned short usStackDepth = 256, unsigned portBASE_TYPE uxPriority = 2) + { + return xTaskCreate(task_t::_task, (signed char *)pcName, usStackDepth, this, uxPriority, NULL); + } + +protected: + /** + * + * @param ms + */ + void sleep(unsigned long ms) + { + vTaskDelay(ms / portTICK_RATE_MS); + } + /** + * + * @return + */ + inline unsigned long millis() + { + return xTaskGetTickCount() * portTICK_RATE_MS; + } + +private: + /** + * + */ + virtual void task() = 0; + /** + * + * @param pvParameters + */ + static void _task(void* pvParameters) + { + if(pvParameters != 0) { + ((task_t*)(pvParameters))->task(); + } + } + + // no copy and no = operator + task_t(const task_t&); + task_t &operator=(const task_t&); +}; + +} //namespace thread { +} //namespace esp_open_rtos { + + +#endif /* COM_THOLUSI_ESP_OPEN_RTOS_TASK_HPP */ + diff --git a/extras/timer/component.mk b/extras/timer/component.mk new file mode 100644 index 0000000..255ebae --- /dev/null +++ b/extras/timer/component.mk @@ -0,0 +1,3 @@ +# Component makefile for extras/timer + +INC_DIRS += $(ROOT)extras diff --git a/extras/timer/countdown.hpp b/extras/timer/countdown.hpp new file mode 100644 index 0000000..ff1a2bf --- /dev/null +++ b/extras/timer/countdown.hpp @@ -0,0 +1,95 @@ +/* + * ESP8266 FreeRTOS Firmware + * Copyright (C) 2015 Michael Jacobsen + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * https://github.com/SuperHouse/esp-open-rtos + * + */ + +#ifndef COM_THOLUSI_ESP_OPEN_RTOS_TIMER_HPP +#define COM_THOLUSI_ESP_OPEN_RTOS_TIMER_HPP + +#include "FreeRTOS.h" +#include "task.h" + +namespace esp_open_rtos { +namespace timer { + +#define __millis() (xTaskGetTickCount() * portTICK_RATE_MS) + +/****************************************************************************************************************** + * countdown_t + * + */ +class countdown_t +{ +public: + /** + * + */ + countdown_t() + { + interval_end_ms = 0L; + } + /** + * + * @param ms + */ + countdown_t(int ms) + { + countdown_ms(ms); + } + /** + * + * @return + */ + bool expired() + { + return (interval_end_ms > 0L) && (__millis() >= interval_end_ms); + } + /** + * + * @param ms + */ + void countdown_ms(unsigned long ms) + { + interval_end_ms = __millis() + ms; + } + /** + * + * @param seconds + */ + void countdown(int seconds) + { + countdown_ms((unsigned long)seconds * 1000L); + } + /** + * + * @return + */ + int left_ms() + { + return interval_end_ms - __millis(); + } + +private: + portTickType interval_end_ms; +}; + +} // namespace timer { +} // namespace esp_open_rtos { + +#endif