Skip to content

Commit 66a9b4d

Browse files
committed
Add image filtering to freeRTOS and fixes
1 parent b298f84 commit 66a9b4d

File tree

8 files changed

+397
-23
lines changed

8 files changed

+397
-23
lines changed
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
#include "FreeRTOS.h"
2+
#include "task.h"
3+
#include "queue.h"
4+
#include "timers.h"
5+
6+
#include <stdio.h>
7+
#include <string.h>
8+
9+
//Testbench Defines
10+
#define IMAG_ROWS 452
11+
#define IMAG_COLS 640
12+
#define RBG_CHANNELS_NUM 3
13+
#define GRAY_CHANNELS_NUM 1
14+
15+
//Testbench Includes
16+
#include "../inc/address_map.hpp"
17+
#include "../inc/common_func.hpp"
18+
// #include "tb_aux_functions.c"
19+
// #include "img_unification.c"
20+
//#include "img_filtering.cpp"
21+
22+
#define TRACE (*(unsigned char *)0x40000000)
23+
24+
extern void register_timer_isr();
25+
26+
QueueHandle_t my_queue = NULL;
27+
28+
static void task_1(void *pParameter) {
29+
30+
int data = 5;
31+
printf("Task 1 starts\n");
32+
33+
while(1) {
34+
printf("T1: Tick %ld\n", xTaskGetTickCount() );
35+
xQueueSend(my_queue, &data, portMAX_DELAY);
36+
vTaskDelay(100 / portTICK_PERIOD_MS);
37+
}
38+
}
39+
40+
static void task_2(void *pParameter) {
41+
42+
int data = 7;
43+
44+
printf("Task 2 starts\n");
45+
46+
while(1) {
47+
printf("T2: Tick %ld\n", xTaskGetTickCount() );
48+
xQueueSend(my_queue, &data, portMAX_DELAY);
49+
vTaskDelay(500 / portTICK_PERIOD_MS);
50+
}
51+
}
52+
53+
static void task_3(void *pParameter) {
54+
int data;
55+
56+
printf("Task 3 starts\n");
57+
58+
while(1) {
59+
xQueueReceive(my_queue, &data, portMAX_DELAY);
60+
printf("T3: Tick %ld. Recv: %ld\n", xTaskGetTickCount(), data);
61+
//vTaskDelay(1000 / portTICK_PERIOD_MS);
62+
}
63+
64+
}
65+
66+
static void testbench(void *pParameter) {
67+
68+
//Set the pointers to memory, where images are stored
69+
unsigned char *img_x = (unsigned char*) IMG_INPUT_ADDRESS_LO;
70+
unsigned char *img_y = (unsigned char*) IMG_INPUT_ADDRESS_LO + IMAG_ROWS*IMAG_COLS;
71+
unsigned char *img_result = (unsigned char*) IMG_OUTPUT_ADDRESS_LO;
72+
73+
printf("Starting Testbench\n");
74+
75+
printf("Starting IMG Filtering Step: \n");
76+
filter_img(img_x, img_result, IMAG_ROWS, IMAG_COLS);
77+
printf("Done IMG Filtering Step: \n");
78+
79+
// printf("Starting IMG Unification Step: \n");
80+
// unificate_img(img_x, img_y, img_result, IMAG_ROWS*IMAG_COLS, GRAY_CHANNELS_NUM);
81+
// printf("Done IMG Unification Step: \n");
82+
83+
printf("Testbench Done\n");
84+
}
85+
86+
int main( void )
87+
{
88+
BaseType_t xReturned;
89+
printf("Starting FreeRTOS test\n");
90+
91+
/* Create tasks */
92+
xReturned = xTaskCreate(testbench, "test_unificate", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY+1, NULL);
93+
94+
printf("Returned: %0d\n", xReturned);
95+
/* Start the kernel. From here on, only tasks and interrupts will run. */
96+
vTaskStartScheduler();
97+
98+
/* Exit FreeRTOS */
99+
return 0;
100+
}
101+
102+
void vApplicationMallocFailedHook( void )
103+
{
104+
/* vApplicationMallocFailedHook() will only be called if
105+
configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook
106+
function that will get called if a call to pvPortMalloc() fails.
107+
pvPortMalloc() is called internally by the kernel whenever a task, queue,
108+
timer or semaphore is created. It is also called by various parts of the
109+
demo application. If heap_1.c or heap_2.c are used, then the size of the
110+
heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in
111+
FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used
112+
to query the size of free heap space that remains (although it does not
113+
provide information on how the remaining heap might be fragmented). */
114+
taskDISABLE_INTERRUPTS();
115+
116+
TRACE='M';
117+
for( ;; );
118+
}
119+
/*-----------------------------------------------------------*/
120+
121+
void vApplicationIdleHook( void )
122+
{
123+
/* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set
124+
to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle
125+
task. It is essential that code added to this hook function never attempts
126+
to block in any way (for example, call xQueueReceive() with a block time
127+
specified, or call vTaskDelay()). If the application makes use of the
128+
vTaskDelete() API function (as this demo application does) then it is also
129+
important that vApplicationIdleHook() is permitted to return to its calling
130+
function, because it is the responsibility of the idle task to clean up
131+
memory allocated by the kernel to any task that has since been deleted. */
132+
}
133+
/*-----------------------------------------------------------*/
134+
135+
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
136+
{
137+
( void ) pcTaskName;
138+
( void ) pxTask;
139+
140+
/* Run time stack overflow checking is performed if
141+
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
142+
function is called if a stack overflow is detected. */
143+
taskDISABLE_INTERRUPTS();
144+
TRACE = 'S';
145+
for( ;; );
146+
}
147+
/*-----------------------------------------------------------*/
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#ifndef IMG_FILTERING_CPP
2+
#define IMG_FILTERING_CPP
3+
4+
#include <string.h>
5+
#include <stdlib.h>
6+
#include "../inc/address_map.hpp"
7+
#include "../inc/common_func.hpp"
8+
9+
#define IPS_FILTER_KERNEL_SIZE 9
10+
11+
12+
void filter_img (unsigned char* input_img, unsigned char* output_img, int img_width, int img_height)
13+
{
14+
unsigned char* filter_kernel_ptr = (unsigned char*) IMG_FILTER_KERNEL_ADDRESS_LO;
15+
unsigned char* filter_output_ptr = (unsigned char*) IMG_FILTER_OUTPUT_ADDRESS_LO;
16+
unsigned char* local_window_ptr = malloc(IPS_FILTER_KERNEL_SIZE*sizeof(char));
17+
unsigned char* read_ptr;
18+
unsigned char data_returned;
19+
20+
int local_count = 0;
21+
int current_number_of_pixels = 0;
22+
int next_target_of_completion = 10;
23+
int local_group_count = 0;
24+
int total_number_of_pixels = img_width*img_height;
25+
unsigned char* local_results;
26+
27+
for (int i = 0; i < img_width; i++)
28+
{
29+
local_group_count = 0;
30+
for (int j = 0; j < img_height; j++)
31+
{
32+
extract_window(i, j, input_img, local_window_ptr, img_width, img_height);
33+
memcpy(filter_kernel_ptr, local_window_ptr, IPS_FILTER_KERNEL_SIZE*sizeof(char)); //Write to filter kernel
34+
memcpy(read_ptr, filter_output_ptr, sizeof(char)); //Read filter output
35+
data_returned = *read_ptr;
36+
37+
if (local_count == 0)
38+
{
39+
local_results = malloc(8);
40+
}
41+
42+
if (data_returned > 255) {
43+
*(local_results + local_count) = 255;
44+
}
45+
else {
46+
*(local_results + local_count) = data_returned;
47+
}
48+
49+
local_count++;
50+
51+
if (local_count == 8)
52+
{
53+
memcpy(output_img + ((i * img_height) + (local_group_count * 8 * sizeof(char))), local_results, 8 * sizeof(char));
54+
local_count = 0;
55+
local_group_count++;
56+
}
57+
58+
current_number_of_pixels++;
59+
if ((((current_number_of_pixels*100) / (total_number_of_pixels))) >= next_target_of_completion) {
60+
printf("Image Filtering completed at %f\n", next_target_of_completion);
61+
next_target_of_completion += 10.0;
62+
}
63+
}
64+
}
65+
}
66+
67+
68+
#endif // IMG_FILTERING_CPP
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
#ifndef TB_AUX_FUNCTIONS_CPP
2+
#define TB_AUX_FUNCTIONS_CPP
3+
4+
#include <stdlib.h>
5+
#include <string.h>
6+
7+
//Extract Window: A function to extract a 3x3 window from an image
8+
void extract_window(int i, int j, unsigned char *initial_address_ptr, unsigned char* local_window_ptr, int img_width, int img_height)
9+
{
10+
unsigned char* read_ptr = malloc(3*sizeof(char));
11+
if ((i == 0) && (j == 0)) // Upper left corner of the image
12+
{
13+
// First row
14+
*(local_window_ptr ) = 0;
15+
*(local_window_ptr + 1) = 0;
16+
*(local_window_ptr + 2) = 0;
17+
// Second row
18+
memcpy(read_ptr, initial_address_ptr, 2 * sizeof(char));
19+
*(local_window_ptr + 3) = 0;
20+
*(local_window_ptr + 4) = *(read_ptr );
21+
*(local_window_ptr + 5) = *(read_ptr + 1);
22+
// Third row
23+
memcpy(read_ptr, initial_address_ptr + img_height, 2 * sizeof(char));
24+
*(local_window_ptr + 6) = 0;
25+
*(local_window_ptr + 7) = *(read_ptr );
26+
*(local_window_ptr + 8) = *(read_ptr + 1);
27+
}
28+
else if ((i == 0) && (j == img_height - 1)) // Upper right corner of the image
29+
{
30+
// First row
31+
*(local_window_ptr ) = 0;
32+
*(local_window_ptr + 1) = 0;
33+
*(local_window_ptr + 2) = 0;
34+
// Second row
35+
memcpy(read_ptr, initial_address_ptr + (img_height - 2), 2 * sizeof(char));
36+
*(local_window_ptr + 3) = *(read_ptr );
37+
*(local_window_ptr + 4) = *(read_ptr + 1);
38+
*(local_window_ptr + 5) = 0;
39+
// Third row
40+
memcpy(read_ptr, initial_address_ptr + (img_height + (img_height - 2)), 2 * sizeof(char));
41+
*(local_window_ptr + 6) = *(read_ptr );
42+
*(local_window_ptr + 7) = *(read_ptr + 1);
43+
*(local_window_ptr + 8) = 0;
44+
}
45+
else if (i == 0) // Upper border
46+
{
47+
// First row
48+
*(local_window_ptr ) = 0;
49+
*(local_window_ptr + 1) = 0;
50+
*(local_window_ptr + 2) = 0;
51+
// Second row
52+
memcpy(read_ptr, initial_address_ptr + (j - 1), 3 * sizeof(char));
53+
*(local_window_ptr + 3) = *(read_ptr );
54+
*(local_window_ptr + 4) = *(read_ptr + 1);
55+
*(local_window_ptr + 5) = *(read_ptr + 2);
56+
// Third row
57+
memcpy(read_ptr, initial_address_ptr + (img_height + (j - 1)), 3 * sizeof(char));
58+
*(local_window_ptr + 6) = *(read_ptr );
59+
*(local_window_ptr + 7) = *(read_ptr + 1);
60+
*(local_window_ptr + 8) = *(read_ptr + 2);
61+
}
62+
else if ((i == img_width - 1) && (j == 0)) // Lower left corner of the image
63+
{
64+
// First row
65+
memcpy(read_ptr, initial_address_ptr + ((img_width - 2) * img_height), 2 * sizeof(char));
66+
*(local_window_ptr ) = 0;
67+
*(local_window_ptr + 1) = *(read_ptr );
68+
*(local_window_ptr + 2) = *(read_ptr + 1);
69+
// Second row
70+
memcpy(read_ptr, initial_address_ptr + ((img_width - 1) * img_height), 2 * sizeof(char));
71+
*(local_window_ptr + 3) = 0;
72+
*(local_window_ptr + 4) = *(read_ptr );
73+
*(local_window_ptr + 5) = *(read_ptr + 1);
74+
// Third row
75+
*(local_window_ptr + 6) = 0;
76+
*(local_window_ptr + 7) = 0;
77+
*(local_window_ptr + 8) = 0;
78+
}
79+
else if ((i == img_width - 1) && (j == img_height - 1)) // Lower right corner of the image
80+
{
81+
// First row
82+
memcpy(read_ptr, initial_address_ptr + (((img_width - 2) * img_height) + (img_height - 2)), 2 * sizeof(char));
83+
*(local_window_ptr ) = *(read_ptr );
84+
*(local_window_ptr + 1) = *(read_ptr + 1);
85+
*(local_window_ptr + 2) = 0;
86+
// Second row
87+
memcpy(read_ptr, initial_address_ptr + (((img_width - 1) * img_height) + (img_height - 2)), 2 * sizeof(char));
88+
*(local_window_ptr + 3) = *(read_ptr );
89+
*(local_window_ptr + 4) = *(read_ptr + 1);
90+
*(local_window_ptr + 5) = 0;
91+
// Third row
92+
*(local_window_ptr + 6) = 0;
93+
*(local_window_ptr + 7) = 0;
94+
*(local_window_ptr + 8) = 0;
95+
}
96+
else if (i == img_width - 1) // Lower border of the image
97+
{
98+
// First row
99+
memcpy(read_ptr, initial_address_ptr + (((img_width - 2) * img_height) + (j - 1)), 3 * sizeof(char));
100+
*(local_window_ptr ) = *(read_ptr );
101+
*(local_window_ptr + 1) = *(read_ptr + 1);
102+
*(local_window_ptr + 2) = *(read_ptr + 2);
103+
// Second row
104+
memcpy(read_ptr, initial_address_ptr + (((img_width - 1) * img_height) + (j - 1)), 3 * sizeof(char));
105+
*(local_window_ptr + 3) = *(read_ptr );
106+
*(local_window_ptr + 4) = *(read_ptr + 1);
107+
*(local_window_ptr + 5) = *(read_ptr + 2);
108+
// Third row
109+
*(local_window_ptr + 6) = 0;
110+
*(local_window_ptr + 7) = 0;
111+
*(local_window_ptr + 8) = 0;
112+
}
113+
else if (j == 0) // Left border of the image
114+
{
115+
// First row
116+
memcpy(read_ptr, initial_address_ptr + ((i - 1) * img_height), 2 * sizeof(char));
117+
*(local_window_ptr ) = 0;
118+
*(local_window_ptr + 1) = *(read_ptr );
119+
*(local_window_ptr + 2) = *(read_ptr + 1);
120+
// Second row
121+
memcpy(read_ptr, initial_address_ptr + (i * img_height), 2 * sizeof(char));
122+
*(local_window_ptr + 3) = 0;
123+
*(local_window_ptr + 4) = *(read_ptr );
124+
*(local_window_ptr + 5) = *(read_ptr + 1);
125+
// Third row
126+
memcpy(read_ptr, initial_address_ptr + ((i + 1) * img_height), 2 * sizeof(char));
127+
*(local_window_ptr + 6) = 0;
128+
*(local_window_ptr + 7) = *(read_ptr );
129+
*(local_window_ptr + 8) = *(read_ptr + 1);
130+
}
131+
else if (j == img_height - 1) // Right border of the image
132+
{
133+
// First row
134+
memcpy(read_ptr, initial_address_ptr + (((i - 1) * img_height) + (j - 1)), 2 * sizeof(char));
135+
*(local_window_ptr ) = *(read_ptr );
136+
*(local_window_ptr + 1) = *(read_ptr + 1);
137+
*(local_window_ptr + 2) = 0;
138+
// Second row
139+
memcpy(read_ptr, initial_address_ptr + ((i * img_height) + (j - 1)), 2 * sizeof(char));
140+
*(local_window_ptr + 3) = *(read_ptr );
141+
*(local_window_ptr + 4) = *(read_ptr + 1);
142+
*(local_window_ptr + 5) = 0;
143+
// Third row
144+
memcpy(read_ptr, initial_address_ptr + (((i + 1) * img_height) + (j - 1)), 2 * sizeof(char));
145+
*(local_window_ptr + 6) = *(read_ptr );
146+
*(local_window_ptr + 7) = *(read_ptr + 1);
147+
*(local_window_ptr + 8) = 0;
148+
}
149+
else // Rest of the image
150+
{
151+
// First row
152+
memcpy(read_ptr, initial_address_ptr + (((i - 1) * img_height) + (j - 1)), 3 * sizeof(char));
153+
*(local_window_ptr ) = *(read_ptr );
154+
*(local_window_ptr + 1) = *(read_ptr + 1);
155+
*(local_window_ptr + 2) = *(read_ptr + 2);
156+
// Second row
157+
memcpy(read_ptr, initial_address_ptr + ((i * img_height) + (j - 1)), 3 * sizeof(char));
158+
*(local_window_ptr + 3) = *(read_ptr );
159+
*(local_window_ptr + 4) = *(read_ptr + 1);
160+
*(local_window_ptr + 5) = *(read_ptr + 2);
161+
// Third row
162+
memcpy(read_ptr, initial_address_ptr + (((i + 1) * img_height) + (j - 1)), 3 * sizeof(char));
163+
*(local_window_ptr + 6) = *(read_ptr );
164+
*(local_window_ptr + 7) = *(read_ptr + 1);
165+
*(local_window_ptr + 8) = *(read_ptr + 2);
166+
}
167+
168+
//printf("Window is: [%0d, %0d, %0d,%0d, %0d, %0d,%0d,%0d,%0d]\n", *(local_window_ptr), *(local_window_ptr + 1), *(local_window_ptr + 2), *(local_window_ptr + 3), *(local_window_ptr + 4), *(local_window_ptr + 5), *(local_window_ptr + 6), *(local_window_ptr + 7), *(local_window_ptr + 8));
169+
}
170+
171+
#endif //TB_AUX_FUNCTIONS_CPP

VirtualPrototype/inc/ips_filter_lt_model.hpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,6 @@ void Filter<IN, OUT, N>::exec_filter()
9999
for (i = 0; i < N; ++i)
100100
for (j = 0; j < N; ++j)
101101
*(this->result_ptr) += this->kernel[i * N + j] * this->img_window_tmp[i * N + j];
102-
printf("Result: %0f, Kernel: %0f, Window[%0d, %0d] %0f \n", *(this->result_ptr), this->kernel[i * N + j], i, j, this->img_window_tmp[i * N + j]);
103-
printf("Result: %0f\n", *(this->result_ptr));
104102
}
105103
}
106104

0 commit comments

Comments
 (0)