SDL2庫使用及QEMU添加虛擬開發(fā)板--Apple的學(xué)習(xí)筆記

一救巷,前言

上次blogQemu虛化HW相關(guān)—Apple的學(xué)習(xí)筆記已經(jīng)分析了要修改qemu源碼自定義開發(fā)板其實(shí)就是要看懂graphic.c绣版,而里面用到的就是SDL2和其擴(kuò)展庫SDL2_Image擴(kuò)展庫台舱,而我之前已經(jīng)搭建了SLD2的mingw開發(fā)環(huán)境赁豆,并且在官網(wǎng)了解了SDL2的API看懂了graphic.c那么就開始修改為自定義開發(fā)板叠萍。

二或颊,在SDL2中實(shí)現(xiàn)開發(fā)板LED閃爍界面

效果為按下鼠標(biāo)后城菊,右下角的LED燈顏色會(huì)變秘蛇。


image.png

codeblocks源碼如下:

#include <stdio.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
//Screen dimension constants
const int SCREEN_WIDTH = 346;
const int SCREEN_HEIGHT = 452;

typedef struct {
    SDL_Renderer *renderer;
    SDL_Window *window;
} App;
App app;

typedef struct {
    int x;
    int y;
    SDL_Texture *texture;
} Entity;
Entity player;

unsigned int click=0;

void prepareScene(void)
{
    #if 0
    if(click == 1)
    {
        SDL_SetRenderDrawColor(app.renderer, 255, 128, 0, 255);
    }
    else
    {
        SDL_SetRenderDrawColor(app.renderer, 96, 128, 255, 255);
    }
    SDL_RenderClear(app.renderer);
    #endif // 0
    if(click == 1)
    {
        SDL_SetRenderDrawColor(app.renderer, 255, 128, 0, 255);
    }
    else
    {
        SDL_SetRenderDrawColor(app.renderer, 0, 255, 0, 255);
    }
    SDL_Rect rectangle;

    rectangle.x = 318;
    rectangle.y = 378;
    rectangle.w = 12;
    rectangle.h = 6;
    SDL_RenderFillRect(app.renderer, &rectangle);
}

void presentScene(void)
{
    SDL_RenderPresent(app.renderer);
}

void initSDL(void)
{
    int rendererFlags, windowFlags;

    rendererFlags = SDL_RENDERER_ACCELERATED;

    windowFlags = 0;

    if (SDL_Init(SDL_INIT_VIDEO) < 0)
    {
        printf("Couldn't initialize SDL: %s\n", SDL_GetError());
        exit(1);
    }

    app.window = SDL_CreateWindow("Apple's STM32 EK-board", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, windowFlags);

    if (!app.window)
    {
        printf("Failed to open %d x %d window: %s\n", SCREEN_WIDTH, SCREEN_HEIGHT, SDL_GetError());
        exit(1);
    }

    SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");

    app.renderer = SDL_CreateRenderer(app.window, -1, rendererFlags);

    if (!app.renderer)
    {
        printf("Failed to create renderer: %s\n", SDL_GetError());
        exit(1);
    }

    IMG_Init(IMG_INIT_PNG | IMG_INIT_JPG);
}

void cleanup(void)
{
    SDL_DestroyRenderer(app.renderer);
    SDL_DestroyWindow(app.window);
    SDL_Quit();
}

void doInput(void)
{
    SDL_Event event;
    while (SDL_PollEvent(&event))
    {
        switch (event.type)
        {
            case SDL_QUIT:
                exit(0);
                break;
            case SDL_MOUSEBUTTONUP:
                click = !click;
                break;
            default:
                break;
        }
    }
}


int main(int argc, char *argv[])
{
    memset(&app, 0, sizeof(App));
    memset(&player, 0, sizeof(Entity));

    initSDL();

    SDL_Surface* board_bitmap = IMG_Load("pic/AppleSTM32.png");
    if (board_bitmap == NULL) {
        printf("Cannot load image file '%s' (%s).\n",
                "pic/player.png",
                IMG_GetError());
        exit(1);
    }
    SDL_Surface* board_bitmap_rgb = SDL_ConvertSurfaceFormat(board_bitmap,SDL_PIXELFORMAT_RGB888, 0);
    if (board_bitmap_rgb == 0) {
        printf("Could not create surface: %s\n", SDL_GetError());
        exit(1);
    }
    player.texture = SDL_CreateTextureFromSurface(app.renderer,board_bitmap_rgb);
    if (player.texture == NULL) {
        printf("Could not create texture: %s\n", SDL_GetError());
        exit(1);
    }
    SDL_RenderClear(app.renderer);
    SDL_RenderCopy(app.renderer, player.texture, NULL, NULL);
    SDL_RenderPresent(app.renderer);
    SDL_FreeSurface(board_bitmap);

    atexit(cleanup);

    while (1)
    {
        prepareScene();
        doInput();
        presentScene();
        SDL_Delay(16);
    }
    return 0;
}

