Compare commits

..

10 Commits

Author SHA1 Message Date
Maxluli d5d7945c8f Started work on tp7 2025-01-09 16:55:25 +01:00
Maxluli feb7609ed6 Finished (Kinda... Im juste f tired of this) 2024-12-27 10:30:33 +01:00
Maxluli c8215f7adb Ctris works and telnet too 2024-12-26 13:57:40 +01:00
Maxluli 8aeece620d Created the user space code to interract with the module. Q4 done 2024-12-25 10:08:20 +01:00
Maxluli 6ddb10c4a5 I think my module is ready 2024-12-23 11:39:22 +01:00
Maxluli 93b92c2d86 Barebones working kernel driver 2024-12-23 10:55:11 +01:00
Florent Gluck e2ff142cb0 Update eval.md 2024-12-19 11:16:16 +01:00
Maxluli 4312a1dafa Started work on the kernel module 2024-12-16 10:21:53 +01:00
Maxluli 373949d02c les choses serieuses commencent 2024-12-16 09:41:59 +01:00
Maxluli d75d6acf9b Programme pulling GPIO 2024-12-16 09:32:57 +01:00
8 changed files with 2371 additions and 2 deletions
+413
View File
@@ -0,0 +1,413 @@
diff --git a/Makefile b/Makefile
index 9831a3a..482f39c 100644
--- a/Makefile
+++ b/Makefile
@@ -2,12 +2,12 @@
MANDIR=$(DESTDIR)/usr/share/man/man6/
BINDIR=$(DESTDIR)/usr/games/
-CC=gcc
+CC=arm-buildroot-linux-musleabi-gcc
MKDIR=mkdir -p
INSTALL=install
-CFLAGS=-Wall -fomit-frame-pointer -O3
-LIBS=-lm -lncurses
+CFLAGS=-Wall -fomit-frame-pointer -O3 -I/home/moi/tp/lib/ncurses/buildNcurse/usr/include
+LIBS=-L/home/moi/tp/lib/ncurses/buildNcurse/usr/lib -lm -lncursesw
OBJS=ctris.o game.o screen.o brick.o highscore.o
OUTPUT=ctris
diff --git a/brick.o b/brick.o
new file mode 100644
index 0000000..8a0e376
Binary files /dev/null and b/brick.o differ
diff --git a/config.h b/config.h
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/config.h
@@ -0,0 +1 @@
+
diff --git a/ctris b/ctris
new file mode 100755
index 0000000..9ed491c
Binary files /dev/null and b/ctris differ
diff --git a/ctris.o b/ctris.o
new file mode 100644
index 0000000..5972bc7
Binary files /dev/null and b/ctris.o differ
diff --git a/game.c b/game.c
index 7a2bea0..b3d4a45 100644
--- a/game.c
+++ b/game.c
@@ -16,6 +16,20 @@ void init_board(char board[BOARD_HEIGHT][BOARD_WIDTH])
}
}
+// NEW CODE
+#define PATH_MODULE "/dev/mylab1_joystick"
+int fd;
+int buffer[5] = {1,1,1,1,1};
+int read_err;
+int init_mylab(){
+ fd = open(PATH_MODULE,O_RDONLY,S_IRUSR);
+ if(fd < 0){
+ printf("Could not retrieve mylab driver\n");
+ return fd;
+ }
+}
+//
+
void remove_this_row(WINDOW *win, char board[BOARD_HEIGHT][BOARD_WIDTH], unsigned char y)
{
unsigned char x;
@@ -88,6 +102,12 @@ unsigned int game_engine(bool resize)
static bool engine_stop = false;
show_headline();
+
+ // NEW CODE
+
+ init_mylab();
+
+ //
if (resize) {
if (game_state != PAUSED_STATE) {
@@ -147,7 +167,28 @@ unsigned int game_engine(bool resize)
while(game_state == RUNNING_STATE)
{
show_board_win(board_win, board, cur_brick, brick_type, x, y);
- switch(get_key(board_win))
+
+ int keyValue = get_key(board_win);
+
+ // NEW CODE
+ // Update KEY_STATE
+ read_err = read(fd,buffer,5 * sizeof(int));
+ if(read_err < 0)
+ printf("Could not read module\n");
+
+ if(!buffer[0])
+ keyValue = KEY_UP;
+ if(!buffer[1])
+ keyValue = KEY_DOWN;
+ if(!buffer[2])
+ keyValue = KEY_LEFT;
+ if(!buffer[3])
+ keyValue = KEY_RIGHT;
+ if(!buffer[4])
+ keyValue = 'p';
+ //
+
+ switch(keyValue)
{
case 's':
case KEY_DOWN:
@@ -278,5 +319,3 @@ unsigned int game_engine(bool resize)
engine_stop = true;
return score;
}
-
-
diff --git a/game.o b/game.o
new file mode 100644
index 0000000..1da7f4d
Binary files /dev/null and b/game.o differ
diff --git a/highscore.o b/highscore.o
new file mode 100644
index 0000000..44a44c1
Binary files /dev/null and b/highscore.o differ
diff --git a/oldgame.c b/oldgame.c
new file mode 100644
index 0000000..7a2bea0
--- /dev/null
+++ b/oldgame.c
@@ -0,0 +1,282 @@
+#include "ctris.h"
+#include "game.h"
+#include "brick.h"
+#include "screen.h"
+#include "highscore.h"
+
+void init_board(char board[BOARD_HEIGHT][BOARD_WIDTH])
+{
+ unsigned char i, n;
+ for(i = 0; i < BOARD_HEIGHT; i++)
+ {
+ for(n = 0; n < BOARD_WIDTH; n++)
+ {
+ board[i][n] = 0;
+ }
+ }
+}
+
+void remove_this_row(WINDOW *win, char board[BOARD_HEIGHT][BOARD_WIDTH], unsigned char y)
+{
+ unsigned char x;
+ show_remove_row(win, board, y);
+ for(; y > 0; y--)
+ {
+ for(x = 0; x < BOARD_WIDTH; x++)
+ {
+ board[y][x] = board[y - 1][x];
+ }
+ }
+}
+
+void remove_rows(WINDOW *win, char board[BOARD_HEIGHT][BOARD_WIDTH], unsigned int *score, const char level)
+{
+ char removed_rows = 0;
+ unsigned char x, y;
+ unsigned int sub_score = 0;
+ for(y = 0; y < BOARD_HEIGHT; y++)
+ {
+ for(x = 0; x < BOARD_WIDTH; x++)
+ {
+ if(board[y][x] == 0)
+ {
+ break;
+ }
+ }
+ if(x >= BOARD_WIDTH)
+ {
+ remove_this_row(win, board, y);
+ removed_rows++;
+ sub_score += BONUS_CONST * level * removed_rows;
+ }
+ }
+ *score += sub_score;
+ if(removed_rows > 0)
+ {
+ refresh_win(win);
+ usleep(REMOVE_SPLASH_TIME);
+ }
+}
+
+void calc_level(const unsigned int score, char *level)
+{
+ while(SPEED_CONST_2 - (*level + 1) * SPEED_CONST_1 >= 0 && score / (LEVEL_CONST * (unsigned int)pow((double)*level, 2)) > 0)
+ {
+ *level += 1;
+ }
+}
+
+void pause_game()
+{
+ game_engine(true);
+}
+
+unsigned int start_game()
+{
+ return game_engine(false);
+}
+
+unsigned int game_engine(bool resize)
+{
+ static char brick_type, next_brick_type, name[40], cur_brick[4][4], board[BOARD_HEIGHT][BOARD_WIDTH], level = 1;
+ char run;
+ unsigned int score = 0;
+ static unsigned long time = 0L;
+ unsigned int tick = 0;
+ static unsigned char x, y;
+ static WINDOW *board_win, *preview_win, *score_win;
+ static bool engine_stop = false;
+
+ show_headline();
+
+ if (resize) {
+ if (game_state != PAUSED_STATE) {
+ // if the game engine is in the RUNING_STATE then
+ // the resize call below will switch the engine to PAUSED_STATE
+
+ // if the game is in the QUIT_STATE then
+ // the call below will simulate a key being pressed
+ // and that will force the highscore screen or play_again dialog to be refreshed
+ put_key('p');
+ }
+
+ if (game_state == QUIT_STATE)
+ {
+ // if the game is in the highscore screen then refresh it upon resize
+ if (!engine_stop) {
+ show_highscore(name);
+ }
+ }
+ else
+ {
+ // here we will only have RUNNING_STATE, PAUSED_STATE or GAME_OVER_STATE
+ // both states coresponds to the main screen so
+ // the main screen will be refreshed upon resize
+ show_score(score_win, score, level, time);
+ show_brick_preview(preview_win, next_brick_type);
+ show_board_win(board_win, board, cur_brick, brick_type, x, y);
+ if (game_state == PAUSED_STATE) {
+ show_pause(board_win);
+ }
+ else if (game_state == GAME_OVER_STATE) {
+ show_game_over(board_win);
+ }
+ }
+ return score;
+ }
+
+ engine_stop = false;
+ board_win = (WINDOW *)create_board_win();
+ preview_win = (WINDOW *)create_preview_win();
+ score_win = (WINDOW *)create_score_win();
+ init_board(board);
+ show_score(score_win, score, level, time);
+ next_brick_type = get_rand(7) + 1;
+ game_state = PAUSED_STATE;
+ wait_for_start(board_win);
+ game_state = RUNNING_STATE;
+ while(game_state == RUNNING_STATE)
+ {
+ brick_type = next_brick_type;
+ next_brick_type = get_rand(7) + 1;
+ show_brick_preview(preview_win, next_brick_type);
+ memcpy(cur_brick, brick_digit[brick_type - 1], sizeof(char) * 4 * 4);
+ x = BOARD_WIDTH / 2;
+ y = 0;
+ run = 1;
+ while(game_state == RUNNING_STATE)
+ {
+ show_board_win(board_win, board, cur_brick, brick_type, x, y);
+ switch(get_key(board_win))
+ {
+ case 's':
+ case KEY_DOWN:
+ if(old_style_keys != 0)
+ {
+ if(counterclockwise_rotation == 1)
+ {
+ change_direction(board, cur_brick, x, y, -1);
+ }
+ else
+ {
+ change_direction(board, cur_brick, x, y, 1);
+ }
+ }
+ else
+ {
+ if(check_brick(board, cur_brick, x, y + 1) == 0)
+ {
+ y++;
+ }
+ }
+ break;
+ case 'w':
+ case 'k':
+ case KEY_UP:
+ if(counterclockwise_rotation == 1)
+ {
+ change_direction(board, cur_brick, x, y, 1);
+ }
+ else
+ {
+ change_direction(board, cur_brick, x, y, -1);
+ }
+ break;
+ case 'd':
+ case 'l':
+ case KEY_RIGHT:
+ if(check_brick(board, cur_brick, x + 1, y) == 0)
+ {
+ x++;
+ }
+ break;
+ case 'a':
+ case 'j':
+ case KEY_LEFT:
+ if(x > 0 && check_brick(board, cur_brick, x - 1, y) == 0)
+ {
+ x--;
+ }
+ break;
+ case ' ':
+ if(old_style_keys != 0)
+ {
+ if(check_brick(board, cur_brick, x, y + 1) == 0)
+ {
+ y++;
+ }
+ }
+ else
+ {
+ while(check_brick(board, cur_brick, x, y + 1) == 0)
+ {
+ y++;
+ }
+ }
+ break;
+ case 'p':
+ game_state = PAUSED_STATE;
+ show_pause(board_win);
+ while(old_get_key(board_win) != 'p');
+ game_state = RUNNING_STATE;
+ break;
+ case 'q':
+ game_state = QUIT_STATE;
+ break;
+ }
+ tick = SPEED_CONST_2 - level * SPEED_CONST_1;
+ time += tick;
+ show_score(score_win, score, level, time);
+ usleep(tick);
+ if(run > 15)
+ {
+ if(check_brick(board, cur_brick, x, y + 1) == 0)
+ {
+ y++;
+ run = 0;
+ }
+ else
+ {
+ if(y <= 1)
+ {
+ game_state = GAME_OVER_STATE;
+ show_game_over(board_win);
+ while(old_get_key(board_win) != ' ');
+ game_state = QUIT_STATE;
+ }
+ draw_to_board(board, cur_brick, brick_type, x, y);
+ show_board_win(board_win, board, cur_brick, brick_type, x, y);
+ remove_rows(board_win, board, &score, level);
+#ifdef EXTRA_BONUS
+ score += level;
+#endif
+ calc_level(score, &level);
+ show_score(score_win, score, level, time);
+ break;
+ }
+ }
+ run++;
+ }
+
+ }
+ destroy_score_win(score_win);
+ destroy_preview_win(preview_win);
+ destroy_board_win(board_win);
+ if(game_state == QUIT_STATE)
+ {
+ if(in_highscore(score) == 0)
+ {
+ add_user_to_highscore(name, score);
+ }
+ else
+ {
+ strncpy(name, "-no-name-", 40);
+ }
+ show_highscore(name);
+ getch();
+ }
+ engine_stop = true;
+ return score;
+}
+
+
diff --git a/screen.o b/screen.o
new file mode 100644
index 0000000..3ea2576
Binary files /dev/null and b/screen.o differ
+28 -1
View File
@@ -21,4 +21,31 @@ eval: 0.9
- Q8 : où voyez vous ces infos ? On peut même trouver la sélection exacte de notre carte - Q8 : où voyez vous ces infos ? On peut même trouver la sélection exacte de notre carte
- Q11 : quavez-vous réalisé pour obtenir un noyau compressé en xz ? - Q11 : quavez-vous réalisé pour obtenir un noyau compressé en xz ?
- Q11 : oublié de calculer le % disque gagné p/r à la version gz - Q11 : oublié de calculer le % disque gagné p/r à la version gz
- «comme ma» : attention à relire votre rapport - «comme ma» : attention à relire votre rapport
# lab05
eval: 0.7
- Que veut dire cette phrase ? "dans /etc/ touch passwd et touch group"
- on ajoute le group "addgroup nogroup" : ceci na aucun sens. Attention à relire ce que vous écrivez.
- «Si on cat le repertoire group» : incorrect, on ne peut pas cat un répertoire
- "On peut aller modifier ensuite le fichier user pour" : quel est ce fichier «user» ?
- nogroup devrait plutôt être un group système
- Vous oubliez de changer lownership de /var/www de manière récursive
- En dehors de /var/www, aucune mise en place de lownership et des permission du reste du rootfs
- « de faire les bons chmods a la racine pour assigner les bonnes autorisations je vais pas tout citer ici.» : le but est exactement de tout citer, afin de voir si ce que vous réalisez est correct ou pas
- Attention à la case : pas «SDA», mais «sda» (ce nest pas le même fichier)
- mdev.conf : regex incorrecte (aussi, explication incorrecte de celle-ci)
- mdev.conf : mauvais propriétaire
- mdev.conf : mauvaises permissions
- mdev.conf : pourquoi @ ?
- script appelé par mdev : mount en read-write : incorrect ; aussi, vous copiez tout plutôt que seulement des images
- Vous vous compliquez nettement la tâche pour faire apparaître les img sur votre serveur web. Pourquoi ne pas simplement les copier dans /var/www/upload/files/ ?
- Aucune gestion derreurs dans votre script appelé par mdev ?
- Où/comment démarrez vous le service mdev ?
- Vous vous compliquez inutilement la vie avec les modules : il suffit simplement dutiliser la cible modules_install du noyau pour quils soient copiés au bon endroit dans le rootfs de votre cible
- «ca ne marche plus car les modules ne sont pas montés.» : attention à la précision du vocabulaire : les modules ne sont jamais montés, mais chargés
- Pensez à ré-écrire les questions dans votre journal
- Quels sont les modules chargés dans votre noyau ? (cf. lsmod)
- Preuve que votre noyau avec les nouveaux modules chargés gère encore la clé usb correctement ?
+321
View File
@@ -0,0 +1,321 @@
#include "ctris.h"
#include "game.h"
#include "brick.h"
#include "screen.h"
#include "highscore.h"
void init_board(char board[BOARD_HEIGHT][BOARD_WIDTH])
{
unsigned char i, n;
for(i = 0; i < BOARD_HEIGHT; i++)
{
for(n = 0; n < BOARD_WIDTH; n++)
{
board[i][n] = 0;
}
}
}
// NEW CODE
#define PATH_MODULE "/dev/mylab1_joystick"
int fd;
int buffer[5] = {1,1,1,1,1};
int read_err;
int init_mylab(){
fd = open(PATH_MODULE,O_RDONLY,S_IRUSR);
if(fd < 0){
printf("Could not retrieve mylab driver\n");
return fd;
}
}
//
void remove_this_row(WINDOW *win, char board[BOARD_HEIGHT][BOARD_WIDTH], unsigned char y)
{
unsigned char x;
show_remove_row(win, board, y);
for(; y > 0; y--)
{
for(x = 0; x < BOARD_WIDTH; x++)
{
board[y][x] = board[y - 1][x];
}
}
}
void remove_rows(WINDOW *win, char board[BOARD_HEIGHT][BOARD_WIDTH], unsigned int *score, const char level)
{
char removed_rows = 0;
unsigned char x, y;
unsigned int sub_score = 0;
for(y = 0; y < BOARD_HEIGHT; y++)
{
for(x = 0; x < BOARD_WIDTH; x++)
{
if(board[y][x] == 0)
{
break;
}
}
if(x >= BOARD_WIDTH)
{
remove_this_row(win, board, y);
removed_rows++;
sub_score += BONUS_CONST * level * removed_rows;
}
}
*score += sub_score;
if(removed_rows > 0)
{
refresh_win(win);
usleep(REMOVE_SPLASH_TIME);
}
}
void calc_level(const unsigned int score, char *level)
{
while(SPEED_CONST_2 - (*level + 1) * SPEED_CONST_1 >= 0 && score / (LEVEL_CONST * (unsigned int)pow((double)*level, 2)) > 0)
{
*level += 1;
}
}
void pause_game()
{
game_engine(true);
}
unsigned int start_game()
{
return game_engine(false);
}
unsigned int game_engine(bool resize)
{
static char brick_type, next_brick_type, name[40], cur_brick[4][4], board[BOARD_HEIGHT][BOARD_WIDTH], level = 1;
char run;
unsigned int score = 0;
static unsigned long time = 0L;
unsigned int tick = 0;
static unsigned char x, y;
static WINDOW *board_win, *preview_win, *score_win;
static bool engine_stop = false;
show_headline();
// NEW CODE
init_mylab();
//
if (resize) {
if (game_state != PAUSED_STATE) {
// if the game engine is in the RUNING_STATE then
// the resize call below will switch the engine to PAUSED_STATE
// if the game is in the QUIT_STATE then
// the call below will simulate a key being pressed
// and that will force the highscore screen or play_again dialog to be refreshed
put_key('p');
}
if (game_state == QUIT_STATE)
{
// if the game is in the highscore screen then refresh it upon resize
if (!engine_stop) {
show_highscore(name);
}
}
else
{
// here we will only have RUNNING_STATE, PAUSED_STATE or GAME_OVER_STATE
// both states coresponds to the main screen so
// the main screen will be refreshed upon resize
show_score(score_win, score, level, time);
show_brick_preview(preview_win, next_brick_type);
show_board_win(board_win, board, cur_brick, brick_type, x, y);
if (game_state == PAUSED_STATE) {
show_pause(board_win);
}
else if (game_state == GAME_OVER_STATE) {
show_game_over(board_win);
}
}
return score;
}
engine_stop = false;
board_win = (WINDOW *)create_board_win();
preview_win = (WINDOW *)create_preview_win();
score_win = (WINDOW *)create_score_win();
init_board(board);
show_score(score_win, score, level, time);
next_brick_type = get_rand(7) + 1;
game_state = PAUSED_STATE;
wait_for_start(board_win);
game_state = RUNNING_STATE;
while(game_state == RUNNING_STATE)
{
brick_type = next_brick_type;
next_brick_type = get_rand(7) + 1;
show_brick_preview(preview_win, next_brick_type);
memcpy(cur_brick, brick_digit[brick_type - 1], sizeof(char) * 4 * 4);
x = BOARD_WIDTH / 2;
y = 0;
run = 1;
while(game_state == RUNNING_STATE)
{
show_board_win(board_win, board, cur_brick, brick_type, x, y);
int keyValue = get_key(board_win);
// NEW CODE
// Update KEY_STATE
read_err = read(fd,buffer,5 * sizeof(int));
if(read_err < 0)
printf("Could not read module\n");
if(!buffer[0])
keyValue = KEY_UP;
if(!buffer[1])
keyValue = KEY_DOWN;
if(!buffer[2])
keyValue = KEY_LEFT;
if(!buffer[3])
keyValue = KEY_RIGHT;
if(!buffer[4])
keyValue = 'p';
//
switch(keyValue)
{
case 's':
case KEY_DOWN:
if(old_style_keys != 0)
{
if(counterclockwise_rotation == 1)
{
change_direction(board, cur_brick, x, y, -1);
}
else
{
change_direction(board, cur_brick, x, y, 1);
}
}
else
{
if(check_brick(board, cur_brick, x, y + 1) == 0)
{
y++;
}
}
break;
case 'w':
case 'k':
case KEY_UP:
if(counterclockwise_rotation == 1)
{
change_direction(board, cur_brick, x, y, 1);
}
else
{
change_direction(board, cur_brick, x, y, -1);
}
break;
case 'd':
case 'l':
case KEY_RIGHT:
if(check_brick(board, cur_brick, x + 1, y) == 0)
{
x++;
}
break;
case 'a':
case 'j':
case KEY_LEFT:
if(x > 0 && check_brick(board, cur_brick, x - 1, y) == 0)
{
x--;
}
break;
case ' ':
if(old_style_keys != 0)
{
if(check_brick(board, cur_brick, x, y + 1) == 0)
{
y++;
}
}
else
{
while(check_brick(board, cur_brick, x, y + 1) == 0)
{
y++;
}
}
break;
case 'p':
game_state = PAUSED_STATE;
show_pause(board_win);
while(old_get_key(board_win) != 'p');
game_state = RUNNING_STATE;
break;
case 'q':
game_state = QUIT_STATE;
break;
}
tick = SPEED_CONST_2 - level * SPEED_CONST_1;
time += tick;
show_score(score_win, score, level, time);
usleep(tick);
if(run > 15)
{
if(check_brick(board, cur_brick, x, y + 1) == 0)
{
y++;
run = 0;
}
else
{
if(y <= 1)
{
game_state = GAME_OVER_STATE;
show_game_over(board_win);
while(old_get_key(board_win) != ' ');
game_state = QUIT_STATE;
}
draw_to_board(board, cur_brick, brick_type, x, y);
show_board_win(board_win, board, cur_brick, brick_type, x, y);
remove_rows(board_win, board, &score, level);
#ifdef EXTRA_BONUS
score += level;
#endif
calc_level(score, &level);
show_score(score_win, score, level, time);
break;
}
}
run++;
}
}
destroy_score_win(score_win);
destroy_preview_win(preview_win);
destroy_board_win(board_win);
if(game_state == QUIT_STATE)
{
if(in_highscore(score) == 0)
{
add_user_to_highscore(name, score);
}
else
{
strncpy(name, "-no-name-", 40);
}
show_highscore(name);
getch();
}
engine_stop = true;
return score;
}
+201
View File
@@ -0,0 +1,201 @@
#include <linux/module.h>
#include <linux/device.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/gpio.h>
const int JOYSTICK_UP = 16; //GPIO0
const int JOYSTICK_DOWN = 17; //GPIO0
const int JOYSTICK_LEFT = 21; //GPIO0
const int JOYSTICK_RIGHT = 27 + 32; //GPIO1 offset of 32 on GPIO 1
const int JOYSTICK_BUTTON = 23; //GPIO0
#define IRQ_NAME "myjoystick_irq"
int irqNbr_UP,irqNbr_DOWN,irqNbr_LEFT,irqNbr_RIGHT,irqNbr_BUTTON = 0;
static int UP,DOWN,LEFT,RIGHT,BUTTON = 0;
int major;
struct class *j_class;
struct device *j_device;
// Operation prototypes
static int dev_open(struct inode *, struct file *);
static ssize_t dev_read(struct file *filep, char __user *buffer, size_t len, loff_t *offset){
int joystick_status[5] = {UP,DOWN,LEFT,RIGHT,BUTTON};
int data_len = 5*sizeof(int);
// Copy data to user-space buffer
if (copy_to_user(buffer, joystick_status, data_len)) {
pr_err("Failed to send data to user\n");
return -EFAULT;
}
return 0;
}
// The driver's file operations
static const struct file_operations fops = {
.owner = THIS_MODULE,
.open = dev_open,
.read = dev_read
};
/*
* Joystick IRQ handler
*/
static irqreturn_t mylab_irq_handler(int irq, void *dev_id) {
int gpio = (int)dev_id; // GPIO number passed as dev_id
int value = gpio_get_value(gpio); // Get the current GPIO value
switch(gpio){
case JOYSTICK_UP:
UP = value;
break;
case JOYSTICK_DOWN:
DOWN = value;
break;
case JOYSTICK_LEFT:
LEFT = value;
break;
case JOYSTICK_RIGHT:
RIGHT = value;
break;
case JOYSTICK_BUTTON:
BUTTON = value;
break;
default:
//Wtf?
break;
}
return (irqreturn_t) IRQ_HANDLED;
}
/**
* Driver initialization code.
*/
static int __init mylab1_joystick_dev_init(void) {
// TODO
// 1) Register the device by dynamically obtaining a major number
major = register_chrdev(0, "mylab1_joystick", &fops);
if(major < 0){
pr_info("mylab1_joystick: could not get a major number, initialisation failed\n");
return -1;
}
// 2) Create the class
j_class = class_create("mylab1_joystick");
if (IS_ERR(j_class)){
pr_info("mylab1_joystick: could not create class, initialisation failed\n");
return -1;
}
// 3) Create the device in /dev
j_device = device_create(j_class, NULL, MKDEV(major, 0), NULL, "mylab1_joystick");
if (IS_ERR(j_device)){
pr_info("mylab1_joystick: could not create device, initialisation failed\n");
return -1;
}
// 6) Request the necessary GPIOs
int err = 0;
err = gpio_request_one(JOYSTICK_UP,GPIOF_DIR_IN,"UP");
if(err != 0)
pr_info("mylab1_joystick: Could not request GPIO %d\n",JOYSTICK_UP);
err = gpio_request_one(JOYSTICK_DOWN,GPIOF_DIR_IN,"DOWN");
if(err != 0)
pr_info("mylab1_joystick: Could not request GPIO %d\n",JOYSTICK_DOWN);
err = gpio_request_one(JOYSTICK_LEFT,GPIOF_DIR_IN,"UP");
if(err != 0)
pr_info("mylab1_joystick: Could not request GPIO %d\n",JOYSTICK_LEFT);
err = gpio_request_one(JOYSTICK_RIGHT,GPIOF_DIR_IN,"UP");
if(err != 0)
pr_info("mylab1_joystick: Could not request GPIO %d\n",JOYSTICK_RIGHT);
err = gpio_request_one(JOYSTICK_BUTTON,GPIOF_DIR_IN,"UP");
if(err != 0)
pr_info("mylab1_joystick: Could not request GPIO %d\n",JOYSTICK_BUTTON);
// 7) Register an IRQ handler per GPIO
int irqres = 0;
// JOYSTICK UP
irqNbr_UP = gpio_to_irq(JOYSTICK_UP);
if(irqNbr_UP < 0)
pr_info("mylab1_joystick: Could not request IRQ number on GPIO : %d\n",JOYSTICK_UP);
irqres = request_irq(irqNbr_UP, mylab_irq_handler, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, IRQ_NAME, (void*)JOYSTICK_UP);
if(irqres < 0)
pr_info("mylab1_joystick: Could not request IRQ on GPIO : %d\n",JOYSTICK_UP);
//JOYSTICK DOWN
irqNbr_DOWN = gpio_to_irq(JOYSTICK_DOWN);
if(irqNbr_DOWN < 0)
pr_info("mylab1_joystick: Could not request IRQ number on GPIO : %d\n",JOYSTICK_DOWN);
irqres = request_irq(irqNbr_DOWN, mylab_irq_handler, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, IRQ_NAME, (void*)JOYSTICK_DOWN);
if(irqres < 0)
pr_info("mylab1_joystick: Could not request IRQ on GPIO : %d\n",JOYSTICK_DOWN);
// JOYSTICK LEFT
irqNbr_LEFT = gpio_to_irq(JOYSTICK_LEFT);
if(irqNbr_LEFT < 0)
pr_info("mylab1_joystick: Could not request IRQ number on GPIO : %d\n",JOYSTICK_LEFT);
irqres = request_irq(irqNbr_LEFT, mylab_irq_handler, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, IRQ_NAME, (void*)JOYSTICK_LEFT);
if(irqres < 0)
pr_info("mylab1_joystick: Could not request IRQ on GPIO : %d\n",JOYSTICK_LEFT);
// JOYSTICK RIGHT
irqNbr_RIGHT = gpio_to_irq(JOYSTICK_RIGHT);
if(irqNbr_RIGHT < 0)
pr_info("mylab1_joystick: Could not request IRQ number on GPIO : %d\n",JOYSTICK_RIGHT);
irqres = request_irq(irqNbr_RIGHT, mylab_irq_handler, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, IRQ_NAME, (void*)JOYSTICK_RIGHT);
if(irqres < 0)
pr_info("mylab1_joystick: Could not request IRQ on GPIO : %d\n",JOYSTICK_RIGHT);
// JOYSTICK BUTTON
irqNbr_BUTTON = gpio_to_irq(JOYSTICK_BUTTON);
if(irqNbr_BUTTON < 0)
pr_info("mylab1_joystick: Could not request IRQ number on GPIO : %d\n",JOYSTICK_BUTTON);
irqres = request_irq(irqNbr_BUTTON, mylab_irq_handler, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, IRQ_NAME, (void*)JOYSTICK_BUTTON);
if(irqres < 0)
pr_info("mylab1_joystick: Could not request IRQ on GPIO : %d\n",JOYSTICK_BUTTON);
//init finished
pr_info("mylab1_joystick: driver initialized\n");
return 0;
}
/**
* This function is called when the module is unloaded.
*/
static void __exit mylab1_joystick_dev_exit(void) {
// TODO
// 1) Destroy the device
device_destroy(j_class,MKDEV(major, 0));
// 2) Destroy the class
class_destroy(j_class);
// 4) Unregister the device
unregister_chrdev(major,"mylab1_joystick");
// 5) Free the IRQs
free_irq(irqNbr_UP, (void*)JOYSTICK_UP);
free_irq(irqNbr_DOWN, (void*)JOYSTICK_DOWN);
free_irq(irqNbr_LEFT, (void*)JOYSTICK_LEFT);
free_irq(irqNbr_RIGHT, (void*)JOYSTICK_RIGHT);
free_irq(irqNbr_BUTTON, (void*)JOYSTICK_BUTTON);
// 6) Free the GPIOs
gpio_free(JOYSTICK_UP);
gpio_free(JOYSTICK_DOWN);
gpio_free(JOYSTICK_LEFT);
gpio_free(JOYSTICK_RIGHT);
gpio_free(JOYSTICK_BUTTON);
pr_info("mylab1_joystick: driver destroyed\n");
}
/**
* Open operation
*/
static int dev_open(struct inode *inod, struct file *f) {
pr_info("mylab1_joystick: device opened\n");
return 0;
}
module_init(mylab1_joystick_dev_init);
module_exit(mylab1_joystick_dev_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("defenestration en cours <maxime.rohmer@hesge.ch>");
MODULE_DESCRIPTION("Module to drive the joystick on the myLab1 card");
MODULE_VERSION("0.1");
+93
View File
@@ -0,0 +1,93 @@
#include <linux/module.h>
#include <linux/device.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/gpio.h>
// Operation prototypes
static int dev_open(struct inode *, struct file *);
int major;
struct class *j_class;
struct device *j_device;
// The driver's file operations
static const struct file_operations fops = {
.owner = THIS_MODULE,
.open = dev_open
};
/**
* Driver initialization code.
*/
static int __init mylab1_joystick_dev_init(void) {
// TODO
// 1) Register the device by dynamically obtaining a major number
major = register_chrdev(0, "mylab1_joystick", &fops);
if(major < 0){
pr_info("mylab1_joystick: could not get a major number, initialisation failed\n");
return -1;
}
// 2) Create the class
j_class = class_create("mylab1_joystick");
if (IS_ERR(j_class)){
pr_info("mylab1_joystick: could not create class, initialisation failed\n");
return -1;
}
// 3) Create the device in /dev
j_device = device_create(j_class, NULL, MKDEV(major, 0), NULL, "mylab1_joystick");
if (IS_ERR(j_device)){
pr_info("mylab1_joystick: could not create device, initialisation failed\n");
return -1;
}
// 6) Request the necessary GPIOs
// 7) Register an IRQ handler per GPIO
pr_info("mylab1_joystick: driver initialized\n");
return 0;
}
/**
* This function is called when the module is unloaded.
*/
static void __exit mylab1_joystick_dev_exit(void) {
// TODO
// 1) Destroy the device
device_destroy(j_class,MKDEV(major, 0));
// 2) Destroy the class
class_destroy(j_class);
// 4) Unregister the device
unregister_chrdev(major,"mylab1_joystick");
// 5) Free the IRQs
// 6) Free the GPIOs
pr_info("mylab1_joystick: driver destroyed\n");
}
/**
* Open operation
*/
static int dev_open(struct inode *inod, struct file *f) {
pr_info("mylab1_joystick: device opened\n");
return 0;
}
/**
* Joystick left IRQ handler
*/
/*
static irqreturn_t mylab_left_irq_handler(int irq, void *dev_id) {
// TODO
// - Operations to be done when the left position of the joystick is triggered
// - At minimum, the joystick state must be updated
return (irqreturn_t) IRQ_HANDLED; // Announce that the IRQ has been handled correctly
}
*/
module_init(mylab1_joystick_dev_init);
module_exit(mylab1_joystick_dev_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jaime Coder <maxime.rohmer@hesge.ch>");
MODULE_DESCRIPTION("Module to drive the joystick on the myLab1 card");
MODULE_VERSION("0.1");
+174
View File
@@ -0,0 +1,174 @@
#include <linux/module.h>
#include <linux/device.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/gpio.h>
const int JOYSTICK_UP = 16; //GPIO0
const int JOYSTICK_DOWN = 17; //GPIO0
const int JOYSTICK_LEFT = 21; //GPIO0
const int JOYSTICK_RIGHT = 27 + 32; //GPIO1 offset of 32 on GPIO 1
const int JOYSTICK_BUTTON = 23; //GPIO0
#define IRQ_NAME "myjoystick_irq"
int irqNbr_UP,irqNbr_DOWN,irqNbr_LEFT,irqNbr_RIGHT,irqNbr_BUTTON = 0;
// Operation prototypes
static int dev_open(struct inode *, struct file *);
int major;
struct class *j_class;
struct device *j_device;
// The driver's file operations
static const struct file_operations fops = {
.owner = THIS_MODULE,
.open = dev_open
};
/*
* Joystick IRQ handler
*/
static irqreturn_t mylab_irq_handler(int irq, void *dev_id) {
int gpio = (int)dev_id; // GPIO number passed as dev_id
int value = gpio_get_value(gpio); // Get the current GPIO value
if (value == 1) {
pr_info("GPIO %d: Rising edge detected\n", gpio);
} else {
pr_info("GPIO %d: Falling edge detected\n", gpio);
}
return (irqreturn_t) IRQ_HANDLED; // Announce that the IRQ has been handled correctly
}
/**
* Driver initialization code.
*/
static int __init mylab1_joystick_dev_init(void) {
// TODO
// 1) Register the device by dynamically obtaining a major number
major = register_chrdev(0, "mylab1_joystick", &fops);
if(major < 0){
pr_info("mylab1_joystick: could not get a major number, initialisation failed\n");
return -1;
}
// 2) Create the class
j_class = class_create("mylab1_joystick");
if (IS_ERR(j_class)){
pr_info("mylab1_joystick: could not create class, initialisation failed\n");
return -1;
}
// 3) Create the device in /dev
j_device = device_create(j_class, NULL, MKDEV(major, 0), NULL, "mylab1_joystick");
if (IS_ERR(j_device)){
pr_info("mylab1_joystick: could not create device, initialisation failed\n");
return -1;
}
// 6) Request the necessary GPIOs
int err = 0;
err = gpio_request_one(JOYSTICK_UP,GPIOF_DIR_IN,"UP");
if(err != 0)
pr_info("mylab1_joystick: Could not request GPIO %d\n",JOYSTICK_UP);
err = gpio_request_one(JOYSTICK_DOWN,GPIOF_DIR_IN,"DOWN");
if(err != 0)
pr_info("mylab1_joystick: Could not request GPIO %d\n",JOYSTICK_DOWN);
err = gpio_request_one(JOYSTICK_LEFT,GPIOF_DIR_IN,"UP");
if(err != 0)
pr_info("mylab1_joystick: Could not request GPIO %d\n",JOYSTICK_LEFT);
err = gpio_request_one(JOYSTICK_RIGHT,GPIOF_DIR_IN,"UP");
if(err != 0)
pr_info("mylab1_joystick: Could not request GPIO %d\n",JOYSTICK_RIGHT);
err = gpio_request_one(JOYSTICK_BUTTON,GPIOF_DIR_IN,"UP");
if(err != 0)
pr_info("mylab1_joystick: Could not request GPIO %d\n",JOYSTICK_BUTTON);
// 7) Register an IRQ handler per GPIO
int irqres = 0;
// JOYSTICK UP
irqNbr_UP = gpio_to_irq(JOYSTICK_UP);
if(irqNbr_UP < 0)
pr_info("mylab1_joystick: Could not request IRQ number on GPIO : %d\n",JOYSTICK_UP);
irqres = request_irq(irqNbr_UP, mylab_irq_handler, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, IRQ_NAME, (void*)JOYSTICK_UP);
if(irqres < 0)
pr_info("mylab1_joystick: Could not request IRQ on GPIO : %d\n",JOYSTICK_UP);
//JOYSTICK DOWN
irqNbr_DOWN = gpio_to_irq(JOYSTICK_DOWN);
if(irqNbr_DOWN < 0)
pr_info("mylab1_joystick: Could not request IRQ number on GPIO : %d\n",JOYSTICK_DOWN);
irqres = request_irq(irqNbr_DOWN, mylab_irq_handler, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, IRQ_NAME, (void*)JOYSTICK_DOWN);
if(irqres < 0)
pr_info("mylab1_joystick: Could not request IRQ on GPIO : %d\n",JOYSTICK_DOWN);
// JOYSTICK LEFT
irqNbr_LEFT = gpio_to_irq(JOYSTICK_LEFT);
if(irqNbr_LEFT < 0)
pr_info("mylab1_joystick: Could not request IRQ number on GPIO : %d\n",JOYSTICK_LEFT);
irqres = request_irq(irqNbr_LEFT, mylab_irq_handler, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, IRQ_NAME, (void*)JOYSTICK_LEFT);
if(irqres < 0)
pr_info("mylab1_joystick: Could not request IRQ on GPIO : %d\n",JOYSTICK_LEFT);
// JOYSTICK RIGHT
irqNbr_RIGHT = gpio_to_irq(JOYSTICK_RIGHT);
if(irqNbr_RIGHT < 0)
pr_info("mylab1_joystick: Could not request IRQ number on GPIO : %d\n",JOYSTICK_RIGHT);
irqres = request_irq(irqNbr_RIGHT, mylab_irq_handler, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, IRQ_NAME, (void*)JOYSTICK_RIGHT);
if(irqres < 0)
pr_info("mylab1_joystick: Could not request IRQ on GPIO : %d\n",JOYSTICK_RIGHT);
// JOYSTICK BUTTON
irqNbr_BUTTON = gpio_to_irq(JOYSTICK_BUTTON);
if(irqNbr_BUTTON < 0)
pr_info("mylab1_joystick: Could not request IRQ number on GPIO : %d\n",JOYSTICK_BUTTON);
irqres = request_irq(irqNbr_BUTTON, mylab_irq_handler, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, IRQ_NAME, (void*)JOYSTICK_BUTTON);
if(irqres < 0)
pr_info("mylab1_joystick: Could not request IRQ on GPIO : %d\n",JOYSTICK_BUTTON);
//init finished
pr_info("mylab1_joystick: driver initialized\n");
return 0;
}
/**
* This function is called when the module is unloaded.
*/
static void __exit mylab1_joystick_dev_exit(void) {
// TODO
// 1) Destroy the device
device_destroy(j_class,MKDEV(major, 0));
// 2) Destroy the class
class_destroy(j_class);
// 4) Unregister the device
unregister_chrdev(major,"mylab1_joystick");
// 5) Free the IRQs
free_irq(irqNbr_UP, (void*)JOYSTICK_UP);
free_irq(irqNbr_DOWN, (void*)JOYSTICK_DOWN);
free_irq(irqNbr_LEFT, (void*)JOYSTICK_LEFT);
free_irq(irqNbr_RIGHT, (void*)JOYSTICK_RIGHT);
free_irq(irqNbr_BUTTON, (void*)JOYSTICK_BUTTON);
// 6) Free the GPIOs
gpio_free(JOYSTICK_UP);
gpio_free(JOYSTICK_DOWN);
gpio_free(JOYSTICK_LEFT);
gpio_free(JOYSTICK_RIGHT);
gpio_free(JOYSTICK_BUTTON);
pr_info("mylab1_joystick: driver destroyed\n");
}
/**
* Open operation
*/
static int dev_open(struct inode *inod, struct file *f) {
pr_info("mylab1_joystick: device opened\n");
return 0;
}
module_init(mylab1_joystick_dev_init);
module_exit(mylab1_joystick_dev_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("defenestration en cours <maxime.rohmer@hesge.ch>");
MODULE_DESCRIPTION("Module to drive the joystick on the myLab1 card");
MODULE_VERSION("0.1");
+1127 -1
View File
File diff suppressed because it is too large Load Diff
+14
View File
@@ -0,0 +1,14 @@
# Travail Pratique 7
## Objectif
Actuellement notre système embarqué a un kernel linux en flash mais e système de fichier est un système ntfs qui est monté depuis notre machine de developement.
Le but de ce tp est de changer ca et permettre à notre système embarqué d'être indépendant en mettant à disposition une carte SD avec les différents systèmes de fichiers avec lequel le kernel pourra interragir et on pourra donc utiliser notre système embarqué sans qu'il soit branché en ethernet sur notre machine de dev.
Le but est également d'utiliser différents systèmes de fichiers qui sont faits pour de la flash et qui seront soit plus rapides soit plus conservateurs sur la durée de vie de la flash ou les deux.
## Noyau : support des systèmes de fichiers
### [Q1] Depuis le shell de votre système embarqué, comment pouvez-vous vous assurez que votre noyau est capable de gérer les systèmes de fichiers ci-dessus ?