Embedded elevator multimedia design code implementation, which has some comments
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <strings.h>
#include <malloc.h>
#include <stdbool.h>
#include <pthread.h>
#include <linux/input.h>
//Define nodes in the linked list
typedef struct node
{
int member;// Members in node
struct node *pNext;// Pointer to the next node
}Node, *pNode;
int *init_mmap(void)
{
int file_fd = open("/dev/fb0", O_RDWR);// Turn on the LCD display
if(file_fd == -1)
{
printf("open /dev/fb0 fail!\n");
return NULL;
}
int *init_mmap_fd = malloc(sizeof(int *));//Define mapping pointers and establish mapping relationships. init_mmap_fd = mmap(NULL, 800*480*4, PROT_READ|PROT_WRITE, MAP_SHARED, file_fd, 0); if(init_mmap_fd == MAP_FAILED) { printf("mmap lcd fail!\n"); return NULL; } return init_mmap_fd;
}
/*
Function: break the mapping relationship and release resources.
Formal parameters:
int *end_mmap: mapping pointer.
Return value: success 0
Failed - 1
/
int close_mmap(int end_mmap)
{
int ret = munmap(end_mmap, 8004804);// Break the mapping relationship and release resources.
if(ret == -1)
{
return -1;
}
return 0;
}
extern pNode pHead;// Call the structure pointer defined in the main function.
/*
Function: create linked list and process floor information.
Formal parameters:
int info: store the floor number of the pressed floor.
Return value:
Success: returns a structure pointer.
Failed: NULL returned
*/
pNode CreateList(int info)
{
pNode pHead = (pNode)malloc(sizeof(Node));// Allocate a header node that does not store valid data
pNode pTail = pHead;// The last node of the linked list
pTail->pNext = NULL;// The pointer to the last node is set to null
pNode pNew = (pNode)malloc(sizeof(Node));//Allocate space for new nodes pNew->member = info;//Assign the data entered by the user to the members of the node pTail->pNext = pNew;//Point the pointer of the last node to the next new node pNew->pNext = NULL;//Set the pointer in the new node to null pTail = pNew;//Assign the new node to the last node return pHead;//Return header node
}
/*
Function: linked list node insertion function.
Formal parameters:
pNode pHead: header node.
int front: insert before the node number.
int data: data to insert.
Return value:
Success: true.
Failed: false.
*/
bool Insert_Node(pNode pHead, int front, int data)
{
int i = 0;
pNode Node = pHead;
pNode pSwap;// For exchange
if ( ( front<1 ) && ( Node!=NULL ) )//Judge whether the data entered by the user is greater than or equal to 1 and whether the Node is empty { return false; } while ( i<( front-1 ) )//Loop the pointer to the node before which node to insert. { Node = Node->pNext; ++i; } pNode pNew = (pNode)malloc(sizeof(Node)); pNew->member = data;//Assign the input data to the node to be inserted pSwap = Node->pNext;//Give the address of the next node to pSwap for exchange Node->pNext = pNew;//Give the address of the node to be inserted to the pointer field of the previous node pNew->pNext = pSwap;//Give the address of the next node of the inserted node to the pointer field of the inserted node return true;
}
/*
Function: query whether the current floor exists in the linked list, c 1 (found) 0 (not found)
Formal parameters:
pNode pHead: header node.
int number: the data to find.
Return value:
Success: returns 1 or 0.
Failed: - 1.
*/
int Search(pNode pHead, int number)
{
int b = 1;
int c = 0;
pNode p; p = pHead->pNext; while( ( p!=NULL ) && ( ( p->member )!=number ))//Find the corresponding floor { p = p->pNext; b++; } if( p && ( p->member )==number ) { c = b; } return c;
}
/*
Function: process trigger floor and delete trigger floor information.
Formal parameters:
pNode pHead: header node.
int number: data to delete.
Return value:
Success: returns 1 or 0.
Failed: - 1.
*/
int Del_Node(pNode pHead, int delete)
{
int j = 0;
int data = 0;
pNode pSwap; pNode Node = pHead; if ( ( delete<1 ) && (Node->pNext == NULL) )//Judge whether there is deleted data { printf("delete node fail!\n"); return 0; } while( j<( delete-1 ) ) { Node = Node->pNext; ++j; } pSwap = Node->pNext; data = pSwap->member; Node->pNext = pSwap->pNext; free(pSwap); return data;
}
/*
Function: calculate the length of the linked list, that is, calculate the total number of floors pressed
Formal parameters:
pNode pHead: header node.
Return value:
Success: 0.
Failed: - 1.
*/
int Length(pNode pHead)
{
int j = 0;
pNode p = pHead;
while( ( p->pNext )!=NULL ) { p = p->pNext; j++; } return j;
}
int show_location_bmp(char *pathname,int lcd_x_coordinates, int lcd_y_coordinates, int wide, int height,int *show_bmp_lcd_mmap)
{
int i;
int ret;
int x, y;
char bmp_buf[wide*height*3]; int new_buf[wide*height]; bzero(bmp_buf, sizeof(bmp_buf)); bzero(new_buf, sizeof(new_buf)); int bmp_fd = open(pathname, O_RDONLY);//1. Open BMP format picture if(bmp_fd == -1) { printf("show_location_bmp(), open bmp failed\n"); return -1; } ret = lseek(bmp_fd,54,SEEK_SET);//2. Skip the first 54 positions of bmp pictures if(ret == -1) { printf("show_location_bmp(), lseek bmp failed\n"); return -1; } int *new_p = show_bmp_lcd_mmap + 800*lcd_y_coordinates + lcd_x_coordinates;//3. Redefine the mapping location. ret = read(bmp_fd, bmp_buf, wide*height*3);//4. Fetch and read picture pixels if(ret == -1) { printf("show_location_bmp(), read bmp failed\n"); return -1; } close(bmp_fd);//5. Close picture for(i=0; i<wide*height; i++)//6. 24bits to 32bits control variable { new_buf[i] = bmp_buf[i*3]<<0 | bmp_buf[(i*3)+1]<<8 | bmp_buf[(i*3)+2]<<16; } for(y=0;y<height;y++)//7. Solve the problem of picture upside down { for(x=0;x<wide;x++) { *(new_p+(800*((height-1)-y))+x) = new_buf[wide*y+x]; } } return 0;
}
static int ts_fd;// Open the socket of the touch screen device
/*
Function: open the touch screen.
Formal parameter: none.
Return value: success 0
Failed - 1
*/
int open_ts()
{
ts_fd=open("/dev/input/event0",O_RDWR);
if(ts_fd==-1)
{
perror("failed to open touch screen \ n");
return -1;
}
}
//Get coordinates
int read_ts(int *ts_x,int *ts_y)
{
//Define event structure
struct input_event ts_event;
//Define count int count=0; while(1) { //2. Read touch coordinates read(ts_fd,&ts_event,sizeof(ts_event)); //3, Processing coordinates and judging information if(ts_event.type==EV_ABS)//Judge whether the current is touch { if(ts_event.code==ABS_X)//Judge whether the current touch coordinate is the x-axis { *ts_x=ts_event.value;//Output x-axis coordinates count++; } if(ts_event.code==ABS_Y)//Judge whether the current touch coordinate is the x-axis { *ts_y=ts_event.value;//Output x-axis coordinates count++; } if(count==2) break; } }
}
//Turn off touch
int ts_close()
{
close(ts_fd);
}
void click_event(int);
void floor_sound(int);
void each_floor(int);
void recover();
//Variable definition
int *main_mmap;// Mapping pointer
int ts_x, ts_y;//x. Y-axis coordinates
int i = 1;// Define current floor
int click;// Define click floor
int state;// Rising and falling state control variable 1 (elevator rising) - 1 (elevator falling) 0 (no key pressed)
int flag = 0;
pNode pHead = NULL;
void *elevator_control(void *arg)
{
int increase_num = 0;
int searchnum = 0;
while(1) { ts_x = 0; ts_y = 0; read_ts(&ts_x, &ts_y); printf("\n\n======thread_start:(x,y):(%d,%d)======\n\n", ts_x, ts_y); if(ts_x<800) continue; if(ts_x>800 && ts_x<900 && ts_y>500 && ts_y<600) click = 1; if(ts_x>900 && ts_x<1000 && ts_y>500 && ts_y<600) click = 2; if(ts_x>800 && ts_x<900 && ts_y>400 && ts_y<500) click = 3; if(ts_x>900 && ts_x<1000 && ts_y>400 && ts_y<500) click = 4; if(ts_x>800 && ts_x<900 && ts_y>300 && ts_y<400) click = 5; if(ts_x>900 && ts_x<1000 && ts_y>300 && ts_y<400) click = 6; if(ts_x>800 && ts_x<900 && ts_y>150 && ts_y<250) click = 7; if(ts_x>900 && ts_x<1000 && ts_y>150 && ts_y<250) click = 8; if(ts_x>800 && ts_x<900 && ts_y>0 && ts_y<100) click = 9; if(ts_x>900 && ts_x<1000 && ts_y>0 && ts_y<100) click = 10; if(click != i) click_event(click); if(pHead == NULL) { if(click > i)//Elevator rise { system("madplay s.mp3 -a +30 &"); flag = 1; state = 1; show_location_bmp("up.bmp", 480, 110, 120, 120, main_mmap); pHead = CreateList(click); } else//Elevator descent { system("madplay x.mp3 -a +30 &"); flag = 1; state = -1; show_location_bmp("down.bmp", 480, 240, 120, 120, main_mmap); pHead = CreateList(click); } } else{ if(state==1 && click>i) { searchnum = Search(pHead, click); if(searchnum == 0) { increase_num = Length(pHead); increase_num = increase_num + 1; Insert_Node(pHead, increase_num, click); } } else if(state==-1 && click<i) { searchnum = Search(pHead, click); if(searchnum == 0) { increase_num = Length(pHead); increase_num = increase_num + 1; Insert_Node(pHead, increase_num, click); } } } } //Thread exit pthread_exit(NULL);
}
void *ad(void *arg)
{
while(1)
{
show_location_bmp("ad1.bmp", 0, 0, 200, 480, main_mmap); sleep(1); show_location_bmp("ad2.bmp", 0, 0, 200, 480, main_mmap); sleep(1); show_location_bmp("ad3.bmp", 0, 0, 200, 480, main_mmap); sleep(1); } pthread_exit(NULL);//Thread exit
}
int main(int argc, char const *argv[])
{
open_ts();// Open touch screen
main_mmap = init_mmap();// Establish mapping relationship
show_location_bmp("main.bmp", 0, 0, 800, 480, main_mmap); while(1)//Click to enter the elevator display system { ts_x = 0; ts_y = 0; read_ts(&ts_x, &ts_y); if(ts_x>0 && ts_x<1000 && ts_y>0 && ts_y<600) { show_location_bmp("elevatorinterface.bmp", 200, 0, 600, 480, main_mmap); show_location_bmp("1.bmp", 210, 140, 200, 200, main_mmap); ts_x = 0; ts_y = 0; break; } } pthread_t ele_con, advertisement;//Create two threads for elevator control and advertisement playback pthread_create(&ele_con, NULL,&elevator_control, NULL);//Elevator control pthread_create(&advertisement, NULL, &ad, NULL);//Advertisement broadcast int b = 0; int del_num = 0; int searchnum = 0; while(1) { while(1) { if(flag == 1) { if(state == 1) { each_floor(i); searchnum = Search(pHead, i); printf("\n=============debug 1: searchnum=%d, i=%d!\n\n", searchnum, i); if(searchnum != 0) { del_num = Del_Node(pHead, searchnum); printf("=============debug 2: delete number: %d\n", del_num); floor_sound(i); sleep(5); } else sleep(1); b = Length(pHead); printf("=============debug 2! Total number of floors=%d\n", b); if(b == 0) { flag = 0; pHead = NULL; state = 0; recover();. each_floor(i); each_floor(i); show_location_bmp("restore_up.bmp", 480, 110, 120, 120, main_mmap); break; } i++; } else if(state==-1) { each_floor(i); searchnum = Search(pHead, i); if(searchnum != 0) { del_num = Del_Node(pHead, searchnum); printf("=============debug 2: delete number: %d\n", del_num); floor_sound(i); sleep(5); } else sleep(1); b = Length(pHead); if (b == 0) { flag = 0; pHead = NULL; state = 0; recover(); each_floor(i); show_location_bmp("restore_down.bmp", 480, 240, 120, 120, main_mmap); break; } i--; } } } } close_ts();//Turn off touch screen close_mmap(main_mmap); //Break the mapping relationship and release resources. pthread_join(ele_con,NULL);//Reclaim elevator control thread pthread_join(advertisement,NULL);//Recycle ad display thread return 0;
}
void floor_sound(int select)
{
switch(select)
{
case 1:
show_location_bmp("01.bmp", 600, 384, 100, 96, main_mmap);
break; case 2: show_location_bmp("02.bmp", 700, 384, 100, 96, main_mmap); break; case 3: show_location_bmp("03.bmp", 600, 288, 100, 96, main_mmap); break; case 4: show_location_bmp("04.bmp", 700, 288, 100, 96, main_mmap); break; case 5: show_location_bmp("05.bmp", 600, 192, 100, 96, main_mmap); break; case 6: show_location_bmp("06.bmp", 700, 192, 100, 96, main_mmap); break; case 7: show_location_bmp("07.bmp", 600, 96, 100, 96, main_mmap); break; case 8: show_location_bmp("08.bmp", 700, 96, 100, 96, main_mmap); break; case 9: show_location_bmp("09.bmp", 600, 0, 100, 96, main_mmap); break; case 10: show_location_bmp("010.bmp", 700, 0, 100, 96, main_mmap); break; }
}
void click_event(int click)
{
if( click1 )
show_location_bmp("001.bmp", 600, 384, 100, 96, main_mmap);
if( click2 )
show_location_bmp("002.bmp", 700, 384, 100, 96, main_mmap);
if( click3 )
show_location_bmp("003.bmp", 600, 288, 100, 96, main_mmap);
if( click4 )
show_location_bmp("004.bmp", 700, 288, 100, 96, main_mmap);
if( click5 )
show_location_bmp("005.bmp", 600, 192, 100, 96, main_mmap);
if( click6 )
show_location_bmp("006.bmp", 700, 192, 100, 96, main_mmap);
if( click7 )
show_location_bmp("007.bmp", 600, 96, 100, 96, main_mmap);
if( click8 )
show_location_bmp("008.bmp", 700, 96, 100, 96, main_mmap);
if( click9 )
show_location_bmp("009.bmp", 600, 0, 100, 96, main_mmap);
if( click10 )
show_location_bmp("0010.bmp", 700, 0, 100, 96, main_mmap);
}
void each_floor(int select)
{
switch(select)
{
case 1:
show_location_bmp("1.bmp", 210, 140, 200, 200, main_mmap);
break;
case 2:
show_location_bmp("2.bmp", 210, 140, 200, 200, main_mmap);
break;
case 3:
show_location_bmp("3.bmp", 210, 140, 200, 200, main_mmap);
break;
case 4:
show_location_bmp("4.bmp", 210, 140, 200, 200, main_mmap);
break;
case 5:
show_location_bmp("5.bmp", 210, 140, 200, 200, main_mmap);
break;
case 6:
show_location_bmp("6.bmp", 210, 140, 200, 200, main_mmap);
break;
case 7:
show_location_bmp("7.bmp", 210, 140, 200, 200, main_mmap);
break;
case 8:
show_location_bmp("8.bmp", 210, 140, 200, 200, main_mmap);
break;
case 9:
show_location_bmp("9.bmp", 210, 140, 200, 200, main_mmap);
break;
case 10:
show_location_bmp("10.bmp", 210, 140, 200, 200, main_mmap);
break;
}
}
void recover(void)
{
show_location_bmp("elevatorinterface.bmp", 200, 0, 600, 480, main_mmap);
}