三其做,修改qemu中的開發(fā)板圖片

boards-discovery.c中修改LED的rect,修改要打開的圖片

//修改1彤叉,LED0位置
static GPIOLEDInfo stm32f429i_discovery_leds_info[] = {
    {
        .name = "led:green",
        .active_low = false,
        .colour_name = "green",
        .x = 486,//519,
        .y = 574,//109,
        .w = 12,//10,
        .h = 8,//8,
        .gpio_path = DEVICE_PATH_STM32_GPIO_G,
        .irq_name = STM32_IRQ_GPIO_ODR_OUT,
        .gpio_bit = 13,
//修改2庶柿,背景開發(fā)板圖片
    BoardGraphicContext *board_graphic_context =cortexm_board_init_graphic_image(board, "AppleSTM32.png");
            //cortexm_board_init_graphic_image(board, "STM32F429I-Discovery.jpg");
//修改3,窗口臺頭名稱
mc->desc = "Apple Cai's STM32F429ZG board";//"ST Discovery kit for STM32F429/439 lines";

qemu運(yùn)行我的stm32開發(fā)板效果秽浇,右下角D1處為LED燈浮庐。


image.png

四,qemu添加自定義虛擬開發(fā)板

剛剛在第三個(gè)步驟中柬焕,只是在原來的開發(fā)板基礎(chǔ)上修改了圖片审残。至于開發(fā)板的IO口等還是原來的。所以第四步是要在qemu中添加自定義開發(fā)板的仿真代碼斑举,而不破壞原來的開發(fā)板仿真代碼搅轿。
關(guān)于如何添加開發(fā)板,要看我最早的一篇qemu源碼分析富玷,主要是調(diào)試了vl.c了解其框架及傳參的作用璧坟,大家可以參考Qemu2.8虛擬機(jī)源碼分析—Apple的學(xué)習(xí)筆記qemu虛化原理入門--Apple的學(xué)習(xí)筆記,在qemu中添加一個(gè)開發(fā)板還是比較簡單的赎懦。參考其它hw中的board.c文件依樣畫葫蘆即可雀鹃。我在stm32_machines_init中注冊了type_register_static(&appleSTM32F429ZG_machine)設(shè)置了board名字為AppleSTM32。添加代碼如下:

/* ----- AppleCai's STM32F429ZG board ----- */
static GPIOLEDInfo appleSTM32_leds_info[] = {
    {
        .name = "led:green",
        .active_low = false,
        .colour_name = "green",
        .x = 486,
        .y = 574,
        .w = 12,
        .h = 8,
        .gpio_path = DEVICE_PATH_STM32_GPIO_F,
        .irq_name = STM32_IRQ_GPIO_ODR_OUT,
        .gpio_bit = 9,
    /**/
    },
    {
        .name = "led:red",
        .active_low = false,
        .colour_name = "red",
        .x = 486,
        .y = 584,
        .w = 10,
        .h = 8,
        .gpio_path = DEVICE_PATH_STM32_GPIO_F,
        .irq_name = STM32_IRQ_GPIO_ODR_OUT,
        .gpio_bit = 10,
    /**/
    },
    { },
/**/
};
static void appleSTM32F4_board_init_callback(MachineState *machine)
{
    CortexMBoardState *board = CORTEXM_BOARD_STATE(machine);

    cortexm_board_greeting(board);
    BoardGraphicContext *board_graphic_context =cortexm_board_init_graphic_image(board, "AppleSTM32.png");
    {
        // Create the MCU
        Object *mcu = cm_object_new_mcu(machine, TYPE_STM32F429ZI);

        // Set the board specific oscillator frequencies.
        cm_object_property_set_int(mcu, 8000000, "hse-freq-hz"); // 8.0 MHz
        cm_object_property_set_int(mcu, 32768, "lse-freq-hz"); // 32 kHz

        cm_object_realize(mcu);
    }

    Object *peripheral = cm_container_get_peripheral();
    // Create board LEDs.
    gpio_led_create_from_info(peripheral, appleSTM32_leds_info,
            board_graphic_context);
}

static void appleSTM32_discovery_init_callback(ObjectClass *oc,void *data);

static const TypeInfo appleSTM32F429ZG_machine = {
    .name = BOARD_TYPE_NAME("AppleSTM32"),
    .parent = TYPE_CORTEXM_BOARD,
    .class_init = appleSTM32_discovery_init_callback
};

static void appleSTM32_discovery_init_callback(ObjectClass *oc,void *data)
{
    MachineClass *mc = MACHINE_CLASS(oc);
    mc->desc = "Apple Cai's STM32F429ZG board";
    mc->init = appleSTM32F4_board_init_callback;
}

編譯通過后励两,查看Apple cai'sboard已經(jīng)添加成功

image.png

接著修改了LED工程的引腳為PF9和PF10黎茎。原來的是PG14和PG14,直接運(yùn)行LED燈是不會(huì)亮的当悔。LED工程make通過后傅瞻,結(jié)合qemu進(jìn)行仿真踢代。記得傳入?yún)?shù)--board AppleSTM32這樣才可以調(diào)用我添加的函數(shù)。輸入仿真命令
qemu-system-gnuarmeclipse --verbose --verbose --board AppleSTM32 --mcu STM32F429ZI -d unimp,guest_errors --image led.elf
led工程中我設(shè)置了D1和D2兩個(gè)LED燈輪流閃爍嗅骄。效果如下胳挎,自定義最小開發(fā)板完工。
image.png

