⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 program8051.cpp

📁 pc loader for 8051 based microcomputers
💻 CPP
字号:
// Program8051.cpp: implementation of the CProgram8051 class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Program8051.h"

#include "ProgramPunjac.h"
#include "ProgramSnimac.h"
#include "../PL3000/I2CComm.h"
#include <algorithm>

#include "../PL3000/MyLog.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CProgram8051::CProgram8051()
: bajtDopune_m(PRG::BAJT_DOPUNE)
, izmenjen_m(false)
, tekstGreske_m("")
, duzina_m(0)
{
    // Alociraj potrebnu memoriju.
    // Dovoljno je da se ovo uradi samo jednom - npr. ovde u konstruktoru.
    kod_m.reserve(NajvecaMogucaAdresa()+1);
    // inicijalizuj sadrzaj koda
    Reset();
}

CProgram8051::~CProgram8051()
{

}

bool CProgram8051::operator==(const CProgram8051& prg) const
{
    bool identicni = false;
    char pomtxt[100];

    // Poredim ceo adresni prostor
    if (kod_m.size() == prg.kod_m.size()) {

        if (kod_m.size() == 0) {
            identicni = true;
        }
        else {
            identicni = std::equal(kod_m.begin(), kod_m.end(), prg.kod_m.begin());

            // Upisi u log spisak razlicitih bajtova
            if (!identicni) {
                CMyLog::Instance()->UpisiLogPoruku("A list of diferent bytes :");
                for (int i=0; i<kod_m.size(); ++i) {
                    if (kod_m[i] != prg.kod_m[i]) {
                        sprintf(pomtxt, "adr %X: %X != %X", i, kod_m[i], prg.kod_m[i]);
                        CMyLog::Instance()->UpisiLogPoruku(pomtxt);
                    }
                }
            }
        }
    }
    else {
        sprintf(
            pomtxt, "Sizes are different: %d != %d", kod_m.size(), prg.kod_m.size()
            );
        CMyLog::Instance()->UpisiLogPoruku(pomtxt);
    }

    return identicni;
}

bool CProgram8051::NapuniProgram(
    CProgramPunjac* pPunjac,
    PRG::tAdresa pocetnaAdresa,
    PRG::tAdresa zavrsnaAdresa,
    bool prethodnoObrisiCeoSadrzaj
    )
{
    bool bOK = true;

    if (!PunjacValidan(pPunjac)) return false; // ovo mora najpre da se proveri !

    if (!StartujPunjenje(pPunjac, pocetnaAdresa, zavrsnaAdresa)) return false;

    // 'Resetuj' sadrzaj programa, ako je potrebno
    if (prethodnoObrisiCeoSadrzaj) {
        if (!Reset()) return false;
    }

    bOK = PrebaciProgramIzPunjaca(pPunjac);
    if (bOK) { // ako je punjenje proteklo bez greske
        // 'normalno' zaustavljam punjenje
        // (sa pamcenjem poruke o gresci ako dodje do eventualne greske)
        bOK = ZaustaviPunjenje(pPunjac);
    }
    else { // ako je pri punjenju vec doslo do greske
        // 'tiho' zaustavljam punjenje, da ne bi pregazio tu poruku greske
        // (ona mi je vaznija nego eventualna greska pri zaustavlanju)
        ZaustaviPunjenjeTiho(pPunjac);
    }

    // Nakon uspesnog punjenja, program je u 'osnovnom' stanju (neizmenjen)
    if (bOK) {
        Izmenjen(false);
    }

    return bOK;
}

bool CProgram8051::NapuniProgram(CProgramPunjac* pPunjac, bool prethodnoObrisiCeoSadrzaj)
{
    return NapuniProgram(pPunjac, 0, NajvecaMogucaAdresa(), prethodnoObrisiCeoSadrzaj);
}

bool CProgram8051::SnimiProgram(
    CProgramSnimac* pSnimac,
    PRG::tAdresa pocetnaAdresa,
    PRG::tAdresa zavrsnaAdresa
    )
{
    bool bOK = true;

    if (!SnimacValidan(pSnimac)) return false; // ovo mora najpre da se proveri !
    if (!StartujSnimanje(pSnimac)) return false;
    bOK = PrebaciProgramSnimacu(pSnimac, pocetnaAdresa, zavrsnaAdresa);
    if (bOK) { // ako je snimanje proteklo bez greske
        // 'normalno' zaustavljam snimanje
        // (sa pamcenjem poruke o gresci ako dodje do eventualne greske)
        bOK = ZaustaviSnimanje(pSnimac);
    }
    else { // ako je pri snimanju vec doslo do greske
        // 'tiho' zaustavljam snimanje, da ne bi pregazio tu poruku greske
        // (ona mi je vaznija nego eventualna greska pri zaustavlanju)
        ZaustaviSnimanjeTiho(pSnimac);
    }

    return bOK;
}

