SIM A9G bài 3: Blink và Hello World thần thánh

SIM A9G bài 3: Blink và Hello World thần thánh

Series: Lập trình module sim A9G với GPRS_C_SDK

wp-content/uploads/2019/09/A9G_GPRS_GPS_SS1.png

Sau khi cài đặt bộ SDK và các công cụ cần thiết, chúng ta hãy bắt tay vào code ngay một project Blink – Hello World, rồi nạp thử xem A9G chạy ngon không nhé.

Video hướng dẫn

Chuẩn bị phần cứng

Chúng ta cần

  • 1 board Pudding
  • 1 cáp microUSB
  • 3 sợi bus kết nối
  • 1 module USB-UART dùng chip CP2102

Vì cổng microUSB của Pudding không có chức năng nạp nên cần phải có một module USB-UART để làm việc đó. Ai-Thinker khuyến cáo nên dùng module USB-UART có sử dụng chip CP2102, tránh dùng các module sử dụng chip PL2303 hoặc CH34 vì có nguồn điện không ổn định.

Mình cũng đã thử nghiệm và kết quả đúng như khuyến cáo, CP2102 nạp được còn CH34 thì không 🙂

Sơ đồ kết nối mạch nạp với Pudding như bên dưới.

Pudding USB to UART
HST_TX RX
HST_RX TX
GND GND


Cấp nguồn cho Pudding thông qua 1 sợi dây microUSB, có thể dùng cục sạc điện thoại hoặc cắm trực tiếp vào máy tính cũng được.

Code ngay và luôn

Trên board Pudding có 2 đèn led được nối với chân GPIO_27 GPIO_28. Chúng ta sẽ viết chương trình để nháy lần lượt 2 led này, đồng thời ghi log ra chữ “hello” và “world“.

Đầu tiên, để dễ dàng tạp project, ta copy một project sẵn có với tên “gpio” từ thư mục C:\GPRS_C_SDK\demo\gpio vào thư mục C:\GPRS_C_SDK\gpio .

Right-Click lên thư mục “gpio” vừa paste, chọn Open with Code

Trên khung Explorer của VS Code, mở file Makefile và sửa dòng số 6 thành như sau:

Mở file demo_gpio.c, xóa toàn bộ code, sau đó chép đoạn code dưới đây và dán vào.

demo_gpio.c

  1. #include "api_hal_gpio.h"
  2. #include "stdint.h"
  3. #include "stdbool.h"
  4. #include "api_debug.h"
  5. #include "api_os.h"
  6. #include "api_hal_pm.h"
  7. #include "api_os.h"
  8. #include "api_event.h"
  9.  
  10. #define MAIN_TASK_STACK_SIZE    (1024 * 2)
  11. #define MAIN_TASK_PRIORITY      0 
  12. #define MAIN_TASK_NAME         "MAIN Test Task"
  13.  
  14. #define TEST_TASK_STACK_SIZE    (1024 * 2)
  15. #define TEST_TASK_PRIORITY      1
  16. #define TEST_TASK_NAME         "GPIO Test Task"
  17.  
  18. static HANDLE mainTaskHandle = NULL;
  19. static HANDLE secondTaskHandle = NULL;
  20.  
  21. void GPIO_TestTask()
  22. {
  23.     static GPIO_LEVEL ledBlueLevel = GPIO_LEVEL_HIGH;
  24.  
  25.     GPIO_config_t gpioLedBlue = {
  26.         .mode         = GPIO_MODE_OUTPUT,
  27.         .defaultLevel = GPIO_LEVEL_LOW
  28.     };
  29.  
  30.     for(uint8_t i=0;i<POWER_TYPE_MAX;++i) PM_PowerEnable(i,true);
  31.  
  32.     gpioLedBlue.pin = GPIO_PIN27;
  33.     GPIO_Init(gpioLedBlue);
  34.  
  35.     gpioLedBlue.pin = GPIO_PIN28;
  36.     GPIO_Init(gpioLedBlue);
  37.  
  38.     while(1)
  39.     {
  40.         GPIO_Set(GPIO_PIN28, !ledBlueLevel);
  41.         GPIO_Set(GPIO_PIN27, ledBlueLevel);
  42.         Trace(1,"Hello");
  43.         OS_Sleep(1000);
  44.  
  45.         GPIO_Set(GPIO_PIN28, ledBlueLevel);
  46.         GPIO_Set(GPIO_PIN27, !ledBlueLevel);
  47.         Trace(1,"World!");
  48.         OS_Sleep(1000);
  49.     }
  50. }
  51.  
  52. void EventDispatch(API_Event_t* pEvent)
  53. {
  54.     switch(pEvent->id)
  55.     {
  56.         default:
  57.             break;
  58.     }
  59. }
  60.  
  61. void MainTask(void *pData)
  62. {
  63.     API_Event_t* event=NULL;
  64.  
  65.     secondTaskHandle = OS_CreateTask(GPIO_TestTask,
  66.         NULL, NULL, TEST_TASK_STACK_SIZE, TEST_TASK_PRIORITY, 0, 0, TEST_TASK_NAME);
  67.  
  68.     while(1)
  69.     {
  70.         if(OS_WaitEvent(mainTaskHandle, (void**)&event, OS_TIME_OUT_WAIT_FOREVER))
  71.         {
  72.             EventDispatch(event);
  73.             OS_Free(event->pParam1);
  74.             OS_Free(event->pParam2);
  75.             OS_Free(event);
  76.         }
  77.     }
  78. }
  79.  
  80. void gpio_Main()
  81. {
  82.     mainTaskHandle = OS_CreateTask(MainTask ,
  83.         NULL, NULL, MAIN_TASK_STACK_SIZE, MAIN_TASK_PRIORITY, 0, 0, MAIN_TASK_NAME);
  84.     OS_SetUserMainHandle(&mainTaskHandle);
  85. }

