기본적으로, 깃 프로젝트 담겨있는 데이터 => 파일 시스템 상에서의 스냅샷(Snapshot)
파일 자체를 저장하기 보다는 실제 프로젝트를 커밋하여 적용할 순간을 중요시 여겨 그 수정 내역 자체를 저장
<Git 프로젝트 3가지 구성요소 >
- Working Directory: 작업할 파일이 있는 디렉토리(내 컴퓨터 작업 공간)
- Staging Area: 커밋(Commit)을 수행할 파일들이 올라가는 영역
- Git Directory: Git 프로젝트의 메타 데이터와 데이터 정보가 저장되는 디렉토리
??저장소란??
저장소(Repo)는 실제 소스코드가 담겨 있으면서 커밋(Commit) 내역 등의 모든 작업 이력이 담겨 있는 공간을 의미합니다. 실제로 프로젝트의 메타 데이터를 포함해 각종 데이터는 .git 폴더에 담기게 됩니다. 실제로 이 폴더를 열어 보면 각종 데이터와 해시 값 등이 담겨 있습니다.
어떠한 파일을 Commit 하게 되면 각 작업들을 분류하기 위해 내부적으로 해당 작업에 대한 해시(Hash) 값을 이용하는 것입니다. 일반적으로 해시 값은 충돌이 발생하지 않기 때문에 정확히 커밋 내역들을 관리할 수 있습니다.
from rest_framework import viewsets
from .models import Post
from .serializer import PostSerializer
class PostViewSet(viewsets.ModelViewSet):
queryset = Post.objects.all()
serializer_class =
ViewSet
-> View(CRUD)를 설계하는 가장 간단한 방법
2. APIView
-> 장점 : 자신의 마음대로 코드를 작성할 수 있다.
-> 단점 : CBV의 장점인 중복되는 코드 제거를 하지 못한다.
-> Response : 클라이언트가 요청한 형태로 콘텐츠를 렌더링 해준다.
-> Status : Http 에서 제공하는 상태 코드는 숫자이지만, REST 프레임워크에서는 문자 형태의 식별자를 제공하여 상태를 좀더 잘 구분할 수 있도록 한다.
-> APIView를 상속해서 view를 설계할 때는 status 와 Response를 import 하여 Response과정을 작성
-> APIView를 상속해서 만든 CBV의 내부 함수들은 필요로 하는 HTTP Method 이름으로 갖는다.
-> 어떠한 status를 받고 response를 전달할지 직접 정하는 것이 apiview를 상속받은 cbv
class SnippetDetail(APIView):
def get(...):
...
def put(...):
...
def delete(...):
...
#SnippetDetail 클래스에 필요한 method는 GET, PUT, DELETE
##실습해보기
django-admin startproject <project-name>
cd <project-name>
python manage.py startapp <app-name>
settings.py에 App, rest_framework추가
models.py에 모델 작성 및 migrate
class Post(models.Model):
title = models.CharField(max_length=100)
body = models.TextField()
serializer.py 생성 및 작성
from .models import Post
from rest_framework import serializers
class PostSerializer(serializers.ModelSerializer):
class Meta:
model = Post
fields = "__all__"
views.py 작성 1) 필요한 모듈 추가(apiview를 상속받은 cbv를 작성하기 위해 아래 모듈 추가)
from CBV.models import Post
from CBV.serializer import PostSerializer
from django.http import Http404
from rest_framework.response import Response
from rest_framework import status
from rest_framework.views import APIView
2)객체들 목록 가져오는 PostList 작성
- post 메서드는 다수의 post 객체를 반환하는 메서드
- 다수의 객체를 직렬화 하기위해서는 PostSerializer 에 many = True를 넘겨야 한다
- post 메서드는 새로운 객세 생성하는 함수
- 저장 성공시 상태코드 201(created) / 반환 실패시 400(bad request)반환
from django.urls import path
from rest_framework.urlpatterns import format_suffix_patterns
from . import views
urlpatterns = [
path("post", views.PostList.as_view()),
path("post/<int:pk>", views.PostDetail.as_view()),
]
urlpatterns = format_suffix_patterns(urlpatterns)
- 프로젝트 폴더 내부의 urls.py 에 include
from django.contrib import admin
from django.urls import path, include
import post.urls
urlpatterns = [
path('admin/', admin.site.urls),
path('', include(post.urls)),
]
실행하고 http://127.0.0.1:8000/post 에 접속하면 정상 작동한다
4. Generic CBV
<분류>
기반 뷰(Base View): 뷰 클래스를 생성하고 다른, 제너릭 뷰의 부모 클래스가 되는 기본 제너릭 뷰
view : 최상위 부모 제너릭 뷰 클래스
TemplateView : 주어진 템플릿으로 렌더링
RedirectView : 주어진 URL로 리다이렉트
제너릭 보기 뷰(Generic Display View): 객체의 목록 또는 하나의 객체 상세 정보를 보여주는 뷰
DetailView : 조건에 맞는 하나의 객체 출력
ListView : 조건에 맞는 객체 목록 출력
제너릭 수정 뷰(Generic Edit View): 폼을 통해 객체를 생성, 수정, 삭제하는 기능을 제공하는 뷰
FormView : 폼이 주어지면 해당 폼 출력
CreateView : 객체 생성하는 폼 출력
UpdateView : 기존 객체 수정하는 폼 출력
DeleteView : 기존 객체 삭제하는 폼 출력
제너릭 날짜 뷰(Generic Date View): 날짜 기반 객체의 연/월/일 페이지로 구분해 보여주는 뷰
YearArchiveView : 주어진 연도에 해당하는 객체 출력
MonthArchiveView : 주어진 월에 해당하는 객체 출력
DayArchiveView : 주어진 날짜에 해당하는 객체 출력
TodayArchiveVIew : 오늘 날짜에 해당하는 객체 출력
DateDetailView : 주어진 연, 월, 일 PK(OR 슬러그)에 해당하는 객체 출력
<제너릭 뷰 오버라이딩>
속성 변수 오버라이딩
model : 기본 뷰(View, Template, RedirectView) 3개를 제외하고 모든 제너릭 뷰에서 사용한다.
queryset : 기본 뷰(View, Template, RedirectView) 3개를 제외하고 모든 제너릭 뷰에서 사용한다.queryset을 사용하면model속성은 무시된다.
template_name : TemplateView를 포함한 모든 제너릭 뷰에서 사용한다. 템플릿 파일명을 문자열로 지정한다.
context_object_name : 뷰에서 템플릿 파일에 전달하는 컨텍스트 변수명을 지정한다.
paginate_by : ListView와 날짜 기반 뷰(예, YearArchiveView)에서 사용한다. 페이징 기능이 활성화 된 경우 페이지당 출력 항목 수를 정수로 지정한다.
date_field : 날짜 기반 뷰(예, YearArchiveView)에서 사용한다. 이 필드의 타입은 DateField 또는 DateTimeField이다.
form_class : FormView, CreateView, UpdateView에서 폼을 만드는데 사용할 클래스를 지정한다.
success_url : FormView, CreateView, UpdateView, DeleteView에서 폼에 대한 처리가 성공한 후 리디이렉트할 URL 주소이다.
메소드 오버라이딩
def get_queryset() : 기본 뷰(View, Template, RedirectView) 3개를 제외하고 모든 제너릭 뷰에서 사용한다. 디폴트는queryset속성을 반환한다.queryset속성이 지정되지 않은 경우 모델 매니저 클래스의 all() 메소드를 호출해 QuerySet 객체를 생성해 반환한다.
def get_context_data(**kwargs) : 뷰에서 템플릿 파일에 넘겨주는 컨텍스트 데이터를 추가하거나 변경하는 목적으로 오버라이딩한다.
def form_valid(form)
<모델을 지정하는 방법 3가지>
model 속성 변수 지정
queryset 속성 변수 지정
def get_queryset() 메소드 오버라이딩
##실습
1. views.py 작성하기 전
django-admin startproject <project-name>
cd <project-name>
python manage.py startapp <app-name>
settings.py에 App, rest_framework추가
models.py에 모델 작성 및 migrate
serializer.py생성 및 작성
2. views.py 작성하기
1) 필요한 모듈 추가하기
- 사용할 모델, serializer , rest_framework 의 generics 추가
from .models import Post
from .serializer import PostSerializer
from rest_framework import generics
2) PostList 클래스 작성하기
- generics의 ListCreateAPIView 는 mixins에서 사용한 list 함수와 create 함수를 가지고 있는 class 이다.
class PostList(generics.ListCreateAPIView):
queryset = Post.objects.all()
serializer_class = PostSerializer
3) PostDetail 클래스 작성하기
- genercis의 RetrieveUpdateDestoryAPIView 또한 mixins에서 사용한 함수들과 동일한 기능
class PostDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Post.objects.all()
serializer_class = PostSerializer
3. urls.py 작성하기
- 앱 내부에 urls.py 생성 및 작성
from django.urls import path
from rest_framework.urlpatterns import format_suffix_patterns
from . import views
urlpatterns = [
path("post", views.PostList.as_view()),
path("post/<int:pk>", views.PostDetail.as_view()),
]
urlpatterns = format_suffix_patterns(urlpatterns)
- 프로젝트 폴더 내부의 urls.py 에 include
from django.contrib import admin
from django.urls import path, include
import post.urls
urlpatterns = [
path('admin/', admin.site.urls),
path('', include(post.urls)),
]
-> 실행 결과 : http://127.0.0.1:8000/post로 접속하면 잘 작동하는 것을 확인할 수 있다.
5. ViewSet
rest_framework의 viewsets.py내부에는 4개의 클래스가 존재한다.
ViewSet
GenericViewSet
ReadOnlyModelViewSet
ModelViewSet
모두 간단하게 구성되어 mixins와 GenricViewSet, APIView등을 묶는 역할을 한다.
ReadOnlyModelViewSet
- 상속 받은 클래스
mixins.RetrieveModelMixin
mixins.ListModelMixin
GenericViewSet
상속받은 클래스로 보아 해당 viewset 역할은 retrieve 함수와 list 함수 기능을 가지고 있다
- 기능 : 특정 객체 가져오는 역할(retrieve) / 객체 목록을 가져오는 역할(list)
ReadOnly를 수행하는 viewSet 이다
아래와 같이 작성하면
기존 postlist, postDetail 클래스의 기능을 따로 작성하지 않아도 ReadOnlyModelViewSet을 상속받아 사용할 수 있다.
from rest_framework import viewsets
from .models import Post
from .serializer import PostSerializer
class PostViewSet(viewsets.ReadOnlyModelViewSet):
queryset = Post.objects.all()
serializer_class =
-> customAPI 함수는 default로 GET 메서드로 처리된다. / 다른 메서드로 처리하고 싶다면 action의 format 인자로 지정 가능
%action decorator
@는 decorator, 장식자라고 부른다. ViewSet을 이용하면 CRUD는 간단하게 구현되나 다른 논리들을 구현할 때 @action를 사용한다. 개발자가 임의로 View를 설계할 수 있도록 해준다.
%renderer_classes
Response를 어떤 형식으로 Rendering시킬 것인가를 정의
renderer.JSONRenderer
renderer.BrowsableAPIRenderer
renderer.StaticHTMLRenderer
TemplateHTMLRenderer
등 여러가지가 있다. 기본 설정은 JSONRenderer와 BrowsableAPIRenderer다.
##실습해보기
viewSet 적용하기
1. views.py 작성하기 전
django-admin startproject <project-name>
cd <project-name>
python manage.py startapp <app-name>
settings.py에 App, rest_framework추가
models.py에 모델 작성 및 migrate
serializer.py생성 및 작성
2. views.py 작성하기
1) 필요한 모듈 추가
from .models import Post
from .serializer import PostSerializer
from rest_framework import viewsets
from rest_framework import renderers
from rest_framework.decorators import action
from django.http import HttpResponse
2) ReadOnlyModelViewSet을 상속해 클래스 작성하기
- viewsets의 ReadOnlyModelViewSet을 상속받아 작성한다. ReadOnlyModelViewSet을 상속받았으므로 읽기만 가능하다.
class PostViewSet(viewsets.ReadOnlyModelViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
3. urls.py 작성하기
- post 앱 내부의 urls.py
from rest_framework.routers import DefaultRouter
from django.urls import include, path
from .views import PostViewSet
router = DefaultRouter()
router.register('', PostViewSet)
urlpatterns = [
path('post', include(router.urls))
]
- 프로젝트 폴더의 urls.py
from django.contrib import admin
from django.urls import path, include
import post.urls
urlpatterns = [
path('admin/', admin.site.urls),
path('', include(post.urls)),
]
>>실행결과
-http://127.0.0.1:8000/로 접속하면 아래와 같은 결과를 확인할 수 있다. DefaultRouter를 사용했기 때문에 PATH가 ""일때도 화면이 나온다.
-http://127.0.0.1:8000/post로 접속하면 사용가능한 HTTP Method가 ReadOnlyModelViewSet을 상속받았으므로 GET밖에 없다.
4. ModelViewSet 상속해 클래스 작성하기
viewsets의 ModelViewset 상속받은 PostViewSet 클래스 작성
사용할 모델과 serializer을 등록하는 것은 기존과 동일
추가적으로 @action 데코레이터를 이용해 custom api 작성
get 방식으로 @action Custom API Test를 띄우는 highlight 함수 작성
class PostViewSet(viewsets.ModelViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
@action(detail=True, renderer_classes=[renderers.StaticHTMLRenderer])
def highlight(self, request, *args, **kwargs):
return HttpResponse("@action Custom API Test")
post로 처리하고 싶다면 @action(method=['post']) 와 같이 작성
>>실행결과
http://127.0.0.1:8000/post로 접속하면 사용가능한 HTTP Method가 GET외에도 POST가 추가된 것을 확인
Custom API 테스트
>http://127.0.0.1:8000/post/2/와 같이 Detail페이지로 접속하면 Extra Actions 스크롤 메뉴가 생긴 것을 확인할 수 있다.
스크롤 메뉴에서 highlight 버튼 클릭 시 아래와 같은 결과가 생성된다
6. Router
viewSet 복습
- ReadOnlyModelViewSet
retrieve()와 list()의 기능
- ModelViewSet
list(), create(), retrieve(), update() partial_update(), destroy()의 기능
path
viewSet을 하나의 path 함수로 처리할 수 있을까?
하나의 path로 ListView, DetailView 의 CRUD가 모두 처리 가능할까??
-> 앱 폴더 내부에 urls.py 생성(계층적 url 관리 위해 분할) ##아니 나는 urls.py를 완성하지 못하면 마이그레이트가 안된다.. 이거먼저!
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from . import views
router = DefaultRouter() #ROUTER 객체 생성
router.register('post', views.PostViewSet) #ROUTER 객체의 REGISTER 함수(첫번째 인자 = URL, 함수)
urlpatterns = [
path('', include(router.urls))
]
#rest_framework는 ROUTER을 사용해 URL을 결정한다
#CRUD 기반으로 URL을 설정한다
-> 프로젝트 폴더 urls.py 에 모듈 추가
from django.contrib import admin
from django.urls import path, include
import post.urls
urlpatterns = [
path('admin/', admin.site.urls),
path('', include(post.urls)),
]
앱 폴더의 models.py 에 모델 클래스 정의 (post/models.py)
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=100)
body = models.TextField()
# Create your models here.
앱 폴더 내부에 serializer.py 생성 및 작성 (어떤 클래스의 어떤 필드를 사용할 것인지)
from .models import Post
from rest_framework import serializers
class PostSerializer(serializers.ModelSerializer):
class Meta:
model = Post
fields = ['title', 'body']
# 모든 필드를 사용할 경우 '__all__' 사용 가능
views.py 작성하기
-> rest_framework 의 viewsets 모듈과 작성한 모델과 serializer 추가
from rest_framework import viewsets
from .models import Post
from .serializer import PostSerializer
class PostViewSet(viewsets.ModelViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
Django Rest Framework는 Class base View 이기에
view로서 class를 작성한다
viewsets의 ModelViewSet을 상속받는다.
##ROUTER
▪ ViewSet에는 여러가지 메소드(함수)들이 있다
ex) retrieve() , destroy(), …
▪ 이 모든 것을 하나의 path()로 처리해 주는 것은 불가능하다.
▪ Path함수를 묶어준다 == path함수의 두번째 인자로 오는 함수를 묶는다
-> Path(요청을 처리할 url, 요청을 인자로 받아 처리할 함수, namespace)
#실행 결과(api 서버 보기)
1. api root : urls.py 에 작성된 DefaultRouter 에 의해 만들어진 기본적인 환경 / 처음 보여지는 화면은 GET 요청을 할 수 있는 URL이 보여진다.
2.POST API
-request : 127.0.0.1/8000/post
-response
post 후 post/1로 들어가면 allow 부분에 put이 들어간 것을 볼 수 있음
각 객체에 pk 값 부여하기
-> serializer.py 파일의 PostSerializer 을 수정한다
class PostSerializer(serializers.ModelSerializer):
class Meta:
model = Post
fields = ['id', 'title', 'body']
새로 고침 후 보면 id 값을 직접 확인할 수 있는 것을 볼 수 있다.
id 값 : 각 인스턴스에 붙는 고유 번호
Read Only 설정하기
-> serializer.py 파일의 PostSerializer을 수정한다
-> read_only_fields 에 read_only 속성을 적용할 필드를 tuple에 추가한다
-> 수정 시 read_only 부분이 true로 바뀌는 것을 볼 수 있다.
-> write_only부분도 같은 방법으로 수정하면된다!
class PostSerializer(serializers.ModelSerializer):
class Meta:
model = Post
fields = "__all__"
read_only_fields = ("title",)
▪ Get 인자가 있으면 쓰고 없으면 안쓴다. ▪ Put 인자가 있으면 쓰고 없으면 안쓴다.
2. CBV
-장고의 view
- 호출 가능한 객체(callable object) 로 정의
-> 함수 / 클래스
- 함수와 클래스의 차이 : 함수 (상속x) / 클래스 (상속o)
- 상속을 사용하는 이유는 ? 중복의 제거 / 코드의 재사용
따라서 CBV를 사용하는 이유는 상속을 사용해 코드를 더 간단하게 작성하기 위해 사용
-FBV(Function Based View) : 함수 기반 뷰
##실습하면서 익혀봅시다
순서 : 프로젝트 생성 -> 앱 생성 -> 템플릿 추가
가상환경 생성 및 활성화
$python -m venv myvenv
$ source myvenv/Scripts/activate
프로젝트 생성
$ django-admin startproject CBV
$ cd CBV
앱 생성
$python manage.py startapp classBaseCrud
settings.py 에 앱 추가
INSTALLED_APPS = [ 'classBaseCrud', ]
models.py 작성하기
- 클래스 생성
from django.db import models
# 클래스를 생성하여 제목, 생성일, 수정일, 본문 필드 작성
class ClassBlog(models.Model):
title = models.CharField(max_length=100)
created_at = models.DateTimeField(auto_now_add=True)
#auto_now_add 옵션 : model이 최초 저장시에만 현재 날짜 적용
updated_at = models.DateTimeField(auto_now=True)
#auto_now 옵션 : 데이터가 저장 될 때마다 현재 날짜로 갱신
body = models.TextField()
def __str__(self):
return self.title
-admin.py에 생성한 클래스 등록
from django.contrib import admin
from .models import ClassBlog
admin.site.register(ClassBlog)
-Generic Views : 웹 개발 시 자주 사용하는 기능을 장고에서 미리 제공 / 외부 모듈 적용이 필요하다
#사용할 모듈 추가 CRUD
from django.utils import timezone
from django.urls import reverse_lazy
from django.views.generic.list import ListView
#게시글 목록 보여줌
from django.views.generic.detail import DetailView
#게시글의 상세 내용을 보여줌
from django.views.generic.edit import CreateView, UpdateView, DeleteView
#게시글 생성, 수정, 삭제
from .models import ClassBlog
2)모듈을 상속해 클래스 작성(classBaseCrud/views.py)
-CREATE
#CREATE
class BlogCreate(CreateView):
model = ClassBlog
fields = ["title", "body"]
success_url = reverse_lazy('list')
#reverse_lazy
#- redirect 와 같은 기능으로 , generic view에서 주로 사용
#- reverse_lazy() 함수 사용 인자로 URL 이름을 넣어줌
#- 작업이 성공적으로 완료되었을 경우 해당 URL로 이동
-READ
#READ
class BlogView(ListView):
model = ClassBlog
template_name = 'classBaseCrud/list.html'
context_object_name = 'blog_list'
# List Views
#- Generi view 중 특정 모델의 리스트를 출력해주는 뷰
#- 모델에 대한 쿼리가 필요하고(queryset)
#- 어느 템플릿에 (template_name)
#- 어떤 파라미터명으로 전달할지 (context_object_name) 를 정의
#- 약속되어있는 html 이름을 사용하지 않고 작성하기 위함
#- 해당 html을 사용할 class에 template_name을 설정하면 된다
#context_object_name : 임의로 설정하여 기본적으로 설정되어있는 객체를 가져옴
class BlogRead(DetailView):
context_object_name = 'blog'
model = ClassBlog
#DetailView
#- 특정 모델의 특정 오브젝트에 대한 자세한 정보를 출력해주는 뷰
#- 어떤 모델의 어떤 오브젝으를 어떤 템플릿에 전달할지 정의
-UPDATE
#UPDATE
class BlogUpdate(UpdateView):
model = ClassBlog
fields = ["title", "body"]
success_url = reverse_lazy("list")
-DELETE
#DELETE
class BlogDelete(DeleteView):
model = ClassBlog
success_url = reverse_lazy("list")
앱 내부에 urls.py 생성 및 작성
- 작성할 클래스에 맞는 url path 작성
- (urls.py / classBaseCurd)
from django.urls import path
from .import views
#작성할 클래스에 맞는 url path 작성
urlpatterns = [
path("", views.BlogView.as_view(), name='list'),
#as_view : view를 하나 만들어서 이를 return
#함수가 하나 만들어지는 것과 같음
#클래스를 정의한 후 이에 해당하는 함수 만들어 사용하는 방식
path("create/", views.BlogCreate.as_view(), name="create"),
path("read/<int:pk>/", views.BlogRead.as_view(), name="read"),
path("update/<int:pk>/", views.BlogUpdate.as_view(), name="update"),
path("delete/<int:pk>/", views.BlogDelete.as_view(), name="delete"),
]
프로젝트 urls.py 에 앱 urls.py 추가
- (urls.py / CBV)
from django.contrib import admin
from django.urls import path, include
#django.urls 의 include 모듈 추가
#앱의 urls.py 파일을 프로젝트 urls.py에 추가
import classBaseCrud.urls
import classBaseCrud.views
urlpatterns = [
path('admin/', admin.site.urls),
path('', include(classBaseCrud.urls)),
]
templates 생성하기
- 수행 결과를 보여주는 HTML 템플릿이 존재해야하고 ListView 는 블로그 리스트 HTML / CreateView, UpdateView 는 입력공간(form)을 갖는 HTML
DetailView는 상세 페이지 HTML / DeleteView 는 삭제 작업을 확인하는 HTML 필요
- Generic View 에서는 기본적으로 설정된 이름이 존재
- 다른 이름으로 HTML 을 작성하기 위해서는 추가 설정이 필요
View 이름
HTML 이름
ListView
(소문자 모델)_list.html
CreateView
(소문자 모델)_form.html
DetailView
(소문자 모델)_detail.html
UpdateView
(소문자 모델)_form.html
DeleteView
(소문자 모델)_confirm_delete.html
##template폴더 구성할 때 template 안에 HTML 파일을 작성하는 게 아니라 App 이름의 폴더를 작성하고 그 안에 작성
앱 안에 templates라는 폴더를 만들고 그 안에 앱 이름으로 폴더를 만들어 그 안에 html를 만들어야함
헤더 파일에 있는 #include <config.h> 지움 -> 이지부트 설정을 담고 있는 파일
extern TConfig Cfg;를 지움 -> 이지부트 설정 담음
void SerialInit( eBauds baudrate ) 함수를 다 지움 -> 이지부트 설정 담음
static volatitle Word *UART = (volatile Word *) STUART; =>>>#ifdef IN_GUMSTIX static volatitle Word *UART = (volatile Word *) FFUART; #else static volatitl #endif -> UART : 컴퓨터 간에 통신 기능을 제공하는 기법 -> 나빌눅스에서는 FULL FUNCTION UART를 사용 ==> UART를 버퍼 주소로 변경해 준다 -> volatile 는 컴파일러로부터 최적화를 막아주는 키워드
include/pxa255.h:46:1: warning: this is the location of the previous definition serial.c:41: error: syntax error before "Word" serial.c:41: warning: initialization discards qualifiers from pointer target type make: *** [all] Error 1
SMC91C1111-0 Net: SMC91C1111-0 Hit any key to stop autoboot: 0 Instruction Cache is ON ### JFFS2 loading 'boot/uImage' to 0xa2000000 Scanning JFFS2 FS: done. find_inode failed for name=boot load: Failed to find inode ### JFFS2 LOAD ERROR<0> for boot/uImage!