bool CProgram8051::SnimiProgram(CProgramSnimac* pSnimac)
{
    if (Duzina() > 0) {
        return SnimiProgram(pSnimac, 0, Duzina()-1);
    }
    return true;
}

bool CProgram8051::UpisiBajt(PRG::tAdresa adresa, PRG::tBajt bajt)
{
    bool bOK = false;
    if (ProveriAdresu(adresa)){
        // Postavi vrednost na datoj adresi
        try {
            kod_m[adresa] = bajt;
            // postavi signal da je fajl izmenjen
            Izmenjen(true);
            // duzina programa se odredjuje na osnovu
            // najvece adrese na koju je upisan bajt
            if (duzina_m < adresa+1 ) {
                duzina_m = adresa+1;
            }
            bOK = true;
        }
        catch (...) {
            OpisiGresku("error in writing byte to program");
        }
    }
    else {
        OpisiGresku("bad address");
    }
    return bOK;
}

bool CProgram8051::ProcitajBajt(PRG::tAdresa adresa, PRG::tBajt& bajt)
{
    bool bOK = false;
    if (ProveriAdresu(adresa)){
        try {
            bajt = kod_m[adresa];
            bOK = true;
        }
        catch (...) {
            OpisiGresku("error reading byte from program");
        }
    }
    else {
        OpisiGresku("bad address");
    }
    return bOK;
}

bool CProgram8051::Prazan(void)
{
//    return (Duzina() == 0);
    return (AdresaPocetkaDopune() == 0);
}

PRG::tAdresa CProgram8051::AdresaPoslednjegBajta(void)
{
    PRG::tAdresa poslednjaAdresa = 0;
    if (Duzina() > 0) {
        poslednjaAdresa = Duzina() - 1;
    }
    return poslednjaAdresa;
}

unsigned int CProgram8051::NajvecaMogucaDuzina(void)
{
    return (NajvecaMogucaAdresa() + 1);
}

PRG::tAdresa CProgram8051::NajvecaMogucaAdresa(void)
{
    // Adresni prostor 8051 je 64K
    return (1024*64-1);
}

bool CProgram8051::ProveriAdresu(PRG::tAdresa adresa)
{
    return (adresa >=0 && adresa <= NajvecaMogucaAdresa());
}

bool CProgram8051::Izmenjen(void)
{
    return izmenjen_m;
}

std::string CProgram8051::TekstGreske(void)
{
    return tekstGreske_m;
}

bool CProgram8051::Reset(void)
{
    bool bOK = true;
    try {
        // obrisi stari sadrzaj
        kod_m.clear();
        duzina_m = 0;
        // inicijalizuj sve bajtove programa na default vrednost
        int duzinaKoda = NajvecaMogucaAdresa()+1;
        for (int i = 0; i < duzinaKoda ;++i) {
            kod_m.push_back(bajtDopune_m);
        }
    }
    catch (...) {
        bOK = false;
    }
    return bOK;
}

PRG::tAdresa CProgram8051::AdresaPocetkaDopune(void)
{
    using namespace PRG;
    tAdresa adresaDopune = kod_m.size();
    while (adresaDopune > 0) {
        --adresaDopune;
        if (kod_m[adresaDopune] != bajtDopune_m) {
            ++adresaDopune;
            break;
        }
    }
    return adresaDopune;
}

//////////////////////////////////////////////////////////////////////
// Pomocne funkcije
//////////////////////////////////////////////////////////////////////

void CProgram8051::Izmenjen(bool izmenjen)
{
    izmenjen_m = izmenjen;
}

void CProgram8051::OpisiGresku(const std::string& tekst)
{
    tekstGreske_m = tekst;
}

unsigned int CProgram8051::Duzina(void)
{
    return duzina_m;
}

//////////////////////////////////////////////////////////////////////
// Pomocne funkcije za proceduru 'NapuniProgram'
//////////////////////////////////////////////////////////////////////

