最近跟研究了Device Tree這東西 , 挺有意思的 , 有時間來寫系列文章(哈) , 目前暫先簡單筆記一下心得 ^^

==========================================================================

在Linux 2.6以前 , 很多ARM base開發版上的Device Driver都用Hard Code方式直接寫到Kernel裡 , 

所以Linux Kernel漸漸地像個胖子 , 又肥又腫.

2011年後 , Device Tree採用 , 許多ARM base開發版上的Device Driver可以透過Device Tree傳遞給Linux Kernel , 

增加可移植性與幫Linux Kernel減肥 ~ 

 

DTS (device tree source)  

.dts採ASCII格式 , 非常人性化 , 適合直接閱讀

 

DTC (device tree compiler)

將.dts編譯為.dtb的工具

 

DTB (device Tree Blob)

給Linux Kernel看的machine code.

make dtbs可生成.dtb檔

Bootloader將帶起Kernel的過程 , 需要將.dtb放到memory , 並在bootcmd裡面宣告.dtb位址讓Kernel知道

==========================================================================

What I say in next is very important .....(抄襲某電影 XD) 

有了Device Tree這個東東後 : 

(1) 不需要在Kernel裡註冊Platform Device, 宣告IO resource, IRQ, GPIO Pins

     這些資料直接宣告在dts裡面 , 然後利用dtc編譯成dtb , Kernel會自己解析超展開~~

(2) Platform Driver裡要增加MODULE_DEVICE_TABLE

    下面是一個簡單的範例

static const struct of_device_id arm_smmu_of_match[] = {
        { .compatible = "arm,smmu-v1", .data = (void *)ARM_SMMU_V1 },
        { .compatible = "arm,smmu-v2", .data = (void *)ARM_SMMU_V2 },
        { .compatible = "arm,mmu-400", .data = (void *)ARM_SMMU_V1 },
        { .compatible = "arm,mmu-401", .data = (void *)ARM_SMMU_V1 },
        { .compatible = "arm,mmu-500", .data = (void *)ARM_SMMU_V2 },
        { },
};
MODULE_DEVICE_TABLE(of, arm_smmu_of_match);

static int arm_smmu_device_dt_probe(struct platform_device *pdev)
{
        const struct of_device_id *of_id;

        of_id = of_match_node(arm_smmu_of_match, dev->of_node);
        smmu->version = (enum arm_smmu_arch_version)of_id->data;

        ...

        if (smmu->version > ARM_SMMU_V1) {
                ...
        }
}

static struct platform_driver arm_smmu_driver = {
       .driver = {
                .name           = "arm-smmu",
                .of_match_table = of_match_ptr(arm_smmu_of_match),
        },
        .probe  = arm_smmu_device_dt_probe,
        .remove = arm_smmu_device_remove,
};

 

Crystina 發表在 痞客邦 留言(0) 人氣()

基礎中的基礎 ~ 

程式原始碼

#include "stdafx.h"
#include "string.h"
#include <stdio.h>
#include <stdlib.h>

#define ELEMENT_SIZE    10
int _tmain(int argc, _TCHAR* argv[])
{
    int    iLoop;
    int iCheckIndex;
    
    int iArray[ELEMENT_SIZE] = {13,99,82,24,57,100,84,90,82,71};
    int iTemp;
    
    // BubbleSort
    for( iLoop = 0 ; iLoop < (ELEMENT_SIZE-1) ; iLoop++ )
    {
        for( iCheckIndex = (iLoop+1) ; iCheckIndex < ELEMENT_SIZE ; iCheckIndex++ )
        {
            if ( iArray[iLoop] > iArray[iCheckIndex] )
            {
                iTemp = iArray[iLoop];
                iArray[iLoop] = iArray[iCheckIndex];
                iArray[iCheckIndex] = iTemp;
            }
        }
    }

    
    
    for( iLoop = 0 ; iLoop < ELEMENT_SIZE ; iLoop++ )
    {
        printf("%d ",iArray[iLoop]);
    }
    printf("\n");
    
    

    system("pause");
    
    return 0;
}

程式執行結果

 

Crystina 發表在 痞客邦 留言(0) 人氣()

Link List算是基礎資料結構的練習 , Embedded System因為資源有限 , 會比較常用 ~ 

這種東西說難不難 , 但久沒用還真的會有點忘記 , 所以照慣例筆記一下 ^^

=====================================================

下面是一個Link List練習題 ,

(1) 產生5個nodes , 分別為a,b,c,d,e , 其內容各為5,6,8,9,10

(2) 在node b 與 node c之間插入node b1 , 其內容為7

(3) 刪除 node b

程式原始碼

#include <stdio.h>
#include <stdlib.h>

typedef struct node
{
    int iData;
    struct node* pNext;
}TNode;

TNode* Create_node( int iData )
{
   
    TNode* ptr_Node = (TNode*)malloc(sizeof(TNode));

    ptr_Node->iData = iData;
    ptr_Node->pNext = NULL;

    return ptr_Node;
}

void Insert_node(TNode* n1, TNode* n2)
{
    // Insert n2 between n1 and n1 original next
    n2->pNext = n1->pNext;        // n2 next = n1 original next    
    n1->pNext = n2;                // n1 netx = n2
}

void Remove_node(TNode* n1)
{
    n1->pNext = n1->pNext->pNext;    // n1 netx = n2's next
}

int main()
{
    // Create 5 nodes , that is "5 6 8 9 10"
    TNode* a = Create_node(5);
    TNode* b = Create_node(6);
    TNode* c = Create_node(8);
    TNode* d = Create_node(9);
    TNode* e = Create_node(10);

    // Setup Link List
    a->pNext = b;
    b->pNext = c;
    c->pNext = d;
    d->pNext = e;
    e->pNext = NULL;

    printf("(1)Link List : %d -> %d -> %d -> %d -> %d \n"  ,a->iData
                                                           ,a->pNext->iData
                                                           ,a->pNext->pNext->iData
                                                           ,a->pNext->pNext->pNext->iData
                                                           ,a->pNext->pNext->pNext->pNext->iData);

    // 1. Insert node between 6 and 8 and data is 7
    TNode* b1 = Create_node(7);
    Insert_node(b,b1);

    printf("(2)Link List : %d -> %d -> %d -> %d -> %d -> %d\n"  ,a->iData
                                                           ,a->pNext->iData
                                                           ,a->pNext->pNext->iData
                                                           ,a->pNext->pNext->pNext->iData
                                                           ,a->pNext->pNext->pNext->pNext->iData
                                                           ,a->pNext->pNext->pNext->pNext->pNext->iData);


    // 2. Remove node between 8 and 10 , that is "5 6 7 8 10"
    Remove_node(c);
    printf("(3)Link List : %d -> %d -> %d -> %d -> %d \n"  ,a->iData
                                                           ,a->pNext->iData
                                                           ,a->pNext->pNext->iData
                                                           ,a->pNext->pNext->pNext->iData
                                                           ,a->pNext->pNext->pNext->pNext->iData);

    system("pause");
    
    return 0;
}

程式執行結果

 

Crystina 發表在 痞客邦 留言(0) 人氣()

心血來潮寫了個簡單小程式

user輸入小時與分鐘 , 程式自動計算時針與分針的角度 ( 夠簡單吧  ^+++^ )

程式碼

#include "stdafx.h"
#include "string.h"
#include <stdio.h>
#include <stdlib.h>

int _tmain(int argc, _TCHAR* argv[])
{
    int iHr;
    int iMin;
    int iDegree;

    printf("Please keyin Hour (1~12) : ");
    scanf("%d",&iHr);

    printf("Please keyin Minute (0 ~ 59) : ");
    scanf("%d",&iMin);
    
    // 360 / 12 = 30 (HR)
    // 360 / 60 = 6  (Min)

    iHr *= 30;
    iMin *= 6;
    iDegree = (iHr-iMin);
    if( iDegree > 180 )
    {
        iDegree = (360-iDegree);
    }
    printf("Degree : %d\n",iDegree);

    system("pause");
    
    return 0;
}

測試結果

Crystina 發表在 痞客邦 留言(0) 人氣()

最近比較有時間 , 在學長建議下 , 開始寫些跟工作相關的技術文章 , 當作複習 , 也順便筆記 , 年紀大了 , 漏電速度比較快 , 哈 XD

技巧 

利用陣列方式儲存輸入數字進行運算 , 共分為3步驟 

Step1 : 輸入字串轉換為數字

     ex String[] = "1234"

                String[0] = '1'  ,  String[1] = '2' , String[2] = '3' , String[3] = '4'

                則 Big[3] = '1' - '0' = 1 , Big[2] = 2 , Big[1] = 3 , Big[0] = 4 , 故必須先金輸入字串進行轉換

Step2 : 逐筆相加 , 有進位設定Carry

     ex Big_A[1] = 8 , Big_A[0] = 3  

                Big_B[1] = 7 , Big_B[0] = 9

                則  Big_A[0] + Big_B[0] = 3 + 9 = 11 = Result 

               (Result / 10)   > 0  因此設定 Carry[0] = 1 , 代表有進位

     接著 Result = (Result % 10)   

Step3 : 進位處理

程式碼 :

/* Source Code By Christine , 2016-08-31 */

#include "stdafx.h"
#include "string.h"
#include <stdio.h>
#include <stdlib.h>

#define MAX_LEN    200
void Read_from_String_to_Int( char* pcInput , int* iBig , int* iBigLen )
{    
    int i;
    int iStrLen = strlen(pcInput);

    *iBigLen = iStrLen;
    for( i = 0 ; i < iStrLen ; i++ )
    {
        iBig[iStrLen-i-1] = (pcInput[i] - '0');
    }
}

void Process_Addition( int* iBig1 , int* iBig2, int* iBigResult , int iBigLen1, int iBigLen2)
{
    
    int iLen;
    int i;
    int iResult;
    int iCarry[MAX_LEN];

    for( i = 0 ; i < MAX_LEN ; i++ ) iCarry[i] = 0;
    
    // Step1 : 確認長度
    if(iBigLen1 > iBigLen2) iLen=iBigLen1; else iLen=iBigLen2;
    
    // Step2 : 逐位相加
    for( i = 0 ; i < iLen ; i++ )
    {
        iResult = ( iBig1[iLen-i-1] + iBig2[iLen-i-1]);
        if((iResult/10) > 0 )iCarry[iLen-i-1]++;
        iBigResult [iLen-i-1] = (iResult%10);    
    }

    // Step3 : 進位處理
    for( i = 0 ; i < iLen ; i++ )
    {
        if( iCarry[i] != 0 )
        {
            iBigResult[i+1]++;
            if((iBigResult[i+1]/10) > 0 )iCarry[i+2]++;
            iBigResult[i+1] = (iBigResult[i+1]%10);    
        }
    }

    // Step4 : 結果顯示
    printf("Addition Result : ");
    for( i = 0 ; i < iLen ; i++ )
    {
        printf("%d",iBigResult[iLen-i-1]);
    }
    printf("\n\n");
}


int _tmain(int argc, _TCHAR* argv[])
{
    char cInput[MAX_LEN];

    int iBig1[MAX_LEN];
    int iBig2[MAX_LEN];

    int iBigLen1 = 0;
    int iBigLen2 = 0;

    int iBigResult[MAX_LEN];
     
    int    i;

    for( i = 0 ; i < MAX_LEN ; i++ )
    {
        cInput[i] = 0;
        iBig1[i] = 0;
        iBig2[i] = 0;
        iBigResult[i] = 0;
    }

    printf("Value1 : ");
    scanf("%s",&cInput);
    Read_from_String_to_Int(cInput,iBig1,&iBigLen1);
    
    printf("Value2 : ");
    scanf("%s",&cInput);
    Read_from_String_to_Int(cInput,iBig2,&iBigLen2);

    Process_Addition(iBig1,iBig2,iBigResult,iBigLen1,iBigLen2);   

    printf("\n");
    system("pause");
    return 0;
}

執行測試結果 :

image

Crystina 發表在 痞客邦 留言(0) 人氣()