Search
Obsahem cvičení je samostatná práce na projektu a konzultace (projektu, témat z přednášek…).
Výhoda následujícího použití informace změně polohy otočných voličů:
#include <stdlib.h> #include <stdio.h> #include <stdint.h> #include <time.h> #include <unistd.h> #include <termios.h> //termios, TCSANOW, ECHO, ICANON #include "mzapo_parlcd.h" #include "mzapo_phys.h" #include "mzapo_regs.h" #include "kote.c" unsigned short *fb; void draw_pixel(int x, int y, unsigned short int color) { if (color!=65535) { fb[(x%480)+480*(y%320)] = color; } } int main(int argc, char *argv[]) { unsigned char *parlcd_mem_base, *mem_base; int i,j, ptr; fb = (unsigned short *)malloc(320*480*2); printf("Hello world\n"); parlcd_mem_base = map_phys_address(PARLCD_REG_BASE_PHYS, PARLCD_REG_SIZE, 0); if (parlcd_mem_base == NULL) exit(1); mem_base = map_phys_address(SPILED_REG_BASE_PHYS, SPILED_REG_SIZE, 0); if (mem_base == NULL) exit(1); parlcd_hx8357_init(parlcd_mem_base); struct timespec loop_delay; loop_delay.tv_sec = 0; loop_delay.tv_nsec = 150 * 1000 * 1000; int xx=240, yy=160; uint32_t r = *(volatile uint32_t*)(mem_base + SPILED_REG_KNOBS_8BIT_o); int last_red = ((r>>16)&0xff); int last_blue = (r&0xff); while (1) { r = *(volatile uint32_t*)(mem_base + SPILED_REG_KNOBS_8BIT_o); if ((r&0x7000000)!=0) { break; } int red = ((r>>16)&0xff); int blue = (r&0xff); int diff_red = red - last_red; last_red = red; if (diff_red<-128) { diff_red+=256; } if (diff_red>128) { diff_red-=256; } xx+=diff_red/2; if (xx<0) { xx=0; } if (xx>350) { xx=350; } int diff_blue = blue - last_blue; last_blue = blue; if (diff_blue<-128) { diff_blue+=256; } if (diff_blue>128) { diff_blue-=256; } yy+=diff_blue/2; if (yy<0) { yy=0; } if (yy>240) { yy=240; } printf("xx %i Diff red %i (%i) yy %i diff blue %i (%i)\n", xx, diff_red, red, yy, diff_blue, blue); for (ptr = 0; ptr < 320*480 ; ptr++) { fb[ptr]=0u; } for (j=0; j<kote_png_height; j++) { for (i=0; i<kote_png_width; i++) { draw_pixel(i+xx,j+yy,kote_png[i+j*kote_png_width]); } } parlcd_write_cmd(parlcd_mem_base, 0x2c); for (ptr = 0; ptr < 480*320 ; ptr++) { parlcd_write_data(parlcd_mem_base, fb[ptr]); } clock_nanosleep(CLOCK_MONOTONIC, 0, &loop_delay, NULL); } parlcd_write_cmd(parlcd_mem_base, 0x2c); for (ptr = 0; ptr < 480*320 ; ptr++) { parlcd_write_data(parlcd_mem_base, 0); } printf("Goodbye world\n"); return 0; }
main
input_thread
output_thread
#define _POSIX_C_SOURCE 200112L #include <stdlib.h> #include <stdio.h> #include <stdint.h> #include <time.h> #include <unistd.h> #include <stdbool.h> #include <pthread.h> #include "mzapo_parlcd.h" #include "mzapo_phys.h" #include "mzapo_regs.h" #include "serialize_lock.h" #define IMG_SIZE 320*480 //type definition of struct for shared data between threads typedef struct { bool quit; unsigned char *parlcd_mem_base; uint16_t * fb_read; uint16_t * fb_write; } data_t; void * input_thread(void * data); void * output_thread(void * data); //mutexes for double buffering of frames pthread_mutex_t mtx_fb; int main(int argc, char *argv[]) { // Serialize execution of applications // Try to acquire lock the first if (serialize_lock(1) <= 0) { printf("System is occupied\n"); if (1) { printf("Waiting\n"); // Wait till application holding lock releases it or exits serialize_lock(0); } } printf("Hello world\n"); //initialize the two frame buffers uint16_t fb0[IMG_SIZE]; uint16_t fb1[IMG_SIZE]; //initialize the shared data data_t shared_data; shared_data.quit = false; shared_data.fb_read = &fb0; shared_data.fb_write = &fb1; //map the memory shared_data.parlcd_mem_base = map_phys_address(PARLCD_REG_BASE_PHYS, PARLCD_REG_SIZE, 0); if (shared_data.parlcd_mem_base == NULL){ exit(1); } //prepare the threads enum {INPUT, OUTPUT, NUM_THREADS}; const char *thread_names[] = {"input", "output"}; void* (*thread_functions[])(void *) = {input_thread, output_thread}; //initialize the threads and mutex pthread_t threads[NUM_THREADS]; pthread_mutex_init(&mtx_fb, NULL); //spawn the threads for (int i = 0; i < NUM_THREADS; ++i){ int res = pthread_create(&threads[i], NULL, thread_functions[i], &shared_data); fprintf(stdout, "INFO: Create thread '%s' %s\n", thread_names[i], (res == 0 ? "OK" : "FAIL") ); //TODO:correctly exit if some thread does not initialize } //main loop uint16_t color = 0x0000; while(!shared_data.quit){ //simulate some long calculations usleep(10000); //write the frame buffer for (int i = 0; i < IMG_SIZE; i++) { //write to the write buffer shared_data.fb_write[i] = color; } color+=1; //swap the buffers - first need to acquire the mutex for write read buffer pthread_mutex_lock(&mtx_fb); //..now swap them uint16_t * tmp = shared_data.fb_read; shared_data.fb_read = shared_data.fb_write; shared_data.fb_write = tmp; //..and unlock the read buffer for display pthread_mutex_unlock(&mtx_fb); } shared_data.quit = true; //joining the threads for (int i = 0; i < NUM_THREADS; ++i) { fprintf(stdout, "INFO: Call join to the thread %s\n", thread_names[i]); int r = pthread_join(threads[i], NULL); fprintf(stdout, "INFO: Joining the thread %s has been %s\n", thread_names[i], (r == 0 ? "OK" : "FAIL")); } printf("Goodbye world\n"); // Release the lock serialize_unlock(); return 0; } //------------------------------------------------------------ void * input_thread(void * data){ data_t * shared_data = (data_t *) data; while(!shared_data->quit){ //TODO: sample the input once in a while char c = getchar(); if (c == 'q'){ shared_data->quit = true; } //sleep for some time usleep(10000); } } //------------------------------------------------------------ void * output_thread(void * data){ data_t * shared_data = (data_t *) data; //initialize the display parlcd_hx8357_init(shared_data->parlcd_mem_base); uint16_t fb_p = NULL; //draw in infinite loop while(!shared_data->quit){ //lock the output frame buffer so no one can write into it pthread_mutex_lock(&mtx_fb); //reset the cursor parlcd_write_cmd(shared_data->parlcd_mem_base, 0x2c); //write the buffer for (int i = 0; i < IMG_SIZE; ++i) { parlcd_write_data( shared_data->parlcd_mem_base, shared_data->fb_read[i]); } //unlock the buffer pthread_mutex_unlock(&mtx_fb); //sleep for some time usleep(10000); } }