bool CProgram8051::PunjacValidan(CProgramPunjac* pPunjac)
{
    if (pPunjac == 0) {
        OpisiGresku("null pointer");
        return false;
    }
    return true;
}

bool CProgram8051::StartujPunjenje(
    CProgramPunjac* pPunjac,
    PRG::tAdresa pocetnaAdresa,
    PRG::tAdresa zavrsnaAdresa
    )
{
    bool bOK = true;
    std::string opis;
    try {
        bOK = pPunjac->Start(pocetnaAdresa, zavrsnaAdresa, opis);
    }
    catch (...) {
        bOK = false;
        opis = "exception while calling Start";
    }
    if (!bOK) {
        OpisiGresku(opis);
    }
    return bOK;
}

bool CProgram8051::PrebaciProgramIzPunjaca(CProgramPunjac* pPunjac)
{
    bool bOK = true;
    try {
        // Ucitaj sadrzaj iz 'punjaca'
        PRG::tBajt bajt;
        PRG::tAdresa adresa;
        while (pPunjac->DajSledeciBajt(bajt, adresa)){
            if (!UpisiBajt(adresa, bajt)){
                bOK = false;
                break;
            }
        }
    }
    catch (CProgramPunjac::CPunjacException& e){
        OpisiGresku(e.opisGreske);
        bOK = false;
    }
    catch (...){
        OpisiGresku("exception while loading program");
        bOK = false;
    }
    return bOK;
}

bool CProgram8051::ZaustaviPunjenje(CProgramPunjac* pPunjac)
{
    std::string opis;
    bool bOK = pPunjac->Stop(opis);
    if (!bOK) {
        OpisiGresku(opis);
    }
    return bOK;
}

bool CProgram8051::ZaustaviPunjenjeTiho(CProgramPunjac* pPunjac)
{
    return pPunjac->Stop();
}

//////////////////////////////////////////////////////////////////////
// Pomocne funkcije za proceduru 'SnimiProgram'
//////////////////////////////////////////////////////////////////////

bool CProgram8051::SnimacValidan(CProgramSnimac* pSnimac)
{
    if (pSnimac == 0) {
        OpisiGresku("null pointer");
        return false;
    }
    return true;
}

bool CProgram8051::StartujSnimanje(CProgramSnimac* pSnimac)
{
    bool bOK = true;
    std::string opis;
    try {
        bOK = pSnimac->Start(opis);
    }
    catch (...) {
        bOK = false;
        opis = "exception while calling Start";
    }
    if (!bOK) {
        OpisiGresku(opis);
    }
    return bOK;
}

bool CProgram8051::PrebaciProgramSnimacu(
    CProgramSnimac* pSnimac,
    PRG::tAdresa pocetnaAdresa,
    PRG::tAdresa zavrsnaAdresa
    )
{
    bool bOK = true;
    try {
        using namespace PRG;
        tAdresa adrDO = OgraniciAdresu(zavrsnaAdresa);
        tAdresa adrOD = pocetnaAdresa;
        // obavesti snimac 'sta ga ceka' (da bi mogao da organizuje kesiranje npr.)
        pSnimac->OpsegAdresa(adrOD, adrDO);
        // salji jedan po jedan bajt na snimanje
        PRG::tBajt bajt;
        for (tAdresa adresa = adrOD; adresa <= adrDO; ++adresa){
            if (ProcitajBajt(adresa, bajt)) {
                pSnimac->SnimiSledeciBajt(bajt, adresa);
            }
            else {
                bOK = false;
                break;
            }
        }
    }
    catch (CProgramSnimac::CSnimacException& e){
        OpisiGresku(e.opisGreske);
        bOK = false;
    }
    catch (...){
        OpisiGresku("exception while loading program");
        bOK = false;
    }

    return bOK;
}

bool CProgram8051::ZaustaviSnimanje(CProgramSnimac* pSnimac)
{
    std::string opis;
    bool bOK = pSnimac->Stop(opis);
    if (!bOK) {
        OpisiGresku(opis);
    }
    return bOK;
}

bool CProgram8051::ZaustaviSnimanjeTiho(CProgramSnimac* pSnimac)
{
    std::string opis;
    return pSnimac->Stop(opis);
}

PRG::tAdresa CProgram8051::OgraniciAdresu(PRG::tAdresa adresa)
{
    if (adresa > NajvecaMogucaAdresa()) {
        return NajvecaMogucaAdresa();
    }
    return adresa;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -