Saturday, June 10, 2017

Bring up a microcontroller from scratch - Part 0

Hi guys,

After 5 years of enjoying playing with embedded system, I wanna demonstrate what I learned/experienced about microcontroller in this bring-up series.

The purpose of this series is not only the summary of myself but also help the other guys, especially students, can bring up the a mircocontroller from scratch, what I mean is nearly from scratch.

I will use Discovery kit from ST which consists of a Cortex M4 MCU and is quite common on the market.

Prerequisite:
- A Discovery Kit from ST, of course, I use it as an example, the concept should be similar to the other MCU.
-A PC, of course, I use an Linux environment for my convenience, you can use Window for your convenience, but you should prepare some equivalent tool which I list below
-A cross compiler for ARM Cortex M4, I used GCC which is quite popular in community, I believe that window variant is available.
-A loader software that helps you to load the code to microC.
-Last but not least, an eagerness to reinvent the wheel.

The method I use is try to approach the thing from theory, then analyze it, try it, apply it, fail, correct it and then loop the whole process.

Let get started

When purchasing an STM32F4DISCOVERY board, you often think of writing some led blinking program and then load to the board, there is some available toolsuites from the vendor that help you do the job. But this series is about building from scratch, isn't it? Let us review something from the university.


We 've already known that a computer work because it Fetch the instruction from the memory, then Decode the instruction into ALU operation, the eXcecute it (FDX cycle). All the cycle is done by CPU itself, what we have to do is just prepare the program which is the arrangement of instructions.

Basically, each type of computer have its own Instruction Set Architecture and yes, our development kit use ARM architecure, specifically, the Cortex M4 architecute, it has their own ISR which contains some instruction like "moving data to register", "adding content of 2 register",...

The computer just understands the instruction in the form of manchine code (binary code), but our programe is often (or always nowaday) written in higher level language such as C or Assembly code, so we should preprare a toolsuite which covert what we write in to machine code, I use gcc as I said before.

Regarding the toolsuite in embedded world, it often consists of a C compiler, an Assember, linker and a loader and might be a debugger.

For the compiler, assember, linker, I use arm-non-eabi-gcc toolchain, it is free. You can download it via the official page of ARM ( https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads )


A loader is a software that help you to load the machine code from your PC to memory of Microcontroller, it is often included in the software called debugger which have a feature "programming". I used openocd for this part. Please refer to http://openocd.org/

Once reading to this line, you should prepare enough tools for next parts of this series. If you have any trouble in installing above tools, please feel free to ask.

I believe you would also have a big picture of what I am going to do in this series.

In the next part, I will put the first step into MCU, it is about memory segmentation. It is very important but they are often omitted in university. Just relax yourself and waiting for the next part.

See you soon.

Friday, March 31, 2017

[Repost] Cô gái trên cầu Long Biên

Post lại từ ngày 6 tháng 1 năm 2017. Sau lần đi bộ trên cầu Long Biên trong chuyến đi Hà Nội

Ký sự thanh niên đi bộ qua cầu Long Biên:
Thanh niên đang tức tối về service của chả cá Lã Vọng liền đi lang thang đến đầu phố hàng cót, đua đòi mua ly nước + bịch khoai lắc cho giống local, ngồi thấy cây cầu, hỏi bé bán hàng lên cầu long biên như nào, bé chỉ đường kèm ánh mắt ái ngại cho mình. Thấy mình cầm bản đồ hn + nói giọng bắc, chắc bé nghĩ mình ở bản mới xuống miền xuôi đi chơi nên bé cũng lắc đầu ngao ngán mà chỉ đường cho đi. Đi đến 1/4 cây cầu, thấy cũng hơi xa, định quay về thì bỗng thấy bé (gái) đi trước, mình liền nới sải chân dài ra, chắc bé cũng sợ nên lấy đt ra gọi vu vơ. Đến khoảng 1/3 cầu thì mình mở lời "đi chung cho đỡ buồn bạn ơi" bé quay đầu lại cười và... ôi muệ ơi con gái nhà ai mà xinh thế <3 hỏi thăm qua loa vớ vẩn vài câu thì biết bạn ấy đi lên cầu tụ tập nướng ngô với bạn bè, bạn ý có mời mình tham gia chung cho vui, nhưng thấy cậu con trai đi cùng ko thiện chí lắm nên mình chữa ngựong "mình còn phải đi hết cây cầu này rồi về, các bạn cứ tự nhiên". Thật ếu có cái ngu nào bằng cái ngu sĩ diện, đường cầu còn hơn nửa đi sợ bỏ mie, sợ một phần giang hồ hiểm ác, sợ một phần vong ma hãm hại (nghe nói cầu long biên có lắm người tự tử). Vừa đi tay vừa nắm chặt cây xiên của bịch khoai lắc, có biến là sẵn sàng chơi ngay. Chưa kể ba lô còn nguyên củ tỏi merlin chưa dùng. Sau một hành trình dài nghĩ vu vơ cũng đã đến chân cầu bên kia (q long biên). Nghĩ giờ đi lại hết một lần cây cầu nữa để về lại hoàn kiếm chắc stress nặng. Nghĩ rồi thanh niên chạy đến 2 ông xe ôm, thấy mặt 2 ông hơi giống đại bàng trong phim cssh, tự hỏi "có khi nào ông này đang chạy rồi xử mình ko@@?" tay hắn vẫn cầm cây xiên mặc dù khoai hắn đã ăn hết rồi. Ông xe ôm chở qua cầu, hỏi han vớ vẩn gì đấy mới biết ông có quê ngoại ở sg. Lúc xuống xe ông còn chỉ dẫn tận tình đi hộ ntn để về phố Hàng Đường. Vậy mà thanh niên vẫn nắm chặt cây xiên @@! Hết rồi ạ.

Wednesday, March 29, 2017

Thread-safe and reentrant function

Trong lập trình, cụ thể trong embedded C domain, các thuộc tính của một function ngoài các arguments, giá trị return còn có 2 khái niệm nữa khá phức tạp là Synchonous/Asynchronous, reentrancy và threadsafe. Trong bài này mình tập trung nói về khái niệm reentrancy.

Nói một cách hàn lâm, một hàm được gọi là "thread safe" nếu nó bị interrupt giữa function và khi trở lại, nó vẫn safely hoạt động như mong đợi.

Ví dụ một vài hàm threadsafe:

int my_adder( int a , int b)
{
    return (a + b);
}

Hàm trên được gọi là threadsafe bởi vì dù bạn có interrupt nó ở đâu thì kết quả của my_adder(10,11) luôn luôn là 21.

Vậy hàm như thế nào được gọi là non safe. Mình sẽ ví dụ một use case cụ thể trong embedded về vấn đề threadsafe.

Giả sử mình cần viết ứng dụng hiển thị đồng hồ phút và giây. Mình có một timer đếm giây, mỗi giây timer sẽ được trigger và đếm tăng counter lên 1.

/* Start of File */
#include <somefile.h>

/* Global variable */
uint32_t count_second = 0;

/* define ISR for timer */ 
ISR void timer( void )
{
    if(count_second == 3600)
    {
        count_second = 0;
    }
    else
    {
        count_second = count_second+1;
    }
}

void show_clock( void );

void main( void )
{
    init_timer( some_configuration );
    init_uart( for_displaying_clock );
    while( 1 )
    {
        show_clock();
    }
}

