feat!: freertos support implemented

This commit is contained in:
2025-08-10 19:41:06 +03:00
parent 8597685a51
commit 8f02ea625c
4 changed files with 68 additions and 70 deletions

View File

@@ -1,9 +1,13 @@
# AVR library for vector (dynamic array) # FreeRTOS based AVR library for vector (dynamic array)
## Features ## Features
1. Support of any data types. 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 ## Using
@@ -11,7 +15,8 @@ In an existing project, run the following command to install the component:
```text ```text
cd ../your_project/lib 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: In the application, add the component:
@@ -32,26 +37,21 @@ Create, add, read, modify and delete items:
#define BAUD_RATE 9600 #define BAUD_RATE 9600
#define BAUD_PRESCALE (F_CPU / 16 / BAUD_RATE - 1) #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) while ((UCSR0A & (1 << UDRE0)) == 0)
{ {
} }
UDR0 = byte; 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}; void vector_example_task(void *pvParameters)
char example[10] = {0};
int main(void)
{ {
UBRR0H = (BAUD_PRESCALE >> 8); zh_avr_vector_t vector = {0};
UBRR0L = BAUD_PRESCALE; char example[10] = {0};
UCSR0B = (1 << RXEN0) | (1 << TXEN0); printf("Free Heap %d.\n", xPortGetFreeHeapSize());
UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);
stdout = &uart;
zh_avr_vector_init(&vector, sizeof(example)); zh_avr_vector_init(&vector, sizeof(example));
printf("Initial vector size is: %d\n", zh_avr_vector_get_size(&vector)); printf("Initial vector size is: %d\n", zh_avr_vector_get_size(&vector));
strcpy(example, "Item 1"); 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)); 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) 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"); strcpy(example, "Item 6");
zh_avr_vector_change_item(&vector, 3, &example); zh_avr_vector_change_item(&vector, 3, &example);
printf("Change item on 3 position.\n"); printf("Change item on 3 position.\n");
for (uint16_t i = 0; i < zh_avr_vector_get_size(&vector); ++i) 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); 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)); 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) 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); 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; return 0;
} }
``` ```

View File

@@ -1,5 +1,7 @@
#pragma once #pragma once
#include "FreeRTOS.h"
#include "task.h"
#include "stdlib.h" #include "stdlib.h"
#include "stdint.h" #include "stdint.h"
#include "string.h" #include "string.h"
@@ -30,11 +32,11 @@ extern "C"
typedef struct // Main structure of vector data. typedef struct // Main structure of vector data.
{ {
void **items; // Array of pointers of vector items. 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. 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.
uint16_t size; // Number of items in the vector. @note Can be read with zh_avr_vector_get_size(). uint8_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. 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. bool status; // Vector initialization status flag. @note Used to prevent execution of vector functions without prior vector initialization.
} zh_avr_vector_t; } zh_avr_vector_t;
/** /**
@@ -43,22 +45,16 @@ extern "C"
* @param[in] vector Pointer to main structure of vector data. * @param[in] vector Pointer to main structure of vector data.
* @param[in] unit Size of vector item. * @param[in] unit Size of vector item.
* *
* @return * @return AVR_OK if success or an error code otherwise.
* - AVR_OK if initialization was success
* - AVR_ERR_INVALID_ARG if parameter error
* - AVR_ERR_INVALID_STATE if vector already initialized
*/ */
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. * @brief Deinitialize vector. Free all allocated memory.
* *
* @param[in] vector Pointer to main structure of vector data. * @param[in] vector Pointer to main structure of vector data.
* *
* @return * @return AVR_OK if success or an error code otherwise.
* - AVR_OK if deinitialization was success
* - AVR_ERR_INVALID_ARG if parameter error
* - AVR_ERR_INVALID_STATE if vector not initialized
*/ */
avr_err_t zh_avr_vector_free(zh_avr_vector_t *vector); 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. * @param[in] vector Pointer to main structure of vector data.
* *
* @return * @return AVR_OK if success or an error code otherwise.
* - Vector size
* - AVR_FAIL if parameter error or vector not initialized
*/ */
avr_err_t zh_avr_vector_get_size(zh_avr_vector_t *vector); 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] vector Pointer to main structure of vector data.
* @param[in] item Pointer to item for add. * @param[in] item Pointer to item for add.
* *
* @return * @return AVR_OK if success or an error code otherwise.
* - 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
*/ */
avr_err_t zh_avr_vector_push_back(zh_avr_vector_t *vector, void *item); 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] index Index of item for change.
* @param[in] item Pointer to new data of item. * @param[in] item Pointer to new data of item.
* *
* @return * @return AVR_OK if success or an error code otherwise.
* - 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
*/ */
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. * @brief Get item by index.
@@ -108,11 +94,9 @@ extern "C"
* @param[in] vector Pointer to main structure of vector data. * @param[in] vector Pointer to main structure of vector data.
* @param[in] index Index of item for get. * @param[in] index Index of item for get.
* *
* @return * @return AVR_OK if success or an error code otherwise.
* - Pointer to item
* - NULL if parameter error or vector not initialized or if index does not exist
*/ */
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. * @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] vector Pointer to main structure of vector data.
* @param[in] index Index of item for delete. * @param[in] index Index of item for delete.
* *
* @return * @return AVR_OK if success or an error code otherwise.
* - 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
*/ */
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 #ifdef __cplusplus
} }

View File

@@ -1 +1 @@
1.0.0 2.0.0

View File

@@ -6,9 +6,9 @@
return err; \ 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 != NULL || unit != 0), AVR_ERR_INVALID_ARG);
ZH_ERROR_CHECK(vector->status != true, AVR_ERR_INVALID_STATE); 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 != NULL, AVR_ERR_INVALID_ARG);
ZH_ERROR_CHECK(vector->status != false, AVR_ERR_INVALID_STATE); 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; vector->status = false;
vPortFree(vector->items);
return AVR_OK; 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); 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); ZH_ERROR_CHECK(vector->items[vector->size] != NULL, AVR_ERR_NO_MEM);
memcpy(vector->items[vector->size++], item, vector->unit); memcpy(vector->items[vector->size++], item, vector->unit);
return AVR_OK; 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 != NULL || item != NULL), AVR_ERR_INVALID_ARG);
ZH_ERROR_CHECK(vector->status != false, AVR_ERR_INVALID_STATE); 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; 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); ZH_ERROR_CHECK((vector != NULL || vector->status != false), NULL);
if (index < vector->size) 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 != NULL, AVR_ERR_INVALID_ARG);
ZH_ERROR_CHECK(vector->status != false, AVR_ERR_INVALID_STATE); ZH_ERROR_CHECK(vector->status != false, AVR_ERR_INVALID_STATE);
if (index < vector->size) if (index < vector->size)
{ {
free(vector->items[index]); vPortFree(vector->items[index]);
for (uint8_t i = index; i < (vector->size - 1); ++i) for (uint8_t i = index; i < (vector->size - 1); ++i)
{ {
vector->items[i] = vector->items[i + 1]; vector->items[i] = vector->items[i + 1];
vector->items[i + 1] = NULL; vector->items[i + 1] = NULL;
} }
--vector->size; --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_OK;
} }
return AVR_FAIL; 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) if (capacity != 0)
{ {
vector->items = realloc(vector->items, sizeof(void *) * capacity); void *items = pvPortCalloc(capacity, sizeof(void *) * capacity);
ZH_ERROR_CHECK(vector->items != NULL, AVR_ERR_NO_MEM); 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; vector->capacity = capacity;
return AVR_OK; return AVR_OK;