五掸读,總結(jié)

通過化繁為簡的方法串远,進(jìn)行分步學(xué)習(xí),逐漸熟悉qemu源碼框架及其子系統(tǒng)儿惫,并且掌握qemu自定義開發(fā)板和外設(shè)的方法澡罚。真的好好玩啊~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市肾请,隨后出現(xiàn)的幾起案子留搔,更是在濱河造成了極大的恐慌,老刑警劉巖铛铁,帶你破解...
    沈念sama閱讀 218,682評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件隔显,死亡現(xiàn)場離奇詭異,居然都是意外死亡饵逐,警方通過查閱死者的電腦和手機(jī)括眠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來倍权,“玉大人掷豺,你說我怎么就攤上這事”∩” “怎么了当船?”我有些...
    開封第一講書人閱讀 165,083評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長默辨。 經(jīng)常有香客問我德频,道長,這世上最難降的妖魔是什么缩幸? 我笑而不...
    開封第一講書人閱讀 58,763評論 1 295
  • 正文 為了忘掉前任壹置,我火速辦了婚禮,結(jié)果婚禮上表谊,老公的妹妹穿的比我還像新娘蒸绩。我一直安慰自己,他們只是感情好铃肯,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,785評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著传蹈,像睡著了一般押逼。 火紅的嫁衣襯著肌膚如雪步藕。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,624評論 1 305
  • 那天挑格,我揣著相機(jī)與錄音咙冗,去河邊找鬼。 笑死漂彤,一個(gè)胖子當(dāng)著我的面吹牛雾消,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播挫望,決...
    沈念sama閱讀 40,358評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼立润,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了媳板?” 一聲冷哼從身側(cè)響起桑腮,我...
    開封第一講書人閱讀 39,261評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蛉幸,沒想到半個(gè)月后破讨,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,722評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡奕纫,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年提陶,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片匹层。...
    茶點(diǎn)故事閱讀 40,030評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡隙笆,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出又固,到底是詐尸還是另有隱情仲器,我是刑警寧澤,帶...
    沈念sama閱讀 35,737評論 5 346
  • 正文 年R本政府宣布仰冠,位于F島的核電站乏冀,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏洋只。R本人自食惡果不足惜辆沦,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,360評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望识虚。 院中可真熱鬧肢扯,春花似錦、人聲如沸担锤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至铭腕,卻和暖如春银择,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背累舷。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評論 1 270
  • 我被黑心中介騙來泰國打工浩考, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人被盈。 一個(gè)月前我還...
    沈念sama閱讀 48,237評論 3 371
  • 正文 我出身青樓析孽,卻偏偏與公主長得像,于是被迫代替她去往敵國和親只怎。 傳聞我的和親對象是個(gè)殘疾皇子袜瞬,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,976評論 2 355

推薦閱讀更多精彩內(nèi)容