Sau khi sửa code xong, ta tiến hành build.
Vào thư mục C:\GPRS_C_SDK -> ấn đồng thời Shift+Right-click vào khoảng trống -> chọn Open PowerShell here

Trong PowerShell, gõ lệnh sau rồi Enter

.\build.bat gpio

Kiểm tra thư mục hex\gpio, ta sẽ thấy các file được sinh ra như hình trên.

Nạp code

Cách sử dụng CoolWatcher

Vào thư mục C:\CSDTK42\cooltools, chạy file coolwatcher.exe lên.

Giao diện của CoolWatcher lần đầu chạy sẽ như hình dưới.
Ở khung Profiles bên trái, chọn 8955. Ở khung bên phải, tại dòng lastcomport, sửa số cổng COM tương ứng với tên cổng đang kết nối với module USB-UART. Như bên dưới, module USB-UART của mình đang kết nối vào cổng COM5 nên mình sửa thành số 5.

Đợi khoảng 10 giây cho chương trình khởi động, ta sẽ thấy các dòng màu xanh xuất hiện, báo hiệu kết nối thành công.
Ta đóng 2 plugin Register WatcherBuffer Watcher vì chưa cần dùng.

Thay vào đó, hãy bật Tracer lên để theo dõi log, cách làm như bên dưới.

Thực hiện lần nạp đầu tiên cho board mới

Có một số thao các cần phải thực hiện cho lần nạp đầu tiên cho board mới mua. Từ các lần nạp sau cho cùng board, ta có thể bỏ qua.

Chọn file Flash Programmer File (ramrun).

Có thể hiểu ramrun như là file nền và/hoặc chứa các hàm API/OS để các project của chúng ta gọi tới.

Tại góc trên bên phải, bấm vào nút thứ 4 từ trái qua (nút có chữ DRY)

Cửa sổ hiện ra, trỏ tới file có đường dẫn như bên dưới -> bấm OK

C:\CSDTK42\cooltools\chipgen\Modem2G\toolpool\plugins\fastpf\flash_programmers\host_8955_flsh_spi32m_ramrun.lod

Chọn file LOD

Trong số các file output ra sau khi build bằng PowerShell, có 3 file đuôi .LOD với tên theo định dạng như sau:

<project_name>_B2108_debug.lod
<project_name>_B2108_debug_ota.lod
<project_name>_flash_debug.lod

File <project_name>_B2108_debug.lod sẽ được dùng để nạp cho board mới mua. Từ lần sau, ta sẽ nạp file <project_name>_flash_debug.lod.

Tại góc trên bên phải, bấm vào nút thứ 3 từ trái qua (nút có chữ LOD)

Cửa sổ hiện ra, trỏ tới thư mục hex của project -> chọn file gpio_B2108_debug.lod -> bấm OK

Nạp và chạy thử

Sau khi chọn ramrun và file .LOD, bấm vào nút thứ 5 từ trái qua (hình ngọn lửa) để nạp code vào Pudding.

Quá trình nạp lần đầu có thể mất tới 1 phút.

Ngay sau khi nạp xong, Pudding sẽ khởi chạy chương trình.
Đây là thành quả của chúng ta.

Và đây là log Hello World do Pudding gửi lên CoolWatcher.

Kết

Như vậy mình đã hoàn thành bài hướng dẫn code và sử dụng CoolWatcher để nạp một project Blink-Hello World cho Pudding.
Tuy không thể nạp trực tiếp code từ IDE như Arduino, nhưng quá trình thực hiện cũng không quá phức tạp.

Sau bài này, hi vọng các bạn sẽ có hứng thú với A9G/Pudding hơn và bắt đầu nghiên cứu về nó. Các bạn gặp lỗi hay khó khăn gì thì hãy comment bên dưới nhé.

Trong bài tới mình sẽ phân tích cấu trúc của một project và hướng dẫn cách tạo lệnh Build trong VS Code.

Thanks and stay tuned!

Source code & Tham khảo

Source code hoàn chỉnh: sim-a9g-bài-3

Burn & Debug
A9G GPIO API

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *

2 Bình luận

  1. `CHST_Read32′: Request to coolhost timed out ! (CoolHostTimeoutError)

    Em gặp lỗi như vậy mò mãi mà vẫn chưa sửa được. Anh giúp em với ạ

    1. Trước hết bạn kiểm tra lại đúng kết nối chưa nha. Nếu kết nối ok thì sau khi bật Plugin->Tracer, nó sẽ hiện log của board.
      Bạn thử nạp lại bằng cách: bấm reset trên board rồi lập tức bấm nút nạp trên CoolWatcher.