void show_clock( void );
{
    uint32_t minute;
    uint32_t second;

    minute = count_second/60;

    /* Timer ISR may happen here */   

    second = count_second%60;
    printf(" It is %d:%d", minute, second");
}

/* End of File */

Bạn nghĩ chương trình trên chạy ổn chứ? Absolutely not,

Giả sử như biến count_second đang có giá trị là 59, theo như logic, thì kết quả đồng hồ phải chuyển từ ... 00:58  >>  00:59  >>  1:00  >>..., đúng không?

Đúng, theo như expectation thì đồng hồ phải hiển thị như vậy, nhưng vẫn có trường hợp, với code kiểu tiên, tôi dám chắc là các bạn từng viết chương trình này đã gặp những giá trị lạ n

00:58  >> 00:59 >> 00:00 > 1:00 tại sao lại có điều đó xảy ra.

Bạn hãy để ý dòng "/* Timer ISR may happen here */"

Lúc counter_second đang có giá trị là 59 thì minute=59/60 = 0;

lúc interrupt xảy ra, giá trị counter_second sẽ là 60 và 60%60 sẽ là 0 nên second sẽ là "00", khi chạy lệnh print, 2 giá trị minute và second sẽ là 0:00. Và hàm này (hàm show_clock) không được gọi là threadsafe, bởi vì khi nó bị ngắt và trở lại, nó đã không hoạt động đúng như mong đợi nữa. Vậy có cách nào để hàm trên trở thành threadsafe, có nhiều cách:

  • Cách #1: lưu giá trị biến toàn cục vào local variable, với cách này (tạm coi như lệnh gán là một lệnh trông thể bị interrupt), hàm này luôn đảm bảo 2 biến minute và second luôn đồng nhất với count_second và vấn đề trên sẽ được giải quyết.
void show_clock( void );{
    uint32_t minute;
    uint32_t second;



    uint32_t t_second_count;

    t_second_count = count_second;
      minute = count_second/60;

    /* Timer ISR may happen here */   

    second = count_second%60;
    printf(" It is %d:%d", minute, second");
}

  • Cách #2: ngắt interrupt tại nơi mà interrupt có thể làm sai lệch hoạt động của hàm, với cách này, interrupt sẽ không thể chen giữa 2 lệnh gán và sẽ không có cơ hội cho giá trị lạ xuất hiên.
 void show_clock( void );{
    uint32_t minute;
    uint32_t second;

    díable_interrupt( void );     minute = count_second/60;

    /* Timer ISR may NOT happen here */   

    second = count_second%60;
    enable_interrupt( void );

    printf(" It is %d:%d", minute, second");
}

Hi vọng các bạn có thể hiểu được phần nào về khái niệm threadsafe. Còn về reentrancy, khơi khó tưởng tượng hơn một chút.

Một function được gọi là reentrancy khi nó có thể gọi lại lần nữa trước khi kết thúc lần chạy đầu tiên.

Ví dụ mình có một hàm làm nhiệm vụ là double giá trị của một biến

#include "somefile.h"

uint32_t my_var=2;

void my_double( uint32_t *arg)
{
    uint32_t temp;
    temp = *arg;
    /*Interrupt may happen here*/
    temp = temp + *arg;
    *arg = temp;
}

ISR someInturrupt( void )
{
   my_double( &my_vả );
}

Hàm này sẽ được gọi trong hàm main mà trong một interrupt:

Giả sử giá trị của my var hiện tại đang là 2, trong trường hợp bình thường, hàm main gọi my_double( &my_var ) thì my_var sau đó phải có giá trị là 4. 

Nhưng không may, trong lúc đay chạy hàm my_double, một interrupt xảy ra và trong interrup, hàm my_double được gọi ngay giữa hàm ( như chú thích), lúc này, hàm inturrupt chạy xong và biến var có giá trị là 4, và temp của lần gọi đầu tiên có giá trị là 2 + với *my_var là 4, và cuối cùng, kết của của biến var là 6, đã mất đi ý nghĩa của hàm my_double.

cách giải quyết vấn đề trên cũng giống như thread safe là disable interuppt những chỗ có thể gây hư hại cho hàm my_double.

Và nhìn chung thì, hàm thread safe luôn luôn reentrant, nhưng hàm reentrant chưa chắc đã threadsafe. Vấn đề này các bạn có thể google thêm, mình chỉ cố gắng đưa ra khái niệm để các bạn hiểu được concept.

Trong thực tế, theo mình thấy thì người ta luôn cố gắng để function trở thành threadsafe hoặc reentrant nếu cần thiết, đương nhiên là chỉ nếu thôi, vì có những trường hợp reentrant là quá xa xỉ với một function, ví dụ như những function luôn chỉ được gọi một lần trong chương trình (initialization) chẳng hạn thì không cần reentrant, vì đâu có hàm nào gọi lại function ấy lần 2. Còn threadsafe,  rõ ràng là để đảm bảo tính đồng nhất (data consistency như trong ví dụ 1), thì phải cố gắng bảo vệ nhũng vùng data dùng chung để cho hàm trở thành threadsafe.

    

[Self Study] Haskell - day#0

Khi bế tắc, việc đầu tiên thanh niên nghĩ đến là học thứ gì đó mới mẻ và fun, và thanh niên đã nghĩ tới Haskell, một ngôn ngữ lập trình hướng hàm (Functional Programming Language), với cấu trúc khác hẳn các ngôn ngữ mà thanh niên hay dùng trong công việc, let him show his journey.
---
Environment:
Thanh niên học haskell trên môi trường linux (Arch linux)
---

Day0: Thanh niên tìm hiểu functional programming trên wiki, đọc sơ sơ để biết về nó, xong tìm hiểu overview về Haskel, tiếp tục thanh niên search từ khóa "learn haskell the hard way" và đọc từ trên xuống dưới.

http://yannesposito.com/Scratch/en/blog/Haskell-the-Hard-Way/#a-type-example

Vừa đọc, thanh niên vừa tìm cách cài tool "ghc" (Haskell compiler), "runhaskel" (run haskell như một script", ghci (haskell command line).

Đọc sơ sơ hắn đã biết Haskell rất khó học, nó khó một phần là do nó là Functional Programming Language (FP), một phần vì Haskell là ngôn ngữ thuần FP, bản thân FP đã khó học rồi, Haskell còn đặc biệt hơn vì nó là ngôn ngữ 100% FP, có một số ngôn ngữ khác cũng là FP, nhưng nó vẫn hỗ trợ imperative, nhưng Haskell thì không. Nó là một ngôn ngữ chỉ dành cho ai muốn học một thứ hoàn toàn khác biệt, không lai tạp, và nó rất hợp với hoàn cảnh của thanh niên lúc này.

Rất nhiều term mới đến với thanh niên, nhưng thanh nhiên bỏ qua, một cách từ tốn, thanh niên gõ những dòng đầu tiên để học về nó, hắn tạo một file mới tên hello.hs có nội dung như bên dưới,

main = print "Hello World!"


Sau đó hắn dùng ghc để build file hello.hs, và file executable tên hello đã được tạo ra
Voila, nó đã chạy, làm phức tạp vấn đề hơn một chút,

main = do
    print "Who are you?"
    yourname <- getLine
    print ("I am " ++ yourname)

Ok, nó đã chạy.


Cảm thấy bài viết trên trang yannesposito hơi cụt, với lại tác giả cũng nói rõ tác giả chỉ giới thiệu overiew thôi nên thanh niên tiếp tục với một trang web khác (http://learnyouahaskell.com/ Learn you a haskell), sau một lúc lại introduction về haskell, và thanh niên lại tiếp tục hành trình Starting out.

Trước khi đến với starting out, cần nhắc lại là ở phần introducotion của trang learnyouahaskell có nhắc đến cách setup môi trường để học Haskell cho hiệu quả:
  • Tạo riêng một thư mục làm việc
  • Trong thư mục đó tạo một file có tên .hs, chính là nơi lưu giữ source code bạn sẽ viết
  • Mở một commandline session trong thư mục đó (Trong linux thì đương nhiên, trong window là cmd thôi) và chạy lệnh ghci (chính là commandlined của Haskell), trong dấu nhắc "Prelude>" của ghci, chạy lệnh ":load filename.hs" để compile và load nội dung code haskell của bạn lên, cho những lần sau, mỗi khi thay đổi source code, chỉ cần gõ ":r" tại dấu nhắc của ghci.
Vậy là setup xong môi trường.

Bắt đầu với ghci, với các lệnh cộng trừ nhân chia cơ bản, không có gì đặc biệt, như bao ngôn ngữ khác.

Các câu lệnh logic and (&&), or (||), và "not". Các câu lệnh so sánh "==" và "/=", một điều lưu ý là với haskell, 2 vế của phép so sánh phải cùng type (type là gì mai mốt học sẽ biết). Haskell có khả năng so sánh 2 list số hoặc chữ.

Tiếp theo là một số hàm có sẵn của haskell:
  • max a b: lấy max(a,b) lưu ý cách gọi hàm của haskell là "function arg"
  • min a b: lấy min(a,b)
  • lưu ý với haskell hàn có độ ưu tiên hơn phép tính ví dụ "max 5 2*3" sẽ tương đương với "(max 5 2)*3" tức là 15, không phải "max 5 (2*3)" tức là kết quả là 6. Nên thử ngay để kiểm chứng lời thanh niên nói.
  • Có một điểm khá thú vị của haskell là khả năng linh hoạt trong cách viết cú pháp, ví dụ chúng ta có hàm div a b, lấy a chia b rồi trả ra phần nguyên, chúng ta có thể viết theo 2 cách "div 19 8" hoặc "19 `div` 8"
Next, chúng trang learyouahaskel sẽ hướng dẫn chung ta cách viết một vài hàm đơn giản, cách khai bao hàm của haskell khá đơn giản, trong haskell, definition và declaration của một hàm là một, và đặc biệt hơn, không giống như C, hàm của haskell không phân biệt thứ tự, trong source code haskell, bạn có thể define hàm foo trước hàm bar, nhưng trong hàm foo hoàn toàn có thể gọi hàm bar, nếu trong C, bạn sẽ bị báo lỗi "definition of sth is not found"

Next, cú pháp if else thần thánh

foo x = ( if x< 100
then DO_STH
else DO_STH_ELSE)

DO_STH_ELSE trong Haskell là bắt buộc.

Tổng kết ngày đầu tiên: cú pháp haskell khá đơn giản, thiên nhiều về toán học, chưa thấy điểm gì đặc biệt của ngôn ngữ haskell.
--




Monday, March 27, 2017

Plan di campuchia

Plan đi du lịch campuchia

Objective:  biết một vùng đất mới, giải trí thư giãn sau những ngày làm việc căng thẳng, học hỏi một nền văn hóa khác.Constrain: Chi phí dưới 4.5Tr, kéo dài trong vòng 4 ngày.

Chọn hành trình đi Sihanoukville vì cảnh đẹp, tương đối thanh bình so với Phnompenh, an toàn hơn so với Angkor Wat.

Phương tiện di chuyển: Bus, feet, tàu biển.

Hành trình:
Tối T4: Bắt xe Kumho đi Hà Tiên buổi tối, giá vé tham khảo loại ghế nằm là 175K/người, đến Hà Tiên có xe trung chuyển miễn phí đến cửa khẩu, cách bến xe Hà Tiên 10km.

Sáng T5: Đến cửa khẩu Xà Xía vào buổi bình minh, những tia nắng chói chang xuyên qua những tán cây. Cửa khẩu làm việc lúc 6h30, hopefully, chúng ta có thể làm thủ tục xong trước 7h30, sau đó bắt xe Đi Sihanoukville (giá tam khảo $14/người) http://hatiensihanoukville.com/home/index.php/shops/Xe-Di-Sihanouk-Ville/Xe-Bus-Di-Campuchia-Xe-Ha-Tien-Di-SIhanoukVille-77.html

Xe đi tầm 4 tiếng, đến Sihanouk vào buổi trưa, nếu đến sớm thì tắm biển rồi ăn trưa và nhận KS, nếu ko thì bỏ phần tắm biển, phòng KS ở Sinanouk khá rẻ, có thể book trên Agoda.

Nhận phòng KS xong nghỉ ngơi, chiều tối dạo khám phá Sihanouk, ăn hải sản ở bờ biển, chém gió, ngắm gái, tâm sự chuyện đời các kiểu, kể chuyện tình lâm ly bi đát, xong về KS nghỉ ngơi.

Sáng T6: Tập thể dục, boxing các kiểu, xong mua vé tàu Party boat (vé khứ hồi là 20$) đi Koh Rong Samloem. Đến Kohrong Samloem, khám phá đảo, chiều tính đường đi ăn ở Lazy beach resort, giá khoảng 1$/1 món.Mang theo đèn pin. Ăn no say thì về KS ngủ, tiết mục tâm sự chuyện đời tư bắt đầu. giá phòng KS là TBD

Sáng T7: Tạm biệt KohRong Samloem lúc 9h sáng, về đến Sihanouk khoảng 10h, ăn trưa rồi nghỉ ngơi, chờ đến 12h bắt xe đi phnoupenh. Đến thủ đô của Vương quốc Campuchia lúc 4 chiều (hơi cập rập khoản khách sạn), nhận phòng và thăm thú thủ đô Phnompenh vào buổi tối. 

Sáng CN (optional): thăm thú nhẹ nhàng Phnompenh, xong bắt xe về HCM, chia tay và hẹn gặp lại tại weekly meeting sáng hôm sau.

Saturday, December 17, 2016

[TLDR] Bàn phím cơ - có đáng để mua không?

Dạo này đi ăn trưa, mình hay nghe mọi người bàn nhau về việc mua bàn phím cơ, và nghe những câu hỏi na ná nhau được đặt ra như "Nó có gì mà nó đắt vậy?", "Hơn 2tr cho cái bàn phím có đáng  không?",...

Và với tư cách là người sử dụng bàn phím cơ được hơn một năm và có chút kiến thức về bàn phím cơ, nay mình viết lên những cảm nhận của mình khi sử dụng bàn phím cơ, qua đó, hi vọng sẽ giúp được mọi người có cái nhìn đúng đắn về bàn phím cơ và giúp mọi người tự tin hơn khi quyết định có nên tậu một cái bàn phím cơ hay không.

Nếu bạn đã suy nghĩ đến việc mua một bàn phím cơ thì có lẽ bạn cũng biết sơ sơ bàn phím cơ là gì rồi, nếu chưa biết thì google, có rất nhiều.

Mình đã nghe nói đến bàn phím cơ từ hồi học năm 1 đại học, xem các bài review về bàn phím cơ trên mạng thấy bàn phím cơ được tung hô rất nhiều, đại khái như "Khi gõ bàn phím cơ rồi thì sẽ không muốn đụng vào bàn phím membrane nữa", mình cũng rất tò mò bàn phím cơ là gì, nhưng mấy thằng chuyên bán HW như phong vũ hay hoàn long lúc đó không có mấy loại đó ( hình như bây giờ cũng không có). Và cái giá của nó thì cũng quá cao so với một sinh viên. Và bẵng đi một thời gian dài, mình bỏ ý định mua cái bàn phím, nhưng mình vẫn rất tò mò cái cảm giác bấm phím trên bàn phím cơ là như thế nào.

Vào năm 3 đại học, mình vào lab của bộ môn mình theo học, trong một lần nghịch ngợm, mình mở cái ngăn kéo hộc bàn của phòng lab thì thấy có cái bàn phím hư, mình gõ thử thì thấy nó khác hẳn các bàn phím mình tưng gõ, cái bàn phím đó tuy cũ, nhưng cảm giác gõ vẫn rất nảy, mình nhớ nó là bàn phím của hãng IBM, mãi sau này mình mới biết đó là bàn phím cơ.

Bàn phím cơ IBM


Khi đi làm, có một lần mình thấy có một anh trong công ty có cái bàn phím lạ lạ trên bàn, mình nhìn thì nhận ra ngay đó là một cái bàn phím cơ (vì cái chữ Filco dễ nhận ra + với bàn phím cơ lúc nào nhìn nó cũng thô hơn sơ với các bàn phím bình thường), mình đã gõ thử và thấy thích. Và lúc đó mình cũng đã nghĩ tới việc mua một cái, mình có về nhà tìm hiểu thì mới biết nó có đủ loại, đủ thương hiệu bàn phím cơ, mình lúc đó suy nghĩ không biết nên mua loại nào, nhỡ mua về không phù hợp thì rất phí phạm.

Bàn phím cơ Filco tenkeyless majestouch


Vậy là mình quyết định tìm chỗ nào có bán bàn phím cơ để ra đó thử các loại switch, cửa hàng đó là phong cách xanh (bạn search google là ra ngay). Nếu bạn nào có ý định thử các switch bàn phím cơ thì ra đó thử cũng đc, chị chủ ở đó cũng khá dễ tính, bạn qua gõ thử, không mua cũng chẳng sao. Và thực sự là lúc đó mình cũng không có ý định mua cái bàn phím cơ ở đó, vì nó đắt tè (vì Filco là thương hiệu đắt mà).

Mình về search xem có loại bàn phím cơ nào chất lượng mà giá cả phải chăng không thì mình tìm ra được một cái bàn phím của hãng WASD, loại có tên là CODE Keyboard. Mình dọc description của cái bàn phím đó mình thấy rất thích vì nó rất phù hợp với nhu cầu của mình. Nói về nhu cầu của mình, mình là người dùng bàn phím khá nhiều ( dạng như anh hùng bàn phím ấy ), mình thực sự cần một cái bàn phím chuyên để gõ, mình không cần các chức năng như led đổi màu, programmable hay nhìn thời trang gì cả, cần trước hết là cái bàn phím chuyên để gõ. Thêm  nữa, tại thời điểm đó, mình đang tập gõ Dvorak (là một alternative layout của qwerty) nên mình muốn tìm cái bàn phím nào có hỗ trợ layout đó, và CODE keyboard của WASD có thể nói là best fit với mình, ngoài ra nó còn có thêm led backlight màu trắng, đúng chức năng là để sử dụng trong điều kiện thiếu ánh sáng (khác với loại có led đổi màu có mục đính là trang trí và thực sự những bàn phím có led đổi màu như vậy mình rất không thích, vì nó làm mình không tập trung làm việc được khi mấy cái đèn cứ chớp mỗi khi mình gõ).



Nhưng có một cái khó khăn là cái bàn phím đó không bán ở VN, mua ở amazon với trên web hãng thì cũng đắt tè, đắt hơn mấy con filco mua ở việt nam nữa, và nó không có những loại swtich phổ biết ở việt nam (lúc đó  CODE keyboard chỉ có green switch và clear switch), nên mình cũng khá là lưỡng lự khi mua, vì không biết cảm giác gõ của nó như nào. Nhưng có một lần, mình dạo massdrop (là một trang group buy chuyên về keyboard của nước ngoài), mình tình cờ thấy WASD CODE đã có blueswitch, nên mình đã order một cái và nhờ bạn mình ship về, nhờ mua group buy nên giá cũng đỡ đi rất nhiều (so với giá gốc nhé), giá về VN của cái bàn phím đó là gần 3 triệu.

WASD CODE keyboard

Vâng, đọc đến đây bạn sẽ thắc mắc tại sao mình lại bỏ ra 3 triệu mua cái bàn phím. Mình sẽ nêu lý do mà mình quyết định mua một cái bàn phím với gía 3 triệu, sau đó mình sẽ review xem nó có đáng giá 3 triệu hay không nhé.

Mình mua đồ luôn luôn quan tâm đến giá trị sử dụng. Trước tiên nói về độ bền của bàn phím cơ, độ bền của bàn phím cơ được cho là tốt hơn nhiều so với bàn phím thường, bộ switch của nó có độ bền 10 triệu lần nhất cho một switch (là specification của hãng cherry). Nói cho dễ hiểu, một phím có 10 triệu lần nhấn, mà bàn phím bạn có khoảng 30 ký tự bạn hay gõ thường xuyên nhất ( phím chữ và phím dấu), tổng cộng là 300 triệu lần nhấn để có thể hư một cái bàn phím, để cho bạn dễ hiểu, tốc độ gõ trung bình của một người gõ rất nhanh là 100word per min (100 wpm là tốc độ rất cao, mình chỉ gõ khoảng 40 wpm thôi, bạn có thể vào đây xem tốc độ gõ của bạn là bao nhiêu https://10fastfingers.com/typing-test/english ), 1 wpm là 5 ký tự, vậy 100wpm là 500 lần nhấn phím, với bàn phím cơ có 300 triệu lần nhấn thì bạn phải gõ liên tục 600 000 phút, nếu bạn gõ phím trong giờ làm việc thì 1 tuần có 40hx52 tuần trong một năm thì bạn phải gõ gần 5 năm sẽ hư cái bàn phím. Việc bạn bỏ ra 3 triệu cho một cái bàn phím dùng trong 5 năm nghĩa là mỗi năm bạn bỏ ra 600 nghìn cho một cái bàn phím. Nói về độ bền thì điểm này thua cái bàn phím mitsumi hàng malaysia (bây h toàn hàng china nhé), một cái bàn phím mitsumi malaysia giá 200k mình dùng phải 2 năm mới phải thay một cái. vậy là cái bàn phím cơ về độ bền đã đắt hơn cái bàn phím mitsumi tới 6 lần.

Bàn phím mitsumi huyền thoại


Thêm nữa, mình đã chi trả thêm cho bàn phím đó là layout dvorak, cái feature đó là vô giá với mình, nếu phải tính giá cho cái chức năng đó thì một cái bàn phím dvorak không đã có giá vài chục Trump tệ (đơn vị tiền tệ mới của Mỹ ạ), lý do là nguyên tắc cung và cầu, mặt hàng này quá đặc biệt, rất rất ít thằng làm cái feature đó.

Thêm cái feature nữa là bàn phím có led backlit, theo mình biết thì một cái bàn phím có led backlit có giá khoảng 500k.

3 yếu tố đó thì mình thấy chi 600k/năm cho cái bàn phím là giá chấp nhận được cho một người sử dụng bàn phím vì mục đích công việc (Nó giống như việc một số bác phóng viên chuyên nghiệp sắm leica để đi chụp hình ấy).

 --------
Và đó là lý do mình chấp nhận bỏ ra 3tr cho một cái bàn phím, và sau một năm sử dụng, nếu hỏi mình 3 tr có đáng giá cho cái bàn phím mình mua không, câu trả lời là "Rất đáng".

Trước tiên xem xét lại về độ bền, độ bền của bàn phím cơ thì có lẽ không như quảng cáo, tại vì nó có quá nhiều bộ phận để hư (giống như một xe Mercedes dễ hư hơn cái Toyota vì toyota chẳng có gì để hư). Nói thế chứ sau một năm mình vẫn chưa thấy nó hư cái gì.

Xét về cái feature led backlit thì nó đáng giá đúng như mình đề cập, cty mình hay tắt điện vào buổi trưa, nhưng mình không có thói quen ngủ trưa nên buổi trưa hay lướt web đọc báo các kiểu, mặc dù mình gõ không cần nhìn phím, nhưng bàn dàn đèn led giúp mình dễ dàng gõ phím tắt khi duyệt web hơn ( mình hay chuyển tab, newtab , back and forward bằng phím tắt).

Còn về cái layout dvorak thì tuyệt vời, mình hiện là người sử dụng layout dvorak 100%, nhưng nếu mình để bàn phím ở chế độ dvorak permanently thì người khác sẽ không thể thao tác trên máy mình, điêu đó rất bất tiện, bàn phím WASD có các switch để chuyển đổi giữa layout dvorak và qwerty.

Nói về khoản tốc độ gõ, có nhiều người review là gõ bằng bàn phím cơ nhanh hơn, mình nói thật là không hẳn, mình thấy tốc độ gõ của mình trên bàn phím cơ và bàn phím chicklet của laptop là gần như nhau. Nếu bạn nào muốn mua bàn phím cơ vì nó gõ nhanh hơn thì nên xem lại nhé, chưa cắc đã applicable với tất cả mọi người đâu.

Tuy nhiên, có một điều rất là đúng là cảm giác gõ trên bàn phím cơ là tuyệt vời, bạn sẽ hứng thú hơn với công việc gõ phím (cái này thực sự không biết diễn tả sao nữa, nó giống như việc các bạn dùng iDevice thấy thích hơn so với các sản phẩm khác vậy). Ah, có một cái tương đối đúng là nói về độ chính xác, vì cảm giác gõ phím tốt nên bạn gõ phím sẽ tương đối chính xác hơn, đặc biệt là so với bàn phím chicklet trên laptop. Và câu nói "Dùng phím cơ rồi không muốn dùng bàn phím thường nữa." là hoàn toàn chính xác.
 
Và dành cho các bác nào chê "Cái bàn phím nhìn cục mịch, không có gì đặc biệt, gõ lại kêu to vãi ra mà đắt tè." thì nó như này: Hiện giờ một cái bàn phím cơ có giá khá mềm rồi, chỉ khoảng 1tr5 là có bàn phím cơ rồi, nói nó "thô", "cục mịch" chứ các bác mua bàn phím để khoe mẽ hay sao mà cần nó "fancy looking" như bàn phím của apple. Bàn phím cơ thường nó rất đơn giản, nhìn nó không khác mấy cái bàn phím mitsumi vậy, nó thường không hầm hố, nhiều nút chức năng như bàn phím gamer, cũng không đẹp và sang trọng như bàn phím của apple, tại vì nó là bàn phím đúng nghĩa, là bàn phím chuyên dùng để gõ phím, that's it. Nói theo ngôn ngữ chợ búa thì "Bàn phím apple không có tuổi so với bất kì bàn phím cơ nào, kể cả bàn phím cơ của tàu"

Bàn phím Apple
Nói về tiếng ồn, thực ra có rất nhiều loại switch với các lực nhấn khác nhau, cũng có cả nhiều loại switch không gây tiếng ồn. Nhưng mình nói thật là chỉ có switch blue là có cảm giác gõ tốt nhất, cảm giác gõ đó chính là nhờ tiếng clicky mà nó tạo ra, tuy nhiên nếu bạn vẫn muốn có cảm giác của phím cơ, nhưng không muốn làm ồn người khác thì mình khuyên nên chọn switch brown, các loại switch khác như red hay black thì theo cá nhân mình nghĩ thì không nên chọn, vì mình thấy cảm giác gõ của nó chỉ giống như mitsumi thôi (ấn nhẹ hơn chút). Dạo này mình thấy rộ lên cái "bàn phím giả cơ", mình cũng đã gõ thử thì khuyên một câu chân thành là không nên mua, nó cũng không hề rẻ gì (500-600K) mà cảm giác bấm chẳng khác gì mitsumi.

Em xin hết ạ.



Thursday, December 1, 2016

TLDR: Photoshop hoạt động như thế nào?

Hôm nay, nhân có đứa bạn hỏi 1 câu rất vu vơ là photoshop hoạt động như nào mà có thể sửa cái ảnh đẹp như vậy. Vâng, một câu hỏi đối với mình khá là thú vị.

Mình không phải dân chơi ảnh, cũng ko phải designer gì cả, kỹ năng sử dụng photoshop của mình chỉ đủ dùng để làm mấy việc như sửa màu, thêm hiệu ứng đơn giản mỗi khi mình cần ...làm màu. Nhưng may mắn mình có một khoảng thời gian làm việc với graphic library (công việc của mình  liên quan với từng pixel của hình ảnh), và photoshop cũng chỉ là một phần mềm dựa trên những graphic library mà thôi, ngoài ra mình cũng có chút kiến thức về xử lý ảnh và về quang học. Mình viết bài này với đối tượng nhắm đến là những ai đang dùng photoshop trong công việc hàng ngày và tò mò như người bạn đặt câu hỏi bên trên, hi vọng bạn có thể hiểu thêm về công cụ đang giúp các bạn kiếm tiền (hoặc không gì cả) mỗi ngày.

Trước khi đi vào chi tiết photoshop làm gì, mình sẽ bắt đầu từ quá trình chụp ảnh. Khi các bạn nhấn nút chụp, ánh sáng sẽ đi qua các thấu kính của máy ảnh và hội tụ ở cảm biến ảnh (sensor), bộ xử lý trong máy ảnh sẽ xử lý những gì nhận được từ sensor thành bức ảnh lưu trên thẻ nhớ (chi tiết quá trình này hơi phức tạp, mình ko nêu chi tiết để các bạn đỡ nhưc đầu), và xong, bạn đã có bức ảnh để sẵn sàng xử lý.

Có một điểm cần lưu ý là ảnh mà máy ảnh chụp được gọi là ảnh raster tức là ảnh được tạo ra bởi nhiều điểm ảnh, khác với ảnh vector (là ảnh được tạo ra bởi những đối tượng toán học như điểm, đường thẳng, đường cong, ...), và photoshop là chương trình xử lý ảnh raster (raster-based image editor) khác với AUTOCAD hay adobe illustrator là chương trình xử lý ảnh vector.

Hẳn các bạn đã biết, ảnh raster là một mảng 2 chiều có các phần tử chính là các pixel, màu sắc của mỗi pixel được thể hiện bởi  phối màu phát xạ (additive color model, ví dụ như RGB, khác với phố màu hấp thụ - subtractive color model CYMK). Ví dụ như hình minh họa dưới đây

Minh họa ảnh raster với các pixel có các thành phần màu sắc khác nhau (ảnh từ wikipedia)
Điều mấu chốt ở đây chính là 3 thành phần màu này, ở hình minh họa trên thì các bạn thấy 3 thành phần màu được thể hiện bằng %, ví dụ cái pixel màu hơi trắng kia có 3 thành phần màu RGB là 93%, nghĩa là mỗi màu được phát sáng với 93% công suất nên mắt bạn sẽ thấy pixel đó hơi sáng, nhưng chưa trắng hẳn, nếu 3 màu phát sáng với công suất 100% thì pixel đó sẽ có màu trắng. Đó là ý tưởng về việc thể hiện màu sắc bằng 3 màu phát xạ.

Có một lưu ý nhỏ ở đây là các bạn làm photoshop sẽ thấy mã màu có dạng 6 chữ số ví dụ như màu đỏ là FF0000, màu lục là 00FF00, màu đen là 000000, mã màu này chính là cách ghi 3 màu RGB trên máy tính, có dạng mã thập lục phân (Hexadecimal). trong mã thập lục phân thì FF tương đương 255, tương đương với 100% "công suất" như mình đề cập ở trên, nên có thể dễ hiểu, mã màu FFFFFF là có 3 màu RGB là 100%, 100%, và 100% tức là màu trắng, 000000 là 3 màu 0% tức là không phát sáng, là màu đen. các bạn có thể kiểm chứng các màu khác.

Cái hay của cơ thế biểu thị màu sắc ở đây ko chỉ là việc hiển thị màu sắc lên màn hình, mà chúng ta còn có thể làm toán với những pixel. Ví dụ, màu đỏ pha với màu xanh lục ra màu gì, mình xin phép được toán học hóa câu hỏi trên.

Trong toán học, có 2 khái niệm là toán tử(operator) và toán hạng (operand), toán tử là một phép tính gì đó, toán hạng là đầu vào (input) của toán tử, đầu ra(output) của toán tử chính là kết quả phép tính, ví dụ a+b thì chúng ta có toán tử + có 2 toán hạng là a và b,  toán tử ở đây có thể là cộng, trừ, nhân, chia, khai căn, lấy mũ, đạo hàm, vi phân, tích phân, ...hoặc cũng có thể là kết hợp tất cả các  phép tính đó lại.
Qua trở lại ví dụ trên, mình có một toán tử pha màu, nhận input là 2 màu lục và đỏ, vậy kết quả là màu gì. Ban hãy tự kiểm tra bằng cách này: trong photoshop, bạn tạo ra 2  layer, một layer toàn màu đỏ (FF0000) và một layer toàn màu lục (00FF00), sau đó chọn kiểu layer blending là linear dodge, xem nó ra màu gì, mình bị mù màu nên ko biết nó ra màu gì, nhưng mình chắc chắn nó ra mã màu FFFF00. Các bạn có thể cho mình biết nó ra màu gì được ko?

Vây cái toán tử pha màu mà mình nhắc ở trên, nó gọi là trộn (blending) màu theo kiểu phối hợp (addition), từ ngữ trong ngành photoshop gọi là linear dodge. Và thực ra thì việc trộn màu trong photoshop nó có đủ thứ kiểu trộn (ví dụ như  nhuộm tóc phải có thêm các phụ gia để màu tóc nó lên đẹp hơn) các bạn ạ, các kiểu trộn đó nó được gọi là blending mode, mỗi mode thì có một kiểu toán tử khác nhau được áp dụng vào 2 layers.

Mình vừa ví dụ về việc blending với 2 layer trong photoshop là 2 màu thôi. Vậy nếu bạn có một bức ảnh hoàn chỉnh, được blending với một "tấm kính màu lục" (giống như giấy màu làm lồng đèn ấy), thì bức ảnh của bạn sẽ như thế nào? Nó sẽ giống như việc bạn nhìn bức ảnh qua mắt kính có dán "tấm kính màu lục" vậy, bức ảnh sẽ tràn ngập màu xanh, giống như cái filter vậy. Bức ảnh dưới đây của mình được chụp bằng máy PnS cách đây 6 năm, bức ảnh gốc thực tế ko đẹp như vậy, mấy cái cây nó ko đc XANH như vậy, nhưng nhờ mấy cái trò blending với layer màu xanh mà trông cây cối có vẻ tốt tươi như thế.

Ảnh gốc



Ảnh sau khi đã cho blend với màu xanh.
Vậy pts làm cách nào mà có thể đưa được toàn bộ bức ảnh từ kiểu xám xịt ra kiểu xanh tốt như thế. Thực chất thì pts làm việc với từng điểm ảnh, ở mỗi điểm ảnh, PTS sẽ thực hiện các toán tử trên các màu, kết quả là các giá trị màu sắc bị thay đổi. Hiểu đơn giản là như thế này: ví dụ việc làm cho bức ảnh xanh hơn, pts sẽ đi đến điểm ảnh đầu tiên, tăng thành phần màu xanh lên một ít, đến điểm ảnh thứ 2, cũng tăng thành phần màu xanh lên một ít, và cứ thế cho đến pixel cuối cùng của hình ảnh, kết quả là chính ta đã có một bức ảnh với tất cả các điểm ảnh đã được làm xanh hơn.

Các ví dụ khác của photoshop mà bạn có thể liên tưởng đến việc, tăng hoặc giảm công suất phát xạ của 3 màu RGB trên tưng điểm ảnh là: chỉnh độ sáng tối, chỉnh độ tương phản, các loại filter màu, sửa ảnh bị ám màu.

Một số hiệu ứng chỉnh màu nổi tiếng các bạn có thể hay gặp như làm cho ảnh trông có vẻ ấm hơn hay lạnh hơn(nó có cái thuật ngữ mà mình quên rồi) bằng cách tăng thêm sắc xanh lam hay đỏ cho bức ảnh.

Có một hiệu cũng là chỉnh màu, nhưng hơi đặc biệt ở chỗ nó sửa màu cho cả 3 kênh RGB làm cho tất cả các điểm ảnh đều có lượng phát xạ của RGB như nhau, đó là hiệu ứng grayscale (ảnh xám). Ảnh xám khác ảnh đen trắng về mặt kỹ thuật nhé các bạn. Ví dụ một điểm ảnh có dạng RrGgBb sau khi qua toán tử grayscale nó sẽ có dạng ZzZzZz, không tin bạn có thể lấy một bức ảnh màu, sau đó áp hiệu ứng đen trắng vào rồi dùng color picker xem màu của các điểm ảnh sau khi đã làm đen trắng có phải có dạng như mình nói ko.

Ok, vậy nếu chỉ là tính toán trên từng điểm ảnh như vậy, tại sao photoshop lại có thể làm được những việc như biến ảnh thường thành tranh bút chì?

Ah đúng mà không đúng, những ví dụ trên thì photoshop chỉ tính toán trên từng điểm ảnh, nhưng có những thuật toán photoshop tính toán trên nhiều điểm ảnh cùng lúc. Ví dụ để tạo hiệu ứng tranh chì, đầu tiên photoshop sẽ phải tìm ra các nét (edge detection) trên bức ảnh gốc bằng các phép toán vi phân 2 chiều (đại khái là phép toán vi phân, nhưng ko phải trên một đường thẳng mà là trên một mặt phẳng, đúng hơn là toán tử gradient), lúc đó nó sẽ có "ảnh chì màu" nhưng ảnh chì màu thì ko đẹp nên nó sẽ chuyển ảnh chì màu thành chì than bằng cách sử dụng hiệu ứng đen trắng. Nguyên tắc cơ bản là vậy, thực tế thì người ta sẽ có thêm các thuật toán đặc biệt để làm cho ảnh trông giống thật hơn.
Ảnh gốc (nguồn wikipedia)
Ảnh sau khi áp dụng thuật toán edge detection



Và nói đến đây, các bạn có thể high light mấy chữ "vi phân", "tích phân" trong bài này và ném vào mặt đứa nào dám hỏi "Học toán làm gì trong khi ra đường chỉ có đếm và cộng trừ nhân chia lấy căn bậc 2?" Vâng, nếu ko có toán thì ko có photoshop  hay camera 360 cho các bạn tự sướng đâu nhé.

Ah, nãy mình chưa nói tích phân được dùng ở đâu trong photoshop, trong các hiệu ứng làm mờ (blur), photoshop sẽ làm các phép nhân chập (convolution) có tác dụng là giảm sự khác nhau giữa các điểm ảnh đi (much là làm cho các điểm ảnh ko rõ ràng nữa), phép convolution trong toán học thực chất là là phép tích phân cộng kết hợp với vài phép toán khác. Dễ thấy ứng dụng của hiệu ứng blur là tạo ra các bức ảnh chụp chân dung lung linh được làm mờ hậu cảnh. Cũng như ví dụ trên, các bạn dùng plugin hay preset thì ấn một vài nút thì bức ảnh từ có DOF dài chuyển thành bức ảnh xóa phông trong huyền thoại. Việc này thực tế thì có nhiều gia đoạn, giai đoạn đầu tiên là phải tách chủ thể và hậu cảnh ra, photoshop làm việc đó bằng nhiều thuật toán edge detection, sau đó sẽ áp dụng các hiệu ứng blur cho phần hậu cảnh, làm lung linh phần chủ thể và ghép 2 phần lại với nhau.

Nhờ vi phân và tích phân mà các bạn mớ có bức ảnh lung linh như thế để up fb đấy nhé.

Các bạn thanh niên trong nghề thấy em nói có gì sai thì sửa giúp ạ. Em chỉ đứng ở view của người làm kỹ thuật mà nói về pts thôi, chứ em ko phải dân sử dụng pts chuyên nghiệp gì đâu ạ.

Em xin hết ạ.