diff --git a/README.md b/README.md index 0ebccc1..9afee99 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,13 @@ -# AVR library for vector (dynamic array) +# FreeRTOS based AVR library for vector (dynamic array) ## Features 1. Support of any data types. -2. The maximum size of the veсtor is 65535 elements. +2. The maximum size of the veсtor is 255 elements. + +## Dependencies + +1. [zh_avr_free_rtos](http://git.zh.com.ru/avr_libraries/zh_avr_free_rtos) ## Using @@ -11,7 +15,8 @@ In an existing project, run the following command to install the component: ```text cd ../your_project/lib -git clone http://git.zh.com.ru/alexey.zholtikov/zh_avr_vector +git clone http://git.zh.com.ru/avr_libraries/zh_avr_free_rtos +git clone http://git.zh.com.ru/avr_libraries/zh_avr_vector ``` In the application, add the component: @@ -32,26 +37,21 @@ Create, add, read, modify and delete items: #define BAUD_RATE 9600 #define BAUD_PRESCALE (F_CPU / 16 / BAUD_RATE - 1) -void _uart(char byte, FILE *stream) +int usart(char byte, FILE *stream) { while ((UCSR0A & (1 << UDRE0)) == 0) { } UDR0 = byte; + return 0; } -FILE uart = FDEV_SETUP_STREAM(_uart, NULL, _FDEV_SETUP_WRITE); +FILE uart = FDEV_SETUP_STREAM(usart, NULL, _FDEV_SETUP_WRITE); -zh_avr_vector_t vector = {0}; - -char example[10] = {0}; - -int main(void) +void vector_example_task(void *pvParameters) { - UBRR0H = (BAUD_PRESCALE >> 8); - UBRR0L = BAUD_PRESCALE; - UCSR0B = (1 << RXEN0) | (1 << TXEN0); - UCSR0C = (1 << UCSZ01) | (1 << UCSZ00); - stdout = &uart; + zh_avr_vector_t vector = {0}; + char example[10] = {0}; + printf("Free Heap %d.\n", xPortGetFreeHeapSize()); zh_avr_vector_init(&vector, sizeof(example)); printf("Initial vector size is: %d\n", zh_avr_vector_get_size(&vector)); strcpy(example, "Item 1"); @@ -67,22 +67,36 @@ int main(void) printf("Add 5 items. New vector size is: %d\n", zh_avr_vector_get_size(&vector)); for (uint16_t i = 0; i < zh_avr_vector_get_size(&vector); ++i) { - printf("Item position %d is: %s\n", i, (char *)zh_avr_vector_get_item(&vector, i)); + printf("Item position %d is: %s\n", i, (char *)zh_avr_vector_get_item(&vector, i)); } strcpy(example, "Item 6"); zh_avr_vector_change_item(&vector, 3, &example); printf("Change item on 3 position.\n"); for (uint16_t i = 0; i < zh_avr_vector_get_size(&vector); ++i) { - printf("Item position %d is: %s\n", i, (char *)zh_avr_vector_get_item(&vector, i)); + printf("Item position %d is: %s\n", i, (char *)zh_avr_vector_get_item(&vector, i)); } zh_avr_vector_delete_item(&vector, 2); printf("Delete item on 2 position. New vector size is: %d\n", zh_avr_vector_get_size(&vector)); for (uint16_t i = 0; i < zh_avr_vector_get_size(&vector); ++i) { - printf("Item position %d is: %s\n", i, (char *)zh_avr_vector_get_item(&vector, i)); + printf("Item position %d is: %s\n", i, (char *)zh_avr_vector_get_item(&vector, i)); } zh_avr_vector_free(&vector); + printf("Task Remaining Stack Size %d.\n", uxTaskGetStackHighWaterMark(NULL)); + printf("Free Heap %d.\n", xPortGetFreeHeapSize()); + vTaskDelete(NULL); +} + +int main(void) +{ + UBRR0H = (BAUD_PRESCALE >> 8); + UBRR0L = BAUD_PRESCALE; + UCSR0B = (1 << RXEN0) | (1 << TXEN0); + UCSR0C = (1 << UCSZ01) | (1 << UCSZ00); + stdout = &uart; + xTaskCreate(vector_example_task, "vector example task", 136, NULL, tskIDLE_PRIORITY, NULL); + vTaskStartScheduler(); return 0; } ``` diff --git a/include/zh_avr_vector.h b/include/zh_avr_vector.h index f3a07ff..e04a740 100755 --- a/include/zh_avr_vector.h +++ b/include/zh_avr_vector.h @@ -1,5 +1,7 @@ #pragma once +#include "FreeRTOS.h" +#include "task.h" #include "stdlib.h" #include "stdint.h" #include "string.h" @@ -30,11 +32,11 @@ extern "C" typedef struct // Main structure of vector data. { - void **items; // Array of pointers of vector items. - uint16_t capacity; // Maximum capacity of the vector. @note Used to control the size of allocated memory for array of pointers of vector items. Usually equal to the current number of items in the vector. Automatically changes when items are added or deleted. - uint16_t size; // Number of items in the vector. @note Can be read with zh_avr_vector_get_size(). - uint16_t unit; // Vector item size. @note Possible values from 1 to 65535. - bool status; // Vector initialization status flag. @note Used to prevent execution of vector functions without prior vector initialization. + void **items; // Array of pointers of vector items. + uint8_t capacity; // Maximum capacity of the vector. @note Used to control the size of allocated memory for array of pointers of vector items. Usually equal to the current number of items in the vector. Automatically changes when items are added or deleted. + uint8_t size; // Number of items in the vector. @note Can be read with zh_avr_vector_get_size(). + uint8_t unit; // Vector item size. @note Possible values from 1 to 255. + bool status; // Vector initialization status flag. @note Used to prevent execution of vector functions without prior vector initialization. } zh_avr_vector_t; /** @@ -43,22 +45,16 @@ extern "C" * @param[in] vector Pointer to main structure of vector data. * @param[in] unit Size of vector item. * - * @return - * - AVR_OK if initialization was success - * - AVR_ERR_INVALID_ARG if parameter error - * - AVR_ERR_INVALID_STATE if vector already initialized + * @return AVR_OK if success or an error code otherwise. */ - avr_err_t zh_avr_vector_init(zh_avr_vector_t *vector, uint16_t unit); + avr_err_t zh_avr_vector_init(zh_avr_vector_t *vector, uint8_t unit); /** * @brief Deinitialize vector. Free all allocated memory. * * @param[in] vector Pointer to main structure of vector data. * - * @return - * - AVR_OK if deinitialization was success - * - AVR_ERR_INVALID_ARG if parameter error - * - AVR_ERR_INVALID_STATE if vector not initialized + * @return AVR_OK if success or an error code otherwise. */ avr_err_t zh_avr_vector_free(zh_avr_vector_t *vector); @@ -67,9 +63,7 @@ extern "C" * * @param[in] vector Pointer to main structure of vector data. * - * @return - * - Vector size - * - AVR_FAIL if parameter error or vector not initialized + * @return AVR_OK if success or an error code otherwise. */ avr_err_t zh_avr_vector_get_size(zh_avr_vector_t *vector); @@ -79,11 +73,7 @@ extern "C" * @param[in] vector Pointer to main structure of vector data. * @param[in] item Pointer to item for add. * - * @return - * - AVR_OK if add was success - * - AVR_ERR_INVALID_ARG if parameter error - * - AVR_ERR_NO_MEM if memory allocation fail or no free memory in the heap - * - AVR_ERR_INVALID_STATE if vector not initialized + * @return AVR_OK if success or an error code otherwise. */ avr_err_t zh_avr_vector_push_back(zh_avr_vector_t *vector, void *item); @@ -94,13 +84,9 @@ extern "C" * @param[in] index Index of item for change. * @param[in] item Pointer to new data of item. * - * @return - * - AVR_OK if change was success - * - AVR_ERR_INVALID_ARG if parameter error - * - AVR_ERR_INVALID_STATE if vector not initialized - * - AVR_FAIL if index does not exist + * @return AVR_OK if success or an error code otherwise. */ - avr_err_t zh_avr_vector_change_item(zh_avr_vector_t *vector, uint16_t index, void *item); + avr_err_t zh_avr_vector_change_item(zh_avr_vector_t *vector, uint8_t index, void *item); /** * @brief Get item by index. @@ -108,11 +94,9 @@ extern "C" * @param[in] vector Pointer to main structure of vector data. * @param[in] index Index of item for get. * - * @return - * - Pointer to item - * - NULL if parameter error or vector not initialized or if index does not exist + * @return AVR_OK if success or an error code otherwise. */ - void *zh_avr_vector_get_item(zh_avr_vector_t *vector, uint16_t index); + void *zh_avr_vector_get_item(zh_avr_vector_t *vector, uint8_t index); /** * @brief Delete item by index and shifts all elements in vector. @@ -120,13 +104,9 @@ extern "C" * @param[in] vector Pointer to main structure of vector data. * @param[in] index Index of item for delete. * - * @return - * - AVR_OK if delete was success - * - AVR_ERR_INVALID_ARG if parameter error - * - AVR_ERR_INVALID_STATE if vector not initialized - * - AVR_FAIL if index does not exist + * @return AVR_OK if success or an error code otherwise. */ - avr_err_t zh_avr_vector_delete_item(zh_avr_vector_t *vector, uint16_t index); + avr_err_t zh_avr_vector_delete_item(zh_avr_vector_t *vector, uint8_t index); #ifdef __cplusplus } diff --git a/version.txt b/version.txt index afaf360..359a5b9 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.0.0 \ No newline at end of file +2.0.0 \ No newline at end of file diff --git a/zh_avr_vector.c b/zh_avr_vector.c index 62c1101..e0959c8 100755 --- a/zh_avr_vector.c +++ b/zh_avr_vector.c @@ -6,9 +6,9 @@ return err; \ } -static avr_err_t _resize(zh_avr_vector_t *vector, uint16_t capacity); +static avr_err_t _resize(zh_avr_vector_t *vector, uint8_t capacity); -avr_err_t zh_avr_vector_init(zh_avr_vector_t *vector, uint16_t unit) +avr_err_t zh_avr_vector_init(zh_avr_vector_t *vector, uint8_t unit) { ZH_ERROR_CHECK((vector != NULL || unit != 0), AVR_ERR_INVALID_ARG); ZH_ERROR_CHECK(vector->status != true, AVR_ERR_INVALID_STATE); @@ -23,11 +23,12 @@ avr_err_t zh_avr_vector_free(zh_avr_vector_t *vector) { ZH_ERROR_CHECK(vector != NULL, AVR_ERR_INVALID_ARG); ZH_ERROR_CHECK(vector->status != false, AVR_ERR_INVALID_STATE); - for (uint16_t i = 0; i < vector->size; ++i) + for (uint8_t i = 0; i < vector->size; ++i) { - free(vector->items[i]); + vPortFree(vector->items[i]); } vector->status = false; + vPortFree(vector->items); return AVR_OK; } @@ -45,13 +46,13 @@ avr_err_t zh_avr_vector_push_back(zh_avr_vector_t *vector, void *item) { ZH_ERROR_CHECK((_resize(vector, vector->capacity + 1) != AVR_ERR_NO_MEM), AVR_ERR_NO_MEM); } - vector->items[vector->size] = calloc(1, vector->unit); + vector->items[vector->size] = pvPortCalloc(1, vector->unit); ZH_ERROR_CHECK(vector->items[vector->size] != NULL, AVR_ERR_NO_MEM); memcpy(vector->items[vector->size++], item, vector->unit); return AVR_OK; } -avr_err_t zh_avr_vector_change_item(zh_avr_vector_t *vector, uint16_t index, void *item) +avr_err_t zh_avr_vector_change_item(zh_avr_vector_t *vector, uint8_t index, void *item) { ZH_ERROR_CHECK((vector != NULL || item != NULL), AVR_ERR_INVALID_ARG); ZH_ERROR_CHECK(vector->status != false, AVR_ERR_INVALID_STATE); @@ -63,7 +64,7 @@ avr_err_t zh_avr_vector_change_item(zh_avr_vector_t *vector, uint16_t index, voi return AVR_FAIL; } -void *zh_avr_vector_get_item(zh_avr_vector_t *vector, uint16_t index) +void *zh_avr_vector_get_item(zh_avr_vector_t *vector, uint8_t index) { ZH_ERROR_CHECK((vector != NULL || vector->status != false), NULL); if (index < vector->size) @@ -77,31 +78,34 @@ void *zh_avr_vector_get_item(zh_avr_vector_t *vector, uint16_t index) } } -avr_err_t zh_avr_vector_delete_item(zh_avr_vector_t *vector, uint16_t index) +avr_err_t zh_avr_vector_delete_item(zh_avr_vector_t *vector, uint8_t index) { ZH_ERROR_CHECK(vector != NULL, AVR_ERR_INVALID_ARG); ZH_ERROR_CHECK(vector->status != false, AVR_ERR_INVALID_STATE); if (index < vector->size) { - free(vector->items[index]); + vPortFree(vector->items[index]); for (uint8_t i = index; i < (vector->size - 1); ++i) { vector->items[i] = vector->items[i + 1]; vector->items[i + 1] = NULL; } --vector->size; - _resize(vector, vector->capacity - 1); + ZH_ERROR_CHECK((_resize(vector, vector->capacity - 1) != AVR_ERR_NO_MEM), AVR_ERR_NO_MEM); return AVR_OK; } return AVR_FAIL; } -static avr_err_t _resize(zh_avr_vector_t *vector, uint16_t capacity) +static avr_err_t _resize(zh_avr_vector_t *vector, uint8_t capacity) { if (capacity != 0) { - vector->items = realloc(vector->items, sizeof(void *) * capacity); - ZH_ERROR_CHECK(vector->items != NULL, AVR_ERR_NO_MEM); + void *items = pvPortCalloc(capacity, sizeof(void *) * capacity); + ZH_ERROR_CHECK(items != NULL, AVR_ERR_NO_MEM); + memcpy(items, vector->items, sizeof(void *) * capacity); + vPortFree(vector->items); + vector->items = items; } vector->capacity = capacity; return AVR_OK;