uboot除錯總結(freescale平臺為例)
uboot入口
arch/arm/lib/crt0.S
#include <config.h> #include <asm-offsets.h> #include <linux/linkage.h> /* * This file handles the target-independent stages of the U-Boot * start-up where a C runtime environment is needed. Its entry point * is _main and is branched into from the target's start.S file. * * _main execution sequence is: * * 1. Set up initial environment for calling board_init_f(). * This environment only provides a stack and a place to store * the GD ('global data') structure, both located in some readily * available RAM (SRAM, locked cache...). In this context, VARIABLE * global data, initialized or not (BSS), are UNAVAILABLE; only * CONSTANT initialized data are available. * * 2. Call board_init_f(). This function prepares the hardware for * execution from system RAM (DRAM, DDR...) As system RAM may not * be available yet, , board_init_f() must use the current GD to * store any data which must be passed on to later stages. These * data include the relocation destination, the future stack, and * the future GD location. * * (the following applies only to non-SPL builds) * * 3. Set up intermediate environment where the stack and GD are the * ones allocated by board_init_f() in system RAM, but BSS and * initialized non-const data are still not available. * * 4. Call relocate_code(). This function relocates U-Boot from its * current location into the relocation destination computed by * board_init_f(). * * 5. Set up final environment for calling board_init_r(). This * environment has BSS (initialized to 0), initialized non-const * data (initialized to their intended value), and stack in system * RAM. GD has retained values set by board_init_f(). Some CPUs * have some work left to do at this point regarding memory, so * call c_runtime_cpu_setup. * * 6. Branch to board_init_r(). */ /* * entry point of crt0 sequence */ ENTRY(_main) /* * Set up initial C runtime environment and call board_init_f(0). */ #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK) ldr sp, =(CONFIG_SPL_STACK) #else ldr sp, =(CONFIG_SYS_INIT_SP_ADDR) #endif bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ mov r2, sp sub sp, sp, #GD_SIZE /* allocate one GD above SP */ bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ mov r9, sp /* GD is above SP */ mov r1, sp mov r0, #0 clr_gd: cmp r1, r2 /* while not at end of GD */ strlo r0, [r1] /* clear 32-bit GD word */ addlo r1, r1, #4 /* move to next */ blo clr_gd #if defined(CONFIG_SYS_MALLOC_F_LEN) sub sp, sp, #CONFIG_SYS_MALLOC_F_LEN str sp, [r9, #GD_MALLOC_BASE] #endif /* mov r0, #0 not needed due to above code */ bl board_init_f #if ! defined(CONFIG_SPL_BUILD) /* * Set up intermediate environment (new sp and gd) and call * relocate_code(addr_moni). Trick here is that we'll return * 'here' but relocated. */ ldr sp, [r9, #GD_START_ADDR_SP] /* sp = gd->start_addr_sp */ bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ ldr r9, [r9, #GD_BD] /* r9 = gd->bd */ sub r9, r9, #GD_SIZE /* new GD is below bd */ adr lr, here ldr r0, [r9, #GD_RELOC_OFF] /* r0 = gd->reloc_off */ add lr, lr, r0 ldr r0, [r9, #GD_RELOCADDR] /* r0 = gd->relocaddr */ b relocate_code here: /* * now relocate vectors */ bl relocate_vectors /* Set up final (full) environment */ bl c_runtime_cpu_setup /* we still call old routine here */ #endif #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_FRAMEWORK) # ifdef CONFIG_SPL_BUILD /* Use a DRAM stack for the rest of SPL, if requested */ bl spl_relocate_stack_gd cmp r0, #0 movne sp, r0 # endif ldr r0, =__bss_start /* this is auto-relocated! */ #ifdef CONFIG_USE_ARCH_MEMSET ldr r3, =__bss_end /* this is auto-relocated! */ mov r1, #0x00000000 /* prepare zero to clear BSS */ subs r2, r3, r0 /* r2 = memset len */ bl memset #else ldr r1, =__bss_end /* this is auto-relocated! */ mov r2, #0x00000000 /* prepare zero to clear BSS */ clbss_l:cmp r0, r1 /* while not at end of BSS */ strlo r2, [r0] /* clear 32-bit BSS word */ addlo r0, r0, #4 /* move to next */ blo clbss_l #endif #if ! defined(CONFIG_SPL_BUILD) bl coloured_LED_init bl red_led_on #endif /* call board_init_r(gd_t *id, ulong dest_addr) */ mov r0, r9 /* gd_t */ ldr r1, [r9, #GD_RELOCADDR] /* dest_addr */ /* call board_init_r */ ldr pc, =<span style="color:#FF0000;">board_init_r</span> /* this is auto-relocated! */ /* we should not return here. */ #endif
board/freescale/mx6sabresd下的mx6sabresd.c
void board_init_f(ulong dummy) { /* setup AIPS and disable watchdog */ arch_cpu_init(); ccgr_init(); gpr_init(); /* iomux and setup of i2c */ board_early_init_f(); /* setup GP timer */ timer_init(); /* UART clocks enabled and gd valid - init serial console */ preloader_console_init(); /* DDR initialization */ spl_dram_init(); /* Clear the BSS. */ memset(__bss_start, 0, __bss_end - __bss_start); /* load/boot image from boot device */ <span style="color:#FF0000;">board_init_r(NULL, 0);</span> }
函式board_init_r(NULL, 0)最終呼叫了common/board_r.c
void board_init_r(gd_t *new_gd, ulong dest_addr) { #ifdef CONFIG_NEEDS_MANUAL_RELOC int i; #endif #ifdef CONFIG_AVR32 mmu_init_r(dest_addr); #endif #if !defined(CONFIG_X86) && !defined(CONFIG_ARM) && !defined(CONFIG_ARM64) gd = new_gd; #endif #ifdef CONFIG_NEEDS_MANUAL_RELOC for (i = 0; i < ARRAY_SIZE(init_sequence_r); i++) init_sequence_r[i] += gd->reloc_off; #endif if (initcall_run_list(<span style="color:#FF0000;">init_sequence_r</span>)) hang(); /* NOTREACHED - run_main_loop() does not return */ hang(); }
這裡看看陣列init_sequence_r的內容。
init_fnc_t init_sequence_r[] = {
initr_trace,
initr_reloc,
/* TODO: could x86/PPC have this also perhaps? */
#ifdef CONFIG_ARM
initr_caches,
#endif
initr_reloc_global_data,
#if defined(CONFIG_SYS_INIT_RAM_LOCK) && defined(CONFIG_E500)
initr_unlock_ram_in_cache,
#endif
initr_barrier,
initr_malloc,
#ifdef CONFIG_SYS_NONCACHED_MEMORY
initr_noncached,
#endif
bootstage_relocate,
#ifdef CONFIG_DM
initr_dm,
#endif
#ifdef CONFIG_ARM
board_init, /* Setup chipselects */
#endif
/*
* TODO: printing of the clock inforamtion of the board is now
* implemented as part of bdinfo command. Currently only support for
* davinci SOC's is added. Remove this check once all the board
* implement this.
*/
#ifdef CONFIG_CLOCKS
set_cpu_clk_info, /* Setup clock information */
#endif
stdio_init_tables,
initr_serial,
initr_announce,
INIT_FUNC_WATCHDOG_RESET
#ifdef CONFIG_NEEDS_MANUAL_RELOC
initr_manual_reloc_cmdtable,
#endif
#if defined(CONFIG_PPC) || defined(CONFIG_M68K)
initr_trap,
#endif
#ifdef CONFIG_ADDR_MAP
initr_addr_map,
#endif
#if defined(CONFIG_BOARD_EARLY_INIT_R)
board_early_init_r,
#endif
INIT_FUNC_WATCHDOG_RESET
#ifdef CONFIG_LOGBUFFER
initr_logbuffer,
#endif
#ifdef CONFIG_POST
initr_post_backlog,
#endif
INIT_FUNC_WATCHDOG_RESET
#ifdef CONFIG_SYS_DELAYED_ICACHE
initr_icache_enable,
#endif
#if defined(CONFIG_PCI) && defined(CONFIG_SYS_EARLY_PCI_INIT)
/*
* Do early PCI configuration _before_ the flash gets initialised,
* because PCU ressources are crucial for flash access on some boards.
*/
initr_pci,
#endif
#ifdef CONFIG_WINBOND_83C553
initr_w83c553f,
#endif
#ifdef CONFIG_ARCH_EARLY_INIT_R
arch_early_init_r,
#endif
power_init_board,
#ifndef CONFIG_SYS_NO_FLASH
initr_flash,
#endif
INIT_FUNC_WATCHDOG_RESET
#if defined(CONFIG_PPC) || defined(CONFIG_M68K)
/* initialize higher level parts of CPU like time base and timers */
cpu_init_r,
#endif
#ifdef CONFIG_PPC
initr_spi,
#endif
#if defined(CONFIG_X86) && defined(CONFIG_SPI)
init_func_spi,
#endif
#ifdef CONFIG_CMD_NAND
initr_nand,
#endif
#ifdef CONFIG_CMD_ONENAND
initr_onenand,
#endif
#ifdef CONFIG_GENERIC_MMC
initr_mmc,
#endif
#ifdef CONFIG_HAS_DATAFLASH
initr_dataflash,
#endif
initr_env,
#ifdef CONFIG_SYS_BOOTPARAMS_LEN
initr_malloc_bootparams,
#endif
INIT_FUNC_WATCHDOG_RESET
initr_secondary_cpu,
#ifdef CONFIG_SC3
initr_sc3_read_eeprom,
#endif
#if defined(CONFIG_ID_EEPROM) || defined(CONFIG_SYS_I2C_MAC_OFFSET)
mac_read_from_eeprom,
#endif
INIT_FUNC_WATCHDOG_RESET
#if defined(CONFIG_PCI) && !defined(CONFIG_SYS_EARLY_PCI_INIT)
/*
* Do pci configuration
*/
initr_pci,
#endif
<span style="color:#FF0000;">stdio_add_devices,</span>
initr_jumptable,
#ifdef CONFIG_API
initr_api,
#endif
console_init_r, /* fully init console as a device */
#ifdef CONFIG_DISPLAY_BOARDINFO_LATE
show_board_info,
#endif
#ifdef CONFIG_ARCH_MISC_INIT
arch_misc_init, /* miscellaneous arch-dependent init */
#endif
#ifdef CONFIG_MISC_INIT_R
misc_init_r, /* miscellaneous platform-dependent init */
#endif
INIT_FUNC_WATCHDOG_RESET
#ifdef CONFIG_CMD_KGDB
initr_kgdb,
#endif
interrupt_init,
#if defined(CONFIG_ARM) || defined(CONFIG_AVR32)
initr_enable_interrupts,
#endif
#if defined(CONFIG_X86) || defined(CONFIG_MICROBLAZE) || defined(CONFIG_AVR32) \
|| defined(CONFIG_M68K)
timer_init, /* initialize timer */
#endif
#if defined(CONFIG_STATUS_LED) && defined(STATUS_LED_BOOT)
initr_status_led,
#endif
/* PPC has a udelay(20) here dating from 2002. Why? */
#ifdef CONFIG_CMD_NET
initr_ethaddr,
#endif
#ifdef CONFIG_BOARD_LATE_INIT
board_late_init,
#endif
#ifdef CONFIG_FSL_FASTBOOT
initr_fastboot_setup,
#endif
#ifdef CONFIG_CMD_SCSI
INIT_FUNC_WATCHDOG_RESET
initr_scsi,
#endif
#ifdef CONFIG_CMD_DOC
INIT_FUNC_WATCHDOG_RESET
initr_doc,
#endif
#ifdef CONFIG_BITBANGMII
initr_bbmii,
#endif
#ifdef CONFIG_CMD_NET
INIT_FUNC_WATCHDOG_RESET
initr_net,
#endif
#ifdef CONFIG_POST
initr_post,
#endif
#if defined(CONFIG_CMD_PCMCIA) && !defined(CONFIG_CMD_IDE)
initr_pcmcia,
#endif
#if defined(CONFIG_CMD_IDE)
initr_ide,
#endif
#ifdef CONFIG_LAST_STAGE_INIT
INIT_FUNC_WATCHDOG_RESET
/*
* Some parts can be only initialized if all others (like
* Interrupts) are up and running (i.e. the PC-style ISA
* keyboard).
*/
last_stage_init,
#endif
#ifdef CONFIG_CMD_BEDBUG
INIT_FUNC_WATCHDOG_RESET
initr_bedbug,
#endif
#if defined(CONFIG_PRAM) || defined(CONFIG_LOGBUFFER)
initr_mem,
#endif
#ifdef CONFIG_PS2KBD
initr_kbd,
#endif
#ifdef CONFIG_FSL_FASTBOOT
initr_check_fastboot,
#endif
run_main_loop,
};
這裡重點研究一下stdio_add_devices函式,該函式在common/stdio.c中實現
int stdio_add_devices(void)
{
#ifdef CONFIG_SYS_I2C
i2c_init_all();
#else
#if defined(CONFIG_HARD_I2C)
i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
#endif
#endif
#ifdef CONFIG_LCD
drv_lcd_init ();
#endif
#if defined(CONFIG_VIDEO) || defined(CONFIG_CFB_CONSOLE)
<span style="color:#FF0000;">drv_video_init ();</span>
#endif
#ifdef CONFIG_KEYBOARD
drv_keyboard_init ();
#endif
#ifdef CONFIG_LOGBUFFER
drv_logbuff_init ();
#endif
drv_system_init ();
serial_stdio_init ();
#ifdef CONFIG_USB_TTY
drv_usbtty_init ();
#endif
#ifdef CONFIG_NETCONSOLE
drv_nc_init ();
#endif
#ifdef CONFIG_JTAG_CONSOLE
drv_jtag_console_init ();
#endif
#ifdef CONFIG_CBMEM_CONSOLE
cbmemc_init();
#endif
return 0;
}
int drv_video_init(void)
{
int skip_dev_init;
struct stdio_dev console_dev;
/* Check if video initialization should be skipped */
<span style="color:#FF0000;">if (board_video_skip())</span>
return 0;
/* Init video chip - returns with framebuffer cleared */
<span style="color:#FF0000;">skip_dev_init = (video_init() == -1);</span>
if (board_cfb_skip())
return 0;
#if !defined(CONFIG_VGA_AS_SINGLE_DEVICE)
debug("KBD: Keyboard init ...\n");
skip_dev_init |= (VIDEO_KBD_INIT_FCT == -1);
#endif
if (skip_dev_init)
return 0;
/* Init vga device */
memset(&console_dev, 0, sizeof(console_dev));
strcpy(console_dev.name, "vga");
console_dev.ext = DEV_EXT_VIDEO; /* Video extensions */
console_dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_SYSTEM;
console_dev.putc = video_putc; /* 'putc' function */
console_dev.puts = video_puts; /* 'puts' function */
#if !defined(CONFIG_VGA_AS_SINGLE_DEVICE)
/* Also init console device */
console_dev.flags |= DEV_FLAGS_INPUT;
console_dev.tstc = VIDEO_TSTC_FCT; /* 'tstc' function */
console_dev.getc = VIDEO_GETC_FCT; /* 'getc' function */
#endif /* CONFIG_VGA_AS_SINGLE_DEVICE */
if (stdio_register(&console_dev) != 0)
return 0;
/* Return success */
return 1;
}
board_video_skip獲取要初始化的螢幕引數arch/arm/imx-common/video.c
int board_video_skip(void)
{
int i;
int ret;
char const *panel = getenv("panel");
if (!panel) {
for (i = 0; i < display_count; i++) {
struct display_info_t const *dev = displays+i;
if (dev->detect && dev->detect(dev)) {
panel = dev->mode.name;
printf("auto-detected panel %s\n", panel);
break;
}
}
if (!panel) {
panel = displays[0].mode.name;
printf("No panel detected: default to %s\n", panel);
i = 2;
}
} else {
for (i = 0; i < display_count; i++) {
if (!strcmp(panel, displays[i].mode.name))
break;
}
}
if (i < display_count) {
ret = <span style="color:#FF0000;">ipuv3_fb_init</span>(&displays[i].mode, 0,
displays[i].pixfmt);
if (!ret) {
if (displays[i].enable)
displays[i].enable(displays + i);
printf("Display: %s (%ux%u)\n",
displays[i].mode.name,
displays[i].mode.xres,
displays[i].mode.yres);
} else
printf("LCD %s cannot be configured: %d\n",
displays[i].mode.name, ret);
} else {
printf("unsupported panel %s\n", panel);
return -EINVAL;
}
return 0;
最終呼叫video_init初始化螢幕並顯示logo
void video_init(void)
{
------
video_hw_init //螢幕初始化(根據上面獲取到的引數)
video_logo();//刷logo(位於tools/logos/xxx.bmp,該bmp點陣圖被編譯成陣列,最終被刷出來)
------
}
在刷logo的過程中會呼叫flush_cache重新整理一下緩衝區,否則影象會變得離散。
if (cfb_do_flush_cache)
flush_cache(VIDEO_FB_ADRS, VIDEO_SIZE);
VIDEO_FB_ADRS顯示基地址
VIDEO_SIZE顯示的大小
在uboot中有很多debug函式,開啟debug函式可以看到uboot中函式的呼叫過程。
dedug函式(include/common.h)的定義為
#ifdef DEBUG
#define _DEBUG 1
#else
#define _DEBUG 0
#endif
#ifndef pr_fmt
#define pr_fmt(fmt) fmt
#endif
/*
* Output a debug text when condition "cond" is met. The "cond" should be
* computed by a preprocessor in the best case, allowing for the best
* optimization.
*/
#define debug_cond(cond, fmt, args...) \
do { \
if (cond) \
printf(pr_fmt(fmt), ##args); \
} while (0)
#define debug(fmt, args...) \
debug_cond(_DEBUG, fmt, ##args)
只需在前面新增#define DEBUG即可開啟該函式。
另外,查詢函式呼叫關係時,如果有多個地方被定義,不確定具體的定義位置時,只需到該目錄下,ls -al *.o,即可確認真正被呼叫的函式。
因為該函式被編譯了,就會生成.o檔案。
相關推薦
uboot除錯總結(freescale平臺為例)
uboot入口 arch/arm/lib/crt0.S #include <config.h> #include <asm-offsets.h> #include <linux/linkage.h> /* * This file h
qt編譯除錯caffe原始碼--lenet為例
之前各種搗騰就qt載入caffe原始碼始終看不到原始碼,都知道載入cmakelist.txt檔案就ok了,但是點開工程看不到原始碼啊!!!就是下面這個介面: 各種配置也不行,然後叫來lilaoshi,見他一頓操作就ok了。步驟如下: 注:step4選擇的是我電腦本
闡述分類演算法評價標準-以網路借貸平臺為例
背景:網際網路金融雖然給投資者提供了新的理財形式,但跑路經營不善等問題同樣會帶來風險。以小貸的問題平臺和正常平臺來闡述運用二分類邏輯迴歸演算法的評價標準描述。 常見的評價指標:混淆矩陣、Accuray、Precision、Recall、Roc、Sensitive、Error Rate 1.混
db2資料庫的備份和恢復!!! (以window平臺為例)
1. 建立好新的資料庫後,首先做一個離線的全備。. E:/Program Files/IBM/SQLLIB/BIN>;db2 connect to sample #聯接到資料庫。
安裝特定版本的TensorFlow(以Linux平臺為例)
在科研學習的過程中,經常出現一些需要使用其他研究人員既有演算法程式碼的情況。這些程式碼很有可能使用版本較早的TensorFlow完成,由於TensorFlow更新很快,所以需要將TensorFlow恢復到較早版本。 以Linux平臺上的pip安
uboot中 make xxx_config 的作用(以make smdk2410_config為例)
mdk nbsp xxx cpu clu samsung uboot 作用 頭文件 1、創建到目標板相關文件的鏈接 ln -s asm-arm asm ln -s arch-s3c24x0 asm-arm/arch ln -s proc-armv asm-arm/pr
循環語句總結(代碼以C#為例)
bre else col 運行 循環條件 span 表達式 條件 ons 1. while循環 代碼格式: while(循環條件) { //循環體 } 流程圖: 解讀: 如果循環條件為真,則執行循環體執行完循環體後,再判斷條件是否為真如果為真,再執行循環體然後
【總結】遊戲框架與架構設計(Unity為例)
單機 業務 github 事件 概念 lec 集合 架構模式 wid 使用框架開發遊戲 優點:耦合性低,重用性高,部署快,可維護性高,方便管理。提高開發效率,降低開發難度 缺點:增加了系統結構和實現的復雜性,需要額外花費精力維護,不適合小型程序,易影響運行效率 常見
Java總結(隨筆)——代碼總結JDBC以及事務,以銀行轉賬,查賬等為例
模擬銀行系統 數據庫 JDBC 事務 本片文章是對上一篇文章中的事務的例子的功能擴寫,用以加深理解,以及代碼的熟練度:(1)數據庫表數據:(2)引入數據庫連接jar包(3)工具類: package org.jdbc.util; import java.io.File; import java
imx6 uboot的mtd分割槽總結(rootfs為ubi檔案系統)
轉載地址:https://blog.csdn.net/qq_29729577/article/details/51130209 此文章基於U-Boot 2014.04版本,燒寫工具為mfgtool,開發環境為yocto 前言: JFFS2、YAFFS2等專用檔案系統存在著一些技術瓶頸,如
雲端計算生產環境架構效能調優和遷移套路總結(以 AWS 為例)
最近完成了一個雲端計算平臺應用的架構調優。客戶是一個 Wordpress + MySQL 的站點,剛從本地資料中心遷移到了 AWS,由於團隊技能限制,無法充分發揮雲端計算的優勢。加之應用程式在夜間高流量時段崩潰,架構優化和遷移迫在眉睫。本文以這次架構遷移經驗為例,介紹雲端計算架構優化遷移的基本步驟和
【第四章】NB-IoT模組BC95 利用串列埠除錯助手接入華為(電信)平臺
BC95的Coap測試需要雲平臺配合,當前的支援Coap協議的平臺有華為OceanConnect平臺、電信天翼雲(除了logo其他和華為的一樣)、移動OneNet。此教程以華為的OceanConnect平臺為例進行測試。下面我將就平臺申請、平臺測開發、EVB_M1與平
Omap138開發板下以uboot2012.04.01為例分析uboot執行(二)
Omapl138記憶體和外設分佈圖 從下圖中的omapl138 top level memory map中可以看出: DSP專用的記憶體空間有: ARM專用的記憶體空間有: Start.s程式碼分析 1.通過objdump可以檢視編譯好的反彙編程式碼,-S顯
Omap138開發板下以uboot2012.04.01為例分析uboot執行(三)
Omap138記憶體分配總圖 board_init_f函式分析 該函式位於/uboot/arch/arm/lib目錄下: 1.分析該函式在記憶體中的位置 起始位置:c1080000 呼叫位置:c1081258 2.在da850sdi.h中,它的與系統相關
Omap138開發板下以uboot2012.04.01為例分析uboot執行()
繼續分析主流程: (4) malloc_start = dest_addr - TOTAL_MALLOC_LEN; mem_malloc_init (malloc_start, TOTAL_MALLOC_LEN); 這個函式的主要作用是將malloc區域的首地址
Omap138開發板下以uboot2012.04.01為例分析uboot執行(八)
(12) /* Setting environment variables */ for (i = 0; i < 3; i++) { setenv(stdio_names[i], stdio_devices[i]->na
以levenblog為例,嘗試在linux+mono平臺上部署asp.net mvc程式
仍然是路徑,果然mono移植最大的問題還是路徑,這次出現問題的web.config中的外部引用,因為配置檔案過大,levenblog將log,route,高亮等配置檔案分離,並在web.config中包含,在windows中我們只能採用<routeConfigure configSource="conf
移動平臺播放器ijkplayer開源框架分析(以IOS原始碼為例)
p_prepare_async_l呼叫stream_open,stream_open中建立了視訊渲染執行緒,該執行緒主要是進行視訊渲染工作,並對視訊進行同步,同步相關邏輯主要在這個執行緒裡面,同步的大概思路就是:有一個絕對時間作為同步起點,然後計算當前幀與上一幀時間差,然後與當前絕對時間基準源比較,如果不到時
MFC與Matlab程式設計總結 (以《Matlab與C/C++混合程式設計技術(第三版)》-劉維 第五章 生成DLL為例)
近期要完成一個任務,把人臉超解析度的演算法整合在一個系統中,嵌入人臉庫及字典集等。老闆的要求是有比較好的介面,目前也只能是VS那一套了,前一段時間完成的專案是用的MFC,這次也就是用MFC來完成吧。但是問題是,以前寫的人臉超解析度的演算法都是用Matlab寫的,Matlab有非常好的矩陣計算能力,要
以國付寶為例,如何完成給某一個平臺提供線上充值功能
線上充值 每一個支付平臺都有一個支付平臺需要傳遞的引數,請參考支付寶文件 1. 首先我定義了一個類,來確定該平臺是和哪個支付平臺做合作,可以通過傳遞引數的不同,很容易解決public interface Constant { //與資料庫配置保持一致 public