Multiple displays using threads

This commit is contained in:
servadmin 2021-11-18 13:20:45 -05:00
parent e0f5bc1af3
commit 289a9a1e34
4 changed files with 155 additions and 1 deletions

View File

@ -1376,6 +1376,11 @@ void u8g2_SetBufferCurrTileRow(u8g2_t *u8g2, uint8_t row) U8G2_NOINLINE;
void u8g2_FirstPage(u8g2_t *u8g2);
uint8_t u8g2_NextPage(u8g2_t *u8g2);
// Add ability to set buffer pointer
#if defined(__ARM_LINUX__) || defined(unix) || defined(__unix__) || defined(__unix)
#define U8G2_USE_DYNAMIC_ALLOC
#endif
#ifdef U8G2_USE_DYNAMIC_ALLOC
#define u8g2_SetBufferPtr(u8g2, buf) ((u8g2)->tile_buf_ptr = (buf));
#define u8g2_GetBufferSize(u8g2) ((u8g2)->u8x8.display_info->tile_width * 8 * (u8g2)->tile_buf_height)

View File

@ -0,0 +1,61 @@
# Chosse proper compiler for your PI
# NanoPi: arm-linux-gnueabi-gcc
# Raspberry Pi Zero: arm-linux-gnueabi-gcc
# Raspberry Pi 2: arm-linux-gnueabihf-gcc
# OrangePi Zero: arm-linux-gnueabihf-gcc
# NanoPi NEO: arm-linux-gnueabihf-gcc
# NanoPi NEO Plus 2: arm-linux-gnueabihf-gcc
# C-SKY Linux: csky-linux-gcc
CC=arm-linux-gnueabi-gcc
# IP Address of your PI
PI=pi@raspberrypi.local
TARGET=u8g2_sw_i2c_thread
IDIR= -I ../../../drivers -I ../../../../../csrc -I ../../../port
SRCDIR=../../../../../csrc
OBJDIR=../../../obj
OUTDIR=../../../bin
LDIR= -L ../../../lib
LIBS= -lm -lpthread
CFLAGS= $(IDIR) -W -Wall -D __ARM_LINUX__
OBJ+=u8g2_sw_i2c_thread.o\
../../../port/u8g2port.o\
../../../drivers/gpio.o\
../../../drivers/spi.o\
../../../drivers/i2c.o\
OBJ+=$(patsubst $(SRCDIR)/%.c,$(OBJDIR)/%.o, $(wildcard $(SRCDIR)/*.c))
all: directories $(TARGET)
directories:
@mkdir -p $(OBJDIR)
@mkdir -p $(OUTDIR)
$(TARGET):$(OBJ)
@echo Generating $(TARGET) ...
@$(CC) -o $(OUTDIR)/$@ $(OBJ) $(LDIR) $(LIBS)
$(OBJDIR)/%.o: $(SRCDIR)/%.c
$(CC) -c -o $@ $< $(CFLAGS) $(LDIR) $(LIBS)
clean:
@echo RM -rf $(OBJDIR)/
@rm -rf $(OBJ)
@rm -rf $(OBJDIR)
@echo RM -rf $(OUTDIR)/
@rm -rf $(OUTDIR)
upload:
scp $(OUTDIR)/$(TARGET) $(PI):~/
run:
ssh $(PI)

View File

@ -0,0 +1,86 @@
/*
* Run three displays drawing random lines. This proves you can use U8g2 to run
* multiple displays in a thread safe way.
*/
#include "u8g2port.h"
#include <pthread.h>
#include <string.h>
#include <errno.h>
// Encapsulate each thread's info
struct display {
uint8_t gpio_chip;
uint8_t scl;
uint8_t sda;
uint8_t res;
unsigned long delay;
};
typedef struct display display_t;
/*
* Draw random lines with 50 ms delay.
*/
void* do_display(void *arg) {
display_t disp = *((display_t*) arg);
pthread_t id = pthread_self();
uint8_t h, w, y1, y2;
uint8_t *buf;
printf("Thread %lu start\n", id);
u8g2_t u8g2;
// Initialization
u8g2_Setup_ssd1306_i2c_128x32_univision_f(&u8g2, U8G2_R0, u8x8_byte_sw_i2c,
u8x8_arm_linux_gpio_and_delay);
// We need unique buffer for each display in order to be thread friendly
buf = (uint8_t*)malloc(u8g2_GetBufferSize(&u8g2));
u8g2_SetBufferPtr(&u8g2, buf);
init_i2c_sw(&u8g2, disp.gpio_chip, disp.scl, disp.sda, disp.res,
disp.delay);
u8g2_InitDisplay(&u8g2);
h = u8g2_GetDisplayHeight(&u8g2);
w = u8g2_GetDisplayWidth(&u8g2);
u8g2_SetPowerSave(&u8g2, 0);
u8g2_SetFont(&u8g2, u8g2_font_ncenB08_tr);
for (int i = 1; i < 200; ++i) {
u8g2_ClearBuffer(&u8g2);
y1 = rand() % h;
y2 = rand() % h;
u8g2_DrawLine(&u8g2, 0, y1, w - 1, y2);
u8g2_SendBuffer(&u8g2);
sleep_ms(50);
}
u8g2_SetPowerSave(&u8g2, 1);
// Close and deallocate GPIO resources
done_user_data(&u8g2);
free(buf);
printf("Thread %lu end\n", id);
return NULL;
}
int main(void) {
pthread_t id_1;
pthread_t id_2;
pthread_t id_3;
void *retval_1;
void *retval_2;
void *retval_3;
display_t display_1 = { 0, 14, 13, U8X8_PIN_NONE, 0 };
display_t display_2 = { 0, 15, 16, U8X8_PIN_NONE, 0 };
display_t display_3 = { 0, 198, 199, U8X8_PIN_NONE, 0 };
pthread_create(&id_1, NULL, &do_display, &display_1);
pthread_create(&id_2, NULL, &do_display, &display_2);
pthread_create(&id_3, NULL, &do_display, &display_3);
pthread_join(id_1, (void**) &retval_1);
pthread_join(id_2, (void**) &retval_2);
pthread_join(id_3, (void**) &retval_3);
printf("Done\n");
return 0;
}

View File

@ -1,7 +1,9 @@
/*
* This code should support multiple displays since GPIO pin handles have been
* This code supports multiple displays since GPIO pin handles have been
* moved into user_data_struct. I2C and SPI handles are global since they can be
* shared by multiple devices (think I2C with different address sharing bus).
*
* So far I have tested this with 3 software I2C displays. See examples.
*/
#include "u8g2port.h"