├── .gitignore ├── Bai 1 ├── Bai_tap_buoi1 │ ├── bai1 │ │ ├── README.txt │ │ └── b1.c │ └── bai3 │ │ ├── Makefile │ │ ├── README.txt │ │ └── b3.c ├── Bài 1 - Lập trình trên Linux.pptx ├── Bài 1 - Tổng quan về hdh Unix.mm ├── documentations │ └── gdb │ │ └── gdb-tutorial-handout.pdf └── tong quan ve hdh unix mindmap.txt ├── Bai 10 ├── Chia sẻ bộ nhớ giữa các process.pptx ├── example code │ ├── mmap api example │ │ ├── README.txt │ │ ├── blink_led_31_mmap.c │ │ ├── blink_mmap.c │ │ ├── reader.c │ │ └── writer.c │ └── shm api example │ │ ├── reader process.txt │ │ └── writer process.txt ├── shared memory outline.txt └── shared memory.mm ├── Bai 11 ├── Device tree.mm ├── Device tree.pptx ├── code │ ├── am33xx.dtsi │ └── led.c └── tai_lieu │ ├── Device tree.pdf │ ├── Petazzoni-device-tree-dummies_0.pdf │ ├── Pincontrol-gpio-update.pdf │ └── devicetree-specification-v0.1-20160524.pdf ├── Bai 12 └── systemcall.pptx ├── Bai 13 ├── Virtual memory management.mm ├── Virtual memory management_outline.txt └── Virtual memory.pptx ├── Bai 14 ├── Docs │ ├── BBB │ │ ├── Beaglebone-Black-Pinout.png │ │ ├── BeagleboneBlackP8HeaderTable.pdf │ │ ├── BeagleboneBlackP9HeaderTable.pdf │ │ ├── Built-in device driver linux.docx │ │ ├── document-build-linux-bbb.txt │ │ └── rmchip.pdf │ ├── New Text Document.txt │ └── trace_spi │ │ ├── can_dma-2.PNG │ │ ├── can_dma.PNG │ │ ├── prepare_mess.PNG │ │ ├── trace-spi.txt │ │ └── transfer_one.PNG ├── LCD_driver.mm ├── README.md ├── SPI-protocol │ ├── Basic-SPI-Protocol-Driver │ │ ├── Makefile │ │ ├── README.md │ │ ├── checkpatch.pl │ │ ├── lcd.h │ │ ├── lcd1.c │ │ ├── lcd_ioctl.h │ │ └── spelling.txt │ ├── Docs │ │ ├── Linux SPI Device Driver.pptx │ │ ├── McBSP_SPI_SLAVE_PINS.PNG │ │ ├── Mcbsp.pptx │ │ ├── SPI-Driver.mm │ │ └── trace_code │ ├── SPI_Multiple_Slave │ │ ├── README.md │ │ ├── am33xx.dtsi │ │ ├── lcd1 │ │ │ ├── Makefile │ │ │ ├── lcd.c │ │ │ ├── lcd.h │ │ │ ├── lcd_ctrl.c │ │ │ └── lcd_ioctl.h │ │ ├── lcd_lib │ │ │ ├── Makefile │ │ │ ├── lcd_lib.c │ │ │ ├── lcd_lib.h │ │ │ └── lcd_test.c │ │ └── lcd_lib1 │ │ │ ├── Makefile │ │ │ ├── lcd_lib.c │ │ │ ├── lcd_lib.h │ │ │ ├── lcd_lib.o │ │ │ ├── lcd_test1 │ │ │ ├── lcd_test1.c │ │ │ └── lcd_test1.o │ └── template_spi.c ├── SPI_controller_driver.pptx ├── SPI_operation_sequence.eap ├── SPI_protocol_driver.pptx ├── picture.xlsx └── spi_controller.mm ├── Bai 15 ├── Linux-storage-stack-diagram_v3.17.pdf ├── Virtual File System.mm ├── Virtual file system.pptx ├── phula-TheLinuxVirtualFilesystemImplementation-150917-1211-158.pdf └── vfs.pdf ├── Bai 16 ├── Pictures.xlsx ├── Watchdog_driver.mm ├── Watchdog_driver.pptx └── source_code │ ├── Beaglebone black │ ├── Makefile │ ├── main.c │ ├── my_watchdog.c │ └── omap_wdt.c │ └── Treerunner │ ├── fsl-ls1012a.dtsi.txt │ ├── imx2_wdt.c │ └── watchdog.conf ├── Bai 17 └── GPIO_controller │ ├── Docs │ ├── API │ ├── API.txt │ ├── BeagleboneBlackP8HeaderTable.pdf │ ├── BeagleboneBlackP9HeaderTable.pdf │ ├── GPIO controller driver.mm │ ├── GPIO controller driver.pptx │ ├── Slice.pptx │ ├── beaglebone-black-pinout.jpg │ ├── document-build-linux-bbb.txt │ ├── reference │ │ ├── API_IRQ1.PNG │ │ ├── am33xx.dtsi │ │ ├── dt-binding_gpio_gpio.h │ │ ├── dt-bindings_pinctrl_am33xx.h │ │ ├── gpio-omap.c │ │ ├── gpio-omap.h │ │ ├── gpio-siul2-s32gen1.c │ │ ├── gpio_pinmuxing.PNG │ │ ├── pinctrl-s32-gen1-core.c │ │ ├── pinctrl-s32.h │ │ ├── pinctrl-s32g275.c │ │ ├── pinctrl-s32v234.c │ │ ├── pinctrl-s32v344.c │ │ ├── request_irq.PNG │ │ ├── s32v344-simulator.dts │ │ ├── struct gpio_chip.PNG │ │ ├── struct irq_chip.PNG │ │ ├── struct irq_chip2.PNG │ │ └── trace-code.txt │ ├── struct in kernel.mm │ └── tools │ ├── GPIO_BBB.mm │ ├── Makefile │ ├── README.md │ ├── checkpatch.pl │ ├── my_gpio.c │ └── spelling.txt ├── Bai 18 ├── IPC.mm ├── IPC.pptx ├── compare_table.xlsx ├── netlink-libmnl-manual.pdf └── sample_code │ └── shared_memory │ ├── Makefile │ ├── kernel_module.c │ └── user_space.c ├── Bai 19 ├── Ethernet_driver.mm ├── Ethernet_driver.pptx └── source_code │ ├── fec_main.c │ └── skbuff.h ├── Bai 2 ├── Bai_tap_buoi2 │ ├── bai1 │ │ ├── Makefile │ │ ├── README.txt │ │ └── bai1.c │ ├── bai3 │ │ ├── Makefile │ │ ├── README.txt │ │ ├── misc-module.c │ │ ├── read.c │ │ └── write.c │ ├── bai4 │ │ ├── Makefile │ │ ├── README.txt │ │ └── bai4.c │ └── bai5 │ │ ├── Makefile │ │ ├── README │ │ ├── bai4.c │ │ ├── bai4b.c │ │ ├── foo.c │ │ └── main.c ├── Bài 2 - File trong Linux.mm ├── Bài 2 - File trong Linux.pptx └── sample_code │ ├── Aio │ ├── README │ ├── aio_read.c │ └── test_aoi.txt │ ├── misc-module.zip │ ├── misc-module │ └── misc-module │ │ ├── Makefile │ │ ├── New Text Document.txt │ │ ├── misc-module.c │ │ └── read.c │ └── shared_lib.zip ├── Bai 20 └── Yocto basic.pptx ├── Bai 21 ├── Hauer-U_BootV2.pdf ├── Porting U-Boot.pptx ├── Uboot.mm ├── Uboot.pptx └── sitara_boot_camp_03_giving_linux_the_boot.pptx ├── Bai 22 Uboot ├── Uboot basic.mm ├── porting_uboot │ ├── Elc2013_Fernandes.pdf │ ├── Porting U-Boot.pptx │ ├── U_boot_Porting_guide.pdf │ ├── sitara_boot_camp_03_giving_linux_the_boot.pptx │ └── uboot2014_kconfig.pdf ├── uboot_build_system │ ├── Built-in Kernel Modules.docx │ ├── Kbuild Overview_1.docx │ ├── U-boot_addr_relocation.txt │ ├── include .config_4.docx │ ├── make xxx_defconfig_2.docx │ ├── make menuconfig_3.docx │ └── u-boot.bin_5.docx └── uboot_flow │ ├── hinh_ve.xlsx │ └── uboot_flow.docx ├── Bai 3 ├── Bai_tap_buoi3 │ ├── bai1 │ │ ├── Makefile │ │ ├── README.txt │ │ ├── shared.c │ │ └── shared.h │ ├── bai3 │ │ ├── Makefile │ │ ├── README.txt │ │ └── my_ls.c │ ├── bai4 │ │ ├── Makefile │ │ ├── README.txt │ │ └── get_environment.c │ ├── bai5 │ │ ├── A.c │ │ ├── B.c │ │ ├── C.c │ │ ├── Makefile │ │ └── README.txt │ └── bai6 │ │ ├── Makefile │ │ ├── README.txt │ │ ├── get_sension_id.c │ │ ├── get_sension_id2.c │ │ └── get_sension_id3.c ├── Bài 3 - Process.mm ├── Process.pptx └── code_example │ └── main_argv │ └── main_argv.c ├── Bai 5 ├── Example_code │ ├── add_timer.c │ └── interrupt_handler.c ├── Handle_button_for_orange_pi_zero │ ├── README.txt │ ├── check_event_timer.c │ └── interrupt.c └── xu_ly_event.pptx ├── Bai 7 ├── Bai_tap │ ├── b3 │ │ ├── Makefile │ │ ├── README.txt │ │ ├── data.txt │ │ └── main.c │ ├── practive_1 │ │ ├── Makefile │ │ ├── README.txt │ │ └── main.c │ └── practive_2 │ │ ├── Makefile │ │ ├── README.txt │ │ └── main.c ├── Signal.mm └── Signal.pptx ├── Bai 8 ├── Bai_tap │ ├── semaphore │ │ ├── Makefile │ │ ├── README.txt │ │ └── main.c │ ├── test_multithread │ │ └── test_multithread.c │ └── wrapper │ │ ├── Makefile │ │ ├── README.txt │ │ ├── wrapper_function_file.c │ │ ├── wrapper_function_file.h │ │ └── wrapper_test.c ├── Lập trình multithread.mm ├── Lập trình multithread.pptx └── sample_code.txt ├── Bai 9 ├── Bai_tap_buoi7 │ └── send_file │ │ ├── Makefile │ │ ├── README.txt │ │ ├── client_sample.c │ │ └── server_sample.c ├── Lập trình với socket.mm ├── Lập trình với socket.pptx └── sample_code │ └── client_server_sample │ ├── client.c │ └── server.c ├── Bai23 Helloworld_kernel_module ├── Hello world kernel module.mm ├── Hello world kernel module.pptx ├── led_driver │ ├── Makefile │ ├── README.txt │ ├── debug.log │ └── led.c ├── outline.txt └── sample_code │ ├── Bat_tat_led.c │ ├── Makefile │ ├── README.txt │ └── hello_world.c ├── Linux_embedded_Aug.xls ├── Tương tác với hệ điều hành Linux.docx ├── bai 4 ├── Character device driver.mm ├── Character device driver.pptx ├── Sample_code │ ├── led_driver │ │ ├── Makefile │ │ └── exam_cdev.c │ └── loopback │ │ ├── Makefile │ │ ├── exam_cdev.c │ │ └── test_character.c └── outline.txt └── misc_code ├── linux_booting_sequence ├── Linux booting sequence.mm └── linux_boot_sequence.xlsx └── serial └── test_serial.c /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | *.db 3 | -------------------------------------------------------------------------------- /Bai 1/Bai_tap_buoi1/bai1/README.txt: -------------------------------------------------------------------------------- 1 | description: 2 | use gcc compiler build execute file on ubuntu 3 | 4 | how to run ? 5 | build: 6 | make all 7 | run : 8 | ./t -------------------------------------------------------------------------------- /Bai 1/Bai_tap_buoi1/bai1/b1.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void main(){ 4 | printf("hello world\n"); 5 | } 6 | -------------------------------------------------------------------------------- /Bai 1/Bai_tap_buoi1/bai3/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | gcc -o t b3.c 3 | clean: 4 | rm t -------------------------------------------------------------------------------- /Bai 1/Bai_tap_buoi1/bai3/README.txt: -------------------------------------------------------------------------------- 1 | description: 2 | get command line call a program with pid ( pass via argument ) 3 | 4 | how to run ? 5 | build command : 6 | make all 7 | 8 | run : 9 | ./t 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /Bai 1/Bai_tap_buoi1/bai3/b3.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | #include 6 | 7 | void main(int argc , char *argv[]){ 8 | 9 | FILE *fp ; 10 | char buf[100], namepro[100]; 11 | int pid ; 12 | 13 | if ( argc == 2) 14 | { 15 | if( pid = atoi(argv[1])) 16 | { 17 | sprintf(buf, "/proc/%d/cmdline",pid); 18 | if( fp = fopen(buf , "r")) 19 | { 20 | fgets(namepro , 100 , fp); 21 | puts(namepro); 22 | } 23 | else 24 | printf("don't have %d\n " , pid); 25 | } 26 | 27 | 28 | } 29 | else { 30 | 31 | puts("error syntax "); 32 | } 33 | 34 | 35 | 36 | } 37 | -------------------------------------------------------------------------------- /Bai 1/Bài 1 - Lập trình trên Linux.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 1/Bài 1 - Lập trình trên Linux.pptx -------------------------------------------------------------------------------- /Bai 1/documentations/gdb/gdb-tutorial-handout.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 1/documentations/gdb/gdb-tutorial-handout.pdf -------------------------------------------------------------------------------- /Bai 1/tong quan ve hdh unix mindmap.txt: -------------------------------------------------------------------------------- 1 | Ưu nhược điểm của embedded Linux 2 | rich user interface 3 | Open source 4 | Có nhiều thư viện hỗ trợ 5 | Cộng đồng lập trình viên lớn 6 | Hệ thống kém ổn định 7 | Tiêu tốn tài nguyên 8 | Các command line cơ bản 9 | Là các chương trình trong thư mục /bin và /sbin 10 | ls 11 | cd 12 | pwd 13 | cp, mv 14 | man 15 | sudo 16 | mkdir 17 | Cài đặt phần mềm 18 | apt command 19 | Chương trình apt chuyên dùng để install, uninstall các chương trình khác trong linux 20 | apt sẽ connect vào 1 số các server của open source và tìm kiếm phần mềm trùng với tên mà người dùng yêu cầu để tiến hành cài đặt 21 | apt-get update, apt-get install 22 | Các kỹ thuật cơ bản khi lập trình trên Linux 23 | Vim editor 24 | Cho phép người dùng lập trình trên giao diện console và không hỗ trợ chuột 25 | Hotkey 26 | I: Insert mode, Esc: Command mode 27 | : x: Nhảy đến dòng x 28 | /string: Tìm kiếm chuỗi string 29 | Shift + 8: Tìm kiếm word hiện tại trên con trỏ 30 | :wq: Quit và save, :q! Quit nhưng không save 31 | https://www.maketecheasier.com/cheatsheet/vim-keyboard-shortcuts/ 32 | gcc compiler 33 | command line dùng để build source code 34 | command cơ bản: gcc -o output_name file.c 35 | options 36 | -I: chỉ đến đường dẫn tìm các file .h 37 | -l: Chỉ đến đường dẫn chứa các file thư viện động 38 | https://www.thegeekstuff.com/2012/10/gcc-compiler-options/ 39 | Sử dụng vim để viết chương trình tính tổng các số từ 1 đến 100 và in ra màn hình 40 | Shell script 41 | Linux cho phép lưu lại các command line trên 1 file text sau đó thực thi file text đó. 42 | Example: build.sh 43 | Viết script để build chương trình tính tổng 44 | Makefile 45 | 1 loại script chuyên dùng để build source code. Được đọc và thực thi bởi chương trình make. 46 | Makefile có khả năng kiểm tra sự thay đổi trong source và chỉ build lại những file source có thay đổi. 47 | Example 48 | https://www.cs.colby.edu/maxwell/courses/tutorials/maketutor/ 49 | Sử dụng Makefile để build chương trình tính tổng 50 | Các kỹ thuật tìm kiếm và debug source code 51 | gdb debugger 52 | Là chương trình cho phép người dùng debug ở trong chế độ console 53 | Sử dụng option 54 | Chỉ định program cần debug: gdb file_name 55 | set break point: b N 56 | run chương trình: run 57 | Xem giá trị của biến: 58 | print val_name 59 | đi qua 1 câu lệnh: next 60 | grep and find command 61 | find path_to_folder *name* 62 | Tìm kiếm tất cả các file có chứa chuỗi name trong foler path_to_folder 63 | grep -nrwI string path_to_folder 64 | Tìm kiếm chuỗi string trong folder path_to_folder 65 | options nrwI 66 | option --include 67 | cscope 68 | Là công cụ phân tích, hỗ trợ tìm kiếm source code trong chế độ console 69 | Cách sử dụng 70 | -------------------------------------------------------------------------------- /Bai 10/Chia sẻ bộ nhớ giữa các process.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 10/Chia sẻ bộ nhớ giữa các process.pptx -------------------------------------------------------------------------------- /Bai 10/example code/mmap api example/README.txt: -------------------------------------------------------------------------------- 1 | command to build 2 | gcc -o reader reader.c -lrt 3 | gcc -o writer writer.c -lrt -------------------------------------------------------------------------------- /Bai 10/example code/mmap api example/blink_led_31_mmap.c: -------------------------------------------------------------------------------- 1 | //Blink led: GPIO2_2 - P8_7 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #define GPIO_ADDR_BASE 0x44E07000 12 | #define ADDR_SIZE (0x44E07FFF - 0x44E07000) 13 | #define GPIO_SETDATAOUT_OFFSET 0x194 14 | #define GPIO_CLEARDATAOUT_OFFSET 0x190 15 | #define GPIO_OE_OFFSET 0x134 16 | #define LED (1 << 31) 17 | 18 | int main () 19 | { 20 | const int SIZE = 4096; 21 | int shm_fd = -1; 22 | unsigned int *ptr = NULL; 23 | 24 | shm_fd = open ("/dev/mem", O_RDWR | O_SYNC, 0666); 25 | ptr = mmap(0, SIZE, PROT_WRITE, MAP_SHARED, shm_fd, GPIO_ADDR_BASE); 26 | *(ptr + GPIO_OE_OFFSET / 4) &= ~LED; 27 | while (1) 28 | { 29 | *(ptr + GPIO_SETDATAOUT_OFFSET / 4) |= LED; 30 | sleep(1); 31 | *(ptr + GPIO_CLEARDATAOUT_OFFSET / 4) |= LED; 32 | sleep(1); 33 | } 34 | 35 | close(shm_fd); 36 | return 0; 37 | } -------------------------------------------------------------------------------- /Bai 10/example code/mmap api example/blink_mmap.c: -------------------------------------------------------------------------------- 1 | //Blink led: GPIO2_2 - P8_7 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #define LED 0x00000004 12 | #define GPIO2_BASE 0x481AC00 13 | #define SET 0x194 14 | #define CLEAR 0x190 15 | 16 | int main () 17 | { 18 | const int SIZE = 4096; 19 | int shm_fd; 20 | void *ptr; 21 | uint32_t *gpio_set; 22 | uint32_t *gpio_clear; 23 | 24 | shm_fd = open ("/dev/mem", O_RDWR | O_SYNC, 0666); 25 | if (shm_fd == -1) 26 | { 27 | perror("Open failed"); 28 | return -1; 29 | } 30 | //ftruncate(shm_fd, SIZE); 31 | ptr = mmap(0, SIZE, PROT_WRITE, MAP_SHARED, shm_fd, GPIO2_BASE); 32 | 33 | gpio_set = ptr + SET; 34 | gpio_clear = ptr + CLEAR; 35 | 36 | while (1) 37 | { 38 | *gpio_set = LED; 39 | sleep(2); 40 | *gpio_clear = LED; 41 | sleep(2); 42 | } 43 | 44 | close(shm_fd); 45 | return 0; 46 | } -------------------------------------------------------------------------------- /Bai 10/example code/mmap api example/reader.c: -------------------------------------------------------------------------------- 1 | // C program for Consumer process illustrating 2 | // POSIX shared-memory API. 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | int main() 13 | { 14 | /* the size (in bytes) of shared memory object */ 15 | const int SIZE = 4096; 16 | 17 | /* name of the shared memory object */ 18 | const char* name = "OS"; 19 | 20 | /* shared memory file descriptor */ 21 | int shm_fd; 22 | 23 | /* pointer to shared memory object */ 24 | void* ptr; 25 | 26 | /* open the shared memory object */ 27 | shm_fd = shm_open(name, O_RDONLY, 0666); 28 | 29 | /* memory map the shared memory object */ 30 | ptr = mmap(0, SIZE, PROT_READ, MAP_SHARED, shm_fd, 0); 31 | 32 | /* read from the shared memory object */ 33 | printf("%s", (char*)ptr); 34 | 35 | /* remove the shared memory object */ 36 | shm_unlink(name); 37 | return 0; 38 | } -------------------------------------------------------------------------------- /Bai 10/example code/mmap api example/writer.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | int main() 12 | { 13 | /* the size (in bytes) of shared memory object */ 14 | const int SIZE = 4096; 15 | 16 | /* name of the shared memory object */ 17 | const char* name = "OS"; 18 | 19 | /* strings written to shared memory */ 20 | const char* message_0 = "Hello"; 21 | const char* message_1 = "World!"; 22 | 23 | /* shared memory file descriptor */ 24 | int shm_fd; 25 | 26 | /* pointer to shared memory obect */ 27 | void* ptr; 28 | 29 | /* create the shared memory object */ 30 | shm_fd = shm_open(name, O_CREAT | O_RDWR, 0666); 31 | 32 | /* configure the size of the shared memory object */ 33 | ftruncate(shm_fd, SIZE); 34 | 35 | /* memory map the shared memory object */ 36 | ptr = mmap(0, SIZE, PROT_WRITE, MAP_SHARED, shm_fd, 0); 37 | 38 | /* write to the shared memory object */ 39 | sprintf(ptr, "%s", message_0); 40 | 41 | ptr += strlen(message_0); 42 | sprintf(ptr, "%s", message_1); 43 | ptr += strlen(message_1); 44 | return 0; 45 | } -------------------------------------------------------------------------------- /Bai 10/example code/shm api example/reader process.txt: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int main() 7 | { 8 | // ftok to generate unique key 9 | key_t key = ftok("shmfile",65); 10 | 11 | // shmget returns an identifier in shmid 12 | int shmid = shmget(key,1024,0666|IPC_CREAT); 13 | 14 | // shmat to attach to shared memory 15 | char *str = (char*) shmat(shmid,(void*)0,0); 16 | 17 | printf("Data read from memory: %s\n",str); 18 | 19 | //detach from shared memory 20 | shmdt(str); 21 | 22 | // destroy the shared memory 23 | shmctl(shmid,IPC_RMID,NULL); 24 | 25 | return 0; 26 | } -------------------------------------------------------------------------------- /Bai 10/example code/shm api example/writer process.txt: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int main() 7 | { 8 | // ftok to generate unique key 9 | key_t key = ftok("shmfile",65); 10 | 11 | // shmget returns an identifier in shmid 12 | int shmid = shmget(key,1024,0666|IPC_CREAT); 13 | 14 | // shmat to attach to shared memory 15 | char *str = (char*) shmat(shmid,(void*)0,0); 16 | 17 | cout<<"Write Data : "; 18 | gets(str); 19 | 20 | printf("Data written in memory: %s\n",str); 21 | 22 | //detach from shared memory 23 | shmdt(str); 24 | 25 | return 0; 26 | } -------------------------------------------------------------------------------- /Bai 10/shared memory outline.txt: -------------------------------------------------------------------------------- 1 | agenda 2 | memory page structure 3 | Library support 4 | shm API 5 | mmap 6 | shm API 7 | Sequence diagram to share memory via shm API 8 | generate a unique key from string 9 | #include 10 | #include 11 | key_t ftok(const char *pathname, int proj_id); 12 | convert a pathname and a project identifier to a key 13 | Alloc memory from key 14 | int shmget(key_t key, size_t size, int shmflg); 15 | Allocate and return memory address for share memory 16 | IPC_CREAT 17 | PROT_READ | PROT_WRITE 18 | Permission like a file 19 | Map shared memory to process address space 20 | void *shmat(int shmid, const void *shmaddr, int shmflg); 21 | shmaddr should be NULL 22 | SHM_RDONLY 23 | Unmap shared memory in process address space 24 | int shmdt(const void *shmaddr); 25 | Destroy shared memory 26 | int shmctl(int shmid, int cmd, struct shmid_ds *buf); 27 | IPC_RMID 28 | Example code 29 | Practice with shm API 30 | mmap API 31 | Sequence diagram to share memory via mmap API 32 | function API 33 | #include 34 | void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset); 35 | int munmap(void *addr, size_t length); 36 | shm_open(name, O_CREAT | O_RDRW, 0666); 37 | ftruncate(shm_fd, SIZE); 38 | Example code 39 | Compare shm and mmap API 40 | Practice with mmap API 41 | Home work -------------------------------------------------------------------------------- /Bai 11/Device tree.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 11/Device tree.pptx -------------------------------------------------------------------------------- /Bai 11/code/led.c: -------------------------------------------------------------------------------- 1 | #include /* Needed by all modules */ 2 | #include /* Needed for KERN_INFO */ 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #define GPIO_SETDATAOUT_OFFSET 0x194 12 | #define GPIO_CLEARDATAOUT_OFFSET 0x190 13 | #define GPIO_OE_OFFSET 0x134 14 | #define GPIO30 ~(1 << 30) 15 | #define GPIO30_DATA_OUT (1 << 30) 16 | #define GPIO03 ~(1 << 3) 17 | #define GPIO03_DATA_OUT (1 << 3) 18 | 19 | struct led_config_t { 20 | uint32_t led; 21 | uint32_t data_out; 22 | uint32_t time; 23 | }; 24 | 25 | struct led_driver_data { 26 | void __iomem *base_addr; 27 | unsigned int count; 28 | const struct led_config_t *led_config; 29 | struct timer_list my_timer; 30 | }; 31 | 32 | struct led_config_t led_gpio30_config = { 33 | .led = GPIO30, 34 | .data_out = GPIO30_DATA_OUT, 35 | .time = 1, 36 | }; 37 | 38 | struct led_config_t led_gpio03_config = { 39 | .led = GPIO03, 40 | .data_out = GPIO03_DATA_OUT, 41 | .time = 3, 42 | }; 43 | 44 | static void timer_function(unsigned long data){ 45 | struct led_driver_data *timer_data = (struct led_driver_data *)data; 46 | 47 | if ((timer_data->count % 2) == 0) 48 | writel_relaxed(timer_data->led_config->data_out, timer_data->base_addr + GPIO_SETDATAOUT_OFFSET); 49 | else 50 | writel_relaxed(timer_data->led_config->data_out, timer_data->base_addr + GPIO_CLEARDATAOUT_OFFSET); 51 | 52 | (timer_data->count)++; 53 | mod_timer(&(timer_data->my_timer), jiffies + timer_data->led_config->time * HZ); 54 | } 55 | 56 | static const struct of_device_id blink_led_of_match[] = { 57 | { .compatible = "led-example1", .data = &led_gpio30_config}, 58 | { .compatible = "led-example2", .data = &led_gpio03_config}, 59 | {}, 60 | }; 61 | 62 | static int blink_led_probe(struct platform_device *pdev) 63 | { 64 | struct resource *res = NULL; 65 | uint32_t reg_data = 0; 66 | const struct of_device_id *of_id = NULL; 67 | struct led_driver_data *timer_data = NULL; 68 | 69 | printk(KERN_EMERG "PhuLA %s, %d\n", __func__, __LINE__); 70 | 71 | timer_data = kmalloc(sizeof(struct led_driver_data), GFP_KERNEL); 72 | timer_data->count = 0; 73 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 74 | printk(KERN_EMERG "PhuLA start = %d, end = %d\n", res->start, res->end); 75 | timer_data->base_addr = ioremap(res->start, res->end - res->start); 76 | 77 | of_id = of_match_device(blink_led_of_match, &pdev->dev); 78 | timer_data->led_config = of_id->data; 79 | 80 | printk(KERN_EMERG "PhuLA led = %u, data_out = %u\n", timer_data->led_config->led, timer_data->led_config->data_out); 81 | 82 | reg_data = readl_relaxed(timer_data->base_addr + GPIO_OE_OFFSET); 83 | reg_data &= timer_data->led_config->led; 84 | writel_relaxed(reg_data, timer_data->base_addr + GPIO_OE_OFFSET); 85 | 86 | init_timer(&(timer_data->my_timer)); 87 | timer_data->my_timer.expires = jiffies + timer_data->led_config->time * HZ; 88 | timer_data->my_timer.function = timer_function; 89 | timer_data->my_timer.data = (unsigned long)timer_data; 90 | add_timer(&(timer_data->my_timer)); 91 | 92 | return 0; 93 | } 94 | 95 | static int blink_led_remove(struct platform_device *pdev) 96 | { 97 | return 0; 98 | } 99 | 100 | static struct platform_driver blink_led_driver = { 101 | .probe = blink_led_probe, 102 | .remove = blink_led_remove, 103 | .driver = { 104 | .name = "blink_led", 105 | .of_match_table = blink_led_of_match, 106 | }, 107 | }; 108 | 109 | module_platform_driver(blink_led_driver); 110 | 111 | MODULE_LICENSE("GPL"); 112 | MODULE_AUTHOR("Phu Luu An"); 113 | MODULE_DESCRIPTION("Hello world kernel module"); 114 | -------------------------------------------------------------------------------- /Bai 11/tai_lieu/Device tree.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 11/tai_lieu/Device tree.pdf -------------------------------------------------------------------------------- /Bai 11/tai_lieu/Petazzoni-device-tree-dummies_0.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 11/tai_lieu/Petazzoni-device-tree-dummies_0.pdf -------------------------------------------------------------------------------- /Bai 11/tai_lieu/Pincontrol-gpio-update.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 11/tai_lieu/Pincontrol-gpio-update.pdf -------------------------------------------------------------------------------- /Bai 11/tai_lieu/devicetree-specification-v0.1-20160524.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 11/tai_lieu/devicetree-specification-v0.1-20160524.pdf -------------------------------------------------------------------------------- /Bai 12/systemcall.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 12/systemcall.pptx -------------------------------------------------------------------------------- /Bai 13/Virtual memory management.mm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Bai 13/Virtual memory management_outline.txt: -------------------------------------------------------------------------------- 1 | Một ví dụ về sự cần thiết của virtual memory 2 | Page frame 3 | Page Descriptors 4 | Virtual and physical memory mapping 5 | Process page table 6 | Virtual address, logical address, physical address 7 | Page fault exception 8 | Memory access in virtual mode and protected mode 9 | Cached memory 10 | Some use cases need to prevent cached memory 11 | Memory allocator 12 | Non continuous allocator 13 | Lazy allocate 14 | Slab allocator 15 | Memory cleanup -------------------------------------------------------------------------------- /Bai 13/Virtual memory.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 13/Virtual memory.pptx -------------------------------------------------------------------------------- /Bai 14/Docs/BBB/Beaglebone-Black-Pinout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 14/Docs/BBB/Beaglebone-Black-Pinout.png -------------------------------------------------------------------------------- /Bai 14/Docs/BBB/BeagleboneBlackP8HeaderTable.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 14/Docs/BBB/BeagleboneBlackP8HeaderTable.pdf -------------------------------------------------------------------------------- /Bai 14/Docs/BBB/BeagleboneBlackP9HeaderTable.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 14/Docs/BBB/BeagleboneBlackP9HeaderTable.pdf -------------------------------------------------------------------------------- /Bai 14/Docs/BBB/Built-in device driver linux.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 14/Docs/BBB/Built-in device driver linux.docx -------------------------------------------------------------------------------- /Bai 14/Docs/BBB/document-build-linux-bbb.txt: -------------------------------------------------------------------------------- 1 | Create Bootable SD-card for Beaglebone Black 2 | ============================================ 3 | 1. Requirement 4 | ============== 5 | - cross-compiler: 6 | - u-boot source 7 | - linux kernel source 8 | - root file system 9 | - sd-card more than 4GB 10 | 11 | 2. Step by step 12 | =============== 13 | 2.1 Get stuff: 14 | - install cross-compiler: 15 | + download from: http://releases.linaro.org/components/toolchain/binaries/7.4-2019.02/arm-linux-gnueabihf/ 16 | + file: gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabihf.tar.xz 17 | + extract this file: 18 | tar -xvf gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabihf.tar.xz 19 | mv gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabihf ~/arm-linux-toolchain/ 20 | 21 | - clone source code u-boot : 22 | cd ~/ 23 | git clone git://git.denx.de/u-boot.git u-boot/ 24 | 25 | - clone source code kernel : 26 | cd ~/ 27 | git clone https://github.com/beagleboard/linux.git 28 | - Download Rootfs: 29 | https://www.dropbox.com/s/k93doprl261hwn2/rootfs.tar.xz?dl=0 30 | 31 | 2.2 Compile source code 32 | - sudo apt install u-boot-tools 33 | - sudo apt install lzop 34 | - Compile U-boot: 35 | cd ~/u-boot/ 36 | make ARCH=arm CROSS_COMPILE=~/arm-linux-toolchain/bin/arm-linux-gnueabihf- am335x_boneblack_vboot_defconfig 37 | make ARCH=arm CROSS_COMPILE=~/arm-linux-toolchain/bin/arm-linux-gnueabihf- 38 | 39 | - Compile linux kernel: 40 | cd ~/linux/ 41 | sudo make ARCH=arm CROSS_COMPILE=~/arm-linux-toolchain/bin/arm-linux-gnueabihf- bb.org_defconfig 42 | sudo make ARCH=arm CROSS_COMPILE=~/arm-linux-toolchain/bin/arm-linux-gnueabihf- uImage dtbs LOADADDR=0x80008000 -j4 43 | 44 | 2.3 Format Sd-card 45 | - install tool format sd-card: 46 | sudo apt-get install gparted 47 | 48 | - plug-in sd-card and format it with two partitions: 49 | + partition 1: .size = 50M 50 | .type: Fat32 51 | .label: BOOT 52 | + partition 2: .size = 3G (rest of total sd-card's size) 53 | .type: ext4 54 | .label: RFS 55 | 56 | - to view what sd-card's partition is. you need run following command: 57 | lsblk 58 | 59 | eg: sdc -| 60 | |- sdc1 /media/trongdung/BOOT/ 61 | |- sdc2 /media/trongdung/RFS/ 62 | 63 | ***NOTE***: if result of command 'lsblk' are not like above, you must mount sdc1 and sdc2 to your system to write data to these partitions. 64 | 65 | - Runs following commands to make BOOT partition: 66 | sudo cp ~/u-boot/MLO /media/trongdung/BOOT/ 67 | sudo cp ~/u-boot/u-boot.img /media/trongdung/BOOT/ 68 | sudo cp ~/linux/arch/arm/boot/uImage /media/trongdung/BOOT/ 69 | sudo cp ~/linux/arch/arm/boot/dts/am335x-boneblack.dtb /media/trongdung/BOOT/ 70 | 71 | vi /media/trongdung/BOOT/uEnv.txt 72 | *** and then paste following content to the uEnv.txt file *** 73 | ----------------------------------------------------- 74 | console=ttyS0,115200n8 75 | netargs=setenv bootargs console=ttyO0,115200n8 root=/dev/mmcblk0p2 ro rootfstype=ext4 rootwait debug earlyprintk mem=512M 76 | netboot=echo Booting from microSD ...; setenv autoload no ; load mmc 0:1 ${loadaddr} uImage ; load mmc 0:1 ${fdtaddr} am335x-boneblack.dtb ; run netargs ; bootm ${loadaddr} - ${fdtaddr} 77 | uenvcmd=run netboot 78 | ------------------------------------------------------ 79 | 80 | after that, run command: 81 | sync 82 | sudo umount /media/trongdung/BOOT/ 83 | 84 | - Runs following commands to make RFS partition: 85 | cd ~/Download/ 86 | tar -xvf rootfs.tar.xz 87 | cd rootfs 88 | sudo cp -r ./* /media/trongdung/RFS/ 89 | sync 90 | sudo umount /media/trongdung/RFS/ 91 | 92 | 3. Done ! Good luck :) 93 | 94 | 95 | 96 | ============================================== Makefile Build Source ================================================= 97 | CC := /home/trongdung/tool-chain/bin/arm-linux-gnueabihf- 98 | 99 | image: 100 | sudo make ARCH=arm CROSS_COMPILE=${CC} uImage dtbs LOADADDR=0x80008000 -j4 101 | all: 102 | sudo make ARCH=arm CROSS_COMPILE=${CC} bb.org_defconfig 103 | sudo make ARCH=arm CROSS_COMPILE=${CC} uImage dtbs LOADADDR=0x80008000 -j4 104 | uboot: 105 | make ARCH=arm CROSS_COMPILE=${CC} am335x_boneblack_vboot_defconfig 106 | make ARCH=arm CROSS_COMPILE=${CC} -------------------------------------------------------------------------------- /Bai 14/Docs/BBB/rmchip.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 14/Docs/BBB/rmchip.pdf -------------------------------------------------------------------------------- /Bai 14/Docs/New Text Document.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 14/Docs/New Text Document.txt -------------------------------------------------------------------------------- /Bai 14/Docs/trace_spi/can_dma-2.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 14/Docs/trace_spi/can_dma-2.PNG -------------------------------------------------------------------------------- /Bai 14/Docs/trace_spi/can_dma.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 14/Docs/trace_spi/can_dma.PNG -------------------------------------------------------------------------------- /Bai 14/Docs/trace_spi/prepare_mess.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 14/Docs/trace_spi/prepare_mess.PNG -------------------------------------------------------------------------------- /Bai 14/Docs/trace_spi/trace-spi.txt: -------------------------------------------------------------------------------- 1 | omap2_mcspi_setup(): setting module spi 2 | setup mode, clock, etc. 3 | omap2_mcspi_can_dma 4 | determine whether this controller support DMA or not. 5 | omap2_mcspi_cleanup 6 | release spi controller 7 | free gpio number of chip-select, free/disable dma, ... 8 | 9 | omap2_mcspi_prepare_message(): set up the controller to transfer a single message 10 | disable tất cả các chân chip-select khác ngoại chip select hiện tại dùng cho current-slave. 11 | disable được được thực hiện bằng cách config giá trị bit FORCE trong thanh ghi CHCONF. 12 | được gọi trước mỗi lần truyền một byte. 13 | 14 | omap2_mcspi_set_cs(): set the logic level of the chip select linen 15 | thực hiện thay đổi value của chân CS, cần gọi 2 lần: 1 lần cs = LOW để chọn chip và 1 lần cs = HIGH to disable 16 | 17 | ------------------------------------------------------------------------ 18 | __spi_pump_message() 19 | { 20 | ret = ctlr->prepare_message(ctlr, ctlr->cur_msg); 21 | ret = ctlr->transfer_one_message(ctlr, ctlr->cur_msg); 22 | } 23 | 24 | ctlr->transfer_one_message() 25 | { 26 | omap2_mcspi_set_cs(...., LOW); 27 | .... 28 | if (dma buffer ready) { 29 | omap2_mcspi_can_dma() 30 | ... 31 | } 32 | ... 33 | omap2_mcspi_set_cs(...., HIGH); 34 | } -------------------------------------------------------------------------------- /Bai 14/Docs/trace_spi/transfer_one.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 14/Docs/trace_spi/transfer_one.PNG -------------------------------------------------------------------------------- /Bai 14/README.md: -------------------------------------------------------------------------------- 1 | # Device-Driver-Linux 2 | -------------------------------------------------------------------------------- /Bai 14/SPI-protocol/Basic-SPI-Protocol-Driver/Makefile: -------------------------------------------------------------------------------- 1 | PWD := $(shell pwd) 2 | 3 | file-to-check = lcd1.c 4 | 5 | obj-m += lcd1.o 6 | 7 | CROSS := /home/dungnt98/toolchain/arm-linux-gnueabihf/bin/arm-linux-gnueabihf- 8 | KERNEL := /home/dungnt98/linux/ 9 | 10 | all: 11 | make ARCH=arm CROSS_COMPILE=$(CROSS) -C $(KERNEL) SUBDIRS=$(PWD) modules 12 | clean: 13 | make -C $(KERNEL) SUBDIRS=$(PWD) clean 14 | check: 15 | ./checkpatch.pl --no-tree --ignore CONST_STRUCT --show-types -f $(file-to-check) 16 | -------------------------------------------------------------------------------- /Bai 14/SPI-protocol/Basic-SPI-Protocol-Driver/README.md: -------------------------------------------------------------------------------- 1 | ******************* GUIDE for use SPI protocol driver as example for studying ************* 2 | - This driver is SPI protocol driver and used controll LCD Nokia 5110. 3 | - It can be create multiple device file by just one driver file. 4 | - It can do it because it use Link list to parse device tree SPI node to get child-node and initialize device infomation (SPI slave). 5 | ------------------------------------------------------------------------------------------------------------------------------------- 6 | Do following step to use this source code: 7 | 8 | 1. Modify spi1 node in device tree file : linux/arch/arm/boot/dts/am33xx.dtsi 9 | 10 | spi1: spi@481a0000 { 11 | compatible = "ti,omap4-mcspi"; 12 | #address-cells = <1>; 13 | #size-cells = <0>; 14 | reg = <0x481a0000 0x400>; 15 | interrupts = <125>; 16 | ti,spi-num-cs = <2>; 17 | ti,hwmods = "spi1"; 18 | cs-gpios = <&gpio3 17 1>, <&gpio0 7 1>; 19 | dmas = <&edma 42 0 20 | &edma 43 0 21 | &edma 44 0 22 | &edma 45 0>; 23 | dma-names = "tx0", "rx0", "tx1", "rx1"; 24 | status = "disabled"; 25 | 26 | lcd0:lcd0@0 { 27 | reg = <0>; 28 | spi-max-frequency = <10000000>; 29 | compatible = "dungnt98,spi1"; 30 | }; 31 | 32 | lcd1:lcd1@1 { 33 | reg = <1>; 34 | spi-max-frequency = <10000000>; 35 | compatible = "dungnt98,spi2"; 36 | }; 37 | }; 38 | 39 | 2. Re-build kernel and coppy file linux/arch/arm/boot/dts/am335x-boneblack.dtb to BOOT partition of sd-card. 40 | 3. Modify path of kernel and toolchain in Makefile file then run following command to build driver: 41 | make clean all 42 | 4. Coppy file lcd_driver.ko to sd-card. 43 | 44 | 5. Insert sd-card and Power up board and run following command to test driver: 45 | insmode lcd_driver.ko 46 | echo "hello" > /dev/lcd_113 47 | 48 | /******** connection between board and 2 lcd ********/ 49 | ---------------------------------------------------------------------------------------------------------- 50 | | LCD_1 | BBB | LCD_2 | 51 | ---------------------------------------------------------------------------------------------------------- 52 | CLK <--------------------> P9_31 - SPI1_SCLK <--------------------> CLK 53 | DIN <--------------------> P9_20 - GPIO_112 / SPI1_D1 <--------------------> DIN 54 | RESET <--------------------> P9_27 - GPIO_115 <--------------------> RESET 55 | CMD <--------------------> P9_25 - GPIO_117 <--------------------> CMD 56 | EN <--------------------> P9_28 - SPI1_CS0 57 | P9_42 - SPI1_CS1 <--------------------> EN 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /Bai 14/SPI-protocol/Basic-SPI-Protocol-Driver/lcd.h: -------------------------------------------------------------------------------- 1 | #ifndef __LCD_5110 2 | #define __LCD_5110 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #define LCD_DC_PIN 15 10 | #define LCD_RST_PIN 14 11 | 12 | #define LCD_WIDTH 84 13 | #define LCD_HEIGHT 48 14 | 15 | #define LCD_POWERDOWN 0x04 16 | #define LCD_ENTRYMODE 0x02 17 | #define LCD_EXTENDEDINSTRUCTION 0x01 18 | #define LCD_DISPLAYBLANK 0x00 19 | #define LCD_DISPLAYNORMAL 0x04 20 | #define LCD_DISPLAYALLON 0x01 21 | #define LCD_DISPLAYINVERTED 0x05 22 | 23 | #define LCD_FUNCTIONSET 0x20 24 | #define LCD_DISPLAYCONTROL 0x08 25 | #define LCD_SETYADDR 0x40 26 | #define LCD_SETXADDR 0x80 27 | #define LCD_SETTEMP 0x04 28 | #define LCD_SETBIAS 0x10 29 | #define LCD_SETVOP 0x80 30 | 31 | #define LCD_BIAS 0x03 32 | #define LCD_TEMP 0x02 33 | #define LCD_CONTRAST 0x46 34 | 35 | #define LCD_CHAR5x7_WIDTH 6 36 | #define LCD_CHAR5x7_HEIGHT 8 37 | #define LCD_CHAR3x5_WIDTH 4 38 | #define LCD_CHAR3x5_HEIGHT 6 39 | 40 | #define LCD_BUFFER_SIZE (LCD_WIDTH * LCD_HEIGHT / 8) 41 | 42 | 43 | typedef unsigned char unit8_t; 44 | 45 | typedef enum { 46 | PIN_LOW = 0, 47 | PIN_HIGH = !PIN_LOW 48 | } Pin_State_t; 49 | 50 | typedef enum { 51 | LCD_COMMAND = 0, 52 | LCD_DATA = !LCD_COMMAND 53 | } LCD_WriteType_t; 54 | 55 | typedef enum { 56 | LCD_State_Low = 0, 57 | LCD_State_High = !LCD_State_Low 58 | } LCD_State_t; 59 | 60 | typedef enum { 61 | LCD_Pin_DC = 1, 62 | LCD_Pin_RST = 2 63 | } LCD_Pin_t; 64 | 65 | typedef enum { 66 | LCD_Pixel_Clear = 0, 67 | LCD_Pixel_Set = !LCD_Pixel_Clear 68 | } LCD_Pixel_t; 69 | 70 | typedef enum { 71 | LCD_FontSize_5x7 = 0, 72 | LCD_FontSize_3x5 = !LCD_FontSize_5x7 73 | } LCD_FontSize_t; 74 | 75 | typedef enum { 76 | LCD_Invert_Yes, 77 | LCD_Invert_No 78 | } LCD_Invert_t; 79 | 80 | void gpio_set_pin(int gpio, Pin_State_t state); 81 | int LCD_init_IO(void); 82 | void LCD_free_IO(void); 83 | void LCD_Init(unsigned char contrast); 84 | 85 | void LCD_send(unsigned char data); 86 | void LCD_Pin(LCD_Pin_t pin, LCD_State_t state); 87 | void LCD_Write(LCD_WriteType_t type, unsigned char data); 88 | void LCD_Home(void); 89 | void LCD_SetContrast(unsigned char contrast); 90 | void LCD_GotoXY(unsigned char x, unsigned char y); 91 | 92 | void LCD_UpdateArea(unsigned char xMin, unsigned char yMin, unsigned char xMax, 93 | unsigned char yMax); 94 | void LCD_Refresh(void); 95 | void LCD_Clear(void); 96 | 97 | void LCD_DrawPixel(unsigned char x, unsigned char y, LCD_Pixel_t pixel); 98 | void LCD_Invert(LCD_Invert_t invert); 99 | void LCD_Putc(char c, LCD_Pixel_t color, LCD_FontSize_t size); 100 | void LCD_Puts(char *s, LCD_Pixel_t color, LCD_FontSize_t size); 101 | 102 | void LCD_DrawLine(unsigned char x0, unsigned char y0, unsigned char x1, 103 | unsigned char y1, LCD_Pixel_t color); 104 | void LCD_DrawRectangle(unsigned char x0, unsigned char y0, unsigned char x1, 105 | unsigned char y1, LCD_Pixel_t color); 106 | void LCD_DrawFilledRectangle(unsigned char x0, unsigned char y0, unsigned char x1, 107 | unsigned char y1, LCD_Pixel_t color); 108 | void LCD_DrawCircle(char x0, char y0, char r, LCD_Pixel_t color); 109 | void LCD_DrawFilledCircle(char x0, char y0, char r, LCD_Pixel_t color); 110 | 111 | 112 | #endif 113 | -------------------------------------------------------------------------------- /Bai 14/SPI-protocol/Basic-SPI-Protocol-Driver/lcd_ioctl.h: -------------------------------------------------------------------------------- 1 | #ifndef __LCD_IOCTL 2 | #define __LCD_IOCTL 3 | 4 | #define MAJIC_NO 100 5 | #define IOCTL_CLEAR _IO(MAJIC_NO, 0) 6 | #define IOCTL_HOME _IO(MAJIC_NO, 1) 7 | #define IOCTL_SET_CONTRAST _IOW(MAJIC_NO, 2, unsigned char) 8 | 9 | typedef struct position { 10 | unsigned char x; 11 | unsigned char y; 12 | } Position_t; 13 | #define IOCTL_GOTOXY _IOW(MAJIC_NO, 3, Position_t) 14 | 15 | typedef enum { 16 | Pixel_Clear = 0, 17 | Pixel_Set = !Pixel_Clear 18 | } Pixel_t; 19 | 20 | typedef struct draw_pixel { 21 | unsigned char x; 22 | unsigned char y; 23 | Pixel_t pixel; 24 | } Draw_Pixel_t; 25 | #define IOCTL_DRAW_PIXEL _IOW(MAJIC_NO, 4, Draw_Pixel_t) 26 | 27 | typedef struct draw_shape { 28 | unsigned char x0; 29 | unsigned char y0; 30 | unsigned char x1; 31 | unsigned char y1; 32 | Pixel_t pixel; 33 | } Draw_Shape_t; 34 | #define IOCTL_DRAW_LINE _IOW(MAJIC_NO, 5, Draw_Shape_t) 35 | #define IOCTL_DRAW_RECT _IOW(MAJIC_NO, 6, Draw_Shape_t) 36 | #define IOCTL_DRAW_FILL_RECT _IOW(MAJIC_NO, 7, Draw_Shape_t) 37 | 38 | typedef struct draw_circle { 39 | char x; 40 | char y; 41 | char r; 42 | Pixel_t pixel; 43 | } Draw_Circle_t; 44 | #define IOCTL_DRAW_CIRCLE _IOW(MAJIC_NO, 8, Draw_Circle_t) 45 | #define IOCTL_DRAW_FILL_CIRCLE _IOW(MAJIC_NO, 9, Draw_Circle_t) 46 | 47 | #define IOCTL_SEND_BUFF _IO(MAJIC_NO, 10) 48 | 49 | typedef enum { 50 | FontSize_5x7 = 0, 51 | FontSize_3x5 = !FontSize_5x7 52 | } FontSize_t; 53 | 54 | typedef struct draw_string { 55 | char message[25]; 56 | Pixel_t pixel; 57 | FontSize_t font; 58 | } Draw_String_t; 59 | 60 | #endif 61 | 62 | -------------------------------------------------------------------------------- /Bai 14/SPI-protocol/Docs/Linux SPI Device Driver.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 14/SPI-protocol/Docs/Linux SPI Device Driver.pptx -------------------------------------------------------------------------------- /Bai 14/SPI-protocol/Docs/McBSP_SPI_SLAVE_PINS.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 14/SPI-protocol/Docs/McBSP_SPI_SLAVE_PINS.PNG -------------------------------------------------------------------------------- /Bai 14/SPI-protocol/Docs/Mcbsp.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 14/SPI-protocol/Docs/Mcbsp.pptx -------------------------------------------------------------------------------- /Bai 14/SPI-protocol/Docs/trace_code: -------------------------------------------------------------------------------- 1 | devm_spi_register_master -> spi_register_controller -> of_register_spi_devices 2 | -> of_register_spi_device 3 | 4 | spi->chip_select = properties in device tree 5 | 6 | /******************************************************************************/ 7 | (0) omap2_mcspi_probe() 8 | { 9 | of_property_read_u32(node, "ti,spi-num-cs", &num_cs); 10 | master->num_chipselect = num_cs; 11 | 12 | status = devm_spi_register_master(&pdev->dev, master); 13 | } 14 | 15 | (1) spi_register_controller() 16 | { 17 | if (!spi_controller_is_slave(ctlr)) { 18 | status = of_spi_register_master(ctlr); /* return 0 */ 19 | if (status) 20 | return status; 21 | } 22 | 23 | /* allocate dynamic bus number using Linux idr */ 24 | id = of_alias_get_id(ctlr->dev.of_node, "spi"); 25 | if (id >= 0) { 26 | ctlr->bus_num = id; 27 | mutex_lock(&board_lock); 28 | id = idr_alloc(&spi_master_idr, ctlr, ctlr->bus_num, ctlr->bus_num + 1, GFP_KERNEL); 29 | mutex_unlock(&board_lock); 30 | if (WARN(id < 0, "couldn't get idr")) 31 | return id == -ENOSPC ? -EBUSY : id; 32 | } 33 | 34 | of_register_spi_devices(ctlr); 35 | } 36 | 37 | (2) static int of_spi_register_master(struct spi_controller *ctlr) 38 | { 39 | int nb, i, *cs; 40 | struct device_node *np = ctlr->dev.of_node; 41 | 42 | if (!np) 43 | return 0; 44 | 45 | nb = of_gpio_named_count(np, "cs-gpios"); 46 | ctlr->num_chipselect = max_t(int, nb, ctlr->num_chipselect); 47 | 48 | /* Return error only for an incorrectly formed cs-gpios property */ 49 | if (nb == 0 || nb == -ENOENT) 50 | return 0; /* run */ 51 | else if (nb < 0) 52 | return nb; 53 | 54 | cs = devm_kzalloc(&ctlr->dev, sizeof(int) * ctlr->num_chipselect, GFP_KERNEL); 55 | ctlr->cs_gpios = cs; 56 | 57 | if (!ctlr->cs_gpios) 58 | return -ENOMEM; 59 | 60 | for (i = 0; i < ctlr->num_chipselect; i++) 61 | cs[i] = -ENOENT; 62 | 63 | for (i = 0; i < nb; i++) 64 | cs[i] = of_get_named_gpio(np, "cs-gpios", i); /* get gpio number to use for gpio.h api */ 65 | return 0; 66 | } 67 | 68 | 69 | (2) of_register_spi_devices(ctlr) 70 | { 71 | for_each_available_child_of_node(ctlr->dev.of_node, nc) { 72 | spi = of_register_spi_device(ctlr, nc); 73 | } 74 | } 75 | 76 | (3) of_register_spi_device() 77 | { 78 | spi = spi_alloc_device(ctlr); 79 | rc = of_spi_parse_dt(ctlr, spi, nc); 80 | rc = spi_add_device(spi); 81 | } 82 | 83 | (4) spi_alloc_device() 84 | { 85 | spi->dev.bus = &spi_bus_type; 86 | spi->cs_gpio = -ENOENT; 87 | } 88 | 89 | (5) static int of_spi_parse_dt(struct spi_controller *ctlr, struct spi_device *spi, 90 | struct device_node *nc) 91 | { 92 | /* Device address */ 93 | rc = of_property_read_u32(nc, "reg", &value); 94 | spi->chip_select = value; 95 | 96 | /* Device speed */ 97 | rc = of_property_read_u32(nc, "spi-max-frequency", &value); 98 | spi->max_speed_hz = value; 99 | } 100 | 101 | 102 | (6) spi_add_device() 103 | { 104 | if (spi->chip_select >= ctlr->num_chipselect) { 105 | dev_err(dev, "cs%d >= max %d\n", spi->chip_select, ctlr->num_chipselect); 106 | return -EINVAL; 107 | } 108 | 109 | if (ctlr->cs_gpios) 110 | spi->cs_gpio = ctlr->cs_gpios[spi->chip_select]; 111 | 112 | status = spi_setup(spi); 113 | } 114 | 115 | /*----------------------------------------------------------------------------*/ 116 | 117 | -------------------------------------------------------------------------------- /Bai 14/SPI-protocol/SPI_Multiple_Slave/README.md: -------------------------------------------------------------------------------- 1 | ******************* GUIDE for use SPI protocol driver as example for studying ************* 2 | - This driver is SPI protocol driver and used controll LCD Nokia 5110. 3 | - It can be create multiple device file by just one driver file. 4 | - It can do it because it use Link list to parse device tree SPI node to get child-node and initialize device infomation (SPI slave). 5 | ------------------------------------------------------------------------------------------------------------------------------------- 6 | Do following step to use this source code: 7 | 8 | 1. Modify spi1 node in device tree file : linux/arch/arm/boot/dts/am33xx.dtsi 9 | 10 | spi1: spi@481a0000 { 11 | compatible = "ti,omap4-mcspi"; 12 | #address-cells = <1>; 13 | #size-cells = <0>; 14 | reg = <0x481a0000 0x400>; 15 | interrupts = <125>; 16 | ti,spi-num-cs = <2>; 17 | ti,hwmods = "spi1"; 18 | cs-gpios = <&gpio3 17 1>, <&gpio0 7 1>; 19 | dmas = <&edma 42 0 20 | &edma 43 0 21 | &edma 44 0 22 | &edma 45 0>; 23 | dma-names = "tx0", "rx0", "tx1", "rx1"; 24 | status = "disabled"; 25 | 26 | lcd0:lcd0@0 { 27 | reg = <0>; 28 | spi-max-frequency = <10000000>; 29 | compatible = "dungnt98,spi1"; 30 | }; 31 | 32 | lcd1:lcd1@1 { 33 | reg = <1>; 34 | spi-max-frequency = <10000000>; 35 | compatible = "dungnt98,spi2"; 36 | }; 37 | }; 38 | 39 | 2. Re-build kernel and coppy file linux/arch/arm/boot/dts/am335x-boneblack.dtb to BOOT partition of sd-card. 40 | 3. Modify path of kernel and toolchain in Makefile file then run following command to build driver: 41 | make clean all 42 | 4. Coppy file lcd_driver.ko to sd-card. 43 | 44 | 5. ******* Build test tool ******* 45 | - In same folder have two sub-folder is lcd_lib and lcd_lib1 which are two program to above driver. 46 | - To use them, we just need modify Makefile in each folder with proper path of source linux and toolchain corresponding to out environment build system. 47 | then call command: 48 | make clean all 49 | to build excutable file test. Then coppy these test file to sd-card. 50 | 51 | 6. Insert sd-card and Power up board and run following command to test driver: 52 | insmode lcd_driver.ko 53 | ./lcd_test - to test spi with slave-0 54 | ./lcd_test1 - to test spi with slave-1 55 | 56 | /******** connection between board and 2 lcd ********/ 57 | ---------------------------------------------------------------------------------------------------------- 58 | | LCD_1 | BBB | LCD_2 | 59 | ---------------------------------------------------------------------------------------------------------- 60 | CLK <--------------------> P9_31 - SPI1_SCLK <--------------------> CLK 61 | DIN <--------------------> P9_20 - GPIO_112 / SPI1_D1 <--------------------> DIN 62 | RESET <--------------------> P9_27 - GPIO_115 <--------------------> RESET 63 | CMD <--------------------> P9_25 - GPIO_117 <--------------------> CMD 64 | EN <--------------------> P9_28 - SPI1_CS0 65 | P9_42 - SPI1_CS1 <--------------------> EN 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /Bai 14/SPI-protocol/SPI_Multiple_Slave/lcd1/Makefile: -------------------------------------------------------------------------------- 1 | PWD := $(shell pwd) 2 | 3 | obj-m += lcd_driver.o 4 | lcd_driver-objs := lcd.o lcd_ctrl.o 5 | 6 | CROSS := /home/dungnt98/toolchain/arm-linux-gnueabihf/bin/arm-linux-gnueabihf- 7 | KERNEL := /home/dungnt98/linux/ 8 | 9 | all: 10 | make ARCH=arm CROSS_COMPILE=$(CROSS) -C $(KERNEL) SUBDIRS=$(PWD) modules 11 | clean: 12 | make -C $(KERNEL) SUBDIRS=$(PWD) clean 13 | -------------------------------------------------------------------------------- /Bai 14/SPI-protocol/SPI_Multiple_Slave/lcd1/lcd.h: -------------------------------------------------------------------------------- 1 | #ifndef __LCD_5110 2 | #define __LCD_5110 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | 10 | #define LCD_WIDTH 84 11 | #define LCD_HEIGHT 48 12 | 13 | #define LCD_POWERDOWN 0x04 14 | #define LCD_ENTRYMODE 0x02 15 | #define LCD_EXTENDEDINSTRUCTION 0x01 16 | #define LCD_DISPLAYBLANK 0x00 17 | #define LCD_DISPLAYNORMAL 0x04 18 | #define LCD_DISPLAYALLON 0x01 19 | #define LCD_DISPLAYINVERTED 0x05 20 | 21 | #define LCD_FUNCTIONSET 0x20 22 | #define LCD_DISPLAYCONTROL 0x08 23 | #define LCD_SETYADDR 0x40 24 | #define LCD_SETXADDR 0x80 25 | #define LCD_SETTEMP 0x04 26 | #define LCD_SETBIAS 0x10 27 | #define LCD_SETVOP 0x80 28 | 29 | #define LCD_BIAS 0x03 30 | #define LCD_TEMP 0x02 31 | #define LCD_CONTRAST 0x46 32 | 33 | #define LCD_CHAR5x7_WIDTH 6 34 | #define LCD_CHAR5x7_HEIGHT 8 35 | #define LCD_CHAR3x5_WIDTH 4 36 | #define LCD_CHAR3x5_HEIGHT 6 37 | 38 | #define LCD_BUFFER_SIZE (LCD_WIDTH * LCD_HEIGHT / 8) 39 | 40 | 41 | struct nokia_5110 { 42 | struct spi_device *spi; 43 | dev_t dev_number; 44 | struct cdev c_dev; 45 | struct device *device_p; 46 | struct list_head device_entry; 47 | int lcd_dc; 48 | int lcd_rs; 49 | }; 50 | 51 | typedef unsigned char unit8_t; 52 | 53 | typedef enum { 54 | PIN_LOW = 0, 55 | PIN_HIGH = !PIN_LOW 56 | } Pin_State_t; 57 | 58 | typedef enum { 59 | LCD_COMMAND = 0, 60 | LCD_DATA = !LCD_COMMAND 61 | } LCD_WriteType_t; 62 | 63 | typedef enum { 64 | LCD_State_Low = 0, 65 | LCD_State_High = !LCD_State_Low 66 | } LCD_State_t; 67 | 68 | typedef enum { 69 | LCD_Pin_DC = 1, 70 | LCD_Pin_RST = 2 71 | } LCD_Pin_t; 72 | 73 | typedef enum { 74 | LCD_Pixel_Clear = 0, 75 | LCD_Pixel_Set = !LCD_Pixel_Clear 76 | } LCD_Pixel_t; 77 | 78 | typedef enum { 79 | LCD_FontSize_5x7 = 0, 80 | LCD_FontSize_3x5 = !LCD_FontSize_5x7 81 | } LCD_FontSize_t; 82 | 83 | typedef enum { 84 | LCD_Invert_Yes, 85 | LCD_Invert_No 86 | } LCD_Invert_t; 87 | 88 | void gpio_set_pin(int gpio, Pin_State_t state); 89 | int LCD_init_IO(struct nokia_5110 *lcd); 90 | void LCD_free_IO(struct nokia_5110 *lcd); 91 | void LCD_Init(struct nokia_5110 *lcd, unsigned char contrast); 92 | 93 | void LCD_Pin(struct nokia_5110 *lcd, LCD_Pin_t pin, LCD_State_t state); 94 | void LCD_send(struct spi_device *spidev, unsigned char data); 95 | void LCD_Write(struct nokia_5110 *lcd, LCD_WriteType_t type, unsigned char data); 96 | void LCD_Home(struct nokia_5110 *lcd); 97 | void LCD_SetContrast(struct nokia_5110 *lcd, unsigned char contrast); 98 | void LCD_GotoXY(struct nokia_5110 *lcd, unsigned char x, unsigned char y); 99 | 100 | void LCD_UpdateArea(unsigned char xMin, unsigned char yMin, unsigned char xMax, 101 | unsigned char yMax); 102 | void LCD_Refresh(struct nokia_5110 *lcd); 103 | void LCD_Clear(struct nokia_5110 *lcd); 104 | 105 | void LCD_DrawPixel(unsigned char x, unsigned char y, LCD_Pixel_t pixel); 106 | void LCD_Invert(struct nokia_5110 *lcd, LCD_Invert_t invert); 107 | void LCD_Putc(char c, LCD_Pixel_t color, LCD_FontSize_t size); 108 | void LCD_Puts(char *s, LCD_Pixel_t color, LCD_FontSize_t size); 109 | 110 | void LCD_DrawLine(unsigned char x0, unsigned char y0, unsigned char x1, 111 | unsigned char y1, LCD_Pixel_t color); 112 | void LCD_DrawRectangle(unsigned char x0, unsigned char y0, unsigned char x1, 113 | unsigned char y1, LCD_Pixel_t color); 114 | void LCD_DrawFilledRectangle(unsigned char x0, unsigned char y0, unsigned char x1, 115 | unsigned char y1, LCD_Pixel_t color); 116 | void LCD_DrawCircle(char x0, char y0, char r, LCD_Pixel_t color); 117 | void LCD_DrawFilledCircle(char x0, char y0, char r, LCD_Pixel_t color); 118 | 119 | 120 | #endif 121 | 122 | -------------------------------------------------------------------------------- /Bai 14/SPI-protocol/SPI_Multiple_Slave/lcd1/lcd_ioctl.h: -------------------------------------------------------------------------------- 1 | #ifndef __LCD_IOCTL 2 | #define __LCD_IOCTL 3 | 4 | #define MAJIC_NO 100 5 | #define IOCTL_CLEAR _IO(MAJIC_NO, 0) 6 | #define IOCTL_HOME _IO(MAJIC_NO, 1) 7 | #define IOCTL_SET_CONTRAST _IOW(MAJIC_NO, 2, unsigned char) 8 | 9 | typedef struct position { 10 | unsigned char x; 11 | unsigned char y; 12 | } Position_t; 13 | #define IOCTL_GOTOXY _IOW(MAJIC_NO, 3, Position_t) 14 | 15 | typedef enum { 16 | Pixel_Clear = 0, 17 | Pixel_Set = !Pixel_Clear 18 | } Pixel_t; 19 | 20 | typedef struct draw_pixel { 21 | unsigned char x; 22 | unsigned char y; 23 | Pixel_t pixel; 24 | } Draw_Pixel_t; 25 | #define IOCTL_DRAW_PIXEL _IOW(MAJIC_NO, 4, Draw_Pixel_t) 26 | 27 | typedef struct draw_shape { 28 | unsigned char x0; 29 | unsigned char y0; 30 | unsigned char x1; 31 | unsigned char y1; 32 | Pixel_t pixel; 33 | } Draw_Shape_t; 34 | #define IOCTL_DRAW_LINE _IOW(MAJIC_NO, 5, Draw_Shape_t) 35 | #define IOCTL_DRAW_RECT _IOW(MAJIC_NO, 6, Draw_Shape_t) 36 | #define IOCTL_DRAW_FILL_RECT _IOW(MAJIC_NO, 7, Draw_Shape_t) 37 | 38 | typedef struct draw_circle { 39 | char x; 40 | char y; 41 | char r; 42 | Pixel_t pixel; 43 | } Draw_Circle_t; 44 | #define IOCTL_DRAW_CIRCLE _IOW(MAJIC_NO, 8, Draw_Circle_t) 45 | #define IOCTL_DRAW_FILL_CIRCLE _IOW(MAJIC_NO, 9, Draw_Circle_t) 46 | 47 | #define IOCTL_SEND_BUFF _IO(MAJIC_NO, 10) 48 | 49 | typedef enum { 50 | FontSize_5x7 = 0, 51 | FontSize_3x5 = !FontSize_5x7 52 | } FontSize_t; 53 | 54 | typedef struct draw_string { 55 | char message[25]; 56 | Pixel_t pixel; 57 | FontSize_t font; 58 | } Draw_String_t; 59 | 60 | #endif 61 | 62 | -------------------------------------------------------------------------------- /Bai 14/SPI-protocol/SPI_Multiple_Slave/lcd_lib/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY : clean 2 | 3 | SOURCES = $(shell echo *.c) 4 | HEADERS = $(shell echo *.h) 5 | OBJECTS = $(SOURCES:.c=.o) 6 | 7 | TARGET = lcd_test 8 | 9 | CC := /home/dungnt98/toolchain/arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc 10 | 11 | 12 | all: $(OBJECTS) 13 | $(CC) -o $(TARGET) $(OBJECTS) 14 | $(OBJECTS): 15 | $(CC) -c $(SOURCES) 16 | 17 | clean: 18 | rm -f $(OBJECTS) $(TARGET) 19 | -------------------------------------------------------------------------------- /Bai 14/SPI-protocol/SPI_Multiple_Slave/lcd_lib/lcd_lib.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "lcd_lib.h" 7 | 8 | 9 | extern int open_file() 10 | { 11 | int fd; 12 | 13 | fd = open(FILENAME, O_RDWR); 14 | if (fd < 0) { 15 | perror("open: Failed\n"); 16 | return fd; 17 | } 18 | 19 | return fd; 20 | } 21 | 22 | extern void draw_string(char *name, Pixel_t color, FontSize_t font) 23 | { 24 | Draw_String_t str; 25 | int fd = open_file(); 26 | 27 | strcpy(str.message, name); 28 | str.pixel = color; 29 | str.font = font; 30 | if (write(fd, &str, sizeof(str)) < 0) { 31 | perror("write: Failed\n"); 32 | return; 33 | } 34 | 35 | close(fd); 36 | } 37 | 38 | extern void lcd_send_buff() 39 | { 40 | int fd = open_file(); 41 | 42 | if (ioctl(fd, IOCTL_SEND_BUFF) < 0) { 43 | printf("ioctl: Failed at %s\n", __func__); 44 | return; 45 | } 46 | 47 | close(fd); 48 | } 49 | 50 | extern void lcd_clear_screen() 51 | { 52 | int fd = open_file(); 53 | 54 | if (ioctl(fd, IOCTL_CLEAR) < 0) { 55 | printf("ioctl: Failed at %s\n", __func__); 56 | return; 57 | } 58 | 59 | close(fd); 60 | } 61 | 62 | extern void lcd_home() 63 | { 64 | int fd = open_file(); 65 | 66 | if (ioctl(fd, IOCTL_HOME) < 0) { 67 | printf("ioctl: Failed at %s\n", __func__); 68 | return; 69 | } 70 | 71 | close(fd); 72 | } 73 | 74 | extern void lcd_set_contrast(unsigned char contrast) 75 | { 76 | unsigned char ct = contrast; 77 | int fd = open_file(); 78 | 79 | if (ioctl(fd, IOCTL_SET_CONTRAST, &ct) < 0) { 80 | printf("ioctl: Failed at %s\n", __func__); 81 | return; 82 | } 83 | 84 | close(fd); 85 | } 86 | 87 | extern void lcd_gotoxy(unsigned char x, unsigned char y) 88 | { 89 | Position_t pos; 90 | int fd = open_file(); 91 | 92 | pos.x = x; 93 | pos.y = y; 94 | 95 | if (ioctl(fd, IOCTL_GOTOXY, &pos) < 0) { 96 | printf("ioctl: Failed at %s\n", __func__); 97 | return; 98 | } 99 | 100 | close(fd); 101 | } 102 | 103 | extern void lcd_draw_pixel(unsigned char x, unsigned char y, Pixel_t pixel) 104 | { 105 | Draw_Pixel_t pixel_pos; 106 | int fd = open_file(); 107 | 108 | pixel_pos.x = x; 109 | pixel_pos.y = y; 110 | pixel_pos.pixel = pixel; 111 | 112 | if (ioctl(fd, IOCTL_DRAW_PIXEL, &pixel_pos) < 0) { 113 | printf("ioctl: Failed at %s\n", __func__); 114 | return; 115 | } 116 | 117 | close(fd); 118 | } 119 | 120 | extern void lcd_draw_line(unsigned char x0, unsigned char y0, 121 | unsigned char x1, unsigned char y1, Pixel_t pixel) 122 | { 123 | Draw_Shape_t shape; 124 | int fd = open_file(); 125 | 126 | shape.x0 = x0; 127 | shape.y0 = y0; 128 | shape.x1 = x1; 129 | shape.y1 = y1; 130 | shape.pixel = pixel; 131 | 132 | if (ioctl(fd, IOCTL_DRAW_LINE, &shape) < 0) { 133 | printf("ioctl: Failed at %s\n", __func__); 134 | return; 135 | } 136 | 137 | close(fd); 138 | } 139 | 140 | extern void lcd_draw_rect(unsigned char x0, unsigned char y0, 141 | unsigned char x1, unsigned char y1, Pixel_t pixel) 142 | { 143 | Draw_Shape_t shape; 144 | int fd = open_file(); 145 | 146 | shape.x0 = x0; 147 | shape.y0 = y0; 148 | shape.x1 = x1; 149 | shape.y1 = y1; 150 | shape.pixel = pixel; 151 | 152 | if (ioctl(fd, IOCTL_DRAW_RECT, &shape) < 0) { 153 | printf("ioctl: Failed at %s\n", __func__); 154 | return; 155 | } 156 | 157 | close(fd); 158 | } 159 | 160 | extern void lcd_draw_fill_rect(unsigned char x0, unsigned char y0, 161 | unsigned char x1, unsigned char y1, Pixel_t pixel) 162 | { 163 | Draw_Shape_t shape; 164 | int fd = open_file(); 165 | 166 | shape.x0 = x0; 167 | shape.y0 = y0; 168 | shape.x1 = x1; 169 | shape.y1 = y1; 170 | shape.pixel = pixel; 171 | 172 | if (ioctl(fd, IOCTL_DRAW_FILL_RECT, &shape) < 0) { 173 | printf("ioctl: Failed at %s\n", __func__); 174 | return; 175 | } 176 | 177 | close(fd); 178 | } 179 | 180 | extern void lcd_draw_circle(char x, char y, char r, Pixel_t pixel) 181 | { 182 | Draw_Circle_t circle; 183 | int fd = open_file(); 184 | 185 | circle.x = x; 186 | circle.y = y; 187 | circle.r = r; 188 | circle.pixel = pixel; 189 | 190 | if (ioctl(fd, IOCTL_DRAW_CIRCLE, &circle) < 0) { 191 | printf("ioctl: Failed at %s\n", __func__); 192 | return; 193 | } 194 | 195 | close(fd); 196 | } 197 | 198 | extern void lcd_draw_fill_circle(char x, char y, char r, Pixel_t pixel) 199 | { 200 | Draw_Circle_t circle; 201 | int fd = open_file(); 202 | 203 | circle.x = x; 204 | circle.y = y; 205 | circle.r = r; 206 | circle.pixel = pixel; 207 | 208 | if (ioctl(fd, IOCTL_DRAW_FILL_CIRCLE, &circle) < 0) { 209 | printf("ioctl: Failed at %s\n", __func__); 210 | return; 211 | } 212 | 213 | close(fd); 214 | } 215 | 216 | -------------------------------------------------------------------------------- /Bai 14/SPI-protocol/SPI_Multiple_Slave/lcd_lib/lcd_lib.h: -------------------------------------------------------------------------------- 1 | #ifndef __LCD_LIB 2 | #define __LCD_LIB 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "../lcd1/lcd_ioctl.h" 10 | 11 | 12 | #define FILENAME "/dev/lcd_0" 13 | 14 | extern void draw_string(char *str, Pixel_t color, FontSize_t font); 15 | extern int open_file(); 16 | extern void lcd_send_buff(); 17 | extern void lcd_clear_screen(); 18 | extern void lcd_home(); 19 | extern void lcd_set_contrast(unsigned char contrast); 20 | extern void lcd_gotoxy(unsigned char x, unsigned char y); 21 | extern void lcd_draw_pixel(unsigned char x, unsigned char y, Pixel_t pixel); 22 | extern void lcd_draw_line(unsigned char x0, unsigned char y0, 23 | unsigned char x1, unsigned char y1, Pixel_t pixel); 24 | extern void lcd_draw_rect(unsigned char x0, unsigned char y0, 25 | unsigned char x1, unsigned char y1, Pixel_t pixel); 26 | extern void lcd_draw_fill_rect(unsigned char x0, unsigned char y0, 27 | unsigned char x1, unsigned char y1, Pixel_t pixel); 28 | extern void lcd_draw_circle(char x, char y, char r, Pixel_t pixel); 29 | extern void lcd_draw_fill_circle(char x, char y, char r, Pixel_t pixel); 30 | 31 | #endif 32 | 33 | 34 | -------------------------------------------------------------------------------- /Bai 14/SPI-protocol/SPI_Multiple_Slave/lcd_lib/lcd_test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "lcd_lib.h" 6 | 7 | int main() 8 | { 9 | char c; 10 | 11 | while(1) { 12 | 13 | 14 | printf("0: Exit\n"); 15 | printf("1: Trong Dung\n"); 16 | printf("2: Dungnt98 Linux\n"); 17 | printf("3; Linux Embedded\n"); 18 | 19 | scanf("%d", &c); 20 | 21 | switch(c) { 22 | case 0: 23 | return 0; 24 | case 1: 25 | lcd_gotoxy(0, 0); 26 | draw_string("Trong Dung", Pixel_Set, FontSize_5x7); 27 | break; 28 | case 2: 29 | lcd_gotoxy(15, 10); 30 | draw_string("Dungnt98 Linux", Pixel_Set, FontSize_5x7); 31 | break; 32 | case 3: 33 | lcd_gotoxy(20, 24); 34 | draw_string("Linux Embedded", Pixel_Set, FontSize_5x7); 35 | break; 36 | default: 37 | lcd_gotoxy(0, 0); 38 | lcd_clear_screen(); 39 | draw_string("Default !", Pixel_Set, FontSize_5x7); 40 | break; 41 | } 42 | lcd_send_buff(); 43 | 44 | do { 45 | c = getchar(); 46 | }while(c != '\n' && c != EOF); 47 | 48 | } 49 | return 0; 50 | } 51 | 52 | -------------------------------------------------------------------------------- /Bai 14/SPI-protocol/SPI_Multiple_Slave/lcd_lib1/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY : clean 2 | 3 | SOURCES = $(shell echo *.c) 4 | HEADERS = $(shell echo *.h) 5 | OBJECTS = $(SOURCES:.c=.o) 6 | 7 | TARGET = lcd_test1 8 | 9 | CC := /home/dungnt98/toolchain/arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc 10 | 11 | 12 | all: $(OBJECTS) 13 | $(CC) -o $(TARGET) $(OBJECTS) 14 | $(OBJECTS): 15 | $(CC) -c $(SOURCES) 16 | 17 | clean: 18 | rm -f $(OBJECTS) $(TARGET) 19 | -------------------------------------------------------------------------------- /Bai 14/SPI-protocol/SPI_Multiple_Slave/lcd_lib1/lcd_lib.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "lcd_lib.h" 7 | 8 | 9 | extern int open_file() 10 | { 11 | int fd; 12 | 13 | fd = open(FILENAME, O_RDWR); 14 | if (fd < 0) { 15 | perror("open: Failed\n"); 16 | return fd; 17 | } 18 | 19 | return fd; 20 | } 21 | 22 | extern void draw_string(char *name, Pixel_t color, FontSize_t font) 23 | { 24 | Draw_String_t str; 25 | int fd = open_file(); 26 | 27 | strcpy(str.message, name); 28 | str.pixel = color; 29 | str.font = font; 30 | if (write(fd, &str, sizeof(str)) < 0) { 31 | perror("write: Failed\n"); 32 | return; 33 | } 34 | 35 | close(fd); 36 | } 37 | 38 | extern void lcd_send_buff() 39 | { 40 | int fd = open_file(); 41 | 42 | if (ioctl(fd, IOCTL_SEND_BUFF) < 0) { 43 | printf("ioctl: Failed at %s\n", __func__); 44 | return; 45 | } 46 | 47 | close(fd); 48 | } 49 | 50 | extern void lcd_clear_screen() 51 | { 52 | int fd = open_file(); 53 | 54 | if (ioctl(fd, IOCTL_CLEAR) < 0) { 55 | printf("ioctl: Failed at %s\n", __func__); 56 | return; 57 | } 58 | 59 | close(fd); 60 | } 61 | 62 | extern void lcd_home() 63 | { 64 | int fd = open_file(); 65 | 66 | if (ioctl(fd, IOCTL_HOME) < 0) { 67 | printf("ioctl: Failed at %s\n", __func__); 68 | return; 69 | } 70 | 71 | close(fd); 72 | } 73 | 74 | extern void lcd_set_contrast(unsigned char contrast) 75 | { 76 | unsigned char ct = contrast; 77 | int fd = open_file(); 78 | 79 | if (ioctl(fd, IOCTL_SET_CONTRAST, &ct) < 0) { 80 | printf("ioctl: Failed at %s\n", __func__); 81 | return; 82 | } 83 | 84 | close(fd); 85 | } 86 | 87 | extern void lcd_gotoxy(unsigned char x, unsigned char y) 88 | { 89 | Position_t pos; 90 | int fd = open_file(); 91 | 92 | pos.x = x; 93 | pos.y = y; 94 | 95 | if (ioctl(fd, IOCTL_GOTOXY, &pos) < 0) { 96 | printf("ioctl: Failed at %s\n", __func__); 97 | return; 98 | } 99 | 100 | close(fd); 101 | } 102 | 103 | extern void lcd_draw_pixel(unsigned char x, unsigned char y, Pixel_t pixel) 104 | { 105 | Draw_Pixel_t pixel_pos; 106 | int fd = open_file(); 107 | 108 | pixel_pos.x = x; 109 | pixel_pos.y = y; 110 | pixel_pos.pixel = pixel; 111 | 112 | if (ioctl(fd, IOCTL_DRAW_PIXEL, &pixel_pos) < 0) { 113 | printf("ioctl: Failed at %s\n", __func__); 114 | return; 115 | } 116 | 117 | close(fd); 118 | } 119 | 120 | extern void lcd_draw_line(unsigned char x0, unsigned char y0, 121 | unsigned char x1, unsigned char y1, Pixel_t pixel) 122 | { 123 | Draw_Shape_t shape; 124 | int fd = open_file(); 125 | 126 | shape.x0 = x0; 127 | shape.y0 = y0; 128 | shape.x1 = x1; 129 | shape.y1 = y1; 130 | shape.pixel = pixel; 131 | 132 | if (ioctl(fd, IOCTL_DRAW_LINE, &shape) < 0) { 133 | printf("ioctl: Failed at %s\n", __func__); 134 | return; 135 | } 136 | 137 | close(fd); 138 | } 139 | 140 | extern void lcd_draw_rect(unsigned char x0, unsigned char y0, 141 | unsigned char x1, unsigned char y1, Pixel_t pixel) 142 | { 143 | Draw_Shape_t shape; 144 | int fd = open_file(); 145 | 146 | shape.x0 = x0; 147 | shape.y0 = y0; 148 | shape.x1 = x1; 149 | shape.y1 = y1; 150 | shape.pixel = pixel; 151 | 152 | if (ioctl(fd, IOCTL_DRAW_RECT, &shape) < 0) { 153 | printf("ioctl: Failed at %s\n", __func__); 154 | return; 155 | } 156 | 157 | close(fd); 158 | } 159 | 160 | extern void lcd_draw_fill_rect(unsigned char x0, unsigned char y0, 161 | unsigned char x1, unsigned char y1, Pixel_t pixel) 162 | { 163 | Draw_Shape_t shape; 164 | int fd = open_file(); 165 | 166 | shape.x0 = x0; 167 | shape.y0 = y0; 168 | shape.x1 = x1; 169 | shape.y1 = y1; 170 | shape.pixel = pixel; 171 | 172 | if (ioctl(fd, IOCTL_DRAW_FILL_RECT, &shape) < 0) { 173 | printf("ioctl: Failed at %s\n", __func__); 174 | return; 175 | } 176 | 177 | close(fd); 178 | } 179 | 180 | extern void lcd_draw_circle(char x, char y, char r, Pixel_t pixel) 181 | { 182 | Draw_Circle_t circle; 183 | int fd = open_file(); 184 | 185 | circle.x = x; 186 | circle.y = y; 187 | circle.r = r; 188 | circle.pixel = pixel; 189 | 190 | if (ioctl(fd, IOCTL_DRAW_CIRCLE, &circle) < 0) { 191 | printf("ioctl: Failed at %s\n", __func__); 192 | return; 193 | } 194 | 195 | close(fd); 196 | } 197 | 198 | extern void lcd_draw_fill_circle(char x, char y, char r, Pixel_t pixel) 199 | { 200 | Draw_Circle_t circle; 201 | int fd = open_file(); 202 | 203 | circle.x = x; 204 | circle.y = y; 205 | circle.r = r; 206 | circle.pixel = pixel; 207 | 208 | if (ioctl(fd, IOCTL_DRAW_FILL_CIRCLE, &circle) < 0) { 209 | printf("ioctl: Failed at %s\n", __func__); 210 | return; 211 | } 212 | 213 | close(fd); 214 | } 215 | 216 | -------------------------------------------------------------------------------- /Bai 14/SPI-protocol/SPI_Multiple_Slave/lcd_lib1/lcd_lib.h: -------------------------------------------------------------------------------- 1 | #ifndef __LCD_LIB 2 | #define __LCD_LIB 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "../lcd1/lcd_ioctl.h" 10 | 11 | 12 | #define FILENAME "/dev/lcd_1" 13 | 14 | extern void draw_string(char *str, Pixel_t color, FontSize_t font); 15 | extern int open_file(); 16 | extern void lcd_send_buff(); 17 | extern void lcd_clear_screen(); 18 | extern void lcd_home(); 19 | extern void lcd_set_contrast(unsigned char contrast); 20 | extern void lcd_gotoxy(unsigned char x, unsigned char y); 21 | extern void lcd_draw_pixel(unsigned char x, unsigned char y, Pixel_t pixel); 22 | extern void lcd_draw_line(unsigned char x0, unsigned char y0, 23 | unsigned char x1, unsigned char y1, Pixel_t pixel); 24 | extern void lcd_draw_rect(unsigned char x0, unsigned char y0, 25 | unsigned char x1, unsigned char y1, Pixel_t pixel); 26 | extern void lcd_draw_fill_rect(unsigned char x0, unsigned char y0, 27 | unsigned char x1, unsigned char y1, Pixel_t pixel); 28 | extern void lcd_draw_circle(char x, char y, char r, Pixel_t pixel); 29 | extern void lcd_draw_fill_circle(char x, char y, char r, Pixel_t pixel); 30 | 31 | #endif 32 | 33 | 34 | -------------------------------------------------------------------------------- /Bai 14/SPI-protocol/SPI_Multiple_Slave/lcd_lib1/lcd_lib.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 14/SPI-protocol/SPI_Multiple_Slave/lcd_lib1/lcd_lib.o -------------------------------------------------------------------------------- /Bai 14/SPI-protocol/SPI_Multiple_Slave/lcd_lib1/lcd_test1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 14/SPI-protocol/SPI_Multiple_Slave/lcd_lib1/lcd_test1 -------------------------------------------------------------------------------- /Bai 14/SPI-protocol/SPI_Multiple_Slave/lcd_lib1/lcd_test1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "lcd_lib.h" 6 | 7 | int main() 8 | { 9 | int c; 10 | 11 | while(1) { 12 | printf("0: Exit\n"); 13 | printf("1: Trong Dung\n"); 14 | printf("2: Dungnt98 Linux\n"); 15 | printf("3; Linux Embedded\n"); 16 | 17 | scanf("%d", &c); 18 | 19 | switch(c) { 20 | case 0: 21 | return 0; 22 | case 1: 23 | lcd_gotoxy(0, 0); 24 | draw_string("Trong Dung", Pixel_Set, FontSize_5x7); 25 | break; 26 | case 2: 27 | lcd_gotoxy(15, 10); 28 | draw_string("Dungnt98 Linux", Pixel_Set, FontSize_5x7); 29 | break; 30 | case 3: 31 | lcd_gotoxy(20, 24); 32 | draw_string("Linux Embedded", Pixel_Set, FontSize_5x7); 33 | break; 34 | default: 35 | lcd_gotoxy(0, 0); 36 | lcd_clear_screen(); 37 | draw_string("Default !", Pixel_Set, FontSize_5x7); 38 | break; 39 | } 40 | lcd_send_buff(); 41 | 42 | do { 43 | c = getchar(); 44 | }while(c != '\n' && c != EOF); 45 | } 46 | 47 | return 0; 48 | } 49 | 50 | -------------------------------------------------------------------------------- /Bai 14/SPI-protocol/SPI_Multiple_Slave/lcd_lib1/lcd_test1.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 14/SPI-protocol/SPI_Multiple_Slave/lcd_lib1/lcd_test1.o -------------------------------------------------------------------------------- /Bai 14/SPI-protocol/template_spi.c: -------------------------------------------------------------------------------- 1 | /* spi_protocol_example.c 2 | * This is template for SPI_PROTOCOL_DRIVER 3 | */ 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | static int my_probe(struct spi_device *spi) 15 | { 16 | spi_setup(spi); 17 | pr_emerg("Dungnt98 %s, %d", __func__, __LINE__); 18 | return 0; 19 | } 20 | 21 | static int my_remove(struct spi_device *spi) 22 | { 23 | pr_emerg("Dungnt98 %s, %d", __func__, __LINE__); 24 | return 0; 25 | } 26 | 27 | struct of_device_id dungnt98_of_match[] = { 28 | { 29 | .compatible = "dungnt98-compatible", 30 | }, 31 | {} 32 | }; 33 | 34 | MODULE_DEVICE_TABLE(of, dungnt98_of_match); 35 | 36 | static struct spi_driver my_spi_driver = { 37 | .probe = my_probe, 38 | .remove = my_remove, 39 | .driver = { 40 | .name = "my_spi", /* /sys/bus/spi/drivers/.... */ 41 | .owner = THIS_MODULE, 42 | .of_match_table = dungnt98_of_match, /* Matching device tree node */ 43 | }, 44 | }; 45 | 46 | static int __init dungnt_init(void) 47 | { 48 | return spi_register_driver(&my_spi_driver); 49 | } 50 | static void __exit dungnt_exit(void) 51 | { 52 | return spi_unregister_driver(&my_spi_driver); 53 | } 54 | 55 | module_init(dungnt_init); 56 | module_exit(dungnt_exit); 57 | 58 | 59 | MODULE_AUTHOR("Trong Dung"); 60 | MODULE_LICENSE("GPL"); 61 | 62 | -------------------------------------------------------------------------------- /Bai 14/SPI_controller_driver.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 14/SPI_controller_driver.pptx -------------------------------------------------------------------------------- /Bai 14/SPI_operation_sequence.eap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 14/SPI_operation_sequence.eap -------------------------------------------------------------------------------- /Bai 14/SPI_protocol_driver.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 14/SPI_protocol_driver.pptx -------------------------------------------------------------------------------- /Bai 14/picture.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 14/picture.xlsx -------------------------------------------------------------------------------- /Bai 15/Linux-storage-stack-diagram_v3.17.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 15/Linux-storage-stack-diagram_v3.17.pdf -------------------------------------------------------------------------------- /Bai 15/Virtual File System.mm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /Bai 15/Virtual file system.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 15/Virtual file system.pptx -------------------------------------------------------------------------------- /Bai 15/phula-TheLinuxVirtualFilesystemImplementation-150917-1211-158.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 15/phula-TheLinuxVirtualFilesystemImplementation-150917-1211-158.pdf -------------------------------------------------------------------------------- /Bai 15/vfs.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 15/vfs.pdf -------------------------------------------------------------------------------- /Bai 16/Pictures.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 16/Pictures.xlsx -------------------------------------------------------------------------------- /Bai 16/Watchdog_driver.mm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /Bai 16/Watchdog_driver.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 16/Watchdog_driver.pptx -------------------------------------------------------------------------------- /Bai 16/source_code/Beaglebone black/Makefile: -------------------------------------------------------------------------------- 1 | obj-m += my_watchdog.o 2 | 3 | src-file := my_watchdog.c 4 | test-file:= main.c 5 | 6 | PWD := $(shell pwd) 7 | GCC := /usr/bin/arm-linux-gnueabihf- 8 | KERNEL := /home/trongdung/linux/ 9 | 10 | all: 11 | make ARCH=arm CROSS_COMPILE=$(GCC) -C $(KERNEL) SUBDIRS=$(PWD) modules 12 | $(GCC)gcc main.c -o main 13 | clean: 14 | make -C $(KERNEL) SUBDIRS=$(PWD) clean 15 | rm main 16 | check: 17 | ./checkpatch.pl --no-tree --ignore CONST_STRUCT --show-types -f $(src-file) 18 | -------------------------------------------------------------------------------- /Bai 16/source_code/Beaglebone black/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | int main(void) 11 | { 12 | int fd = 0; 13 | int c = '\0'; 14 | int timeout = 0; 15 | 16 | fd = open("/dev/watchdog1",O_RDWR); 17 | if (fd < 0) { 18 | perror("can not open this file, permission...\n"); 19 | return -1; 20 | } 21 | 22 | while(1) { 23 | printf("\nChoose: 1. write driver\n"); 24 | printf("Choose: 2. set timeout driver\n"); 25 | printf("Choose: 3. out\n"); 26 | 27 | scanf("%d", &c); 28 | fflush(stdin); 29 | 30 | switch(c) { 31 | case 1: 32 | write(fd,"1",1); 33 | break; 34 | case 2: 35 | puts("nhap timeout"); 36 | 37 | scanf("%d", &timeout); 38 | fflush(stdin); 39 | 40 | ioctl(fd, WDIOC_SETTIMEOUT, &timeout); 41 | ioctl(fd, WDIOC_GETTIMEOUT, &timeout); 42 | break; 43 | case 3: 44 | close(fd); 45 | exit(0); 46 | break; 47 | default: 48 | printf("nhap lai"); 49 | break; 50 | } 51 | } 52 | 53 | return 0; 54 | } 55 | -------------------------------------------------------------------------------- /Bai 16/source_code/Treerunner/watchdog.conf: -------------------------------------------------------------------------------- 1 | #ping = 172.31.14.1 2 | #ping = 172.26.1.255 3 | #interface = eth0 4 | #file = /var/log/messages 5 | #change = 1407 6 | 7 | # Uncomment to enable test. Setting one of these values to '0' disables it. 8 | # These values will hopefully never reboot your machine during normal use 9 | # (if your machine is really hung, the loadavg will go much higher than 25) 10 | #max-load-1 = 24 11 | #max-load-5 = 18 12 | #max-load-15 = 12 13 | 14 | # Note that this is the number of pages! 15 | # To get the real size, check how large the pagesize is on your machine. 16 | #min-memory = 1 17 | #allocatable-memory = 1 18 | 19 | #repair-binary = /usr/sbin/repair 20 | #repair-timeout = 21 | #test-binary = 22 | #test-timeout = 23 | 24 | #watchdog-device = /dev/watchdog 25 | 26 | # Defaults compiled into the binary 27 | #temperature-device = 28 | #max-temperature = 120 29 | 30 | # Defaults compiled into the binary 31 | #admin = root 32 | #interval = 1 33 | #logtick = 1 34 | #log-dir = /var/log/watchdog 35 | 36 | # This greatly decreases the chance that watchdog won't be scheduled before 37 | # your machine is really loaded 38 | realtime = yes 39 | priority = 1 40 | 41 | # Check if rsyslogd is still running by enabling the following line 42 | #pidfile = /var/run/rsyslogd.pid 43 | 44 | -------------------------------------------------------------------------------- /Bai 17/GPIO_controller/Docs/BeagleboneBlackP8HeaderTable.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 17/GPIO_controller/Docs/BeagleboneBlackP8HeaderTable.pdf -------------------------------------------------------------------------------- /Bai 17/GPIO_controller/Docs/BeagleboneBlackP9HeaderTable.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 17/GPIO_controller/Docs/BeagleboneBlackP9HeaderTable.pdf -------------------------------------------------------------------------------- /Bai 17/GPIO_controller/Docs/GPIO controller driver.mm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /Bai 17/GPIO_controller/Docs/GPIO controller driver.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 17/GPIO_controller/Docs/GPIO controller driver.pptx -------------------------------------------------------------------------------- /Bai 17/GPIO_controller/Docs/Slice.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 17/GPIO_controller/Docs/Slice.pptx -------------------------------------------------------------------------------- /Bai 17/GPIO_controller/Docs/beaglebone-black-pinout.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 17/GPIO_controller/Docs/beaglebone-black-pinout.jpg -------------------------------------------------------------------------------- /Bai 17/GPIO_controller/Docs/document-build-linux-bbb.txt: -------------------------------------------------------------------------------- 1 | Create Bootable SD-card for Beaglebone Black 2 | ============================================ 3 | 1. Requirement 4 | ============== 5 | - cross-compiler: 6 | - u-boot source 7 | - linux kernel source : 4.14.108 8 | - root file system 9 | - sd-card more than 4GB 10 | 11 | 2. Step by step 12 | =============== 13 | 2.1 Get stuff: 14 | - install cross-compiler: 15 | + download from: http://releases.linaro.org/components/toolchain/binaries/7.4-2019.02/arm-linux-gnueabihf/ 16 | + file: gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabihf.tar.xz 17 | + extract this file: 18 | tar -xvf gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabihf.tar.xz 19 | mv gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabihf ~/arm-linux-toolchain/ 20 | 21 | - clone source code u-boot : 22 | cd ~/ 23 | git clone git://git.denx.de/u-boot.git u-boot/ 24 | 25 | - clone source code kernel : 26 | cd ~/ 27 | git clone https://github.com/beagleboard/linux.git 28 | - Download Rootfs: 29 | https://www.dropbox.com/s/k93doprl261hwn2/rootfs.tar.xz?dl=0 30 | 31 | 2.2 Compile source code 32 | - sudo apt install u-boot-tools 33 | - sudo apt install lzop 34 | - Compile U-boot: 35 | cd ~/u-boot/ 36 | make ARCH=arm CROSS_COMPILE=~/arm-linux-toolchain/bin/arm-linux-gnueabihf- am335x_boneblack_vboot_defconfig 37 | make ARCH=arm CROSS_COMPILE=~/arm-linux-toolchain/bin/arm-linux-gnueabihf- 38 | 39 | - Compile linux kernel: 40 | cd ~/linux/ 41 | sudo make ARCH=arm CROSS_COMPILE=~/arm-linux-toolchain/bin/arm-linux-gnueabihf- bb.org_defconfig 42 | sudo make ARCH=arm CROSS_COMPILE=~/arm-linux-toolchain/bin/arm-linux-gnueabihf- uImage dtbs LOADADDR=0x80008000 -j4 43 | 44 | 2.3 Format Sd-card 45 | - install tool format sd-card: 46 | sudo apt-get install gparted 47 | 48 | - plug-in sd-card and format it with two partitions: 49 | + partition 1: .size = 50M 50 | .type: Fat32 51 | .label: BOOT 52 | + partition 2: .size = 3G (rest of total sd-card's size) 53 | .type: ext4 54 | .label: RFS 55 | 56 | - to view what sd-card's partition is. you need run following command: 57 | lsblk 58 | 59 | eg: sdc -| 60 | |- sdc1 /media/trongdung/BOOT/ 61 | |- sdc2 /media/trongdung/RFS/ 62 | 63 | ***NOTE***: if result of command 'lsblk' are not like above, you must mount sdc1 and sdc2 to your system to write data to these partitions. 64 | 65 | - Runs following commands to make BOOT partition: 66 | sudo cp ~/u-boot/MLO /media/trongdung/BOOT/ 67 | sudo cp ~/u-boot/u-boot.img /media/trongdung/BOOT/ 68 | sudo cp ~/linux/arch/arm/boot/uImage /media/trongdung/BOOT/ 69 | sudo cp ~/linux/arch/arm/boot/dts/am335x-boneblack.dtb /media/trongdung/BOOT/ 70 | 71 | vi /media/trongdung/BOOT/uEnv.txt 72 | *** and then paste following content to the uEnv.txt file *** 73 | ----------------------------------------------------- 74 | console=ttyS0,115200n8 75 | netargs=setenv bootargs console=ttyO0,115200n8 root=/dev/mmcblk0p2 ro rootfstype=ext4 rootwait debug earlyprintk mem=512M 76 | netboot=echo Booting from microSD ...; setenv autoload no ; load mmc 0:1 ${loadaddr} uImage ; load mmc 0:1 ${fdtaddr} am335x-boneblack.dtb ; run netargs ; bootm ${loadaddr} - ${fdtaddr} 77 | uenvcmd=run netboot 78 | ------------------------------------------------------ 79 | 80 | after that, run command: 81 | sync 82 | sudo umount /media/trongdung/BOOT/ 83 | 84 | - Runs following commands to make RFS partition: 85 | cd ~/Download/ 86 | tar -xvf rootfs.tar.xz 87 | cd rootfs 88 | sudo cp -r ./* /media/trongdung/RFS/ 89 | sync 90 | sudo umount /media/trongdung/RFS/ 91 | 92 | 3. Done ! Now, we can lug-in sd-card to Board and power on. 93 | 94 | 4. To use PL2303 as debugger. 95 | install screen tool: 96 | sudo apt install screen 97 | run command: 98 | sudo screen /dev/ttyUSB0 115200 99 | -------------------------------------------------------------------------------- /Bai 17/GPIO_controller/Docs/reference/API_IRQ1.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 17/GPIO_controller/Docs/reference/API_IRQ1.PNG -------------------------------------------------------------------------------- /Bai 17/GPIO_controller/Docs/reference/dt-binding_gpio_gpio.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0 */ 2 | /* 3 | * This header provides constants for most GPIO bindings. 4 | * 5 | * Most GPIO bindings include a flags cell as part of the GPIO specifier. 6 | * In most cases, the format of the flags cell uses the standard values 7 | * defined in this header. 8 | */ 9 | 10 | #ifndef _DT_BINDINGS_GPIO_GPIO_H 11 | #define _DT_BINDINGS_GPIO_GPIO_H 12 | 13 | /* Bit 0 express polarity */ 14 | #define GPIO_ACTIVE_HIGH 0 15 | #define GPIO_ACTIVE_LOW 1 16 | 17 | /* Bit 1 express single-endedness */ 18 | #define GPIO_PUSH_PULL 0 19 | #define GPIO_SINGLE_ENDED 2 20 | 21 | /* Bit 2 express Open drain or open source */ 22 | #define GPIO_LINE_OPEN_SOURCE 0 23 | #define GPIO_LINE_OPEN_DRAIN 4 24 | 25 | /* 26 | * Open Drain/Collector is the combination of single-ended open drain interface. 27 | * Open Source/Emitter is the combination of single-ended open source interface. 28 | */ 29 | #define GPIO_OPEN_DRAIN (GPIO_SINGLE_ENDED | GPIO_LINE_OPEN_DRAIN) 30 | #define GPIO_OPEN_SOURCE (GPIO_SINGLE_ENDED | GPIO_LINE_OPEN_SOURCE) 31 | 32 | /* Bit 3 express GPIO suspend/resume persistence */ 33 | #define GPIO_SLEEP_MAINTAIN_VALUE 0 34 | #define GPIO_SLEEP_MAY_LOOSE_VALUE 8 35 | 36 | #endif -------------------------------------------------------------------------------- /Bai 17/GPIO_controller/Docs/reference/dt-bindings_pinctrl_am33xx.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0 */ 2 | /* 3 | * This header provides constants specific to AM33XX pinctrl bindings. 4 | */ 5 | 6 | #ifndef _DT_BINDINGS_PINCTRL_AM33XX_H 7 | #define _DT_BINDINGS_PINCTRL_AM33XX_H 8 | 9 | #include 10 | 11 | /* am33xx specific mux bit defines */ 12 | #undef PULL_ENA 13 | #undef INPUT_EN 14 | 15 | #define PULL_DISABLE (1 << 3) 16 | #define INPUT_EN (1 << 5) 17 | #define SLEWCTRL_SLOW (1 << 6) 18 | #define SLEWCTRL_FAST 0 19 | 20 | /* update macro depending on INPUT_EN and PULL_ENA */ 21 | #undef PIN_OUTPUT 22 | #undef PIN_OUTPUT_PULLUP 23 | #undef PIN_OUTPUT_PULLDOWN 24 | #undef PIN_INPUT 25 | #undef PIN_INPUT_PULLUP 26 | #undef PIN_INPUT_PULLDOWN 27 | 28 | #define PIN_OUTPUT (PULL_DISABLE) 29 | #define PIN_OUTPUT_PULLUP (PULL_UP) 30 | #define PIN_OUTPUT_PULLDOWN 0 31 | #define PIN_INPUT (INPUT_EN | PULL_DISABLE) 32 | #define PIN_INPUT_PULLUP (INPUT_EN | PULL_UP) 33 | #define PIN_INPUT_PULLDOWN (INPUT_EN) 34 | 35 | /* undef non-existing modes */ 36 | #undef PIN_OFF_NONE 37 | #undef PIN_OFF_OUTPUT_HIGH 38 | #undef PIN_OFF_OUTPUT_LOW 39 | #undef PIN_OFF_INPUT_PULLUP 40 | #undef PIN_OFF_INPUT_PULLDOWN 41 | #undef PIN_OFF_WAKEUPENABLE 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /Bai 17/GPIO_controller/Docs/reference/gpio_pinmuxing.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 17/GPIO_controller/Docs/reference/gpio_pinmuxing.PNG -------------------------------------------------------------------------------- /Bai 17/GPIO_controller/Docs/reference/pinctrl-s32.h: -------------------------------------------------------------------------------- 1 | /* 2 | * S32 pinmux core definitions 3 | * 4 | * Copyright 2016-2018 NXP 5 | * Copyright 2015-2016 Freescale Semiconductor, Inc. 6 | * Copyright (C) 2012 Linaro Ltd. 7 | * 8 | * This program is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation; either version 2 of the License, or 11 | * (at your option) any later version. 12 | */ 13 | 14 | #ifndef __DRIVERS_PINCTRL_S32_H 15 | #define __DRIVERS_PINCTRL_S32_H 16 | 17 | /** 18 | * Pinctrl driver versions 19 | */ 20 | enum s32_pinctrl_version { 21 | /* Pinctrl driver reserves all SIUL2 registers */ 22 | PINCTRL_V1, 23 | /* Pinctrl driver reserves only pinctrl registers */ 24 | PINCTRL_V2, 25 | }; 26 | 27 | struct platform_device; 28 | 29 | /** 30 | * struct s32_pin - describes a single S32 pin 31 | * @pin_id: the pin_id of this pin 32 | * @config: the config for this pin. 33 | */ 34 | struct s32_pin { 35 | unsigned int pin_id; 36 | unsigned long config; 37 | }; 38 | 39 | /** 40 | * struct s32_pin_group - describes an S32 pin group 41 | * @name: the name of this specific pin group 42 | * @npins: the number of pins in this group array, i.e. the number of 43 | * elements in .pins so we can iterate over that array 44 | * @pin_ids: array of pin_ids. pinctrl forces us to maintain such an array 45 | * @pins: array of pins 46 | */ 47 | struct s32_pin_group { 48 | const char *name; 49 | unsigned int npins; 50 | unsigned int *pin_ids; 51 | struct s32_pin *pins; 52 | }; 53 | 54 | /** 55 | * struct s32_pmx_func - describes S32 pinmux functions 56 | * @name: the name of this specific function 57 | * @groups: corresponding pin groups 58 | * @num_groups: the number of groups 59 | */ 60 | struct s32_pmx_func { 61 | const char *name; 62 | const char **groups; 63 | unsigned int num_groups; 64 | }; 65 | 66 | struct s32_pinctrl_soc_info { 67 | struct device *dev; 68 | const struct pinctrl_pin_desc *pins; 69 | unsigned int npins; 70 | struct s32_pin_group *groups; 71 | unsigned int ngroups; 72 | struct s32_pmx_func *functions; 73 | unsigned int nfunctions; 74 | unsigned int flags; 75 | unsigned int grp_index; 76 | unsigned int mscr_base_pin; 77 | unsigned int mscr_end_pin; 78 | unsigned int imcr_base_pin; 79 | unsigned int imcr_end_pin; 80 | }; 81 | 82 | #define S32_PINCTRL_PIN(pin) PINCTRL_PIN(pin, #pin) 83 | #define S32_MSCR_OFFSET (0x240) 84 | #define S32_PAD_CONFIG(idx) ((idx) * 4) 85 | #define S32_PIN_SIZE (8) 86 | 87 | int s32_pinctrl_probe(struct platform_device *pdev, 88 | struct s32_pinctrl_soc_info *info); 89 | int s32_pinctrl_remove(struct platform_device *pdev); 90 | #endif /* __DRIVERS_PINCTRL_S32_H */ 91 | 92 | -------------------------------------------------------------------------------- /Bai 17/GPIO_controller/Docs/reference/request_irq.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 17/GPIO_controller/Docs/reference/request_irq.PNG -------------------------------------------------------------------------------- /Bai 17/GPIO_controller/Docs/reference/struct gpio_chip.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 17/GPIO_controller/Docs/reference/struct gpio_chip.PNG -------------------------------------------------------------------------------- /Bai 17/GPIO_controller/Docs/reference/struct irq_chip.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 17/GPIO_controller/Docs/reference/struct irq_chip.PNG -------------------------------------------------------------------------------- /Bai 17/GPIO_controller/Docs/reference/struct irq_chip2.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 17/GPIO_controller/Docs/reference/struct irq_chip2.PNG -------------------------------------------------------------------------------- /Bai 17/GPIO_controller/Docs/reference/trace-code.txt: -------------------------------------------------------------------------------- 1 | grep "pinctrl_request_gpio" -> drivers/pinctrl/core.c -> grep "pinmux_request_gpio" -> 2 | -> drivers/pinctrl/pinmux.c -> grep "pin_request" -> :83 -> grep "gpio_request_enable" -> 3 | -> drivers/pinctrl/pinctrl-single.c -> pcs_request_gpio 4 | 5 | 6 | *********************** Flowing of omap code: ********************** 7 | export: 8 | my_gpio_request 9 | my_gpio_get_direction 10 | my_irq_bus_lock 11 | my_ack_irq 12 | my_irq_bus_sync_unlock 13 | 14 | unexport: 15 | my_irq_bus_lock 16 | my_irq_shutdown -> if current mode is irq 17 | my_irq_bus_sync_unlock 18 | my_gpio_free 19 | 20 | direction: 21 | my_gpio_set_config *just once* 22 | my_gpio_direction_output / input 23 | 24 | edge: enable irq 25 | my_irq_bus_lock 26 | my_gpio_get_direction 27 | my_irq_type -> is_input 28 | *** my_irq_startup -> is_input, enable_gpio_module 29 | my_irq_bus_sync_unlock 30 | 31 | edge: disable irq 32 | my_irq_bus_lock 33 | my_irq_shutdown -> disable_irq, disable_gpio_module 34 | my_irq_bus_sync_unlock 35 | -------------------------------------------------------------------------------------------------------------------------- 36 | 37 | export: 38 | SyS_write -> kernfs_fop_write -> export_store -> gpiod_request -> __gpiod_request -> my_gpio_request (enable_gpio_module) 39 | | |------> my_gpio_get_direction 40 | | 41 | |---> gpiod_export -> device_create_groups -> device_add -> sysfs_create_groups -> gpiod_to_irq -> irq_create_mapping -> irq_domain_associate -> gpiochip_irq_map -> irq_set_chip_and_handler_name -> __irq_set_handler -> __irq_get_desc_lock -> omap_gpio_irq_bus_lock 42 | |--> __irq_do_set_handler -> omap_gpio_ack_irq 43 | |--> __irq_push_desc_lock -> gpio_irq_bus_sync_unlock 44 | 45 | direction: 46 | SyS_write -> kernfs_fop_write -> dev_attr_store -> direction_store -> __gpiod_direction_output_raw -> omap_gpio_set_config 47 | | |---> omap_gpio_output 48 | | 49 | |---> gpiod_direction_input ->omap_gpio_input 50 | 51 | value: 52 | SyS_write -> kernfs_fop_read -> dev_attr_show -> omap_gpio_get 53 | 54 | unexport: 55 | SyS_write -> unexport_store -> gpiod_free -> omap_gpio_free 56 | 57 | edge: 58 | SyS_write -> edge_store -> gpio_sysfs_request_irq -> omap_gpio_get_direction 59 | | |---> __setup_irq -> omap_gpio_irq_bus_lock 60 | | | --> omap_gpio_get_direction 61 | | | --> omap_gpio_irq_type 62 | | | --> omap_gpio_irq_startup -> omap_gpio_unmask_irq 63 | | | --> gpio_irq_bus_sync_unlock 64 | | 65 | | ----> gpio_sysfs_free_irq -> omap_gpio_irq_bus_lock 66 | | --> omap_gpio_irq_shutdown -> disable_gpio_module 67 | | --> gpio_irq_bus_sync_unlock 68 | 69 | -------------------------------------------------------------------------------- /Bai 17/GPIO_controller/Docs/tools: -------------------------------------------------------------------------------- 1 | Tools and Trick for Embedded Linux 2 | ================================== 3 | 1. grep -nrwI "string-need-find" 4 | 2. grep -nrwI --include=*\.c --include=*\.h "string-need-find" 5 | 3. find -name "file-name" 6 | 4. dump_stack(); 7 | 5. pr_emerg("Dungnt98 %s, %d", __func__, __LINE__); -------------------------------------------------------------------------------- /Bai 17/GPIO_controller/Makefile: -------------------------------------------------------------------------------- 1 | PWD := $(shell pwd) 2 | 3 | src-file = ./my_gpio.c 4 | obj-m += my_gpio.o 5 | 6 | CROSS := /data/dungnt98/toolchain/gcc-linaro-7.3.1-2018.05-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf- 7 | KERNEL := /data/dungnt98/linux/ 8 | 9 | all: 10 | make ARCH=arm CROSS_COMPILE=$(CROSS) -C $(KERNEL) SUBDIRS=$(PWD) modules 11 | clean: 12 | make -C $(KERNEL) SUBDIRS=$(PWD) clean 13 | check: 14 | ./checkpatch.pl --no-tree --ignore CONST_STRUCT --show-types -f $(src-file) 15 | -------------------------------------------------------------------------------- /Bai 17/GPIO_controller/README.md: -------------------------------------------------------------------------------- 1 | ************* GUIDE for use GPIO_CONTROLLER driver as example of tutorial ********** 2 | 3 | 1. Modify compatible property of gpio node in device tree at path: linux/arch/arm/boot/dts/am33xx.dtsi 4 | - notice that we just be able to modify node gpio1 gpio2 gpio3 and can not change gpio0 node, because need it for boot-up system. 5 | 6 | 2. Modify path of source code linux and toolchain in Makefile file corresponding to your environment build system. 7 | 8 | 3. run command to build: 9 | make clean all 10 | 11 | 4. Coppy file my_gpio.ko to your sd-card and then insert it to Beaglebone Black board. 12 | 13 | 5. Power-up board, and use command with sysfs to test driver. 14 | -------------------------------------------------------------------------------- /Bai 18/IPC.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 18/IPC.pptx -------------------------------------------------------------------------------- /Bai 18/compare_table.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 18/compare_table.xlsx -------------------------------------------------------------------------------- /Bai 18/netlink-libmnl-manual.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 18/netlink-libmnl-manual.pdf -------------------------------------------------------------------------------- /Bai 18/sample_code/shared_memory/Makefile: -------------------------------------------------------------------------------- 1 | obj-m:=kernel_module.o 2 | 3 | all: 4 | make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules 5 | gcc -o user_space user_space.c -lrt 6 | 7 | clean: 8 | make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean 9 | rm -rf user_space 10 | -------------------------------------------------------------------------------- /Bai 18/sample_code/shared_memory/kernel_module.c: -------------------------------------------------------------------------------- 1 | #include /* copy_from_user */ 2 | #include 3 | #include 4 | #include 5 | #include /* min */ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #define DEVICE_NAME "exam_mmap" 13 | static dev_t dev_num; 14 | struct class *my_class; 15 | struct device *my_dev; 16 | struct cdev my_cdev; 17 | 18 | struct mmap_info { 19 | char *data; 20 | }; 21 | 22 | /* After unmap. */ 23 | static void vm_close(struct vm_area_struct *vma) 24 | { 25 | struct mmap_info *info; 26 | info = (struct mmap_info *)vma->vm_private_data; 27 | pr_info("PhuLA %s, %d, data = %s\n", __func__, __LINE__, info->data); 28 | } 29 | 30 | /* First page access. */ 31 | static int vm_fault(struct vm_fault *vmf) 32 | { 33 | struct page *page; 34 | struct mmap_info *info; 35 | struct vm_area_struct *vma = vmf->vma; 36 | 37 | pr_info("PhuLA %s, %d\n", __func__, __LINE__); 38 | info = (struct mmap_info *)vma->vm_private_data; 39 | if (info->data) { 40 | page = virt_to_page(info->data); 41 | get_page(page); 42 | vmf->page = page; 43 | } 44 | return 0; 45 | } 46 | 47 | /* Aftr mmap. TODO vs mmap, when can this happen at a different time than mmap? */ 48 | static void vm_open(struct vm_area_struct *vma) 49 | { 50 | pr_info("PhuLA %s, %d\n", __func__, __LINE__); 51 | } 52 | 53 | static struct vm_operations_struct vm_ops = 54 | { 55 | .close = vm_close, 56 | .fault = vm_fault, 57 | .open = vm_open, 58 | }; 59 | 60 | static int mmap(struct file *filp, struct vm_area_struct *vma) 61 | { 62 | pr_info("PhuLA %s, %d\n", __func__, __LINE__); 63 | vma->vm_ops = &vm_ops; 64 | vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP; 65 | vma->vm_private_data = filp->private_data; 66 | vm_open(vma); 67 | return 0; 68 | } 69 | 70 | static int open(struct inode *inode, struct file *filp) 71 | { 72 | struct mmap_info *info; 73 | 74 | pr_info("PhuLA %s, %d\n", __func__, __LINE__); 75 | info = kmalloc(sizeof(struct mmap_info), GFP_KERNEL); 76 | 77 | info->data = (char *)get_zeroed_page(GFP_KERNEL); 78 | memcpy(info->data, "asdf", strlen("asdf")); 79 | filp->private_data = info; 80 | return 0; 81 | } 82 | 83 | static int release(struct inode *inode, struct file *filp) 84 | { 85 | struct mmap_info *info; 86 | 87 | pr_info("PhuLA %s, %d\n", __func__, __LINE__); 88 | info = filp->private_data; 89 | free_page((unsigned long)info->data); 90 | kfree(info); 91 | filp->private_data = NULL; 92 | return 0; 93 | } 94 | 95 | static const struct file_operations fops = { 96 | .mmap = mmap, 97 | .open = open, 98 | .release = release, 99 | }; 100 | 101 | static int myinit(void) 102 | { 103 | alloc_chrdev_region(&dev_num, 0, 1, DEVICE_NAME); 104 | my_class = class_create(THIS_MODULE, DEVICE_NAME); 105 | cdev_init(&my_cdev, &fops); 106 | my_cdev.owner = THIS_MODULE; 107 | cdev_add(&my_cdev, dev_num, 1); 108 | device_create(my_class, NULL, dev_num, NULL, DEVICE_NAME); 109 | 110 | return 0; 111 | } 112 | 113 | static void myexit(void) 114 | { 115 | cdev_del(&my_cdev); 116 | device_destroy(my_class, dev_num); 117 | class_destroy(my_class); 118 | unregister_chrdev(dev_num, DEVICE_NAME); 119 | } 120 | 121 | module_init(myinit) 122 | module_exit(myexit) 123 | MODULE_LICENSE("GPL"); -------------------------------------------------------------------------------- /Bai 18/sample_code/shared_memory/user_space.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | int main() 12 | { 13 | /* the size (in bytes) of shared memory object */ 14 | const int SIZE = 4096; 15 | 16 | /* name of the shared memory object */ 17 | const char* name = "/dev/exam_mmap"; 18 | 19 | /* strings written to shared memory */ 20 | const char* message_0 = "Hello"; 21 | const char* message_1 = "World!"; 22 | 23 | /* shared memory file descriptor */ 24 | int shm_fd; 25 | 26 | /* pointer to shared memory obect */ 27 | void* ptr; 28 | 29 | /* create the shared memory object */ 30 | shm_fd = open(name, O_CREAT | O_RDWR, 0666); 31 | 32 | /* configure the size of the shared memory object */ 33 | ftruncate(shm_fd, SIZE); 34 | 35 | /* memory map the shared memory object */ 36 | ptr = mmap(0, SIZE, PROT_WRITE, MAP_SHARED, shm_fd, 0); 37 | 38 | /* write to the shared memory object */ 39 | sprintf(ptr, "%s", message_0); 40 | 41 | ptr += strlen(message_0); 42 | sprintf(ptr, "%s", message_1); 43 | ptr += strlen(message_1); 44 | close(shm_fd); 45 | return 0; 46 | } -------------------------------------------------------------------------------- /Bai 19/Ethernet_driver.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 19/Ethernet_driver.pptx -------------------------------------------------------------------------------- /Bai 2/Bai_tap_buoi2/bai1/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | gcc bai1.c -o t 3 | clean: 4 | rm t 5 | -------------------------------------------------------------------------------- /Bai 2/Bai_tap_buoi2/bai1/README.txt: -------------------------------------------------------------------------------- 1 | program read a number character of a file at any point ( SET , CUR , END) 2 | 3 | how to run ? 4 | 1.run command "make all" 5 | 2. "./t " 6 | 7 | -------------------------------------------------------------------------------- /Bai 2/Bai_tap_buoi2/bai1/bai1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | int main(int argc , char * argv[]){ 8 | char *buffer; 9 | int fd ; 10 | 11 | printf("program read a file at any point from SET , CUR , END\n"); 12 | if( argc != 4){ 13 | perror("incorrect syntax\n"); 14 | return -1; 15 | } 16 | 17 | buffer = (char *) malloc(100); 18 | if( (fd = open(argv[1] , O_RDONLY )) ) 19 | { 20 | lseek(fd, atoi(argv[2]), atoi(argv[3])); 21 | while(read(fd, buffer, 100) != 0) 22 | puts(buffer); 23 | } 24 | free(buffer); 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /Bai 2/Bai_tap_buoi2/bai3/Makefile: -------------------------------------------------------------------------------- 1 | obj-m := misc-module.o 2 | 3 | all: 4 | make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules 5 | gcc read.c -o read 6 | clean: 7 | make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean 8 | rm -rf read 9 | -------------------------------------------------------------------------------- /Bai 2/Bai_tap_buoi2/bai3/README.txt: -------------------------------------------------------------------------------- 1 | description : read a device file ( a file is generated by driver misc-module ) 2 | user get a string is : "nguyen thanh tung" when read "/dev/my_misc_device" file 3 | 4 | how to run ? 5 | 1. run "make all" 6 | 2. ./read -------------------------------------------------------------------------------- /Bai 2/Bai_tap_buoi2/bai3/misc-module.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | static struct miscdevice my_dev; 9 | 10 | static int dev_open(struct inode *, struct file *); 11 | static int dev_close(struct inode *, struct file *); 12 | static ssize_t dev_read(struct file *, char __user *, size_t, loff_t *); 13 | static ssize_t dev_write(struct file *, const char __user *, size_t, loff_t *); 14 | 15 | char *buff = "nguyen thanh tung"; 16 | 17 | static const struct file_operations fops = { 18 | .owner = THIS_MODULE, 19 | .open = dev_open, 20 | .release = dev_close, 21 | .read = dev_read, 22 | .write = dev_write 23 | }; 24 | 25 | static int dev_open(struct inode *inodep, struct file *filep) 26 | { 27 | pr_info("open file\n"); 28 | return 0; 29 | } 30 | 31 | static int dev_close(struct inode *inodep, struct file *filep) 32 | { 33 | pr_info("close file\n"); 34 | return 0; 35 | } 36 | 37 | static ssize_t dev_read(struct file *filep, char __user *buf, size_t len, 38 | loff_t *offset) 39 | { 40 | int ret; 41 | 42 | pr_info("read file\n"); 43 | ret = copy_to_user(buf, buff, strlen(buff)); 44 | if (ret) { 45 | pr_alert("can not put to user\n"); 46 | return ret; 47 | } 48 | 49 | pr_info("send %d letter to user\n", (int)strlen(buff)); 50 | return 0; 51 | } 52 | 53 | static ssize_t dev_write(struct file *filep, const char __user *buf, size_t len, 54 | loff_t *offset) 55 | { 56 | pr_info("write to file\n"); 57 | return 0; 58 | } 59 | 60 | static int __init exam_init(void) 61 | { 62 | int ret; 63 | 64 | my_dev.minor = MISC_DYNAMIC_MINOR; 65 | my_dev.name = "my_misc_device"; 66 | my_dev.fops = &fops; 67 | ret = misc_register(&my_dev); 68 | if (ret) 69 | return ret; 70 | pr_info("register succesfully device with minor %d\n", my_dev.minor); 71 | return 0; 72 | } 73 | 74 | static void __exit exam_exit(void) 75 | { 76 | pr_info("goodbye\n"); 77 | misc_deregister(&my_dev); 78 | } 79 | 80 | module_init(exam_init); 81 | module_exit(exam_exit); 82 | 83 | 84 | MODULE_AUTHOR("TUNG"); 85 | MODULE_LICENSE("GPL"); 86 | -------------------------------------------------------------------------------- /Bai 2/Bai_tap_buoi2/bai3/read.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #define FILE "/dev/my_misc_device" 10 | 11 | int main(void) 12 | { 13 | char buff[20] ; 14 | 15 | memset(buff, 0, 20); 16 | int fd = open(FILE, O_RDONLY); 17 | 18 | if (fd < 0) { 19 | perror("open\n"); 20 | exit(1); 21 | } 22 | read(fd, buff, 20); 23 | 24 | 25 | printf("%s\n", buff); 26 | 27 | close(fd); 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /Bai 2/Bai_tap_buoi2/bai3/write.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #define FILE "/dev/my_misc_device" 10 | 11 | int main(void) 12 | { 13 | char buff[20] = "vu hai long"; 14 | 15 | memset(buff, 0, 20); 16 | int fd = open(FILE, O_WRONLY); 17 | 18 | if (fd < 0) { 19 | perror("open\n"); 20 | exit(1); 21 | } 22 | 23 | write(fd , buff, 20); 24 | 25 | close(fd); 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /Bai 2/Bai_tap_buoi2/bai4/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | gcc bai4.c -o t 3 | clean: 4 | rm t -------------------------------------------------------------------------------- /Bai 2/Bai_tap_buoi2/bai4/README.txt: -------------------------------------------------------------------------------- 1 | description : create a tree directory with permition is seted by programer 2 | 3 | detail : page 12 in slide "File trong Linux.pdf" 4 | 5 | how to run ? 6 | 1. "make all" 7 | 2. "./t " -------------------------------------------------------------------------------- /Bai 2/Bai_tap_buoi2/bai4/bai4.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #define RWRWRW (S_IROTH |S_IWOTH|S_IXOTH| S_IRGRP |S_IWGRP|S_IXGRP | S_IRUSR |S_IWUSR |S_IXUSR) 9 | int main(int argc , char *argv[]){ 10 | 11 | char *buff1 = (char *) malloc(100); 12 | char *buff2 = (char *) malloc(100); 13 | char *buff3 = (char *) malloc(100); 14 | char *buff4 = (char *) malloc(100); 15 | 16 | if( argc != 2 ) 17 | { 18 | perror("incorrect format command\n"); 19 | return -1; 20 | } 21 | puts("need permission as root to run correct command "); 22 | sprintf(buff1, "%s/%s", argv[1],"Testfolder"); 23 | sprintf(buff2, "%s/%s", buff1,"Test1"); 24 | sprintf(buff3, "%s/%s", buff1,"efg"); 25 | sprintf(buff4, "%s/%s", buff2,"abc"); 26 | 27 | puts(argv[1]); 28 | puts(buff1); 29 | puts(buff2); 30 | puts(buff3); 31 | puts(buff4); 32 | 33 | // if(mkdir( buff1, (RWRWRW &(~( S_IXUSR |S_IXGRP| S_IXOTH|S_IWOTH) )))== 0) 34 | if(mkdir( buff1, 0744) ==0) 35 | { 36 | if(mkdir( buff2, (RWRWRW &(~( S_IXUSR|S_IXGRP| S_IXOTH|S_IWOTH) )))==0) 37 | { 38 | 39 | printf("create ok %s\n" , buff4); 40 | if(creat( buff4, (S_IRUSR | S_IRGRP| S_IROTH))) 41 | { 42 | 43 | printf("create ok %s\n" , buff2); 44 | } 45 | } 46 | if(mkdir( buff3, (RWRWRW &(~(S_IXUSR | S_IXGRP| S_IXOTH|S_IWOTH) )))==0 ) 47 | { 48 | printf("create ok %s\n" , buff3); 49 | } 50 | } 51 | free(buff1); 52 | free(buff2); 53 | free(buff3); 54 | free(buff4); 55 | 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /Bai 2/Bai_tap_buoi2/bai5/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | gcc -c -Wall -Werror -fpic foo.c 3 | gcc -shared -o libfoo.so foo.o 4 | gcc -L./ -Wl,-rpath=/usr/bin -Wall -o test1 main.c -lfoo 5 | clean: 6 | rm -f test1 7 | rm *.o *.so 8 | -------------------------------------------------------------------------------- /Bai 2/Bai_tap_buoi2/bai5/README: -------------------------------------------------------------------------------- 1 | description : 2 | you write a program install(and uninstall) for a package 3 | sequense program : 4 | 5 | 1. Go Make de build source code 6 | 2. Chuong trinh setup phai lam nhung viec sau: 7 | 2.1 Tao 1 file text voi duong dan /etc/foo.conf 8 | 2.2 Copy libfoo.so vao thu muc /usr/bin 9 | 2.3 Copy file test vao thu muc bin 10 | 3. Cd vao thu muc khac va go lenh "test" de kiem tra ket qua 11 | 12 | how to run ? 13 | 1. "make all" 14 | 2. sudo cp libfoo.so /usr/bin 15 | 2. "./test1" 16 | -------------------------------------------------------------------------------- /Bai 2/Bai_tap_buoi2/bai5/bai4.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #define linkconf "/etc/foo.conf" 8 | #define linkfoolib "/usr/bin/libfoo.so" 9 | #define link4run "/bin/test1" 10 | 11 | int copyFile(const char *f1 ,const char* f2 ){ 12 | 13 | FILE * fp1 , *fp2 ; 14 | char c ; 15 | if ( (fp1 = fopen(f1,"rb")) == NULL ) 16 | { 17 | printf("error open file %s\n " , f1); 18 | return -1; 19 | } 20 | if ( (fp2 = fopen(f2,"wb") ) == NULL) 21 | { 22 | printf("error open file %s\n " , f2); 23 | return -1; 24 | } 25 | 26 | while(!feof(fp1)) 27 | { 28 | c = fgetc(fp1); 29 | //putc(c , stdout); 30 | fputc(c, fp2); 31 | } 32 | fclose(fp1); 33 | fclose(fp2); 34 | return 0; 35 | } 36 | int main(){ 37 | 38 | int fd ; 39 | #if 1 40 | // step 1 41 | if(creat(linkconf,511) != -1 ) 42 | { 43 | puts("step 1 create link configure ok"); 44 | //step 2 45 | if( (fd = creat(linkfoolib,511)) != -1 ) 46 | { 47 | if(copyFile("libfoo.so","/usr/bin/libfoo.so") != 0) 48 | { 49 | puts("error copyfile libfoo.so"); 50 | return -1; 51 | } 52 | puts("step 2 copy libfoo.so to usr/bin ok"); 53 | //step 3 54 | if( (fd = creat(link4run,511 )) != -1 ) 55 | { 56 | 57 | if(copyFile("test1","/bin/test1") != 0) 58 | { 59 | puts("error copy test to bin"); 60 | return -1; 61 | } 62 | puts("step 3 copy test to /bin ok"); 63 | } 64 | 65 | else { puts("error step 2 " ); return -1;} 66 | } 67 | else { perror("error : ");; return -1;} 68 | 69 | } 70 | else { perror("error : ");; return -1;} 71 | #endif 72 | puts("install successfully !!!"); 73 | 74 | 75 | return 0; 76 | } 77 | -------------------------------------------------------------------------------- /Bai 2/Bai_tap_buoi2/bai5/bai4b.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | 10 | 11 | int main(){ 12 | 13 | if(remove("/etc/foo.conf") != 0 ) 14 | { 15 | perror("error message"); 16 | //printf("%s " , strerror(errno)); 17 | return -1; 18 | } 19 | if(remove("/usr/bin/libfoo.so") != 0) 20 | { 21 | perror("error message"); 22 | //printf("%s " , strerror(errno)); 23 | return -1; 24 | } 25 | if(remove("/bin/test1")) 26 | { 27 | perror("error message"); 28 | //printf("%s " , strerror(errno)); 29 | return -1; 30 | } 31 | 32 | puts("uninstall succeessfull"); 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /Bai 2/Bai_tap_buoi2/bai5/foo.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void foo() 4 | { 5 | printf("Hello, I'm a shared library\n"); 6 | } 7 | 8 | 9 | -------------------------------------------------------------------------------- /Bai 2/Bai_tap_buoi2/bai5/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | extern void foo(void); 3 | 4 | int main() 5 | { 6 | FILE *fp = fopen("/etc/foo.conf", "r"); 7 | 8 | if (NULL == fp) { 9 | printf("No config file"); 10 | return -1; 11 | } 12 | 13 | fclose(fp); 14 | 15 | foo(); 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /Bai 2/Bài 2 - File trong Linux.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 2/Bài 2 - File trong Linux.pptx -------------------------------------------------------------------------------- /Bai 2/sample_code/Aio/README: -------------------------------------------------------------------------------- 1 | Create a text file with at least 100 characters. 2 | Set name for it is: test_aoi.txt 3 | Put text file in same working directory with executable file. 4 | Add option -lrt when build source code -------------------------------------------------------------------------------- /Bai 2/sample_code/Aio/aio_read.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | const int SIZE_TO_READ = 100; 11 | 12 | int main() 13 | { 14 | // open the file 15 | int file = open("test_aoi.txt", O_RDONLY, 0); 16 | 17 | if (file == -1) 18 | { 19 | printf("Unable to open file!\n"); 20 | return 1; 21 | } 22 | 23 | // create the buffer 24 | char* buffer = (char *)calloc(SIZE_TO_READ, 1); 25 | 26 | // create the control block structure 27 | struct aiocb cb; 28 | 29 | memset(&cb, 0, sizeof(struct aiocb)); 30 | cb.aio_nbytes = SIZE_TO_READ; 31 | cb.aio_fildes = file; 32 | cb.aio_offset = 0; 33 | cb.aio_buf = buffer; 34 | 35 | // read! 36 | if (aio_read(&cb) == -1) 37 | { 38 | printf("Unable to create request!\n"); 39 | close(file); 40 | } 41 | 42 | printf("Request enqueued!\n"); 43 | 44 | // wait until the request has finished 45 | while(aio_error(&cb) == EINPROGRESS) 46 | { 47 | printf("Working...\n"); 48 | } 49 | 50 | // success? 51 | int numBytes = aio_return(&cb); 52 | 53 | if (numBytes != -1) 54 | printf("Success!\n"); 55 | else 56 | printf("Error!\n"); 57 | 58 | // now clean up 59 | free(buffer); 60 | close(file); 61 | 62 | return 0; 63 | } -------------------------------------------------------------------------------- /Bai 2/sample_code/Aio/test_aoi.txt: -------------------------------------------------------------------------------- 1 | A careful programmer will check the return value of close(), since it 2 | is quite possible that errors on a previous write(2) operation are 3 | reported only on the final close() that releases the open file 4 | description. Failing to check the return value when closing a file 5 | may lead to silent loss of data. This can especially be observed 6 | with NFS and with disk quota. 7 | 8 | Note, however, that a failure return should be used only for 9 | diagnostic purposes (i.e., a warning to the application that there 10 | may still be I/O pending or there may have been failed I/O) or 11 | remedial purposes (e.g., writing the file once more or creating a 12 | backup). 13 | 14 | Retrying the close() after a failure return is the wrong thing to do, 15 | since this may cause a reused file descriptor from another thread to 16 | be closed. This can occur because the Linux kernel always releases 17 | the file descriptor early in the close operation, freeing it for 18 | reuse; the steps that may return an error, such as flushing data to 19 | the filesystem or device, occur only later in the close operation. 20 | 21 | Many other implementations similarly always close the file descriptor 22 | (except in the case of EBADF, meaning that the file descriptor was 23 | invalid) even if they subsequently report an error on return from 24 | close(). POSIX.1 is currently silent on this point, but there are 25 | plans to mandate this behavior in the next major release of the 26 | standard. 27 | 28 | A careful programmer who wants to know about I/O errors may precede 29 | close() with a call to fsync(2). 30 | 31 | The EINTR error is a somewhat special case. Regarding the EINTR 32 | error, POSIX.1-2013 says: 33 | 34 | If close() is interrupted by a signal that is to be caught, it 35 | shall return -1 with errno set to EINTR and the state of 36 | fildes is unspecified. 37 | 38 | This permits the behavior that occurs on Linux and many other 39 | implementations, where, as with other errors that may be reported by 40 | close(), the file descriptor is guaranteed to be closed. However, it 41 | also permits another possibility: that the implementation returns an 42 | EINTR error and keeps the file descriptor open. (According to its 43 | documentation, HP-UX's close() does this.) The caller must then once 44 | more use close() to close the file descriptor, to avoid file 45 | descriptor leaks. This divergence in implementation behaviors 46 | provides a difficult hurdle for portable applications, since on many 47 | implementations, close() must not be called again after an EINTR 48 | error, and on at least one, close() must be called again. There are 49 | plans to address this conundrum for the next major release of the 50 | POSIX.1 standard. -------------------------------------------------------------------------------- /Bai 2/sample_code/misc-module.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 2/sample_code/misc-module.zip -------------------------------------------------------------------------------- /Bai 2/sample_code/misc-module/misc-module/Makefile: -------------------------------------------------------------------------------- 1 | obj-m := misc-module.o 2 | 3 | all: 4 | make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules 5 | gcc read.c -o read 6 | clean: 7 | make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean 8 | rm -rf read 9 | -------------------------------------------------------------------------------- /Bai 2/sample_code/misc-module/misc-module/New Text Document.txt: -------------------------------------------------------------------------------- 1 | a -------------------------------------------------------------------------------- /Bai 2/sample_code/misc-module/misc-module/misc-module.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | static struct miscdevice my_dev; 9 | 10 | static int dev_open(struct inode *, struct file *); 11 | static int dev_close(struct inode *, struct file *); 12 | static ssize_t dev_read(struct file *, char __user *, size_t, loff_t *); 13 | static ssize_t dev_write(struct file *, const char __user *, size_t, loff_t *); 14 | 15 | char *buff = "nguyen thanh tung"; 16 | 17 | static const struct file_operations fops = { 18 | .owner = THIS_MODULE, 19 | .open = dev_open, 20 | .release = dev_close, 21 | .read = dev_read, 22 | .write = dev_write 23 | }; 24 | 25 | static int dev_open(struct inode *inodep, struct file *filep) 26 | { 27 | pr_info("open file\n"); 28 | return 0; 29 | } 30 | 31 | static int dev_close(struct inode *inodep, struct file *filep) 32 | { 33 | pr_info("close file\n"); 34 | return 0; 35 | } 36 | 37 | static ssize_t dev_read(struct file *filep, char __user *buf, size_t len, 38 | loff_t *offset) 39 | { 40 | int ret; 41 | 42 | pr_info("read file\n"); 43 | ret = copy_to_user(buf, buff, strlen(buff)); 44 | if (ret) { 45 | pr_alert("can not put to user\n"); 46 | return ret; 47 | } 48 | 49 | pr_info("send %d letter to user\n", (int)strlen(buff)); 50 | return 0; 51 | } 52 | 53 | static ssize_t dev_write(struct file *filep, const char __user *buf, size_t len, 54 | loff_t *offset) 55 | { 56 | pr_info("write to file\n"); 57 | return 0; 58 | } 59 | 60 | static int __init exam_init(void) 61 | { 62 | int ret; 63 | 64 | my_dev.minor = MISC_DYNAMIC_MINOR; 65 | my_dev.name = "my_misc_device"; 66 | my_dev.fops = &fops; 67 | ret = misc_register(&my_dev); 68 | if (ret) 69 | return ret; 70 | pr_info("register succesfully device with minor %d\n", my_dev.minor); 71 | return 0; 72 | } 73 | 74 | static void __exit exam_exit(void) 75 | { 76 | pr_info("goodbye\n"); 77 | misc_deregister(&my_dev); 78 | } 79 | 80 | module_init(exam_init); 81 | module_exit(exam_exit); 82 | 83 | 84 | MODULE_AUTHOR("TUNG"); 85 | MODULE_LICENSE("GPL"); 86 | -------------------------------------------------------------------------------- /Bai 2/sample_code/misc-module/misc-module/read.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #define FILE "/dev/my_misc_device" 10 | 11 | int main(void) 12 | { 13 | char buff[20]; 14 | 15 | memset(buff, 0, 20); 16 | int fd = open(FILE, O_RDONLY); 17 | 18 | if (fd < 0) { 19 | perror("open\n"); 20 | exit(1); 21 | } 22 | read(fd, buff, 20); 23 | 24 | printf("%s\n", buff); 25 | 26 | close(fd); 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /Bai 2/sample_code/shared_lib.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 2/sample_code/shared_lib.zip -------------------------------------------------------------------------------- /Bai 20/Yocto basic.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 20/Yocto basic.pptx -------------------------------------------------------------------------------- /Bai 21/Hauer-U_BootV2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 21/Hauer-U_BootV2.pdf -------------------------------------------------------------------------------- /Bai 21/Porting U-Boot.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 21/Porting U-Boot.pptx -------------------------------------------------------------------------------- /Bai 21/Uboot.mm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /Bai 21/Uboot.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 21/Uboot.pptx -------------------------------------------------------------------------------- /Bai 21/sitara_boot_camp_03_giving_linux_the_boot.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 21/sitara_boot_camp_03_giving_linux_the_boot.pptx -------------------------------------------------------------------------------- /Bai 22 Uboot/Uboot basic.mm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /Bai 22 Uboot/porting_uboot/Elc2013_Fernandes.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 22 Uboot/porting_uboot/Elc2013_Fernandes.pdf -------------------------------------------------------------------------------- /Bai 22 Uboot/porting_uboot/Porting U-Boot.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 22 Uboot/porting_uboot/Porting U-Boot.pptx -------------------------------------------------------------------------------- /Bai 22 Uboot/porting_uboot/U_boot_Porting_guide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 22 Uboot/porting_uboot/U_boot_Porting_guide.pdf -------------------------------------------------------------------------------- /Bai 22 Uboot/porting_uboot/sitara_boot_camp_03_giving_linux_the_boot.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 22 Uboot/porting_uboot/sitara_boot_camp_03_giving_linux_the_boot.pptx -------------------------------------------------------------------------------- /Bai 22 Uboot/porting_uboot/uboot2014_kconfig.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 22 Uboot/porting_uboot/uboot2014_kconfig.pdf -------------------------------------------------------------------------------- /Bai 22 Uboot/uboot_build_system/Built-in Kernel Modules.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 22 Uboot/uboot_build_system/Built-in Kernel Modules.docx -------------------------------------------------------------------------------- /Bai 22 Uboot/uboot_build_system/Kbuild Overview_1.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 22 Uboot/uboot_build_system/Kbuild Overview_1.docx -------------------------------------------------------------------------------- /Bai 22 Uboot/uboot_build_system/U-boot_addr_relocation.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 22 Uboot/uboot_build_system/U-boot_addr_relocation.txt -------------------------------------------------------------------------------- /Bai 22 Uboot/uboot_build_system/include .config_4.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 22 Uboot/uboot_build_system/include .config_4.docx -------------------------------------------------------------------------------- /Bai 22 Uboot/uboot_build_system/make xxx_defconfig_2.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 22 Uboot/uboot_build_system/make xxx_defconfig_2.docx -------------------------------------------------------------------------------- /Bai 22 Uboot/uboot_build_system/make menuconfig_3.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 22 Uboot/uboot_build_system/make menuconfig_3.docx -------------------------------------------------------------------------------- /Bai 22 Uboot/uboot_build_system/u-boot.bin_5.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 22 Uboot/uboot_build_system/u-boot.bin_5.docx -------------------------------------------------------------------------------- /Bai 22 Uboot/uboot_flow/hinh_ve.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 22 Uboot/uboot_flow/hinh_ve.xlsx -------------------------------------------------------------------------------- /Bai 22 Uboot/uboot_flow/uboot_flow.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 22 Uboot/uboot_flow/uboot_flow.docx -------------------------------------------------------------------------------- /Bai 3/Bai_tap_buoi3/bai1/Makefile: -------------------------------------------------------------------------------- 1 | all : 2 | gcc -c -Wall -Werror -fPIC shared.c 3 | gcc -shared -o libshared.so shared.o 4 | #gcc -L./ -Wl,-rpath=/usr/bin -Wall -o test build_dlib.c -lshared 5 | clean: 6 | rm *.so *.o 7 | -------------------------------------------------------------------------------- /Bai 3/Bai_tap_buoi3/bai1/README.txt: -------------------------------------------------------------------------------- 1 | description: 2 | build a share library 3 | how to run ? 4 | 5 | 1. "make all" 6 | 2. get a file "libshared.so" . that is share lib after build 7 | 8 | note : 9 | in read file "Bai 2/buoi2/bai5/main.c" to using share library -------------------------------------------------------------------------------- /Bai 3/Bai_tap_buoi3/bai1/shared.c: -------------------------------------------------------------------------------- 1 | #include "shared.h" 2 | 3 | void share_foo(char *s) 4 | { 5 | puts("ok"); 6 | puts(s); 7 | } 8 | -------------------------------------------------------------------------------- /Bai 3/Bai_tap_buoi3/bai1/shared.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void share_foo(char *); 4 | -------------------------------------------------------------------------------- /Bai 3/Bai_tap_buoi3/bai3/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | gcc my_ls.c -o t 3 | clean: 4 | rm t -------------------------------------------------------------------------------- /Bai 3/Bai_tap_buoi3/bai3/README.txt: -------------------------------------------------------------------------------- 1 | description 2 | a program copy ls command function with a some argument pass via terminal 3 | 4 | how to run ? 5 | 1. "make all" 6 | 2. ./t -la -------------------------------------------------------------------------------- /Bai 3/Bai_tap_buoi3/bai3/my_ls.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main(int argc , char *argv[]) 6 | { 7 | 8 | char *s = (char *) malloc(sizeof(char) *100); 9 | int i = 0,j = 0 ; 10 | for ( i = 1 ; i < argc ; i ++) 11 | { 12 | 13 | if(argv[i][0] == '-') 14 | for(j = 1 ; j < strlen(argv[i]); j++) 15 | { 16 | switch(argv[i][j]){ 17 | case 'l': strcat(s,"full property\n");break; 18 | case 'a': strcat(s,"hien thi file an\n");break; 19 | default : strcpy(s,"incorrect flag");break;break; 20 | } 21 | } 22 | } 23 | puts(s); 24 | free(s); 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /Bai 3/Bai_tap_buoi3/bai4/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | gcc get_environment.c -o t 3 | clean: 4 | rm t 5 | -------------------------------------------------------------------------------- /Bai 3/Bai_tap_buoi3/bai4/README.txt: -------------------------------------------------------------------------------- 1 | description : 2 | a program access environment variable and print HOME , UserName, PWD 3 | 4 | how to run ? 5 | 1. "make all" 6 | 2. "./t" -------------------------------------------------------------------------------- /Bai 3/Bai_tap_buoi3/bai4/get_environment.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | extern char** environ; 5 | 6 | int main(){ 7 | 8 | printf("home = %s \n",(char *)getenv("HOME")); 9 | printf("user = %s \n",(char *)getenv("USER")); 10 | printf("pwd = %s \n",(char *)getenv("PWD")); 11 | 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /Bai 3/Bai_tap_buoi3/bai5/A.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() 6 | { 7 | sleep(13); 8 | printf("id of A.c %lld" ,(long long ) getpgid(0)); 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /Bai 3/Bai_tap_buoi3/bai5/B.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() 6 | { 7 | sleep(13); 8 | printf("id of B.c %lld" ,(long long ) getpgid(0)); 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /Bai 3/Bai_tap_buoi3/bai5/C.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() 6 | { 7 | sleep(13); 8 | printf("id of C.c %lld" ,(long long) getpgid(0)); 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /Bai 3/Bai_tap_buoi3/bai5/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | gcc A.c -o A 3 | gcc B.c -o B 4 | gcc C.c -o C 5 | 6 | clean: 7 | rm A B C -------------------------------------------------------------------------------- /Bai 3/Bai_tap_buoi3/bai5/README.txt: -------------------------------------------------------------------------------- 1 | description: 2 | 3 programs run parallel to check background , foreground process 3 | 4 | how to run ? 5 | 1. "make all" 6 | 2. open terminal run : ./A | ./B | ./C & -------------------------------------------------------------------------------- /Bai 3/Bai_tap_buoi3/bai6/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | gcc get_sension_id.c -o A 3 | gcc get_sension_id2.c -o B 4 | gcc get_sension_id3.c -o C 5 | 6 | clean: 7 | rm -f A B C 8 | -------------------------------------------------------------------------------- /Bai 3/Bai_tap_buoi3/bai6/README.txt: -------------------------------------------------------------------------------- 1 | description : get session id of some process on one terminal and 2 terminal 2 | 3 | how to run ? 4 | 1. "make all" 5 | 2. test 1: open 1 terminal and run sequense ./A ./B ./C 6 | test 2: open 2 terminal and run ./A ./B on first terminal , ./C on other 7 | -------------------------------------------------------------------------------- /Bai 3/Bai_tap_buoi3/bai6/get_sension_id.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(){ 5 | 6 | printf("sension id of A %d " ,getsid(0)); 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /Bai 3/Bai_tap_buoi3/bai6/get_sension_id2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(){ 5 | 6 | printf("sension id of 2 %d " ,getsid(0)); 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /Bai 3/Bai_tap_buoi3/bai6/get_sension_id3.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(){ 5 | 6 | printf("sension id of 3%d " ,getsid(0)); 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /Bai 3/Process.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 3/Process.pptx -------------------------------------------------------------------------------- /Bai 3/code_example/main_argv/main_argv.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(int argc, char *argv[]) 4 | { 5 | int i = 0; 6 | 7 | for(i = 0; i < argc; i++) 8 | printf("%s\n", argv[i]); 9 | 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /Bai 5/Example_code/add_timer.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | struct timer_list exp_timer; 10 | 11 | static void do_something(unsigned long data) 12 | { 13 | printk(KERN_INFO "Your timer expired and app has been called\n"); 14 | } 15 | 16 | static int __init tst_init(void) 17 | { 18 | int delay = 300; 19 | 20 | printk(KERN_INFO "Init called\n"); 21 | 22 | init_timer_on_stack(&exp_timer); 23 | 24 | exp_timer.expires = jiffies + delay * HZ; 25 | exp_timer.data = 0; 26 | exp_timer.function = do_something; 27 | 28 | add_timer(&exp_timer); 29 | 30 | return 0; 31 | } 32 | 33 | static void __exit tst_exit(void) 34 | { 35 | del_timer(&exp_timer); 36 | printk(KERN_INFO "Exit called\n"); 37 | } 38 | 39 | module_init(tst_init); 40 | module_exit(tst_exit); 41 | 42 | MODULE_LICENSE("GPL"); -------------------------------------------------------------------------------- /Bai 5/Example_code/interrupt_handler.c: -------------------------------------------------------------------------------- 1 | irqreturn_t irq_handler(int irq, void *dev_id, struct pt_regs *regs) 2 | { 3 | static int initialised = 0; 4 | static unsigned char scancode; 5 | static struct work_struct task; 6 | unsigned char status; 7 | 8 | return IRQ_HANDLED; 9 | } 10 | 11 | int init_module() 12 | { 13 | free_irq(1, NULL); 14 | 15 | return request_irq(1, /* The number of the keyboard IRQ on PCs */ 16 | irq_handler, /* our handler */ 17 | SA_SHIRQ, "test_keyboard_irq_handler", 18 | (void *)(irq_handler)); 19 | } -------------------------------------------------------------------------------- /Bai 5/Handle_button_for_orange_pi_zero/README.txt: -------------------------------------------------------------------------------- 1 | - Source code duoc viet cho board orange pi zero 2 | - Cach test: 3 | + Connect button vao chan GPIOA_0 4 | + Connect den led vao chan GPIOA_1 5 | - Build 2 file code thanh 2 file .ko. 1 file de xu ly button bang timer, 1 file xu ly bang interrupt. 6 | - Sau khi load file ko vao he thong, moi khi clicl button thi den led se sang. -------------------------------------------------------------------------------- /Bai 5/Handle_button_for_orange_pi_zero/check_event_timer.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define AUTHOR "NGUYEN HUU THINH" 6 | 7 | #define BUTTON 0 8 | #define BASE_ADD_GPIO 0x01C20800 9 | #define OFFSET_GPIOA 0x00 10 | #define OFFSET_GPIOA_PULL 0x1C 11 | #define SIZE_GPIOA 0x14 12 | #define SIZE_GPIOA_PULL 0x08 13 | 14 | 15 | static struct timer_list exp_timer; 16 | 17 | int flag = 1; 18 | unsigned int *address_gpioa; 19 | unsigned int *address_gpioa_pull; 20 | 21 | static void check_button(unsigned long); 22 | 23 | static void check_button(unsigned long data) 24 | { 25 | unsigned int delay = 0.1 * HZ; 26 | if(((address_gpioa[4] & (1 << 0)) == 0) && flag == 1) 27 | { 28 | flag = 0; 29 | if((address_gpioa[4] & (1 << 1)) == 0) 30 | { 31 | address_gpioa[4] |= (1 << 1); 32 | printk("LED ON\n"); 33 | } 34 | else 35 | { 36 | address_gpioa[4] &= ~(1 << 1); 37 | printk("LED OFF\n"); 38 | } 39 | } 40 | else if(((address_gpioa[4] & (1 << 0)) == 1) && flag == 0) 41 | flag = 1; 42 | exp_timer.expires = jiffies + delay; 43 | exp_timer.function = (void *)check_button; 44 | add_timer(&exp_timer); 45 | 46 | } 47 | 48 | static int __init check_event_timer_init(void) 49 | { 50 | printk("START!\n"); 51 | 52 | address_gpioa = ioremap(BASE_ADD_GPIO + OFFSET_GPIOA, SIZE_GPIOA); 53 | if(address_gpioa == NULL) 54 | { 55 | printk("Mapping address gpioa fail\n"); 56 | goto address_gpioa_fail; 57 | } 58 | //Select GPIOA_0 input mode 59 | address_gpioa[0] &= ~(7 << 0); 60 | //Select GPIOA_1 output mode 61 | address_gpioa[0] &= ~(7 << 4); 62 | address_gpioa[0] |= (1 << 4); 63 | 64 | address_gpioa_pull = ioremap(BASE_ADD_GPIO + OFFSET_GPIOA_PULL, SIZE_GPIOA_PULL); 65 | if(address_gpioa_pull == NULL) 66 | { 67 | printk("Mapping gpioa pull fail\n"); 68 | goto address_gpioa_pull_fail; 69 | } 70 | 71 | //Select GPIOA_0 PULL UP. 72 | address_gpioa_pull[0] &= ~(3 << 0); 73 | address_gpioa_pull[0] |= (1 << 0); 74 | 75 | //Khoi tao timer 76 | //init_timer_on_stack(&exp_timer); 77 | exp_timer.expires = jiffies + 1 * HZ; 78 | exp_timer.function = (void *)check_button; 79 | //exp_timer.data = NULL; 80 | 81 | //Bat dau timer 82 | add_timer(&exp_timer); 83 | return 0; 84 | address_gpioa_pull_fail: 85 | iounmap(address_gpioa); 86 | address_gpioa_fail: 87 | return -1; 88 | } 89 | 90 | static void __exit check_event_timer_exit(void) 91 | { 92 | printk("END!\n"); 93 | iounmap(address_gpioa); 94 | iounmap(address_gpioa_pull); 95 | } 96 | 97 | module_init(check_event_timer_init); 98 | module_exit(check_event_timer_exit); 99 | 100 | MODULE_LICENSE("GPL"); 101 | MODULE_AUTHOR(AUTHOR); 102 | -------------------------------------------------------------------------------- /Bai 5/Handle_button_for_orange_pi_zero/interrupt.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #define AUTHOR "NGUYEN HUU THINH" 7 | 8 | #define BUTTON 0 9 | #define BASE_ADD_GPIO 0x01C20800 10 | #define OFFSET_GPIOA 0x00 11 | #define OFFSET_GPIOA_PULL 0x1C 12 | #define OFFSET_EXTERNAL_INTERRUPT_GPIOA 0x200 13 | #define SIZE_EXTERNAL_INTERRUPT_GPIOA 0x20 14 | #define SIZE_GPIOA_PULL 0x08 15 | #define SIZE_GPIOA 0x14 16 | 17 | unsigned char irq_eint0; 18 | unsigned int *gpioa_0_7; 19 | unsigned int *ex_gpioa_0_7; 20 | unsigned int *gpioa_pull_0_15; 21 | 22 | irqreturn_t external_interrupt_handler(int irq, void *dev_id, struct pt_regs *regs) 23 | { 24 | 25 | if((gpioa_0_7[4] & (1 << 0)) == 0) 26 | { 27 | if((gpioa_0_7[4] & (1 << 1)) == 0) 28 | { 29 | gpioa_0_7[4] |= (1 << 1); 30 | printk("led_on\n"); 31 | } 32 | else 33 | { 34 | gpioa_0_7[4] &= ~(1 << 1); 35 | printk("led_off\n"); 36 | } 37 | } 38 | return IRQ_HANDLED; 39 | 40 | } 41 | 42 | static int __init external_interrupt_init(void) 43 | { 44 | int ret; 45 | printk("START!\n"); 46 | //Mapping GPIOA_0_7 47 | gpioa_0_7 = ioremap(BASE_ADD_GPIO + OFFSET_GPIOA, SIZE_GPIOA); 48 | if(gpioa_0_7 == NULL) 49 | { 50 | printk("Mapping address gpioa fail\n"); 51 | return -1; 52 | } 53 | 54 | //Select EINT0 mode GPIOA_0 55 | gpioa_0_7[0] &= ~(7 << 0); 56 | gpioa_0_7[0] |= (6 << 0); 57 | 58 | //Select output mode GPIOA_1 59 | gpioa_0_7[0] &= ~(7 << 4); 60 | gpioa_0_7[0] |= (1 << 4); 61 | 62 | //Mapping EINT_GPIOA 63 | ex_gpioa_0_7 = ioremap(BASE_ADD_GPIO + OFFSET_EXTERNAL_INTERRUPT_GPIOA, SIZE_EXTERNAL_INTERRUPT_GPIOA); 64 | if(ex_gpioa_0_7 == NULL) 65 | { 66 | printk("Mapping ex_gpioa fail\n"); 67 | return -1; 68 | } 69 | 70 | //EINT0 Negative Edge 71 | ex_gpioa_0_7[0] &= ~(15 << 0); 72 | ex_gpioa_0_7[0] |= (1 << 0); 73 | 74 | //Mapping gpioa pull 75 | gpioa_pull_0_15 = ioremap(BASE_ADD_GPIO + OFFSET_GPIOA_PULL, SIZE_GPIOA_PULL); 76 | if(gpioa_pull_0_15 == NULL) 77 | { 78 | printk("Mapping gpioa pull fail!\n"); 79 | return -1; 80 | } 81 | //GPIOA0 PULL UP 82 | gpioa_pull_0_15[0] &= ~(3 << 0); 83 | gpioa_pull_0_15[0] |= (1 << 0); 84 | 85 | //Init interrupt. 86 | irq_eint0 = gpio_to_irq(BUTTON); 87 | ret = request_irq(irq_eint0, (irq_handler_t) external_interrupt_handler, IRQF_SHARED, "EINT0", (void *)external_interrupt_handler); 88 | if(ret) 89 | printk("Init EINT0 success\n"); 90 | return 0; 91 | } 92 | 93 | static void __exit external_interrupt_exit(void) 94 | { 95 | printk("END!\n"); 96 | iounmap(gpioa_0_7); 97 | iounmap(ex_gpioa_0_7); 98 | iounmap(gpioa_pull_0_15); 99 | free_irq(irq_eint0, (void *)external_interrupt_handler); 100 | } 101 | 102 | module_init(external_interrupt_init); 103 | module_exit(external_interrupt_exit); 104 | 105 | MODULE_LICENSE("GPL"); 106 | MODULE_AUTHOR(AUTHOR); 107 | 108 | 109 | 110 | -------------------------------------------------------------------------------- /Bai 5/xu_ly_event.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 5/xu_ly_event.pptx -------------------------------------------------------------------------------- /Bai 7/Bai_tap/b3/Makefile: -------------------------------------------------------------------------------- 1 | all : 2 | gcc main.c -o t 3 | clean: 4 | rm -f t 5 | -------------------------------------------------------------------------------- /Bai 7/Bai_tap/b3/README.txt: -------------------------------------------------------------------------------- 1 | description: 2 | using fork() 3 | both A, B process write to a file 4 | update counter at end of file when write 5 | using signal to synchronized 6 | 7 | how to run ? 8 | 1. make 9 | 2. ./t -------------------------------------------------------------------------------- /Bai 7/Bai_tap/b3/data.txt: -------------------------------------------------------------------------------- 1 | 2 2 | 4 3 | 72054 8 4 | 2069 5 | 6 | 2605 2070 7 | 8 | 2615 2071 9 | 10 | 2989 2072 11 | 12 | 2990 2073 13 | 14 | 3003 2074 15 | 16 | 3011 2075 17 | 18 | 3024 2076 19 | 20 | 3025 2077 21 | 22 | 3063 2078 23 | 24 | 3071 2079 25 | 26 | 3072 2080 27 | 28 | 3138 2081 29 | 30 | 3152 2082 31 | 32 | 3160 2083 33 | 34 | 3173 2084 35 | 36 | 3187 2085 37 | 38 | 3206 2086 39 | 40 | 3256 2087 41 | 42 | 3272 2088 43 | 44 | 3271 2089 45 | 46 | 3307 2090 47 | 48 | 3306 2091 49 | 50 | 3320 2092 51 | 52 | 3319 2093 53 | 54 | 3339 2094 55 | 56 | 3338 2095 57 | 58 | 3366 2096 59 | 60 | 3376 2097 61 | 62 | 3375 2098 63 | 64 | 2175 2099 65 | 66 | 2174 2100 67 | 68 | 2278 2101 69 | 70 | 2279 2102 71 | 72 | 2287 2103 73 | 74 | 2286 2104 75 | 76 | 2302 2105 77 | 78 | 2303 2106 79 | 80 | 2315 2107 81 | 82 | 2316 2108 83 | 84 | 2325 2109 85 | 86 | 2326 2110 87 | 88 | 2360 2111 89 | 90 | 2361 2112 91 | 92 | 2368 2113 93 | 94 | 2369 2114 95 | 96 | 2376 2115 97 | 98 | 2394 2116 99 | 100 | 2403 2117 101 | 102 | 2402 2118 103 | 104 | 2410 2119 105 | 106 | 2411 2120 107 | 108 | 2418 2121 109 | 110 | 2419 2122 111 | 112 | 2426 2123 113 | 114 | 2427 2124 115 | 116 | 2434 2125 117 | 118 | 2435 2126 119 | 120 | 2443 2127 121 | 122 | 2442 2128 123 | 124 | 2450 2129 125 | 126 | 2451 2130 127 | 128 | 2459 2131 129 | 130 | 2458 2132 131 | 132 | 2466 2133 133 | 134 | 2467 2134 135 | 136 | 2475 2135 137 | 138 | 2482 2136 139 | 140 | 2483 2137 141 | 142 | 2490 2138 143 | 144 | 2491 2139 145 | 146 | 2498 2140 147 | 148 | 2499 2141 149 | 150 | 2506 2142 151 | 152 | 2507 2143 153 | 154 | 2514 2144 155 | 156 | 2515 2145 157 | 158 | 2523 2146 159 | 160 | 2522 2147 161 | 162 | 2530 2148 163 | 164 | 2538 2149 165 | 166 | 2610 2150 167 | 168 | 2609 2151 169 | 170 | 2617 2152 171 | 172 | 2618 2153 173 | 174 | 2620 2154 175 | 176 | 2621 2155 177 | 178 | 2623 2156 179 | 180 | 2626 2157 181 | 182 | 2628 2158 183 | 184 | 2630 2159 185 | 186 | 2632 2160 187 | 188 | 2633 2161 189 | 190 | 2636 2162 191 | -------------------------------------------------------------------------------- /Bai 7/Bai_tap/b3/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | int write_to_file() 10 | { 11 | char c ; 12 | int counter = 0 ; 13 | FILE *fp ; 14 | if( (fp = fopen("data.txt" , "r+")) == NULL ) 15 | { 16 | perror("fopen"); 17 | return -1; 18 | } 19 | // dung o cuoi 20 | fseek(fp , 0 , SEEK_END); 21 | // loai bo khoang trong 22 | do { 23 | c = getc(fp); 24 | fseek(fp , -2 , SEEK_CUR); 25 | } 26 | while ( (c > '9') || (c < '0')); 27 | 28 | // tim toan bo so 29 | do { 30 | c = getc(fp); 31 | fseek(fp , -2 , SEEK_CUR); 32 | } 33 | while ( (c <= '9') && (c >= '0')); 34 | 35 | fseek( fp , 2 , SEEK_CUR); 36 | 37 | // da tim duoc vi tri thich hop 38 | while ( (c = getc(fp) ) != EOF) 39 | { 40 | if (c < '0' || c > '9') break; 41 | counter = counter*10 + (c -'0'); 42 | } 43 | counter ++; 44 | printf("after change : %d\n" , counter ) ; 45 | 46 | fprintf(fp ,"\n%ld %d\n" , (long int)getpid() , counter); 47 | fclose(fp); 48 | } 49 | 50 | volatile int ready_to_write = 0; 51 | void handler_17(int n) 52 | { 53 | printf("%d :someone is writting \n" , getpid()); 54 | } 55 | void handler_chld(int n) 56 | { 57 | printf("%d:someone write completly\n" , getpid()); 58 | ready_to_write = 1 ; 59 | } 60 | int main() 61 | { 62 | // child write before parent write 63 | // child signal over SIGCHLD when done to Parent 64 | 65 | int pid; 66 | signal(17 , handler_17); 67 | signal(SIGCHLD , handler_chld); 68 | 69 | if (( pid = fork()) <0 ) 70 | { 71 | perror("fork"); 72 | return -1; 73 | } 74 | else if( pid == 0 ) 75 | { 76 | //child 77 | printf("child : %d\n" , (int) getpid()); 78 | kill( getppid() , 17); 79 | write_to_file(); 80 | } 81 | else { 82 | // parent 83 | int n ; 84 | printf("parent : %d\n", (int) getpid()); 85 | ready_to_write = 0; 86 | while(!ready_to_write); 87 | write_to_file(); 88 | } 89 | return 0; 90 | } 91 | 92 | -------------------------------------------------------------------------------- /Bai 7/Bai_tap/practive_1/Makefile: -------------------------------------------------------------------------------- 1 | all : 2 | gcc main.c -o t 3 | clean: 4 | rm -f t -------------------------------------------------------------------------------- /Bai 7/Bai_tap/practive_1/README.txt: -------------------------------------------------------------------------------- 1 | program overwrite handler of Ctrl+C : 2 | print string "hello world" when user press Ctrl + C 3 | 4 | test: 5 | 1. open termial Ctrl + Alt + T 6 | 2. make 7 | 3. ./t -------------------------------------------------------------------------------- /Bai 7/Bai_tap/practive_1/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void sig_handler(int sig) 5 | { 6 | if( sig == 9) 7 | { 8 | puts("hello world"); 9 | } 10 | } 11 | int main() 12 | { 13 | signal(9 , sig_handler); 14 | 15 | while(1); 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /Bai 7/Bai_tap/practive_2/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | gcc -o t main.c 3 | clean: 4 | rm t -------------------------------------------------------------------------------- /Bai 7/Bai_tap/practive_2/README.txt: -------------------------------------------------------------------------------- 1 | c program : block Ctrl + C from user 2 | 3 | check pendding using sigpendding to detect user press Ctrl + C 4 | 5 | test : 6 | 1.open terminal 7 | 2. make 8 | 3. ./t -------------------------------------------------------------------------------- /Bai 7/Bai_tap/practive_2/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main(void) 6 | { 7 | int k = 0; 8 | sigset_t newmask, oldmask, pendmask; 9 | sigemptyset(&newmask); 10 | sigaddset(&newmask, 2); 11 | if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0) 12 | perror("SIG_BLOCK error"); 13 | while(1) 14 | { 15 | if (sigpending(&pendmask) < 0) 16 | perror("sigpending error"); 17 | if (sigismember(&pendmask, 2)) 18 | { 19 | printf("\n2 pending\n"); 20 | break; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Bai 7/Signal.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 7/Signal.pptx -------------------------------------------------------------------------------- /Bai 8/Bai_tap/semaphore/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: all cleanall 2 | 3 | FLAGS :=-pthread -lrt 4 | 5 | all:cleanall main.o 6 | gcc -g main.o -o t $(FLAGS) 7 | 8 | main.o:main.c 9 | gcc -g -c main.c -o $@ 10 | 11 | cleanall: 12 | rm -f fsemaphore* 13 | rm -f *.o 14 | -------------------------------------------------------------------------------- /Bai 8/Bai_tap/semaphore/README.txt: -------------------------------------------------------------------------------- 1 | description: 2 | a process create n thread write to m file a string 3 | using semaphore to synchronized , 4 | 5 | how to run ? 6 | 1. make 7 | 2. ./t -------------------------------------------------------------------------------- /Bai 8/Bai_tap/semaphore/main.c: -------------------------------------------------------------------------------- 1 | // C program to demonstrate working of Semaphores 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #define MAX_NUM_FILE 10 9 | 10 | sem_t sem_write; 11 | pthread_mutex_t lock_valid_file; 12 | char files_info[MAX_NUM_FILE] ; 13 | 14 | void write_to_file( int n) 15 | { 16 | int i = 0; 17 | int ok = 0; 18 | while(!ok) 19 | for (i = 0 ; i < n ; i ++) 20 | { 21 | pthread_mutex_lock(&lock_valid_file); 22 | if(files_info[i] == 0) 23 | { 24 | files_info[i] = 1; 25 | ok = 1; 26 | } 27 | pthread_mutex_unlock(&lock_valid_file); 28 | // ghi vao file neu ok o tren 29 | if( ok == 1) 30 | { 31 | 32 | char nameFile[30]; 33 | sprintf(nameFile ,"fsemaphore%d.txt" , i); 34 | FILE *fp = fopen(nameFile , "a+"); 35 | 36 | fprintf( fp , "\n %lu ok write to file %d at %ld \n\n", pthread_self(), i, clock()); 37 | sleep(2); 38 | files_info[i] = 0; 39 | fclose(fp); 40 | break; 41 | } 42 | } 43 | } 44 | void* thread(void* arg) 45 | { 46 | //wait 47 | sem_wait(&sem_write); 48 | 49 | write_to_file(5); 50 | 51 | sem_post(&sem_write); 52 | } 53 | 54 | int main() 55 | { 56 | pthread_t t[10]; 57 | int i = 0, nthread = 9; 58 | pthread_mutex_init(&lock_valid_file, NULL ); 59 | sem_init(&sem_write, 0, 7); 60 | 61 | 62 | for (i = 0 ; i < nthread ; i ++) 63 | { 64 | pthread_create(&t[i],NULL,thread , NULL); 65 | } 66 | 67 | for ( i = 0 ; i < nthread ; i ++) 68 | { 69 | pthread_join(t[i],NULL); 70 | } 71 | 72 | pthread_mutex_destroy(&lock_valid_file); 73 | sem_destroy(&sem_write); 74 | puts("ok"); 75 | return 0; 76 | } 77 | 78 | -------------------------------------------------------------------------------- /Bai 8/Bai_tap/test_multithread/test_multithread.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | unsigned long sum; 8 | 9 | void *gen_random_number(void *ptr) 10 | { 11 | unsigned long local_sum = 0; 12 | unsigned int i = 0; 13 | unsigned long n = *(unsigned long*)ptr; 14 | 15 | for (i = 0; i < n; i++) { 16 | local_sum = local_sum + (i % 10); 17 | } 18 | 19 | sum = sum + local_sum; 20 | 21 | return NULL; 22 | } 23 | 24 | void main() 25 | { 26 | time_t start_time; 27 | time_t finish_time; 28 | unsigned long count = 2000000000; 29 | unsigned long count0 = 500000000; 30 | unsigned long count1 = 500000000; 31 | unsigned long count2 = 500000000; 32 | unsigned long count3 = 500000000; 33 | pthread_t thread0; 34 | pthread_t thread1; 35 | pthread_t thread2; 36 | pthread_t thread3; 37 | 38 | start_time = time(NULL); 39 | sum = 0; 40 | gen_random_number((void *) &count); 41 | finish_time = time(NULL); 42 | printf("With single thread, it takes %ld seconds to gen a random number = %lu\n", finish_time - start_time, sum); 43 | 44 | start_time = time(NULL); 45 | sum = 0; 46 | 47 | pthread_create(&thread0, NULL, gen_random_number, (void*) &count0); 48 | pthread_create(&thread1, NULL, gen_random_number, (void*) &count1); 49 | pthread_create(&thread2, NULL, gen_random_number, (void*) &count2); 50 | pthread_create(&thread3, NULL, gen_random_number, (void*) &count3); 51 | pthread_join(thread0, NULL); 52 | pthread_join(thread1, NULL); 53 | pthread_join(thread2, NULL); 54 | pthread_join(thread3, NULL); 55 | 56 | finish_time = time(NULL); 57 | printf("With 4 threads, it takes %ld seconds to gen a random number = %lu\n", finish_time - start_time, sum); 58 | } 59 | -------------------------------------------------------------------------------- /Bai 8/Bai_tap/wrapper/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | gcc wrapper_function_file.c wrapper_function_file.h wrapper_test.c -o t -pthread 3 | clean: 4 | rm -f t -------------------------------------------------------------------------------- /Bai 8/Bai_tap/wrapper/README.txt: -------------------------------------------------------------------------------- 1 | description: 2 | a process create 2 thread write to a file using mutex to synchronize 3 | 4 | how to run ? 5 | 1. make 6 | 2. ./t -------------------------------------------------------------------------------- /Bai 8/Bai_tap/wrapper/wrapper_function_file.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "wrapper_function_file.h" 5 | 6 | int open_file() 7 | { 8 | if((fp = fopen(name_file , "w+")) == NULL ) 9 | { 10 | return -1; 11 | } 12 | pthread_mutex_unlock(&lock); 13 | } 14 | 15 | 16 | int read_file(char *buffer , int nsize ) 17 | { 18 | char c ; 19 | while( ( nsize-- ) && ((c = fgetc(fp)) != EOF)) 20 | { 21 | *buffer = c; 22 | buffer ++; 23 | } 24 | buffer = '\0'; 25 | } 26 | int write_file(char *buffer , int nsize) 27 | { 28 | pthread_mutex_lock(&lock); 29 | int nsi = strlen(buffer); 30 | while(nsi --) 31 | { 32 | fputc(*buffer , fp); 33 | buffer ++; 34 | } 35 | 36 | pthread_mutex_unlock(&lock); 37 | } 38 | int destroy_wrapper() 39 | { 40 | fclose(fp); 41 | pthread_mutex_destroy(&lock); 42 | } 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /Bai 8/Bai_tap/wrapper/wrapper_function_file.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | static char *name_file = "wrapper_file_function.txt"; 4 | static FILE *fp; 5 | pthread_mutex_t lock; 6 | 7 | 8 | 9 | int open_file(); 10 | int read_file(char *buffer , int nsize); 11 | int write_file(char *buffer , int nsize); 12 | int destroy_wrapper(); 13 | -------------------------------------------------------------------------------- /Bai 8/Bai_tap/wrapper/wrapper_test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "wrapper_function_file.h" 4 | 5 | pthread_t th1 , th2; 6 | void *test(void *st) 7 | { 8 | char *s = (char *)st; 9 | write_file(s, 100); 10 | return (void*)NULL; 11 | } 12 | int main() 13 | { 14 | open_file() ; 15 | pthread_create(&th1 , NULL , test , "vu hai long thread vu hai long thread 1 vu hai long thread 1\n"); 16 | pthread_create(&th2 , NULL , test , "vu hai long thread 2 vu hai long thread 2 vu hai long thread 2\n"); 17 | 18 | 19 | pthread_join(th1 , NULL); 20 | pthread_join(th2 , NULL); 21 | destroy_wrapper(); 22 | } 23 | -------------------------------------------------------------------------------- /Bai 8/Lập trình multithread.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 8/Lập trình multithread.pptx -------------------------------------------------------------------------------- /Bai 8/sample_code.txt: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include //Header file for sleep(). man 3 sleep for details. 4 | #include 5 | 6 | // A normal C function that is executed as a thread 7 | // when its name is specified in pthread_create() 8 | void *myThreadFun(void *vargp) 9 | { 10 | sleep(1); 11 | printf("Printing GeeksQuiz from Thread \n"); 12 | return NULL; 13 | } 14 | 15 | int main() 16 | { 17 | pthread_t thread_id; 18 | printf("Before Thread\n"); 19 | pthread_create(&thread_id, NULL, myThreadFun, NULL); 20 | pthread_join(thread_id, NULL); 21 | printf("After Thread\n"); 22 | exit(0); 23 | } 24 | 25 | // C program to demonstrate working of Semaphores 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | sem_t mutex; 32 | 33 | void* thread(void* arg) 34 | { 35 | //wait 36 | sem_wait(&mutex); 37 | printf("\nEntered..\n"); 38 | 39 | //critical section 40 | sleep(4); 41 | 42 | //signal 43 | printf("\nJust Exiting...\n"); 44 | sem_post(&mutex); 45 | } 46 | 47 | 48 | int main() 49 | { 50 | sem_init(&mutex, 0, 1); 51 | pthread_t t1,t2; 52 | pthread_create(&t1,NULL,thread,NULL); 53 | sleep(2); 54 | pthread_create(&t2,NULL,thread,NULL); 55 | pthread_join(t1,NULL); 56 | pthread_join(t2,NULL); 57 | sem_destroy(&mutex); 58 | return 0; 59 | } 60 | 61 | 62 | pthread_t tid[2]; 63 | int counter; 64 | 65 | void* doSomeThing(void *arg) 66 | { 67 | unsigned long i = 0; 68 | counter += 1; 69 | printf("\n Job %d started\n", counter); 70 | 71 | for(i=0; i<(0xFFFFFFFF);i++); 72 | printf("\n Job %d finished\n", counter); 73 | 74 | return NULL; 75 | } 76 | 77 | int main(void) 78 | { 79 | int i = 0; 80 | int err; 81 | 82 | while(i < 2) 83 | { 84 | err = pthread_create(&(tid[i]), NULL, &doSomeThing, NULL); 85 | if (err != 0) 86 | printf("\ncan't create thread :[%s]", strerror(err)); 87 | i++; 88 | } 89 | 90 | pthread_join(tid[0], NULL); 91 | pthread_join(tid[1], NULL); 92 | 93 | return 0; 94 | } -------------------------------------------------------------------------------- /Bai 9/Bai_tap_buoi7/send_file/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY:clean all 2 | 3 | FLAGS:=-pthread -g 4 | all :server_sample.c client_sample.c 5 | gcc $(FLAGS) server_sample.c -o s 6 | gcc $(FLAGS) client_sample.c -o c 7 | 8 | *.o:*.c 9 | gcc -c $< -o $@ 10 | clean: 11 | rm -f *.o 12 | 13 | -------------------------------------------------------------------------------- /Bai 9/Bai_tap_buoi7/send_file/README.txt: -------------------------------------------------------------------------------- 1 | description: 2 | socket 3 | a program comunicate between client and server 4 | 5 | how to run ? 6 | 1 make 7 | 2. ./s 8 | 3. ./c -------------------------------------------------------------------------------- /Bai 9/Bai_tap_buoi7/send_file/client_sample.c: -------------------------------------------------------------------------------- 1 | // Client side C/C++ program to demonstrate Socket programming 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #define PORT 8080 10 | 11 | int main(int argc, char const *argv[]) 12 | { 13 | struct sockaddr_in address; 14 | int sock = 0, valread; 15 | struct sockaddr_in serv_addr; 16 | char *hello = "Hello from client"; 17 | char buffer[1024] = {0}; 18 | if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) 19 | { 20 | printf("\n Socket creation error \n"); 21 | return -1; 22 | } 23 | 24 | memset(&serv_addr, '0', sizeof(serv_addr)); 25 | 26 | serv_addr.sin_family = AF_INET; 27 | serv_addr.sin_port = htons(PORT); 28 | 29 | // Convert IPv4 and IPv6 addresses from text to binary form 30 | if(inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr)<=0) 31 | { 32 | printf("\nInvalid address/ Address not supported \n"); 33 | return -1; 34 | } 35 | 36 | if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) 37 | return -1; 38 | } 39 | send(sock , hello , strlen(hello) , 0 ); 40 | printf("Hello message sent\n"); 41 | valread = read( sock , buffer, 1024); 42 | printf("%s\n",buffer ); 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /Bai 9/Bai_tap_buoi7/send_file/server_sample.c: -------------------------------------------------------------------------------- 1 | // Server side C/C++ program to demonstrate Socket programming 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #define PORT 8080 9 | int main(int argc, char const *argv[]) 10 | { 11 | int server_fd, new_socket, valread; 12 | struct sockaddr_in address; 13 | int opt = 1; 14 | int addrlen = sizeof(address); 15 | char buffer[1024] = {0}; 16 | char *hello = "Hello from server"; 17 | 18 | // Creating socket file descriptor 19 | if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) 20 | { 21 | perror("socket failed"); 22 | exit(EXIT_FAILURE); 23 | } 24 | 25 | // Forcefully attaching socket to the port 8080 26 | if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, 27 | &opt, sizeof(opt))) 28 | { 29 | perror("setsockopt"); 30 | exit(EXIT_FAILURE); 31 | } 32 | address.sin_family = AF_INET; 33 | address.sin_addr.s_addr = INADDR_ANY; 34 | address.sin_port = htons( PORT ); 35 | 36 | // Forcefully attaching socket to the port 8080 37 | if (bind(server_fd, (struct sockaddr *)&address, 38 | sizeof(address))<0) 39 | { 40 | perror("bind failed"); 41 | exit(EXIT_FAILURE); 42 | } 43 | if (listen(server_fd, 3) < 0) 44 | { 45 | perror("listen"); 46 | exit(EXIT_FAILURE); 47 | } 48 | if ((new_socket = accept(server_fd, (struct sockaddr *)&address, 49 | (socklen_t*)&addrlen))<0) 50 | { 51 | perror("accept"); 52 | exit(EXIT_FAILURE); 53 | } 54 | valread = read( new_socket , buffer, 1024); 55 | printf("%s\n",buffer ); 56 | send(new_socket , hello , strlen(hello) , 0 ); 57 | printf("Hello message sent\n"); 58 | return 0; 59 | } 60 | -------------------------------------------------------------------------------- /Bai 9/Lập trình với socket.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai 9/Lập trình với socket.pptx -------------------------------------------------------------------------------- /Bai 9/sample_code/client_server_sample/client.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | void main() 13 | { 14 | int sockfd = -1; 15 | struct sockaddr_in server_addr; 16 | char recv_buffer[1024]; 17 | time_t ticks; 18 | 19 | memset(recv_buffer, 0, sizeof(recv_buffer)); 20 | memset(&server_addr, 0, sizeof(server_addr)); 21 | 22 | sockfd = socket(AF_INET, SOCK_STREAM, 0); 23 | server_addr.sin_family = AF_INET; 24 | server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); 25 | server_addr.sin_port = htons(5000); 26 | 27 | bind(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr)); 28 | if(connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == 0) { 29 | read(sockfd, recv_buffer, sizeof(recv_buffer)-1); 30 | printf("\n%s\n", recv_buffer); 31 | } 32 | 33 | close(sockfd); 34 | } -------------------------------------------------------------------------------- /Bai 9/sample_code/client_server_sample/server.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | void main() 13 | { 14 | int listenfd = -1; 15 | int connfd = -1; 16 | struct sockaddr_in server_addr; 17 | char send_buffer[1024]; 18 | time_t ticks; 19 | 20 | memset(send_buffer, 0, sizeof(send_buffer)); 21 | memset(&server_addr, 0, sizeof(server_addr)); 22 | 23 | listenfd = socket(AF_INET, SOCK_STREAM, 0); 24 | server_addr.sin_family = AF_INET; 25 | server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); 26 | server_addr.sin_port = htons(5000); 27 | 28 | bind(listenfd, (struct sockaddr*)&server_addr, sizeof(server_addr)); 29 | listen(listenfd, 10); 30 | 31 | while(1) { 32 | connfd = accept(listenfd, (struct sockaddr*)NULL, NULL); 33 | ticks = time(NULL); 34 | sprintf(send_buffer, "Server reply %s", ctime(&ticks)); 35 | write(connfd, send_buffer, strlen(send_buffer)); 36 | close(connfd); 37 | } 38 | close(listenfd); 39 | } -------------------------------------------------------------------------------- /Bai23 Helloworld_kernel_module/Hello world kernel module.mm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /Bai23 Helloworld_kernel_module/Hello world kernel module.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Bai23 Helloworld_kernel_module/Hello world kernel module.pptx -------------------------------------------------------------------------------- /Bai23 Helloworld_kernel_module/led_driver/Makefile: -------------------------------------------------------------------------------- 1 | obj-m += led.o 2 | 3 | all: 4 | make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules 5 | 6 | clean: 7 | make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean 8 | -------------------------------------------------------------------------------- /Bai23 Helloworld_kernel_module/led_driver/README.txt: -------------------------------------------------------------------------------- 1 | description: 2 | driver control led build-in (green) on orangepi zero board . 3 | turn on led when user insmod driver to system 4 | turn off when rmmod driver 5 | 6 | how to run ? 7 | 1. make all 8 | 2 . check led status on board orangepi zeros 9 | 10 | note LED GREEN is PA17 pin -------------------------------------------------------------------------------- /Bai23 Helloworld_kernel_module/led_driver/debug.log: -------------------------------------------------------------------------------- 1 | [0816/163802.812:ERROR:registration_protocol_win.cc(131)] TransactNamedPipe: The pipe has been ended. (0x6D) 2 | -------------------------------------------------------------------------------- /Bai23 Helloworld_kernel_module/led_driver/led.c: -------------------------------------------------------------------------------- 1 | #include /* Needed by all modules */ 2 | #include /* Needed for KERN_INFO */ 3 | #include 4 | #include 5 | #include 6 | 7 | #define GPIO_ADDR_BASE 0x44E07000 8 | #define ADDR_SIZE (0x1000) 9 | #define GPIO_SETDATAOUT_OFFSET 0x194 10 | #define GPIO_CLEARDATAOUT_OFFSET 0x190 11 | #define GPIO_OE_OFFSET 0x134 12 | #define LED ~(1 << 31) 13 | #define DATA_OUT (1 << 31) 14 | 15 | void __iomem *base_addr; 16 | struct timer_list my_timer; 17 | unsigned int count = 0; 18 | 19 | static void timer_function(unsigned long data){ 20 | if ((count % 2) == 0) 21 | writel_relaxed(DATA_OUT, base_addr + GPIO_SETDATAOUT_OFFSET); 22 | else 23 | writel_relaxed(DATA_OUT, base_addr + GPIO_CLEARDATAOUT_OFFSET); 24 | 25 | count++; 26 | mod_timer(&my_timer, jiffies + HZ); 27 | } 28 | 29 | int init_module(void) 30 | { 31 | uint32_t reg_data = 0; 32 | 33 | base_addr = ioremap(GPIO_ADDR_BASE, ADDR_SIZE); 34 | 35 | reg_data = readl_relaxed(base_addr + GPIO_OE_OFFSET); 36 | reg_data &= LED; 37 | writel_relaxed(reg_data, base_addr + GPIO_OE_OFFSET); 38 | 39 | init_timer(&my_timer); 40 | my_timer.expires = jiffies + HZ; 41 | my_timer.function = timer_function; 42 | my_timer.data = 0; 43 | add_timer(&my_timer); 44 | 45 | return 0; 46 | } 47 | 48 | void cleanup_module(void) 49 | { 50 | del_timer(&my_timer); 51 | } 52 | 53 | MODULE_LICENSE("GPL"); 54 | MODULE_AUTHOR("Phu Luu An"); 55 | MODULE_DESCRIPTION("Hello world kernel module"); 56 | -------------------------------------------------------------------------------- /Bai23 Helloworld_kernel_module/outline.txt: -------------------------------------------------------------------------------- 1 | Agenda 2 | Introduction 3 | Can extend kernel code when needed 4 | Interact with kernel to become only one kernel process 5 | Code instruction has same priority with kernel 6 | Setup environment for development 7 | Hardware 8 | Board 9 | Pi 10 | Good support from community 11 | Poor hardware document 12 | Udoo 13 | Good hardware document 14 | Should use Udoo for development 15 | Firmware 16 | Download firmware from main page 17 | https://www.raspberrypi.org/downloads/raspbian/ 18 | Install firmware 19 | Install Window's tool to write firmware for sdcard 20 | https://www.raspberrypi.org/documentation/installation/installing-images/README.md 21 | Plug in sdcard, power cable, mouse, keyboard and monitor for Pi 22 | Connect PC with board 23 | Install MobaXterm for PC 24 | https://mobaxterm.mobatek.net/ 25 | Setup network to connect Pi with PC 26 | Set static IP for Pi and PC 27 | Install ssh tool for Pi 28 | Create new session in MobaXterm to ssh with Pi 29 | Install kernel header in Pi 30 | It include all source header need to develop kernel module 31 | It is generate when they build kernel image 32 | Each kernel instance has only one kernel header 33 | sudo apt-get install raspberrypi-kernel-headers 34 | Create Hello world kernel module 35 | Source code 36 | Make file 37 | Load and test result 38 | Home work -------------------------------------------------------------------------------- /Bai23 Helloworld_kernel_module/sample_code/Bat_tat_led.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | //static int *gpio_func = (int*) 0xF2200004; 6 | //static int *gpio_set = (int*) 0xF220001C; 7 | 8 | #define GPIO_ADDR_BASE 0x20200000 9 | 10 | 11 | unsigned int *gpio_base; 12 | unsigned int *set_mode; 13 | unsigned int *set_high; 14 | unsigned int *set_low; 15 | 16 | int __init init_module(void){ 17 | printk(KERN_INFO "Hello World!\n"); 18 | gpio_base = (unsigned int *)ioremap(GPIO_ADDR_BASE,0x100); 19 | 20 | set_mode = (unsigned int *)gpio_base+1; 21 | (*set_mode) = ((*set_mode)&(~(7<<21)))|(1<<21); 22 | 23 | 24 | set_high = (unsigned int *)(gpio_base+7); 25 | (*set_high) = 1<<17; 26 | 27 | return 0; 28 | } 29 | 30 | void __exit cleanup_module(void){ 31 | 32 | printk(KERN_INFO "Goodbye!\n"); 33 | 34 | set_low = (unsigned int *)(gpio_base+10); 35 | (*set_low) = 1<<17; 36 | } 37 | 38 | -------------------------------------------------------------------------------- /Bai23 Helloworld_kernel_module/sample_code/Makefile: -------------------------------------------------------------------------------- 1 | obj-m += hello_world.o 2 | 3 | all: 4 | make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules 5 | 6 | clean: 7 | make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean -------------------------------------------------------------------------------- /Bai23 Helloworld_kernel_module/sample_code/README.txt: -------------------------------------------------------------------------------- 1 | description: 2 | driver control GPIO on raspberry pi 3B+ board 3 | turn on led(external led) when user insmod driver to system 4 | turn off when rmmod driver 5 | 6 | how to run ? 7 | 1. make all 8 | 2. check led status on board orangepi zeros 9 | 10 | note LED is pin GPIO17 ON raspberry pi 3B+ 11 | h1ff4He7 -------------------------------------------------------------------------------- /Bai23 Helloworld_kernel_module/sample_code/hello_world.c: -------------------------------------------------------------------------------- 1 | /* 2 | * hello_world.c - The simplest kernel module. 3 | */ 4 | #include /* Needed by all modules */ 5 | #include /* Needed for KERN_INFO */ 6 | 7 | static int __init init_module(void) 8 | { 9 | printk(KERN_INFO "Hello world 1.\n"); 10 | 11 | /* 12 | * A non 0 return means init_module failed; module can't be loaded. 13 | */ 14 | return 0; 15 | } 16 | 17 | static void __exit cleanup_module(void) 18 | { 19 | printk(KERN_INFO "Goodbye world 1.\n"); 20 | } 21 | 22 | module_init(init_module); 23 | module_exit(cleanup_module); -------------------------------------------------------------------------------- /Linux_embedded_Aug.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Linux_embedded_Aug.xls -------------------------------------------------------------------------------- /Tương tác với hệ điều hành Linux.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/Tương tác với hệ điều hành Linux.docx -------------------------------------------------------------------------------- /bai 4/Character device driver.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/bai 4/Character device driver.pptx -------------------------------------------------------------------------------- /bai 4/Sample_code/led_driver/Makefile: -------------------------------------------------------------------------------- 1 | PWD := $(shell pwd) 2 | KERNEL := /home/phula/training/source_code_download/bbb_old_source/linux/ 3 | CROSS := /opt/gcc-arm-linux/bin/arm-linux-gnueabihf- 4 | obj-m += exam_cdev.o 5 | 6 | all: 7 | make ARCH=arm CROSS_COMPILE=$(CROSS) -C $(KERNEL) SUBDIRS=$(PWD) modules 8 | clean: 9 | make -C $(KERNEL) SUBDIRS=$(PWD) clean 10 | -------------------------------------------------------------------------------- /bai 4/Sample_code/led_driver/exam_cdev.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | 10 | #define DEVICE 5 11 | #define AUTHOR "Phu Luu An luuanphu@gmail.com" 12 | #define DESC "A example character device driver" 13 | #define DEVICE_NAME "led_30" 14 | 15 | #define MAGIC_NO 100 16 | #define SEND_DATA_CMD _IOW(MAGIC_NO, 1, char*) 17 | #define IOCTL_DATA_LEN 1024 18 | 19 | #define GPIO_ADDR_BASE 0x44E07000 20 | #define ADDR_SIZE (0x1000) 21 | #define GPIO_SETDATAOUT_OFFSET 0x194 22 | #define GPIO_CLEARDATAOUT_OFFSET 0x190 23 | #define DATA_IN_REG 0x138 24 | #define GPIO_OE_OFFSET 0x134 25 | #define LED ~(1 << 30) 26 | #define DATA_OUT (1 << 30) 27 | 28 | static dev_t dev_num; 29 | struct class *my_class; 30 | struct device *my_dev; 31 | struct cdev my_cdev; 32 | char data[4096]; 33 | bool first_oper; 34 | char config_data[IOCTL_DATA_LEN]; 35 | 36 | void __iomem *base_addr; 37 | uint32_t reg_data; 38 | uint32_t old_pin_mode; 39 | 40 | static int my_open(struct inode *inode, struct file *file) 41 | { 42 | printk(KERN_INFO "PhuLA %s, %d\n", __func__, __LINE__); 43 | reg_data = readl_relaxed(base_addr + GPIO_OE_OFFSET); 44 | old_pin_mode = reg_data; 45 | reg_data &= LED; 46 | writel_relaxed(reg_data, base_addr + GPIO_OE_OFFSET); 47 | first_oper = true; 48 | 49 | return 0; 50 | } 51 | 52 | static int my_close(struct inode *inode, struct file *file) 53 | { 54 | printk(KERN_INFO "PhuLA %s, %d\n", __func__, __LINE__); 55 | reg_data = old_pin_mode; 56 | writel_relaxed(reg_data, base_addr + GPIO_OE_OFFSET); 57 | return 0; 58 | } 59 | 60 | static ssize_t my_read(struct file *flip, char __user *user_buf, size_t len, loff_t *offs) 61 | { 62 | char *data = NULL; 63 | printk(KERN_INFO "PhuLA %s, %d\n", __func__, __LINE__); 64 | 65 | data = kmalloc(len, GFP_KERNEL); 66 | memset(data, 0, len); 67 | reg_data = readl_relaxed(base_addr + DATA_IN_REG); 68 | data[0] = ((reg_data & LED) >> 30) + 48; 69 | copy_to_user(user_buf, data, len); 70 | 71 | if (true == first_oper) { 72 | first_oper = false; 73 | return 1; 74 | } 75 | else 76 | return 0; 77 | } 78 | 79 | static ssize_t my_write(struct file *flip, const char __user *user_buf, size_t len, loff_t *offs) 80 | { 81 | char data = '\0'; 82 | printk(KERN_INFO "PhuLA %s, %d\n", __func__, __LINE__); 83 | 84 | copy_from_user(&data, &user_buf[0], sizeof(data)); 85 | switch (data) { 86 | case '1': 87 | writel_relaxed(DATA_OUT, base_addr + GPIO_SETDATAOUT_OFFSET); 88 | break; 89 | case '0': 90 | writel_relaxed(DATA_OUT, base_addr + GPIO_CLEARDATAOUT_OFFSET); 91 | break; 92 | default: 93 | printk(KERN_INFO "PhuLA un-support operation"); 94 | }; 95 | 96 | return len; 97 | } 98 | 99 | static long my_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) 100 | { 101 | switch (cmd) { 102 | case SEND_DATA_CMD: 103 | memset(config_data, 0, IOCTL_DATA_LEN); 104 | copy_from_user(config_data, (char*)arg, IOCTL_DATA_LEN); 105 | printk(KERN_INFO "PhuLA %s, %d, ioctl message = %s\n", __func__, __LINE__, config_data); 106 | break; 107 | 108 | default: 109 | return -ENOTTY; 110 | } 111 | 112 | return 0; 113 | } 114 | 115 | static struct file_operations fops = { 116 | .owner = THIS_MODULE, 117 | .open = my_open, 118 | .release = my_close, 119 | .read = my_read, 120 | .write = my_write, 121 | .unlocked_ioctl = my_ioctl, 122 | }; 123 | 124 | static int __init func_init(void) 125 | { 126 | memset(data, 0, sizeof(data)); 127 | 128 | alloc_chrdev_region(&dev_num, 0, DEVICE, DEVICE_NAME); 129 | my_class = class_create(THIS_MODULE, DEVICE_NAME); 130 | cdev_init(&my_cdev, &fops); 131 | my_cdev.owner = THIS_MODULE; 132 | cdev_add(&my_cdev, dev_num, 1); 133 | device_create(my_class, NULL, dev_num, NULL, DEVICE_NAME); 134 | 135 | base_addr = ioremap(GPIO_ADDR_BASE, ADDR_SIZE); 136 | 137 | return 0; 138 | } 139 | 140 | static void __exit func_exit(void) 141 | { 142 | cdev_del(&my_cdev); 143 | device_destroy(my_class, dev_num); 144 | class_destroy(my_class); 145 | unregister_chrdev(dev_num, DEVICE_NAME); 146 | } 147 | 148 | module_init(func_init); 149 | module_exit(func_exit); 150 | 151 | MODULE_LICENSE("GPL"); 152 | MODULE_AUTHOR(AUTHOR); 153 | MODULE_DESCRIPTION(DESC); 154 | MODULE_VERSION("0.01"); 155 | 156 | -------------------------------------------------------------------------------- /bai 4/Sample_code/loopback/Makefile: -------------------------------------------------------------------------------- 1 | obj-m:=exam_cdev.o 2 | 3 | all: 4 | make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules 5 | 6 | clean: 7 | make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean 8 | -------------------------------------------------------------------------------- /bai 4/Sample_code/loopback/exam_cdev.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #define DEVICE 5 9 | #define AUTHOR "Phu Luu An luuanphu@gmail.com" 10 | #define DESC "A example character device driver" 11 | #define DEVICE_NAME "char_dd" 12 | 13 | #define MAGIC_NO 100 14 | #define SEND_DATA_CMD _IOW(MAGIC_NO, 1, char*) 15 | #define IOCTL_DATA_LEN 1024 16 | 17 | static dev_t dev_num; 18 | struct class *my_class; 19 | struct device *my_dev; 20 | struct cdev my_cdev; 21 | char data[4096]; 22 | bool first_oper; 23 | char config_data[IOCTL_DATA_LEN]; 24 | 25 | static int my_open(struct inode *inode, struct file *file) 26 | { 27 | printk(KERN_INFO "PhuLA %s, %d\n", __func__, __LINE__); 28 | first_oper = true; 29 | 30 | return 0; 31 | } 32 | 33 | static int my_close(struct inode *inode, struct file *file) 34 | { 35 | printk(KERN_INFO "PhuLA %s, %d\n", __func__, __LINE__); 36 | 37 | return 0; 38 | } 39 | 40 | static ssize_t my_read(struct file *flip, char __user *user_buf, size_t len, loff_t *offs) 41 | { 42 | int read_len = 0; 43 | 44 | printk(KERN_INFO "PhuLA %s, %d\n", __func__, __LINE__); 45 | if (true != first_oper) 46 | return 0; 47 | 48 | if (len > strlen(data)) 49 | read_len = strlen(data); 50 | else 51 | read_len = len; 52 | 53 | copy_to_user(user_buf, data, read_len); 54 | first_oper = false; 55 | 56 | return read_len; 57 | } 58 | 59 | static ssize_t my_write(struct file *flip, const char __user *user_buf, size_t len, loff_t *offs) 60 | { 61 | printk(KERN_INFO "PhuLA %s, %d\n", __func__, __LINE__); 62 | 63 | if (true != first_oper) 64 | return 0; 65 | 66 | memset(data, 0, sizeof(data)); 67 | copy_from_user(data, user_buf, len); 68 | first_oper = false; 69 | 70 | return len; 71 | } 72 | 73 | static long my_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) 74 | { 75 | switch (cmd) { 76 | case SEND_DATA_CMD: 77 | memset(config_data, 0, IOCTL_DATA_LEN); 78 | copy_from_user(config_data, (char*)arg, IOCTL_DATA_LEN); 79 | printk(KERN_INFO "PhuLA %s, %d, ioctl message = %s\n", __func__, __LINE__, config_data); 80 | break; 81 | 82 | default: 83 | return -ENOTTY; 84 | } 85 | 86 | return 0; 87 | } 88 | 89 | static struct file_operations fops = { 90 | .owner = THIS_MODULE, 91 | .open = my_open, 92 | .release = my_close, 93 | .read = my_read, 94 | .write = my_write, 95 | .unlocked_ioctl = my_ioctl, 96 | }; 97 | 98 | static int __init func_init(void) 99 | { 100 | memset(data, 0, sizeof(data)); 101 | 102 | alloc_chrdev_region(&dev_num, 0, DEVICE, DEVICE_NAME); 103 | my_class = class_create(THIS_MODULE, DEVICE_NAME); 104 | cdev_init(&my_cdev, &fops); 105 | my_cdev.owner = THIS_MODULE; 106 | cdev_add(&my_cdev, dev_num, 1); 107 | device_create(my_class, NULL, dev_num, NULL, DEVICE_NAME); 108 | 109 | return 0; 110 | } 111 | 112 | static void __exit func_exit(void) 113 | { 114 | cdev_del(&my_cdev); 115 | device_destroy(my_class, dev_num); 116 | class_destroy(my_class); 117 | unregister_chrdev(dev_num, DEVICE_NAME); 118 | } 119 | 120 | module_init(func_init); 121 | module_exit(func_exit); 122 | 123 | MODULE_LICENSE("GPL"); 124 | MODULE_AUTHOR(AUTHOR); 125 | MODULE_DESCRIPTION(DESC); 126 | MODULE_VERSION("0.01"); 127 | 128 | -------------------------------------------------------------------------------- /bai 4/Sample_code/loopback/test_character.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #define FILE "/dev/char_dd" 10 | #define MAGIC_NO 100 11 | #define SEND_DATA_CMD _IOW(MAGIC_NO, 1, char*) 12 | #define IOCTL_DATA_LEN 1024 13 | 14 | char config_data[IOCTL_DATA_LEN]; 15 | char data[4096]; 16 | 17 | int main() 18 | { 19 | int fd = -1; 20 | int menu = 0; 21 | 22 | while (1) { 23 | printf("\nPress 1 to write data to file."); 24 | printf("\nPress 2 to read data from file."); 25 | printf("\nPress 3 to send an IOCTL message to file."); 26 | printf("\nPress 4 to exit program.\n"); 27 | fflush(stdin); 28 | scanf("%d", &menu); 29 | 30 | switch (menu) { 31 | case 1: 32 | printf("\nInput data to write: "); 33 | fflush(stdin); 34 | memset(data, 0, sizeof(data)); 35 | scanf("%s", data); 36 | fd = open(FILE, O_RDWR); 37 | write(fd, data, strlen(data)); 38 | close(fd); 39 | break; 40 | case 2: 41 | memset(data, 0, sizeof(data)); 42 | fd = open(FILE, O_RDWR); 43 | read(fd, data, sizeof(data)); 44 | close(fd); 45 | printf("\nData reading from file: %s\n", data); 46 | break; 47 | case 3: 48 | memset(config_data, 0, IOCTL_DATA_LEN); 49 | strcpy(config_data, "Hello world"); 50 | fd = open(FILE, O_RDWR); 51 | ioctl(fd, SEND_DATA_CMD, &config_data); 52 | close(fd); 53 | break; 54 | case 4: 55 | return 0; 56 | default: 57 | printf("\nOperation %d is not supported.\n", menu); 58 | return 0; 59 | } 60 | } 61 | 62 | return 0; 63 | } 64 | -------------------------------------------------------------------------------- /bai 4/outline.txt: -------------------------------------------------------------------------------- 1 | Agenda 2 | Objective 3 | Driver main functions 4 | Service user space 5 | Call service from kernel space 6 | Working directly with hardware 7 | Character device 8 | Cây phân cấp device 9 | Character device 10 | Block device 11 | Network device 12 | Device file 13 | All device file place in /dev folder 14 | Major number 15 | Minor number 16 | Create a device file 17 | By udev 18 | By mknod command 19 | By device driver 20 | Device operation 21 | open 22 | close 23 | read 24 | write 25 | ioctl 26 | Implement file operation in driver 27 | static int dev_open(struct inode *inodep, struct file *filep) 28 | static int dev_close(struct inode *inodep, struct file *filep) 29 | static ssize_t dev_read(struct file*filep, char __user *buf, size_t len, loff_t *offset) 30 | static ssize_t dev_write(struct file*filep, const char __user *buf, size_t len, loff_t *offset) 31 | unsigned long copy_from_user(void *to, const void __user *from, unsigned long n); 32 | unsigned long copy_to_user(void __user *to, const void *from, unsigned long n); 33 | Register file operation with kernel 34 | Basic steps of character driver 35 | Define file operation 36 | Define other interface 37 | Initialize private resource 38 | Create device file 39 | Register file operation and other interface 40 | Create device file 41 | void cdev_init ( struct cdev * cdev, const struct file_operations * fops); 42 | int cdev_add ( struct cdev * p, dev_t dev, unsigned count); 43 | struct class *class_create(struct module *owner, const char *name); 44 | struct device *device_create(struct class *class, struct device *parent, dev_t devt, const char *fmt, ); 45 | Destroy device file 46 | void cdev_del(struct cdev *); 47 | void device_destroy(struct class *class, dev_t devt); 48 | void class_destroy ( struct class * cls); 49 | void unregister_chrdev_region(dev_t from, unsigned count); 50 | Compare create and destroy a device 51 | Example code 52 | Practice 53 | Ioctl 54 | Driver code 55 | static long dev_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) 56 | User space code 57 | #include 58 | int ioctl(int fd, unsigned long request, ...); 59 | Example code 60 | Home work -------------------------------------------------------------------------------- /misc_code/linux_booting_sequence/linux_boot_sequence.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phuthodien/training_linux_embedded_v2/815580600e6bc7a2f04817d08631fa9f5c48c87f/misc_code/linux_booting_sequence/linux_boot_sequence.xlsx -------------------------------------------------------------------------------- /misc_code/serial/test_serial.c: -------------------------------------------------------------------------------- 1 | /* 2 | * test_serial.c 3 | * Sample application to read/write data from serial device. 4 | * Path to serial device is /dev/ttyUSB0 5 | * This program have to run with root permission. 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | int 32 | set_interface_attribs (int fd, int speed, int parity) 33 | { 34 | struct termios tty; 35 | int status; 36 | if (tcgetattr (fd, &tty) != 0) 37 | { 38 | printf("error %d from tcgetattr", errno); 39 | return -1; 40 | } 41 | 42 | cfsetospeed (&tty, speed); 43 | cfsetispeed (&tty, speed); 44 | 45 | tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; // 8-bit chars 46 | tty.c_iflag &= ~IGNBRK; // disable break processing 47 | tty.c_lflag = 0; // no signaling chars, no echo, 48 | // no canonical processing 49 | tty.c_oflag = 0; // no remapping, no delays 50 | tty.c_cc[VMIN] = 0; // read doesn't block 51 | tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout 52 | 53 | tty.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl 54 | 55 | tty.c_cflag |= (CLOCAL | CREAD);// ignore modem controls, 56 | // enable reading 57 | tty.c_cflag &= ~(PARENB | PARODD); // shut off parity 58 | tty.c_cflag |= parity; 59 | tty.c_cflag &= ~CSTOPB; 60 | tty.c_cflag &= ~CRTSCTS; 61 | 62 | //PhuLA set hardware flow control 63 | tty.c_cflag |= CRTSCTS; 64 | 65 | if (tcsetattr (fd, TCSANOW, &tty) != 0) 66 | { 67 | printf("error %d from tcsetattr", errno); 68 | return -1; 69 | } 70 | 71 | ioctl(fd, TIOCMGET, &status); 72 | ioctl(fd, TIOCMSET, &status); 73 | 74 | return 0; 75 | } 76 | 77 | void 78 | set_blocking(int fd, int should_block) 79 | { 80 | struct termios tty; 81 | memset (&tty, 0, sizeof tty); 82 | if (tcgetattr (fd, &tty) != 0) 83 | { 84 | printf("error %d from tggetattr", errno); 85 | return; 86 | } 87 | 88 | tty.c_cc[VMIN] = should_block ? 1 : 0; 89 | tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout 90 | 91 | if (tcsetattr (fd, TCSANOW, &tty) != 0) 92 | printf("error %d setting term attributes", errno); 93 | } 94 | 95 | void main() 96 | { 97 | char *portname = "/dev/ttyUSB0"; 98 | char buf[4098]; 99 | int n = 0; 100 | int fd = open (portname, O_RDWR | O_NOCTTY | O_SYNC); 101 | if (fd < 0) 102 | { 103 | printf("error %d opening %s: %s", errno, portname, strerror (errno)); 104 | return; 105 | } 106 | 107 | set_interface_attribs (fd, B115200, 0); // set speed to 115,200 bps, 8n1 (no parity) 108 | set_blocking (fd, 1); // set no blocking 109 | 110 | write (fd, "hello!\n", 7); // send 7 character greeting 111 | 112 | usleep ((7 + 25) * 100); // sleep enough to transmit the 7 plus 113 | // receive 25: approx 100 uS per char transmit 114 | 115 | while (1) { 116 | n = read(fd, buf, sizeof buf); 117 | if (n > 0) 118 | printf("%s", buf); 119 | n = 0; 120 | } 121 | return; 122 | } 123 | --------------------------------------------------------------------------------