色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

riscv在rt-smart中的板級初始化

RTThread物聯(lián)網(wǎng)操作系統(tǒng) ? 來源:未知 ? 2023-02-09 17:45 ? 次閱讀

本文章的代碼來自于rt-smart中針對qemu-virt-riscv的bsp

倉庫地址 https://gitee.com/rtthread/rt-thread/tree/rt-smart/

commit ID:d28249c08a152bcf0e1a076cf5b4b082c0a84add

qemu-virt-riscv介紹

簡介

Virt板不對應(yīng)于任何真實硬件的平臺;它是為虛擬機設(shè)計的。如果你只是想運行Linux等客戶機,而不關(guān)心重現(xiàn)真實世界硬件的特殊性和局限性,那么它是推薦的板卡類型。(摘自https://www.qemu.org/docs/master/system/riscv/virt.html)

內(nèi)存空間布局(包括外設(shè)地址)

staticconstMemMapEntryvirt_memmap[]={
[VIRT_DEBUG]={0x0,0x100},
[VIRT_MROM]={0x1000,0xf000},
[VIRT_TEST]={0x100000,0x1000},
[VIRT_RTC]={0x101000,0x1000},
[VIRT_CLINT]={0x2000000,0x10000},
[VIRT_ACLINT_SSWI]={0x2F00000,0x4000},
[VIRT_PCIE_PIO]={0x3000000,0x10000},
[VIRT_PLIC]={0xc000000,VIRT_PLIC_SIZE(VIRT_CPUS_MAX*2)},
[VIRT_APLIC_M]={0xc000000,APLIC_SIZE(VIRT_CPUS_MAX)},
[VIRT_APLIC_S]={0xd000000,APLIC_SIZE(VIRT_CPUS_MAX)},
[VIRT_UART0]={0x10000000,0x100},/*串口設(shè)備*/
[VIRT_VIRTIO]={0x10001000,0x1000},
[VIRT_FW_CFG]={0x10100000,0x18},
[VIRT_FLASH]={0x20000000,0x4000000},
[VIRT_IMSIC_M]={0x24000000,VIRT_IMSIC_MAX_SIZE},
[VIRT_IMSIC_S]={0x28000000,VIRT_IMSIC_MAX_SIZE},
[VIRT_PCIE_ECAM]={0x30000000,0x10000000},
[VIRT_PCIE_MMIO]={0x40000000,0x40000000},
[VIRT_DRAM]={0x80000000,0x0},/*DDR空間*/
};

rt-smart針對virt board的ddr空間規(guī)劃

參考鏈接腳本

bspqemu-virt64-riscvlink.lds

以及board.h中的相關(guān)定義

bspqemu-virt64-riscvdriveroard.h

得到ddr的空間規(guī)劃如下

內(nèi)容地址空間
代碼段數(shù)據(jù)段棧空間以及bss段0x80200000 ~ __bss_end
堆空間__bss_end ~ __bss_end + 100M
頁分配空間__bss_end + 100M ~ __bss_end + 200M

rt-smart針對virt board的初始化

整體初始化

rt_hw_board_init定義了與qemu-virt-riscv相關(guān)的板級初始化的全部內(nèi)容,包括內(nèi)存系統(tǒng),plic中斷子系統(tǒng),定時器系統(tǒng)以及串口設(shè)備等。它由rtthread_startup調(diào)用,完整的調(diào)用路徑如下。

(libcpu isc-vvirt64startup_gcc.S)_start->primary_cpu_entry->entry->rtthread_startup->rt_hw_board_init

源碼如下

voidrt_hw_board_init(void)
{
#ifdefRT_USING_USERSPACE
rt_page_init(init_page_region);
/*initmmu_infostructure*/
rt_hw_mmu_map_init(&mmu_info,(void*)(USER_VADDR_START-IOREMAP_SIZE),IOREMAP_SIZE,(rt_size_t*)MMUTable,0);
//thisAPIisreservedcurrentlysincePLICetchadnotbeenportingcompletelytoMMUversion
rt_hw_mmu_kernel_map_init(&mmu_info,0x00000000UL,0x80000000);
/*setupregion,andenableMMU*/
rt_hw_mmu_setup(&mmu_info,platform_mem_desc,NUM_MEM_DESC);

#endif

#ifdefRT_USING_HEAP
/*initializememorysystem*/
rt_system_heap_init(RT_HW_HEAP_BEGIN,RT_HW_HEAP_END);
#endif

plic_init();

rt_hw_interrupt_init();

rt_hw_uart_init();

#ifdefRT_USING_CONSOLE
/*setconsoledevice*/
rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
#endif/*RT_USING_CONSOLE*/

rt_hw_tick_init();

#ifdefRT_USING_COMPONENTS_INIT
rt_components_board_init();
#endif

#ifdefRT_USING_HEAP
rt_kprintf("heap:[0x%08x-0x%08x] ",(rt_ubase_t)RT_HW_HEAP_BEGIN,(rt_ubase_t)RT_HW_HEAP_END);
#endif/*RT_USING_HEAP*/
}

rt_page_init

rt-smart中使用了buddy算法管理了一部分內(nèi)存區(qū)域,系統(tǒng)使用page_alloc來向buddy管理的內(nèi)存區(qū)域申請內(nèi)存資源,像linux一樣每個page是4k的大小。rt-smart采用buddy算法將系統(tǒng)中部分可用的物理內(nèi)存頁面按照每1個頁面、2個頁面、4個頁面等等劃分為了不同的單元。詳情可參考這篇文章https://club.rt-thread.org/ask/article/3e3a9a0b6d3e2105.html

voidrt_page_init(rt_region_treg)
{
inti;

LOG_D("split0x%08x0x%08x ",reg.start,reg.end);

reg.start+=ARCH_PAGE_MASK;
reg.start&=~ARCH_PAGE_MASK;

reg.end&=~ARCH_PAGE_MASK;

{
intnr=ARCH_PAGE_SIZE/sizeof(structpage);
inttotal=(reg.end-reg.start)>>ARCH_PAGE_SHIFT;
intmnr=(total+nr)/(nr+1);

LOG_D("nr=0x%08x ",nr);
LOG_D("total=0x%08x ",total);
LOG_D("mnr=0x%08x ",mnr);

RT_ASSERT(mnr
page_start=(structpage*)reg.start;
reg.start+=(mnr<page_addr=(void*)reg.start;
page_nr=(reg.end-reg.start)>>ARCH_PAGE_SHIFT;
}

這里rt-smart直接將一部分頁表空間分配給struct page去使用,有可能會造成頁面的浪費。例如當(dāng)total=7,nr=5時,mnr=2,也就是倆個頁表用于存儲page,五個頁表是真正可以被alloc_page申請的。但實際上五個頁表只需要一個頁表的空間就可以存放page結(jié)構(gòu)體了,相當(dāng)于浪費了一個頁表。

rt_hw_mmu_map_init

#defineUSER_VADDR_START0x100000000UL
#defineIOREMAP_SIZE(1ul<
intrt_hw_mmu_map_init(rt_mmu_info*mmu_info,void*v_address,rt_size_tsize,rt_size_t*vtable,rt_size_tpv_off)
{
/*代碼省略*/
mmu_info->vtable=vtable;
mmu_info->vstart=va_s;
mmu_info->vend=va_e;
mmu_info->pv_off=pv_off;

return0;
}

mmu_info是一個全局變量,在調(diào)用rt_hw_mmu_map_init后,(USER_VADDR_START - IOREMAP_SIZE) ~ USER_VADDR_START 這片虛擬地址空間將來專門提供給ioremap來使用。也就是ioremap返回的虛擬地址區(qū)間就是0xc0000000 ~ 0xFFFFFFFF

rt_hw_mmu_kernel_map_init

voidrt_hw_mmu_kernel_map_init(rt_mmu_info*mmu_info,rt_size_tvaddr_start,rt_size_tsize)
{
rt_size_tpaddr_start=__UMASKVALUE(VPN_TO_PPN(vaddr_start,mmu_info->pv_off),PAGE_OFFSET_MASK);
rt_size_tva_s=GET_L1(vaddr_start);
rt_size_tva_e=GET_L1(vaddr_start+size-1);
rt_size_ti;

for(i=va_s;i<=?va_e;?i++)
{
mmu_info->vtable[i]=COMBINEPTE(paddr_start,PAGE_ATTR_RWX|PTE_G|PTE_V);
paddr_start+=L1_PAGE_SIZE;
}

rt_hw_cpu_tlb_invalidate();
}

這里將0x0 ~ 0x80000000的物理地址空間做了offset為0的一比一映射,且只使用了一級頁表。之后0x80000000之下的地址CPU都可以直接訪問了。從頁表的屬性配置上看,這片區(qū)域是nocache的。

rt_hw_mmu_setup

#defineKERNEL_VADDR_START0x80000000
#definePV_OFFSET0

structmem_descplatform_mem_desc[]={
{KERNEL_VADDR_START,KERNEL_VADDR_START+0x10000000-1,KERNEL_VADDR_START+PV_OFFSET,NORMAL_MEM},
};

voidrt_hw_mmu_setup(rt_mmu_info*mmu_info,structmem_desc*mdesc,intdesc_nr)
{
void*err;
for(size_ti=0;i{
size_tattr;
switch(mdesc->attr)
{
caseNORMAL_MEM:
attr=MMU_MAP_K_RWCB;
break;
caseNORMAL_NOCACHE_MEM:
attr=MMU_MAP_K_RWCB;
break;
caseDEVICE_MEM:
attr=MMU_MAP_K_DEVICE;
break;
default:
attr=MMU_MAP_K_DEVICE;
}
rt_kprintf("vaddrstart:%lxpaddr_start:%lx ",mdesc->vaddr_start,mdesc->paddr_start);
err=_rt_hw_mmu_map(mmu_info,(void*)mdesc->vaddr_start,(void*)mdesc->paddr_start,
mdesc->vaddr_end-mdesc->vaddr_start+1,attr);
mdesc++;
}
rt_hw_mmu_switch((void*)MMUTable);
}

這里首先將0x80000000 ~ 0x90000000這片區(qū)域做了offset為0的線性映射,映射使用的是三級頁表一頁一頁映射的,相當(dāng)于page的區(qū)域也被映射好了。之后調(diào)用rt_hw_mmu_switch配置SATP配置MMU的地址翻譯模式為SV39。STAP的mode被配置后,MMU就相當(dāng)于開啟了。

將rtconfig.h中的PV_OFFSET改為非0值后系統(tǒng)無法啟動,對比bsp/qemu-vexpress-a9中board.c里關(guān)于頁表的配置這塊兒應(yīng)該還是有問題的。

rt_hw_tick_init

intrt_hw_tick_init(void)
{
/*Readcoreid*/
//unsignedlongcore_id=current_coreid();
unsignedlonginterval=1000/RT_TICK_PER_SECOND;

/*CleartheSupervisor-TimerbitinSIE*/
clear_csr(sie,SIP_STIP);

/*calculatethetickcycles*/
//tick_cycles=interval*sysctl_clock_get_freq(SYSCTL_CLOCK_CPU)/CLINT_CLOCK_DIV/1000ULL-1;
tick_cycles=40000;
/*Settimer*/
sbi_set_timer(get_ticks()+tick_cycles);

/*EnabletheSupervisor-TimerbitinSIE*/
set_csr(sie,SIP_STIP);

return0;
}

這里使用的是riscv中的mtime。mtime是riscv中定義的一個64位的系統(tǒng)計時器,它被要求工作在常開的時鐘域下。內(nèi)核中使用以下指令可以讀取mtime的值

staticuint64_tget_ticks()
{
__asm____volatile__(
"rdtime%0"
:"=r"(time_elapsed));
returntime_elapsed;
}

補充知識,在qemu中這個時鐘的獲取來源如下

staticinlineint64_tget_clock_realtime(void)
{
structtimevaltv;

gettimeofday(&tv,NULL);
returntv.tv_sec*1000000000LL+(tv.tv_usec*1000);
}

sbi_set_timer并不是設(shè)置timer本身的值,而是設(shè)置機器模式計時器比較值寄存器MTIMECMPH, MTIMECMPL的值,當(dāng)系統(tǒng)計時器的值小于等于 {M/STIMECMPH[31:0],M/STIMECMPL[31:0]}的值時不產(chǎn)生中斷;當(dāng)系統(tǒng)計時器的值大于 {M/STIMECMPH[31:0],M/STIMECMPL[31:0]} 的值時 CLINT產(chǎn)生對應(yīng)的計時器中斷。它的配置過程為rt-smart將比較寄存器的配置按規(guī)則組織為sbi_call的指令,將指令類型指令參數(shù)等放入cpu的a0~a7的寄存器,然后調(diào)用ecall指令使cpu陷入M態(tài)。

sbi_set_timer->SBI_CALL1(SBI_SET_TIMER, 0, val)->sbi_call

static__inlinestructsbi_ret
sbi_call(uint64_targ7,uint64_targ6,uint64_targ0,uint64_targ1,
uint64_targ2,uint64_targ3,uint64_targ4)

{
structsbi_retret;

registeruintptr_ta0__asm("a0")=(uintptr_t)(arg0);
registeruintptr_ta1__asm("a1")=(uintptr_t)(arg1);
registeruintptr_ta2__asm("a2")=(uintptr_t)(arg2);
registeruintptr_ta3__asm("a3")=(uintptr_t)(arg3);
registeruintptr_ta4__asm("a4")=(uintptr_t)(arg4);
registeruintptr_ta6__asm("a6")=(uintptr_t)(arg6);
registeruintptr_ta7__asm("a7")=(uintptr_t)(arg7);

__asm__volatile(
"ecall"
:"+r"(a0),"+r"(a1)
:"r"(a2),"r"(a3),"r"(a4),"r"(a6),"r"(a7)
:"memory");

ret.error=a0;
ret.value=a1;
return(ret);
}

CPU陷入M態(tài)后,opensbi會處理這個ecall產(chǎn)生的異常。獲取內(nèi)核放到寄存器中參數(shù),把新的值賦值給比較值寄存器,并清除計時器中斷

voidsbi_timer_event_start(u64next_event)
{
if(timer_dev&&timer_dev->timer_event_start)
timer_dev->timer_event_start(next_event);
csr_clear(CSR_MIP,MIP_STIP);
csr_set(CSR_MIE,MIP_MTIP);
}

其他

之后的初始化都是原先rt-thread中的內(nèi)容了,感興趣的讀者可以自行查閱rt-thread官方的《RT-THREAD 編程指南》手冊來學(xué)習(xí)。另外需要注意的點在plic_init中,plic的寄存器的基地址沒有使用ioremap就直接使用了,這是因為上面描述的0x0 ~ 0x80000000的物理地址空間被做了offset為0的一比一映射。

rt-smart的ioremap實現(xiàn)

void*rt_ioremap(void*paddr,size_tsize)
{
return_ioremap_type(paddr,size,MM_AREA_TYPE_PHY);
}

void*rt_ioremap_nocache(void*paddr,size_tsize)
{
return_ioremap_type(paddr,size,MM_AREA_TYPE_PHY);
}

void*rt_ioremap_cached(void*paddr,size_tsize)
{
return_ioremap_type(paddr,size,MM_AREA_TYPE_PHY_CACHED);
}

rt-smart中的ioremap實際上只分了倆種映射方式,分別是cache和nocache。在當(dāng)前的qemu-virt64-riscv里,cache的屬性沒有配置到頁表中,我也沒有查qemu的頁表支不支持配置cache,感興趣的讀者請參考C906的相關(guān)代碼libcpu/risc-v/t-head/c906/riscv_mmu.h

/*C-SKYextend*/
#definePTE_SEC(1UL</*Security*/
#definePTE_SHARE(1UL</*Shareable*/
#definePTE_BUF(1UL</*Bufferable*/
#definePTE_CACHE(1UL</*Cacheable*/
#definePTE_SO(1UL</*StrongOrder*/
#defineMMU_MAP_K_DEVICE(PAGE_ATTR_RWX|PTE_V|PTE_G|PTE_SO|PTE_BUF|PTE_A|PTE_D)
#defineMMU_MAP_K_RWCB(PAGE_ATTR_RWX|PTE_V|PTE_G|PTE_SHARE|PTE_BUF|PTE_CACHE|PTE_A|PTE_D)
staticvoid*_ioremap_type(void*paddr,size_tsize,inttype)
{
void*v_addr=NULL;
size_tattr;

switch(type)
{
caseMM_AREA_TYPE_PHY:
attr=MMU_MAP_K_DEVICE;
break;
caseMM_AREA_TYPE_PHY_CACHED:
attr=MMU_MAP_K_RWCB;
break;
default:
returnv_addr;
}

rt_mm_lock();
v_addr=rt_hw_mmu_map(&mmu_info,0,paddr,size,attr);
if(v_addr)
{
intret=lwp_map_area_insert(&k_map_area,(size_t)v_addr,size,type);
if(ret!=0)
{
_iounmap_range(v_addr,size);
v_addr=NULL;
}
}
rt_mm_unlock();
returnv_addr;
}

__ioremap_type中會記錄頁表要配置的屬性然后調(diào)用rt_hw_mmu_map進行映射。之后會將映射得到的虛擬地址插入到k_map_area中。

void*_rt_hw_mmu_map(rt_mmu_info*mmu_info,void*v_addr,void*p_addr,rt_size_tsize,rt_size_tattr)
{
/*代碼省略*/
if(v_addr)
{
/*代碼省略*/
}
else
{
vaddr=find_vaddr(mmu_info,pages);
}

if(vaddr)
{
ret=__rt_hw_mmu_map(mmu_info,(void*)vaddr,p_addr,pages,attr);

if(ret==0)
{
rt_hw_cpu_tlb_invalidate();
return(void*)(vaddr|GET_PF_OFFSET((rt_size_t)p_addr));
}
}
return0;
}

ioremap傳入的虛擬地址是0,所以這里先需要調(diào)用find_vaddr得到一個可用的虛擬地址。另一個傳入find_vaddr的參數(shù)pages代表要要映射的物理內(nèi)存區(qū)域需要多少個page(4K).

staticsize_tfind_vaddr(rt_mmu_info*mmu_info,intpages)
{
size_tloop_pages;
size_tva;
size_tfind_va=0;
intn=0;
size_ti;

loop_pages=(mmu_info->vend-mmu_info->vstart)?(mmu_info->vend-mmu_info->vstart):1;
loop_pages<<=?(ARCH_INDEX_WIDTH?*?2);
va=mmu_info->vstart;
va<<=?(ARCH_PAGE_SHIFT?+?ARCH_INDEX_WIDTH?*?2);
for(i=0;iif(_rt_hw_mmu_v2p(mmu_info,(void*)va)){
n=0;
find_va=0;
continue;
}
if(!find_va){
find_va=va;
}
n++;
if(n>=pages){
returnfind_va;
}
}
return0;
}

這里會從mmu_info->vstart的虛擬地址開始找,這個地址就是最前面提到的0xC0000000。從0XC0000000開始一個page一個page的去找,看對應(yīng)的虛擬地址有沒有被映射。如果沒有,那么將va賦值給find_va。之后會繼續(xù)往后查找看能不能找到連續(xù)的虛擬內(nèi)存空間大小可以滿足ioremap需要的大小。如果滿足大小最終就返回找到的虛擬地址。總結(jié)這個過程就是尋找一塊連續(xù)的沒有被映射的大小滿足的虛擬地址空間。


———————End———————


你可以添加微信:rtthread2020 為好友,注明:公司+姓名,拉進RT-Thread官方微信交流群!



愛我就給我點在看

點擊閱讀原文進入官網(wǎng)


原文標題:riscv在rt-smart中的板級初始化

文章出處:【微信公眾號:RTThread物聯(lián)網(wǎng)操作系統(tǒng)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • RT-Thread
    +關(guān)注

    關(guān)注

    31

    文章

    1285

    瀏覽量

    40095
收藏 人收藏

    評論

    相關(guān)推薦

    STM32F407 MCU使用SD NAND?不斷電初始化失效解決方案

    STM32F407微控制器單元(MCU)與SD NAND的結(jié)合提供了強大的存儲解決方案。然而,不斷電初始化失效問題可能會導(dǎo)致系統(tǒng)穩(wěn)定性和數(shù)據(jù)完整性受損。我們將STM32F407與SD NAND集成時可能遇到的初始化問題,并提供專業(yè)的解決方案。
    的頭像 發(fā)表于 12-11 10:51 ?316次閱讀
    STM32F407 MCU使用SD NAND?不斷電<b class='flag-5'>初始化</b>失效解決方案

    segger編譯器初始化問題

    的圖; 2.第二張圖是該變量文件的所有操作,第一行是初始化,該行代碼初始化部分最后一個,執(zhí)行完就是主循環(huán)了; 3.第2,3行也是對變量
    發(fā)表于 12-09 18:06

    基于旋轉(zhuǎn)平移解耦框架的視覺慣性初始化方法

    精確和魯棒的初始化對于視覺慣性里程計(VIO)至關(guān)重要,因為不良的初始化會嚴重降低姿態(tài)精度。
    的頭像 發(fā)表于 11-01 10:16 ?326次閱讀
    基于旋轉(zhuǎn)平移解耦框架的視覺慣性<b class='flag-5'>初始化</b>方法

    TMS320C6000 McBSP初始化

    電子發(fā)燒友網(wǎng)站提供《TMS320C6000 McBSP初始化.pdf》資料免費下載
    發(fā)表于 10-26 10:10 ?0次下載
    TMS320C6000 McBSP<b class='flag-5'>初始化</b>

    如何在i.MX RT微控制器上初始化LWIP協(xié)議棧

    i.MX RT微控制器上初始化LWIP協(xié)議棧是一個復(fù)雜但有趣的過程,它涉及多個步驟和關(guān)鍵組件的配置.
    的頭像 發(fā)表于 10-12 11:48 ?357次閱讀
    如何在i.MX <b class='flag-5'>RT</b>微控制器上<b class='flag-5'>初始化</b>LWIP協(xié)議棧

    RK3568平臺RT-smart系統(tǒng)跑不起來,為什么?

    RK3568平臺RT-smart系統(tǒng)跑不起來
    發(fā)表于 09-13 07:28

    Keil變量不被初始化方法

    有些時候我們的應(yīng)用過程要求變量有連續(xù)性,或者現(xiàn)場保留,例如Bootloader跳轉(zhuǎn),某種原因的復(fù)位過程我們有些關(guān)鍵變量不能被初始化
    的頭像 發(fā)表于 08-30 11:47 ?648次閱讀
    Keil<b class='flag-5'>中</b>變量不被<b class='flag-5'>初始化</b>方法

    瀚海微SD NAND應(yīng)用之SD協(xié)議存儲功能描述2 初始化命令

    初始化和識別過程: 總線激活后,主機啟動卡初始化和識別過程。 初始化過程從SD SEND OP COND (ACMD41)開始,通過設(shè)置其操作條件和OCR的HCS位。HCS (Ho
    的頭像 發(fā)表于 07-22 10:54 ?359次閱讀
    瀚海微SD NAND應(yīng)用之SD協(xié)議存儲功能描述2 <b class='flag-5'>初始化</b>命令

    初始化IO口為外部中斷線的時候,最先初始化的會被后初始化的覆蓋掉為什么?

    初始化IO口為外部中斷線的時候,比如GPIOA6與GPIOB6先后初始化為外部中斷,最先初始化的會被后初始化的覆蓋掉,不知道是為什么?
    發(fā)表于 05-14 08:26

    stm32定時器初始化參數(shù)之前是否必須開啟對應(yīng)時鐘?

    調(diào)用RT-thread的PWM組件,發(fā)現(xiàn)HAL_TIM_PWM_MspInit用的默認的,沒有任何操作的函數(shù)。這就導(dǎo)致調(diào)用HAL_TIM_PWM_Init和HAL_TIM_Base_Init初始化
    發(fā)表于 04-18 06:42

    字符型、指針型等變量等該如何初始化

     對于數(shù)值類型的變量往往初始化為0,但對于其他類型的變量,如字符型、指針型等變量等該如何初始化呢?
    的頭像 發(fā)表于 03-18 11:02 ?1438次閱讀

    MCU單片機GPIO初始化該按什么順序配置?為什么初始化時有電平跳變?

    GPIO初始化時有時鐘配置、模式配置、輸出配置、復(fù)用配置,那么在編寫初始化代碼時,到底該按什么順序執(zhí)行呢?如果順序不當(dāng)那初始化過程可能會出現(xiàn)短暫的電平跳變。
    的頭像 發(fā)表于 02-22 11:07 ?1528次閱讀
    MCU單片機GPIO<b class='flag-5'>初始化</b>該按什么順序配置?為什么<b class='flag-5'>初始化</b>時有電平跳變?

    如何在PSOC 6初始化QSPI?

    *cfg,uint32_t hz) 我查看了 \" MTB CAT1 外圍設(shè)備驅(qū)動程序庫的文檔。\"初始化不會那么復(fù)雜,對吧? 我的配置有什么問題? 在此先感謝。
    發(fā)表于 01-26 07:48

    串口初始化一般是初始化哪些內(nèi)容

    串口初始化是指在使用串口進行數(shù)據(jù)通信之前,對串口進行一系列的設(shè)置和配置,以確保串口能夠正常工作。串口初始化的內(nèi)容主要包括以下幾個方面: 串口硬件設(shè)置:首先,需要確定要使用的串口是哪一個,通常計算機
    的頭像 發(fā)表于 01-04 09:39 ?3158次閱讀

    labview運行后如何初始化

    LabVIEW是一款強大的圖形編程軟件,在運行之前通常需要進行一些初始化操作。本文將詳細介紹LabVIEW運行前的初始化過程,并提供了一些常用的初始化方法。 創(chuàng)建新項目:
    的頭像 發(fā)表于 12-28 17:24 ?2630次閱讀
    主站蜘蛛池模板: 99久久久久亚洲AV无码| 国内精品久久人妻无码HD浪潮| 九九久久国产精品大片| 热久久视久久精品18| 岳扒开让我添| 国产精品悠悠久久人妻精品| 女张腿男人桶羞羞漫画| 亚洲中文字幕日产乱码2020| 国产成人一区二区三中文| 男人叼女人| 永久免费的无码中文字幕| 国产精品视频人人做人人爽| 强奸美女老师| 2021国产精品| 久久精品久久精品| 亚洲AV 无码AV 中文字幕| 成人在线观看播放| 欧美日韩亚洲中字二区| 在线日本v二区不卡| 精品淑女少妇AV久久免费| 校花爽好大快深点h| 给个男人都懂的网址2019| 欧美日韩高清一区| 91久久精品国产亚洲| 久久全国免费观看视频| 亚洲欧美日韩另类精品一区二区三区| 国产精品成人网| 三级全黄a| 成人在线视频免费看| 欧美日韩亚洲一区视频二区| 99精品国产福利在线观看| 伦理片免费秋霞e| 真实的强视频免费网站 | 国产中文字幕在线| 我的年轻漂亮继坶三级| 国产成人精品免费视频下载 | 大学生第一次破苞疼哭了| 青草影院内射中出高潮-百度| 99在线观看免费| 欧美日韩第一区| xxxxx69hd杨幂|